get_cred starting realm

Nico Williams nico at
Thu Apr 30 16:23:03 EDT 2015

On Thu, Apr 30, 2015 at 03:40:40PM -0400, Greg Hudson wrote:
> I was wrong about this; there actually is logic in the generic ccache
> store_cred() and retrieve_cred functions for the referral realm.
> Apologies for incorrectly contradicting Nico on this point.

Well, I should have noticed earlier.  No need to apologize.

> I will revise my opinion to: I'm not really happy with solving these
> problems inside a layer which was originally designed just to be a
> container for credentials and a default client principal.  I think we
> have an unfortunate history in MIT krb5 of adding complexity to our
> lower-layer contracts in order to solve higher-layer problems.  We
> definitely have a history of this in the ccache layer (referrals, config
> entries encoded as creds, timestamps), and we have paid costs for that
> history.  It may not hurt much to add one more bit of complexity to an
> already complex lower layer, but I would like to at least explore other
> options.

I'd be happy to have a brand new credentials cache API (and SPI) and
file formats that rock.  However, backwards-compatibility is still an
imperative (ABI, source, and file format backwards compatibility, with
file format interoperability added in as a requirement), so... we can't
have that.

Even if we could, we'd still want to put "magic" at the new ccache layer
just because of the DRY principle and to simplify the API for third
parties.  (I expand on this line of argument below.)

The start-realm ccconfig proposal... does just that: simplifies the API
for third parties (e.g., no need to modify pam_krb5) because it reduces
the need to repeat oneself.

> I think the two other viable options are:
> 1. Make kinit -n and krb5_gss_accept_sec_context() responsible for
> setting a start-realm config entry when the local TGT realm differs from
> the client principal realm.  Basically, treat the edge cases as
> exceptional and force them to be addressed at the highest possible layers.

I'd live with this because it'd at least interop with Heimdal and could
be implemented by other stacks that implement the FILE ccache format.

But I won't contribute patches to implement (1) because I'd have to also
submit patches for third-party applications like pam_krb5, and I'm not
interested in boiling oceans in general.  See more below.

> 2. Ditch the cache config entry, and instead add a new ccache function
> to retrieve the main local TGT (which is defined to be the first local
> TGT stored in the cache).  Each type would be responsible for
> implementing this, either by being order-preserving and just iterating
> over the creds until it finds a local TGT, or by remembering which local
> TGT was first.

I strongly object to (2) on these grounds:

 - It depends on ccaches having an iteration order that reflects
   insertion order;

 - it does not allow one to change the starting realm except by
   initializing the/a new ccache and then inserting local TGTs in the
   desired order.

   This is a disgusting API complification[*], and an example of why
   pushing some things to lower layers is exactly the right thing to do.

(1) also is a complification: because it requires upper layers / apps to
do more work.

> The second option has a pitfall: if a ccache contains multiple local
> TGTs (unusual) and is copied using iterate-and-store, and the source

It's not unusual if one has implemented destination-only credential
delegation (a step along the way to doing that is fetching a local TGT
for the destination realm and storing it in the ccache, then asking for
a forwarded destination TGT).

One might want a configuration where the start-realm is not the same as
the client principal's realm even when a local TGT for it is available
or can be had.  Having to implement such a configuration/policy by
pushing and repeating the implementation in every possible kinit-alike
is an obnoxious complification too.  At that rate one might think that
one might as well open-code everything everywhere...

Libraries exist precisely to reduce the amount repetition.  In this case
that means that the default start-realm behavior should indeed be
implemented by "magic" in krb5_cc_store_cred().  Except it's not magic.
It's exactly the right thing to do, and it's hard to call that magic.

> ccache type isn't order-preserving, then the local TGTs might not be
> stored in the same order and the wrong one might be treated as the main
> TGT.  I don't expect that this problem would occur in practice, but we
> might look for a way to solve it at least in krb5_cc_copy_creds() and
> krb5_cc_move().

[*] I'm not even the first to coin that neologism.  But there's a reason
    that 'complification' is not in the dictionary: we generally don't
    like to deliberately complicate things.  No, 'complication' is not a
    synonym of 'complification', not to me.

More information about the krbdev mailing list