[SCM] Samba Shared Repository - branch master updated

Matthias Dieter Wallnöfer mdw at samba.org
Tue Nov 16 08:13:01 MST 2010


The branch, master has been updated
       via  d451ac1 s4:acl LDB module - use also here "dsdb_find_nc_root" to implement the NC-specific checks
       via  856e309 s4:descriptor LDB module - also "get_default_ag" should make use of "dsdb_find_nc_root"
       via  cebad70 s4:descriptor LDB module - handle the NCs in a more generic way by using "dsdb_find_nc_root"
       via  7cc2f98 s4:"dsdb_find_nc_root" - let it work also when the "namingContexts" attribute isn't available yet
       via  d2453b5 s4:descriptor LDB module - make more clear that special control entries never should be handled by modules
       via  f863f434 s4:objectclass LDB module - the "olddn" is the special DN for rename requests
      from  cce6627 s4-schema_load: Don't clean in_transaction flag until transaction is really finished

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


- Log -----------------------------------------------------------------
commit d451ac1f3ac7b391e3cb28dca8e665bf1e1beddd
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Tue Nov 16 14:22:27 2010 +0100

    s4:acl LDB module - use also here "dsdb_find_nc_root" to implement the NC-specific checks
    
    Autobuild-User: Matthias Dieter Wallnöfer <mdw at samba.org>
    Autobuild-Date: Tue Nov 16 15:12:13 UTC 2010 on sn-devel-104

commit 856e309b14491849ec65d37fc23e03dd07063e21
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Tue Nov 16 13:17:32 2010 +0100

    s4:descriptor LDB module - also "get_default_ag" should make use of "dsdb_find_nc_root"

commit cebad70ee6d8fb3e2f3d306d98fb88a4c8526f28
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Tue Nov 16 13:12:02 2010 +0100

    s4:descriptor LDB module - handle the NCs in a more generic way by using "dsdb_find_nc_root"

commit 7cc2f9803801dcae0a4780f46cd2b642fac1b1cf
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Tue Nov 16 15:20:04 2010 +0100

    s4:"dsdb_find_nc_root" - let it work also when the "namingContexts" attribute isn't available yet
    
    This is needed on provisioning when the modules aren't set up yet.

commit d2453b52d84c148176b7384d0973645423647d38
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Tue Nov 16 13:25:34 2010 +0100

    s4:descriptor LDB module - make more clear that special control entries never should be handled by modules

commit f863f434a01d49a27b963ec71a86727f0d95dc59
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Tue Nov 16 13:22:05 2010 +0100

    s4:objectclass LDB module - the "olddn" is the special DN for rename requests

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

Summary of changes:
 source4/dsdb/common/util.c                   |   42 ++++++++++---
 source4/dsdb/samdb/ldb_modules/acl.c         |   85 +++++++++++++++++---------
 source4/dsdb/samdb/ldb_modules/descriptor.c  |   63 ++++++++++++-------
 source4/dsdb/samdb/ldb_modules/objectclass.c |    2 +-
 4 files changed, 133 insertions(+), 59 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 7f6ce64..fb891ab 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -3282,15 +3282,41 @@ int dsdb_find_nc_root(struct ldb_context *samdb, TALLOC_CTX *mem_ctx, struct ldb
 		DEBUG(1,("Searching for namingContexts in rootDSE failed: %s\n", ldb_errstring(samdb)));
 		talloc_free(tmp_ctx);
 		return ret;
-       }
+	}
 
-       el = ldb_msg_find_element(root_res->msgs[0], "namingContexts");
-       if (!el) {
-               DEBUG(1,("Finding namingContexts element in root_res failed: %s\n",
-			ldb_errstring(samdb)));
-	       talloc_free(tmp_ctx);
-	       return LDB_ERR_NO_SUCH_ATTRIBUTE;
-       }
+	el = ldb_msg_find_element(root_res->msgs[0], "namingContexts");
+	if (!el) {
+		struct ldb_message *tmp_msg;
+
+		DEBUG(5,("Finding namingContexts element in root_res failed. Using a temporary list."));
+
+		/* This generates a temporary list of NCs in order to let the
+		 * provisioning work. */
+		tmp_msg = ldb_msg_new(tmp_ctx);
+		if (tmp_msg == NULL) {
+			talloc_free(tmp_ctx);
+			return ldb_oom(samdb);
+		}
+		ret = ldb_msg_add_steal_string(tmp_msg, "namingContexts",
+					       ldb_dn_alloc_linearized(tmp_msg, ldb_get_schema_basedn(samdb)));
+		if (ret != LDB_SUCCESS) {
+			talloc_free(tmp_ctx);
+			return ret;
+		}
+		ret = ldb_msg_add_steal_string(tmp_msg, "namingContexts",
+					       ldb_dn_alloc_linearized(tmp_msg, ldb_get_config_basedn(samdb)));
+		if (ret != LDB_SUCCESS) {
+			talloc_free(tmp_ctx);
+			return ret;
+		}
+		ret = ldb_msg_add_steal_string(tmp_msg, "namingContexts",
+					       ldb_dn_alloc_linearized(tmp_msg, ldb_get_default_basedn(samdb)));
+		if (ret != LDB_SUCCESS) {
+			talloc_free(tmp_ctx);
+			return ret;
+		}
+		el = &tmp_msg->elements[0];
+	}
 
        nc_dns = talloc_array(tmp_ctx, struct ldb_dn *, el->num_values);
        if (!nc_dns) {
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
index b6635b1..69ab72a 100644
--- a/source4/dsdb/samdb/ldb_modules/acl.c
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
@@ -438,6 +438,7 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req)
 	const struct dsdb_schema *schema;
 	struct ldb_message_element *oc_el;
 	const struct GUID *guid;
+	struct ldb_dn *nc_root;
 	struct ldb_control *as_system = ldb_request_get_control(req, LDB_CONTROL_AS_SYSTEM_OID);
 
 	if (as_system != NULL) {
@@ -447,19 +448,24 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req)
 	if (dsdb_module_am_system(module) || as_system) {
 		return ldb_next_request(module, req);
 	}
-
 	if (ldb_dn_is_special(req->op.add.message->dn)) {
 		return ldb_next_request(module, req);
 	}
+
 	ldb = ldb_module_get_ctx(module);
+
 	/* Creating an NC. There is probably something we should do here,
 	 * but we will establish that later */
-	/* FIXME: this has to be made dynamic at some point */
-	if ((ldb_dn_compare(req->op.add.message->dn, (ldb_get_schema_basedn(ldb))) == 0) ||
-	    (ldb_dn_compare(req->op.add.message->dn, (ldb_get_config_basedn(ldb))) == 0) ||
-	    (ldb_dn_compare(req->op.add.message->dn, (ldb_get_default_basedn(ldb))) == 0)) {
+
+	ret = dsdb_find_nc_root(ldb, req, req->op.add.message->dn, &nc_root);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+	if (ldb_dn_compare(nc_root, req->op.add.message->dn) == 0) {
+		talloc_free(nc_root);
 		return ldb_next_request(module, req);
 	}
+	talloc_free(nc_root);
 
 	schema = dsdb_get_schema(ldb, req);
 	if (!schema) {
@@ -812,12 +818,13 @@ fail:
 }
 
 /* similar to the modify for the time being.
- * We need to concider the special delete tree case, though - TODO */
+ * We need to consider the special delete tree case, though - TODO */
 static int acl_delete(struct ldb_module *module, struct ldb_request *req)
 {
 	int ret;
 	struct ldb_dn *parent = ldb_dn_get_parent(req, req->op.del.dn);
 	struct ldb_context *ldb;
+	struct ldb_dn *nc_root;
 	struct ldb_control *as_system = ldb_request_get_control(req, LDB_CONTROL_AS_SYSTEM_OID);
 
 	if (as_system != NULL) {
@@ -828,31 +835,42 @@ static int acl_delete(struct ldb_module *module, struct ldb_request *req)
 	if (dsdb_module_am_system(module) || as_system) {
 		return ldb_next_request(module, req);
 	}
-
 	if (ldb_dn_is_special(req->op.del.dn)) {
 		return ldb_next_request(module, req);
 	}
+
 	ldb = ldb_module_get_ctx(module);
-	/* first check if we have delete object right */
-	ret = dsdb_module_check_access_on_dn(module, req, req->op.del.dn, SEC_STD_DELETE, NULL);
-	if (ret == LDB_SUCCESS) {
-		return ldb_next_request(module, req);
+
+	/* Make sure we aren't deleting a NC */
+
+	ret = dsdb_find_nc_root(ldb, req, req->op.del.dn, &nc_root);
+	if (ret != LDB_SUCCESS) {
+		return ret;
 	}
+	if (ldb_dn_compare(nc_root, req->op.del.dn) == 0) {
+		talloc_free(nc_root);
+		DEBUG(10,("acl:deleting a NC\n"));
+		/* Windows returns "ERR_UNWILLING_TO_PERFORM */
+		return ldb_module_done(req, NULL, NULL,
+				       LDB_ERR_UNWILLING_TO_PERFORM);
+	}
+	talloc_free(nc_root);
 
-	/* Nope, we don't have delete object. Lets check if we have delete child on the parent */
-	/* No parent, so check fails */
-	/* FIXME: this has to be made dynamic at some point */
-	if ((ldb_dn_compare(req->op.del.dn, (ldb_get_schema_basedn(ldb))) == 0) ||
-	    (ldb_dn_compare(req->op.del.dn, (ldb_get_config_basedn(ldb))) == 0) ||
-	    (ldb_dn_compare(req->op.del.dn, (ldb_get_default_basedn(ldb))) == 0)) {
-		DEBUG(10,("acl:deleting an NC\n"));
-		return ldb_module_done(req, NULL, NULL, LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS);
+	/* First check if we have delete object right */
+	ret = dsdb_module_check_access_on_dn(module, req, req->op.del.dn,
+					     SEC_STD_DELETE, NULL);
+	if (ret == LDB_SUCCESS) {
+		return ldb_next_request(module, req);
 	}
 
-	ret = dsdb_module_check_access_on_dn(module, req, parent, SEC_ADS_DELETE_CHILD, NULL);
+	/* Nope, we don't have delete object. Lets check if we have delete
+	 * child on the parent */
+	ret = dsdb_module_check_access_on_dn(module, req, parent,
+					     SEC_ADS_DELETE_CHILD, NULL);
 	if (ret != LDB_SUCCESS) {
 		return ret;
 	}
+
 	return ldb_next_request(module, req);
 }
 
@@ -867,6 +885,7 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req)
 	struct dom_sid *sid = NULL;
 	struct ldb_result *acl_res;
 	const struct GUID *guid;
+	struct ldb_dn *nc_root;
 	struct object_tree *root = NULL;
 	struct object_tree *new_node = NULL;
 	struct ldb_control *as_system = ldb_request_get_control(req, LDB_CONTROL_AS_SYSTEM_OID);
@@ -892,8 +911,26 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req)
 	if (ldb_dn_is_special(req->op.rename.olddn)) {
 		return ldb_next_request(module, req);
 	}
+
 	ldb = ldb_module_get_ctx(module);
 
+	/* Make sure we aren't renaming/moving a NC */
+
+	ret = dsdb_find_nc_root(ldb, req, req->op.rename.olddn, &nc_root);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+	if (ldb_dn_compare(nc_root, req->op.rename.olddn) == 0) {
+		talloc_free(nc_root);
+		DEBUG(10,("acl:renaming/moving a NC\n"));
+		/* Windows returns "ERR_UNWILLING_TO_PERFORM */
+		return ldb_module_done(req, NULL, NULL,
+				       LDB_ERR_UNWILLING_TO_PERFORM);
+	}
+	talloc_free(nc_root);
+
+	/* Look for the parent */
+
 	ret = dsdb_module_search_dn(module, req, &acl_res, req->op.rename.olddn,
 				    acl_attrs,
 				    DSDB_FLAG_NEXT_MODULE |
@@ -967,14 +1004,6 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req)
 		return ldb_next_request(module, req);
 	}
 
-	/* What exactly to do in this case? It would fail anyway.. */
-	/* FIXME: this has to be made dynamic at some point */
-	if ((ldb_dn_compare(req->op.rename.newdn, (ldb_get_schema_basedn(ldb))) == 0) ||
-	    (ldb_dn_compare(req->op.rename.newdn, (ldb_get_config_basedn(ldb))) == 0) ||
-	    (ldb_dn_compare(req->op.rename.newdn, (ldb_get_default_basedn(ldb))) == 0)) {
-		DEBUG(10,("acl:moving as an NC\n"));
-		return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
-	}
 	/* new parent should have create child */
 	talloc_free(tmp_ctx);
 	tmp_ctx = talloc_new(req);
diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c
index 0515dfe..baf00ad 100644
--- a/source4/dsdb/samdb/ldb_modules/descriptor.c
+++ b/source4/dsdb/samdb/ldb_modules/descriptor.c
@@ -66,19 +66,21 @@ struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
 			       struct ldb_context *ldb)
 {
 	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-	struct ldb_dn *default_base_dn = ldb_get_default_basedn(ldb);
-	struct ldb_dn *schema_base_dn = ldb_get_schema_basedn(ldb);
-	struct ldb_dn *config_base_dn = ldb_get_config_basedn(ldb);
 	const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
 	struct dom_sid *da_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
 	struct dom_sid *ea_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ENTERPRISE_ADMINS);
 	struct dom_sid *sa_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_SCHEMA_ADMINS);
 	struct dom_sid *dag_sid;
+	struct ldb_dn *nc_root;
+	int ret;
 
-	/* FIXME: this has to be fixed regarding the forest DN (root DN) and
-	 * the domain DN (default DN) - they aren't always the same. */
+	ret = dsdb_find_nc_root(ldb, tmp_ctx, dn, &nc_root);
+	if (ret != LDB_SUCCESS) {
+		talloc_free(tmp_ctx);
+		return NULL;
+	}
 
-	if (ldb_dn_compare_base(schema_base_dn, dn) == 0){
+	if (ldb_dn_compare(nc_root, ldb_get_schema_basedn(ldb)) == 0) {
 		if (security_token_has_sid(token, sa_sid))
 			dag_sid = dom_sid_dup(mem_ctx, sa_sid);
 		else if (security_token_has_sid(token, ea_sid))
@@ -87,25 +89,23 @@ struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
 			dag_sid = dom_sid_dup(mem_ctx, da_sid);
 		else
 			dag_sid = NULL;
-	}
-	else if (ldb_dn_compare_base(config_base_dn, dn) == 0){
+	} else if (ldb_dn_compare(nc_root, ldb_get_config_basedn(ldb)) == 0) {
 		if (security_token_has_sid(token, ea_sid))
 			dag_sid = dom_sid_dup(mem_ctx, ea_sid);
 		else if (security_token_has_sid(token, da_sid))
 			dag_sid = dom_sid_dup(mem_ctx, da_sid);
 		else
 			dag_sid = NULL;
-	}
-	else if (ldb_dn_compare_base(default_base_dn, dn) == 0){
+	} else if (ldb_dn_compare(nc_root, ldb_get_default_basedn(ldb)) == 0) {
 		if (security_token_has_sid(token, da_sid))
 			dag_sid = dom_sid_dup(mem_ctx, da_sid);
 		else if (security_token_has_sid(token, ea_sid))
 				dag_sid = dom_sid_dup(mem_ctx, ea_sid);
 		else
 			dag_sid = NULL;
-	}
-	else
+	} else {
 		dag_sid = NULL;
+	}
 
 	talloc_free(tmp_ctx);
 	return dag_sid;
@@ -692,16 +692,28 @@ static int descriptor_do_add(struct descriptor_context *ac)
 					   sizeof(struct ldb_val));
 	}
 
-	/* NC's have no parent */
-	/* FIXME: this has to be made dynamic at some point */
-	if ((ldb_dn_compare(ac->msg->dn, (ldb_get_schema_basedn(ldb))) == 0) ||
-	    (ldb_dn_compare(ac->msg->dn, (ldb_get_config_basedn(ldb))) == 0) ||
-	    (ldb_dn_compare(ac->msg->dn, (ldb_get_default_basedn(ldb))) == 0)) {
-		ac->parentsd_val = NULL;
-	} else if (ac->search_res != NULL) {
-		struct ldb_message_element *parent_element = ldb_msg_find_element(ac->search_res->message, "nTSecurityDescriptor");
-		if (parent_element) {
-			ac->parentsd_val = talloc_memdup(ac, &parent_element->values[0], sizeof(struct ldb_val));
+	/* If we do have a parent, then please fetch it's security descriptor.
+	 * But have in mind: NCs don't have any parents! That means
+	 * "CN=Configuration,DC=example,DC=com" has no parent
+	 * "DC=example,DC=com" since this is located under another NC! */
+	if (ac->search_res != NULL) {
+		struct ldb_message_element *parent_element = NULL;
+		struct ldb_dn *nc_root;
+
+		ret = dsdb_find_nc_root(ldb, ac, ac->msg->dn, &nc_root);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+
+		if (ldb_dn_compare(ac->msg->dn, nc_root) != 0) {
+			/* we aren't any NC */
+			parent_element = ldb_msg_find_element(ac->search_res->message,
+							      "nTSecurityDescriptor");
+			if (parent_element != NULL) {
+				ac->parentsd_val = talloc_memdup(ac,
+								 &parent_element->values[0],
+								 sizeof(struct ldb_val));
+			}
 		}
 	}
 
@@ -785,6 +797,7 @@ static int descriptor_change(struct ldb_module *module, struct ldb_request *req)
 	}
 	ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_change: %s\n", ldb_dn_get_linearized(dn));
 
+	/* do not manipulate our control entries */
 	if (ldb_dn_is_special(dn)) {
 		return ldb_next_request(module, req);
 	}
@@ -865,6 +878,12 @@ static int descriptor_rename(struct ldb_module *module, struct ldb_request *req)
 {
 	struct ldb_context *ldb = ldb_module_get_ctx(module);
 	ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_rename: %s\n", ldb_dn_get_linearized(req->op.rename.olddn));
+
+	/* do not manipulate our control entries */
+	if (ldb_dn_is_special(req->op.rename.olddn)) {
+		return ldb_next_request(module, req);
+	}
+
 	return ldb_next_request(module, req);
 }
 
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index 5a7c67e..7dc3ae2 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -1209,7 +1209,7 @@ static int objectclass_rename(struct ldb_module *module, struct ldb_request *req
 	ldb_debug(ldb, LDB_DEBUG_TRACE, "objectclass_rename\n");
 
 	/* do not manipulate our control entries */
-	if (ldb_dn_is_special(req->op.rename.newdn)) {
+	if (ldb_dn_is_special(req->op.rename.olddn)) {
 		return ldb_next_request(module, req);
 	}
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list