[PATCH 01/22] dsdb: Change acl module to look for instanceType flag rather than list of NCs

abartlet at samba.org abartlet at samba.org
Tue Aug 19 20:06:36 MDT 2014


From: Andrew Bartlett <abartlet at samba.org>

This avoids any DNs being a free pass beyond the ACL code, instead it is based on the CN=Partitions ACL.

Andrew Bartlett
---
 source4/dsdb/samdb/ldb_modules/acl.c          | 87 ++++++++++++++++++++++-----
 source4/dsdb/samdb/ldb_modules/instancetype.c |  5 ++
 2 files changed, 77 insertions(+), 15 deletions(-)

diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
index b4f7cef..90670da 100644
--- a/source4/dsdb/samdb/ldb_modules/acl.c
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
@@ -749,8 +749,8 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req)
 	struct ldb_context *ldb;
 	const struct dsdb_schema *schema;
 	const struct dsdb_class *objectclass;
-	struct ldb_dn *nc_root;
 	struct ldb_control *as_system;
+	struct ldb_message_element *el;
 
 	if (ldb_dn_is_special(req->op.add.message->dn)) {
 		return ldb_next_request(module, req);
@@ -772,19 +772,6 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req)
 		return ldb_oom(ldb);
 	}
 
-	/* Creating an NC. There is probably something we should do here,
-	 * but we will establish that later */
-
-	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) {
 		return ldb_operr(ldb);
@@ -793,15 +780,85 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req)
 	objectclass = dsdb_get_structural_oc_from_msg(schema, req->op.add.message);
 	if (!objectclass) {
 		ldb_asprintf_errstring(ldb_module_get_ctx(module),
-				       "acl: unable to find or validate structrual objectClass on %s\n",
+				       "acl: unable to find or validate structural objectClass on %s\n",
 				       ldb_dn_get_linearized(req->op.add.message->dn));
 		return ldb_module_done(req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
 	}
 
+	el = ldb_msg_find_element(req->op.add.message, "instanceType");
+	if (el != NULL) {
+		unsigned int instanceType;
+		if (el->num_values != 1) {
+			ldb_set_errstring(ldb, "acl: the 'instanceType' attribute is single-valued!");
+			return LDB_ERR_UNWILLING_TO_PERFORM;
+		}
+
+		instanceType = ldb_msg_find_attr_as_uint(req->op.add.message,
+							 "instanceType", 0);
+		if (instanceType & INSTANCE_TYPE_IS_NC_HEAD) {
+			static const char *no_attrs[] = { NULL };
+			struct ldb_dn *partitions_dn = samdb_partitions_dn(ldb, req);
+			struct ldb_result *partition_res;
+			if (!partitions_dn) {
+				ldb_set_errstring(ldb, "acl: CN=partitions dn could not be generated!");
+				return LDB_ERR_UNWILLING_TO_PERFORM;
+			}
+
+			ret = dsdb_module_search(module, req, &partition_res, partitions_dn, LDB_SCOPE_ONELEVEL,
+						 no_attrs,
+						 DSDB_FLAG_NEXT_MODULE |
+						 DSDB_FLAG_AS_SYSTEM |
+						 DSDB_SEARCH_ONE_ONLY |
+						 DSDB_SEARCH_SHOW_RECYCLED,
+						 req, "(&(nCName=%s)(objectClass=crossRef))", ldb_dn_get_linearized(req->op.add.message->dn));
+
+			if (ret == LDB_SUCCESS) {
+				/* Check that we can write to the crossRef object MS-ADTS 3.1.1.5.2.8.2 */
+				ret = dsdb_module_check_access_on_dn(module, req, partition_res->msgs[0]->dn,
+								     SEC_ADS_WRITE_PROP,
+								     &objectclass->schemaIDGUID, req);
+				if (ret != LDB_SUCCESS) {
+					ldb_asprintf_errstring(ldb_module_get_ctx(module),
+							       "acl: ACL check failed on crossRef object %s: %s\n",
+							       ldb_dn_get_linearized(partition_res->msgs[0]->dn),
+							       ldb_errstring(ldb));
+					return ret;
+				}
+
+				/*
+				 * TODO: Remaining checks, like if we are
+				 * the naming master etc need to be handled
+				 * in the instanceType module
+				 */
+				return ldb_next_request(module, req);
+			}
+			/* Check that we can create a crossRef object MS-ADTS 3.1.1.5.2.8.2 */
+			ret = dsdb_module_check_access_on_dn(module, req, partitions_dn,
+							     SEC_ADS_CREATE_CHILD,
+							     &objectclass->schemaIDGUID, req);
+			/* Allow provision bootstrap */
+			if (ret != LDB_SUCCESS && (ret != LDB_ERR_NO_SUCH_OBJECT && ldb_request_get_control(req, LDB_CONTROL_RELAX_OID))) {
+				ldb_asprintf_errstring(ldb_module_get_ctx(module),
+						       "acl: ACL check failed on CN=Partitions crossRef container %s: %s\n",
+						       ldb_dn_get_linearized(partitions_dn), ldb_errstring(ldb));
+				return ret;
+			}
+			/*
+			 * TODO: Remaining checks, like if we are the naming
+			 * master and adding the crossRef object need to be
+			 * handled in the instanceType module
+			 */
+			return ldb_next_request(module, req);
+		}
+	}
+
 	ret = dsdb_module_check_access_on_dn(module, req, parent,
 					     SEC_ADS_CREATE_CHILD,
 					     &objectclass->schemaIDGUID, req);
 	if (ret != LDB_SUCCESS) {
+		ldb_asprintf_errstring(ldb_module_get_ctx(module),
+				       "acl: unable to find or validate structrual objectClass on %s\n",
+				       ldb_dn_get_linearized(req->op.add.message->dn));
 		return ret;
 	}
 	return ldb_next_request(module, req);
diff --git a/source4/dsdb/samdb/ldb_modules/instancetype.c b/source4/dsdb/samdb/ldb_modules/instancetype.c
index c35f4b6..d700adf 100644
--- a/source4/dsdb/samdb/ldb_modules/instancetype.c
+++ b/source4/dsdb/samdb/ldb_modules/instancetype.c
@@ -84,6 +84,11 @@ static int instancetype_add(struct ldb_module *module, struct ldb_request *req)
 				ldb_set_errstring(ldb, "instancetype: if TYPE_IS_NC_HEAD was set, then also TYPE_WRITE is requested!");
 				return LDB_ERR_UNWILLING_TO_PERFORM;
 			}
+			/*
+			 * TODO: Confirm we are naming master or start
+			 * a remote call to the naming master to
+			 * create the crossRef object
+			 */
 		}
 
 		/* we did only tests, so proceed with the original request */
-- 
2.0.1



More information about the samba-technical mailing list