TODO: s4:kdc: samba_kdc_sort_keys(max_keys)
authorStefan Metzmacher <metze@samba.org>
Thu, 24 Mar 2022 13:12:12 +0000 (14:12 +0100)
committerStefan Metzmacher <metze@samba.org>
Fri, 2 Feb 2024 10:31:16 +0000 (11:31 +0100)
This can be used in future to limit the number of keys to 1,
in order to expose only the strongest etype.

source4/kdc/db-glue.c

index 110107ccdf402efdd6d1697e8bc6015a3f2a507d..49c660b582c899d8e366f6993e34c2e776cf4ebc 100644 (file)
@@ -328,13 +328,23 @@ static int sdb_key_strength_cmp(const struct sdb_key *k1, const struct sdb_key *
        }
 }
 
-static void samba_kdc_sort_keys(struct sdb_keys *keys)
+static void samba_kdc_sort_keys(struct sdb_keys *keys,
+                               unsigned int max_keys)
 {
+       SMB_ASSERT(max_keys > 0);
+
        if (keys == NULL) {
                return;
        }
 
        TYPESAFE_QSORT(keys->val, keys->len, sdb_key_strength_cmp);
+
+       while (keys->len > max_keys) {
+               unsigned int idx = keys->len - 1;
+
+               sdb_key_free(&keys->val[idx]);
+               keys->len -= 1;
+       }
 }
 
 int samba_kdc_set_fixed_keys(krb5_context context,
@@ -436,6 +446,7 @@ static int samba_kdc_set_random_keys(krb5_context context,
 
 struct samba_kdc_user_keys {
        struct sdb_keys *skeys;
+       uint32_t max_keys;
        uint32_t kvno;
        uint32_t *returned_kvno;
        uint32_t supported_enctypes;
@@ -567,7 +578,7 @@ static krb5_error_code samba_kdc_fill_user_keys(krb5_context context,
                }
        }
 
-       samba_kdc_sort_keys(p->skeys);
+       samba_kdc_sort_keys(p->skeys, p->max_keys);
 
        return 0;
 fail:
@@ -793,6 +804,7 @@ krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
                         * so we return it.
                         */
                        keys.skeys = &entry->keys;
+                       keys.max_keys = UINT32_MAX;
                        keys.available_enctypes = &available_enctypes;
                        keys.returned_kvno = &returned_kvno;
                } else if (requested_kvno == 0) {
@@ -805,6 +817,7 @@ krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
                         * with the requested kvno.
                         */
                        old_keys.skeys = &entry->keys;
+                       old_keys.max_keys = UINT32_MAX;
                        old_keys.available_enctypes = &available_enctypes;
                        old_keys.returned_kvno = &returned_kvno;
                } else if (requested_kvno == older_keys.kvno) {
@@ -813,6 +826,7 @@ krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
                         * with the requested kvno.
                         */
                        older_keys.skeys = &entry->keys;
+                       older_keys.max_keys = UINT32_MAX;
                        older_keys.available_enctypes = &available_enctypes;
                        older_keys.returned_kvno = &returned_kvno;
                } else {
@@ -830,14 +844,17 @@ krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
                }
 
                keys.skeys = &entry->keys;
+               keys.max_keys = UINT32_MAX;
                keys.available_enctypes = &available_enctypes;
                keys.returned_kvno = &returned_kvno;
 
                if (include_history && old_keys.kvno != 0) {
                        old_keys.skeys = &entry->old_keys;
+                       old_keys.max_keys = UINT32_MAX;
                }
                if (include_history && older_keys.kvno != 0) {
                        older_keys.skeys = &entry->older_keys;
+                       older_keys.max_keys = UINT32_MAX;
                }
        }
 
@@ -2235,7 +2252,7 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
        /* Match Windows behavior and allow forwardable flag in cross-realm. */
        entry->flags.forwardable = 1;
 
-       samba_kdc_sort_keys(&entry->keys);
+       samba_kdc_sort_keys(&entry->keys, UINT32_MAX);
 
        ret = sdb_entry_set_etypes(entry);
        if (ret) {