summaryrefslogtreecommitdiffstats
path: root/ipapython
diff options
context:
space:
mode:
authorFraser Tweedale <ftweedal@redhat.com>2018-11-06 14:17:17 +1100
committerChristian Heimes <cheimes@redhat.com>2018-11-06 10:59:06 +0100
commit4cd26fcba5b444020536935c979e44af4fdc654b (patch)
tree8c2e14dd72a795efbd8cc33d580ea2d277ca43b7 /ipapython
parentda2078bc6075b69a7bb52e18ab68cea4e1ecd346 (diff)
downloadfreeipa-4cd26fcba5b444020536935c979e44af4fdc654b.tar.gz
freeipa-4cd26fcba5b444020536935c979e44af4fdc654b.tar.xz
freeipa-4cd26fcba5b444020536935c979e44af4fdc654b.zip
ipaldap: avoid invalid modlist when attribute encoding differs
ipaldap does not take into account the possibility of the attribute encoding returned by python-ldap differing from the attribute encoding produced by FreeIPA. In particular this can occur with DNs with special characters that require escaping. For example, python-ldap (or the underlying LDAP library) escapes special characters using hex encoding: CN=Test Sub-CA 201604041620,OU=ftweedal,O=Red Hat\2C Inc.,L=Brisbane,C=AU Whereas FreeIPA, when encoding the DN, escapes the character directly: CN=Test Sub-CA 201604041620,OU=ftweedal,O=Red Hat\, Inc.,L=Brisbane,C=AU Therefore it is possible to generate an invalid modlist. For example, during external CA certificate renewal, if the issuer DN includes a comma in one of the attribute values (as above), an invalid modlist will be generated: [ (ldap.MOD_ADD, 'ipacaissuerdn', [b'CN=Test Sub-CA 201604041620,OU=ftweedal,O=Red Hat\, Inc.,L=Brisbane,C=AU']) , (ldap.MOD_DELETE, 'ipacaissuerdn', [b'CN=Test Sub-CA 201604041620,OU=ftweedal,O=Red Hat\2C Inc.,L=Brisbane,C=AU']) ] Although encoded differently, these are the same value. If this modification is applied to the object, attributeOrValueExists (error 20) occurs. To avoid the issue, put deletes before adds in the modlist. If a value is present (with different encodings) as both an addition and a deletion, it must be because the original object contained the value with a different encoding. Therefore it is safe to delete it, then add it back. Note that the modlist is not optimal. In the simplest case (like above example), there should be no modification to perform. It is considerably more complex (and more computation) to implement this because the raw attribute values must be decoded before comparison. Fixes: https://pagure.io/freeipa/issue/7750 Reviewed-By: Christian Heimes <cheimes@redhat.com>
Diffstat (limited to 'ipapython')
-rw-r--r--ipapython/ipaldap.py7
1 files changed, 5 insertions, 2 deletions
diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py
index 93cba8919..48988b017 100644
--- a/ipapython/ipaldap.py
+++ b/ipapython/ipaldap.py
@@ -562,10 +562,13 @@ class LDAPEntry(MutableMapping):
raise errors.OnlyOneValueAllowed(attr=name)
modlist.append((ldap.MOD_REPLACE, name, adds))
else:
- if adds:
- modlist.append((ldap.MOD_ADD, name, adds))
+ # dels before adds, in case the same value occurs in
+ # both due to encoding differences
+ # (https://pagure.io/freeipa/issue/7750)
if dels:
modlist.append((ldap.MOD_DELETE, name, dels))
+ if adds:
+ modlist.append((ldap.MOD_ADD, name, adds))
# Usually the modlist order does not matter.
# However, for schema updates, we want 'attributetypes' before