]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s4:kdc: Add KDC support for Protected Users group
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Wed, 2 Feb 2022 04:08:41 +0000 (17:08 +1300)
committerStefan Metzmacher <metze@samba.org>
Fri, 18 Mar 2022 11:55:30 +0000 (11:55 +0000)
Accounts in the Protected Users group acting as clients lack support for
the RC4 encryption type. TGTs issued to such accounts have a lifetime
restricted to four hours, and are unable to be proxied or forwarded.

To determine at lookup time whether a client account is a member of
Protected Users, we now also create an auth_user_info_dc structure when
creating the database entry for an AS-REQ, rather than only when
creating a PAC for a TGT, or when recreating the PAC from an RODC-issued
TGT.

This means that the user's groups are now expanded even for AS-REQs that
result in an error (such as a PREAUTH_REQUIRED error), but this is
required to be able to correctly determine the account's available
encryption types, which are needed soon after fetching the user account.

Currently, the TGT lifetime may exceed four hours (for Heimdal
specifically). This may happen if PKINIT is used, and either the
pkinit_max_life_from_cert_extension option is TRUE and
pkinit_max_life_bound is greater than four hours, or
pkinit_max_life_from_cert is greater than four hours.

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
selftest/knownfail_heimdal_kdc
selftest/knownfail_mit_kdc
source4/kdc/db-glue.c
source4/kdc/db-glue.h
source4/kdc/hdb-samba4.c

index f6ac23894cb9afecf265ccb15e8b29c1620595a9..b03fca8ef21c1787872e7d84cd21c39a092d1a5a 100644 (file)
 # This test fails, which is fine, as we have an alternate test that considers a policy error as successful.
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_proxiable_as_protected.ad_dc
 #
-^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_forwardable_as_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_ntlm_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_ntlm_protected_nested.ad_dc
-^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_proxiable_as_protected_policy_error.ad_dc
-^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_rc4_mac_protected.ad_dc
-^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_rc4_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_samlogon_interactive_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_samlogon_network_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_samr_change_password_protected.ad_dc
-^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_tgt_lifetime_longer_protected.ad_dc
-^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_ts_rc4_mac_protected.ad_dc
-^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_ts_rc4_protected.ad_dc
-^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_ts_rc4_protected_nested.ad_dc
index c16a8de448b192169e656c8542c5dc93226cb65d..f450312ff7ab272ab2ddab6561f6aecf1de067f3 100644 (file)
@@ -427,17 +427,14 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_
 #
 # Protected Users tests
 #
-^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_forwardable_as_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_ntlm_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_ntlm_protected_nested.ad_dc
-^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_proxiable_as_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_proxiable_as_protected_policy_error.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_rc4_mac_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_rc4_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_samlogon_interactive_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_samlogon_network_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_samr_change_password_protected.ad_dc
-^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_tgt_lifetime_longer_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_ts_aes128_mac_not_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_ts_aes128_mac_protected.ad_dc
 ^samba.tests.krb5.protected_users_tests.samba.tests.krb5.protected_users_tests.ProtectedUsersTests.test_ts_aes128_not_protected.ad_dc
index eef2a9dc4c040c5ddcfa49846e7ae37fb10034a4..d384ecea811d05f231d214cbbd778670107143c8 100644 (file)
@@ -323,9 +323,10 @@ static int samba_kdc_sort_encryption_keys(struct sdb_entry_ex *entry_ex)
 int samba_kdc_set_fixed_keys(krb5_context context,
                             struct samba_kdc_db_context *kdc_db_ctx,
                             const struct ldb_val *secretbuffer,
+                            bool is_protected,
                             struct sdb_entry_ex *entry_ex)
 {
-       const uint32_t supported_enctypes = ENC_ALL_TYPES;
+       uint32_t supported_enctypes = ENC_ALL_TYPES;
        uint16_t allocated_keys = 0;
        int ret;
 
@@ -338,6 +339,10 @@ int samba_kdc_set_fixed_keys(krb5_context context,
                goto out;
        }
 
+       if (is_protected) {
+               supported_enctypes &= ~ENC_RC4_HMAC_MD5;
+       }
+
        if (supported_enctypes & ENC_HMAC_SHA1_96_AES256) {
                struct sdb_key key = {};
 
@@ -396,7 +401,8 @@ out:
 
 static int samba_kdc_set_random_keys(krb5_context context,
                                     struct samba_kdc_db_context *kdc_db_ctx,
-                                    struct sdb_entry_ex *entry_ex)
+                                    struct sdb_entry_ex *entry_ex,
+                                    bool is_protected)
 {
        struct ldb_val secret_val;
        uint8_t secretbuffer[32];
@@ -414,6 +420,7 @@ static int samba_kdc_set_random_keys(krb5_context context,
                                     sizeof(secretbuffer));
        return samba_kdc_set_fixed_keys(context, kdc_db_ctx,
                                        &secret_val,
+                                       is_protected,
                                        entry_ex);
 }
 
@@ -427,6 +434,7 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
                                                    uint32_t userAccountControl,
                                                    enum samba_kdc_ent_type ent_type,
                                                    struct sdb_entry_ex *entry_ex,
+                                                   bool is_protected,
                                                    uint32_t *supported_enctypes_out)
 {
        krb5_error_code ret = 0;
@@ -481,6 +489,10 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
                supported_enctypes |= ENC_RC4_HMAC_MD5;
        }
 
+       if (is_protected) {
+               supported_enctypes &= ~ENC_RC4_HMAC_MD5;
+       }
+
        /* Is this the krbtgt or a RODC krbtgt */
        if (is_rodc) {
                rodc_krbtgt_number = ldb_msg_find_attr_as_int(msg, "msDS-SecondaryKrbTgtNumber", -1);
@@ -498,7 +510,8 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
            && (userAccountControl & UF_SMARTCARD_REQUIRED)) {
                ret = samba_kdc_set_random_keys(context,
                                                kdc_db_ctx,
-                                               entry_ex);
+                                               entry_ex,
+                                               is_protected);
 
                *supported_enctypes_out = supported_enctypes;
 
@@ -869,6 +882,7 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
        uint32_t supported_enctypes = 0;
        NTTIME acct_expiry;
        NTSTATUS status;
+       bool protected_user = false;
        uint32_t rid;
        bool is_rodc = false;
        struct ldb_message_element *objectclasses;
@@ -1239,10 +1253,50 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
 
        *entry_ex->entry.max_renew = kdc_db_ctx->policy.renewal_lifetime;
 
+       if (ent_type == SAMBA_KDC_ENT_TYPE_CLIENT && (flags & SDB_F_FOR_AS_REQ)) {
+               int result;
+               struct auth_user_info_dc *user_info_dc = NULL;
+               /*
+                * These protections only apply to clients, so servers in the
+                * Protected Users group may still have service tickets to them
+                * encrypted with RC4. For accounts looked up as servers, note
+                * that 'msg' does not contain the 'memberOf' attribute for
+                * determining whether the account is a member of Protected
+                * Users.
+                *
+                * Additionally, Microsoft advises that accounts for services
+                * and computers should never be members of Protected Users, or
+                * they may fail to authenticate.
+                */
+               status = samba_kdc_get_user_info_from_db(p, msg, &user_info_dc);
+               if (!NT_STATUS_IS_OK(status)) {
+                       ret = EINVAL;
+                       goto out;
+               }
+
+               result = dsdb_is_protected_user(kdc_db_ctx->samdb,
+                                               user_info_dc->sids,
+                                               user_info_dc->num_sids);
+               if (result == -1) {
+                       ret = EINVAL;
+                       goto out;
+               }
+
+               protected_user = result;
+
+               if (protected_user) {
+                       *entry_ex->entry.max_life = MIN(*entry_ex->entry.max_life, 4 * 60 * 60);
+                       *entry_ex->entry.max_renew = MIN(*entry_ex->entry.max_renew, 4 * 60 * 60);
+
+                       entry_ex->entry.flags.forwardable = 0;
+                       entry_ex->entry.flags.proxiable = 0;
+               }
+       }
+
        /* Get keys from the db */
        ret = samba_kdc_message2entry_keys(context, kdc_db_ctx, p, msg,
                                           rid, is_rodc, userAccountControl,
-                                          ent_type, entry_ex, &supported_enctypes);
+                                          ent_type, entry_ex, protected_user, &supported_enctypes);
        if (ret) {
                /* Could be bogus data in the entry, or out of memory */
                goto out;
index f3d9c817b77dd18f80850c00bba227ffc04f5ab3..ad1015171a915a8546c56708c71c83652fb5b5cd 100644 (file)
@@ -27,6 +27,7 @@ struct sdb_entry_ex;
 int samba_kdc_set_fixed_keys(krb5_context context,
                             struct samba_kdc_db_context *kdc_db_ctx,
                             const struct ldb_val *secretbuffer,
+                            bool is_protected,
                             struct sdb_entry_ex *entry_ex);
 
 krb5_error_code samba_kdc_fetch(krb5_context context,
index e82ebbe7daa619b8cdb158a1e7647a502d8135a1..dcd9c3979aa611875e3cf8a8ae3d4b416d53a3c9 100644 (file)
@@ -221,7 +221,7 @@ static krb5_error_code hdb_samba4_fetch_fast_cookie(krb5_context context,
        }
 
        ret = samba_kdc_set_fixed_keys(context, kdc_db_ctx,
-                                      val, &sdb_entry_ex);
+                                      val, false, &sdb_entry_ex);
        if (ret != 0) {
                return ret;
        }