summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Sutton <josephsutton@catalyst.net.nz>2022-05-26 16:39:20 +1200
committerJule Anger <janger@samba.org>2022-07-24 11:42:02 +0200
commitc0c4b7a4bd229bd36d586faec6249baaba8e7adc (patch)
tree207292f15da485e7b13c7ce0cb0f4f0df0228bc9
parent997f50c66471071efb8e02d8efbe4bf5d932e7ee (diff)
downloadsamba-c0c4b7a4bd229bd36d586faec6249baaba8e7adc.tar.gz
CVE-2022-32744 s4:kdc: Modify HDB plugin to only look up kpasswd principal
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> [jsutton@samba.org Fixed knownfail conflicts] [jsutton@samba.org Renamed entry to entry_ex; fixed knownfail conflicts; retained knownfail for test_kpasswd_from_rodc which now causes the KDC to panic]
-rw-r--r--selftest/knownfail_heimdal_kdc3
-rw-r--r--source4/kdc/hdb-samba4-plugin.c2
-rw-r--r--source4/kdc/hdb-samba4.c66
-rw-r--r--source4/kdc/kdc-glue.h3
4 files changed, 70 insertions, 4 deletions
diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc
index afb9bcf1209..0d93253f999 100644
--- a/selftest/knownfail_heimdal_kdc
+++ b/selftest/knownfail_heimdal_kdc
@@ -275,6 +275,3 @@
# Kpasswd tests
#
^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc
-^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
diff --git a/source4/kdc/hdb-samba4-plugin.c b/source4/kdc/hdb-samba4-plugin.c
index 4b90a766f76..dba25e825de 100644
--- a/source4/kdc/hdb-samba4-plugin.c
+++ b/source4/kdc/hdb-samba4-plugin.c
@@ -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;
diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c
index 43e836f8360..a8aae50b5b0 100644
--- a/source4/kdc/hdb-samba4.c
+++ b/source4/kdc/hdb-samba4.c
@@ -136,6 +136,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_ex *entry_ex)
+{
+ 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_ex);
+
+ krb5_free_principal(context, kpasswd_principal);
+ return ret;
+}
+
static krb5_error_code hdb_samba4_firstkey(krb5_context context, HDB *db, unsigned flags,
hdb_entry_ex *entry)
{
@@ -194,6 +235,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_ex *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);
@@ -522,3 +571,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;
+}
diff --git a/source4/kdc/kdc-glue.h b/source4/kdc/kdc-glue.h
index c083b8c6429..ff8684e1666 100644
--- a/source4/kdc/kdc-glue.h
+++ b/source4/kdc/kdc-glue.h
@@ -45,6 +45,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,