[PATCH] Avoid going via printf/escape during deleted DN creation

Andrew Bartlett abartlet at samba.org
Fri Oct 27 03:00:16 UTC 2017


G'Day,

While trying (and failing, sadly) to find a root case for the flapping
tests at:

https://git.samba.org/autobuild.flakey.sn-devel-144/2017-10-05-0940/samba.stderr

I created the attached patches to prove to myself that there couldn't
be an issue in the parent DN creation for deleted DNs. 

Having created the code, I think we should include it, as is reduces
the printf() and escape calls and more clearly modifies the RDN as a
single component. 

Please review/push!

For context, in the above link this in particular is the still unsolved
problem.  I would love it if someone else can look over the deleted DN
and 'find parent dn' code and find the issue:

getncchanges: failed to fetch DN 
<GUID=6e4d1cfa-9c32-40f2-ad5d-24500a681af7> - 
operational_search_post_process failed for attribute 'parentGUID' - 
Parent dn

OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
CN=Deleted Objects,DC=samba,DC=example,DC=com

for

OU=test_ou_parent99,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
OU=getncchanges2659416_test\0ADEL:6bec890b-dcc6-4325-9fd2-fb2bda44c987,
CN=Deleted Objects,DC=samba,DC=example,DC=com does not exist at 
../source4/dsdb/samdb/ldb_modules/operational.c:365

Thanks,

Andrew Bartlett

-- 
Andrew Bartlett
https://samba.org/~abartlet/
Authentication Developer, Samba Team         https://samba.org
Samba Development and Support, Catalyst IT   
https://catalyst.net.nz/services/samba



-------------- next part --------------
From cd974b73e545015f04b89181fb68abf72b7a17ef Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Mon, 16 Oct 2017 17:11:00 +1300
Subject: [PATCH 1/7] auth: Allow an domain of "" and no UPN to authenticate
 using NTLMSSP

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 source4/auth/ntlm/auth_sam.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
index 24fe1677ed3..67102a00fa8 100644
--- a/source4/auth/ntlm/auth_sam.c
+++ b/source4/auth/ntlm/auth_sam.c
@@ -792,7 +792,7 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx,
 
 	p = strchr_m(user_info->mapped.account_name, '@');
 	if (p == NULL) {
-		if (effective_domain == NULL) {
+		if (effective_domain == NULL || strequal(effective_domain, "")) {
 			return NT_STATUS_OK;
 		}
 		DEBUG(6,("authsam_check_password: '' without upn not handled (DC)\n"));
-- 
2.11.0


From 813e63eb96dfe8f81eb0bfa81862c1159717dd61 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Mon, 16 Oct 2017 16:02:57 +1300
Subject: [PATCH 2/7] repl_meta_data: Avoid printf() and use binary direct RDN
 creation for deleted objects

This makes it clearer that we are just replacing the RDN and ensures we do not
somehow create multiple components inside ldb_dn_add_child_fmt().

We also avoid an escape/un-escape round-trip.

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 64 ++++++++++++++++++++++---
 1 file changed, 58 insertions(+), 6 deletions(-)

diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index c443102d98c..d893a61cdd6 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -3844,7 +3844,7 @@ static int replmd_delete_internals(struct ldb_module *module, struct ldb_request
 {
 	int ret = LDB_ERR_OTHER;
 	bool retb, disallow_move_on_delete;
-	struct ldb_dn *old_dn, *new_dn;
+	struct ldb_dn *old_dn = NULL, *new_dn = NULL;
 	const char *rdn_name;
 	const struct ldb_val *rdn_value, *new_rdn_value;
 	struct GUID guid;
@@ -4056,11 +4056,13 @@ static int replmd_delete_internals(struct ldb_module *module, struct ldb_request
 	guid = samdb_result_guid(old_msg, "objectGUID");
 
 	if (deletion_state == OBJECT_NOT_DELETED) {
-		/* Add a formatted child */
-		retb = ldb_dn_add_child_fmt(new_dn, "%s=%s\\0ADEL:%s",
-					    rdn_name,
-					    ldb_dn_escape_value(tmp_ctx, *rdn_value),
-					    GUID_string(tmp_ctx, &guid));
+		struct ldb_val deleted_child_rdn_val;
+		struct GUID_txt_buf guid_str;
+		const char *four_char_prefix = "DEL:";
+
+		GUID_buf_string(&guid, &guid_str);
+
+		retb = ldb_dn_add_child_fmt(new_dn, "X=Y");
 		if (!retb) {
 			ldb_asprintf_errstring(ldb, __location__
 					       ": Unable to add a formatted child to dn: %s",
@@ -4069,6 +4071,56 @@ static int replmd_delete_internals(struct ldb_module *module, struct ldb_request
 			return LDB_ERR_OPERATIONS_ERROR;
 		}
 
+
+		deleted_child_rdn_val = ldb_val_dup(tmp_ctx, rdn_value);
+
+		/*
+		 * sizeof(guid_str.buf) will always be longer than
+		 * strlen(guid_str.buf) but we allocate using this and
+		 * waste the trailing bytes to avoid scaring folks
+		 * with memcpy() using strlen() below
+		 */
+
+		deleted_child_rdn_val.data
+			= talloc_realloc(tmp_ctx, deleted_child_rdn_val.data,
+					 uint8_t,
+					 rdn_value->length + 5
+					 + sizeof(guid_str.buf));
+		if (!deleted_child_rdn_val.data) {
+			ldb_asprintf_errstring(ldb, __location__
+					       ": Unable to add a formatted child to dn: %s",
+					       ldb_dn_get_linearized(new_dn));
+			talloc_free(tmp_ctx);
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+
+		deleted_child_rdn_val.length =
+			rdn_value->length + 5
+			+ strlen(guid_str.buf);
+
+		SMB_ASSERT(deleted_child_rdn_val.length <
+			   talloc_get_size(deleted_child_rdn_val.data));
+
+		/*
+		 * talloc won't allocate more than 256MB so we can't
+		 * overflow but just to be sure
+		 */
+		if (deleted_child_rdn_val.length < rdn_value->length) {
+			talloc_free(tmp_ctx);
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+
+		deleted_child_rdn_val.data[rdn_value->length] = 0x0a;
+		memcpy(&deleted_child_rdn_val.data[rdn_value->length + 1],
+		       four_char_prefix, 4);
+		memcpy(&deleted_child_rdn_val.data[rdn_value->length + 5],
+		       guid_str.buf,
+		       sizeof(guid_str.buf));
+
+		/* Now set the value into the RDN, without parsing it */
+		ldb_dn_set_component(new_dn, 0, rdn_name,
+				     deleted_child_rdn_val);
+
 		ret = ldb_msg_add_string(msg, "isDeleted", "TRUE");
 		if (ret != LDB_SUCCESS) {
 			ldb_asprintf_errstring(ldb, __location__
-- 
2.11.0


From af7432e73851fc59ded951a596e908d0e5a07089 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Mon, 16 Oct 2017 17:27:59 +1300
Subject: [PATCH 3/7] repl_meta_data: Move creation of deleted DN into helper:
 replmd_make_deleted_child_dn()

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 150 ++++++++++++++----------
 1 file changed, 90 insertions(+), 60 deletions(-)

diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index d893a61cdd6..8664267a512 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -127,6 +127,13 @@ static int replmd_set_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct dsdb
 			     uint64_t usn, uint64_t local_usn, NTTIME nttime,
 			     uint32_t version, bool deleted);
 
+static int replmd_make_deleted_child_dn(TALLOC_CTX *tmp_ctx,
+					struct ldb_context *ldb,
+					struct ldb_dn *dn,
+					const char *rdn_name,
+					const struct ldb_val *rdn_value,
+					struct GUID guid);
+
 enum urgent_situation {
 	REPL_URGENT_ON_CREATE = 1,
 	REPL_URGENT_ON_UPDATE = 2,
@@ -4056,71 +4063,18 @@ static int replmd_delete_internals(struct ldb_module *module, struct ldb_request
 	guid = samdb_result_guid(old_msg, "objectGUID");
 
 	if (deletion_state == OBJECT_NOT_DELETED) {
-		struct ldb_val deleted_child_rdn_val;
-		struct GUID_txt_buf guid_str;
-		const char *four_char_prefix = "DEL:";
-
-		GUID_buf_string(&guid, &guid_str);
-
-		retb = ldb_dn_add_child_fmt(new_dn, "X=Y");
-		if (!retb) {
-			ldb_asprintf_errstring(ldb, __location__
-					       ": Unable to add a formatted child to dn: %s",
-					       ldb_dn_get_linearized(new_dn));
-			talloc_free(tmp_ctx);
-			return LDB_ERR_OPERATIONS_ERROR;
-		}
-
-
-		deleted_child_rdn_val = ldb_val_dup(tmp_ctx, rdn_value);
-
-		/*
-		 * sizeof(guid_str.buf) will always be longer than
-		 * strlen(guid_str.buf) but we allocate using this and
-		 * waste the trailing bytes to avoid scaring folks
-		 * with memcpy() using strlen() below
-		 */
 
-		deleted_child_rdn_val.data
-			= talloc_realloc(tmp_ctx, deleted_child_rdn_val.data,
-					 uint8_t,
-					 rdn_value->length + 5
-					 + sizeof(guid_str.buf));
-		if (!deleted_child_rdn_val.data) {
-			ldb_asprintf_errstring(ldb, __location__
-					       ": Unable to add a formatted child to dn: %s",
-					       ldb_dn_get_linearized(new_dn));
-			talloc_free(tmp_ctx);
-			return LDB_ERR_OPERATIONS_ERROR;
-		}
-
-		deleted_child_rdn_val.length =
-			rdn_value->length + 5
-			+ strlen(guid_str.buf);
+		ret = replmd_make_deleted_child_dn(tmp_ctx,
+						   ldb,
+						   new_dn,
+						   rdn_name, rdn_value,
+						   guid);
 
-		SMB_ASSERT(deleted_child_rdn_val.length <
-			   talloc_get_size(deleted_child_rdn_val.data));
-
-		/*
-		 * talloc won't allocate more than 256MB so we can't
-		 * overflow but just to be sure
-		 */
-		if (deleted_child_rdn_val.length < rdn_value->length) {
+		if (ret != LDB_SUCCESS) {
 			talloc_free(tmp_ctx);
-			return LDB_ERR_OPERATIONS_ERROR;
+			return ret;
 		}
 
-		deleted_child_rdn_val.data[rdn_value->length] = 0x0a;
-		memcpy(&deleted_child_rdn_val.data[rdn_value->length + 1],
-		       four_char_prefix, 4);
-		memcpy(&deleted_child_rdn_val.data[rdn_value->length + 5],
-		       guid_str.buf,
-		       sizeof(guid_str.buf));
-
-		/* Now set the value into the RDN, without parsing it */
-		ldb_dn_set_component(new_dn, 0, rdn_name,
-				     deleted_child_rdn_val);
-
 		ret = ldb_msg_add_string(msg, "isDeleted", "TRUE");
 		if (ret != LDB_SUCCESS) {
 			ldb_asprintf_errstring(ldb, __location__
@@ -4586,6 +4540,82 @@ static struct ldb_dn *replmd_conflict_dn(TALLOC_CTX *mem_ctx, struct ldb_dn *dn,
 	return new_dn;
 }
 
+/*
+  form a deleted DN
+ */
+static int replmd_make_deleted_child_dn(TALLOC_CTX *tmp_ctx,
+					struct ldb_context *ldb,
+					struct ldb_dn *dn,
+					const char *rdn_name,
+					const struct ldb_val *rdn_value,
+					struct GUID guid)
+{
+	struct ldb_val deleted_child_rdn_val;
+	struct GUID_txt_buf guid_str;
+	const char *four_char_prefix = "DEL:";
+	bool retb;
+
+	GUID_buf_string(&guid, &guid_str);
+
+	retb = ldb_dn_add_child_fmt(dn, "X=Y");
+	if (!retb) {
+		ldb_asprintf_errstring(ldb, __location__
+				       ": Unable to add a formatted child to dn: %s",
+				       ldb_dn_get_linearized(dn));
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+
+	deleted_child_rdn_val = ldb_val_dup(tmp_ctx, rdn_value);
+
+	/*
+	 * sizeof(guid_str.buf) will always be longer than
+	 * strlen(guid_str.buf) but we allocate using this and
+	 * waste the trailing bytes to avoid scaring folks
+	 * with memcpy() using strlen() below
+	 */
+
+	deleted_child_rdn_val.data
+		= talloc_realloc(tmp_ctx, deleted_child_rdn_val.data,
+				 uint8_t,
+				 rdn_value->length + 5
+				 + sizeof(guid_str.buf));
+	if (!deleted_child_rdn_val.data) {
+		ldb_asprintf_errstring(ldb, __location__
+				       ": Unable to add a formatted child to dn: %s",
+				       ldb_dn_get_linearized(dn));
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	deleted_child_rdn_val.length =
+		rdn_value->length + 5
+		+ strlen(guid_str.buf);
+
+	SMB_ASSERT(deleted_child_rdn_val.length <
+		   talloc_get_size(deleted_child_rdn_val.data));
+
+	/*
+	 * talloc won't allocate more than 256MB so we can't
+	 * overflow but just to be sure
+	 */
+	if (deleted_child_rdn_val.length < rdn_value->length) {
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	deleted_child_rdn_val.data[rdn_value->length] = 0x0a;
+	memcpy(&deleted_child_rdn_val.data[rdn_value->length + 1],
+	       four_char_prefix, 4);
+	memcpy(&deleted_child_rdn_val.data[rdn_value->length + 5],
+	       guid_str.buf,
+	       sizeof(guid_str.buf));
+
+	/* Now set the value into the RDN, without parsing it */
+	ldb_dn_set_component(dn, 0, rdn_name,
+			     deleted_child_rdn_val);
+
+	return LDB_SUCCESS;
+}
+
 
 /*
   perform a modify operation which sets the rDN and name attributes to
-- 
2.11.0


From d33fa3ddcb05bfe14bfca1fc9af235e42cfb875d Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Tue, 17 Oct 2017 11:27:49 +1300
Subject: [PATCH 4/7] repl_meta_data: Split replmd_make_deleted_child_dn() into
 a helper function

This will allow it to be used in common with replmd_conflict_dn()

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 69 ++++++++++++++++++++++---
 1 file changed, 62 insertions(+), 7 deletions(-)

diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 8664267a512..8bb47b330ab 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -4543,16 +4543,16 @@ static struct ldb_dn *replmd_conflict_dn(TALLOC_CTX *mem_ctx, struct ldb_dn *dn,
 /*
   form a deleted DN
  */
-static int replmd_make_deleted_child_dn(TALLOC_CTX *tmp_ctx,
-					struct ldb_context *ldb,
-					struct ldb_dn *dn,
-					const char *rdn_name,
-					const struct ldb_val *rdn_value,
-					struct GUID guid)
+static int replmd_make_prefix_child_dn(TALLOC_CTX *tmp_ctx,
+				       struct ldb_context *ldb,
+				       struct ldb_dn *dn,
+				       const char *four_char_prefix,
+				       const char *rdn_name,
+				       const struct ldb_val *rdn_value,
+				       struct GUID guid)
 {
 	struct ldb_val deleted_child_rdn_val;
 	struct GUID_txt_buf guid_str;
-	const char *four_char_prefix = "DEL:";
 	bool retb;
 
 	GUID_buf_string(&guid, &guid_str);
@@ -4618,6 +4618,61 @@ static int replmd_make_deleted_child_dn(TALLOC_CTX *tmp_ctx,
 
 
 /*
+  form a conflict DN
+ */
+static struct ldb_dn *replmd_conflict_dn(TALLOC_CTX *mem_ctx,
+					 struct ldb_context *ldb,
+					 struct ldb_dn *dn,
+					 struct GUID *guid)
+{
+	const struct ldb_val *rdn_val;
+	const char *rdn_name;
+	struct ldb_dn *new_dn;
+	int ret;
+
+	rdn_val = ldb_dn_get_rdn_val(dn);
+	rdn_name = ldb_dn_get_rdn_name(dn);
+	if (!rdn_val || !rdn_name) {
+		return NULL;
+	}
+
+	new_dn = ldb_dn_get_parent(mem_ctx, dn);
+	if (!new_dn) {
+		return NULL;
+	}
+
+	ret = replmd_make_prefix_child_dn(mem_ctx,
+					  ldb, new_dn,
+					  "CNF:",
+					  rdn_name,
+					  rdn_val,
+					  *guid);
+	if (ret != LDB_SUCCESS) {
+		return NULL;
+	}
+	return new_dn;
+}
+
+/*
+  form a deleted DN
+ */
+static int replmd_make_deleted_child_dn(TALLOC_CTX *tmp_ctx,
+					struct ldb_context *ldb,
+					struct ldb_dn *dn,
+					const char *rdn_name,
+					const struct ldb_val *rdn_value,
+					struct GUID guid)
+{
+	return replmd_make_prefix_child_dn(tmp_ctx,
+					   ldb, dn,
+					   "DEL:",
+					   rdn_name,
+					   rdn_value,
+					   guid);
+}
+
+
+/*
   perform a modify operation which sets the rDN and name attributes to
   their current values. This has the effect of changing these
   attributes to have been last updated by the current DC. This is
-- 
2.11.0


From 9016c7193e001ed7e12a5a73428737a90e9c4300 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Tue, 17 Oct 2017 11:28:45 +1300
Subject: [PATCH 5/7] repl_meta_data: Use replmd_make_prefix_child_dn() in
 replmd_conflict_dn()

Now both routines avoid the escape/unescape implicit in ldb_dn_add_child_fmt()

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 52 +++++++------------------
 1 file changed, 13 insertions(+), 39 deletions(-)

diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 8bb47b330ab..bdc6aee944e 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -4507,41 +4507,7 @@ static bool replmd_replPropertyMetaData1_new_should_be_taken(uint32_t dsdb_repl_
 
 
 /*
-  form a conflict DN
- */
-static struct ldb_dn *replmd_conflict_dn(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, struct GUID *guid)
-{
-	const struct ldb_val *rdn_val;
-	const char *rdn_name;
-	struct ldb_dn *new_dn;
-
-	rdn_val = ldb_dn_get_rdn_val(dn);
-	rdn_name = ldb_dn_get_rdn_name(dn);
-	if (!rdn_val || !rdn_name) {
-		return NULL;
-	}
-
-	new_dn = ldb_dn_copy(mem_ctx, dn);
-	if (!new_dn) {
-		return NULL;
-	}
-
-	if (!ldb_dn_remove_child_components(new_dn, 1)) {
-		return NULL;
-	}
-
-	if (!ldb_dn_add_child_fmt(new_dn, "%s=%s\\0ACNF:%s",
-				  rdn_name,
-				  ldb_dn_escape_value(new_dn, *rdn_val),
-				  GUID_string(new_dn, guid))) {
-		return NULL;
-	}
-
-	return new_dn;
-}
-
-/*
-  form a deleted DN
+  form a DN for a deleted (DEL:) or conflict (CNF:) DN
  */
 static int replmd_make_prefix_child_dn(TALLOC_CTX *tmp_ctx,
 				       struct ldb_context *ldb,
@@ -4953,7 +4919,9 @@ static int replmd_op_possible_conflict_callback(struct ldb_request *req, struct
 				 ldb_dn_get_linearized(conflict_dn)));
 			goto failed;
 		}
-		new_dn = replmd_conflict_dn(req, conflict_dn, &guid);
+		new_dn = replmd_conflict_dn(req,
+					    ldb_module_get_ctx(ar->module),
+					    conflict_dn, &guid);
 		if (new_dn == NULL) {
 			DEBUG(0,(__location__ ": Failed to form conflict DN for %s\n",
 				 ldb_dn_get_linearized(conflict_dn)));
@@ -4978,7 +4946,9 @@ static int replmd_op_possible_conflict_callback(struct ldb_request *req, struct
 			goto failed;
 		}
 
-		new_dn = replmd_conflict_dn(req, conflict_dn, &guid);
+		new_dn = replmd_conflict_dn(req,
+					    ldb_module_get_ctx(ar->module),
+					    conflict_dn, &guid);
 		if (new_dn == NULL) {
 			DEBUG(0,(__location__ ": Failed to form conflict DN for %s\n",
 				 ldb_dn_get_linearized(conflict_dn)));
@@ -5580,7 +5550,9 @@ static int replmd_replicated_handle_rename(struct replmd_replicated_request *ar,
 
 	if (rename_incoming_record) {
 
-		new_dn = replmd_conflict_dn(msg, msg->dn,
+		new_dn = replmd_conflict_dn(msg,
+					    ldb_module_get_ctx(ar->module),
+					    msg->dn,
 					    &ar->objs->objects[ar->index_current].object_guid);
 		if (new_dn == NULL) {
 			ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
@@ -5616,7 +5588,9 @@ static int replmd_replicated_handle_rename(struct replmd_replicated_request *ar,
 		goto failed;
 	}
 
-	new_dn = replmd_conflict_dn(tmp_ctx, conflict_dn, &guid);
+	new_dn = replmd_conflict_dn(tmp_ctx,
+				    ldb_module_get_ctx(ar->module),
+				    conflict_dn, &guid);
 	if (new_dn == NULL) {
 		DEBUG(0,(__location__ ": Failed to form conflict DN for %s\n",
 			 ldb_dn_get_linearized(conflict_dn)));
-- 
2.11.0


From 450266cc84d810167ff1bbff518d728f8e178df2 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Tue, 17 Oct 2017 11:36:03 +1300
Subject: [PATCH 6/7] repl_meta_data: Explain that we do not truncate the DN at
 present

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index bdc6aee944e..d0cf3cd36e0 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -4531,7 +4531,16 @@ static int replmd_make_prefix_child_dn(TALLOC_CTX *tmp_ctx,
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-
+	/*
+	 * TODO: Per MS-ADTS 3.1.1.5.5 Delete Operation
+	 * we should truncate this value to ensure the RDN is not more than 255 chars.
+	 *
+	 * However we MS-ADTS 3.1.1.5.1.2 Naming Constraints indicates that:
+	 *
+	 * "Naming constraints are not enforced for replicated
+	 * updates." so this is safe and we don't have to work out not
+	 * splitting a UTF8 char right now.
+	 */
 	deleted_child_rdn_val = ldb_val_dup(tmp_ctx, rdn_value);
 
 	/*
-- 
2.11.0


From 372ad0f1b9c47d98c7b857143c543b62e325ca42 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Tue, 17 Oct 2017 12:00:27 +1300
Subject: [PATCH 7/7] repl_meta_data: Initialise parent_dn to NULL

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index d0cf3cd36e0..9a243497be7 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -5256,7 +5256,7 @@ static int replmd_replicated_apply_search_for_parent_callback(struct ldb_request
 	{
 		struct ldb_message *parent_msg = ares->message;
 		struct ldb_message *msg = ar->objs->objects[ar->index_current].msg;
-		struct ldb_dn *parent_dn;
+		struct ldb_dn *parent_dn = NULL;
 		int comp_num;
 
 		if (!ldb_msg_check_string_attribute(msg, "isDeleted", "TRUE")
-- 
2.11.0



More information about the samba-technical mailing list