summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Williams <nico@cryptonector.com>2011-11-08 19:54:45 -0600
committerStefan Metzmacher <metze@samba.org>2022-12-14 00:48:48 +0100
commit33e5f0b4a44c0d8231b4176a881cd7279dbe9292 (patch)
tree137adc78c1679ae39e5abe42b8ef4186b8017e74
parentcc6196fa005187c93486a83348b1d69a94219b1e (diff)
downloadsamba-33e5f0b4a44c0d8231b4176a881cd7279dbe9292.tar.gz
CVE-2022-37966 Fix enctype selection issues for PAC and other authz-data signatures
We were using the enctype from the PA-TGS-REQ's AP-REQ's Ticket to decide what key from the service's realm's krbtgt principal to use. This breaks when: a) we're doing cross-realm, b) the service's realm's krbtgt principal doesn't have keys for the enctype used in the cross-realm TGT. The fix is to pick the correct key (strongest or first, per-config) from the service's realm's krbtgt principal. (backported from Heimdal commit 8586d9f88efcf60b971466f0d83ea0bc1962e24f) [jsutton@samba.org Fixed conflicts due to different Heimdal revision] BUG: https://bugzilla.samba.org/show_bug.cgi?id=15237 [This is 4.15 only] Reviewed-by: Stefan Metzmacher <metze@samba.org>
-rw-r--r--source4/heimdal/kdc/krb5tgs.c57
1 files changed, 33 insertions, 24 deletions
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
index 1e3405d4119..b64d2f49950 100644
--- a/source4/heimdal/kdc/krb5tgs.c
+++ b/source4/heimdal/kdc/krb5tgs.c
@@ -1320,9 +1320,9 @@ tgs_build_reply(krb5_context context,
{
krb5_error_code ret;
krb5_principal cp = NULL, sp = NULL, tp = NULL, dp = NULL;
- krb5_principal krbtgt_principal = NULL;
+ krb5_principal krbtgt_out_principal = NULL;
krb5_principal user2user_princ = NULL;
- char *spn = NULL, *cpn = NULL, *tpn = NULL, *dpn = NULL;
+ char *spn = NULL, *cpn = NULL, *tpn = NULL, *dpn = NULL, *krbtgt_out_n = NULL;
char *user2user_name = NULL;
hdb_entry_ex *server = NULL, *client = NULL, *s4u2self_impersonated_client = NULL;
hdb_entry_ex *user2user_krbtgt = NULL;
@@ -1488,7 +1488,7 @@ server_lookup:
/* Now refetch the primary krbtgt, and get the current kvno (the
* sign check may have been on an old kvno, and the server may
* have been an incoming trust) */
- ret = krb5_make_principal(context, &krbtgt_principal,
+ ret = krb5_make_principal(context, &krbtgt_out_principal,
krb5_principal_get_comp_string(context,
krbtgt->entry.principal,
1),
@@ -1498,24 +1498,28 @@ server_lookup:
1), NULL);
if(ret) {
kdc_log(context, config, 0,
- "Failed to generate krbtgt principal");
+ "Failed to make krbtgt principal name object for "
+ "authz-data signatures");
+ goto out;
+ }
+ ret = krb5_unparse_name(context, krbtgt_out_principal, &krbtgt_out_n);
+ if (ret) {
+ kdc_log(context, config, 0,
+ "Failed to make krbtgt principal name object for "
+ "authz-data signatures");
goto out;
}
- ret = _kdc_db_fetch(context, config, krbtgt_principal, HDB_F_GET_KRBTGT, NULL, NULL, &krbtgt_out);
- krb5_free_principal(context, krbtgt_principal);
+ ret = _kdc_db_fetch(context, config, krbtgt_out_principal,
+ HDB_F_GET_KRBTGT, NULL, NULL, &krbtgt_out);
if (ret) {
- krb5_error_code ret2;
- char *ktpn, *ktpn2;
+ char *ktpn = NULL;
ret = krb5_unparse_name(context, krbtgt->entry.principal, &ktpn);
- ret2 = krb5_unparse_name(context, krbtgt_principal, &ktpn2);
kdc_log(context, config, 0,
- "Request with wrong krbtgt: %s, %s not found in our database",
- (ret == 0) ? ktpn : "<unknown>", (ret2 == 0) ? ktpn2 : "<unknown>");
- if(ret == 0)
- free(ktpn);
- if(ret2 == 0)
- free(ktpn2);
+ "No such principal %s (needed for authz-data signature keys) "
+ "while processing TGS-REQ for service %s with krbtg %s",
+ krbtgt_out_n, spn, (ret == 0) ? ktpn : "<unknown>");
+ free(ktpn);
ret = KRB5KRB_AP_ERR_NOT_US;
goto out;
}
@@ -1713,8 +1717,15 @@ server_lookup:
ret = KRB5KRB_AP_ERR_NOT_US;
}
+ ret = _kdc_get_preferred_key(context, config, krbtgt_out, krbtgt_out_n,
+ NULL, &tkey_sign);
+ if (ret) {
+ kdc_log(context, config, 0,
+ "Failed to find key for krbtgt PAC signature");
+ goto out;
+ }
ret = hdb_enctype2key(context, &krbtgt_out->entry,
- krbtgt_etype, &tkey_sign);
+ tkey_sign->key.keytype, &tkey_sign);
if(ret) {
kdc_log(context, config, 0,
"Failed to find key for krbtgt PAC signature");
@@ -2166,8 +2177,8 @@ out:
free(tpn);
free(spn);
free(cpn);
- if (dpn)
- free(dpn);
+ free(dpn);
+ free(krbtgt_out_n);
krb5_free_keyblock_contents(context, &sessionkey);
if(krbtgt_out)
@@ -2185,12 +2196,10 @@ out:
krb5_free_principal(context, user2user_princ);
if (tp && tp != cp)
krb5_free_principal(context, tp);
- if (cp)
- krb5_free_principal(context, cp);
- if (dp)
- krb5_free_principal(context, dp);
- if (sp)
- krb5_free_principal(context, sp);
+ krb5_free_principal(context, cp);
+ krb5_free_principal(context, dp);
+ krb5_free_principal(context, sp);
+ krb5_free_principal(context, krbtgt_out_principal);
if (ref_realm)
free(ref_realm);
free_METHOD_DATA(&enc_pa_data);