From e3021debe82e6a35f128eb600bc11df40c441a98 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Thu, 16 Sep 2021 08:46:42 +1200
Subject: [PATCH 063/266] CVE-2020-25722 dsdb: objectclass computer becomes
 UF_WORKSTATION_TRUST by default

There are a lot of knownfail entries added with this commit.  These
all need to be addressed and removed in subsequent commits which
will restructure the tests to pass within this new reality.

This default applies even to users with administrator rights,
as changing the default based on permissions would break
to many assumptions.

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

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

Conflict:NA
Reference:https://gitlab.com/samba-team/samba/-/commit/e3021debe82e6a35f128eb600bc11df40c441a98

---
 selftest/knownfail.d/uac_objectclass_restrict | 42 +++++++++++++++++++
 source4/dsdb/samdb/ldb_modules/samldb.c       | 27 +++++++++---
 2 files changed, 64 insertions(+), 5 deletions(-)
 create mode 100644 selftest/knownfail.d/uac_objectclass_restrict

diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict
new file mode 100644
index 00000000000..a076f9cfedb
--- /dev/null
+++ b/selftest/knownfail.d/uac_objectclass_restrict
@@ -0,0 +1,42 @@
+# Knownfail entries due to restricting the creation of computer/user
+# accounts (in terms of userAccountControl) that do not match the objectclass
+#
+# All these tests need to be fixed and the entries here removed
+
+^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_isCriticalSystemObject\(fl2008r2dc\)
+^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_userAccountControl\(fl2008r2dc\)
+^samba4.sam.python\(fl2008r2dc\).__main__.SamTests.test_users_groups\(fl2008r2dc\)
+^samba4.ldap.python\(ad_dc_default\).__main__.BasicTests.test_all\(ad_dc_default\)
+^samba4.sam.python\(ad_dc_default\).__main__.SamTests.test_isCriticalSystemObject\(ad_dc_default\)
+^samba4.sam.python\(ad_dc_default\).__main__.SamTests.test_userAccountControl\(ad_dc_default\)
+^samba4.sam.python\(ad_dc_default\).__main__.SamTests.test_users_groups\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_add_computer_sd_cc\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_admin_mod_uac\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_computer_cc\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_0x10000000\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_0x20000000\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_0x40000000\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_0x80000000\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00000004\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00000400\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00004000\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_00008000\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_ACCOUNTDISABLE\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_DONT_EXPIRE_PASSWD\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_DONT_REQUIRE_PREAUTH\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_HOMEDIR_REQUIRED\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_LOCKOUT\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_MNS_LOGON_ACCOUNT\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_NORMAL_ACCOUNT\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_NOT_DELEGATED\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_NO_AUTH_DATA_REQUIRED\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_PASSWD_CANT_CHANGE\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_PASSWD_NOTREQD\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_PASSWORD_EXPIRED\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_SCRIPT\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_SMARTCARD_REQUIRED\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_USE_AES_KEYS\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_USE_DES_KEY_ONLY\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_NORMAL_ACCOUNT\(ad_dc_default\)
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index cb5fda324a4..8df86f29883 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -1413,19 +1413,33 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac)
 
 	switch(ac->type) {
 	case SAMLDB_TYPE_USER: {
+		bool is_computer_objectclass;
 		bool uac_generated = false, uac_add_flags = false;
-
+		uint32_t default_user_account_control = UF_NORMAL_ACCOUNT;
 		/* Step 1.2: Default values */
 		ret = dsdb_user_obj_set_defaults(ldb, ac->msg, ac->req);
 		if (ret != LDB_SUCCESS) return ret;
 
+		is_computer_objectclass
+			= (samdb_find_attribute(ldb,
+						 ac->msg,
+						"objectclass",
+						"computer")
+			   != NULL);
+
+		if (is_computer_objectclass) {
+			default_user_account_control
+				= UF_WORKSTATION_TRUST_ACCOUNT;
+		}
+
+
 		/* On add operations we might need to generate a
 		 * "userAccountControl" (if it isn't specified). */
 		el = ldb_msg_find_element(ac->msg, "userAccountControl");
 		if ((el == NULL) && (ac->req->operation == LDB_ADD)) {
 			ret = samdb_msg_set_uint(ldb, ac->msg, ac->msg,
 						 "userAccountControl",
-						 UF_NORMAL_ACCOUNT);
+						 default_user_account_control);
 			if (ret != LDB_SUCCESS) {
 				return ret;
 			}
@@ -1444,11 +1458,14 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac)
 			raw_uac = user_account_control;
 			/*
 			 * "userAccountControl" = 0 or missing one of
-			 * the types means "UF_NORMAL_ACCOUNT".  See
-			 * MS-SAMR 3.1.1.8.10 point 8
+			 * the types means "UF_NORMAL_ACCOUNT"
+			 * or "UF_WORKSTATION_TRUST_ACCOUNT" (if a computer).
+			 * See MS-SAMR 3.1.1.8.10 point 8
 			 */
 			if ((user_account_control & UF_ACCOUNT_TYPE_MASK) == 0) {
-				user_account_control = UF_NORMAL_ACCOUNT | user_account_control;
+				user_account_control
+					= default_user_account_control
+					| user_account_control;
 				uac_generated = true;
 			}
 
-- 
2.23.0

