I want these to be easier to find than a deleted development branch.
notes on krb5_get_cred_from_kdc_opt:
- start with known target realm
- check if we have TGT for that realm
- if not, traverse world to find TGTs
- if that worked, request ticket from ultimate target realm
problems with this:
- linear processing doesn't work, since ultimate target realm can change at any time
- can't really check if we already have the remote TGT since required TGT can change
- is checking for a cached TGT useful at all, or should we go
straight to asking the KDC about it?
answer: yes, if there's a proposed realm attached to the
principal, search for a matching TGT and use that for the
request, but this request should still be made with referrals
new answer: no, absent an actual service ticket for what you're
after, start with the local KDC and see what it gives you. you
may get a TGT you already have (which is pointless), but you may
also get a referral you need to make sense of it. EXCEPT that if
you start with a non-local realm it came from a domain_realm
mapping (which we always trust), so start with that instead.
problem: how do you tell if it's from a domain_realm mapping or
something user-constructed? the answer seems to be that if
there's a non-local service realm name given for the initial
credential that it should always be used no matter what.
this might be broken behaviour, though.
- if referred, it comes with a cross-realm TGT for the new realm,
so we will always already have a TGT for the new realm, and
checking isn't necessary. we can also be assumed to already have a
TGT for the start realm.
- BUT, we may not have a TGT initially if we're subject to a
1) the referrals case:
- check for TGT for initial realm
- if a remote realm was specified (which must have happened via a
domain_realm mapping), obtain a TGT for it the standard way and
start with that.
- use client realm for server if not specified
- iterate through this loop:
- request ticket with referrals turned on
- if that fails:
- if this was the first request, punt to non-referrals case
- otherwise, retry once without referrals turned on then terminate
- if it works, either use the service ticket or follow the referral path
- if loop count exceeded, hardfail
2) the nonreferrals case
- this is mostly the old walk_realm_tree TGT-finding (which allows
limited shortcut referrals per 4120) followed by a standard tgs-req.
- originally requested principal is used for this, although if we were
handed something without a realm, determine a fallback realm based on
DNS TXT records or a truncation of the domain name.
notes on resolving hostnames
krb5_get_host_realm does various sanity-checking on supplied hostnames
including folding them to lowercase and using the local hostname if
blank. Currently krb5_get_fallback_host realm is set up to do the same
thing, with the common code moved to krb5_clean_hostname. (Stupid
name...) Should it really do that, or should it be much more limited?
- draft and actual microsoft implementation are divergent enough that MS
machines not usable for full testing
realm referrals, client side implementation:
- new realm selection priority is:
1) client-side locally configured domain_realm mapping
2) referral request to kdc (always!)
3) DNS TXT record lookup (if configured)
4) default realm assumption (realm=DNS domain of server)
(this is the same as exists now but with referrals added,
though 3 and 4 are deferred to get_cred_from_kdc)
- whether to do referral or not is *not* configurable
- client-side realm of "" (empty but *not* null string) used in client
libraries to indicate domain_realm mapping failure and fallback to
referral. not subject to configuration.
- krb5_sname_to_principal makes existing call to krb5_get_host_realm
- krb5_get_host_realm returns domain_realm mapping if found, otherwise
[this could fall back to TXT or default realm assumption instead]
[but it isn't; this happens later if at all; the relevant fallbacks
will happen as part of credential-obtaining process]
- code using alternatives to krb5_sname_to_principal (krb5_parse_name,
krb5_build_principal) is on its own.
- actual referral request handled in krb5_get_cred_from_kdc
- client will always request referrals from kdc
- realm choice:
- if realm supplied, start with that.
- if no realm specified, request server referral; if that fails,
fall back to TXT request/default realm assumption and try that instead
(copy code from krb5_get_host_realm; make fallback a separate function
if referrals are runtime-configurable and the same code will be
needed in krb5_get_host_realm
- ccache considerations:
- referrals may also have had name canonicalization done. store the
ultimate ticket under the requested service name under the
assumption that it will continue to be requested the same way.
service names for non-referral requests will never be
canonicalized but we should handle that case anyway.
- canonical service name still available within the ticket
- will/should the library use or search on the canonical principal
name as well?
- cross realm routing
- if capath present *and* realm is known, attempt to follow to end,
- recheck for capath entry if realm is rewritten on referral
- requests still made with referrals turned on, so referrals along
the path, and especially at the end of the path, still work
- still need to understand full capth functionality here.
- client currently tries to construct a trust path following the DNS
hierarchy until it finds a server to ask; this is still useful
(maybe?) as a fallback but should only be tried after server
referrals have failed.
- if referrals provide an initial referral TGT or two, but this path
terminates at a server that provides neither a service ticket or a
referral, what happens?
- establish maximum referral traverse; more than microsoft's 5, but
realm referrals, server side implementation:
- kdc should accept any sort of name, short or long
(see below for detailed canonicalization notes)
- add code to process_tgs_req to handle tgs_req canonicalize flag
- add second case for firstpass=1 within the "if (nprincs != 1)" block
- add new library function to fetch referral realm
- Microsoft/umich patch uses static kdc.conf configuration along the
same general lines as the domain_realm mapping; compatability with
that (logically and probably syntactically) seems desirable and
- raeburn thinks it might be interesting to make this overridable
with a kdc plugin.
hostname canonicalization, server side
- do not rewrite service names when not also returning a referral; this
is a nonstated design requirement for clients that appears to violate
the client requirements in the -06 draft, but currently deployed
implementations apparently rely upon this not happening. unclear now
if it's the right thing, but we're stuck with it.
- canonicalization only done:
1) if local db lookup of principal as presented fails
2) only if uncanonicalized referral has already failed
3) only for principals with exactly two parts
(this will break NT-SRV-XHST; does anyone care?)
4) only for principals with a specified name type,
by default NT-SRV-HST and maybe NT-UNKNOWN
5) only for principals with specified service names
- any rewriting action taken on presumed hostnames will end with case
folding to lowercase. there's some conflict on whether this is a
"MUST" or "SHOULD" in 4120, but it's clearly appropriate once we're
- strategy for service name canonicalization
- if short name, try resolving it serially with a kdc-configured domain list
- thus the client can send an unqualified name, but loses security
- follow cnames, but don't do rdns lookup
- can this break backward compatability?
- is blocking on DNS here OK?
- utilize a mapping, possibly something automatically generated from
local DNS zone(s), to rewrite hostnames for referral.
- unanswered question: how do we handle servers known by multiple names?
provide multiple db entries? add these to keytab as well?
hostname canonicalization, client side
- our client will always send a fully-qualified name to the server
for something that appears to be a hostname
(basically the same cases where we do rdns now)
- idea: client code will not do rdns by default, but instead will resolve
hostnames as far as fully qualifying them in the client name resolution
environment and following CNAME records
[this seems desirable but could be technically problematic]
- defined separate KDC option bit for RFC-style canonicalization since
the microsoft implementation is so different
- should key usage and padata types be different as well?
- keyusage defined in draft (26) collides with KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID
from 21 aug 2006 meeting, notable screw cases and notes on same:
- referrals which terminate at a non-referral-capable realm should retry
the final request without referrals turned on (the "referrals to MIT" case)
- intermediate cross-realm TGTs should not be cached, only the final
service ticket, anything from the local KDC, and anything that came up
during the degenerate (walk_realm_tree) unreferred traversal case
- "too many hops" failure can be a hard failure
- TGT referrals per original 4120 spec should continue to Just Work
- the code path for this is different and doesn't check much.
is this a gaping hole waiting to be filled maliciously?
- bug: principal parsing fails with zero-length realm
- maybe bug: win->athena referrals don't work
- hey, wait, there's no cross-realm TGT there. wacky.
- the case where we make a default realm assumption is very important to
maintain the current functionality with
- it's more important to minimize KDC round-trips and perform to
minimally functional spec than to make all possible (and probably
from 25 august 2006 meeting, thoughts on fallbacks:
Part of the current plan is to move configuration information from the
client to the server. This, however, leaves us vulnerable in cases where
the home KDC ("A") knows that the service principal exists in C but that
the trust path traverses B, which is not referral capable. Our
conclusion is that the server should not be configured to offer referrals
to C at all, but should of course continue to return a cross-realm TGT to
B if asked, and that the client fallback to the standard
non-referral-based traversal is the only functional path here.
But is that really the right thing?
misc questions answered:
- should do_traversal code for old-style lookups still be requesting referrals?
If so, within what scope should they actually be used?
- probably not. the old traversal code is network-intensive and resilient enough as is.