ghudson at MIT.EDU
Tue Mar 30 21:00:22 EDT 2010
I'm working on extending Luke's IAKERB work to handle the full logic
of krb5_get_cred_from_kdc_opt(), and I want to ensure that I preserve
the intended behaviors of the current code, without necessarily
preserving unintended behaviors or bugs. A rough outline of the
current logic is:
1. Retrieve a TGT for the service realm (or local realm if no
service realm given).
2. Ask the service realm's KDC for the ticket, with canonicalize on.
3. If we get a TGT back, rewrite the service realm to match the
TGT's remote realm and repeat step 2 (up to ten requests total).
4. If we receive an error on the second or later iteration, retry
with canonicalize off.
5. If we get the actual ticket back, possibly repeat the final query
using the app-provided enctypes (and canonicalize on).
6. If we receive an error in the first iteration, or were referred
back to the immediately preceding realm in any iteration, or receive
a non-TGT in any iteration:
6a. Retrieve a TGT for the fallback realm. This is determined by
krb5_get_fallback_host_realm() if no service realm was
originally specified for the service principal. Otherwise it
is whatever realm we last saw a referral for, although that
doesn't seem to be the code's intent. More on that later.
6b. Ask the fallback realm's KDC for the ticket, with
To retrieve a TGT for a realm (if not already cached):
1. Construct a list of realms between the local realm and target
realm, using a complicated algorithm which isn't important right
2. Retrieve the TGT for the local realm from the cache.
3. Using the TGT we have, walk backwards from the target realm,
querying (if not already cached) for a TGT of that realm.
4. If we get back a TGT for the target realm, we're done.
5. If we get back a TGT for some realm on the path we expected,
substitute it for the one we had, and return to step 3.
6. If we get back a TGT for a realm not on the path we expected,
repeatedly query for the target realm TGT from the KDC of the TGT
we have in hand, up to 10 times, until we get a target realm TGT
I have some questions about the subtleties:
1. How important is it to retry with the canonicalize bit turned off,
if we get a failure with it turned on? RFC 4120 requires KDCs to
ignore unrecognized KDC options. Are we aware of KDCs which do not do
so, and fail instead?
(Note that the existing code does not *always* retry with the
canonicalize bit turned off. If we get an error in the first
iteration, then we go to the fallback code path, which may perform its
final query in a different realm than the one which gave us an error.)
2. The comments for the fallback path, as well as ticket #2652, imply
that the fallback path is supposed to use the originally requested
service principal it had no realm. But there's no code to actually
reset server->realm to the originally requested realm, so if the realm
had been rewritten in the referrals loop, it will remain rewritten.
Is this a straightforward bug or am I missing something?
3. Assuming #2 is fixed, is there any reason to repeat the process of
obtaining a TGT for the service realm, in the case where one was
explicitly specified? (I get that we need to obtain a TGT for the
fallback realm in the case where no realm was specified.)
More information about the krbdev