]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2022-32744 s4:kdc: Modify HDB plugin to only look up kpasswd principal
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Thu, 26 May 2022 04:39:20 +0000 (16:39 +1200)
committerJule Anger <janger@samba.org>
Wed, 27 Jul 2022 10:52:36 +0000 (10:52 +0000)
This plugin is now only used by the kpasswd service. Thus, ensuring we
only look up the kadmin/changepw principal means we can't be fooled into
accepting tickets for other service principals. We make sure not to
specify a specific kvno, to ensure that we do not accept RODC-issued
tickets.

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

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andreas Schneider <asn@samba.org>
selftest/knownfail_heimdal_kdc
source4/kdc/hdb-samba4-plugin.c
source4/kdc/hdb-samba4.c
source4/kdc/kdc-glue.h

index 341cdfb21c11a6e94bf9891833e3798fa8907ef3..4ae27eacb0919b6ffcc402ed199fc622b40e559c 100644 (file)
@@ -54,9 +54,3 @@
 ^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_samr_change_password_protected.ad_dc
-#
-# Kpasswd tests
-#
-^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc
-^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc
-^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc
index 7a5a9485e05cf73b2def14c6a34ee527922b2a29..be6d2437d0ef913207823423b53336c101dd3e4b 100644 (file)
@@ -36,7 +36,7 @@ static krb5_error_code hdb_samba4_create(krb5_context context, struct HDB **db,
        base_ctx = talloc_get_type_abort(ptr, struct samba_kdc_base_context);
 
        /* The global kdc_mem_ctx and kdc_lp_ctx, Disgusting, ugly hack, but it means one less private hook */
-       nt_status = hdb_samba4_create_kdc(base_ctx, context, db);
+       nt_status = hdb_samba4_kpasswd_create_kdc(base_ctx, context, db);
 
        if (NT_STATUS_IS_OK(nt_status)) {
                return 0;
index 480d2c06e5eb0617cad12f208849dbf89c1d75b9..13c3a8bd2659ca08c237146e8817d56ee10d60ef 100644 (file)
@@ -293,6 +293,47 @@ static krb5_error_code hdb_samba4_fetch_kvno(krb5_context context, HDB *db,
        return code;
 }
 
+static krb5_error_code hdb_samba4_kpasswd_fetch_kvno(krb5_context context, HDB *db,
+                                                    krb5_const_principal _principal,
+                                                    unsigned flags,
+                                                    krb5_kvno _kvno,
+                                                    hdb_entry *entry)
+{
+       struct samba_kdc_db_context *kdc_db_ctx = NULL;
+       krb5_error_code ret;
+       krb5_principal kpasswd_principal = NULL;
+
+       kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
+                                          struct samba_kdc_db_context);
+
+       ret = smb_krb5_make_principal(context, &kpasswd_principal,
+                                     lpcfg_realm(kdc_db_ctx->lp_ctx),
+                                     "kadmin", "changepw",
+                                     NULL);
+       if (ret) {
+               return ret;
+       }
+       smb_krb5_principal_set_type(context, kpasswd_principal, KRB5_NT_SRV_INST);
+
+       /*
+        * For the kpasswd service, always ensure we get the latest kvno. This
+        * also means we (correctly) refuse RODC-issued tickets.
+        */
+       flags &= ~HDB_F_KVNO_SPECIFIED;
+
+       /* Don't bother looking up a client or krbtgt. */
+       flags &= ~(SDB_F_GET_CLIENT|SDB_F_GET_KRBTGT);
+
+       ret = hdb_samba4_fetch_kvno(context, db,
+                                   kpasswd_principal,
+                                   flags,
+                                   0,
+                                   entry);
+
+       krb5_free_principal(context, kpasswd_principal);
+       return ret;
+}
+
 static krb5_error_code hdb_samba4_firstkey(krb5_context context, HDB *db, unsigned flags,
                                        hdb_entry *entry)
 {
@@ -351,6 +392,14 @@ static krb5_error_code hdb_samba4_nextkey(krb5_context context, HDB *db, unsigne
        return ret;
 }
 
+static krb5_error_code hdb_samba4_nextkey_panic(krb5_context context, HDB *db,
+                                               unsigned flags,
+                                               hdb_entry *entry)
+{
+       DBG_ERR("Attempt to iterate kpasswd keytab => PANIC\n");
+       smb_panic("hdb_samba4_nextkey_panic: Attempt to iterate kpasswd keytab");
+}
+
 static krb5_error_code hdb_samba4_destroy(krb5_context context, HDB *db)
 {
        talloc_free(db);
@@ -813,3 +862,20 @@ NTSTATUS hdb_samba4_create_kdc(struct samba_kdc_base_context *base_ctx,
 
        return NT_STATUS_OK;
 }
+
+NTSTATUS hdb_samba4_kpasswd_create_kdc(struct samba_kdc_base_context *base_ctx,
+                                      krb5_context context, struct HDB **db)
+{
+       NTSTATUS nt_status;
+
+       nt_status = hdb_samba4_create_kdc(base_ctx, context, db);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               return nt_status;
+       }
+
+       (*db)->hdb_fetch_kvno = hdb_samba4_kpasswd_fetch_kvno;
+       (*db)->hdb_firstkey = hdb_samba4_nextkey_panic;
+       (*db)->hdb_nextkey = hdb_samba4_nextkey_panic;
+
+       return NT_STATUS_OK;
+}
index 47642e124320a3c9342ccde29a97c137a2c9ee24..7a0184c40217f23735ed91de531d046032294609 100644 (file)
@@ -46,6 +46,9 @@ kdc_code kpasswdd_process(struct kdc_server *kdc,
 NTSTATUS hdb_samba4_create_kdc(struct samba_kdc_base_context *base_ctx,
                               krb5_context context, struct HDB **db);
 
+NTSTATUS hdb_samba4_kpasswd_create_kdc(struct samba_kdc_base_context *base_ctx,
+                                      krb5_context context, struct HDB **db);
+
 /* from kdc-glue.c */
 int kdc_check_pac(krb5_context krb5_context,
                  DATA_BLOB server_sig,