From 1726038708bcebd706dc4565963611dc86a33699 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 24 Sep 2009 07:06:03 -0700 Subject: s4-ldb: accept the binary DN OIDs in extended DN modules --- source4/dsdb/samdb/ldb_modules/extended_dn_out.c | 6 ++++-- source4/dsdb/samdb/ldb_modules/extended_dn_store.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c index f93090ace9..bb5e3795db 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c @@ -340,7 +340,8 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares) } /* Look to see if this attributeSyntax is a DN */ - if (strcmp(attribute->attributeSyntax_oid, "2.5.5.1") != 0) { + if (strcmp(attribute->attributeSyntax_oid, "2.5.5.1") != 0 && + strcmp(attribute->attributeSyntax_oid, "2.5.5.7") != 0) { continue; } @@ -617,7 +618,8 @@ static int extended_dn_out_dereference_init(struct ldb_module *module) NULL }; - if (strcmp(cur->syntax->attributeSyntax_oid, "2.5.5.1") != 0) { + if (strcmp(cur->syntax->attributeSyntax_oid, "2.5.5.1") != 0 && + strcmp(cur->syntax->attributeSyntax_oid, "2.5.5.7") != 0) { continue; } dereference_control->dereference diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c index 3234f6f269..122a9bb2b7 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c @@ -303,7 +303,8 @@ static int extended_dn_add(struct ldb_module *module, struct ldb_request *req) } /* We only setup an extended DN GUID on these particular DN objects */ - if (strcmp(schema_attr->attributeSyntax_oid, "2.5.5.1") != 0) { + if (strcmp(schema_attr->attributeSyntax_oid, "2.5.5.1") != 0 && + strcmp(schema_attr->attributeSyntax_oid, "2.5.5.7") != 0) { continue; } @@ -376,7 +377,8 @@ static int extended_dn_modify(struct ldb_module *module, struct ldb_request *req } /* We only setup an extended DN GUID on these particular DN objects */ - if (strcmp(schema_attr->attributeSyntax_oid, "2.5.5.1") != 0) { + if (strcmp(schema_attr->attributeSyntax_oid, "2.5.5.1") != 0 && + strcmp(schema_attr->attributeSyntax_oid, "2.5.5.7") != 0) { continue; } -- cgit From 48e5e215c93e1834bdacaa5a0f6dfde7788a0472 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 2 Oct 2009 20:00:08 +1000 Subject: s4-samdb: added some debugging This helped track down the samba3sam.py failures --- source4/dsdb/samdb/ldb_modules/samldb.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index e59b5dd1ce..2d87a017fd 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -699,8 +699,14 @@ static int samldb_check_primaryGroupID_1(struct samldb_ctx *ac) static int samldb_check_primaryGroupID_2(struct samldb_ctx *ac) { - if (ac->res_dn == NULL) + if (ac->res_dn == NULL) { + struct ldb_context *ldb; + ldb = ldb_module_get_ctx(ac->module); + ldb_asprintf_errstring(ldb, + "Failed to find group sid %s", + dom_sid_string(ac->sid, ac->sid)); return LDB_ERR_UNWILLING_TO_PERFORM; + } return samldb_next_step(ac); } @@ -1866,7 +1872,7 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req) int ret; ldb = ldb_module_get_ctx(module); - ldb_debug(ldb, LDB_DEBUG_TRACE, "samldb_add_record\n"); + ldb_debug(ldb, LDB_DEBUG_TRACE, "samldb_add\n"); /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.add.message->dn)) { -- cgit From 61598258450589db4b42e3ef38453c37080c5265 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 2 Oct 2009 20:00:42 +1000 Subject: s4-samldb: the samldb module requires that the primary group exists We need to create Domain Users in the test ldb --- source4/dsdb/samdb/ldb_modules/tests/samba3sam.py | 26 +++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py index fe96b88221..c61d3973a1 100644 --- a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py +++ b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py @@ -311,6 +311,14 @@ class MapTestCase(MapBaseTestCase): "sambaDomainName": "TESTS" }) + # Add a set of split records + self.ldb.add_ldif(""" +dn: """+ self.samba4.dn("cn=Domain Users") + """ +objectClass: group +cn: Domain Users +objectSid: S-1-5-21-4231626423-2410014848-2360679739-513 +""") + # Add a set of split records self.ldb.add_ldif(""" dn: """+ self.samba4.dn("cn=X") + """ @@ -459,7 +467,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # errors, letting the search fail with no results. #res = self.ldb.search("(objectSid=S-1-5-21-4231626423-2410014848-2360679739-552)", scope=SCOPE_DEFAULT, attrs) res = self.ldb.search(expression="(objectSid=*)", base=None, scope=SCOPE_DEFAULT, attrs=["dnsHostName", "lastLogon", "objectSid"]) - self.assertEquals(len(res), 3) + self.assertEquals(len(res), 4) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X")) self.assertEquals(str(res[0]["dnsHostName"]), "x") self.assertEquals(str(res[0]["lastLogon"]), "x") @@ -621,7 +629,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by negated local attribute res = self.ldb.search(expression="(!(revision=x))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 5) + self.assertEquals(len(res), 6) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "y") @@ -638,7 +646,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by negated remote attribute res = self.ldb.search(expression="(!(description=x))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 3) + self.assertEquals(len(res), 4) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Z")) self.assertEquals(str(res[0]["dnsHostName"]), "z") self.assertEquals(str(res[0]["lastLogon"]), "z") @@ -649,7 +657,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by negated conjunction of local attributes res = self.ldb.search(expression="(!(&(codePage=x)(revision=x)))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 5) + self.assertEquals(len(res), 6) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "y") @@ -666,7 +674,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by negated conjunction of remote attributes res = self.ldb.search(expression="(!(&(lastLogon=x)(description=x)))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 5) + self.assertEquals(len(res), 6) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y")) self.assertEquals(str(res[0]["dnsHostName"]), "y") self.assertEquals(str(res[0]["lastLogon"]), "y") @@ -683,7 +691,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by negated conjunction of local and remote attribute res = self.ldb.search(expression="(!(&(codePage=x)(description=x)))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 5) + self.assertEquals(len(res), 6) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "y") @@ -716,7 +724,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by negated disjunction of remote attributes res = self.ldb.search(expression="(!(|(badPwdCount=x)(lastLogon=x)))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 4) + self.assertEquals(len(res), 5) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y")) self.assertEquals(str(res[0]["dnsHostName"]), "y") self.assertEquals(str(res[0]["lastLogon"]), "y") @@ -730,7 +738,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by negated disjunction of local and remote attribute res = self.ldb.search(expression="(!(|(revision=x)(lastLogon=y)))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 4) + self.assertEquals(len(res), 5) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A")) self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "x") @@ -743,7 +751,7 @@ objectSid: S-1-5-21-4231626423-2410014848-2360679739-552 # Search by complex parse tree res = self.ldb.search(expression="(|(&(revision=x)(dnsHostName=x))(!(&(description=x)(nextRid=y)))(badPwdCount=y))", attrs=["dnsHostName", "lastLogon"]) - self.assertEquals(len(res), 6) + self.assertEquals(len(res), 7) self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B")) self.assertTrue(not "dnsHostName" in res[0]) self.assertEquals(str(res[0]["lastLogon"]), "y") -- cgit From 642dd95d817521f75f193a1e594b4dacf04d7b26 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 21 Sep 2009 17:24:43 -0700 Subject: s4:Ensure the selected RDN is the right one per the schema The relative DN must be the one that the most specific structural objectclass specifies. Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/objectclass.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 3cf252c71a..ad14acbcf8 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -547,7 +547,13 @@ static int objectclass_do_add(struct oc_context *ac) if (!current->next) { struct ldb_message_element *el; int32_t systemFlags = 0; - DATA_BLOB *sd; + const char *rdn_name = ldb_dn_get_rdn_name(msg->dn); + if (ldb_attr_cmp(rdn_name, current->objectclass->rDNAttID) != 0) { + ldb_asprintf_errstring(ldb, "RDN %s is not correct for most specific structural objectclass %s, should be %s", + rdn_name, current->objectclass->lDAPDisplayName, current->objectclass->rDNAttID); + return LDB_ERR_NAMING_VIOLATION; + } + if (!ldb_msg_find_element(msg, "objectCategory")) { value = talloc_strdup(msg, current->objectclass->defaultObjectCategory); if (value == NULL) { -- cgit From 8d7a987766b99e34b965b56bd2b1792ca7e95b5f Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Wed, 23 Sep 2009 13:36:40 +0400 Subject: s4-ldb: Use relax control to check in replace metadata module if we accept request that specify objectGUID attribute. --- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 43 ++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 253596ddea..73c070aa0a 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -457,11 +457,14 @@ static int replmd_op_callback(struct ldb_request *req, struct ldb_reply *ares) static int replmd_add(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; + struct ldb_control *control; + struct ldb_control **saved_controls; struct replmd_replicated_request *ac; const struct dsdb_schema *schema; enum ndr_err_code ndr_err; struct ldb_request *down_req; struct ldb_message *msg; + const DATA_BLOB *guid_blob; struct GUID guid; struct ldb_val guid_value; struct replPropertyMetaDataBlob nmd; @@ -473,6 +476,14 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) char *time_str; int ret; uint32_t i, ni=0; + int allow_add_guid=0; + int remove_current_guid=0; + + /* check if there's a show deleted control */ + control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); + if (control) { + allow_add_guid = 1; + } /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.add.message->dn)) { @@ -498,10 +509,26 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ac->schema = schema; - if (ldb_msg_find_element(req->op.add.message, "objectGUID") != NULL) { - ldb_debug_set(ldb, LDB_DEBUG_ERROR, + guid_blob = ldb_msg_find_ldb_val(req->op.add.message, "objectGUID"); + if ( guid_blob != NULL ) { + if( !allow_add_guid ) { + ldb_debug_set(ldb, LDB_DEBUG_ERROR, "replmd_add: it's not allowed to add an object with objectGUID\n"); - return LDB_ERR_UNWILLING_TO_PERFORM; + return LDB_ERR_UNWILLING_TO_PERFORM; + } else { + NTSTATUS status = GUID_from_data_blob(guid_blob,&guid); + if ( !NT_STATUS_IS_OK(status)) { + ldb_debug_set(ldb, LDB_DEBUG_ERROR, + "replmd_add: Unable to parse as a GUID the attribute objectGUID\n"); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + /* we remove this attribute as it can be a string and will not be treated + correctly and then we will readd it latter on in the good format*/ + remove_current_guid = 1; + } + } else { + /* a new GUID */ + guid = GUID_random(); } /* Get a sequence number from the backend */ @@ -510,8 +537,6 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) return ret; } - /* a new GUID */ - guid = GUID_random(); /* get our invocationId */ our_invocation_id = samdb_ntds_invocation_id(ldb); @@ -534,6 +559,9 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) if (!time_str) { return LDB_ERR_OPERATIONS_ERROR; } + if (remove_current_guid) { + ldb_msg_remove_attr(msg,"objectGUID"); + } /* * remove autogenerated attributes @@ -681,6 +709,11 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) return ret; } + /* if a control is there remove if from the modified request */ + if (control && !save_controls(control, down_req, &saved_controls)) { + return LDB_ERR_OPERATIONS_ERROR; + } + /* go on with the call chain */ return ldb_next_request(module, down_req); } -- cgit From 46c2af361252ae5543691854e8e3896d1e4b8e92 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Sep 2009 08:08:18 -0700 Subject: s4:dsdb Add 'lazy_commit' module to swallow the 'lazy commit' OID This allows this control to be specified as critical. We support the control because we choose to always be durable in our transactions. We really, really need a 'duplicate request' API, as at the moment we can't do this without a large, error-prone set of code that cannot cope with new request fields or types. Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/config.mk | 12 +++ source4/dsdb/samdb/ldb_modules/lazy_commit.c | 132 +++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 source4/dsdb/samdb/ldb_modules/lazy_commit.c (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index a49b238591..456ff5756c 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -369,3 +369,15 @@ INIT_FUNCTION = LDB_MODULE(acl) ################################################ ldb_acl_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/acl.o + +################################################ +# Start MODULE ldb_lazy_commit +[MODULE::ldb_lazy_commit] +PRIVATE_DEPENDENCIES = SAMDB +SUBSYSTEM = LIBLDB +INIT_FUNCTION = LDB_MODULE(lazy_commit) + +# End MODULE ldb_lazy_commit +################################################ + +ldb_lazy_commit_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/lazy_commit.o diff --git a/source4/dsdb/samdb/ldb_modules/lazy_commit.c b/source4/dsdb/samdb/ldb_modules/lazy_commit.c new file mode 100644 index 0000000000..69ac99e246 --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/lazy_commit.c @@ -0,0 +1,132 @@ +/* + ldb database library + + Copyright (C) Andrew Bartlett 2009 + + 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb lazy_commit module + * + * Description: module to pretend to support the 'lazy commit' control + * + * Author: Andrew Bartlett + */ + +#include "ldb_module.h" + +static int unlazy_op(struct ldb_module *module, struct ldb_request *req) +{ + int ret; + struct ldb_request *new_req; + struct ldb_control **saved_controls; + struct ldb_control *control = ldb_request_get_control(req, LDB_CONTROL_SERVER_LAZY_COMMIT); + if (!control) { + return ldb_next_request(module, req); + } + + switch (req->operation) { + case LDB_SEARCH: + ret = ldb_build_search_req_ex(&new_req, ldb_module_get_ctx(module), + req, + req->op.search.base, + req->op.search.scope, + req->op.search.tree, + req->op.search.attrs, + req->controls, + req->context, req->callback, + req); + break; + case LDB_ADD: + ret = ldb_build_add_req(&new_req, ldb_module_get_ctx(module), req, + req->op.add.message, + req->controls, + req->context, req->callback, + req); + break; + case LDB_MODIFY: + ret = ldb_build_mod_req(&new_req, ldb_module_get_ctx(module), req, + req->op.mod.message, + req->controls, + req->context, req->callback, + req); + break; + case LDB_DELETE: + ret = ldb_build_del_req(&new_req, ldb_module_get_ctx(module), req, + req->op.del.dn, + req->controls, + req->context, req->callback, + req); + break; + case LDB_RENAME: + ret = ldb_build_rename_req(&new_req, ldb_module_get_ctx(module), req, + req->op.rename.olddn, + req->op.rename.newdn, + req->controls, + req->context, req->callback, + req); + break; + case LDB_EXTENDED: + ret = ldb_build_extended_req(&new_req, ldb_module_get_ctx(module), + req, + req->op.extended.oid, + req->op.extended.data, + req->controls, + req->context, req->callback, + req); + break; + default: + ldb_set_errstring(ldb_module_get_ctx(module), + "Unsupported request type!"); + ret = LDB_ERR_UNWILLING_TO_PERFORM; + } + + if (ret != LDB_SUCCESS) { + return ret; + } + + save_controls(control, req, &saved_controls); + return ldb_next_request(module, new_req); +} + +static int unlazy_init(struct ldb_module *module) +{ + int ret; + struct ldb_context *ldb; + ldb = ldb_module_get_ctx(module); + + ret = ldb_mod_register_control(module, LDB_CONTROL_SHOW_DELETED_OID); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "lazy_commit: Unable to register control with rootdse!\n"); + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_init(module); +} + +const struct ldb_module_ops ldb_lazy_commit_module_ops = { + .name = "lazy_commit", + .search = unlazy_op, + .add = unlazy_op, + .modify = unlazy_op, + .del = unlazy_op, + .rename = unlazy_op, + .request = unlazy_op, + .extended = unlazy_op, + .init_context = unlazy_init, +}; -- cgit From 1c71c096459da85b1e5276d8c315b05e7bc870fa Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Sep 2009 08:34:33 -0700 Subject: s4:dsdb Don't allow creating of new objects with an isDefunct schema class --- source4/dsdb/samdb/ldb_modules/objectclass.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index ad14acbcf8..cc88d6b96d 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -138,7 +138,13 @@ static int objectclass_sort(struct ldb_module *module, 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); - return LDB_ERR_OBJECT_CLASS_VIOLATION; + /* 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; } /* this is the root of the tree. We will start -- cgit From 984ea88156767776dc2ab0b7da84c9701c34f345 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Sep 2009 15:06:11 -0700 Subject: s4:dsdb rework instanceType module - put instanceType in provision The instanceType needs to be specified in future because that's how the partitions are actually created. --- source4/dsdb/samdb/ldb_modules/instancetype.c | 38 +++++++-------------------- 1 file changed, 9 insertions(+), 29 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/instancetype.c b/source4/dsdb/samdb/ldb_modules/instancetype.c index de46c0a42a..201ed04412 100644 --- a/source4/dsdb/samdb/ldb_modules/instancetype.c +++ b/source4/dsdb/samdb/ldb_modules/instancetype.c @@ -77,8 +77,6 @@ static int instancetype_add(struct ldb_module *module, struct ldb_request *req) struct it_context *ac; uint32_t instance_type; int ret; - const struct ldb_control *partition_ctrl; - const struct dsdb_control_current_partition *partition; ldb = ldb_module_get_ctx(module); @@ -90,31 +88,19 @@ static int instancetype_add(struct ldb_module *module, struct ldb_request *req) } if (ldb_msg_find_element(req->op.add.message, "instanceType")) { + unsigned int instanceType = ldb_msg_find_attr_as_uint(req->op.add.message, "instanceType", 0); + + if (instanceType & INSTANCE_TYPE_IS_NC_HEAD) { + /* Do something in future */ + } + /* TODO: we need to validate and possibly create a new partition */ return ldb_next_request(module, req); } - partition_ctrl = ldb_request_get_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID); - if (!partition_ctrl) { - ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "instancetype_add: no current partition control found"); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - partition = talloc_get_type(partition_ctrl->data, - struct dsdb_control_current_partition); - SMB_ASSERT(partition && partition->version == DSDB_CONTROL_CURRENT_PARTITION_VERSION); - - ac = talloc(req, struct it_context); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ac->module = module; - ac->req = req; - /* we have to copy the message as the caller might have it as a const */ - msg = ldb_msg_copy_shallow(ac, req->op.add.message); + msg = ldb_msg_copy_shallow(req, req->op.add.message); if (msg == NULL) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; @@ -124,12 +110,6 @@ static int instancetype_add(struct ldb_module *module, struct ldb_request *req) * TODO: calculate correct instance type */ instance_type = INSTANCE_TYPE_WRITE; - if (ldb_dn_compare(partition->dn, msg->dn) == 0) { - instance_type |= INSTANCE_TYPE_IS_NC_HEAD; - if (ldb_dn_compare(msg->dn, samdb_base_dn(ldb)) != 0) { - instance_type |= INSTANCE_TYPE_NC_ABOVE; - } - } ret = ldb_msg_add_fmt(msg, "instanceType", "%u", instance_type); if (ret != LDB_SUCCESS) { @@ -137,10 +117,10 @@ static int instancetype_add(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_OPERATIONS_ERROR; } - ret = ldb_build_add_req(&down_req, ldb, ac, + ret = ldb_build_add_req(&down_req, ldb, req, msg, req->controls, - ac, it_callback, + req->context, req->callback, req); if (ret != LDB_SUCCESS) { return ret; -- cgit From 44df2488e30da783add33b4fb85d96ce65856484 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 29 Sep 2009 11:49:50 +0200 Subject: s4: fix various warnings (not "const" related ones) --- source4/dsdb/samdb/ldb_modules/anr.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/anr.c b/source4/dsdb/samdb/ldb_modules/anr.c index deeccac072..a5220b3f91 100644 --- a/source4/dsdb/samdb/ldb_modules/anr.c +++ b/source4/dsdb/samdb/ldb_modules/anr.c @@ -67,8 +67,10 @@ static struct ldb_parse_tree *make_parse_list(struct ldb_module *module, * Make an equality or prefix match tree, from the attribute, operation and matching value supplied */ static struct ldb_parse_tree *make_match_tree(struct ldb_module *module, - TALLOC_CTX *mem_ctx, enum ldb_parse_op op, - const char *attr, const DATA_BLOB *match) + TALLOC_CTX *mem_ctx, + enum ldb_parse_op op, + const char *attr, + struct ldb_val *match) { struct ldb_context *ldb; struct ldb_parse_tree *match_tree; @@ -123,7 +125,7 @@ struct anr_context { */ static int anr_replace_value(struct anr_context *ac, TALLOC_CTX *mem_ctx, - const struct ldb_val *match, + struct ldb_val *match, struct ldb_parse_tree **ntree) { struct ldb_parse_tree *tree = NULL; @@ -146,7 +148,7 @@ static int anr_replace_value(struct anr_context *ac, ac->found_anr = true; if (match->length > 1 && match->data[0] == '=') { - DATA_BLOB *match2 = talloc(mem_ctx, DATA_BLOB); + struct ldb_val *match2 = talloc(mem_ctx, struct ldb_val); *match2 = data_blob_const(match->data+1, match->length - 1); if (match2 == NULL){ ldb_oom(ldb); @@ -181,8 +183,8 @@ static int anr_replace_value(struct anr_context *ac, if (p) { struct ldb_parse_tree *first_split_filter, *second_split_filter, *split_filters, *match_tree_1, *match_tree_2; - DATA_BLOB *first_match = talloc(tree, DATA_BLOB); - DATA_BLOB *second_match = talloc(tree, DATA_BLOB); + struct ldb_val *first_match = talloc(tree, struct ldb_val); + struct ldb_val *second_match = talloc(tree, struct ldb_val); if (!first_match || !second_match) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; -- cgit From ab9c2320661901c05b217cc86a46e8b15e3f8425 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Sep 2009 21:13:22 -0700 Subject: s4:dsdb Pass down the exact error code on failure in repl_meta_data --- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 73c070aa0a..59dc2ec928 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -667,27 +667,27 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ret = ldb_msg_add_value(msg, "objectGUID", &guid_value, NULL); if (ret != LDB_SUCCESS) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } ret = ldb_msg_add_string(msg, "whenChanged", time_str); if (ret != LDB_SUCCESS) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } ret = samdb_msg_add_uint64(ldb, msg, msg, "uSNCreated", seq_num); if (ret != LDB_SUCCESS) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } ret = samdb_msg_add_uint64(ldb, msg, msg, "uSNChanged", seq_num); if (ret != LDB_SUCCESS) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } ret = ldb_msg_add_value(msg, "replPropertyMetaData", &nmd_value, NULL); if (ret != LDB_SUCCESS) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } /* -- cgit From e6d82267454a4678484b62cd5b28527f845af84f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Sep 2009 16:40:30 -0700 Subject: s4:dsdb Return correct error on invalid attribute This error per the Microsoft testsuite --- source4/dsdb/samdb/ldb_modules/objectclass.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index cc88d6b96d..6d22141a3b 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -361,7 +361,8 @@ static int fix_attributes(struct ldb_context *ldb, const struct dsdb_schema *sch 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); - return LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE; + /* Apparently Windows sends exactly this behaviour */ + return LDB_ERR_NO_SUCH_ATTRIBUTE; } } else { msg->elements[i].name = attribute->lDAPDisplayName; -- cgit From 2ab27d78b0f2c10a6d632015090872a0f6542add Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Fri, 2 Oct 2009 23:26:35 +0200 Subject: s4:repl_meta_data - various - Add more "talloc_free"s and right error values where needed - Add a pre-lookup for entries before searching for metadata attribute (also suggested by TODO list) - Now the most part of "ldap.py" works again --- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 47 ++++++++++++++++++++----- 1 file changed, 38 insertions(+), 9 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 59dc2ec928..489985a22f 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -514,12 +514,14 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) if( !allow_add_guid ) { ldb_debug_set(ldb, LDB_DEBUG_ERROR, "replmd_add: it's not allowed to add an object with objectGUID\n"); + talloc_free(ac); return LDB_ERR_UNWILLING_TO_PERFORM; } else { NTSTATUS status = GUID_from_data_blob(guid_blob,&guid); if ( !NT_STATUS_IS_OK(status)) { ldb_debug_set(ldb, LDB_DEBUG_ERROR, "replmd_add: Unable to parse as a GUID the attribute objectGUID\n"); + talloc_free(ac); return LDB_ERR_UNWILLING_TO_PERFORM; } /* we remove this attribute as it can be a string and will not be treated @@ -534,15 +536,16 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) /* Get a sequence number from the backend */ ret = ldb_sequence_number(ldb, LDB_SEQ_NEXT, &seq_num); if (ret != LDB_SUCCESS) { + talloc_free(ac); return ret; } - /* get our invocationId */ our_invocation_id = samdb_ntds_invocation_id(ldb); if (!our_invocation_id) { ldb_debug_set(ldb, LDB_DEBUG_ERROR, "replmd_add: unable to find invocationId\n"); + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } @@ -550,6 +553,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) msg = ldb_msg_copy_shallow(ac, req->op.add.message); if (msg == NULL) { ldb_oom(ldb); + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } @@ -557,6 +561,8 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) unix_to_nt_time(&now, t); time_str = ldb_timestring(msg, t); if (!time_str) { + ldb_oom(ldb); + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } if (remove_current_guid) { @@ -576,7 +582,8 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ret = ldb_msg_add_fmt(msg, "instanceType", "%u", INSTANCE_TYPE_WRITE); if (ret != LDB_SUCCESS) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + talloc_free(ac); + return ret; } } @@ -586,7 +593,8 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ret = ldb_msg_add_string(msg, "whenCreated", time_str); if (ret != LDB_SUCCESS) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + talloc_free(ac); + return ret; } /* build the replication meta_data */ @@ -598,6 +606,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) nmd.ctr.ctr1.count); if (!nmd.ctr.ctr1.array) { ldb_oom(ldb); + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } @@ -613,6 +622,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ldb_debug_set(ldb, LDB_DEBUG_ERROR, "replmd_add: attribute '%s' not defined in schema\n", e->name); + talloc_free(ac); return LDB_ERR_NO_SUCH_ATTRIBUTE; } @@ -640,6 +650,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) */ ret = replmd_replPropertyMetaDataCtr1_sort(&nmd.ctr.ctr1, schema, msg->dn); if (ret != LDB_SUCCESS) { + talloc_free(ac); return ret; } @@ -650,6 +661,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) (ndr_push_flags_fn_t)ndr_push_GUID); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { ldb_oom(ldb); + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } ndr_err = ndr_push_struct_blob(&nmd_value, msg, @@ -658,6 +670,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) (ndr_push_flags_fn_t)ndr_push_replPropertyMetaDataBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { ldb_oom(ldb); + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } @@ -667,26 +680,31 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ret = ldb_msg_add_value(msg, "objectGUID", &guid_value, NULL); if (ret != LDB_SUCCESS) { ldb_oom(ldb); + talloc_free(ac); return ret; } ret = ldb_msg_add_string(msg, "whenChanged", time_str); if (ret != LDB_SUCCESS) { ldb_oom(ldb); + talloc_free(ac); return ret; } ret = samdb_msg_add_uint64(ldb, msg, msg, "uSNCreated", seq_num); if (ret != LDB_SUCCESS) { ldb_oom(ldb); + talloc_free(ac); return ret; } ret = samdb_msg_add_uint64(ldb, msg, msg, "uSNChanged", seq_num); if (ret != LDB_SUCCESS) { ldb_oom(ldb); + talloc_free(ac); return ret; } ret = ldb_msg_add_value(msg, "replPropertyMetaData", &nmd_value, NULL); if (ret != LDB_SUCCESS) { ldb_oom(ldb); + talloc_free(ac); return ret; } @@ -701,16 +719,19 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ac, replmd_op_callback, req); if (ret != LDB_SUCCESS) { + talloc_free(ac); return ret; } ret = replmd_notify(module, msg->dn, seq_num); if (ret != LDB_SUCCESS) { + talloc_free(ac); return ret; } /* if a control is there remove if from the modified request */ if (control && !save_controls(control, down_req, &saved_controls)) { + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } @@ -818,7 +839,7 @@ static int replmd_update_rpmd(struct ldb_module *module, /* search for the existing replPropertyMetaDataBlob */ ret = dsdb_search_dn_with_deleted(ldb, msg, &res, msg->dn, attrs); - if (ret != LDB_SUCCESS || res->count < 1) { + if (ret != LDB_SUCCESS || res->count != 1) { DEBUG(0,(__location__ ": Object %s failed to find replPropertyMetaData\n", ldb_dn_get_linearized(msg->dn))); return LDB_ERR_OPERATIONS_ERROR; @@ -913,9 +934,10 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) const struct dsdb_schema *schema; struct ldb_request *down_req; struct ldb_message *msg; - int ret; + struct ldb_result *res; time_t t = time(NULL); uint64_t seq_num = 0; + int ret; /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.mod.message->dn)) { @@ -944,13 +966,12 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) /* we have to copy the message as the caller might have it as a const */ msg = ldb_msg_copy_shallow(ac, req->op.mod.message); if (msg == NULL) { + ldb_oom(ldb); talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } /* TODO: - * - get the whole old object - * - if the old object doesn't exist report an error * - give an error when a readonly attribute should * be modified * - merge the changed into the old object @@ -959,8 +980,15 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) * attribute was changed */ + ret = dsdb_search_dn_with_deleted(ldb, msg, &res, msg->dn, NULL); + if (ret != LDB_SUCCESS) { + talloc_free(ac); + return ret; + } + ret = replmd_update_rpmd(module, msg, &seq_num); if (ret != LDB_SUCCESS) { + talloc_free(ac); return ret; } @@ -974,6 +1002,7 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) ac, replmd_op_callback, req); if (ret != LDB_SUCCESS) { + talloc_free(ac); return ret; } talloc_steal(down_req, msg); @@ -983,12 +1012,12 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) if (seq_num != 0) { if (add_time_element(msg, "whenChanged", t) != LDB_SUCCESS) { talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } if (add_uint64_element(msg, "uSNChanged", seq_num) != LDB_SUCCESS) { talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } } -- cgit From 90828cc7022807a6036700d0edc8061c408ef8a7 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Sat, 3 Oct 2009 10:52:53 +0200 Subject: s4:dsdb Don't allow creation of systemOnly objectclasses (except as part of the provision, which specifies the 'relax' control) Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/objectclass.c | 6 ++++++ source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 6d22141a3b..b3d54612dd 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -561,6 +561,12 @@ static int objectclass_do_add(struct oc_context *ac) return LDB_ERR_NAMING_VIOLATION; } + if (current->objectclass->systemOnly && !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) { + ldb_asprintf_errstring(ldb, "objectClass %s is systemOnly, rejecting creation of %s", + current->objectclass->lDAPDisplayName, ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + if (!ldb_msg_find_element(msg, "objectCategory")) { value = talloc_strdup(msg, current->objectclass->defaultObjectCategory); if (value == NULL) { diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 489985a22f..74dd7e5bbb 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -476,10 +476,10 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) char *time_str; int ret; uint32_t i, ni=0; - int allow_add_guid=0; - int remove_current_guid=0; + bool allow_add_guid = false; + bool remove_current_guid = false; - /* check if there's a show deleted control */ + /* check if there's a show relax control (used by provision to say 'I know what I'm doing') */ control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); if (control) { allow_add_guid = 1; @@ -526,7 +526,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) } /* we remove this attribute as it can be a string and will not be treated correctly and then we will readd it latter on in the good format*/ - remove_current_guid = 1; + remove_current_guid = true; } } else { /* a new GUID */ -- cgit From f86beaaad96ac2dd7cf6a3a9d57f42c57c2440c2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Sep 2009 21:16:42 -0700 Subject: s4:dsdb Add objectClass and RDN constraints to objectClass module These additional constraints are applied, found by the Microsoft testsuite. - When the parent is not present, we now return 'NO_SUCH_OBJECT'. - Restrict the choice of RDN to the correct one per the schema - Honour the allowedChildClasses attribute from the parent's objectClass. Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/objectclass.c | 43 ++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 8 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index b3d54612dd..b68149f2f2 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -2,7 +2,7 @@ ldb database library Copyright (C) Simo Sorce 2006-2008 - Copyright (C) Andrew Bartlett 2005-2007 + Copyright (C) Andrew Bartlett 2005-2009 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 @@ -381,7 +381,7 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req) struct oc_context *ac; struct ldb_dn *parent_dn; int ret; - static const char * const parent_attrs[] = { "objectGUID", NULL }; + static const char * const parent_attrs[] = { "objectGUID", "objectClass", NULL }; ldb = ldb_module_get_ctx(module); @@ -465,7 +465,7 @@ static int objectclass_do_add(struct oc_context *ac) ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, parent does not exist!", ldb_dn_get_linearized(msg->dn)); talloc_free(mem_ctx); - return LDB_ERR_UNWILLING_TO_PERFORM; + return LDB_ERR_NO_SUCH_OBJECT; } } else { const struct ldb_val *parent_guid; @@ -491,9 +491,6 @@ static int objectclass_do_add(struct oc_context *ac) return LDB_ERR_UNWILLING_TO_PERFORM; } - /* TODO: Check this is a valid child to this parent, - * by reading the allowedChildClasses and - * allowedChildClasssesEffective attributes */ ret = ldb_msg_add_steal_value(msg, "parentGUID", discard_const(parent_guid)); if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, failed to add parentGUID", @@ -555,12 +552,42 @@ static int objectclass_do_add(struct oc_context *ac) struct ldb_message_element *el; int32_t systemFlags = 0; const char *rdn_name = ldb_dn_get_rdn_name(msg->dn); - if (ldb_attr_cmp(rdn_name, current->objectclass->rDNAttID) != 0) { - ldb_asprintf_errstring(ldb, "RDN %s is not correct for most specific structural objectclass %s, should be %s", + if (current->objectclass->rDNAttID + && ldb_attr_cmp(rdn_name, current->objectclass->rDNAttID) != 0) { + ldb_asprintf_errstring(ldb, + "RDN %s is not correct for most specific structural objectclass %s, should be %s", rdn_name, current->objectclass->lDAPDisplayName, current->objectclass->rDNAttID); return LDB_ERR_NAMING_VIOLATION; } + if (ac->search_res && ac->search_res->message) { + struct ldb_message_element *oc_el + = ldb_msg_find_element(ac->search_res->message, "objectClass"); + + bool allowed_class = false; + int i, j; + for (i=0; !allowed_class && 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]); + if (!sclass) { + /* We don't know this class? what is going on? */ + continue; + } + for (j=0; !allowed_class && sclass->possibleInferiors && sclass->possibleInferiors[j]; j++) { + if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, sclass->possibleInferiors[j]) == 0) { + allowed_class = true; + } + } + } + + if (!allowed_class) { + ldb_asprintf_errstring(ldb, "structural objectClass %s is not a valid child class for %s", + current->objectclass->lDAPDisplayName, ldb_dn_get_linearized(ac->search_res->message->dn)); + return LDB_ERR_NAMING_VIOLATION; + } + } + if (current->objectclass->systemOnly && !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) { ldb_asprintf_errstring(ldb, "objectClass %s is systemOnly, rejecting creation of %s", current->objectclass->lDAPDisplayName, ldb_dn_get_linearized(msg->dn)); -- cgit From 4bc9a39eed3e47cd87ea8cd24f9ac4f9e2712f43 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Sep 2009 15:14:49 -0700 Subject: s4:dsdb Use possibleInferiors to restrict creation of child objects This also uses systemPossibleInferiors when the 'relax' control is specified, which is done by the provision. Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/objectclass.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index b68149f2f2..51a1ac845e 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -42,6 +42,7 @@ #include "libcli/security/security.h" #include "auth/auth.h" #include "param/param.h" +#include "../libds/common/flags.h" struct oc_context { @@ -566,7 +567,7 @@ static int objectclass_do_add(struct oc_context *ac) bool allowed_class = false; int i, j; - for (i=0; !allowed_class && oc_el && i < oc_el->num_values; i++) { + 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]); @@ -574,9 +575,19 @@ static int objectclass_do_add(struct oc_context *ac) /* We don't know this class? what is going on? */ continue; } - for (j=0; !allowed_class && sclass->possibleInferiors && sclass->possibleInferiors[j]; j++) { - if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, sclass->possibleInferiors[j]) == 0) { - allowed_class = true; + if (ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) { + for (j=0; sclass->systemPossibleInferiors && sclass->systemPossibleInferiors[j]; j++) { + if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) { + allowed_class = true; + break; + } + } + } else { + for (j=0; sclass->systemPossibleInferiors && sclass->systemPossibleInferiors[j]; j++) { + if (ldb_attr_cmp(current->objectclass->lDAPDisplayName, sclass->systemPossibleInferiors[j]) == 0) { + allowed_class = true; + break; + } } } } -- cgit From 24422fae24744f9c9113342692db285ba1409799 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Sat, 3 Oct 2009 15:08:19 +0200 Subject: s4:objectclass - Free unused memory from responses --- source4/dsdb/samdb/ldb_modules/objectclass.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 51a1ac845e..b6f1a1aa23 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -881,6 +881,8 @@ static int oc_modify_callback(struct ldb_request *req, struct ldb_reply *ares) LDB_ERR_OPERATIONS_ERROR); } + talloc_free(ares); + ret = ldb_build_search_req(&search_req, ldb, ac, ac->req->op.mod.message->dn, LDB_SCOPE_BASE, "(objectClass=*)", @@ -1089,6 +1091,7 @@ static int objectclass_rename_callback(struct ldb_request *req, struct ldb_reply ares->response, ares->error); } + talloc_free(ares); /* the ac->search_res should contain the new parents objectGUID */ parent_guid = ldb_msg_find_ldb_val(ac->search_res->message, "objectGUID"); -- cgit From b87769c9a98904bb18c737923de4cb8d619528d1 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 6 Oct 2009 19:24:28 +0200 Subject: s4:acl module - intendation fix and comment enhancement --- source4/dsdb/samdb/ldb_modules/acl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c index 1b02abcb8e..2f123145db 100644 --- a/source4/dsdb/samdb/ldb_modules/acl.c +++ b/source4/dsdb/samdb/ldb_modules/acl.c @@ -802,6 +802,7 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_OPERATIONS_ERROR; } +/* TODO Is this really right? */ /* if (what_is_user(module) == SECURITY_SYSTEM) */ return ldb_next_request(module, req); @@ -813,7 +814,7 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) ac->user_type = what_is_user(module); ac->sec_result = LDB_SUCCESS; if (!is_root_base_dn(ldb, req->op.mod.message->dn) && parent && !is_root_base_dn(ldb, parent)){ - filter = talloc_asprintf(req,"(&(objectClass=*)(|(%s=%s)(%s=%s))))", + filter = talloc_asprintf(req,"(&(objectClass=*)(|(%s=%s)(%s=%s))))", ldb_dn_get_component_name(parent,0), ldb_dn_get_component_val(parent,0)->data, ldb_dn_get_component_name(req->op.mod.message->dn,0), -- cgit From 0d7c34a5b4362ae8b1083a8bcf3a4115c37cafde Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 6 Oct 2009 19:26:15 +0200 Subject: s4:rootdse module - intendation fixup --- source4/dsdb/samdb/ldb_modules/rootdse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index a8e08ec3ad..83e4e3b50e 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -722,9 +722,9 @@ static int rootdse_modify(struct ldb_module *module, struct ldb_request *req) } _PUBLIC_ const struct ldb_module_ops ldb_rootdse_module_ops = { - .name = "rootdse", + .name = "rootdse", .init_context = rootdse_init, .search = rootdse_search, - .request = rootdse_request, + .request = rootdse_request, .modify = rootdse_modify }; -- cgit From 8536e1b947ad8a2bc5596a9a1de9a58262153ebf Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 6 Oct 2009 19:27:17 +0200 Subject: s4:various LDB modules - "build_request" functions - propagate result codes back It's very useful to know the exact result code when something fails and not only a generic (by the module) created one. Sure, there are some exception cases with specific results (special message constellations, attributes, values...) which shouldn't be changed at all (examples of them are in the "ldap.py" test). Therefore I looked very carefully to not change them. --- source4/dsdb/samdb/ldb_modules/kludge_acl.c | 2 +- source4/dsdb/samdb/ldb_modules/local_password.c | 5 ++--- source4/dsdb/samdb/ldb_modules/objectguid.c | 4 ++-- source4/dsdb/samdb/ldb_modules/partition.c | 20 ++++++++++++++------ 4 files changed, 19 insertions(+), 12 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/kludge_acl.c b/source4/dsdb/samdb/ldb_modules/kludge_acl.c index 34f848de8a..79309e82bf 100644 --- a/source4/dsdb/samdb/ldb_modules/kludge_acl.c +++ b/source4/dsdb/samdb/ldb_modules/kludge_acl.c @@ -379,7 +379,7 @@ static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req) ac, kludge_acl_callback, req); if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; + return ret; } /* check if there's an SD_FLAGS control */ diff --git a/source4/dsdb/samdb/ldb_modules/local_password.c b/source4/dsdb/samdb/ldb_modules/local_password.c index 58c0f1f0d5..9c386b354d 100644 --- a/source4/dsdb/samdb/ldb_modules/local_password.c +++ b/source4/dsdb/samdb/ldb_modules/local_password.c @@ -633,8 +633,7 @@ static int lpdb_delete_callabck(struct ldb_request *req, ret = ldb_next_request(ac->module, search_req); if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); + return ldb_module_done(ac->req, NULL, NULL, ret); } return LDB_SUCCESS; } @@ -1082,7 +1081,7 @@ static int local_password_search(struct ldb_module *module, struct ldb_request * ac, lpdb_remote_search_callback, req); if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; + return ret; } /* perform the search */ diff --git a/source4/dsdb/samdb/ldb_modules/objectguid.c b/source4/dsdb/samdb/ldb_modules/objectguid.c index 3d218edc76..12dd402617 100644 --- a/source4/dsdb/samdb/ldb_modules/objectguid.c +++ b/source4/dsdb/samdb/ldb_modules/objectguid.c @@ -209,7 +209,7 @@ static int objectguid_add(struct ldb_module *module, struct ldb_request *req) ac, og_op_callback, req); if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; + return ret; } /* go on with the call chain */ @@ -267,7 +267,7 @@ static int objectguid_modify(struct ldb_module *module, struct ldb_request *req) ac, og_op_callback, req); if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; + return ret; } /* go on with the call chain */ diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 6e86d4c484..c5bbdf8dce 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -829,14 +829,22 @@ static int partition_sequence_number(struct ldb_module *module, struct ldb_reque res, ldb_extended_default_callback, NULL); - ret = ldb_next_request(module, treq); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(treq->handle, LDB_WAIT_ALL); + if (ret != LDB_SUCCESS) { + talloc_free(res); + return ret; } + + ret = ldb_next_request(module, treq); if (ret != LDB_SUCCESS) { talloc_free(res); return ret; } + ret = ldb_wait(treq->handle, LDB_WAIT_ALL); + if (ret != LDB_SUCCESS) { + talloc_free(res); + return ret; + } + seqr = talloc_get_type(res->extended->data, struct ldb_seqnum_result); if (seqr->flags & LDB_SEQ_TIMESTAMP_SEQUENCE) { @@ -1083,7 +1091,7 @@ static int partition_extended_schema_update_now(struct ldb_module *module, struc } /* fire the first one */ - ret = partition_call_first(ac); + ret = partition_call_first(ac); if (ret != LDB_SUCCESS){ return ret; @@ -1385,14 +1393,14 @@ static int partition_init(struct ldb_module *module) if (ret != LDB_SUCCESS) { ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_ERROR, "partition: Unable to register control with rootdse!\n"); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } ret = ldb_mod_register_control(module, LDB_CONTROL_SEARCH_OPTIONS_OID); if (ret != LDB_SUCCESS) { ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_ERROR, "partition: Unable to register control with rootdse!\n"); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } talloc_free(mem_ctx); -- cgit From 75eff6eaf3df69a397980f0717fc5cc720cfe0b9 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Wed, 7 Oct 2009 12:38:00 +0200 Subject: s4:subtree_delete - Make the initialisation of the child counter more clear --- source4/dsdb/samdb/ldb_modules/subtree_delete.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/subtree_delete.c b/source4/dsdb/samdb/ldb_modules/subtree_delete.c index 241cc5f7d6..e1ce9c1fa8 100644 --- a/source4/dsdb/samdb/ldb_modules/subtree_delete.c +++ b/source4/dsdb/samdb/ldb_modules/subtree_delete.c @@ -55,6 +55,8 @@ static struct subtree_delete_context *subdel_ctx_init(struct ldb_module *module, ac->module = module; ac->req = req; + ac->num_children = 0; + return ac; } -- cgit From 1dfa2ed42361bb8d22446513a85f0523a740982c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 12 Oct 2009 16:44:19 +1100 Subject: s4:provision Remove all references to samba4LocalDomain This was a bad idea all along, as Simo said at the time. With the full MS schema and enforcement of it, it is an even worse idea. This fixes the provision of the member server in 'make test' Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/password_hash.c | 2 +- source4/dsdb/samdb/ldb_modules/samldb.c | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index fdb044198b..adb62d3544 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -1673,7 +1673,7 @@ static int build_domain_data_request(struct ph_context *ac) ldb = ldb_module_get_ctx(ac->module); filter = talloc_asprintf(ac, - "(&(objectSid=%s)(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain)))", + "(&(objectSid=%s)(|(objectClass=domain)(objectClass=builtinDomain)))", ldap_encode_ndr_dom_sid(ac, ac->domain_sid)); if (filter == NULL) { ldb_oom(ldb); diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 2d87a017fd..2a0bb2dfe6 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -284,8 +284,7 @@ static int samldb_get_parent_domain(struct samldb_ctx *ac) ret = ldb_build_search_req(&req, ldb, ac, dn, LDB_SCOPE_BASE, "(|(objectClass=domain)" - "(objectClass=builtinDomain)" - "(objectClass=samba4LocalDomain))", + "(objectClass=builtinDomain))", attrs, NULL, ac, samldb_get_parent_domain_callback, @@ -559,10 +558,10 @@ static int samldb_get_sid_domain(struct samldb_ctx *ac) /* get the domain component part of the provided SID */ ac->domain_sid->num_auths--; - filter = talloc_asprintf(ac, "(&(objectSid=%s)" - "(|(objectClass=domain)" - "(objectClass=builtinDomain)" - "(objectClass=samba4LocalDomain)))", + filter = talloc_asprintf(ac, + "(&(objectSid=%s)" + "(|(objectClass=domain)" + "(objectClass=builtinDomain)))", ldap_encode_ndr_dom_sid(ac, ac->domain_sid)); if (filter == NULL) { return LDB_ERR_OPERATIONS_ERROR; -- cgit From 1e5562ff0410c1cedb2279eb7e0362f8d3867972 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 10 Oct 2009 09:06:07 +1100 Subject: s4:dsdb Add new functions to help modules do an ldb_search() These take an ldb_module argument, and avoid doing the search from the top of the stack again. (This will help when modules are initialised before being added to the partition set) Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/config.mk | 20 +++-- source4/dsdb/samdb/ldb_modules/naming_fsmo.c | 26 +----- source4/dsdb/samdb/ldb_modules/pdc_fsmo.c | 20 +---- source4/dsdb/samdb/ldb_modules/util.c | 128 +++++++++++++++++++++++++++ source4/dsdb/samdb/ldb_modules/util.h | 22 +++++ 5 files changed, 173 insertions(+), 43 deletions(-) create mode 100644 source4/dsdb/samdb/ldb_modules/util.c create mode 100644 source4/dsdb/samdb/ldb_modules/util.h (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index 456ff5756c..ea4e722822 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -1,3 +1,13 @@ +################################################ +# Start SUBSYSTEM DSDB_MODULE_HELPERS +[SUBSYSTEM::DSDB_MODULE_HELPERS] +PRIVATE_DEPENDENCIES = LIBLDB + +DSDB_MODULE_HELPERS_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/util.o + +$(eval $(call proto_header_template,$(dsdbsrcdir)/samdb/ldb_modules/util_proto.h,$(DSDB_MODULE_HELPERS_OBJ_FILES:.o=.c))) + + ################################################ # Start MODULE ldb_objectguid [MODULE::ldb_objectguid] @@ -15,7 +25,7 @@ ldb_objectguid_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/objectguid.o SUBSYSTEM = LIBLDB PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS \ LIBNDR NDR_DRSUAPI \ - NDR_DRSBLOBS LIBNDR + NDR_DRSBLOBS LIBNDR DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(repl_meta_data) # End MODULE ldb_repl_meta_data ################################################ @@ -39,7 +49,7 @@ ldb_dsdb_cache_OBJ_FILES = \ # Start MODULE ldb_schema_fsmo [MODULE::ldb_schema_fsmo] SUBSYSTEM = LIBLDB -PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS +PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(schema_fsmo) # End MODULE ldb_schema_fsmo ################################################ @@ -51,7 +61,7 @@ ldb_schema_fsmo_OBJ_FILES = \ # Start MODULE ldb_naming_fsmo [MODULE::ldb_naming_fsmo] SUBSYSTEM = LIBLDB -PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS +PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(naming_fsmo) # End MODULE ldb_naming_fsmo ################################################ @@ -63,7 +73,7 @@ ldb_naming_fsmo_OBJ_FILES = \ # Start MODULE ldb_pdc_fsmo [MODULE::ldb_pdc_fsmo] SUBSYSTEM = LIBLDB -PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS +PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(pdc_fsmo) # End MODULE ldb_pdc_fsmo ################################################ @@ -220,7 +230,7 @@ ldb_show_deleted_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/show_deleted.o # Start MODULE ldb_partition [MODULE::ldb_partition] SUBSYSTEM = LIBLDB -PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS SAMDB +PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS SAMDB DSDB_MODULE_HELPERS INIT_FUNCTION = LDB_MODULE(partition) # End MODULE ldb_partition ################################################ diff --git a/source4/dsdb/samdb/ldb_modules/naming_fsmo.c b/source4/dsdb/samdb/ldb_modules/naming_fsmo.c index 607bf054d2..15cad259ce 100644 --- a/source4/dsdb/samdb/ldb_modules/naming_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/naming_fsmo.c @@ -28,6 +28,7 @@ #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" #include "../lib/util/dlinklist.h" +#include "dsdb/samdb/ldb_modules/util.h" static int naming_fsmo_init(struct ldb_module *module) { @@ -65,34 +66,15 @@ static int naming_fsmo_init(struct ldb_module *module) } ldb_module_set_private(module, naming_fsmo); - ret = ldb_search(ldb, mem_ctx, &naming_res, - naming_dn, LDB_SCOPE_BASE, - naming_attrs, NULL); + ret = dsdb_module_search_dn(module, mem_ctx, &naming_res, + naming_dn, + naming_attrs); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_debug(ldb, LDB_DEBUG_WARNING, "naming_fsmo_init: no partitions dn present: (skip loading of naming contexts details)\n"); talloc_free(mem_ctx); return ldb_next_init(module); } - if (ret != LDB_SUCCESS) { - ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "naming_fsmo_init: failed to search the cross-ref container: %s: %s", - ldb_strerror(ret), ldb_errstring(ldb)); - talloc_free(mem_ctx); - return ret; - } - if (naming_res->count == 0) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - "naming_fsmo_init: no cross-ref container present: (skip loading of naming contexts details)\n"); - talloc_free(mem_ctx); - return ldb_next_init(module); - } else if (naming_res->count > 1) { - ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "naming_fsmo_init: [%u] cross-ref containers found on a base search", - naming_res->count); - talloc_free(mem_ctx); - return LDB_ERR_CONSTRAINT_VIOLATION; - } naming_fsmo->master_dn = ldb_msg_find_attr_as_dn(ldb, naming_fsmo, naming_res->msgs[0], "fSMORoleOwner"); if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), naming_fsmo->master_dn) == 0) { diff --git a/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c b/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c index 950f87eb74..6d814f9334 100644 --- a/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c @@ -27,6 +27,7 @@ #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" #include "../lib/util/dlinklist.h" +#include "dsdb/samdb/ldb_modules/util.h" static int pdc_fsmo_init(struct ldb_module *module) { @@ -64,9 +65,9 @@ static int pdc_fsmo_init(struct ldb_module *module) } ldb_module_set_private(module, pdc_fsmo); - ret = ldb_search(ldb, mem_ctx, &pdc_res, - pdc_dn, LDB_SCOPE_BASE, - pdc_attrs, NULL); + ret = dsdb_module_search_dn(module, mem_ctx, &pdc_res, + pdc_dn, + pdc_attrs); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_debug(ldb, LDB_DEBUG_WARNING, "pdc_fsmo_init: no domain object present: (skip loading of domain details)\n"); @@ -79,19 +80,6 @@ static int pdc_fsmo_init(struct ldb_module *module) talloc_free(mem_ctx); return ret; } - if (pdc_res->count == 0) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - "pdc_fsmo_init: no domain object present: (skip loading of domain details)\n"); - talloc_free(mem_ctx); - return ldb_next_init(module); - } else if (pdc_res->count > 1) { - ldb_debug_set(ldb, LDB_DEBUG_FATAL, - "pdc_fsmo_init: [%u] domain objects found on a base search", - pdc_res->count); - DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb))); - talloc_free(mem_ctx); - return LDB_ERR_CONSTRAINT_VIOLATION; - } pdc_fsmo->master_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, pdc_res->msgs[0], "fSMORoleOwner"); if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), pdc_fsmo->master_dn) == 0) { diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c new file mode 100644 index 0000000000..476eb08ed0 --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/util.c @@ -0,0 +1,128 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + + Copyright (C) Andrew Tridgell 2009 + Copyright (C) Andrew Bartlett 2009 + + 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "ldb.h" +#include "ldb_module.h" + +/* + search for attrs on one DN, in the modules below + */ +int dsdb_module_search_dn(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_result **_res, + struct ldb_dn *basedn, + const char * const *attrs) +{ + int ret; + struct ldb_request *req; + TALLOC_CTX *tmp_ctx; + struct ldb_result *res; + + tmp_ctx = talloc_new(mem_ctx); + + res = talloc_zero(tmp_ctx, struct ldb_result); + if (!res) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx, + basedn, + LDB_SCOPE_BASE, + NULL, + attrs, + NULL, + res, + ldb_search_default_callback, + NULL); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + ret = ldb_next_request(module, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + if (res->count != 1) { + /* we may be reading a DB that does not have the 'check base on search' option... */ + ret = LDB_ERR_NO_SUCH_OBJECT; + } else { + *_res = talloc_steal(mem_ctx, res); + } + talloc_free(tmp_ctx); + return ret; +} + +/* + search for attrs in the modules below + */ +int dsdb_module_search(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_result **_res, + struct ldb_dn *basedn, enum ldb_scope scope, + const char * const *attrs, + const char *expression) +{ + int ret; + struct ldb_request *req; + TALLOC_CTX *tmp_ctx; + struct ldb_result *res; + + tmp_ctx = talloc_new(mem_ctx); + + res = talloc_zero(tmp_ctx, struct ldb_result); + if (!res) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx, + basedn, + scope, + expression, + attrs, + NULL, + res, + ldb_search_default_callback, + NULL); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + ret = ldb_next_request(module, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + talloc_free(req); + if (ret == LDB_SUCCESS) { + *_res = talloc_steal(mem_ctx, res); + } + talloc_free(tmp_ctx); + return ret; +} + diff --git a/source4/dsdb/samdb/ldb_modules/util.h b/source4/dsdb/samdb/ldb_modules/util.h new file mode 100644 index 0000000000..0a1ab83c6d --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/util.h @@ -0,0 +1,22 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + + Copyright (C) Andrew Tridgell 2009 + Copyright (C) Andrew Bartlett 2009 + + 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "dsdb/samdb/ldb_modules/util_proto.h" -- cgit From c9f70fc3c7a6a44696a64ca40eca6e1995db35b9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 10 Oct 2009 09:10:03 +1100 Subject: s4:dsdb Search for the schema with dsdb_module_search(), in schema_fsmo This avoids using an ldb_search(), which would run from the top of the module stack. This will help us load the schema before the partitions are initialised. Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/schema_fsmo.c | 113 ++++++++++++++++++++++++--- 1 file changed, 101 insertions(+), 12 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c index c482ab57df..2b6606c147 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c @@ -5,6 +5,7 @@ checkings, it also loads the dsdb_schema. Copyright (C) Stefan Metzmacher 2007 + Copyright (C) Andrew Bartlett 2009 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 @@ -28,6 +29,7 @@ #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" #include "param/param.h" +#include "dsdb/samdb/ldb_modules/util.h" static int generate_objectClasses(struct ldb_context *ldb, struct ldb_message *msg, const struct dsdb_schema *schema); @@ -90,13 +92,107 @@ struct schema_fsmo_search_data { const struct dsdb_schema *schema; }; +/* + Given an LDB module (pointing at the schema DB), and the DN, set the populated schema +*/ + +static int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_module *module, + struct smb_iconv_convenience *iconv_convenience, + struct ldb_dn *schema_dn, + struct dsdb_schema **schema) +{ + TALLOC_CTX *tmp_ctx; + char *error_string; + int ret; + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct ldb_result *schema_res; + struct ldb_result *a_res; + struct ldb_result *c_res; + static const char *schema_attrs[] = { + "prefixMap", + "schemaInfo", + "fSMORoleOwner", + NULL + }; + unsigned flags; + + tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* we don't want to trace the schema load */ + flags = ldb_get_flags(ldb); + ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING); + + /* + * setup the prefix mappings and schema info + */ + ret = dsdb_module_search_dn(module, tmp_ctx, &schema_res, + schema_dn, schema_attrs); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + goto failed; + } else if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, + "dsdb_schema: failed to search the schema head: %s", + ldb_errstring(ldb)); + goto failed; + } + + /* + * load the attribute definitions + */ + ret = dsdb_module_search(module, tmp_ctx, &a_res, + schema_dn, LDB_SCOPE_ONELEVEL, NULL, + "(objectClass=attributeSchema)"); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, + "dsdb_schema: failed to search attributeSchema objects: %s", + ldb_errstring(ldb)); + goto failed; + } + + /* + * load the objectClass definitions + */ + ret = dsdb_module_search(module, tmp_ctx, &c_res, + schema_dn, LDB_SCOPE_ONELEVEL, NULL, + "(objectClass=classSchema)"); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, + "dsdb_schema: failed to search attributeSchema objects: %s", + ldb_errstring(ldb)); + goto failed; + } + + ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb, + lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), + schema_res, a_res, c_res, schema, &error_string); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, + "dsdb_schema load failed: %s", + error_string); + goto failed; + } + talloc_steal(mem_ctx, *schema); + +failed: + if (flags & LDB_FLG_ENABLE_TRACING) { + flags = ldb_get_flags(ldb); + ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING); + } + talloc_free(tmp_ctx); + return ret; +} + + static int schema_fsmo_init(struct ldb_module *module) { struct ldb_context *ldb; TALLOC_CTX *mem_ctx; struct ldb_dn *schema_dn; struct dsdb_schema *schema; - char *error_string = NULL; int ret; struct schema_fsmo_private_data *data; @@ -134,9 +230,9 @@ static int schema_fsmo_init(struct ldb_module *module) return LDB_ERR_OPERATIONS_ERROR; } - ret = dsdb_schema_from_schema_dn(mem_ctx, ldb, + ret = dsdb_schema_from_schema_dn(mem_ctx, module, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), - schema_dn, &schema, &error_string); + schema_dn, &schema); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_reset_err_string(ldb); @@ -147,9 +243,6 @@ static int schema_fsmo_init(struct ldb_module *module) } if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, - "schema_fsmo_init: dsdb_schema load failed: %s", - error_string); talloc_free(mem_ctx); return ret; } @@ -246,7 +339,6 @@ static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *r struct ldb_context *ldb; struct ldb_dn *schema_dn; struct dsdb_schema *schema; - char *error_string = NULL; int ret; TALLOC_CTX *mem_ctx; @@ -270,9 +362,9 @@ static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *r return LDB_ERR_OPERATIONS_ERROR; } - ret = dsdb_schema_from_schema_dn(mem_ctx, ldb, + ret = dsdb_schema_from_schema_dn(mem_ctx, module, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), - schema_dn, &schema, &error_string); + schema_dn, &schema); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_reset_err_string(ldb); @@ -283,9 +375,6 @@ static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *r } if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, - "schema_fsmo_extended: dsdb_schema load failed: %s", - error_string); talloc_free(mem_ctx); return ldb_next_request(module, req); } -- cgit From 8b67e1ab703e85182eb288138d3fb1fa8a903002 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Mon, 12 Oct 2009 17:32:24 +0200 Subject: s4:objectclass ldb module - Check for empty messages I think the check for empty messages fits best here. --- source4/dsdb/samdb/ldb_modules/objectclass.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index b6f1a1aa23..b5e058df0b 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -706,7 +706,13 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req if (!schema) { return ldb_next_request(module, req); } - objectclass_element = ldb_msg_find_element(req->op.mod.message, "objectClass"); + + /* As with the "real" AD we don't accept empty messages */ + if (req->op.mod.message->num_elements == 0) { + ldb_set_errstring(ldb, "objectclass: modify message must have " + "elements/attributes!"); + return LDB_ERR_UNWILLING_TO_PERFORM; + } ac = oc_init_context(module, req); if (ac == NULL) { @@ -715,6 +721,7 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req /* 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 */ -- cgit From 5931734be69d802a6fabbf2ec70866c60cac4b25 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Wed, 14 Oct 2009 11:40:25 +0200 Subject: s4:password_hash - load the domain parameters from the "loadparm context" And don't cut them out from the DNS hostname. --- source4/dsdb/samdb/ldb_modules/password_hash.c | 53 ++++++-------------------- 1 file changed, 11 insertions(+), 42 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index adb62d3544..a3c99f4222 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -87,9 +87,9 @@ struct domain_data { bool store_cleartext; uint_t pwdProperties; uint_t pwdHistoryLength; - char *netbios_domain; - char *dns_domain; - char *realm; + const char *netbios_domain; + const char *dns_domain; + const char *realm; }; struct setup_password_fields_io { @@ -1552,9 +1552,8 @@ static int get_domain_data_callback(struct ldb_request *req, struct ldb_context *ldb; struct domain_data *data; struct ph_context *ac; + struct loadparm_context *lp_ctx; int ret; - char *tmp; - char *p; ac = talloc_get_type(req->context, struct ph_context); ldb = ldb_module_get_ctx(ac->module); @@ -1591,43 +1590,13 @@ static int get_domain_data_callback(struct ldb_request *req, * but that doesn't really matter, as it's just used for salt * and kerberos principals, which don't exist here */ - tmp = ldb_dn_canonical_string(data, ares->message->dn); - if (!tmp) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } + lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), + struct loadparm_context); - /* But it puts a trailing (or just before 'builtin') / on things, so kill that */ - p = strchr(tmp, '/'); - if (p) { - p[0] = '\0'; - } - - data->dns_domain = strlower_talloc(data, tmp); - if (data->dns_domain == NULL) { - ldb_oom(ldb); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - data->realm = strupper_talloc(data, tmp); - if (data->realm == NULL) { - ldb_oom(ldb); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - /* FIXME: NetbIOS name is *always* the first domain component ?? -SSS */ - p = strchr(tmp, '.'); - if (p) { - p[0] = '\0'; - } - data->netbios_domain = strupper_talloc(data, tmp); - if (data->netbios_domain == NULL) { - ldb_oom(ldb); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } + data->dns_domain = lp_dnsdomain(lp_ctx); + data->realm = lp_realm(lp_ctx); + data->netbios_domain = lp_workgroup(lp_ctx); - talloc_free(tmp); ac->domain = data; break; @@ -1673,7 +1642,7 @@ static int build_domain_data_request(struct ph_context *ac) ldb = ldb_module_get_ctx(ac->module); filter = talloc_asprintf(ac, - "(&(objectSid=%s)(|(objectClass=domain)(objectClass=builtinDomain)))", + "(objectSid=%s)", ldap_encode_ndr_dom_sid(ac, ac->domain_sid)); if (filter == NULL) { ldb_oom(ldb); @@ -1682,7 +1651,7 @@ static int build_domain_data_request(struct ph_context *ac) return ldb_build_search_req(&ac->dom_req, ldb, ac, ldb_get_default_basedn(ldb), - LDB_SCOPE_SUBTREE, + LDB_SCOPE_BASE, filter, attrs, NULL, ac, get_domain_data_callback, -- cgit From fdeeafb481778ee9ef7e87f8afa046d5f311a769 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 15 Oct 2009 15:54:20 +1100 Subject: s4-dsdb: implement limit on rDN length w2k8 imposes a limit of 64 characters on the rDN --- source4/dsdb/samdb/ldb_modules/objectclass.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules') diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index b5e058df0b..003d6731d4 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -330,6 +330,8 @@ static int fix_dn(TALLOC_CTX *mem_ctx, struct ldb_dn **fixed_dn) { char *upper_rdn_attr; + const struct ldb_val *rdn_val; + /* Fix up the DN to be in the standard form, taking particular care to match the parent DN */ *fixed_dn = ldb_dn_copy(mem_ctx, parent_dn); @@ -339,15 +341,21 @@ static int fix_dn(TALLOC_CTX *mem_ctx, if (!upper_rdn_attr) { return LDB_ERR_OPERATIONS_ERROR; } - + /* Create a new child */ if (ldb_dn_add_child_fmt(*fixed_dn, "X=X") == false) { return LDB_ERR_OPERATIONS_ERROR; } + /* AD doesn't allow the rDN to be longer than 64 characters */ + rdn_val = ldb_dn_get_rdn_val(newdn); + if (!rdn_val || rdn_val->length > 64) { + DEBUG(2,(__location__ ": rDN longer than 64 limit for '%s'\n", ldb_dn_get_linearized(newdn))); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + /* And replace it with CN=foo (we need the attribute in upper case */ - return ldb_dn_set_component(*fixed_dn, 0, upper_rdn_attr, - *ldb_dn_get_rdn_val(newdn)); + 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 */ -- cgit