The branch, master has been updated via aa32725... s4:ldap.py - add some "objectclass" behaviour tests via e3c686d... s4:objectclass LDB module - rework the code which handles the objectclasses modification via 17f465a... s4:ldap.py - enhance the attributes testcase to demonstrate how the attributes are checked against the schema and the specified objectclasses via ee278bf... s4:acl LDB module - LDB attribute names should be compared using "ldb_attr_cmp" or "strcasecmp" via 566d13c... s4:acl LDB module - adaption for "objectclass_attrs" module via e7eef53... s4:objectclass LDB module - remove "fix_check_attributes" via 227144e... s4:samldb LDB module - adjust the module to set always a "defaultObjectCategory" on objectclass add operations via bd91095... s4:remove the "validate_update" LDB module - the task is now handled by the far more complete "objectclass_attrs" LDB module via 2586cba... s4:dsdb - introduce a new "objectclass_attrs" LDB module which performs the objectclass attributes checking via 9e56b54... s4:objectclass LDB module - instanciate the schema variable centrally on the "ac" context creation via da90868... s4:samldb LDB module - finally we can remove the RDN check via 9ab3365... s4:ldap.py - enhance the rename tests to demonstrate the functionality via ec9b6f3... s4:objectclass LDB module - finally implement the correct entry rename protections via 0ca17ea... s4:objectclass LDB module - cosmetic change via c6020cc... s4:objectclass LDB module - remove duplicated code via 95da724... s4:objectclass LDB module - fix counter variable types via 0408ec1... s4:objectclass LDB module - explain why the search can return with an empty return via 6afa5a7... s4:objectclass LDB module - this "talloc_steal" is not necessary via 2d3760c... s4:objectclass LDB module - fix error result if an entry doesn't contain a structural objectclass via 2a294d3... s4:objectclass LDB module - use "ldb_oom" for expressing out of memory via 3c4336b... s4:objectclass LDB module - fix header and add my copyright from 04c7484... s3-waf: Build rpc_server/srv_spoolss_util.c too.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit aa3272588662f1389138a177a4c6644668c052fa Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Thu Jun 3 20:58:43 2010 +0200 s4:ldap.py - add some "objectclass" behaviour tests commit e3c686daec130fb3c4a7457943173f31851a8e7d Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Sat Jun 5 23:02:25 2010 +0200 s4:objectclass LDB module - rework the code which handles the objectclasses modification Before it has been very incomplete. We try now to match the Windows Server behaviour as close as possible. commit 17f465a4ac5562bec1b40dc97ac414fb3920175b Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Sun Jun 6 23:09:28 2010 +0200 s4:ldap.py - enhance the attributes testcase to demonstrate how the attributes are checked against the schema and the specified objectclasses This demonstrates the bew "objectclass_attrs" LDB module behaviour. commit ee278bf0c48dbc8b7afc37762ad4f305014a2e2c Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Sun Jun 6 19:06:58 2010 +0200 s4:acl LDB module - LDB attribute names should be compared using "ldb_attr_cmp" or "strcasecmp" commit 566d13c5d11ae832285c09f74d25ffdcf0397735 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Sat Jun 5 20:19:31 2010 +0200 s4:acl LDB module - adaption for "objectclass_attrs" module Since the attribute schema checking code moved back we need to give here the "LDB_ERR_NO_SUCH_ATTRIBUTE" error. commit e7eef53fe543c940f7a792b16d037fed8d7743ec Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Sat Jun 5 19:11:25 2010 +0200 s4:objectclass LDB module - remove "fix_check_attributes" Also this task is now performed by the "objectclass_attrs" LDB module. commit 227144e0503504d4c716af4a4e92dc6397c705de Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Sun Jun 6 19:53:33 2010 +0200 s4:samldb LDB module - adjust the module to set always a "defaultObjectCategory" on objectclass add operations This is needed to make the "objectclass_attrs" LDB module happy. The search check and case adjustment are done as it was using a second modify operation. commit bd910952ba2256ff54c0e48a6feda285b9fbb8a5 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Sat Jun 5 19:09:51 2010 +0200 s4:remove the "validate_update" LDB module - the task is now handled by the far more complete "objectclass_attrs" LDB module commit 2586cbaadcdf9baf77be5ec5b612cff324ab19a8 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Sat Jun 5 17:34:35 2010 +0200 s4:dsdb - introduce a new "objectclass_attrs" LDB module which performs the objectclass attributes checking Until now we had no real consistent mechanism which allowed us to check if attributes belong to the specified objectclasses. commit 9e56b54414ce9f62edbd8f87c09885dbb4b3ccea Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Thu Jun 3 19:17:16 2010 +0200 s4:objectclass LDB module - instanciate the schema variable centrally on the "ac" context creation This unifies the position when the schema is read and prevents multiple instanciations (eg on a modification operation). commit da90868907c7dc7f9894dc06bd49df701ff442eb Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Wed Jun 2 22:13:03 2010 +0200 s4:samldb LDB module - finally we can remove the RDN check This is now dynamically always done by the objectclass LDB module commit 9ab3365fa5a37257d818c414925264a336eb103c Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Wed Jun 2 22:06:39 2010 +0200 s4:ldap.py - enhance the rename tests to demonstrate the functionality commit ec9b6f3c608f61d694f2defe816b55bdc6d169ea Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Wed Jun 2 21:55:08 2010 +0200 s4:objectclass LDB module - finally implement the correct entry rename protections Only the "systemFlags" check is still missing. commit 0ca17eaa15641708acf182b9ed1cb33222b05617 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Wed Jun 2 21:43:55 2010 +0200 s4:objectclass LDB module - cosmetic change commit c6020ccb87337b9045c51674d4d01c19f43fd288 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Wed Jun 2 21:42:06 2010 +0200 s4:objectclass LDB module - remove duplicated code commit 95da72432560c042400faccb7f16d9ab9cd38df1 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Wed Jun 2 21:24:49 2010 +0200 s4:objectclass LDB module - fix counter variable types commit 0408ec11a9503a6e523651cc078334158c8c6f53 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Wed Jun 2 21:23:34 2010 +0200 s4:objectclass LDB module - explain why the search can return with an empty return commit 6afa5a733c3ab12fd03e6980898e21f8d112bc3b Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Wed Jun 2 19:44:22 2010 +0200 s4:objectclass LDB module - this "talloc_steal" is not necessary The "parent_dn" was created on the "ac" context which lives anyway longer than this child request. commit 2d3760c04cd4a17a8c85196a0a7c4275e3b7050c Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Fri Jun 4 20:48:52 2010 +0200 s4:objectclass LDB module - fix error result if an entry doesn't contain a structural objectclass We need to return LDB_ERR_UNWILLING_TO_PERFORM (not LDB_ERR_NAMING_VIOLATION). commit 2a294d380f13edad6fcdd3572336ba797baaa0e1 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Sat Jun 5 13:06:54 2010 +0200 s4:objectclass LDB module - use "ldb_oom" for expressing out of memory commit 3c4336bf949a47084ebcb068b2b9223eba4137e3 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Wed Jun 2 22:42:59 2010 +0200 s4:objectclass LDB module - fix header and add my copyright ----------------------------------------------------------------------- Summary of changes: source4/dsdb/samdb/ldb_modules/acl.c | 24 +- source4/dsdb/samdb/ldb_modules/objectclass.c | 624 +++++++++++--------- source4/dsdb/samdb/ldb_modules/objectclass_attrs.c | 392 ++++++++++++ source4/dsdb/samdb/ldb_modules/samba_dsdb.c | 2 +- source4/dsdb/samdb/ldb_modules/samldb.c | 133 ++--- source4/dsdb/samdb/ldb_modules/validate_update.c | 120 ---- source4/dsdb/samdb/ldb_modules/wscript_build | 15 +- source4/dsdb/schema/schema_syntax.c | 13 - source4/lib/ldb/tests/python/ldap.py | 304 ++++++++++- 9 files changed, 1116 insertions(+), 511 deletions(-) create mode 100644 source4/dsdb/samdb/ldb_modules/objectclass_attrs.c delete mode 100644 source4/dsdb/samdb/ldb_modules/validate_update.c Changeset truncated at 500 lines: diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c index 1b84e8a..ccc7edf 100644 --- a/source4/dsdb/samdb/ldb_modules/acl.c +++ b/source4/dsdb/samdb/ldb_modules/acl.c @@ -730,21 +730,31 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) for (i=0; i < req->op.mod.message->num_elements; i++){ const struct dsdb_attribute *attr; /* clearTextPassword is not in schema */ - if (strcmp("clearTextPassword", req->op.mod.message->elements[i].name) == 0) { + if (ldb_attr_cmp("clearTextPassword", req->op.mod.message->elements[i].name) == 0) { attr = dsdb_attribute_by_lDAPDisplayName(schema, "unicodePwd"); } else { attr = dsdb_attribute_by_lDAPDisplayName(schema, req->op.mod.message->elements[i].name); } - if (strcmp("nTSecurityDescriptor", req->op.mod.message->elements[i].name) == 0) { + + /* This basic attribute existence check with the right errorcode + * is needed since this module is the first one which requests + * schema attribute informations. + * The complete attribute checking is done in the + * "objectclass_attrs" module behind this one. + */ + if (!attr) { + ldb_asprintf_errstring(ldb, "acl_modify: attribute '%s' on entry '%s' was not found in the schema!", + req->op.mod.message->elements[i].name, + ldb_dn_get_linearized(req->op.mod.message->dn)); + talloc_free(tmp_ctx); + return LDB_ERR_NO_SUCH_ATTRIBUTE; + } + + if (ldb_attr_cmp("nTSecurityDescriptor", req->op.mod.message->elements[i].name) == 0) { modify_sd = true; } else { - if (!attr) { - DEBUG(10, ("acl_modify: cannot find attribute %s\n", - req->op.mod.message->elements[i].name)); - goto fail; - } if (!insert_in_object_tree(tmp_ctx, &attr->attributeSecurityGUID, SEC_ADS_WRITE_PROP, &new_node, &new_node)) { diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index fdff3a8..b15dff0 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -3,6 +3,7 @@ Copyright (C) Simo Sorce 2006-2008 Copyright (C) Andrew Bartlett <abart...@samba.org> 2005-2009 + Copyright (C) Matthias Dieter Wallnöfer 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,13 +22,14 @@ /* * Name: ldb * - * Component: objectClass sorting module + * Component: objectClass sorting and constraint checking module * * Description: * - sort the objectClass attribute into the class - * hierarchy, - * - fix DNs and attributes into 'standard' case - * - Add objectCategory and ntSecurityDescriptor defaults + * hierarchy and perform constraint checks (correct RDN name, + * valid parent), + * - fix DNs into 'standard' case + * - Add objectCategory and some other attribute defaults * * Author: Andrew Bartlett */ @@ -49,8 +51,10 @@ struct oc_context { struct ldb_module *module; struct ldb_request *req; + const struct dsdb_schema *schema; struct ldb_reply *search_res; + struct ldb_reply *search_res2; int (*step_fn)(struct oc_context *); }; @@ -70,12 +74,13 @@ static struct oc_context *oc_init_context(struct ldb_module *module, ac = talloc_zero(req, struct oc_context); if (ac == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); + ldb_oom(ldb); return NULL; } ac->module = module; ac->req = req; + ac->schema = dsdb_get_schema(ldb, ac); return ac; } @@ -346,42 +351,6 @@ static int fix_dn(TALLOC_CTX *mem_ctx, return ldb_dn_set_component(*fixed_dn, 0, upper_rdn_attr, *rdn_val); } -/* Fix all attribute names to be in the correct case, and check they are all valid per the schema */ -static int fix_check_attributes(struct ldb_context *ldb, - const struct dsdb_schema *schema, - struct ldb_message *msg, - enum ldb_request_type op) -{ - unsigned int i; - for (i=0; i < msg->num_elements; i++) { - const struct dsdb_attribute *attribute = dsdb_attribute_by_lDAPDisplayName(schema, msg->elements[i].name); - /* Add in a very special case for 'clearTextPassword', - * which is used for internal processing only, and is - * not presented in the schema */ - if (!attribute) { - if (strcasecmp(msg->elements[i].name, "clearTextPassword") != 0) { - ldb_asprintf_errstring(ldb, "attribute %s is not a valid attribute in schema", msg->elements[i].name); - /* Apparently Windows sends exactly this behaviour */ - return LDB_ERR_NO_SUCH_ATTRIBUTE; - } - } else { - msg->elements[i].name = attribute->lDAPDisplayName; - - /* We have to deny write operations on constructed attributes */ - if ((attribute->systemFlags & DS_FLAG_ATTR_IS_CONSTRUCTED) != 0) { - ldb_asprintf_errstring(ldb, "attribute %s is constructed", msg->elements[i].name); - if (op == LDB_ADD) { - return LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE; - } else { - return LDB_ERR_CONSTRAINT_VIOLATION; - } - } - - } - } - - return LDB_SUCCESS; -} static int objectclass_do_add(struct oc_context *ac); @@ -435,7 +404,6 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req) if (ret != LDB_SUCCESS) { return ret; } - talloc_steal(search_req, parent_dn); ac->step_fn = objectclass_do_add; @@ -445,7 +413,6 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req) static int objectclass_do_add(struct oc_context *ac) { struct ldb_context *ldb; - const struct dsdb_schema *schema; struct ldb_request *add_req; char *value; struct ldb_message_element *objectclass_element, *el; @@ -458,7 +425,6 @@ static int objectclass_do_add(struct oc_context *ac) const char *rdn_name = NULL; ldb = ldb_module_get_ctx(ac->module); - schema = dsdb_get_schema(ldb, ac); mem_ctx = talloc_new(ac); if (mem_ctx == NULL) { @@ -468,7 +434,8 @@ static int objectclass_do_add(struct oc_context *ac) msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message); - /* Check we have a valid parent */ + /* Check if we have a valid parent - this check is needed since + * we don't get a LDB_ERR_NO_SUCH_OBJECT error. */ if (ac->search_res == NULL) { if (ldb_dn_compare(ldb_get_root_basedn(ldb), msg->dn) == 0) { /* Allow the tree to be started */ @@ -483,27 +450,22 @@ static int objectclass_do_add(struct oc_context *ac) } } else { - /* Fix up the DN to be in the standard form, taking particular care to match the parent DN */ + /* Fix up the DN to be in the standard form, taking + * particular care to match the parent DN */ ret = fix_dn(msg, ac->req->op.add.message->dn, ac->search_res->message->dn, &msg->dn); if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, "Could not munge DN %s into normal form", + ldb_asprintf_errstring(ldb, "objectclass: Could not munge DN %s into normal form", ldb_dn_get_linearized(ac->req->op.add.message->dn)); talloc_free(mem_ctx); return ret; } } - if (schema) { - ret = fix_check_attributes(ldb, schema, msg, ac->req->operation); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - return ret; - } - + if (ac->schema != NULL) { /* This is now the objectClass list from the database */ objectclass_element = ldb_msg_find_element(msg, "objectClass"); @@ -512,7 +474,8 @@ static int objectclass_do_add(struct oc_context *ac) talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; } - ret = objectclass_sort(ac->module, schema, mem_ctx, objectclass_element, &sorted); + ret = objectclass_sort(ac->module, ac->schema, mem_ctx, + objectclass_element, &sorted); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); return ret; @@ -551,12 +514,13 @@ static int objectclass_do_add(struct oc_context *ac) objectclass_element = ldb_msg_find_element(msg, "objectClass"); /* Make sure its valid to add an object of this type */ - objectclass = get_last_structural_class(schema,objectclass_element); + objectclass = 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)); - return LDB_ERR_NAMING_VIOLATION; + "Failed to find a structural class for %s", + ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_UNWILLING_TO_PERFORM; } rdn_name = ldb_dn_get_rdn_name(msg->dn); @@ -573,28 +537,20 @@ static int objectclass_do_add(struct oc_context *ac) = ldb_msg_find_element(ac->search_res->message, "objectClass"); bool allowed_class = false; - int i, j; + unsigned int i, j; for (i=0; allowed_class == false && oc_el && i < oc_el->num_values; i++) { const struct dsdb_class *sclass; - sclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &oc_el->values[i]); + sclass = dsdb_class_by_lDAPDisplayName_ldb_val(ac->schema, + &oc_el->values[i]); if (!sclass) { /* We don't know this class? what is going on? */ continue; } - if (ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) { - for (j=0; sclass->systemPossibleInferiors && sclass->systemPossibleInferiors[j]; j++) { - if (ldb_attr_cmp(objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) { - allowed_class = true; - break; - } - } - } else { - for (j=0; sclass->systemPossibleInferiors && sclass->systemPossibleInferiors[j]; j++) { - if (ldb_attr_cmp(objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) { - allowed_class = true; - break; - } + for (j=0; sclass->systemPossibleInferiors && sclass->systemPossibleInferiors[j]; j++) { + if (ldb_attr_cmp(objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) { + allowed_class = true; + break; } } } @@ -700,12 +656,9 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req struct ldb_context *ldb = ldb_module_get_ctx(module); struct ldb_message_element *objectclass_element; struct ldb_message *msg; - const struct dsdb_schema *schema = dsdb_get_schema(ldb, NULL); - struct class_list *sorted, *current; struct ldb_request *down_req; struct oc_context *ac; - TALLOC_CTX *mem_ctx; - char *value; + bool oc_changes = false; int ret; ldb_debug(ldb, LDB_DEBUG_TRACE, "objectclass_modify\n"); @@ -714,11 +667,6 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req if (ldb_dn_is_special(req->op.mod.message->dn)) { return ldb_next_request(module, req); } - - /* Without schema, there isn't much to do here */ - if (!schema) { - return ldb_next_request(module, req); - } /* As with the "real" AD we don't accept empty messages */ if (req->op.mod.message->num_elements == 0) { @@ -729,150 +677,32 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req ac = oc_init_context(module, req); if (ac == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (!talloc_reference(ac, schema)) { - ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } - /* If no part of this touches the objectClass, then we don't - * need to make any changes. */ - objectclass_element = ldb_msg_find_element(req->op.mod.message, "objectClass"); - - /* If the only operation is the deletion of the objectClass - * then go on with just fixing the attribute case */ - if (!objectclass_element) { - msg = ldb_msg_copy_shallow(ac, req->op.mod.message); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = fix_check_attributes(ldb, schema, msg, req->operation); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_build_mod_req(&down_req, ldb, ac, - msg, - req->controls, - ac, oc_op_callback, - req); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* go on with the call chain */ - return ldb_next_request(module, down_req); - } - - switch (objectclass_element->flags & LDB_FLAG_MOD_MASK) { - case LDB_FLAG_MOD_DELETE: - if (objectclass_element->num_values == 0) { - return LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED; - } - break; - - case LDB_FLAG_MOD_REPLACE: - mem_ctx = talloc_new(ac); - if (mem_ctx == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg = ldb_msg_copy_shallow(ac, req->op.mod.message); - if (msg == NULL) { - talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = fix_check_attributes(ldb, schema, msg, req->operation); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - return ret; - } - - ret = objectclass_sort(module, schema, mem_ctx, objectclass_element, &sorted); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - return ret; - } - - /* We must completely replace the existing objectClass entry, - * because we need it sorted */ - - ldb_msg_remove_attr(msg, "objectClass"); - ret = ldb_msg_add_empty(msg, "objectClass", LDB_FLAG_MOD_REPLACE, NULL); - - 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) { - /* copy the value as this string is on the schema - * context and we can't rely on it not changing - * before the operation is over */ - value = talloc_strdup(msg, - current->objectclass->lDAPDisplayName); - if (value == NULL) { - ldb_oom(ldb); - talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - ret = ldb_msg_add_string(msg, "objectClass", value); - 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); - - ret = ldb_msg_sanity_check(ldb, msg); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_build_mod_req(&down_req, ldb, ac, - msg, - req->controls, - ac, oc_op_callback, - req); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* go on with the call chain */ - return ldb_next_request(module, down_req); + /* Without schema, there isn't much to do here */ + if (ac->schema == NULL) { + talloc_free(ac); + return ldb_next_request(module, req); } - /* This isn't the default branch of the switch, but a 'in any - * other case'. When a delete isn't for all objectClasses for - * example - */ - msg = ldb_msg_copy_shallow(ac, req->op.mod.message); if (msg == NULL) { - ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } - ret = fix_check_attributes(ldb, schema, msg, req->operation); - if (ret != LDB_SUCCESS) { - ldb_oom(ldb); - return ret; + /* For now change everything except the objectclasses */ + + objectclass_element = ldb_msg_find_element(msg, "objectClass"); + if (objectclass_element != NULL) { + ldb_msg_remove_attr(msg, "objectClass"); + oc_changes = true; } ret = ldb_build_mod_req(&down_req, ldb, ac, msg, - req->controls, - ac, oc_modify_callback, + req->controls, ac, + oc_changes ? oc_modify_callback : oc_op_callback, req); if (ret != LDB_SUCCESS) { return ret; @@ -883,8 +713,8 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req static int oc_modify_callback(struct ldb_request *req, struct ldb_reply *ares) { - struct ldb_context *ldb; static const char * const attrs[] = { "objectClass", NULL }; + struct ldb_context *ldb; struct ldb_request *search_req; struct oc_context *ac; int ret; @@ -914,8 +744,11 @@ static int oc_modify_callback(struct ldb_request *req, struct ldb_reply *ares) talloc_free(ares); - ret = ldb_build_search_req(&search_req, ldb, ac, - ac->req->op.mod.message->dn, LDB_SCOPE_BASE, + /* this looks up the real existing object for fetching some important + * informations (objectclasses) */ + ret = ldb_build_search_req(&search_req, ldb, + ac, ac->req->op.mod.message->dn, + LDB_SCOPE_BASE, "(objectClass=*)", attrs, NULL, ac, get_search_callback, @@ -930,75 +763,197 @@ static int oc_modify_callback(struct ldb_request *req, struct ldb_reply *ares) if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } + return LDB_SUCCESS; } static int objectclass_do_mod(struct oc_context *ac) { struct ldb_context *ldb; - const struct dsdb_schema *schema; struct ldb_request *mod_req; char *value; -- Samba Shared Repository