From 0c20aa465c4543055fcb38d3e28cefb9ee603f87 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Thu, 12 Aug 2021 11:10:09 +1200
Subject: [PATCH 056/266] CVE-2020-25722 dsdb: Move krbtgt password setup after
 the point of checking if any passwords are changed

This allows the add of an RODC, before setting the password, to avoid
this module, which helps isolate testing of security around the
msDS-SecondaryKrbTgtNumber attribute.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14703

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>

Conflict:remove test
Reference:https://gitlab.com/samba-team/samba/-/commit/0c20aa465c4543055fcb38d3e28cefb9ee603f87

---
 .../dsdb/samdb/ldb_modules/password_hash.c    | 106 +++++++++---------
 1 files changed, 53 insertions(+), 53 deletions(-)

diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 82d9e8ebd2e..bb437a3b982 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -2476,6 +2476,59 @@ static int setup_password_fields(struct setup_password_fields_io *io)
 		return LDB_SUCCESS;
 	}
 
+	if (io->u.is_krbtgt) {
+		size_t min = 196;
+		size_t max = 255;
+		size_t diff = max - min;
+		size_t len = max;
+		struct ldb_val *krbtgt_utf16 = NULL;
+
+		if (!io->ac->pwd_reset) {
+			return dsdb_module_werror(io->ac->module,
+					LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS,
+					WERR_DS_ATT_ALREADY_EXISTS,
+					"Password change on krbtgt not permitted!");
+		}
+
+		if (io->n.cleartext_utf16 == NULL) {
+			return dsdb_module_werror(io->ac->module,
+					LDB_ERR_UNWILLING_TO_PERFORM,
+					WERR_DS_INVALID_ATTRIBUTE_SYNTAX,
+					"Password reset on krbtgt requires UTF16!");
+		}
+
+		/*
+		 * Instead of taking the callers value,
+		 * we just generate a new random value here.
+		 *
+		 * Include null termination in the array.
+		 */
+		if (diff > 0) {
+			size_t tmp;
+
+			generate_random_buffer((uint8_t *)&tmp, sizeof(tmp));
+
+			tmp %= diff;
+
+			len = min + tmp;
+		}
+
+		krbtgt_utf16 = talloc_zero(io->ac, struct ldb_val);
+		if (krbtgt_utf16 == NULL) {
+			return ldb_oom(ldb);
+		}
+
+		*krbtgt_utf16 = data_blob_talloc_zero(krbtgt_utf16,
+						      (len+1)*2);
+		if (krbtgt_utf16->data == NULL) {
+			return ldb_oom(ldb);
+		}
+		krbtgt_utf16->length = len * 2;
+		generate_secret_buffer(krbtgt_utf16->data,
+				       krbtgt_utf16->length);
+		io->n.cleartext_utf16 = krbtgt_utf16;
+	}
+
 	/* transform the old password (for password changes) */
 	ret = setup_given_passwords(io, &io->og);
 	if (ret != LDB_SUCCESS) {
@@ -3653,59 +3706,6 @@ static int setup_io(struct ph_context *ac,
 		return ldb_operr(ldb);
 	}
 
-	if (io->u.is_krbtgt) {
-		size_t min = 196;
-		size_t max = 255;
-		size_t diff = max - min;
-		size_t len = max;
-		struct ldb_val *krbtgt_utf16 = NULL;
-
-		if (!ac->pwd_reset) {
-			return dsdb_module_werror(ac->module,
-					LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS,
-					WERR_DS_ATT_ALREADY_EXISTS,
-					"Password change on krbtgt not permitted!");
-		}
-
-		if (io->n.cleartext_utf16 == NULL) {
-			return dsdb_module_werror(ac->module,
-					LDB_ERR_UNWILLING_TO_PERFORM,
-					WERR_DS_INVALID_ATTRIBUTE_SYNTAX,
-					"Password reset on krbtgt requires UTF16!");
-		}
-
-		/*
-		 * Instead of taking the callers value,
-		 * we just generate a new random value here.
-		 *
-		 * Include null termination in the array.
-		 */
-		if (diff > 0) {
-			size_t tmp;
-
-			generate_random_buffer((uint8_t *)&tmp, sizeof(tmp));
-
-			tmp %= diff;
-
-			len = min + tmp;
-		}
-
-		krbtgt_utf16 = talloc_zero(io->ac, struct ldb_val);
-		if (krbtgt_utf16 == NULL) {
-			return ldb_oom(ldb);
-		}
-
-		*krbtgt_utf16 = data_blob_talloc_zero(krbtgt_utf16,
-						      (len+1)*2);
-		if (krbtgt_utf16->data == NULL) {
-			return ldb_oom(ldb);
-		}
-		krbtgt_utf16->length = len * 2;
-		generate_secret_buffer(krbtgt_utf16->data,
-				       krbtgt_utf16->length);
-		io->n.cleartext_utf16 = krbtgt_utf16;
-	}
-
 	if (existing_msg != NULL) {
 		NTSTATUS status;
 
-- 
2.23.0

