summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Kosek <mkosek@redhat.com>2013-01-11 13:43:15 +0100
committerRob Crittenden <rcritten@redhat.com>2013-01-11 11:30:15 -0500
commit41b2febff00999dc6b477f18e2ad89cd49e39532 (patch)
treeae6c7192a3fc58796f133d89c0ae629d55754979
parentd9114842f62b465306ecbba40bda5c57f581260b (diff)
downloadfreeipa.git-41b2febff00999dc6b477f18e2ad89cd49e39532.tar.gz
freeipa.git-41b2febff00999dc6b477f18e2ad89cd49e39532.tar.xz
freeipa.git-41b2febff00999dc6b477f18e2ad89cd49e39532.zip
Sort LDAP updates properly
LDAP updates were sorted by number of RDNs in DN. This, however, sometimes caused updates to be executed before cn=schema updates. If the update required an objectClass or attributeType added during the cn=schema update, the update operation failed. Fix the sorting so that the cn=schema updates are always run first and then the other updates sorted by RDN count. https://fedorahosted.org/freeipa/ticket/3342
-rw-r--r--ipaserver/install/ldapupdate.py35
1 files changed, 16 insertions, 19 deletions
diff --git a/ipaserver/install/ldapupdate.py b/ipaserver/install/ldapupdate.py
index f7261adc..48544108 100644
--- a/ipaserver/install/ldapupdate.py
+++ b/ipaserver/install/ldapupdate.py
@@ -893,26 +893,23 @@ class LDAPUpdate:
def _run_updates(self, all_updates):
# For adds and updates we want to apply updates from shortest
- # to greatest length of the DN. For deletes we want the reverse.
-
- dn_by_rdn_count = {}
- for dn in all_updates.keys():
+ # to greatest length of the DN. cn=schema must always go first to add
+ # new objectClasses and attributeTypes
+ # For deletes we want the reverse
+ def update_sort_key(dn_update):
+ dn, update = dn_update
assert isinstance(dn, DN)
- rdn_count = len(dn)
- rdn_count_list = dn_by_rdn_count.setdefault(rdn_count, [])
- if dn not in rdn_count_list:
- rdn_count_list.append(dn)
-
- sortedkeys = dn_by_rdn_count.keys()
- sortedkeys.sort()
- for rdn_count in sortedkeys:
- for dn in dn_by_rdn_count[rdn_count]:
- self._update_record(all_updates[dn])
-
- sortedkeys.reverse()
- for rdn_count in sortedkeys:
- for dn in dn_by_rdn_count[rdn_count]:
- self._delete_record(all_updates[dn])
+ return dn != DN(('cn', 'schema')), len(dn)
+
+ sorted_updates = sorted(all_updates.iteritems(), key=update_sort_key)
+
+ for dn, update in sorted_updates:
+ self._update_record(update)
+
+ # Now run the deletes in reversed order
+ sorted_updates.reverse()
+ for dn, update in sorted_updates:
+ self._delete_record(update)
def update(self, files):
"""Execute the update. files is a list of the update files to use.