* Tom Lane ([EMAIL PROTECTED]) wrote:
> Stephen Frost <[EMAIL PROTECTED]> writes:
> >> I have little idea of how expensive the operations called by
> >> pg_krb5_init really are.  If they are expensive then it'd probably
> >> make sense to keep the current static variables but treat 'em as a
> >> one-element cache, ie, recompute if a new user name is being demanded.
> >> If not, we ought to be able to simplify some things.
> > We'd have to recompute based on the KRB5CCNAME environment variable
> > changing, which is certainly an option.  It's not necessairly the case
> > that the username is changing, possibly just the cache.
> Hm, apparently I completely misunderstand the problem here.  What I
> thought the bug was was that the cache wasn't recomputed given an
> attempt to connect as a different Postgres username than the first
> time.  If that's not the issue, then what is?

The specific problem which I and the original reporter ran into is this:

pg_connect() -- works fine
pg_close() -- works fine
rm /tmp/krb5cc_apache_aev0kF
pg_connect() -- Doesn't work, Kerberos error is "no credentials cache"

What's happening here is that for every connection to apache by the
client a new credentials cache is created, and then destroyed when the
connection closes.  When using PHP (ie: phppgadmin) and mod_php (as is
common) the Apache process is the one actually making the connection to
the database and a given Apache process usually serves multiple requests
in its lifetime, sometimes to the same user, sometimes to different

The static variables being used are for: krb5_init_context,
krb5_cc_default, krb5_cc_get_principal, and krb5_unparse_name.
Technically, between one connection and the next, krb5_cc_default,
krb5_cc_get_principal and krb5_unparse_name could reasonably return
different values.  krb5_init_context is pretty unlikely to change as
that would mean /etc/krb5.conf changed.  Looking through the krb5 source
code it appears that the only one which checks for something existing
is krb5_cc_default_name (called by krb5_cc_default), which will just 
return the current ccache name if one has been set.
(src/lib/krb5/os/ccdefname.c:278, krb5-1.4.3)

We initially brought up this issue with the Kerberos folks actually:

They pretty clearly felt that the application was responsible for
handling the cache in the event it changes.  Unfortunately, it's not the
application which is talking to Kerberos but another library in this
case which doesn't expose the Kerberos API to the application in such a
way to allow the application to notify Kerberos of the cache change.

Looking through the Kerberos API again it looks like it might be
possible to use krb5_cc_set_default_name(context, NULL) to force
krb5_cc_default_name() (from krb5_cc_default()) to re-find the cache.
Finding the cache again is reasonably inexpensive.  I've tried a couple
of things along these lines now but I havn't found a workable solution
which doesn't reinitialize the main Kerberos context, unfortunately.
I'll keep working on it as time allows though honestly I don't believe
it's generally terribly expensive to reinitialize the context...

Sorry it took so long to reply, running down the paths through the 
various libraries takes a bit of time and I was really hoping to be able
to suggest an alternative solution using krb5_cc_set_default_name.



Attachment: signature.asc
Description: Digital signature

Reply via email to