diff options
author | Nicolas Williams <nico@cryptonector.com> | 2011-11-08 19:54:45 -0600 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2022-12-14 00:48:48 +0100 |
commit | 33e5f0b4a44c0d8231b4176a881cd7279dbe9292 (patch) | |
tree | 137adc78c1679ae39e5abe42b8ef4186b8017e74 | |
parent | cc6196fa005187c93486a83348b1d69a94219b1e (diff) | |
download | samba-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.c | 57 |
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); |