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