[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Wed Jul 24 11:22:02 UTC 2019


The branch, master has been updated
       via  e77237bb46c s4/dsdb/replmd: use incoming_dn_should_be_renamed() 2/2
       via  b9dab848de0 s4/dsdb/replmd: use incoming_dn_should_be_renamed() 1/2
       via  5d75ab3ebf4 s4/dsdb/replmd: add a helper for common calculations
       via  e7a6c70953d s4/dsdb/replmd: replicated_handle_rename free temp_ctx
      from  4db886db066 s3: smbd: Naming consistency. Change all uses of struct smb_Dir * variables to be dir_hnd.

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


- Log -----------------------------------------------------------------
commit e77237bb46cb1e39433c04d3f4552c4f0ddd4f96
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jul 24 15:43:46 2019 +1200

    s4/dsdb/replmd: use incoming_dn_should_be_renamed() 2/2
    
    In replmd_replicated_handle_rename().
    
    The helper function was introduced two commits ago and consists of
    a large common stretch of this and the function modified in the previous
    commit.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Wed Jul 24 11:21:50 UTC 2019 on sn-devel-184

commit b9dab848de066a8a3821c30261de8d6cccd77370
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jul 24 15:21:10 2019 +1200

    s4/dsdb/replmd: use incoming_dn_should_be_renamed() 1/2
    
    In replmd_op_possible_conflict_callback().
    
    The helper function was introduced in the previous commit and consists
    of a large common stretch of this and replmd_replicated_handle_rename().
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5d75ab3ebf48f876f4fb462e0d18c71f931a27c2
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jul 24 15:16:36 2019 +1200

    s4/dsdb/replmd: add a helper for common calculations
    
    We currently do exactly this work, in exactly these words (ignoring
    formatting) in two different places. The next two commits will make
    those places use this helper function. We do this over three commits
    so that we can more easily compare the next two and be sure they are
    doing the same thing.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit e7a6c70953daa84b88004e791e67b9a45f086946
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Apr 24 21:30:07 2019 +1200

    s4/dsdb/replmd: replicated_handle_rename free temp_ctx
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 282 +++++++++++-------------
 1 file changed, 123 insertions(+), 159 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 1d800feb0c1..b52d5163066 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -5192,56 +5192,37 @@ static int replmd_op_name_modify_callback(struct ldb_request *req, struct ldb_re
 	return replmd_op_callback(req, ares);
 }
 
+
+
 /*
-  callback for replmd_replicated_apply_add()
-  This copes with the creation of conflict records in the case where
-  the DN exists, but with a different objectGUID
+ * A helper for replmd_op_possible_conflict_callback() and
+ * replmd_replicated_handle_rename()
  */
-static int replmd_op_possible_conflict_callback(struct ldb_request *req, struct ldb_reply *ares, int (*callback)(struct ldb_request *req, struct ldb_reply *ares))
+static int incoming_dn_should_be_renamed(TALLOC_CTX *mem_ctx,
+					 struct replmd_replicated_request *ar,
+					 struct ldb_dn *conflict_dn,
+					 struct ldb_result **res,
+					 bool *rename_incoming_record)
 {
-	struct ldb_dn *conflict_dn;
-	struct replmd_replicated_request *ar =
-		talloc_get_type_abort(req->context, struct replmd_replicated_request);
-	struct ldb_result *res;
-	const char *attrs[] = { "replPropertyMetaData", "objectGUID", NULL };
 	int ret;
-	const struct ldb_val *omd_value;
-	struct replPropertyMetaDataBlob omd, *rmd;
+	bool rodc;
 	enum ndr_err_code ndr_err;
-	bool rename_incoming_record, rodc;
-	struct replPropertyMetaData1 *rmd_name, *omd_name;
-	struct ldb_message *msg;
-	struct ldb_request *down_req = NULL;
-
-	/* call the normal callback for success */
-	if (ares->error == LDB_SUCCESS) {
-		return callback(req, ares);
-	}
-
-	/*
-	 * we have a conflict, and need to decide if we will keep the
-	 * new record or the old record
-	 */
-
-	msg = ar->objs->objects[ar->index_current].msg;
-	conflict_dn = msg->dn;
-
-	/* For failures other than conflicts, fail the whole operation here */
-	if (ares->error != LDB_ERR_ENTRY_ALREADY_EXISTS) {
-		ldb_asprintf_errstring(ldb_module_get_ctx(ar->module), "Failed to locally apply remote add of %s: %s",
-				       ldb_dn_get_linearized(conflict_dn),
-				       ldb_errstring(ldb_module_get_ctx(ar->module)));
-
-		return ldb_module_done(ar->req, NULL, NULL,
-				       LDB_ERR_OPERATIONS_ERROR);
-	}
+	const struct ldb_val *omd_value = NULL;
+	struct replPropertyMetaDataBlob omd, *rmd = NULL;
+	struct ldb_context *ldb = ldb_module_get_ctx(ar->module);
+	const char *attrs[] = { "replPropertyMetaData", "objectGUID", NULL };
+	struct replPropertyMetaData1 *omd_name = NULL;
+	struct replPropertyMetaData1 *rmd_name = NULL;
+	struct ldb_message *msg = NULL;
 
-	ret = samdb_rodc(ldb_module_get_ctx(ar->module), &rodc);
+	ret = samdb_rodc(ldb, &rodc);
 	if (ret != LDB_SUCCESS) {
-		ldb_asprintf_errstring(ldb_module_get_ctx(ar->module), "Failed to determine if we are an RODC when attempting to form conflict DN: %s", ldb_errstring(ldb_module_get_ctx(ar->module)));
-		return ldb_module_done(ar->req, NULL, NULL,
-				       LDB_ERR_OPERATIONS_ERROR);
-
+		ldb_asprintf_errstring(
+			ldb,
+			"Failed to determine if we are an RODC when attempting "
+			"to form conflict DN: %s",
+			ldb_errstring(ldb));
+		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
 	if (rodc) {
@@ -5251,42 +5232,50 @@ static int replmd_op_possible_conflict_callback(struct ldb_request *req, struct
 		 * someone who owns the partition sorts it
 		 * out
 		 */
-		ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
-				       "Conflict adding object '%s' from incoming replication as we are read only for the partition.  \n"
-				       " - We must fail the operation until a master for this partition resolves the conflict",
-				       ldb_dn_get_linearized(conflict_dn));
-		ret = LDB_ERR_OPERATIONS_ERROR;
-		goto failed;
+		ldb_asprintf_errstring(
+			ldb,
+			"Conflict adding object '%s' from incoming replication "
+			"but we are read only for the partition.  \n"
+			" - We must fail the operation until a master for this "
+			"partition resolves the conflict",
+			ldb_dn_get_linearized(conflict_dn));
+		 return LDB_ERR_OPERATIONS_ERROR;
 	}
 
 	/*
 	 * first we need the replPropertyMetaData attribute from the
-	 * local, conflicting record
+	 * old record
 	 */
-	ret = dsdb_module_search_dn(ar->module, req, &res, conflict_dn,
+	ret = dsdb_module_search_dn(ar->module, mem_ctx, res, conflict_dn,
 				    attrs,
 				    DSDB_FLAG_NEXT_MODULE |
 				    DSDB_SEARCH_SHOW_DELETED |
-				    DSDB_SEARCH_SHOW_RECYCLED, req);
+				    DSDB_SEARCH_SHOW_RECYCLED, ar->req);
 	if (ret != LDB_SUCCESS) {
-		DEBUG(0,(__location__ ": Unable to find object for conflicting record '%s'\n",
-			 ldb_dn_get_linearized(conflict_dn)));
-		goto failed;
+		DBG_ERR(__location__
+			": Unable to find object for conflicting record '%s'\n",
+			ldb_dn_get_linearized(conflict_dn));
+		 return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	omd_value = ldb_msg_find_ldb_val(res->msgs[0], "replPropertyMetaData");
+	msg = (*res)->msgs[0];
+	omd_value = ldb_msg_find_ldb_val(msg, "replPropertyMetaData");
 	if (omd_value == NULL) {
-		DEBUG(0,(__location__ ": Unable to find replPropertyMetaData for conflicting record '%s'\n",
-			 ldb_dn_get_linearized(conflict_dn)));
-		goto failed;
+		DBG_ERR(__location__
+			": Unable to find replPropertyMetaData for conflicting "
+			"record '%s'\n",
+			ldb_dn_get_linearized(conflict_dn));
+		 return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	ndr_err = ndr_pull_struct_blob(omd_value, res->msgs[0], &omd,
-				       (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob);
+	ndr_err = ndr_pull_struct_blob(
+		omd_value, msg, &omd,
+		(ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob);
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		DEBUG(0,(__location__ ": Failed to parse old replPropertyMetaData for %s\n",
-			 ldb_dn_get_linearized(conflict_dn)));
-		goto failed;
+		DBG_ERR(__location__
+			": Failed to parse old replPropertyMetaData for %s\n",
+			ldb_dn_get_linearized(conflict_dn));
+		 return LDB_ERR_OPERATIONS_ERROR;
 	}
 
 	rmd = ar->objs->objects[ar->index_current].meta_data;
@@ -5301,21 +5290,77 @@ static int replmd_op_possible_conflict_callback(struct ldb_request *req, struct
 	 * local name in
 	 * replmd_replPropertyMetaData1_new_should_be_taken()
 	 */
-	rmd_name = replmd_replPropertyMetaData1_find_attid(rmd, DRSUAPI_ATTID_name);
-	omd_name = replmd_replPropertyMetaData1_find_attid(&omd, DRSUAPI_ATTID_name);
+	rmd_name = replmd_replPropertyMetaData1_find_attid(rmd,
+							   DRSUAPI_ATTID_name);
+	omd_name = replmd_replPropertyMetaData1_find_attid(&omd,
+							   DRSUAPI_ATTID_name);
 	if (!omd_name) {
-		DEBUG(0,(__location__ ": Failed to find name attribute in local LDB replPropertyMetaData for %s\n",
-			 ldb_dn_get_linearized(conflict_dn)));
-		goto failed;
+		DBG_ERR(__location__
+			": Failed to find name attribute in "
+			"local LDB replPropertyMetaData for %s\n",
+			 ldb_dn_get_linearized(conflict_dn));
+		 return LDB_ERR_OPERATIONS_ERROR;
 	}
 
 	/*
 	 * Should we preserve the current record, and so rename the
 	 * incoming record to be a conflict?
 	 */
-	rename_incoming_record
-		= !replmd_replPropertyMetaData1_new_should_be_taken(ar->objs->dsdb_repl_flags & DSDB_REPL_FLAG_PRIORITISE_INCOMING,
-								    omd_name, rmd_name);
+	*rename_incoming_record =
+		!replmd_replPropertyMetaData1_new_should_be_taken(
+			(ar->objs->dsdb_repl_flags &
+			 DSDB_REPL_FLAG_PRIORITISE_INCOMING),
+			omd_name, rmd_name);
+
+	return LDB_SUCCESS;
+}
+
+
+/*
+  callback for replmd_replicated_apply_add()
+  This copes with the creation of conflict records in the case where
+  the DN exists, but with a different objectGUID
+ */
+static int replmd_op_possible_conflict_callback(struct ldb_request *req, struct ldb_reply *ares, int (*callback)(struct ldb_request *req, struct ldb_reply *ares))
+{
+	struct ldb_dn *conflict_dn;
+	struct replmd_replicated_request *ar =
+		talloc_get_type_abort(req->context, struct replmd_replicated_request);
+	struct ldb_result *res;
+	int ret;
+	bool rename_incoming_record;
+	struct ldb_message *msg;
+	struct ldb_request *down_req = NULL;
+
+	/* call the normal callback for success */
+	if (ares->error == LDB_SUCCESS) {
+		return callback(req, ares);
+	}
+
+	/*
+	 * we have a conflict, and need to decide if we will keep the
+	 * new record or the old record
+	 */
+
+	msg = ar->objs->objects[ar->index_current].msg;
+	conflict_dn = msg->dn;
+
+	/* For failures other than conflicts, fail the whole operation here */
+	if (ares->error != LDB_ERR_ENTRY_ALREADY_EXISTS) {
+		ldb_asprintf_errstring(ldb_module_get_ctx(ar->module), "Failed to locally apply remote add of %s: %s",
+				       ldb_dn_get_linearized(conflict_dn),
+				       ldb_errstring(ldb_module_get_ctx(ar->module)));
+
+		return ldb_module_done(ar->req, NULL, NULL,
+				       LDB_ERR_OPERATIONS_ERROR);
+	}
+
+
+	ret = incoming_dn_should_be_renamed(req, ar, conflict_dn, &res,
+					    &rename_incoming_record);
+	if (ret != LDB_SUCCESS) {
+		goto failed;
+	}
 
 	if (rename_incoming_record) {
 		struct GUID guid;
@@ -5840,12 +5885,7 @@ static int replmd_replicated_handle_rename(struct replmd_replicated_request *ar,
 	TALLOC_CTX *tmp_ctx = talloc_new(msg);
 	struct ldb_result *res;
 	struct ldb_dn *conflict_dn;
-	const char *attrs[] = { "replPropertyMetaData", "objectGUID", NULL };
-	const struct ldb_val *omd_value;
-	struct replPropertyMetaDataBlob omd, *rmd;
-	enum ndr_err_code ndr_err;
-	bool rename_incoming_record, rodc;
-	struct replPropertyMetaData1 *rmd_name, *omd_name;
+	bool rename_incoming_record;
 	struct ldb_dn *new_dn;
 	struct GUID guid;
 
@@ -5871,94 +5911,15 @@ static int replmd_replicated_handle_rename(struct replmd_replicated_request *ar,
 		return ret;
 	}
 
-	ret = samdb_rodc(ldb_module_get_ctx(ar->module), &rodc);
-	if (ret != LDB_SUCCESS) {
-		ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
-				       "Failed to determine if we are an RODC when attempting to form conflict DN: %s",
-				       ldb_errstring(ldb_module_get_ctx(ar->module)));
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-	/*
-	 * we have a conflict, and need to decide if we will keep the
-	 * new record or the old record
-	 */
-
 	conflict_dn = msg->dn;
 
-	if (rodc) {
-		/*
-		 * We are on an RODC, or were a GC for this
-		 * partition, so we have to fail this until
-		 * someone who owns the partition sorts it
-		 * out
-		 */
-		ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
-				       "Conflict adding object '%s' from incoming replication but we are read only for the partition.  \n"
-				       " - We must fail the operation until a master for this partition resolves the conflict",
-				       ldb_dn_get_linearized(conflict_dn));
-		ret = LDB_ERR_OPERATIONS_ERROR;
-		goto failed;
-	}
 
-	/*
-	 * first we need the replPropertyMetaData attribute from the
-	 * old record
-	 */
-	ret = dsdb_module_search_dn(ar->module, tmp_ctx, &res, conflict_dn,
-				    attrs,
-				    DSDB_FLAG_NEXT_MODULE |
-				    DSDB_SEARCH_SHOW_DELETED |
-				    DSDB_SEARCH_SHOW_RECYCLED, ar->req);
+	ret = incoming_dn_should_be_renamed(tmp_ctx, ar, conflict_dn, &res,
+					    &rename_incoming_record);
 	if (ret != LDB_SUCCESS) {
-		DEBUG(0,(__location__ ": Unable to find object for conflicting record '%s'\n",
-			 ldb_dn_get_linearized(conflict_dn)));
-		goto failed;
-	}
-
-	omd_value = ldb_msg_find_ldb_val(res->msgs[0], "replPropertyMetaData");
-	if (omd_value == NULL) {
-		DEBUG(0,(__location__ ": Unable to find replPropertyMetaData for conflicting record '%s'\n",
-			 ldb_dn_get_linearized(conflict_dn)));
 		goto failed;
 	}
 
-	ndr_err = ndr_pull_struct_blob(omd_value, res->msgs[0], &omd,
-				       (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob);
-	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		DEBUG(0,(__location__ ": Failed to parse old replPropertyMetaData for %s\n",
-			 ldb_dn_get_linearized(conflict_dn)));
-		goto failed;
-	}
-
-	rmd = ar->objs->objects[ar->index_current].meta_data;
-
-	/*
-	 * we decide which is newer based on the RPMD on the name
-	 * attribute.  See [MS-DRSR] ResolveNameConflict.
-	 *
-	 * We expect omd_name to be present, as this is from a local
-	 * search, but while rmd_name should have been given to us by
-	 * the remote server, if it is missing we just prefer the
-	 * local name in
-	 * replmd_replPropertyMetaData1_new_should_be_taken()
-	 */
-	rmd_name = replmd_replPropertyMetaData1_find_attid(rmd, DRSUAPI_ATTID_name);
-	omd_name = replmd_replPropertyMetaData1_find_attid(&omd, DRSUAPI_ATTID_name);
-	if (!omd_name) {
-		DEBUG(0,(__location__ ": Failed to find name attribute in local LDB replPropertyMetaData for %s\n",
-			 ldb_dn_get_linearized(conflict_dn)));
-		goto failed;
-	}
-
-	/*
-	 * Should we preserve the current record, and so rename the
-	 * incoming record to be a conflict?
-	 */
-	rename_incoming_record =
-		!replmd_replPropertyMetaData1_new_should_be_taken(
-			ar->objs->dsdb_repl_flags & DSDB_REPL_FLAG_PRIORITISE_INCOMING,
-			omd_name, rmd_name);
-
 	if (rename_incoming_record) {
 
 		new_dn = replmd_conflict_dn(msg,
@@ -5970,6 +5931,7 @@ static int replmd_replicated_handle_rename(struct replmd_replicated_request *ar,
 								  "Failed to form conflict DN for %s\n",
 								  ldb_dn_get_linearized(msg->dn));
 
+			talloc_free(tmp_ctx);
 			return replmd_replicated_request_werror(ar, WERR_NOT_ENOUGH_MEMORY);
 		}
 
@@ -5982,11 +5944,13 @@ static int replmd_replicated_handle_rename(struct replmd_replicated_request *ar,
 					       ldb_dn_get_linearized(ar->search_msg->dn),
 					       ldb_dn_get_linearized(new_dn),
 					       ldb_errstring(ldb_module_get_ctx(ar->module)));
+			talloc_free(tmp_ctx);
 			return replmd_replicated_request_werror(ar, WERR_DS_DRA_DB_ERROR);
 		}
 
 		msg->dn = new_dn;
 		*renamed = true;
+		talloc_free(tmp_ctx);
 		return LDB_SUCCESS;
 	}
 


-- 
Samba Shared Repository



More information about the samba-cvs mailing list