krb5: Fix dst TGT deleg w/o dns_lookup_realm

Setting `dns_lookup_realm = false` in `[libdefaults]` and setting name
canon rules that force the empty realm causes destination-TGT delegation
to break because the client doesn't know the service's realm.

Because MIT and Heimdal check that the (unauthenticated plaintext)
sname/realm of the Ticket in the KDC reply matches the sname/srealm in
the enc-part of the KDC reply, we know we can trust the realm of the
ticket found in the ccache.  So use that.
This commit is contained in:
Nicolas Williams
2021-12-06 15:02:32 -06:00
parent eb293680a8
commit bba573f286

View File

@@ -1283,6 +1283,33 @@ check_cc(krb5_context context, krb5_flags options, krb5_ccache ccache,
if (options & KRB5_GC_ANONYMOUS)
krb5_free_principal(context, mcreds.client);
if (ret == 0 && out_creds->server->realm &&
out_creds->server->realm[0] == '\0') {
Ticket ticket;
/*
* We only write tickets to the ccache that have been validated, as in,
* the sname/srealm from the KDC-REP enc-part have been checked to
* match the sname/realm from the Ticket from the KDC-REP.
*
* Our caller needs the canonical realm of the service in order to be
* able to get forwarded credentials for it when destination-TGT
* forwarding is enabled.
*
* As well, gss_init_sec_context() ought to arrange for
* gss_inquire_context() to output the canonical acceptor name on the
* initiator side.
*/
ret = decode_Ticket(out_creds->ticket.data, out_creds->ticket.length,
&ticket, NULL);
if (ret == 0) {
ret = krb5_principal_set_realm(context, out_creds->server,
ticket.realm);
free_Ticket(&ticket);
} else {
krb5_free_cred_contents(context, out_creds);
}
}
return ret;
}