add KDC default referral feature

FEATURE

Two new realm configuration parameters:

* default_referral_realm (string, default none)
* cross_realm_default_referral (boolean, default false)

If default_referral_realm is set, then the KDC will issue referrals to the
specified realm for TGS requests otherwise qualifying for a referral but
lacking a static realm mapping, as long as the presented TGT is not
cross-realm (setting cross_realm_default_referral omits that check).

RATIONALE

I’ll explain by way of the real motivating situation for us. We have two realms:

  AD: Windows AD
UNIX: MIT Kerberos on Unix

We have two-way trust between these realms, and AD provides referrals to Unix via top-level name translation rules. Our hosts have a mix of realms in the same DNS domains, so static realm-mapping rules don’t work for us; we use _kerberos DNS TXT records for Unix clients to get host realm memberships. Consider the scenario of a client with Unix TGT accessing a Windows-realm service, say an OpenSSH client logging into the Bitvise WinSSHD server.

1. client acquires TGT for user@UNIX -> krbtgt/UNIX@UNIX
1. client correctly identifies the server in the AD realm
1. client obtains a cross-realm ticket krbtgt/AD@UNIX from Unix
1. client uses that to obtain an SSH service ticket host/foo@AD
1. client successfully logs into the SSH server (we use AD altSecurityIdentity attributes to authorize Unix principals to their corresponding AD accounts)

So far, so good. However, the client also requests GSSAPI delegation via SSH. This succeeds, and klist on the Windows side shows a forwarded TGT for krbtgt/AD@UNIX. This TGT works for accessing further Unix-realm services -- but access to AD services fails, even though the analogous situation with a Unix client would succeed.

The reason this fails is that Windows always assumes the realm of the TGT issuer for all requests, and relies on referrals to locate the correct realm if necessary. Say the remote Windows session now wants to access LDAP on a domain controller dc; Windows then queries a Unix KDC for ldap/dc@UNIX (because the TGT was issued by the Unix realm). This fails, because our Unix KDCs do not issue referrals.

The MIT KDC can do referrals, but only for hosts with static realm mappings in krb5.conf. Since in our case the realm mappings are in the DNS, this doesn’t work for us.

My patch allows the KDC to issue referrals to a designated default realm, in our case the AD realm. The trick is to avoid referral loops, and I do that by refusing to issue a default referral if the presented TGT is cross-realm; this indicates that the client has already consulted the other realm, so sending them back again would be pointless.

Certainly, using this feature with more than two realms would be less straightforward, and there are various corner cases to consider. However, I imagine our case may be quite common, and it has proved to solve the problem perfectly for us, so I thought I’d send it along for consideration. Other use cases include Unix clients using delegation to Microsoft SQL Server for “bulk insert” (in which the dataserver accesses a CIFS filesystem using the client’s credentials), and “chained queries” (in which the dataserver issues further queries to other dataservers using the client’s credentials).

Thanks,

Richard E. Silverman