sshd deletes the GSSAPI ticket on exit

Senthil Kumar senthilkumar_sen at hotpop.com
Wed Jun 29 18:43:06 EST 2005


Hello All,

I have run into a situation where a user exiting from a 
PAM_KERBEROS-authenticated session runs the risk of deleting a 
kinit-generated credentials file that was already sitting on the server.  I 
will explain the problem in detail, but let me begin with my question.  It 
has a specific reference to PAM_KERBEROS, but it can also be a general 
question.

If a user (ssh) session was such that it skipped pam_authenticate() during 
login (probably because it used a Key-based auth method),  then is it all 
right for sshd to correspondingly skip pam_setcred() during session exit? 
What will happen if we take that approach?

As I understand it,  pam_setcred() is called as part of the authentication 
phase as well as part of the session exit phase.  When called during 
authentication,  pam_setcred() sets the KRB5CCNAME environment variable to 
the credentials file name,  and when called during session exit, 
pam_setcred() is called to delete that credentials file.

The problem:
Consider a server with pam.conf set up for PAM_KERBEROS all the way 
(authentication, acct management, session management, the works).   This is 
done, presumably, because most all users connecting to the sshd instance on 
this machine are to be PAM_KERBEROS authenticated, with some exceptions.

1.  And now a telnet user U1 comes along, logs into the server machine, and 
does a kinit (on the server).  There may be very good reasons for doing so, 
and I will not go into those reasons here.  We do not control those reasons 
anyway. As a result of the kinit,  a ticket file /tmp/krb5cc_U1uid is 
created on the server (where U1uid is the UID of this telnet user).

2.  Now user U1 logs in via SSH into this machine, this time with a 
PublicKey.  This will cause sshd to skip pam_authenticate(),  and therefore 
also skip the pam_setcred() call.  As a result, the KRB5CCNAME variable will 
remain unset.  No harm so far.

3.  Now, this user (U1, with PublicKey auth) exits. Since session management 
is also set to PAM_KERBEROS, sshd will call pam_setcred(), but this time to 
delete the credentials file.  Note that the credentials file was never 
created, but sshd still calls pam_setcred().  And even that should not have 
been a problem.  But it is, for a few PAM_KERBEROS implementations.

Typical pam_setcred() implementations for the deletion of credentials work 
in the following way:

* Either directly or indirectly, they call the  standard kerberos5 function 
krb5_cc_default_name(), to first determine the credentials file name.  This 
function does not know whether it is being called from PAM_KERBEROS or from 
a GSSAPI environment.  It first checks to see if KRB5CCNAME is set.  If set, 
it returns the file name that the variable is set to.  If not set, then this 
function assumes it is being called from a regular GSSAPI environment, and 
returns a filename that matches what a kinit would have generated. So for 
instance, for user U1, it will return a file name /tmp/krb5cc_U1uid.

* Remove the file whose name is returned by krb5_cc_default_name() !!

Not good.

Of course, the file generated by PAM_KERBEROS itself has a different naming 
convention, intentionally so, in order not to cause overlap between 
kinit-generated ticket filenames and PAM_KERBEROS generated file names. So 
if authentication had indeed been done via PAM, then sshd would have called 
pam_setcred () to establish the credentials file.  Generally speaking, 
pam_setcred() would create the credentials file, and then make the 
appropriate kerberos function calls to set the  name of the cred cache file 
and the KRB5CCNAME environment variable.  It is important to note here that 
the file name generated by pam_setcred() for the credentials file is 
different from that of a kinit-generated file for the same user.

However, a combination of the following events makes a valid server-resident 
kinit-generated ticket disappear:
A kinit-generated ticket exists on the server for user U1 (how it got there 
is not relevant.  Let us assume it is there)
pam.conf is set to have authentication and session management both done via 
PAM_KERBEROS
User U1 logs in via SSH, using a non-PAM method (e.g. Public Key), thereby 
causing KRB5CCNAME to be not set.
User U1 exits
When the user (U1) 's session terminates, the kinit-generated ticket will be 
deleted.


Fixing the problem:
I see at least two ways of fixing the problem.  The first of course, would 
be for PAM_KERBEROS to first check if KRB5CCNAME is set.  If not, it should 
probably just skip the file delete.  That would be ideal for us.

Alternatively, we could do something in sshd.  If pam_setcred() was not 
called during authentication, then don't call pam_setcred() during session 
exit either.

Could there be any problems with this approach?

thanks
Senthil 





More information about the openssh-unix-dev mailing list