summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2021-10-22 16:07:46 +1300
committerJule Anger <janger@samba.org>2021-11-09 19:45:32 +0000
commita00c525a4e01342ee8b9ec8441994ad27bffb254 (patch)
treef92ecc25e745f7e4f9d9a8ee086f3efa52999f1e
parent6a8f03c52746bc5e55caf40d4a57838a84808269 (diff)
downloadsamba-a00c525a4e01342ee8b9ec8441994ad27bffb254.tar.gz
CVE-2020-25722 dsdb: Prohibit mismatch between UF_ account types and objectclass.
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. The restriction is not applied to users with administrator rights, as this breaks a lot of tests and provides no security benefit. 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>
-rw-r--r--selftest/knownfail.d/priv_attr6
-rw-r--r--selftest/knownfail.d/uac_mod_lock6
-rw-r--r--selftest/knownfail.d/uac_objectclass_restrict35
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c153
4 files changed, 145 insertions, 55 deletions
diff --git a/selftest/knownfail.d/priv_attr b/selftest/knownfail.d/priv_attr
index 4b85a869089..e0d6104cec9 100644
--- a/selftest/knownfail.d/priv_attr
+++ b/selftest/knownfail.d/priv_attr
@@ -6,9 +6,3 @@ samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sid
samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_WP_user
samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_default_computer
samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_sidHistory_add_admin-add_default_user
-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-RODC_add_CC_WP_user
-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-RODC_add_CC_default_user
-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-computer_add_CC_WP_user
-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-computer_add_CC_default_user
-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-computer_add_CC_WP_user
-samba4.priv_attrs.strict.python\(.*\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-computer_add_CC_default_user
diff --git a/selftest/knownfail.d/uac_mod_lock b/selftest/knownfail.d/uac_mod_lock
index 6f45fa50554..a84a236c355 100644
--- a/selftest/knownfail.d/uac_mod_lock
+++ b/selftest/knownfail.d/uac_mod_lock
@@ -24,16 +24,10 @@
^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_remove_dollar
^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_keep_dollar
^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_NORMAL_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_remove_dollar
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_None_UF_NORMAL_ACCOUNT_keep_dollar
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_None_UF_NORMAL_ACCOUNT_remove_dollar
^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_None_UF_SERVER_TRUST_ACCOUNT_remove_dollar
^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_None_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_keep_dollar
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_computer_UF_NORMAL_ACCOUNT_remove_dollar
^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_computer_UF_SERVER_TRUST_ACCOUNT_remove_dollar
^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_computer_UF_WORKSTATION_TRUST_ACCOUNT_remove_dollar
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_keep_dollar
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_NORMAL_ACCOUNT_remove_dollar
^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_keep_dollar
^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_SERVER_TRUST_ACCOUNT_remove_dollar
^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_mod_lock_wp_computer_UF_SERVER_TRUST_ACCOUNT_to_user_UF_WORKSTATION_TRUST_ACCOUNT_keep_dollar
diff --git a/selftest/knownfail.d/uac_objectclass_restrict b/selftest/knownfail.d/uac_objectclass_restrict
index bb0787c1a48..040c4eb219d 100644
--- a/selftest/knownfail.d/uac_objectclass_restrict
+++ b/selftest/knownfail.d/uac_objectclass_restrict
@@ -10,6 +10,16 @@
^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.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-DC_add_CC_WP_user\(ad_dc_default\)
+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-DC_add_CC_default_user\(ad_dc_default\)
+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_CC_WP_computer\(ad_dc_default\)
+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_add_CC_default_computer\(ad_dc_default\)
+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_mod-del-add_CC_default_computer\(ad_dc_default\)
+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-a2d-user_mod-replace_CC_default_computer\(ad_dc_default\)
+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-user_add_CC_WP_computer\(ad_dc_default\)
+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-user_add_CC_default_computer\(ad_dc_default\)
+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-user_mod-del-add_CC_default_computer\(ad_dc_default\)
+^samba4.priv_attrs.strict.python\(ad_dc_default\).__main__.PrivAttrsTests.test_priv_attr_userAccountControl-t4d-user_mod-replace_CC_default_computer\(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\)
@@ -17,18 +27,6 @@
^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_NORMAL_ACCOUNT_user_replace\(ad_dc_default\)
^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_SERVER_TRUST_ACCOUNT_computer_replace\(ad_dc_default\)
^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_computer_replace\(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\)
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_uac_dollar_lock_UF_NORMAL_ACCOUNT_computer_cc_plain\(ad_dc_default\)
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_uac_dollar_lock_UF_NORMAL_ACCOUNT_computer_cc_withdollar\(ad_dc_default\)
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_uac_dollar_lock_UF_SERVER_TRUST_ACCOUNT_user_cc_plain\(ad_dc_default\)
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_uac_dollar_lock_UF_SERVER_TRUST_ACCOUNT_user_cc_withdollar\(ad_dc_default\)
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_WORKSTATION_TRUST_ACCOUNT_deladd_wp\(ad_dc_default\)
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_WORKSTATION_TRUST_ACCOUNT_replace_wp\(ad_dc_default\)
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_SERVER_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_deladd_wp\(ad_dc_default\)
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_SERVER_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_replace_wp\(ad_dc_default\)
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_deladd_wp\(ad_dc_default\)
-^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_WORKSTATION_TRUST_ACCOUNT_UF_NORMAL_ACCOUNT_replace_wp\(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\)
@@ -54,3 +52,16 @@
^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\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_unrelated_modify_UF_WORKSTATION_TRUST_ACCOUNT\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_SERVER_TRUST_ACCOUNT_deladd_priv\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_SERVER_TRUST_ACCOUNT_deladd_wp\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_SERVER_TRUST_ACCOUNT_replace_priv\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_objectclass_uac_mod_lock_UF_NORMAL_ACCOUNT_UF_SERVER_TRUST_ACCOUNT_replace_wp\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_add_UF_INTERDOMAIN_TRUST_ACCOUNT\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_add_UF_NORMAL_ACCOUNT\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_add_UF_NORMAL_ACCOUNT_UF_PASSWD_NOTREQD\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_INTERDOMAIN_TRUST_ACCOUNT\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_TRUSTED_FOR_DELEGATION\(ad_dc_default\)
+^samba4.user_account_control.python\(ad_dc_default\).__main__.UserAccountControlTests.test_uac_bits_set_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION\(ad_dc_default\)
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index da74462ec57..d7e0a33be96 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -1368,7 +1368,8 @@ static int samldb_check_user_account_control_rules(struct samldb_ctx *ac,
struct dom_sid *sid,
uint32_t req_uac,
uint32_t user_account_control,
- uint32_t user_account_control_old);
+ uint32_t user_account_control_old,
+ bool is_computer_objectclass);
/*
* "Objectclass" trigger (MS-SAMR 3.1.1.8.1)
@@ -1487,21 +1488,12 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac)
ret = samldb_check_user_account_control_rules(ac, NULL,
raw_uac,
user_account_control,
- 0);
+ 0,
+ is_computer_objectclass);
if (ret != LDB_SUCCESS) {
return ret;
}
- /* Workstation and (read-only) DC objects do need objectclass "computer" */
- if ((samdb_find_attribute(ldb, ac->msg,
- "objectclass", "computer") == NULL) &&
- (user_account_control &
- (UF_SERVER_TRUST_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT))) {
- ldb_set_errstring(ldb,
- "samldb: Requested account type does need objectclass 'computer'!");
- return LDB_ERR_OBJECT_CLASS_VIOLATION;
- }
-
/* add "sAMAccountType" attribute */
ret = dsdb_user_obj_set_account_type(ldb, ac->msg, user_account_control, NULL);
if (ret != LDB_SUCCESS) {
@@ -1997,6 +1989,106 @@ static int samldb_check_user_account_control_invariants(struct samldb_ctx *ac,
return ret;
}
+/*
+ * It would be best if these rules apply, always, but for now they
+ * apply only to non-admins
+ */
+static int samldb_check_user_account_control_objectclass_invariants(
+ struct samldb_ctx *ac,
+ uint32_t user_account_control,
+ uint32_t user_account_control_old,
+ bool is_computer_objectclass)
+{
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
+
+ uint32_t old_ufa = user_account_control_old & UF_ACCOUNT_TYPE_MASK;
+ uint32_t new_ufa = user_account_control & UF_ACCOUNT_TYPE_MASK;
+
+ uint32_t old_rodc = user_account_control_old & UF_PARTIAL_SECRETS_ACCOUNT;
+ uint32_t new_rodc = user_account_control & UF_PARTIAL_SECRETS_ACCOUNT;
+
+ bool is_admin;
+ struct security_token *user_token
+ = acl_user_token(ac->module);
+ if (user_token == NULL) {
+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
+ }
+
+ is_admin
+ = security_token_has_builtin_administrators(user_token);
+
+
+ /*
+ * We want to allow changes to (eg) disable an account
+ * that was created wrong, only checking the
+ * objectclass if the account type changes.
+ */
+ if (old_ufa == new_ufa && old_rodc == new_rodc) {
+ return LDB_SUCCESS;
+ }
+
+ switch (new_ufa) {
+ case UF_NORMAL_ACCOUNT:
+ if (is_computer_objectclass && !is_admin) {
+ ldb_asprintf_errstring(ldb,
+ "%08X: samldb: UF_NORMAL_ACCOUNT "
+ "requires objectclass 'user' not 'computer'!",
+ W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4));
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
+ }
+ break;
+
+ case UF_INTERDOMAIN_TRUST_ACCOUNT:
+ if (is_computer_objectclass) {
+ ldb_asprintf_errstring(ldb,
+ "%08X: samldb: UF_INTERDOMAIN_TRUST_ACCOUNT "
+ "requires objectclass 'user' not 'computer'!",
+ W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4));
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
+ }
+ break;
+
+ case UF_WORKSTATION_TRUST_ACCOUNT:
+ if (!is_computer_objectclass) {
+ /*
+ * Modify of a user account account into a
+ * workstation without objectclass computer
+ * as an admin is still permitted, but not
+ * to make an RODC
+ */
+ if (is_admin
+ && ac->req->operation == LDB_MODIFY
+ && new_rodc == 0) {
+ break;
+ }
+ ldb_asprintf_errstring(ldb,
+ "%08X: samldb: UF_WORKSTATION_TRUST_ACCOUNT "
+ "requires objectclass 'computer'!",
+ W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4));
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
+ }
+ break;
+
+ case UF_SERVER_TRUST_ACCOUNT:
+ if (!is_computer_objectclass) {
+ ldb_asprintf_errstring(ldb,
+ "%08X: samldb: UF_SERVER_TRUST_ACCOUNT "
+ "requires objectclass 'computer'!",
+ W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4));
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
+ }
+ break;
+
+ default:
+ ldb_asprintf_errstring(ldb,
+ "%08X: samldb: invalid userAccountControl[0x%08X]",
+ W_ERROR_V(WERR_INVALID_PARAMETER),
+ user_account_control);
+ return LDB_ERR_OTHER;
+ }
+ return LDB_SUCCESS;
+}
+
static int samldb_get_domain_secdesc(struct samldb_ctx *ac,
struct security_descriptor **domain_sd)
{
@@ -2196,7 +2288,8 @@ static int samldb_check_user_account_control_rules(struct samldb_ctx *ac,
struct dom_sid *sid,
uint32_t req_uac,
uint32_t user_account_control,
- uint32_t user_account_control_old)
+ uint32_t user_account_control_old,
+ bool is_computer_objectclass)
{
int ret;
struct dsdb_control_password_user_account_control *uac = NULL;
@@ -2205,6 +2298,14 @@ static int samldb_check_user_account_control_rules(struct samldb_ctx *ac,
if (ret != LDB_SUCCESS) {
return ret;
}
+ ret = samldb_check_user_account_control_objectclass_invariants(ac,
+ user_account_control,
+ user_account_control_old,
+ is_computer_objectclass);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
ret = samldb_check_user_account_control_acl(ac, sid, user_account_control, user_account_control_old);
if (ret != LDB_SUCCESS) {
return ret;
@@ -2266,7 +2367,7 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
"objectSid",
NULL
};
- bool is_computer = false;
+ bool is_computer_objectclass = false;
bool old_is_critical = false;
bool new_is_critical = false;
@@ -2321,7 +2422,10 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
"lockoutTime", 0);
old_is_critical = ldb_msg_find_attr_as_bool(res->msgs[0],
"isCriticalSystemObject", 0);
- /* When we do not have objectclass "computer" we cannot switch to a (read-only) DC */
+ /*
+ * When we do not have objectclass "computer" we cannot
+ * switch to a workstation or (RO)DC
+ */
el = ldb_msg_find_element(res->msgs[0], "objectClass");
if (el == NULL) {
return ldb_operr(ldb);
@@ -2329,7 +2433,7 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
computer_val = data_blob_string_const("computer");
val = ldb_msg_find_val(el, &computer_val);
if (val != NULL) {
- is_computer = true;
+ is_computer_objectclass = true;
}
old_ufa = old_uac & UF_ACCOUNT_TYPE_MASK;
@@ -2354,7 +2458,8 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
ret = samldb_check_user_account_control_rules(ac, sid,
raw_uac,
new_uac,
- old_uac);
+ old_uac,
+ is_computer_objectclass);
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -2376,25 +2481,11 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
case UF_WORKSTATION_TRUST_ACCOUNT:
new_is_critical = false;
if (new_uac & UF_PARTIAL_SECRETS_ACCOUNT) {
- if (!is_computer) {
- ldb_asprintf_errstring(ldb,
- "%08X: samldb: UF_PARTIAL_SECRETS_ACCOUNT "
- "requires objectclass 'computer'!",
- W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4));
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
new_is_critical = true;
}
break;
case UF_SERVER_TRUST_ACCOUNT:
- if (!is_computer) {
- ldb_asprintf_errstring(ldb,
- "%08X: samldb: UF_SERVER_TRUST_ACCOUNT "
- "requires objectclass 'computer'!",
- W_ERROR_V(WERR_DS_MACHINE_ACCOUNT_CREATED_PRENT4));
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
new_is_critical = true;
break;