[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Thu Nov 19 20:26:26 MST 2009


The branch, master has been updated
       via  f3f0c8e... s4-dsdb: removed attributes that should not be displayed by default
       via  086fa79... s4-drs: Removes stored parentGUID's creation and renaming
       via  70d8db8... s4-drs: Synchronous Implementation of generated parentGUID
       via  8481581... s4-drs: Utility functions to deal with GUID
      from  a2707a3... ldb:ldb_tdb backend/indexes - Outside API

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


- Log -----------------------------------------------------------------
commit f3f0c8e2ce9fe315848d15eeb289eae9fb525a3a
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Nov 20 14:19:18 2009 +1100

    s4-dsdb: removed attributes that should not be displayed by default
    
    Some attributes (like ntSecurityDescriptor) are stored in our db, but
    should only be displayed if asked for. This also applied to parentGUID
    from old installs, which is now generated.

commit 086fa79d4d633e2165cae4e4d8e98a96fd5f9166
Author: Fernando J V da Silva <fernandojvsilva at yahoo.com.br>
Date:   Thu Nov 19 15:35:38 2009 -0300

    s4-drs: Removes stored parentGUID's creation and renaming
    
    parentGUID is now created on demand in operational.c
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

commit 70d8db86b92c57f7ff736fb6e275a085da92f856
Author: Fernando J V da Silva <fernandojvsilva at yahoo.com.br>
Date:   Thu Nov 19 15:37:45 2009 -0300

    s4-drs: Synchronous Implementation of generated parentGUID
    
    This generated parentGUID on demand, rather than getting it from the
    database
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

commit 8481581dc4d1795b943a46cabc718e3c558f41aa
Author: Fernando J V da Silva <fernandojvsilva at yahoo.com.br>
Date:   Thu Nov 19 15:28:37 2009 -0300

    s4-drs: Utility functions to deal with GUID
    
    dsdb_find_parentguid_by_dn() returns the parentGUID for a given DN
    dsdb_msg_add_guid() adds a GUID value to a given message (either
    objectGUID or parentGUID).
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

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

Summary of changes:
 source4/dsdb/common/util.c                   |   99 ++++++++++++++++++++++++++
 source4/dsdb/samdb/ldb_modules/objectclass.c |   87 ++---------------------
 source4/dsdb/samdb/ldb_modules/operational.c |   73 ++++++++++++++++++-
 3 files changed, 177 insertions(+), 82 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 4175928..e587545 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -2266,6 +2266,105 @@ int dsdb_find_guid_by_dn(struct ldb_context *ldb,
 	return LDB_SUCCESS;
 }
 
+
+/*
+  Use a DN to find it's parentGUID
+
+  Results
+   LDB_ERR_OPERATIONS_ERROR for out of memory
+   LDB_ERR_NO_SUCH_OBJECT if there is no parent object for the given DN
+   LDB_ERR_NO_SUCH_ATTRIBUTE if couldn't get the ObjectGUID from the parent
+   LDB_SUCCESS if it could find the parentGUID correctly
+ */
+int dsdb_find_parentguid_by_dn(struct ldb_context *ldb,
+			struct ldb_dn *dn,
+			struct GUID *parent_guid)
+{
+
+	int ret;
+	struct ldb_result *res;
+	struct ldb_dn *parent_dn;
+	const char *attrs[] = { "objectGUID", NULL };
+	TALLOC_CTX *tmp_ctx = talloc_new(ldb);
+
+
+	parent_dn = ldb_dn_get_parent(tmp_ctx, dn);
+
+	if (parent_dn == NULL){
+		DEBUG(4,(__location__ ": Failed to find parent for dn %s\n",
+					 ldb_dn_get_linearized(dn)));
+		ret = LDB_ERR_NO_SUCH_OBJECT;
+		goto done;
+	}
+
+	/*
+		The few lines of code bellow are very similar to the
+		dsdb_find_guid_by_dn() function implementation, but this way we can
+		differ situations when the parent_dn doesn't exist from when there is
+		an error on returning it's GUID.
+	 */
+	ret = dsdb_search_dn_with_deleted(ldb, tmp_ctx, &res, parent_dn, attrs);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(4,(__location__ ": Parent dn for %s does not exist \n",
+							 ldb_dn_get_linearized(dn)));
+		/* When there is no parent dn, it simply doesn't return a parentGUID  */
+		ret = LDB_ERR_NO_SUCH_OBJECT;
+		goto done;
+	}
+	if (res->count < 1) {
+		DEBUG(4,(__location__ ": Failed to find GUID for dn %s\n",
+					 ldb_dn_get_linearized(parent_dn)));
+		ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
+		goto done;
+	}
+
+	*parent_guid = samdb_result_guid(res->msgs[0], "objectGUID");
+	ret = LDB_SUCCESS;
+
+done:
+	talloc_free(tmp_ctx);
+	return ret;
+}
+
+/*
+ adds the given GUID to the given ldb_message. This value is added
+ for the given attr_name (may be either "objectGUID" or "parentGUID").
+ */
+int dsdb_msg_add_guid(struct ldb_message *msg,
+		struct GUID *guid,
+		const char *attr_name)
+{
+	int ret;
+	enum ndr_err_code ndr_err;
+	struct ldb_val v;
+
+	TALLOC_CTX *tmp_ctx =  talloc_init("dsdb_msg_add_guid");
+
+	ndr_err = ndr_push_struct_blob(&v, tmp_ctx, NULL,
+				       guid,
+				       (ndr_push_flags_fn_t)ndr_push_GUID);
+
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		ret = LDB_ERR_OPERATIONS_ERROR;
+		goto done;
+	}
+
+	ret = ldb_msg_add_steal_value(msg, attr_name, &v);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(4,(__location__ ": Failed to add %s to the message\n",
+					 attr_name));
+		goto done;
+	}
+
+	ret = LDB_SUCCESS;
+
+done:
+	talloc_free(tmp_ctx);
+	return ret;
+
+}
+
+
 /*
   use a DN to find a SID
  */
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index a26dcd2..53c1cc7 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -484,7 +484,6 @@ static int objectclass_do_add(struct oc_context *ac)
 			return LDB_ERR_NO_SUCH_OBJECT;
 		}
 	} 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, 
@@ -499,21 +498,6 @@ 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;			
-		}
-
-		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) {
 		ret = fix_attributes(ldb, schema, msg);
@@ -1033,7 +1017,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[] = { "objectGUID", NULL };
+	static const char * const attrs[] = { NULL };
 	struct ldb_context *ldb;
 	struct ldb_request *search_req;
 	struct oc_context *ac;
@@ -1067,12 +1051,14 @@ static int objectclass_rename(struct ldb_module *module, struct ldb_request *req
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	/* note that the results of this search are kept and used to
-	   update the parentGUID in objectclass_rename_callback() */
+	/*
+	  it makes a search request, looking for the parent DN to fix up the new DN
+	  to a standard one, at objectclass_do_rename()
+	 */
 	ret = ldb_build_search_req(&search_req, ldb,
 				   ac, parent_dn, LDB_SCOPE_BASE,
 				   "(objectClass=*)",
-				   attrs, NULL, 
+				   attrs, NULL,
 				   ac, get_search_callback,
 				   req);
 	if (ret != LDB_SUCCESS) {
@@ -1091,67 +1077,8 @@ static int objectclass_rename(struct ldb_module *module, struct ldb_request *req
 	ac->step_fn = objectclass_do_rename;
 
 	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);
-	}
-
-	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");
-	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)
@@ -1187,7 +1114,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, objectclass_rename_callback,
+				   ac, oc_op_callback,
 				   ac->req);
 	if (ret != LDB_SUCCESS) {
 		return ret;
diff --git a/source4/dsdb/samdb/ldb_modules/operational.c b/source4/dsdb/samdb/ldb_modules/operational.c
index cd2a6bc..23d1a9f 100644
--- a/source4/dsdb/samdb/ldb_modules/operational.c
+++ b/source4/dsdb/samdb/ldb_modules/operational.c
@@ -63,10 +63,12 @@
   modifiersName: not supported by w2k3?
 */
 
+#include "includes.h"
 #include "ldb_includes.h"
 #include "ldb_module.h"
 
-#include "includes.h"
+#include "librpc/gen_ndr/ndr_misc.h"
+#include "param/param.h"
 #include "dsdb/samdb/samdb.h"
 
 #ifndef ARRAY_SIZE
@@ -108,6 +110,35 @@ static int construct_primary_group_token(struct ldb_module *module,
 	}
 }
 
+static int construct_parent_guid(struct ldb_module *module,
+		struct ldb_message *msg)
+{
+	struct ldb_context *ldb;
+	struct GUID parent_guid;
+	int ret;
+
+	ldb = ldb_module_get_ctx(module);
+
+	ret = dsdb_find_parentguid_by_dn(ldb, msg->dn, &parent_guid);
+
+
+	if (ret != LDB_SUCCESS){
+
+		/* if there is no parentGUID for this object, then return */
+		if (ret == LDB_ERR_NO_SUCH_OBJECT){
+			return LDB_SUCCESS;
+		}else{
+			return ret;
+		}
+
+	}
+
+	ret = dsdb_msg_add_guid(msg, &parent_guid, "parentGUID");
+
+	return ret;
+
+}
+
 
 /*
   a list of attribute names that should be substituted in the parse
@@ -135,9 +166,29 @@ static const struct {
 	{ "modifyTimestamp", "whenChanged", NULL },
 	{ "structuralObjectClass", "objectClass", NULL },
 	{ "canonicalName", "distinguishedName", construct_canonical_name },
-	{ "primaryGroupToken", "objectSid", construct_primary_group_token }
+	{ "primaryGroupToken", "objectSid", construct_primary_group_token },
+	{ "parentGUID", NULL, construct_parent_guid }
+};
+
+
+enum op_remove {
+	OPERATIONAL_REMOVE_ALWAYS, /* remove always */
+	OPERATIONAL_REMOVE_UNASKED /* remove if not requested */
+};
+
+/*
+  a list of attributes that may need to be removed from the
+  underlying db return
+*/
+static const struct {
+	const char *attr;
+	enum op_remove op;
+} operational_remove[] = {
+	{ "ntSecurityDescriptor", OPERATIONAL_REMOVE_UNASKED },
+	{ "parentGUID",           OPERATIONAL_REMOVE_ALWAYS }
 };
 
+
 /*
   post process a search result record. For any search_sub[] attributes that were
   asked for, we need to call the appropriate copy routine to copy the result
@@ -153,6 +204,24 @@ static int operational_search_post_process(struct ldb_module *module,
 
 	ldb = ldb_module_get_ctx(module);
 
+	/* removed any attrs that should not be shown to the user */
+	for (i=0; i<ARRAY_SIZE(operational_remove); i++) {
+		struct ldb_message_element *el;
+
+		switch (operational_remove[i].op) {
+		case OPERATIONAL_REMOVE_UNASKED:
+			if (ldb_attr_in_list(attrs, operational_remove[i].attr)) {
+				continue;
+			}
+		case OPERATIONAL_REMOVE_ALWAYS:
+			el = ldb_msg_find_element(msg, operational_remove[i].attr);
+			if (el) {
+				ldb_msg_remove_element(msg, el);
+			}
+			break;
+		}
+	}
+
 	for (a=0;attrs && attrs[a];a++) {
 		for (i=0;i<ARRAY_SIZE(search_sub);i++) {
 			if (ldb_attr_cmp(attrs[a], search_sub[i].attr) != 0) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list