pgreco / rpms / ipa

Forked from forks/areguera/rpms/ipa 4 years ago
Clone

Blame SOURCES/0013-ipaldap_invalid_modlist_when_attribute_encoding_can_vary_rhbz#1658302.patch

6d47df
From 9e7e9c1014c10f838b341a45436aba0840ad5b07 Mon Sep 17 00:00:00 2001
6d47df
From: Fraser Tweedale <ftweedal@redhat.com>
6d47df
Date: Nov 07 2018 13:51:59 +0000
6d47df
Subject: ipaldap: avoid invalid modlist when attribute encoding differs
6d47df
6d47df
6d47df
ipaldap does not take into account the possibility of the attribute
6d47df
encoding returned by python-ldap differing from the attribute
6d47df
encoding produced by FreeIPA.  In particular this can occur with DNs
6d47df
with special characters that require escaping.  For example,
6d47df
python-ldap (or the underlying LDAP library) escapes special
6d47df
characters using hex encoding:
6d47df
6d47df
  CN=Test Sub-CA 201604041620,OU=ftweedal,O=Red Hat\2C Inc.,L=Brisbane,C=AU
6d47df
6d47df
Whereas FreeIPA, when encoding the DN, escapes the character
6d47df
directly:
6d47df
6d47df
  CN=Test Sub-CA 201604041620,OU=ftweedal,O=Red Hat\, Inc.,L=Brisbane,C=AU
6d47df
6d47df
Therefore it is possible to generate an invalid modlist. For
6d47df
example, during external CA certificate renewal, if the issuer DN
6d47df
includes a comma in one of the attribute values (as above), an
6d47df
invalid modlist will be generated:
6d47df
6d47df
  [ (ldap.MOD_ADD, 'ipacaissuerdn',
6d47df
      [b'CN=Test Sub-CA 201604041620,OU=ftweedal,O=Red Hat\, Inc.,L=Brisbane,C=AU'])
6d47df
  , (ldap.MOD_DELETE, 'ipacaissuerdn',
6d47df
      [b'CN=Test Sub-CA 201604041620,OU=ftweedal,O=Red Hat\2C Inc.,L=Brisbane,C=AU'])
6d47df
  ]
6d47df
6d47df
Although encoded differently, these are the same value.  If this
6d47df
modification is applied to the object, attributeOrValueExists (error
6d47df
20) occurs.
6d47df
6d47df
To avoid the issue, put deletes before adds in the modlist.  If a
6d47df
value is present (with different encodings) as both an addition and
6d47df
a deletion, it must be because the original object contained the
6d47df
value with a different encoding.  Therefore it is safe to delete it,
6d47df
then add it back.
6d47df
6d47df
Note that the modlist is not optimal.  In the simplest case (like
6d47df
above example), there should be no modification to perform.  It is
6d47df
considerably more complex (and more computation) to implement this
6d47df
because the raw attribute values must be decoded before comparison.
6d47df
6d47df
Fixes: https://pagure.io/freeipa/issue/7750
6d47df
Reviewed-By: Christian Heimes <cheimes@redhat.com>
6d47df
6d47df
---
6d47df
6d47df
diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py
6d47df
index fbc824e..cf1e60b 100644
6d47df
--- a/ipapython/ipaldap.py
6d47df
+++ b/ipapython/ipaldap.py
6d47df
@@ -565,10 +565,13 @@ class LDAPEntry(MutableMapping):
6d47df
                     raise errors.OnlyOneValueAllowed(attr=name)
6d47df
                 modlist.append((ldap.MOD_REPLACE, name, adds))
6d47df
             else:
6d47df
-                if adds:
6d47df
-                    modlist.append((ldap.MOD_ADD, name, adds))
6d47df
+                # dels before adds, in case the same value occurs in
6d47df
+                # both due to encoding differences
6d47df
+                # (https://pagure.io/freeipa/issue/7750)
6d47df
                 if dels:
6d47df
                     modlist.append((ldap.MOD_DELETE, name, dels))
6d47df
+                if adds:
6d47df
+                    modlist.append((ldap.MOD_ADD, name, adds))
6d47df
 
6d47df
         # Usually the modlist order does not matter.
6d47df
         # However, for schema updates, we want 'attributetypes' before
6d47df