diff options
-rw-r--r-- | ipapython/ipaldap.py | 27 | ||||
-rw-r--r-- | ipaserver/install/ldapupdate.py | 115 |
2 files changed, 12 insertions, 130 deletions
diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py index 1d392497f..027bfa979 100644 --- a/ipapython/ipaldap.py +++ b/ipapython/ipaldap.py @@ -1963,25 +1963,14 @@ class IPAdmin(LDAPClient): if key in FORCE_REPLACE_ON_UPDATE_ATTRS or is_single_value: force_replace = True - # You can't remove schema online. An add will automatically - # replace any existing schema. - if old_entry.dn == DN(('cn', 'schema')): - if len(adds) > 0: - if key.lower() == 'attributetypes': - modlist.insert(0, (ldap.MOD_ADD, key, adds)) - else: - modlist.append((ldap.MOD_ADD, key, adds)) - else: - if adds: - if force_replace: - modlist.append((ldap.MOD_REPLACE, key, adds)) - else: - modlist.append((ldap.MOD_ADD, key, adds)) - if removes: - if not force_replace: - modlist.append((ldap.MOD_DELETE, key, removes)) - elif new_values == []: # delete an empty value - modlist.append((ldap.MOD_DELETE, key, removes)) + if adds: + if force_replace: + modlist.append((ldap.MOD_REPLACE, key, adds)) + else: + modlist.append((ldap.MOD_ADD, key, adds)) + if removes: + if not force_replace or not new_values: + modlist.append((ldap.MOD_DELETE, key, removes)) return modlist diff --git a/ipaserver/install/ldapupdate.py b/ipaserver/install/ldapupdate.py index 69eb18957..87bd0c8fe 100644 --- a/ipaserver/install/ldapupdate.py +++ b/ipaserver/install/ldapupdate.py @@ -32,12 +32,10 @@ import os import pwd import fnmatch import csv -import inspect import re import krbV import ldap -from ldap.schema.models import ObjectClass, AttributeType from ipaserver.install import installutils from ipapython import ipautil, ipaldap @@ -576,36 +574,6 @@ class LDAPUpdate: else: entry_values = [entry_values] - # Replacing objectClassess needs a special handling and - # normalization of OC definitions to avoid update failures for - # example when X-ORIGIN is the only difference - schema_update = False - schema_elem_class = None - schema_elem_name = None - if action == "replace" and entry.dn == DN(('cn', 'schema')): - if attr.lower() == "objectclasses": - schema_elem_class = ObjectClass - schema_elem_name = "ObjectClass" - elif attr.lower() == "attributetypes": - schema_elem_class = AttributeType - schema_elem_name = "AttributeType" - - if schema_elem_class is not None: - schema_update = True - oid_index = {} - # build the OID index for replacing - for schema_elem in entry_values: - try: - schema_elem_object = schema_elem_class(str(schema_elem)) - except Exception, e: - self.error('replace: cannot parse %s "%s": %s', - schema_elem_name, schema_elem, e) - continue - # In a corner case, there may be more representations of - # the same objectclass/attributetype due to the previous updates - # We want to replace them all - oid_index.setdefault(schema_elem_object.oid, []).append(schema_elem) - for update_value in update_values: if action == 'remove': self.debug("remove: '%s' from %s, current value %s", safe_output(attr, update_value), attr, safe_output(attr,entry_values)) @@ -672,37 +640,6 @@ class LDAPUpdate: (old, new) = update_value.split('::', 1) except ValueError: raise BadSyntax, "bad syntax in replace, needs to be in the format old::new in %s" % update_value - try: - if schema_update: - try: - schema_elem_old = schema_elem_class(str(old)) - except Exception, e: - self.error('replace: cannot parse replaced %s "%s": %s', - schema_elem_name, old, e) - continue - replaced_values = [] - for schema_elem in oid_index.get(schema_elem_old.oid, []): - schema_elem_object = schema_elem_class(str(schema_elem)) - if str(schema_elem_old).lower() == str(schema_elem_object).lower(): - # compare normalized values - replaced_values.append(schema_elem) - self.debug('replace: replace %s "%s" with "%s"', - schema_elem_name, - safe_output(attr, old), - safe_output(attr, new)) - if not replaced_values: - self.debug('replace: no match for replaced %s "%s"', - schema_elem_name, safe_output(attr, old)) - continue - for value in replaced_values: - entry_values.remove(value) - else: - entry_values.remove(old) - entry_values.append(new) - self.debug('replace: updated value %s', safe_output(attr, entry_values)) - entry[attr] = entry_values - except ValueError: - self.debug('replace: %s not found, skipping', safe_output(attr, old)) return entry @@ -720,43 +657,6 @@ class LDAPUpdate: else: self.debug('%s: %s', a, safe_output(a, value)) - def is_schema_updated(self, s): - """Compare the schema in 's' with the current schema in the DS to - see if anything has changed. This should account for syntax - differences (like added parens that make no difference but are - detected as a change by generateModList()). - - This doesn't handle re-ordering of attributes. They are still - detected as changes, so foo $ bar != bar $ foo. - - return True if the schema has changed - return False if it has not - """ - signature = inspect.getargspec(ldap.schema.SubSchema.__init__) - if 'check_uniqueness' in signature.args: - s = ldap.schema.SubSchema(s, check_uniqueness=0) - else: - s = ldap.schema.SubSchema(s) - s = s.ldap_entry() - - # Get a fresh copy and convert into a SubSchema - n = self._get_entry(DN(('cn', 'schema')))[0] - - # Convert IPA data types back to strings - d = dict() - for k,v in n.data.items(): - d[k] = [str(x) for x in v] - - # Convert to subschema dict - n = ldap.schema.SubSchema(d) - n = n.ldap_entry() - - # Are they equal? - if s == n: - return False - else: - return True - def _update_record(self, update): found = False @@ -823,14 +723,8 @@ class LDAPUpdate: # Update LDAP try: changes = self.conn.generateModList(entry.orig_data, entry) - if (entry.dn == DN(('cn', 'schema'))): - d = dict() - for k,v in entry.items(): - d[k] = [str(x) for x in v] - updated = self.is_schema_updated(d) - else: - if len(changes) >= 1: - updated = True + if len(changes) >= 1: + updated = True safe_changes = [] for (type, attr, values) in changes: safe_changes.append((type, attr, safe_output(attr, values))) @@ -906,13 +800,12 @@ 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. cn=schema must always go first to add - # new objectClasses and attributeTypes + # to greatest length of the DN. # For deletes we want the reverse def update_sort_key(dn_update): dn, update = dn_update assert isinstance(dn, DN) - return dn != DN(('cn', 'schema')), len(dn) + return len(dn) sorted_updates = sorted(all_updates.iteritems(), key=update_sort_key) |