]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2020-25722 dsdb: Prohibit mismatch between UF_ account types and objectclass.
authorAndrew Bartlett <abartlet@samba.org>
Fri, 22 Oct 2021 03:07:46 +0000 (16:07 +1300)
committerJule Anger <janger@samba.org>
Mon, 8 Nov 2021 09:52:10 +0000 (10:52 +0100)
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>
selftest/knownfail.d/priv_attr
selftest/knownfail.d/uac_mod_lock
selftest/knownfail.d/uac_objectclass_restrict
source4/dsdb/samdb/ldb_modules/samldb.c

index 4b85a8690892c38720ca75cc1179b9569c3512a1..e0d6104cec9c27a19ce80871c27335275d44569d 100644 (file)
@@ -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
index 6f45fa5055465cc1564336723c2a3a07a46959ac..a84a236c355be8765bf710c466aeb5cc8c791b77 100644 (file)
 ^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
index bb0787c1a48ba1ec0052348566587707f2a0b7ad..040c4eb219d7b964f5ef66e389456df0c41ee7a1 100644 (file)
 ^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\)
 ^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\)
 ^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\)
index 8df86f29883b33bb10c299b8489f1e2a13b6262b..15459abcbca01c128c401f31e14f6a57eb2845ac 100644 (file)
@@ -1365,7 +1365,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)
@@ -1484,21 +1485,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) {
@@ -1993,6 +1985,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)
 {
@@ -2191,7 +2283,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;
@@ -2200,6 +2293,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;
@@ -2261,7 +2362,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;
 
@@ -2316,7 +2417,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);
@@ -2324,7 +2428,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;
@@ -2349,7 +2453,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;
        }
@@ -2371,25 +2476,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;