]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2022-37966 s4:kdc: Move supported enc-type handling out of samba_kdc_message2entr...
authorAndrew Bartlett <abartlet@samba.org>
Wed, 23 Mar 2022 00:07:29 +0000 (13:07 +1300)
committerStefan Metzmacher <metze@samba.org>
Tue, 13 Dec 2022 23:48:48 +0000 (00:48 +0100)
By putting this in the caller we potentially allow samba_kdc_message2entry_keys()
to be reused by a non-KDC caller.

Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit 29eb7e2488e2c55ceacb859a57836a08cbb7f8e8)

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

[jsutton@samba.org Adapted to older code without support for Protected
 Users or older keys; kept still-needed 'kdc_db_ctx'
 samba_kdc_message2entry_keys() parameter]
Reviewed-by: Stefan Metzmacher <metze@samba.org>
[jsutton@samba.org Adapted to older db-glue code]

source4/kdc/db-glue.c

index ec696bf53b8fb1bc660bdc58b4b09ff29e7324eb..dd6b6a247aaef04357f7741d4931f5b1e345fadf 100644 (file)
@@ -320,11 +320,12 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
                                                    struct samba_kdc_db_context *kdc_db_ctx,
                                                    TALLOC_CTX *mem_ctx,
                                                    struct ldb_message *msg,
-                                                   uint32_t rid,
+                                                   bool is_krbtgt,
                                                    bool is_rodc,
                                                    uint32_t userAccountControl,
                                                    enum samba_kdc_ent_type ent_type,
                                                    struct sdb_entry_ex *entry_ex,
+                                                   const uint32_t supported_enctypes_in,
                                                    uint32_t *supported_enctypes_out)
 {
        struct sdb_entry *entry = &entry_ex->entry;
@@ -338,43 +339,14 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
        struct package_PrimaryKerberosBlob _pkb;
        struct package_PrimaryKerberosCtr3 *pkb3 = NULL;
        struct package_PrimaryKerberosCtr4 *pkb4 = NULL;
-       bool is_krbtgt = false;
        int krbtgt_number = 0;
        uint32_t current_kvno;
        uint32_t returned_kvno = 0;
        uint16_t i;
        uint16_t allocated_keys = 0;
-       uint32_t supported_enctypes
-               = ldb_msg_find_attr_as_uint(msg,
-                                           "msDS-SupportedEncryptionTypes",
-                                           0);
-       *supported_enctypes_out = 0;
-
-       if (rid == DOMAIN_RID_KRBTGT || is_rodc) {
-               /* KDCs (and KDCs on RODCs) use AES */
-               supported_enctypes |= ENC_HMAC_SHA1_96_AES128 | ENC_HMAC_SHA1_96_AES256;
-               is_krbtgt = true;
-       } else if (userAccountControl & (UF_PARTIAL_SECRETS_ACCOUNT|UF_SERVER_TRUST_ACCOUNT)) {
-               /* DCs and RODCs comptuer accounts use AES */
-               supported_enctypes |= ENC_HMAC_SHA1_96_AES128 | ENC_HMAC_SHA1_96_AES256;
-       } else if (ent_type == SAMBA_KDC_ENT_TYPE_CLIENT ||
-                  (ent_type == SAMBA_KDC_ENT_TYPE_ANY)) {
-               /* for AS-REQ the client chooses the enc types it
-                * supports, and this will vary between computers a
-                * user logs in from.
-                *
-                * likewise for 'any' return as much as is supported,
-                * to export into a keytab */
-               supported_enctypes = ENC_ALL_TYPES;
-       }
+       uint32_t supported_enctypes = supported_enctypes_in;
 
-       /* If UF_USE_DES_KEY_ONLY has been set, then don't allow use of the newer enc types */
-       if (userAccountControl & UF_USE_DES_KEY_ONLY) {
-               supported_enctypes = 0;
-       } else {
-               /* Otherwise, add in the default enc types */
-               supported_enctypes |= ENC_RC4_HMAC_MD5;
-       }
+       *supported_enctypes_out = 0;
 
        /* Is this the krbtgt or a RODC krbtgt */
        if (is_rodc) {
@@ -976,14 +948,18 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
        krb5_boolean is_computer = FALSE;
 
        struct samba_kdc_entry *p;
-       uint32_t supported_enctypes = 0;
        NTTIME acct_expiry;
        NTSTATUS status;
 
        uint32_t rid;
+       bool is_krbtgt = false;
        bool is_rodc = false;
        struct ldb_message_element *objectclasses;
        struct ldb_val computer_val;
+       uint32_t supported_enctypes
+               = ldb_msg_find_attr_as_uint(msg,
+                                           "msDS-SupportedEncryptionTypes",
+                                           0);
        const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
        computer_val.data = discard_const_p(uint8_t,"computer");
        computer_val.length = strlen((const char *)computer_val.data);
@@ -1276,10 +1252,39 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
 
        *entry_ex->entry.max_renew = kdc_db_ctx->policy.renewal_lifetime;
 
+       if (rid == DOMAIN_RID_KRBTGT || is_rodc) {
+               /* KDCs (and KDCs on RODCs) use AES */
+               supported_enctypes |= ENC_HMAC_SHA1_96_AES128 | ENC_HMAC_SHA1_96_AES256;
+               is_krbtgt = true;
+       } else if (userAccountControl & (UF_PARTIAL_SECRETS_ACCOUNT|UF_SERVER_TRUST_ACCOUNT)) {
+               /* DCs and RODCs comptuer accounts use AES */
+               supported_enctypes |= ENC_HMAC_SHA1_96_AES128 | ENC_HMAC_SHA1_96_AES256;
+       } else if (ent_type == SAMBA_KDC_ENT_TYPE_CLIENT ||
+                  (ent_type == SAMBA_KDC_ENT_TYPE_ANY)) {
+               /* for AS-REQ the client chooses the enc types it
+                * supports, and this will vary between computers a
+                * user logs in from.
+                *
+                * likewise for 'any' return as much as is supported,
+                * to export into a keytab */
+               supported_enctypes = ENC_ALL_TYPES;
+       }
+
+       /* If UF_USE_DES_KEY_ONLY has been set, then don't allow use of the newer enc types */
+       if (userAccountControl & UF_USE_DES_KEY_ONLY) {
+               supported_enctypes = 0;
+       } else {
+               /* Otherwise, add in the default enc types */
+               supported_enctypes |= ENC_RC4_HMAC_MD5;
+       }
+
        /* 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);
+                                          is_krbtgt, is_rodc,
+                                          userAccountControl,
+                                          ent_type, entry_ex,
+                                          supported_enctypes,
+                                          &supported_enctypes);
        if (ret) {
                /* Could be bogus data in the entry, or out of memory */
                goto out;