When using referrals, the TGS client starts the referrals chasing process at the client principal's realm. That is, the desired service principal's realm is replaced with the client principal's and a TGS-REQ is sent to that realm's TGS.
There are two cases where this choice of "start" realm are inappropriate:
- when the client principal's realm is a WELLKNOWN realm (e.g., the anonymous realm) - when the client has a "root TGT" (krbtgt/REALM@REALM) but not for its own realm
The latter is used at some sites as a form of constrained credential delegation: a client at realm A forwards a ticket for krbtgt/B@B to a service in realm B, thus that service cannot reach realm A services (because of loop detection at A's TGSes), but it can still authenticate as the client @A. (The services in realm B can probably also not reach other realms that are reachable from A.)
The TGS client really needs a way to record the "start" realm where the TGT for that realm is stored: in the ccache.
Recording the start realm in the ccache
Searching for a root TGT in the ccache is not a good way to find a start realm: there is no guarantee that there will be only one such TGT, and there is no guarantee that the ccache preserves insertion order, therefore such a search could yield non-deterministic results.
The proposed solution is: record the start realm in a "cc config" ccache entry. Any process that initializes a ccache should add this cc config entry along with the TGT that it stores in the ccache. This should be done automatically by the krb5 library. When trying referrals, the client should search for this cc config entry, and if it finds it, it should use the realm recorded in it as the "start realm".
The new cc config name should be "start_realm", and the value stored there should be the start realm's name. (XXX NUL-terminated or not?)