View | Details | Raw Unified | Return to bug 41207 | Differences between
and this patch

Collapse All | Expand All

(-)a/branches/ucs-4.1/ucs-4.1-2/management/univention-directory-manager-modules/modules/univention/admin/handlers/__init__.py (-32 / +40 lines)
 Lines 815-856   class simpleLdap(base): Link Here 
815
		ocs -= set(chain.from_iterable(m.options[option].objectClasses for option in removed_options))
815
		ocs -= set(chain.from_iterable(m.options[option].objectClasses for option in removed_options))
816
		ocs |= set(chain.from_iterable(m.options[option].objectClasses for option in added_options))
816
		ocs |= set(chain.from_iterable(m.options[option].objectClasses for option in added_options))
817
		if set(self.oldattr.get('objectClass', [])) != ocs:
817
		if set(self.oldattr.get('objectClass', [])) != ocs:
818
			ml = [x for x in ml if x[0].lower() != 'objectClass'.lower()]
818
			ml = [x for x in ml if x[0].lower() != 'objectclass']
819
			ml.append(('objectClass', self.oldattr.get('objectClass', []), list(ocs)))
819
			ml.append(('objectClass', self.oldattr.get('objectClass', []), list(ocs)))
820
		elif not object_classes_to_remove:
821
			return ml
822
823
		# parse LDAP schema
824
		schema = self.lo.get_schema()
825
		newattr = ldap.cidict.cidict(_MergedAttributes(self, ml).get_attributes())
826
		ocs_afterwards = ocs - object_classes_to_remove
827
828
		# make sure we still have a structural object class
829
		if not schema.get_structural_oc(ocs_afterwards):
830
			structural_ocs = schema.get_structural_oc(object_classes_to_remove)
831
			if structural_ocs:
832
				univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'Preventing to remove last structural object class %r' % (structural_ocs,))
833
				object_classes_to_remove -= set(schema.get_obj(ldap.schema.models.ObjectClass, structural_ocs).names)
834
				ocs_afterwards = ocs - object_classes_to_remove
835
			else:
836
				univention.debug.debug(univention.debug.ADMIN, univention.debug.ERROR, 'missing structural object class. Modify will fail.')
837
				return ml
820
838
821
		if object_classes_to_remove or set(self.oldattr.get('objectClass', [])) != ocs:
839
		# validate removal of object classes
822
			# parse LDAP schema
840
		must, may = schema.attribute_types(ocs_afterwards)
823
			schema = self.lo.get_schema()
841
		allowed = set(name.lower() for attr in may.values() for name in attr.names) | set(name.lower() for attr in must.values() for name in attr.names)
824
			newattr = ldap.cidict.cidict(_MergedAttributes(self, ml).get_attributes())
842
825
			ocs_afterwards = set(newattr.get('objectClass', [])) - object_classes_to_remove
843
		for attr, val in newattr.items():
826
844
			if not val:
827
			# make sure we still have a structural object class
845
				continue
828
			if not schema.get_structural_oc(ocs_afterwards):
846
			if attr.lower() not in allowed:
829
				structural_ocs = schema.get_structural_oc(object_classes_to_remove)
847
				univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'The attribute %r is not allowed by any object class.' % (attr,))
830
				if structural_ocs:
848
				# ml.append((attr, val, [])) # TODO: Remove the now invalid attribute instead
831
					univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'Preventing to remove last structural object class %r' % (structural_ocs,))
849
				return ml
832
					object_classes_to_remove -= set(schema.get_obj(ldap.schema.models.ObjectClass, structural_ocs).names)
850
833
					ocs_afterwards = set(newattr.get('objectClass', [])) - object_classes_to_remove
851
		for attr in must.values():
834
				else:
852
			for name in attr.names:
835
					univention.debug.debug(univention.debug.ADMIN, univention.debug.ERROR, 'missing structural object class. Modify will fail.')
853
				if newattr.get(name):
836
837
			# validate removal of object classes
838
			must, may = schema.attribute_types(ocs_afterwards)
839
			must = ldap.cidict.cidict(dict((x, x) for x in list(chain.from_iterable(x.names for x in must.values()))))
840
			may = ldap.cidict.cidict(dict((x, x) for x in list(chain.from_iterable(x.names for x in may.values()))))
841
			for attr in must.keys():
842
				if not newattr.get(attr):
843
					univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'The attribute %r is required by the current object classes.' % (attr,))
844
					break
854
					break
845
			else:
855
			else:
846
				for attr, val in newattr.items():
856
				univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'The attribute %r is required by the current object classes.' % (attr.names,))
847
					if val and not must.get(attr) and not may.get(attr):
857
				return ml
848
						univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'The attribute %r is not allowed by any object class.' % (attr,))
858
849
						# ml.append((attr, val, [])) # TODO: Remove the now invalid attribute instead
859
		ml = [x for x in ml if x[0].lower() != 'objectclass']
850
						break
860
		ml.append(('objectClass', self.oldattr.get('objectClass', []), list(ocs_afterwards)))
851
				else:
861
852
					ml = [x for x in ml if x[0].lower() != 'objectclass']
853
					ml.append(('objectClass', self.oldattr.get('objectClass', []), list(ocs - object_classes_to_remove)))
854
		return ml
862
		return ml
855
863
856
	def _move_in_subordinates(self, olddn):
864
	def _move_in_subordinates(self, olddn):

Return to bug 41207