[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Wed Apr 6 11:56:02 MDT 2011


The branch, master has been updated
       via  b3bb983 s4:dsdb/repl_meta_data: update replPropertyMetaData on originating renames
       via  4d5a295 s4:dsdb/repl_meta_data: allow passing an explicit attribute list to replmd_update_rpmd()
       via  d622d21 s4:dsdb/repl_meta_data: normalize the rdn attribute name based on the schema
      from  3626579 s3: Fix tldap_make_mod_blob_int() debug messages

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


- Log -----------------------------------------------------------------
commit b3bb983f256e3a48dafea309800fac1a42648157
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Apr 6 14:02:08 2011 +0200

    s4:dsdb/repl_meta_data: update replPropertyMetaData on originating renames
    
    The version of the "name" attribute needs to change even if the value
    is the same. This also normalizes the rdn attribute name based on
    the schema.
    
    metze
    
    Autobuild-User: Stefan Metzmacher <metze at samba.org>
    Autobuild-Date: Wed Apr  6 19:55:50 CEST 2011 on sn-devel-104

commit 4d5a2955a1724d6b5ef95289704686d730bc7071
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Apr 6 16:10:34 2011 +0200

    s4:dsdb/repl_meta_data: allow passing an explicit attribute list to replmd_update_rpmd()
    
    This will be used for renames.
    
    metze

commit d622d21054e46dde53f751e43d8f3b481b4332b0
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Apr 5 16:47:20 2011 +0200

    s4:dsdb/repl_meta_data: normalize the rdn attribute name based on the schema
    
    metze

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c |  167 +++++++++++++++++++++--
 1 files changed, 152 insertions(+), 15 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 06c63a8..646abeb 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -1126,6 +1126,7 @@ static uint64_t find_max_local_usn(struct replPropertyMetaDataBlob omd)
 static int replmd_update_rpmd(struct ldb_module *module,
 			      const struct dsdb_schema *schema,
 			      struct ldb_request *req,
+			      const char * const *rename_attrs,
 			      struct ldb_message *msg, uint64_t *seq_num,
 			      time_t t,
 			      bool *is_urgent)
@@ -1137,14 +1138,21 @@ static int replmd_update_rpmd(struct ldb_module *module,
 	NTTIME now;
 	const struct GUID *our_invocation_id;
 	int ret;
-	const char *attrs[] = { "replPropertyMetaData", "*", NULL };
-	const char *attrs2[] = { "uSNChanged", "objectClass", NULL };
+	const char * const *attrs = NULL;
+	const char * const attrs1[] = { "replPropertyMetaData", "*", NULL };
+	const char * const attrs2[] = { "uSNChanged", "objectClass", NULL };
 	struct ldb_result *res;
 	struct ldb_context *ldb;
 	struct ldb_message_element *objectclass_el;
 	enum urgent_situation situation;
 	bool rodc, rmd_is_provided;
 
+	if (rename_attrs) {
+		attrs = rename_attrs;
+	} else {
+		attrs = attrs1;
+	}
+
 	ldb = ldb_module_get_ctx(module);
 
 	our_invocation_id = samdb_ntds_invocation_id(ldb);
@@ -1167,6 +1175,8 @@ static int replmd_update_rpmd(struct ldb_module *module,
 	 * otherwise we consider we are updating */
 	if (ldb_msg_check_string_attribute(msg, "isDeleted", "TRUE")) {
 		situation = REPL_URGENT_ON_DELETE;
+	} else if (rename_attrs) {
+		situation = REPL_URGENT_ON_CREATE | REPL_URGENT_ON_DELETE;
 	} else {
 		situation = REPL_URGENT_ON_UPDATE;
 	}
@@ -1185,7 +1195,7 @@ static int replmd_update_rpmd(struct ldb_module *module,
 				"a specified replPropertyMetaData attribute or with others\n"));
 			return LDB_ERR_OPERATIONS_ERROR;
 		}
-		if (situation == REPL_URGENT_ON_DELETE) {
+		if (situation != REPL_URGENT_ON_UPDATE) {
 			DEBUG(0,(__location__ ": changereplmetada control can't be called when deleting an object\n"));
 			return LDB_ERR_OPERATIONS_ERROR;
 		}
@@ -2218,7 +2228,8 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
 	ldb_msg_remove_attr(msg, "whenChanged");
 	ldb_msg_remove_attr(msg, "uSNChanged");
 
-	ret = replmd_update_rpmd(module, ac->schema, req, msg, &ac->seq_num, t, &is_urgent);
+	ret = replmd_update_rpmd(module, ac->schema, req, NULL,
+				 msg, &ac->seq_num, t, &is_urgent);
 	if (ret == LDB_ERR_REFERRAL) {
 		referral = talloc_asprintf(req,
 					   "ldap://%s/%s",
@@ -2353,8 +2364,13 @@ static int replmd_rename_callback(struct ldb_request *req, struct ldb_reply *are
 	struct replmd_replicated_request *ac;
 	struct ldb_request *down_req;
 	struct ldb_message *msg;
+	const struct dsdb_attribute *rdn_attr;
+	const char *rdn_name;
+	const struct ldb_val *rdn_val;
+	const char *attrs[4] = { NULL, };
 	time_t t = time(NULL);
 	int ret;
+	bool is_urgent = false;
 
 	ac = talloc_get_type(req->context, struct replmd_replicated_request);
 	ldb = ldb_module_get_ctx(ac->module);
@@ -2372,12 +2388,6 @@ static int replmd_rename_callback(struct ldb_request *req, struct ldb_reply *are
 					LDB_ERR_OPERATIONS_ERROR);
 	}
 
-	/* Get a sequence number from the backend */
-	ret = ldb_sequence_number(ldb, LDB_SEQ_NEXT, &ac->seq_num);
-	if (ret != LDB_SUCCESS) {
-		return ret;
-	}
-
 	/* TODO:
 	 * - replace the old object with the newly constructed one
 	 */
@@ -2390,6 +2400,123 @@ static int replmd_rename_callback(struct ldb_request *req, struct ldb_reply *are
 
 	msg->dn = ac->req->op.rename.newdn;
 
+	rdn_name = ldb_dn_get_rdn_name(msg->dn);
+	if (rdn_name == NULL) {
+		talloc_free(ares);
+		return ldb_module_done(ac->req, NULL, NULL,
+				       ldb_operr(ldb));
+	}
+
+	/* normalize the rdn attribute name */
+	rdn_attr = dsdb_attribute_by_lDAPDisplayName(ac->schema, rdn_name);
+	if (rdn_attr == NULL) {
+		talloc_free(ares);
+		return ldb_module_done(ac->req, NULL, NULL,
+				       ldb_operr(ldb));
+	}
+	rdn_name = rdn_attr->lDAPDisplayName;
+
+	rdn_val = ldb_dn_get_rdn_val(msg->dn);
+	if (rdn_val == NULL) {
+		talloc_free(ares);
+		return ldb_module_done(ac->req, NULL, NULL,
+				       ldb_operr(ldb));
+	}
+
+	if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) {
+		talloc_free(ares);
+		return ldb_module_done(ac->req, NULL, NULL,
+				       ldb_oom(ldb));
+	}
+	if (ldb_msg_add_value(msg, rdn_name, rdn_val, NULL) != 0) {
+		talloc_free(ares);
+		return ldb_module_done(ac->req, NULL, NULL,
+				       ldb_oom(ldb));
+	}
+	if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) {
+		talloc_free(ares);
+		return ldb_module_done(ac->req, NULL, NULL,
+				       ldb_oom(ldb));
+	}
+	if (ldb_msg_add_value(msg, "name", rdn_val, NULL) != 0) {
+		talloc_free(ares);
+		return ldb_module_done(ac->req, NULL, NULL,
+				       ldb_oom(ldb));
+	}
+
+	/*
+	 * here we let replmd_update_rpmd() only search for
+	 * the existing "replPropertyMetaData" and rdn_name attributes.
+	 *
+	 * We do not want the existing "name" attribute as
+	 * the "name" attribute needs to get the version
+	 * updated on rename even if the rdn value hasn't changed.
+	 *
+	 * This is the diff of the meta data, for a moved user
+	 * on a w2k8r2 server:
+	 *
+	 * # record 1
+	 * -dn: CN=sdf df,CN=Users,DC=bla,DC=base
+	 * +dn: CN=sdf df,OU=TestOU,DC=bla,DC=base
+	 *  replPropertyMetaData:     NDR: struct replPropertyMetaDataBlob
+	 *         version                  : 0x00000001 (1)
+	 *         reserved                 : 0x00000000 (0)
+	 * @@ -66,11 +66,11 @@ replPropertyMetaData:     NDR: struct re
+	 *                      local_usn                : 0x00000000000037a5 (14245)
+	 *                 array: struct replPropertyMetaData1
+	 *                      attid                    : DRSUAPI_ATTID_name (0x90001)
+	 * -                    version                  : 0x00000001 (1)
+	 * -                    originating_change_time  : Wed Feb  9 17:20:49 2011 CET
+	 * +                    version                  : 0x00000002 (2)
+	 * +                    originating_change_time  : Wed Apr  6 15:21:01 2011 CEST
+	 *                      originating_invocation_id: 0d36ca05-5507-4e62-aca3-354bab0d39e1
+	 * -                    originating_usn          : 0x00000000000037a5 (14245)
+	 * -                    local_usn                : 0x00000000000037a5 (14245)
+	 * +                    originating_usn          : 0x0000000000003834 (14388)
+	 * +                    local_usn                : 0x0000000000003834 (14388)
+	 *                 array: struct replPropertyMetaData1
+	 *                      attid                    : DRSUAPI_ATTID_userAccountControl (0x90008)
+	 *                      version                  : 0x00000004 (4)
+	 */
+	attrs[0] = "replPropertyMetaData";
+	attrs[1] = "objectClass";
+	attrs[2] = rdn_name;
+	attrs[3] = NULL;
+
+	ret = replmd_update_rpmd(ac->module, ac->schema, req, attrs,
+				 msg, &ac->seq_num, t, &is_urgent);
+	if (ret == LDB_ERR_REFERRAL) {
+		struct ldb_dn *olddn = ac->req->op.rename.olddn;
+		struct loadparm_context *lp_ctx;
+		const char *referral;
+
+		lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
+					 struct loadparm_context);
+
+		referral = talloc_asprintf(req,
+					   "ldap://%s/%s",
+					   lpcfg_dnsdomain(lp_ctx),
+					   ldb_dn_get_linearized(olddn));
+		ret = ldb_module_send_referral(req, referral);
+		talloc_free(ac);
+		return ldb_module_done(req, NULL, NULL, ret);
+	}
+
+	if (ret != LDB_SUCCESS) {
+		talloc_free(ares);
+		return ldb_module_done(ac->req, NULL, NULL,
+				       ldb_error(ldb, ret,
+					"failed to call replmd_update_rpmd()"));
+	}
+
+	if (ac->seq_num == 0) {
+		talloc_free(ares);
+		return ldb_module_done(ac->req, NULL, NULL,
+				       ldb_error(ldb, ret,
+					"internal error seq_num == 0"));
+	}
+	ac->is_urgent = is_urgent;
+
 	ret = ldb_build_mod_req(&down_req, ldb, ac,
 				msg,
 				req->controls,
@@ -2975,11 +3102,13 @@ static struct ldb_dn *replmd_conflict_dn(TALLOC_CTX *mem_ctx, struct ldb_dn *dn,
   needed to ensure that renames performed as part of conflict
   resolution are propogated to other DCs
  */
-static int replmd_name_modify(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn)
+static int replmd_name_modify(struct replmd_replicated_request *ar,
+			      struct ldb_request *req, struct ldb_dn *dn)
 {
 	struct ldb_message *msg;
 	const char *rdn_name;
 	const struct ldb_val *rdn_val;
+	const struct dsdb_attribute *rdn_attr;
 	int ret;
 
 	msg = ldb_msg_new(req);
@@ -2993,6 +3122,13 @@ static int replmd_name_modify(struct ldb_module *module, struct ldb_request *req
 		goto failed;
 	}
 
+	/* normalize the rdn attribute name */
+	rdn_attr = dsdb_attribute_by_lDAPDisplayName(ar->schema, rdn_name);
+	if (rdn_attr == NULL) {
+		goto failed;
+	}
+	rdn_name = rdn_attr->lDAPDisplayName;
+
 	rdn_val = ldb_dn_get_rdn_val(dn);
 	if (rdn_val == NULL) {
 		goto failed;
@@ -3011,10 +3147,11 @@ static int replmd_name_modify(struct ldb_module *module, struct ldb_request *req
 		goto failed;
 	}
 
-	ret = dsdb_module_modify(module, msg, DSDB_FLAG_OWN_MODULE, req);
+	ret = dsdb_module_modify(ar->module, msg, DSDB_FLAG_OWN_MODULE, req);
 	if (ret != LDB_SUCCESS) {
 		DEBUG(0,(__location__ ": Failed to modify rDN/name of conflict DN '%s' - %s",
-			 ldb_dn_get_linearized(dn), ldb_errstring(ldb_module_get_ctx(module))));
+			 ldb_dn_get_linearized(dn),
+			 ldb_errstring(ldb_module_get_ctx(ar->module))));
 		return ret;
 	}
 
@@ -3047,7 +3184,7 @@ static int replmd_op_name_modify_callback(struct ldb_request *req, struct ldb_re
 	}
 
 	/* perform a modify of the rDN and name of the record */
-	ret = replmd_name_modify(ar->module, req, req->op.add.message->dn);
+	ret = replmd_name_modify(ar, req, req->op.add.message->dn);
 	if (ret != LDB_SUCCESS) {
 		ares->error = ret;
 		return replmd_op_callback(req, ares);
@@ -3218,7 +3355,7 @@ static int replmd_op_add_callback(struct ldb_request *req, struct ldb_reply *are
 		 * now we need to ensure that the rename is seen as an
 		 * originating update. We do that with a modify.
 		 */
-		ret = replmd_name_modify(ar->module, req, new_dn);
+		ret = replmd_name_modify(ar, req, new_dn);
 		if (ret != LDB_SUCCESS) {
 			goto failed;
 		}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list