Credential cache searching, ccapi and file caches
Alexandra Ellwood
lxs at MIT.EDU
Tue Jul 13 18:37:56 EDT 2004
On Jul 13, 2004, at 5:16 PM, Miro Jurišić wrote:
>> I'd like to start with a brief summary of how CCAPI works now to
>> confirm my understanding and to bring people not familiar with CCAPI
>> up to speed. A CCAPI cache collection is a set of caches that live in
>> one cache server process. Caches contain a set of credentials for
>> both v4 and v5 and associated with the credentials is a principal.
>> That is, all tickets in a single ccapi cache are expected to have the
>> same client principal. For the most part there is at most one cache
>> with a particular client principal at any given time.
>
> Keeping in mind that my knowledge is out of date, this is not true.
> CCAPI does not require that there be any association between
> credentials in one cache and a particular principal. However, the way
> that CCAPI is used on Mac OS (and presumably now other platforms) is
> that the GUI tools, by means of KLL, create a new ccache when the user
> obtains a new TGT that is not a cross-realm TGT (IIRC). Because of the
> fact that we forced everyone to go through KLL, you can discover "the"
> principal of a ccache by looking for the first TGT in a ccache. I am
> sure that if you make the change in how KLL uses CCAPI to actually put
> multiple principals in a ccache you will discover some client code
> that relied on that, but I would consider such reliance a bug in the
> client code.
CCAPI has the concept of a default client principal for its ccaches
(cc_ccache_[gs]et_principal()) just like file based ccaches. On KfM,
the Kerberos Login library (KLL) creates ccaches whose default client
principal is the same as the client principal of the tickets in the
ccache.
For example, if I get tickets for the client principal
lxs at ATHENA.MIT.EDU on KfM, KLL creates a single ccache with the default
principal set to lxs at ATHENA.MIT.EDU and places the TGT and service
tickets for lxs at ATHENA.MIT.EDU in that ccache. If I subsequently get
tickets for lxs/root at ATHENA.MIT.EDU, KLL will create a second ccache
with a default client principal of lxs/root at ATHENA.MIT.EDU containing
the tickets for lxs/root at ATHENA.MIT.EDU.
As a result of the way that KLL searches for a valid TGT before it
tries to get new tickets, it also only creates one ccache per client
principal. If KLL needs to use tickets for a client principal and the
existing tickets are expired, KLL will overwrite the existing ccache
with any newly acquired tickets rather than creating a new one and
leaving the old expired tickets behind.
Currently KLL and Kerberos.app try not to assume that there is only one
ccache per client principal or that all the tickets in a given ccache
have the same client principal. This is because the krb5_cc_*()
functions allow you violate these constraints, and we wouldn't want to
crash or misbehave just because someone is using some of our exported
APIs. :-)
I believe what Sam is talking about is making the one ccache per client
principal constraint more fundamental to the CCAPI (possibly by
unifying the principal and name attributes of a ccache) and making the
krb5_ccache type equivalent to the CCAPI cache collection so that we
don't have to change any code in the krb5 library or in
KLL/Kerberos.app.
The primary problem I have with this is one of name confusion. I don't
think there should be two things named "ccache" where one is actually a
subset of the other. Our APIs are hard enough to understand already.
:-)
Another problem I have with Sam's proposal is that it seems to be
trying to make the krb5_cc_*() API fit better with the existing file
format rather than designing an API which is clean and efficient for
the caller. For instance, one of the really common operations in
Kerberos.app is to display a list of the client principals for which
the user has TGTs and the state of each TGT (lifetime, flags, etc). In
Sam's proposed design, Kerberos.app would have to iterate through all
the creds in the file-based krb5_ccache, including the service tickets.
If the user has managed to get themselves 10 TGTs and 100 service
tickets (yes, we've seen this) then this search is going to be
needlessly slow.
Sam proposes adding an iterator to loop over the client principals, but
unless it returns the TGTs, it won't help Kerberos.app get the ticket
lifetime. So Kerberos.app will still have to walk the whole list of
credentials. Obviously this can be solved with caching or other
optimizations, but I'd much prefer for the looping code that separates
the tickets for a given client principal from the rest of the tickets
to be inside the krb5_cc_*() functions so that we can make
optimizations to it in the future and make everything faster.
Also, does the krb5 library actually currently take advantage of
multiple TGTs for client principals in its ccaches? Much of the code
I've looked at calls krb5_cc_get_principal() to get the client
principal which will only return the default principal in a file based
ccache. If the support isn't there, it seems to me that the krb5
library already has to be modified all over the place to search across
multiple TGTs trying to get a service ticket.
I'd much prefer the krb5_cc_*() API to gain the concept of a cache
collection which loops over krb5_ccaches. If we added this support
then all the existing callers of the krb5_cc_*() functions would just
manipulate the krb5_ccache pointed to by the system default ccache
(KRB5CCNAME) and have no idea that there is actually a cache
collection, but modern callers could loop over all the ccaches
available to search for a TGT. If we did this then we could slowly
work over all the places in the krb5 library where we deal with ccaches
and make them smart rather than having to audit the whole thing
immediately to make sure that the new behavior of krb5_ccaches won't
break things.
Note that I am not trying to say we would need to support looping over
multiple ticket files. We could put the whole "cache collection" into
the single ticket file. What I'm not sure of is whether you could do
this without changing the ticket file format (which would suck). It's
also possible that we could create a meta-data file that points to all
the file caches so that file caches would work a lot like CCAPI caches.
This is attractive because it means that kdestroy wouldn't get more
complicated and we wouldn't need to change what KRB5CCNAME means (ie:
that the string after FILE: is still actually a ticket file containing
the system default client principal).
Now before everyone points out that all sorts of krb5 functions take
krb5_ccaches, I'd like to point out that the only sane "search for a
TGT to get a service ticket" algorithms I've seen proposed all have the
concept of a user or programmer-settable ccache that you try first. If
you don't have one, and you have two sets of tickets which give you
different privileges (say lxs at ATHENA.MIT.EDU and
lxs/root at ATHENA.MIT.EDU), then you have no way of telling the krb5
library which one you'd prefer it to use. So what I would do is in all
the places where a function takes a krb5_ccache, treat that one as the
one whose client principal it should try first. If that client
principal doesn't work, *then* search across the rest of the cache
collection.
There should, of course, also be a way (ie: a libdefault) to turn off
the searching and fall back on the old one-ccache, no searching
behavior.
> This change does have significant impact on the user experience, of
> course, but your email basically says that it's the user experience
> you are trying to change, so I assume you have thought through those
> implications.
It isn't nearly as big of a user experience change on the Mac because
KLL is already trying to maintain one ccache per client principal (and
if you only use Kerberos.app and the supplied kinit, it basically
succeeds). I believe the reason this was proposed here was so people
who are doing something funky with ccaches could pipe up and point out
how it breaks their stuff.
--lxs
-----------------------------------------------------------------------
Alexandra Ellwood lxs at mit.edu
MIT Information Services & Technology http://mit.edu/lxs/www/
-----------------------------------------------------------------------
More information about the krbdev
mailing list