[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-400-g467cc69

Andrew Tridgell tridge at samba.org
Tue Mar 17 03:24:37 GMT 2009


The branch, master has been updated
       via  467cc6927f57e36ce9b97131e72b79ef6e39a668 (commit)
       via  a1ebb850209289734b12ea966b01d295d8fc436d (commit)
      from  382d8069adcc49e351eef63d86036ae553b119a2 (commit)

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


- Log -----------------------------------------------------------------
commit 467cc6927f57e36ce9b97131e72b79ef6e39a668
Merge: a1ebb850209289734b12ea966b01d295d8fc436d 382d8069adcc49e351eef63d86036ae553b119a2
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Mar 17 14:19:25 2009 +1100

    Merge branch 'master' of ssh://git.samba.org/data/git/samba

commit a1ebb850209289734b12ea966b01d295d8fc436d
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Mar 17 14:18:53 2009 +1100

    added support for parentGUID
    
    This is made up of 4 parts:
    
      1) change our schema to include the parentGUID attribute type
    
      2) in the add hook in the objectclass module, get the objectGUID of
      the parent and add it to the message as parentGUID
    
      3) in the rename hook in the objectclass module, get the objectGUID
      of the new parent, and insert an async modify request after the
      renmam is done
    
      4) added a simple test suite

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/objectclass.c |   89 ++++++++++++++++++++++++--
 source4/lib/ldb/tests/python/ldap.py         |   30 +++++++++
 source4/setup/schema.ldif                    |   15 ++++
 3 files changed, 129 insertions(+), 5 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index 898d913..7883bcc 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -414,6 +414,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 };
 
 	ldb = ldb_module_get_ctx(module);
 
@@ -449,7 +450,7 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
 
 	ret = ldb_build_search_req(&search_req, ldb,
 				   ac, parent_dn, LDB_SCOPE_BASE,
-				   "(objectClass=*)", NULL,
+				   "(objectClass=*)", parent_attrs,
 				   NULL,
 				   ac, get_search_callback,
 				   req);
@@ -500,7 +501,8 @@ static int objectclass_do_add(struct oc_context *ac)
 			return LDB_ERR_UNWILLING_TO_PERFORM;
 		}
 	} else {
-		
+		const struct ldb_val *parent_guid;
+
 		/* Fix up the DN to be in the standard form, taking particular care to match the parent DN */
 		ret = fix_dn(msg, 
 			     ac->req->op.add.message->dn,
@@ -514,10 +516,24 @@ static int objectclass_do_add(struct oc_context *ac)
 			return ret;
 		}
 
+		parent_guid = ldb_msg_find_ldb_val(ac->search_res->message, "objectGUID");
+		if (parent_guid == NULL) {
+			ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, parent does not have an objectGUID!", 
+					       ldb_dn_get_linearized(msg->dn));
+			talloc_free(mem_ctx);
+			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", 
+					       ldb_dn_get_linearized(msg->dn));
+			talloc_free(mem_ctx);
+			return LDB_ERR_UNWILLING_TO_PERFORM;						
+		}
 	}
 
 	if (schema) {
@@ -974,7 +990,7 @@ static int objectclass_do_rename(struct oc_context *ac);
 
 static int objectclass_rename(struct ldb_module *module, struct ldb_request *req)
 {
-	static const char * const attrs[] = { NULL };
+	static const char * const attrs[] = { "objectGUID", NULL };
 	struct ldb_context *ldb;
 	struct ldb_request *search_req;
 	struct oc_context *ac;
@@ -1007,6 +1023,9 @@ static int objectclass_rename(struct ldb_module *module, struct ldb_request *req
 		ldb_oom(ldb);
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
+
+	/* note that the results of this search are kept and used to
+	   update the parentGUID in objectclass_rename_callback() */
 	ret = ldb_build_search_req(&search_req, ldb,
 				   ac, parent_dn, LDB_SCOPE_BASE,
 				   "(objectClass=*)",
@@ -1022,6 +1041,66 @@ static int objectclass_rename(struct ldb_module *module, struct ldb_request *req
 	return ldb_next_request(ac->module, search_req);
 }
 
+/* 
+   called after the rename happens. 
+   We now need to fix the parentGUID of the object to be the objectGUID of
+   the new parent 
+*/
+static int objectclass_rename_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+	struct ldb_context *ldb;
+	struct oc_context *ac;
+	const struct ldb_val *parent_guid;
+	struct ldb_request *mod_req = NULL;
+	int ret;
+	struct ldb_message *msg;
+	struct ldb_message_element *el = NULL;
+
+	ac = talloc_get_type(req->context, struct oc_context);
+	ldb = ldb_module_get_ctx(ac->module);
+
+	/* make sure the rename succeeded */
+	if (!ares) {
+		return ldb_module_done(ac->req, NULL, NULL,
+					LDB_ERR_OPERATIONS_ERROR);
+	}
+	if (ares->error != LDB_SUCCESS) {
+		return ldb_module_done(ac->req, ares->controls,
+					ares->response, ares->error);
+	}
+
+
+	/* the ac->search_res should contain the new parents objectGUID */
+	parent_guid = ldb_msg_find_ldb_val(ac->search_res->message, "objectGUID");
+	if (parent_guid == NULL) {
+		ldb_asprintf_errstring(ldb, "objectclass: Cannot rename %s, new parent does not have an objectGUID!", 
+				       ldb_dn_get_linearized(ac->req->op.rename.newdn));
+		return LDB_ERR_UNWILLING_TO_PERFORM;
+
+	}
+
+	/* construct the modify message */
+	msg = ldb_msg_new(ac);
+	if (msg == NULL) {
+		ldb_oom(ldb);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	msg->dn = ac->req->op.rename.newdn;
+
+	ret = ldb_msg_add_value(msg, "parentGUID", parent_guid, &el);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	el->flags = LDB_FLAG_MOD_REPLACE;
+
+	ret = ldb_build_mod_req(&mod_req, ldb, ac, msg,
+				NULL, ac, oc_op_callback, req);
+
+	return ldb_next_request(ac->module, mod_req);
+}
+
 static int objectclass_do_rename(struct oc_context *ac)
 {
 	struct ldb_context *ldb;
@@ -1055,7 +1134,7 @@ static int objectclass_do_rename(struct oc_context *ac)
 	ret = ldb_build_rename_req(&rename_req, ldb, ac,
 				   ac->req->op.rename.olddn, fixed_dn,
 				   ac->req->controls,
-				   ac, oc_op_callback,
+				   ac, objectclass_rename_callback,
 				   ac->req);
 	if (ret != LDB_SUCCESS) {
 		return ret;
diff --git a/source4/lib/ldb/tests/python/ldap.py b/source4/lib/ldb/tests/python/ldap.py
index a30273f..7d2c7d0 100755
--- a/source4/lib/ldb/tests/python/ldap.py
+++ b/source4/lib/ldb/tests/python/ldap.py
@@ -90,6 +90,36 @@ class BasicTests(unittest.TestCase):
         except LdbError, (num, _): 
             self.assertEquals(num, ERR_NO_SUCH_OBJECT)
 
+    def test_parentGUID(self):
+        """Test parentGUID behaviour"""
+        print "Testing parentGUID behaviour\n"
+        
+        self.ldb.add({
+            "dn": "cn=parentguidtest,cn=users," + self.base_dn,
+            "objectclass":"user",
+            "samaccountname":"parentguidtest"});
+        res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE,
+                          attrs=["parentGUID"]);
+        res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE,
+                          attrs=["objectGUID"]);
+        self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
+
+        """Test parentGUID behaviour"""
+        print "Testing parentGUID behaviour on rename\n"
+
+        self.ldb.add({
+            "dn": "cn=testotherusers," + self.base_dn,
+            "objectclass":"container"});
+        res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
+                          attrs=["objectGUID"]);
+        ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
+                   "cn=parentguidtest,cn=testotherusers," + self.base_dn);
+        res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
+                          scope=SCOPE_BASE,
+                          attrs=["parentGUID"]);
+        self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
+        
+
     def test_all(self):
         """Basic tests"""
 
diff --git a/source4/setup/schema.ldif b/source4/setup/schema.ldif
index 56eb7ce..a4dfaea 100644
--- a/source4/setup/schema.ldif
+++ b/source4/setup/schema.ldif
@@ -4096,6 +4096,21 @@ systemOnly: TRUE
 systemFlags: 19
 isMemberOfPartialAttributeSet: TRUE
 
+dn: CN=Parent-GUID,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: Parent-GUID
+ldapDisplayName: parentGUID
+attributeId: 1.2.840.113556.1.4.1224
+attributeSyntax: 2.5.5.10
+omSyntax: 4
+isSingleValued: TRUE
+schemaIdGuid: 2df90d74-009f-11d2-aa4c-00c04fd7d83a
+systemOnly: TRUE
+searchFlags: 0
+systemFlags: 134217748
+schemaFlagsEx: 1
+
 dn: CN=ms-DS-Tasks-For-Az-Task-BL,${SCHEMADN}
 objectClass: top
 objectClass: attributeSchema


-- 
Samba Shared Repository


More information about the samba-cvs mailing list