summaryrefslogtreecommitdiffstats
path: root/ipaserver/install/ldapupdate.py
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:29:04 -0500
commit1d2d1e1af1660d022adca447f900403d171cba00 (patch)
treed97a5d8b71e74a4f0b1172ccf5b81ee677fbf8a8 /ipaserver/install/ldapupdate.py
parent79bcf904a50aff704819134a58d09ba688b285e8 (diff)
downloadfreeipa-1d2d1e1af1660d022adca447f900403d171cba00.tar.gz
freeipa-1d2d1e1af1660d022adca447f900403d171cba00.tar.xz
freeipa-1d2d1e1af1660d022adca447f900403d171cba00.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
Diffstat (limited to 'ipaserver/install/ldapupdate.py')
-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 f7261adc4..485441089 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.