[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Tue Apr 10 22:32:02 MDT 2012


The branch, master has been updated
       via  0c44d46 s4:dsdb/samdb/ldb_modules/schema.c - move "get_last_structural_class()" into "util.c"
       via  8306212 s4:dsdb/samdb/ldb_modules/schema.c - inline "get_oc_guid_from_message()" to its only user
       via  3fa5f84 s4:dsdb - introduce a only constant-time "get_last_structural_class()" call
       via  ba96b24 s4:dsdb/samdb/ldb_modules/schema.c - inline "acl_check_access_on_class" to its only user
       via  4eb0d42 s4:dsdb - move "objectclass_sort()" out from the objectclass LDB module into the schema code
       via  1777518 s4:acl LDB module - remove set but unused variables
       via  93f0905 s4:objectclass LDB module - remove unneeded build dependencies
       via  55f4275 LDB:ldb_msg.c - add another OOM check in "ldb_msg_copy()"
       via  3d886e3 s4:schema/schema_query.c - fix a comment
       via  35dfd79 s4:schema/schema_init.c - better use "ldb_attr_cmp" instead of "strcasecmp"
       via  0c2c5f2 s4:dsdb/pydsdb.c - fix indentation
      from  47e7013 on our way with Samba 4.0alpha20

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 0c44d46f24ef69598eaef281bcb82f943655d0bc
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Wed Apr 4 22:24:16 2012 +0200

    s4:dsdb/samdb/ldb_modules/schema.c - move "get_last_structural_class()" into "util.c"
    
    And remove this helper module - it does not have much sense keeping it.
    
    Autobuild-User: Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date: Wed Apr 11 06:31:51 CEST 2012 on sn-devel-104

commit 83062125e60dd097a1a151fb35467fe55a356780
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Wed Apr 4 21:58:04 2012 +0200

    s4:dsdb/samdb/ldb_modules/schema.c - inline "get_oc_guid_from_message()" to its only user
    
    Reduce the number of not to be shared functions in "schema.c". Change it
    to make use of "get_last_structural_class()".

commit 3fa5f84d2f7bdd3747ea14453fc49eb6931eeedf
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Wed Apr 4 18:55:40 2012 +0200

    s4:dsdb - introduce a only constant-time "get_last_structural_class()" call
    
    With the redesign of the previous patches this has become possible.

commit ba96b2491e106dd9035d3b3b1f95cb81412e0847
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Wed Apr 4 12:29:58 2012 +0200

    s4:dsdb/samdb/ldb_modules/schema.c - inline "acl_check_access_on_class" to its only user
    
    Reduce the number of not to be shared functions in "schema.c".

commit 4eb0d42291c61a01be3f2fa57d35872967257d9f
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Wed Apr 4 18:40:00 2012 +0200

    s4:dsdb - move "objectclass_sort()" out from the objectclass LDB module into the schema code
    
    This allows it to be useful for the dbchecker utility in respect to
    object class problems.
    Fix up the API to only work with standardised LDB "ldb_message_element"
    structures which do allow much easier interoperations. As a consequence this
    leads to some changes in the objectclass module as well.

commit 17775186df7893345e99d6577eb2a6be444e8b71
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Wed Apr 4 20:27:30 2012 +0200

    s4:acl LDB module - remove set but unused variables

commit 93f0905f073c63d51eb26b0d296ba4295ed4f5b6
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Wed Apr 4 18:48:23 2012 +0200

    s4:objectclass LDB module - remove unneeded build dependencies

commit 55f4275f18088838ec2b8a37d59a49368e90deb8
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Wed Apr 4 16:05:50 2012 +0200

    LDB:ldb_msg.c - add another OOM check in "ldb_msg_copy()"

commit 3d886e3e151c792685431385c9ea68e27a1d52b1
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Thu Apr 5 21:55:07 2012 +0200

    s4:schema/schema_query.c - fix a comment

commit 35dfd79dcafdadcc61818975bd0719605d95cf95
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Thu Apr 5 21:38:14 2012 +0200

    s4:schema/schema_init.c - better use "ldb_attr_cmp" instead of "strcasecmp"
    
    LDB convention

commit 0c2c5f24a91e365f913dbc1d369341a366ba1e17
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Wed Apr 4 12:14:12 2012 +0200

    s4:dsdb/pydsdb.c - fix indentation

-----------------------------------------------------------------------

Summary of changes:
 lib/ldb/common/ldb_msg.c                     |    1 +
 source4/dsdb/pydsdb.c                        |    2 +-
 source4/dsdb/samdb/ldb_modules/acl.c         |   79 +++++++-
 source4/dsdb/samdb/ldb_modules/descriptor.c  |    9 +-
 source4/dsdb/samdb/ldb_modules/objectclass.c |  265 ++++----------------------
 source4/dsdb/samdb/ldb_modules/schema.c      |  137 -------------
 source4/dsdb/samdb/ldb_modules/util.c        |   30 +++
 source4/dsdb/samdb/ldb_modules/wscript_build |   16 +-
 source4/dsdb/schema/schema_init.c            |    2 +-
 source4/dsdb/schema/schema_query.c           |  166 ++++++++++++++++-
 10 files changed, 318 insertions(+), 389 deletions(-)
 delete mode 100644 source4/dsdb/samdb/ldb_modules/schema.c


Changeset truncated at 500 lines:

diff --git a/lib/ldb/common/ldb_msg.c b/lib/ldb/common/ldb_msg.c
index 1a2bebc..c17e5f3 100644
--- a/lib/ldb/common/ldb_msg.c
+++ b/lib/ldb/common/ldb_msg.c
@@ -652,6 +652,7 @@ struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx,
 		el->name = talloc_strdup(msg2->elements, el->name);
 		if (el->name == NULL) goto failed;
 		el->values = talloc_array(msg2->elements, struct ldb_val, el->num_values);
+		if (el->values == NULL) goto failed;
 		for (j=0;j<el->num_values;j++) {
 			el->values[j] = ldb_val_dup(el->values, &values[j]);
 			if (el->values[j].data == NULL && values[j].length != 0) {
diff --git a/source4/dsdb/pydsdb.c b/source4/dsdb/pydsdb.c
index 616e169..762a03d 100644
--- a/source4/dsdb/pydsdb.c
+++ b/source4/dsdb/pydsdb.c
@@ -96,7 +96,7 @@ static PyObject *py_samdb_server_site_name(PyObject *self, PyObject *args)
 }
 
 static PyObject *py_dsdb_convert_schema_to_openldap(PyObject *self,
-													PyObject *args)
+						    PyObject *args)
 {
 	char *target_str, *mapping;
 	PyObject *py_ldb;
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
index 6aed682..843d17e 100644
--- a/source4/dsdb/samdb/ldb_modules/acl.c
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
@@ -39,7 +39,6 @@
 #include "librpc/gen_ndr/ndr_security.h"
 #include "param/param.h"
 #include "dsdb/samdb/ldb_modules/util.h"
-#include "dsdb/samdb/ldb_modules/schema.h"
 #include "lib/util/tsort.h"
 #include "system/kerberos.h"
 #include "auth/kerberos/kerberos.h"
@@ -287,6 +286,52 @@ static int acl_childClasses(struct ldb_module *module,
 	return LDB_SUCCESS;
 }
 
+static int acl_check_access_on_class(struct ldb_module *module,
+				     const struct dsdb_schema *schema,
+				     TALLOC_CTX *mem_ctx,
+				     struct security_descriptor *sd,
+				     struct security_token *token,
+				     struct dom_sid *rp_sid,
+				     uint32_t access_mask,
+				     const char *class_name)
+{
+	int ret;
+	NTSTATUS status;
+	uint32_t access_granted;
+	struct object_tree *root = NULL;
+	struct object_tree *new_node = NULL;
+	const struct GUID *guid;
+
+	if (class_name != NULL) {
+		guid = class_schemaid_guid_by_lDAPDisplayName(schema, class_name);
+		if (!guid) {
+			DEBUG(10, ("acl_search: cannot find class %s\n",
+				   class_name));
+			goto fail;
+		}
+		if (!insert_in_object_tree(mem_ctx,
+					   guid, access_mask,
+					   &root, &new_node)) {
+			DEBUG(10, ("acl_search: cannot add to object tree guid\n"));
+			goto fail;
+		}
+	}
+
+	status = sec_access_check_ds(sd, token,
+				     access_mask,
+				     &access_granted,
+				     root,
+				     rp_sid);
+	if (!NT_STATUS_IS_OK(status)) {
+		ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
+	} else {
+		ret = LDB_SUCCESS;
+	}
+	return ret;
+fail:
+	return ldb_operr(ldb_module_get_ctx(module));
+}
+
 static int acl_childClassesEffective(struct ldb_module *module,
 				     const struct dsdb_schema *schema,
 				     struct ldb_message *sd_msg,
@@ -339,6 +384,7 @@ static int acl_childClassesEffective(struct ldb_module *module,
 							schema,
 							msg,
 							sd,
+							acl_user_token(module),
 							sid,
 							SEC_ADS_CREATE_CHILD,
 							sclass->possibleInferiors[j]);
@@ -449,7 +495,6 @@ static int acl_validate_spn_value(TALLOC_CTX *mem_ctx,
 	char *instanceName;
 	char *serviceType;
 	char *serviceName;
-	const char *realm;
 	const char *forest_name = samdb_forest_name(ldb, mem_ctx);
 	const char *base_domain = samdb_default_domain_name(ldb, mem_ctx);
 	struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
@@ -483,7 +528,6 @@ static int acl_validate_spn_value(TALLOC_CTX *mem_ctx,
 
 	instanceName = principal->name.name_string.val[1];
 	serviceType = principal->name.name_string.val[0];
-	realm = krb5_principal_get_realm(krb_ctx, principal);
 	if (principal->name.name_string.len == 3) {
 		serviceName = principal->name.name_string.val[2];
 	} else {
@@ -863,6 +907,26 @@ static int acl_check_password_rights(TALLOC_CTX *mem_ctx,
 	return ret;
 }
 
+static const struct GUID *get_oc_guid_from_message(const struct dsdb_schema *schema,
+						   struct ldb_message *msg)
+{
+	struct ldb_message_element *oc_el;
+	const struct dsdb_class *object_class;
+
+	oc_el = ldb_msg_find_element(msg, "objectClass");
+	if (!oc_el) {
+		return NULL;
+	}
+
+	object_class = dsdb_get_last_structural_class(schema, oc_el);
+	if (object_class == NULL) {
+		return NULL;
+	}
+
+	return &object_class->schemaIDGUID;
+}
+
+
 static int acl_modify(struct ldb_module *module, struct ldb_request *req)
 {
 	int ret;
@@ -928,7 +992,7 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req)
 		goto success;
 	}
 
-	guid = get_oc_guid_from_message(module, schema, acl_res->msgs[0]);
+	guid = get_oc_guid_from_message(schema, acl_res->msgs[0]);
 	if (!guid) {
 		talloc_free(tmp_ctx);
 		return ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR,
@@ -1202,7 +1266,7 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req)
 		return ldb_operr(ldb);
 	}
 
-	guid = get_oc_guid_from_message(module, schema, acl_res->msgs[0]);
+	guid = get_oc_guid_from_message(schema, acl_res->msgs[0]);
 	if (!insert_in_object_tree(tmp_ctx, guid, SEC_ADS_WRITE_PROP,
 				   &root, &new_node)) {
 		talloc_free(tmp_ctx);
@@ -1270,7 +1334,7 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req)
 	/* new parent should have create child */
 	root = NULL;
 	new_node = NULL;
-	guid = get_oc_guid_from_message(module, schema, acl_res->msgs[0]);
+	guid = get_oc_guid_from_message(schema, acl_res->msgs[0]);
 	if (!guid) {
 		ldb_asprintf_errstring(ldb_module_get_ctx(module),
 				       "acl:renamed object has no object class\n");
@@ -1314,7 +1378,6 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req)
 
 static int acl_search_callback(struct ldb_request *req, struct ldb_reply *ares)
 {
-	struct ldb_context *ldb;
 	struct acl_context *ac;
 	struct acl_private *data;
 	struct ldb_result *acl_res;
@@ -1329,8 +1392,6 @@ static int acl_search_callback(struct ldb_request *req, struct ldb_reply *ares)
 
 	ac = talloc_get_type(req->context, struct acl_context);
 	data = talloc_get_type(ldb_module_get_private(ac->module), struct acl_private);
-	ldb = ldb_module_get_ctx(ac->module);
-
 	if (!ares) {
 		return ldb_module_done(ac->req, NULL, NULL,
 				       LDB_ERR_OPERATIONS_ERROR);
diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c
index f2afe74..18245a0 100644
--- a/source4/dsdb/samdb/ldb_modules/descriptor.c
+++ b/source4/dsdb/samdb/ldb_modules/descriptor.c
@@ -39,7 +39,6 @@
 #include "librpc/ndr/libndr.h"
 #include "librpc/gen_ndr/ndr_security.h"
 #include "libcli/security/security.h"
-#include "dsdb/samdb/ldb_modules/schema.h"
 #include "auth/auth.h"
 #include "param/param.h"
 #include "dsdb/samdb/ldb_modules/util.h"
@@ -542,8 +541,8 @@ static int descriptor_add(struct ldb_module *module, struct ldb_request *req)
 		return ldb_operr(ldb);
 	}
 
-	objectclass = get_last_structural_class(schema, objectclass_element,
-						true);
+	objectclass = dsdb_get_last_structural_class(schema,
+						     objectclass_element);
 	if (objectclass == NULL) {
 		return ldb_operr(ldb);
 	}
@@ -661,8 +660,8 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req)
 		return ldb_operr(ldb);
 	}
 
-	objectclass = get_last_structural_class(schema, objectclass_element,
-						true);
+	objectclass = dsdb_get_last_structural_class(schema,
+						     objectclass_element);
 	if (objectclass == NULL) {
 		return ldb_operr(ldb);
 	}
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index 0d75e5f..d431367 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -37,7 +37,6 @@
 
 #include "includes.h"
 #include "ldb_module.h"
-#include "util/dlinklist.h"
 #include "dsdb/samdb/samdb.h"
 #include "librpc/ndr/libndr.h"
 #include "librpc/gen_ndr/ndr_security.h"
@@ -45,7 +44,6 @@
 #include "auth/auth.h"
 #include "param/param.h"
 #include "../libds/common/flags.h"
-#include "dsdb/samdb/ldb_modules/schema.h"
 #include "dsdb/samdb/ldb_modules/util.h"
 
 struct oc_context {
@@ -60,11 +58,6 @@ struct oc_context {
 	int (*step_fn)(struct oc_context *);
 };
 
-struct class_list {
-	struct class_list *prev, *next;
-	const struct dsdb_class *objectclass;
-};
-
 static struct oc_context *oc_init_context(struct ldb_module *module,
 					  struct ldb_request *req)
 {
@@ -88,140 +81,6 @@ static struct oc_context *oc_init_context(struct ldb_module *module,
 
 static int objectclass_do_add(struct oc_context *ac);
 
-/* Sort objectClasses into correct order, and validate that all
- * objectClasses specified actually exist in the schema
- */
-
-static int objectclass_sort(struct ldb_module *module,
-			    const struct dsdb_schema *schema,
-			    TALLOC_CTX *mem_ctx,
-			    struct ldb_message_element *objectclass_element,
-			    struct class_list **sorted_out) 
-{
-	struct ldb_context *ldb;
-	unsigned int i, lowest;
-	struct class_list *unsorted = NULL, *sorted = NULL, *current = NULL,
-			  *poss_parent = NULL, *new_parent = NULL,
-			  *current_lowest = NULL, *current_lowest_struct = NULL;
-
-	ldb = ldb_module_get_ctx(module);
-
-	/* DESIGN:
-	 *
-	 * We work on 4 different 'bins' (implemented here as linked lists):
-	 *
-	 * * sorted:       the eventual list, in the order we wish to push
-	 *                 into the database.  This is the only ordered list.
-	 *
-	 * * parent_class: The current parent class 'bin' we are
-	 *                 trying to find subclasses for
-	 *
-	 * * subclass:     The subclasses we have found so far
-	 *
-	 * * unsorted:     The remaining objectClasses
-	 *
-	 * The process is a matter of filtering objectClasses up from
-	 * unsorted into sorted.  Order is irrelevent in the later 3 'bins'.
-	 * 
-	 * We start with 'top' (found and promoted to parent_class
-	 * initially).  Then we find (in unsorted) all the direct
-	 * subclasses of 'top'.  parent_classes is concatenated onto
-	 * the end of 'sorted', and subclass becomes the list in
-	 * parent_class.
-	 *
-	 * We then repeat, until we find no more subclasses.  Any left
-	 * over classes are added to the end.
-	 *
-	 */
-
-	/* Firstly, dump all the objectClass elements into the
-	 * unsorted bin, except for 'top', which is special */
-	for (i=0; i < objectclass_element->num_values; i++) {
-		current = talloc(mem_ctx, struct class_list);
-		if (!current) {
-			return ldb_oom(ldb);
-		}
-		current->objectclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &objectclass_element->values[i]);
-		if (!current->objectclass) {
-			ldb_asprintf_errstring(ldb, "objectclass %.*s is not a valid objectClass in schema", 
-					       (int)objectclass_element->values[i].length, (const char *)objectclass_element->values[i].data);
-			/* This looks weird, but windows apparently returns this for invalid objectClass values */
-			return LDB_ERR_NO_SUCH_ATTRIBUTE;
-		} else if (current->objectclass->isDefunct) {
-			ldb_asprintf_errstring(ldb, "objectclass %.*s marked as isDefunct objectClass in schema - not valid for new objects", 
-					       (int)objectclass_element->values[i].length, (const char *)objectclass_element->values[i].data);
-			/* This looks weird, but windows apparently returns this for invalid objectClass values */
-			return LDB_ERR_NO_SUCH_ATTRIBUTE;
-		}
-
-		/* Don't add top to list, we will do that later */
-		if (ldb_attr_cmp("top", current->objectclass->lDAPDisplayName) != 0) {
-			DLIST_ADD_END(unsorted, current, struct class_list *);
-		}
-	}
-
-	/* Add top here, to prevent duplicates */
-	current = talloc(mem_ctx, struct class_list);
-	current->objectclass = dsdb_class_by_lDAPDisplayName(schema, "top");
-	DLIST_ADD_END(sorted, current, struct class_list *);
-
-	/* If we don't have a schema yet, then just merge the lists again */
-	if (!schema) {
-		DLIST_CONCATENATE(sorted, unsorted, struct class_list *);
-		*sorted_out = sorted;
-		return LDB_SUCCESS;
-	}
-
-	/* For each object:  find parent chain */
-	for (current = unsorted; current != NULL; current = current->next) {
-		for (poss_parent = unsorted; poss_parent; poss_parent = poss_parent->next) {
-			if (ldb_attr_cmp(poss_parent->objectclass->lDAPDisplayName, current->objectclass->subClassOf) == 0) {
-				break;
-			}
-		}
-		/* If we didn't get to the end of the list, we need to add this parent */
-		if (poss_parent || (ldb_attr_cmp("top", current->objectclass->subClassOf) == 0)) {
-			continue;
-		}
-
-		new_parent = talloc(mem_ctx, struct class_list);
-		new_parent->objectclass = dsdb_class_by_lDAPDisplayName(schema, current->objectclass->subClassOf);
-		DLIST_ADD_END(unsorted, new_parent, struct class_list *);
-	}
-
-	/* For each object: order by hierarchy */
-	while (unsorted != NULL) {
-		lowest = UINT_MAX;
-		current_lowest = current_lowest_struct = NULL;
-		for (current = unsorted; current != NULL; current = current->next) {
-			if (current->objectclass->subClass_order <= lowest) {
-				/*
-				 * According to MS-ADTS 3.1.1.1.4 structural
-				 * and 88 object classes are always listed after
-				 * the other class types in a subclass hierarchy
-				 */
-				if (current->objectclass->objectClassCategory > 1) {
-					current_lowest = current;
-				} else {
-					current_lowest_struct = current;
-				}
-				lowest = current->objectclass->subClass_order;
-			}
-		}
-		if (current_lowest == NULL) {
-			current_lowest = current_lowest_struct;
-		}
-
-		if (current_lowest != NULL) {
-			DLIST_REMOVE(unsorted,current_lowest);
-			DLIST_ADD_END(sorted,current_lowest, struct class_list *);
-		}
-	}
-
-	*sorted_out = sorted;
-	return LDB_SUCCESS;
-}
-
 /*
  * This checks if we have unrelated object classes in our entry's "objectClass"
  * attribute. That means "unsatisfied" abstract classes (no concrete subclass)
@@ -525,7 +384,6 @@ static int objectclass_do_add(struct oc_context *ac)
 	struct ldb_message_element *objectclass_element, *el;
 	struct ldb_message *msg;
 	TALLOC_CTX *mem_ctx;
-	struct class_list *sorted, *current;
 	const char *rdn_name = NULL;
 	char *value;
 	const struct dsdb_class *objectclass;
@@ -572,6 +430,12 @@ static int objectclass_do_add(struct oc_context *ac)
 	}
 
 	if (ac->schema != NULL) {
+		/*
+		 * Notice: by the normalization function call in "ldb_request()"
+		 * case "LDB_ADD" we have always only *one* "objectClass"
+		 * attribute at this stage!
+		 */
+
 		objectclass_element = ldb_msg_find_element(msg, "objectClass");
 		if (!objectclass_element) {
 			ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, no objectclass specified!",
@@ -589,57 +453,24 @@ static int objectclass_do_add(struct oc_context *ac)
 			return ldb_module_oom(ac->module);
 		}
 
-		/* Here we do now get the "objectClass" list from the
-		 * database. */
-		ret = objectclass_sort(ac->module, ac->schema, mem_ctx,
-				       objectclass_element, &sorted);
-		if (ret != LDB_SUCCESS) {
-			talloc_free(mem_ctx);
-			return ret;
-		}
-		
-		ldb_msg_remove_element(msg, objectclass_element);
-
-		/* Well, now we shouldn't find any additional "objectClass"
-		 * message element (required by the AD specification). */
-		objectclass_element = ldb_msg_find_element(msg, "objectClass");
-		if (objectclass_element != NULL) {
-			ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, only one 'objectclass' attribute specification is allowed!",
-					       ldb_dn_get_linearized(msg->dn));
-			talloc_free(mem_ctx);
-			return LDB_ERR_OBJECT_CLASS_VIOLATION;
-		}
-
-		/* We must completely replace the existing objectClass entry,
-		 * because we need it sorted. */
-		ret = ldb_msg_add_empty(msg, "objectClass", 0,
-					&objectclass_element);
+		/* Now do the sorting */
+		ret = dsdb_sort_objectClass_attr(ldb, ac->schema, mem_ctx,
+						 objectclass_element, msg,
+						 objectclass_element);
 		if (ret != LDB_SUCCESS) {
 			talloc_free(mem_ctx);
 			return ret;
 		}
 
-		/* Move from the linked list back into an ldb msg */
-		for (current = sorted; current; current = current->next) {
-			const char *objectclass_name = current->objectclass->lDAPDisplayName;
-
-			ret = ldb_msg_add_string(msg, "objectClass", objectclass_name);
-			if (ret != LDB_SUCCESS) {
-				ldb_set_errstring(ldb,
-						  "objectclass: could not re-add sorted "
-						  "objectclass to modify msg");
-				talloc_free(mem_ctx);
-				return ret;
-			}
-		}
-
 		talloc_free(mem_ctx);
 
-		/* Make sure its valid to add an object of this type */
-		objectclass = get_last_structural_class(ac->schema,
-							objectclass_element,
-							true);
-		if(objectclass == NULL) {
+		/*
+		 * Get the new top-most structural object class and check for
+		 * unrelated structural classes
+		 */
+		objectclass = dsdb_get_last_structural_class(ac->schema,
+							     objectclass_element);
+		if (objectclass == NULL) {
 			ldb_asprintf_errstring(ldb,
 					       "Failed to find a structural class for %s",
 					       ldb_dn_get_linearized(msg->dn));
@@ -993,7 +824,6 @@ static int objectclass_do_mod(struct oc_context *ac)
 	struct ldb_val *vals;
 	struct ldb_message *msg;
 	TALLOC_CTX *mem_ctx;
-	struct class_list *sorted, *current;
 	const struct dsdb_class *objectclass;
 	unsigned int i, j, k;
 	bool found;
@@ -1111,9 +941,20 @@ static int objectclass_do_mod(struct oc_context *ac)
 			break;
 		}
 
-		/* Get the new top-most structural object class */
-		objectclass = get_last_structural_class(ac->schema, oc_el_entry,
-							false);
+		/* Now do the sorting */
+		ret = dsdb_sort_objectClass_attr(ldb, ac->schema, mem_ctx,
+						 oc_el_entry, msg, oc_el_entry);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list