For a normal TGS request, the get_credentials state machine begins with a
referrals request (KDC_OPT_CANONICALIZE added to KDC options), and follows any
referrals issued from the KDC. In several circumstances the state machine can
fall back to a query without adding KDC_OPT_CANONICALIZE:
* If the KDC reply to the first request is an error
* If the KDC reply to the first request yields a decoding or verification error
* If the KDC reply server name is not a TGS name and not the requested name.
(The comparison includes the realm, so srealm differing from the request realm
will trigger this.)
* If the KDC reply server name is a TGS name to the same realm as the TGT used
in the request. (See tickets 4955 and 7016.)
In the first two cases, the fallback realm is used, possibly leading to a TGT
If the caller specifies the KRB5_GC_CANONICALIZE flag, KDC_OPT_CANONICALIZE is
already in the base options. If the fallback realm isn't used or is the same as
the local realm, the non-referrals fallback just retransmits the same request
as the previous query. However, the reply processing is different--there is no
check on the reply server name. krb5int_process_tgs_reply() skips it because
the canonicalize flag is set in kdcoptions, and step_non_referral() does no
checking because it is not expecting a referral.
Isaac has identified two potentially helpful use cases for the relaxed reply
server processing, involving realm aliases:
* For a request to server@REALMALIAS, an Active Directory KDC canonicalizes the
reply realm whether or not the canonicalize flag was set. Our code only sees
that the reply server differs from the request server (i.e. it doesn't notice
that only srealm is different), retries without adding the canonicalize option,
and errors out in krb5int_process_tgs_reply() on the fallback attempt. With
KRB5_GC_CANONICALIZE, the reply to the fallback query is accepted because of
the relaxed processing.
* For a request to krbtgt/REALMALIAS@REALM, the server name is canonicalized to
krbtgt/REALM@REALM in the reply if the canonicalize flag is step.
step_referrals() sees this as a referral back to the same realm and tries again
without canonicalization, succeeding with a ticket for krbtgt/REALMALIAS. With
KRB5_GC_CANONICALIZE, the fallback reply is for krbtgt/REALM@REALM and is
These cases could be handled without a fallback query. It is not clear whether
KRB5_GC_CANONICALIZE should affect their behavior or whether the
KRB5_GC_CANONICALIZE behavior should be always-on for both cases.