Is KRB5_CONFIG info cached?

Marcus Watts mdw at umich.edu
Fri Jun 30 01:39:47 EDT 2006


Mike Friedman <mikef at ack.berkeley.edu> writes:

...
> > So, at a closer look at Jeff Horwitz's code, looks like he expects 
> > Authen::Krb5::init_context().  He's got this right before:
> > 	if (context) croak("Authen::Krb5 already initialized");
> 
> I ran into this problem a while back and contacted Jeff about it. He 
> suggested the fix you mentioned (to free_context()), which I implemented. 
> So I don't have the problem of the context hanging around, because I do a 
> free_context() at the end of my subroutine.

I see.  I'm not quite sure how I missed the part where you said
that up front, but whatever.

> 
> Ken,
> 
> You said,
> 
> > If these KDCs are for two different realms, can you list both config 
> > files in KRB5_CONFIG?
> 
> But then how do I get the *default realm* set correctly?  In my script, I 
> do a parse_name() to create a principal object corresponding to the TGS 
> service principal (e.g., krbtgt/<realm>@<realm>).  (It's this principal 
> object that I must pass to get_in_tkt_with_password()).  And, 
> unfortunately, parse_name() complains if my config file doesn't have a 
> default realm, so defining both realms in the [realms] stanza doesn't do 
> me any good.  But if I do define a default realm, then that's the KDC to 
> which I get connected, regardless of the realm name I specify when 
> constructing the TGS service principal name itself.
> 
> So, it seems I need to point to a different config file each time I want 
> to go to a different KDC.  And, I don't know any way except the 
> KRB5_CONFIG environment variable to do it from within my subroutine code.
> 
> But given that I get a new context each time, why can't I reset the value 
> of KRB5_CONFIG on each call and have it be honored?  This is the crux of 
> the matter, apparently.

I believe you're still barking up the wrong tree.  The default
realm is just that, a default.  If you really want to specify
two different realms, then that's fine -- that's why you can
specify the realm explicitly and override the default.

So here's an example:

ganesh$ /usr/local/mit-k5/bin/klist -e -k -t /tmp/combined.keytab
Keytab name: FILE:/tmp/combined.keytab
KVNO Timestamp         Principal
---- ----------------- --------------------------------------------------------
   3 06/30/06 00:35:32 onvoldeep at CATS.UMICH.EDU (AES-256 CTS mode with 96-bit SHA-1 HMAC) 
   3 06/30/06 00:35:32 onvoldeep at CATS.UMICH.EDU (AES-128 CTS mode with 96-bit SHA-1 HMAC) 
   3 06/30/06 00:35:32 onvoldeep at CATS.UMICH.EDU (Triple DES cbc mode with HMAC/sha1) 
   3 06/30/06 00:35:32 onvoldeep at CATS.UMICH.EDU (DES cbc mode with CRC-32) 
   3 06/30/06 00:35:32 fienzahew at DOGS.UMICH.EDU (AES-256 CTS mode with 96-bit SHA-1 HMAC) 
   3 06/30/06 00:35:32 fienzahew at DOGS.UMICH.EDU (AES-128 CTS mode with 96-bit SHA-1 HMAC) 
   3 06/30/06 00:35:32 fienzahew at DOGS.UMICH.EDU (Triple DES cbc mode with HMAC/sha1) 
   3 06/30/06 00:35:32 fienzahew at DOGS.UMICH.EDU (DES cbc mode with CRC-32) 
ganesh$ 

Here we have a keytab that happens to have two principals in different
realms with lots of keys.  You can make such things with ktutil,
or you can use two keytab files.  I used one because I can.

ganesh$ cat k5.conf
[libdefaults]
        default_realm = UMICH.EDU
        dns_fallback = 0
[realms]
        DOGS.UMICH.EDU = {
                kdc = strawdogs.ifs.umich.edu:88
                kdc = reservoirdogs.ifs.umich.edu:88
                admin_server = strawdogs.ifs.umich.edu:749
        }
        CATS.UMICH.EDU = {
                kdc = lose-the-lion.ifs.umich.edu:88
                admin_server = lose-the-lion.ifs.umich.edu:749
        }
        UMICH.EDU = {
                kdc = fear.ifs.umich.edu:88
                kdc = surprise.ifs.umich.edu:88
                kdc = ruthless.ifs.umich.edu:88
                admin_server = fear.ifs.umich.edu:749
                default_domain = umich.edu
        }
ganesh$ egrep CATS /etc/krb5.conf
ganesh$ 

This was my test krb5 configuration file.  Note it has CATS, DOGS,
and the default realm is something else again -- UMICH.EDU .
Note that /etc/krb5.conf - the default configuration file, does not
have CATS (it does have DOGS, UMICH.EDU plus more junk.)

ganesh$ cat testintkt.pl
use strict;
use Authen::Krb5;
my $cc;
my $kt;
my $cat = 'onvoldeep at CATS.UMICH.EDU';
my $dog = 'fienzahew at DOGS.UMICH.EDU';
my $combined = '/tmp/combined.keytab';
my $user;
my $tgt;
my @klist = ('/usr/local/mit-k5/bin/klist', '-5fea');

my $client;
my $server;

$ENV{'KRB5_CONFIG'} = 'k5.conf';

Authen::Krb5::init_context() || die "Problem with init_context: ".Authen::Krb5::error();
$cc = Authen::Krb5::cc_default() || die "Problem with cc_default: ".Authen::Krb5::error();

for $user ($cat, $dog) {
        $client = Authen::Krb5::parse_name($user)
                || die "cannot parse <$user>: ".Authen::Krb5::error();
        $tgt = $user; $tgt =~ s/.*@//; $tgt = "krbtgt/$tgt\@$tgt";
        $server = Authen::Krb5::parse_name($tgt)
                || die "cannot parse <$tgt>: ".Authen::Krb5::error();

        $cc->initialize($client);
        $kt = Authen::Krb5::kt_resolve($combined)
                || die "Problem with kt_resolve <$combined>: ".Authen::Krb5::error();
        Authen::Krb5::get_in_tkt_with_keytab($client, $server, $kt, $cc)
                || die "Cant authenticate as $user: ".Authen::Krb5::error();
        print "\n**** After authenticating as $user.\n";
        system {$klist[0]} @klist;
}
__END__
ganesh$ 

This is my test script.  I don't have your patch in my copy of
Authen::Krb5, so I can only call Authen::Krb5::init_context once.

ganesh$ perl testintkt.pl

**** After authenticating as onvoldeep at CATS.UMICH.EDU.
Ticket cache: FILE:/tmp/krb5cc_25131
Default principal: onvoldeep at CATS.UMICH.EDU

Valid starting     Expires            Service principal
06/30/06 01:03:16  06/30/06 11:03:16  krbtgt/CATS.UMICH.EDU at CATS.UMICH.EDU
        Flags: I, Etype (skey, tkt): AES-256 CTS mode with 96-bit SHA-1 HMAC, AES-256 CTS mode with 96-bit SHA-1 HMAC 
        Addresses: (none)

**** After authenticating as fienzahew at DOGS.UMICH.EDU.
Ticket cache: FILE:/tmp/krb5cc_25131
Default principal: fienzahew at DOGS.UMICH.EDU

Valid starting     Expires            Service principal
06/30/06 01:03:16  06/30/06 11:03:16  krbtgt/DOGS.UMICH.EDU at DOGS.UMICH.EDU
        Flags: I, Etype (skey, tkt): Triple DES cbc mode with HMAC/sha1, Triple DES cbc mode with HMAC/sha1 
        Addresses: (none)
ganesh$ 

There it is, working.  I got a tgt for CATS (therefore I must have
been using k5.conf), and I could then reinitialize & fetch a tgt
for DOGS.  One perl script, one run, two successful initial authentications,
in different realms - and no messing around with changing default realm,
context, or environment variables.  If I wanted to keep both tgts, I
could probably stuff both tgt's into one credential cache - or I could
easily manage two separate credential caches using cc_resolve.

Note that if I actually cared *which* kdc I was going to inside
of one realm, like strawdogs vs. reservoirdogs, I'd have to do something
else.  The only reason I can think of where I'd want to do that is for
testing or monitoring purposes.

If you still want to get a context more than once, Ken's
idea to set a breakpoint on krb5_init_context or trap its
call to getenv is a great idea.  A fancier scheme would be
to rework Jeff's code so that you can have more than one
krb5 context accessible from perl at the same time.

				-Marcus Watts



More information about the Kerberos mailing list