From: Joseph Sutton Date: Wed, 2 Feb 2022 04:08:41 +0000 (+1300) Subject: s4:kdc: Add KDC support for Protected Users group X-Git-Tag: tevent-0.12.0~368 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=402d5f59bcb1929cf3db5efb03edf2f62748e40e;p=thirdparty%2Fsamba.git s4:kdc: Add KDC support for Protected Users group 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 Reviewed-by: Stefan Metzmacher --- diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc index f6ac23894cb..b03fca8ef21 100644 --- a/selftest/knownfail_heimdal_kdc +++ b/selftest/knownfail_heimdal_kdc @@ -53,16 +53,8 @@ # 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 diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc index c16a8de448b..f450312ff7a 100644 --- a/selftest/knownfail_mit_kdc +++ b/selftest/knownfail_mit_kdc @@ -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 diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c index eef2a9dc4c0..d384ecea811 100644 --- a/source4/kdc/db-glue.c +++ b/source4/kdc/db-glue.c @@ -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; diff --git a/source4/kdc/db-glue.h b/source4/kdc/db-glue.h index f3d9c817b77..ad1015171a9 100644 --- a/source4/kdc/db-glue.h +++ b/source4/kdc/db-glue.h @@ -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, diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index e82ebbe7daa..dcd9c3979aa 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -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; }