[SCM] Samba Shared Repository - branch master updated

Matthias Dieter Wallnöfer mdw at samba.org
Sun Aug 1 14:11:59 MDT 2010


The branch, master has been updated
       via  e92f447... s4:ldap.py - additional "instanceType" checks
       via  c38219a... s4:instancetype LDB module - add checks requested by MS-ADTS 3.1.1.5.2.2
       via  ba4578f... s4:objectclass LDB module - consider the "instanceType" when adding NCs
       via  89c7859... s4:descriptor LDB module - remove the "forest DN" check
       via  f824e45... s4:acl LDB module - remove the "forest DN" check
       via  149f425... s4:acl LDB module - remove unused call "is_root_base_dn"
      from  3f2a8d5... s4:urgent_replication.py test - adapt the test for the harder delete restrictions

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


- Log -----------------------------------------------------------------
commit e92f44782385be5315daa77f7821296f96ea729d
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Aug 1 21:12:50 2010 +0200

    s4:ldap.py - additional "instanceType" checks

commit c38219adfc12828d436bd46b17107feba619aa55
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Aug 1 17:34:43 2010 +0200

    s4:instancetype LDB module - add checks requested by MS-ADTS 3.1.1.5.2.2
    
    We've to test for the WRITE flag if we are performing an NC add. And if it
    isn't an NC add then only the WRITE or no flag is allowed.

commit ba4578f98b411f175803160a9a1f81c1c3786f1f
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Aug 1 17:36:11 2010 +0200

    s4:objectclass LDB module - consider the "instanceType" when adding NCs
    
    This is requested by MS-ADTS 3.1.1.5.2.2 (NC add operation).

commit 89c7859006a47d646762f8f3e2256f72d6133c70
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Aug 1 17:02:45 2010 +0200

    s4:descriptor LDB module - remove the "forest DN" check
    
    Also here we have to work with the default base DN.
    
    After some reading I've discovered that this isn't really true. The forest
    partition does exist on one or more DCs and is there the same as the default
    base DN (which is already checked by the module).
    And if we have other DCs which contain child domains then they never contain
    data of the forest domain beside the schema and the configuration partition
    (which are checked anyway) since a DC can always contain only one domain!
    
    Link: http://www.informit.com/articles/article.aspx?p=26896&seqNum=5

commit f824e459f0c7971e86ff214bdfe84ce93dba14aa
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Aug 1 17:02:45 2010 +0200

    s4:acl LDB module - remove the "forest DN" check
    
    After some reading I've discovered that this isn't really true. The forest
    partition does exist on one or more DCs and is there the same as the default
    base DN (which is already checked by the module).
    And if we have other DCs which contain child domains then they never contain
    data of the forest domain beside the schema and the configuration partition
    (which are checked anyway) since a DC can always contain only one domain!
    
    Link: http://www.informit.com/articles/article.aspx?p=26896&seqNum=5

commit 149f4251c5ae38d598a14aa899f5b418acf1c962
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Aug 1 16:39:45 2010 +0200

    s4:acl LDB module - remove unused call "is_root_base_dn"

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/acl.c          |   17 ++------------
 source4/dsdb/samdb/ldb_modules/descriptor.c   |    7 ++---
 source4/dsdb/samdb/ldb_modules/instancetype.c |   26 +++++++++++++++++-----
 source4/dsdb/samdb/ldb_modules/objectclass.c  |   28 ++++++++++++++++---------
 source4/dsdb/tests/python/ldap.py             |   23 ++++++++++++++++++++
 5 files changed, 67 insertions(+), 34 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
index eedeb1a..1b85c5d 100644
--- a/source4/dsdb/samdb/ldb_modules/acl.c
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
@@ -64,14 +64,6 @@ struct acl_context {
 	struct dsdb_schema *schema;
 };
 
-bool is_root_base_dn(struct ldb_context *ldb, struct ldb_dn *dn_to_check)
-{
-	int result;
-	struct ldb_dn *root_base_dn = ldb_get_root_basedn(ldb);
-	result = ldb_dn_compare(root_base_dn,dn_to_check);
-	return (result==0);
-}
-
 static struct security_token *acl_user_token(struct ldb_module *module)
 {
 	struct ldb_context *ldb = ldb_module_get_ctx(module);
@@ -631,8 +623,7 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req)
 	/* 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) ||
-	    (ldb_dn_compare(req->op.add.message->dn, (ldb_get_root_basedn(ldb))) == 0)) {
+	    (ldb_dn_compare(req->op.add.message->dn, (ldb_get_default_basedn(ldb))) == 0)) {
 		return ldb_next_request(module, req);
 	}
 
@@ -1033,8 +1024,7 @@ static int acl_delete(struct ldb_module *module, struct ldb_request *req)
 	/* 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) ||
-	    (ldb_dn_compare(req->op.del.dn, (ldb_get_root_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);
 	}
@@ -1161,8 +1151,7 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req)
 	/* 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) ||
-	    (ldb_dn_compare(req->op.rename.newdn, (ldb_get_root_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;
 	}
diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c
index d96e18e..f32383e 100644
--- a/source4/dsdb/samdb/ldb_modules/descriptor.c
+++ b/source4/dsdb/samdb/ldb_modules/descriptor.c
@@ -63,7 +63,7 @@ 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 *root_base_dn = ldb_get_root_basedn(ldb);
+	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);
@@ -93,7 +93,7 @@ struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
 		else
 			dag_sid = NULL;
 	}
-	else if (ldb_dn_compare_base(root_base_dn, dn) == 0){
+	else if (ldb_dn_compare_base(default_base_dn, dn) == 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))
@@ -705,8 +705,7 @@ static int descriptor_do_add(struct descriptor_context *ac)
 	/* FIXME: this has to be made dynamic at some point */
 	if ((ldb_dn_compare(msg->dn, (ldb_get_schema_basedn(ldb))) == 0) ||
 	    (ldb_dn_compare(msg->dn, (ldb_get_config_basedn(ldb))) == 0) ||
-	    (ldb_dn_compare(msg->dn, (ldb_get_default_basedn(ldb))) == 0) ||
-	    (ldb_dn_compare(msg->dn, (ldb_get_root_basedn(ldb))) == 0)) {
+	    (ldb_dn_compare(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");
diff --git a/source4/dsdb/samdb/ldb_modules/instancetype.c b/source4/dsdb/samdb/ldb_modules/instancetype.c
index 7360c7c..0a11bcc 100644
--- a/source4/dsdb/samdb/ldb_modules/instancetype.c
+++ b/source4/dsdb/samdb/ldb_modules/instancetype.c
@@ -86,7 +86,7 @@ static int instancetype_add(struct ldb_module *module, struct ldb_request *req)
 	struct ldb_message *msg;
 	struct ldb_message_element *el;
 	struct it_context *ac;
-	uint32_t instance_type;
+	uint32_t instanceType;
 	int ret;
 
 	ldb = ldb_module_get_ctx(module);
@@ -100,8 +100,6 @@ static int instancetype_add(struct ldb_module *module, struct ldb_request *req)
 
 	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, "instancetype: the 'instanceType' attribute is single-valued!");
 			return LDB_ERR_UNWILLING_TO_PERFORM;
@@ -110,9 +108,25 @@ static int instancetype_add(struct ldb_module *module, struct ldb_request *req)
 		instanceType = ldb_msg_find_attr_as_uint(req->op.add.message,
 							 "instanceType", 0);
 		if (!(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
+			/* if we have no NC add operation (no TYPE_IS_NC_HEAD)
+			 * then "instanceType" can only be "0" or "TYPE_WRITE".
+			 */
+			if ((instanceType != 0) &&
+			    ((instanceType & INSTANCE_TYPE_WRITE) == 0)) {
+				ldb_set_errstring(ldb, "instancetype: if TYPE_IS_NC_HEAD wasn't set, then only TYPE_WRITE or 0 are allowed!");
+				return LDB_ERR_UNWILLING_TO_PERFORM;
+			}
+
 			return ldb_next_request(module, req);		
 		}
 
+		/* if we have a NC add operation then we need also the
+		 * "TYPE_WRITE" flag in order to succeed. */
+		if (!(instanceType & INSTANCE_TYPE_WRITE)) {
+			ldb_set_errstring(ldb, "instancetype: if TYPE_IS_NC_HEAD was set, then also TYPE_WRITE is requested!");
+			return LDB_ERR_UNWILLING_TO_PERFORM;
+		}
+
 		/* Forward the 'add' to the modules below, but if it
 		 * succeeds, then we might need to add the boilerplate
 		 * entries (lost+found, deleted objects) */
@@ -146,11 +160,11 @@ static int instancetype_add(struct ldb_module *module, struct ldb_request *req)
 	/*
 	 * TODO: calculate correct instance type
 	 */
-	instance_type = INSTANCE_TYPE_WRITE;
+	instanceType = INSTANCE_TYPE_WRITE;
 
-	ret = ldb_msg_add_fmt(msg, "instanceType", "%u", instance_type);
+	ret = ldb_msg_add_fmt(msg, "instanceType", "%u", instanceType);
 	if (ret != LDB_SUCCESS) {
-		return ldb_oom(ldb);
+		return ret;
 	}
 
 	ret = ldb_build_add_req(&down_req, ldb, req,
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index b71f91f..44d8889 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -374,11 +374,14 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
 		return ldb_next_request(module, req);
 	}
 
-	/* An add operation on the root basedn has a special handling when the
-	 * relax control isn't specified. */
-	if (ldb_dn_compare(ldb_get_root_basedn(ldb), req->op.add.message->dn) == 0) {
-		if (ldb_request_get_control(req,
-					    LDB_CONTROL_RELAX_OID) == NULL) {
+	/* An add operation on the basedn without "NC-add" operation isn't
+	 * allowed. */
+	if (ldb_dn_compare(ldb_get_default_basedn(ldb), req->op.add.message->dn) == 0) {
+		unsigned int instanceType;
+
+		instanceType = ldb_msg_find_attr_as_uint(req->op.add.message,
+							 "instanceType", 0);
+		if (!(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
 			/* When we are trying to readd the root basedn then
 			 * this is denied, but with an interesting mechanism:
 			 * there is generated a referral with the last
@@ -457,15 +460,20 @@ static int objectclass_do_add(struct oc_context *ac)
 	/* Check if we have a valid parent - this check is needed since
 	 * we don't get a LDB_ERR_NO_SUCH_OBJECT error. */
 	if (ac->search_res == NULL) {
-		if (ldb_dn_compare(ldb_get_root_basedn(ldb), msg->dn) == 0) {
-			/* Allow the tree to be started but don't keep any
-			 * error strings - they're meaningless. */
-			ldb_set_errstring(ldb, NULL);
-		} else {
+		unsigned int instanceType;
+
+		/* An add operation on partition DNs without "NC-add" operation
+		 * isn't allowed. */
+		instanceType = ldb_msg_find_attr_as_uint(ac->req->op.add.message,
+							 "instanceType", 0);
+		if (!(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
 			ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, parent does not exist!", 
 					       ldb_dn_get_linearized(msg->dn));
 			return LDB_ERR_NO_SUCH_OBJECT;
 		}
+
+		/* Don't keep any error messages - we've to add a partition */
+		ldb_set_errstring(ldb, NULL);
 	} else {
 		/* Fix up the DN to be in the standard form, taking
 		 * particular care to match the parent DN */
diff --git a/source4/dsdb/tests/python/ldap.py b/source4/dsdb/tests/python/ldap.py
index ea0aa3a..728c537 100755
--- a/source4/dsdb/tests/python/ldap.py
+++ b/source4/dsdb/tests/python/ldap.py
@@ -658,6 +658,7 @@ class BasicTests(unittest.TestCase):
         """Tests the 'instanceType' attribute"""
         print "Tests the 'instanceType' attribute"""
 
+        # The instance type is single-valued
         try:
             self.ldb.add({
                 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
@@ -667,6 +668,28 @@ class BasicTests(unittest.TestCase):
         except LdbError, (num, _):
             self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
 
+        # The head NC flag cannot be set without the write flag
+        try:
+            self.ldb.add({
+                "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
+                "objectclass": "group",
+                "instanceType": "1" })
+            self.fail()
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+        # We cannot manipulate NCs without the head NC flag
+        try:
+            self.ldb.add({
+                "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
+                "objectclass": "group",
+                "instanceType": "32" })
+            self.fail()
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
+
+
         self.ldb.add({
              "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
              "objectclass": "group"})


-- 
Samba Shared Repository


More information about the samba-cvs mailing list