mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2026-10-12 16:32:01 -05:00
Add attributeTypes to safe schema updater
AttributeType updates are sensitive to case, whitespace or X-ORIGIN mismatch just like ObjectClass attribute which is already being normalized before an update value is compared with update instructions. Expand safe schema updater routine to cover both ObjectClasses and AttributeTypes updates. https://fedorahosted.org/freeipa/ticket/2440
This commit is contained in:
1 parent
cd7a85c12c
commit
edf8138568
1 file changed
+32
-22
@@ -35,7 +35,7 @@ from ipalib import errors
|
|||||||
from ipalib import api
|
from ipalib import api
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
import ldap
|
import ldap
|
||||||
from ldap.schema.models import ObjectClass
|
from ldap.schema.models import ObjectClass, AttributeType
|
||||||
from ipapython.ipa_log_manager import *
|
from ipapython.ipa_log_manager import *
|
||||||
import krbV
|
import krbV
|
||||||
import platform
|
import platform
|
||||||
@@ -551,23 +551,32 @@ class LDAPUpdate:
|
|||||||
# Replacing objectClassess needs a special handling and
|
# Replacing objectClassess needs a special handling and
|
||||||
# normalization of OC definitions to avoid update failures for
|
# normalization of OC definitions to avoid update failures for
|
||||||
# example when X-ORIGIN is the only difference
|
# example when X-ORIGIN is the only difference
|
||||||
objectclass_replacement = False
|
schema_update = False
|
||||||
if action == "replace" and entry.dn == DN(('cn', 'schema')) and \
|
schema_elem_class = None
|
||||||
attr.lower() == "objectclasses":
|
schema_elem_name = None
|
||||||
objectclass_replacement = True
|
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 = {}
|
oid_index = {}
|
||||||
# build the OID index for replacing
|
# build the OID index for replacing
|
||||||
for objectclass in entry_values:
|
for schema_elem in entry_values:
|
||||||
try:
|
try:
|
||||||
objectclass_object = ObjectClass(str(objectclass))
|
schema_elem_object = schema_elem_class(str(schema_elem))
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
self.error('replace: cannot parse ObjectClass "%s": %s',
|
self.error('replace: cannot parse %s "%s": %s',
|
||||||
objectclass, e)
|
schema_elem_name, schema_elem, e)
|
||||||
continue
|
continue
|
||||||
# In a corner case, there may be more representations of
|
# In a corner case, there may be more representations of
|
||||||
# the same objectclass due to the previous updates
|
# the same objectclass/attributetype due to the previous updates
|
||||||
# We want to replace them all
|
# We want to replace them all
|
||||||
oid_index.setdefault(objectclass_object.oid, []).append(objectclass)
|
oid_index.setdefault(schema_elem_object.oid, []).append(schema_elem)
|
||||||
|
|
||||||
for update_value in update_values:
|
for update_value in update_values:
|
||||||
if action == 'remove':
|
if action == 'remove':
|
||||||
@@ -624,23 +633,24 @@ class LDAPUpdate:
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
raise BadSyntax, "bad syntax in replace, needs to be in the format old::new in %s" % update_value
|
raise BadSyntax, "bad syntax in replace, needs to be in the format old::new in %s" % update_value
|
||||||
try:
|
try:
|
||||||
if objectclass_replacement:
|
if schema_update:
|
||||||
try:
|
try:
|
||||||
objectclass_old = ObjectClass(str(old))
|
schema_elem_old = schema_elem_class(str(old))
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
self.error('replace: cannot parse replaced ObjectClass "%s": %s',
|
self.error('replace: cannot parse replaced %s "%s": %s',
|
||||||
old, e)
|
schema_elem_name, old, e)
|
||||||
continue
|
continue
|
||||||
replaced_values = []
|
replaced_values = []
|
||||||
for objectclass in oid_index.get(objectclass_old.oid, []):
|
for schema_elem in oid_index.get(schema_elem_old.oid, []):
|
||||||
objectclass_object = ObjectClass(str(objectclass))
|
schema_elem_object = schema_elem_class(str(schema_elem))
|
||||||
if str(objectclass_old).lower() == str(objectclass_object).lower():
|
if str(schema_elem_old).lower() == str(schema_elem_object).lower():
|
||||||
# compare normalized values
|
# compare normalized values
|
||||||
replaced_values.append(objectclass)
|
replaced_values.append(schema_elem)
|
||||||
self.debug('replace: replace ObjectClass "%s" with "%s"',
|
self.debug('replace: replace %s "%s" with "%s"',
|
||||||
old, new)
|
schema_elem_name, old, new)
|
||||||
if not replaced_values:
|
if not replaced_values:
|
||||||
self.debug('replace: no match for replaced ObjectClass "%s"', old)
|
self.debug('replace: no match for replaced %s "%s"',
|
||||||
|
schema_elem_name, old)
|
||||||
continue
|
continue
|
||||||
for value in replaced_values:
|
for value in replaced_values:
|
||||||
entry_values.remove(value)
|
entry_values.remove(value)
|
||||||
|
|||||||
Reference in new issue
Block a user