summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Sutton <josephsutton@catalyst.net.nz>2022-05-30 19:16:02 +1200
committerJule Anger <janger@samba.org>2022-07-24 11:42:02 +0200
commit340181bc1100fa31c63af88214a3d8328b944fe9 (patch)
treec5d4f4d55ad4b891c9c6bbdfbbcd7f4e6cd8bab4
parentc0c4b7a4bd229bd36d586faec6249baaba8e7adc (diff)
downloadsamba-340181bc1100fa31c63af88214a3d8328b944fe9.tar.gz
CVE-2022-32744 s4:kpasswd: Ensure we pass the kpasswd server principal into krb5_rd_req_ctx()
To ensure that, when decrypting the kpasswd ticket, we look up the correct principal and don't trust the sname from the ticket, we should pass the principal name of the kpasswd service into krb5_rd_req_ctx(). However, gensec_krb5_update_internal() will pass in NULL unless the principal in our credentials is CRED_SPECIFIED. At present, our principal will be considered obtained as CRED_SMB_CONF (from the cli_credentials_set_conf() a few lines up), so we explicitly set the realm again, but this time as CRED_SPECIFIED. Now the value of server_in_keytab that we provide to smb_krb5_rd_req_decoded() will not be NULL. 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 Removed knownfail as KDC no longer panics]
-rw-r--r--selftest/knownfail_heimdal_kdc4
-rw-r--r--selftest/knownfail_mit_kdc2
-rw-r--r--source4/kdc/kpasswd-service.c30
3 files changed, 30 insertions, 6 deletions
diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc
index 0d93253f999..424a8b81c38 100644
--- a/selftest/knownfail_heimdal_kdc
+++ b/selftest/knownfail_heimdal_kdc
@@ -271,7 +271,3 @@
^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket
^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing
^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting
-#
-# Kpasswd tests
-#
-^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc
diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc
index c2a31b4a140..0d2f5bab6d2 100644
--- a/selftest/knownfail_mit_kdc
+++ b/selftest/knownfail_mit_kdc
@@ -581,5 +581,3 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_
^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc
^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize_realm_case.ad_dc
^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.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/kpasswd-service.c b/source4/kdc/kpasswd-service.c
index 0d2acd8d9e8..b6400be0c49 100644
--- a/source4/kdc/kpasswd-service.c
+++ b/source4/kdc/kpasswd-service.c
@@ -29,6 +29,7 @@
#include "kdc/kdc-server.h"
#include "kdc/kpasswd-service.h"
#include "kdc/kpasswd-helper.h"
+#include "param/param.h"
#define HEADER_LEN 6
#ifndef RFC3244_VERSION
@@ -158,6 +159,20 @@ kdc_code kpasswd_process(struct kdc_server *kdc,
cli_credentials_set_conf(server_credentials, kdc->task->lp_ctx);
+ /*
+ * After calling cli_credentials_set_conf(), explicitly set the realm
+ * with CRED_SPECIFIED. We need to do this so the result of
+ * principal_from_credentials() called from the gensec layer is
+ * CRED_SPECIFIED rather than CRED_SMB_CONF, avoiding a fallback to
+ * match-by-key (very undesirable in this case).
+ */
+ ok = cli_credentials_set_realm(server_credentials,
+ lpcfg_realm(kdc->task->lp_ctx),
+ CRED_SPECIFIED);
+ if (!ok) {
+ goto done;
+ }
+
ok = cli_credentials_set_username(server_credentials,
"kadmin/changepw",
CRED_SPECIFIED);
@@ -165,6 +180,21 @@ kdc_code kpasswd_process(struct kdc_server *kdc,
goto done;
}
+ /* Check that the server principal is indeed CRED_SPECIFIED. */
+ {
+ char *principal = NULL;
+ enum credentials_obtained obtained;
+
+ principal = cli_credentials_get_principal_and_obtained(server_credentials,
+ tmp_ctx,
+ &obtained);
+ if (obtained < CRED_SPECIFIED) {
+ goto done;
+ }
+
+ TALLOC_FREE(principal);
+ }
+
rv = cli_credentials_set_keytab_name(server_credentials,
kdc->task->lp_ctx,
kdc->kpasswd_keytab_name,