Lion-PAM-Kerberos Bug (Apple Bug ID# 10956542)

The goal is to login at the Login Window with a Kerberos principal and Kerberos password. Two methods were used to accomplish that goal, but there is a specific circumstance in each method when this doesn't work, which I'll try to explain below. This is a bug.

In both cases below, no changes were made to the default /etc/authorization file.

Table of Contents
Case 1:
When The Kerberos Principal And Password Is The Same As The Local Account And Password
Case 2:
When The kerberos Principal Is The Same As The Local Account, But The Passwords Are Different
    More Detailed Follow-up Discovery
Summary

Case 1:
When The Kerberos Principal And Password Is The Same As The Local Account And Password

/etc/pam.d/authorization file used:

auth    optional   pam_krb5.so use_first_pass use_kcminit default_principal
auth    optional   pam_ntlm.so use_first_pass
auth    required   pam_opendirectory.so use_first_pass nullok
account required   pam_opendirectory.so

We are able to login and get a TGT. We can logout and login many times and all is good. However, if we do a kinit from the command line while logged in, then logout; at the next login, we don't get a TGT. We can logout and login many times, but will never again get a TGT.

Log in with Kerberos principal and password, list the /etc/pam.d/authorization file that is currently being used and show that a TGT was obtained:

Last login: Mon Feb 27 12:02:56 on console
$ more /etc/pam.d/authorization
auth    optional   pam_krb5.so use_first_pass use_kcminit default_principal
auth    optional   pam_ntlm.so use_first_pass
auth    required   pam_opendirectory.so use_first_pass nullok
account required   pam_opendirectory.so
$ klist
Credentials cache: API:502:3
        Principal: rod@IASTATE.EDU

  Issued           Expires          Principal
$ 
Feb 27 12:02:57  Feb 27 22:02:57  krbtgt/IASTATE.EDU@IASTATE.EDU
$ 

Logout and login several more times to show that this is working:

Last login: Mon Feb 27 12:03:29 on console
$ klist
Credentials cache: API:502:4
        Principal: rod@IASTATE.EDU

  Issued           Expires          Principal
Feb 27 12:03:29  Feb 27 22:03:29  krbtgt/IASTATE.EDU@IASTATE.EDU
$ 

Last login: Mon Feb 27 12:04:02 on console
$ klist
Credentials cache: API:502:5
        Principal: rod@IASTATE.EDU

  Issued           Expires          Principal
Feb 27 12:04:02  Feb 27 22:04:02  krbtgt/IASTATE.EDU@IASTATE.EDU
$ 

While logged in, run kinit on the command line to get a new TGT and then logout:

$ kinit -l 30d
rod@IASTATE.EDU's Password: 
$ klist
Credentials cache: API:502:5
        Principal: rod@IASTATE.EDU

  Issued           Expires          Principal
Feb 27 12:04:35  Mar 28 13:04:28  krbtgt/IASTATE.EDU@IASTATE.EDU
$ 

Login again, but this time no TGT was obtained:

Last login: Mon Feb 27 12:05:04 on console
$ klist
klist: krb5_cc_get_principal: No credentials cache file found
$ 

Logout and login several more times to show that we will never again get a TGT:

Last login: Mon Feb 27 12:05:24 on console
$ klist
klist: krb5_cc_get_principal: No credentials cache file found
$ 

Last login: Mon Feb 27 12:05:41 on console
$ klist
klist: krb5_cc_get_principal: No credentials cache file found
$ 

Case 2:
When The Kerberos Principal Is The Same As The Local Account, But The Passwords Are Different

/etc/pam.d/authorization file used:

auth    optional   pam_krb5.so use_first_pass use_kcminit default_principal
auth    sufficient pam_krb5.so use_first_pass default_principal
auth    optional   pam_ntlm.so use_first_pass
auth    required   pam_opendirectory.so use_first_pass nullok
account required   pam_opendirectory.so

We are able to login using the Kerberos principal and password and get a TGT. We can logout and login many times and all is good. However, if we do a kinit from the command line while logged in, then logout; at the next login, we don't get a TGT. The next login after that, we do get a TGT. The next login after that we don't. Then do, then don't, then do, etc. At a login when we do get a TGT and then run kdestroy and then klist, we see a new credentials cache (apparently reusing the TGT obtained from the command line kinit), but with new "Issued" and "Expires" dates. After we kdestroy that one too, we're back to getting a TGT again at every login.

Log in with Kerberos principal and password, list the /etc/pam.d/authorization file that is currently being used and show that a TGT was obtained:

Last login: Mon Feb 27 13:22:00 on console
$ more /etc/pam.d/authorization
auth    optional   pam_krb5.so use_first_pass use_kcminit default_principal
auth    sufficient pam_krb5.so use_first_pass default_principal
auth    optional   pam_ntlm.so use_first_pass
auth    required   pam_opendirectory.so use_first_pass nullok
account required   pam_opendirectory.so
$ klist
Credentials cache: API:502:2
        Principal: rod@IASTATE.EDU

  Issued           Expires          Principal
Feb 27 13:22:00  Feb 27 23:21:59  krbtgt/IASTATE.EDU@IASTATE.EDU
$ 

Logout and login several times to show that this is working:

Last login: Mon Feb 27 13:22:41 on console
$ klist
Credentials cache: API:502:3
        Principal: rod@IASTATE.EDU

  Issued           Expires          Principal
Feb 27 13:22:40  Feb 27 23:22:40  krbtgt/IASTATE.EDU@IASTATE.EDU
$ 

Last login: Mon Feb 27 13:23:10 on console
$ klist
Credentials cache: API:502:4
        Principal: rod@IASTATE.EDU

  Issued           Expires          Principal
Feb 27 13:23:10  Feb 27 23:23:09  krbtgt/IASTATE.EDU@IASTATE.EDU

While logged in, run kinit on the command line to get a new TGT and then logout:

$ kinit -l 30d
rod@IASTATE.EDU's Password: 
$ klist
Credentials cache: API:502:4
        Principal: rod@IASTATE.EDU

  Issued           Expires          Principal
Feb 27 13:23:39  Mar 28 14:23:30  krbtgt/IASTATE.EDU@IASTATE.EDU
$ 

At the next login using a Kerberos principal and password, we don't get a TGT:

Last login: Mon Feb 27 13:23:59 on console
$ klist
klist: krb5_cc_get_principal: No credentials cache file found
$ 

The next login after that, we do get a TGT:

Last login: Mon Feb 27 13:24:19 on console
$ klist
Credentials cache: API:502:4
        Principal: rod@IASTATE.EDU

  Issued           Expires          Principal
Feb 27 13:24:19  Feb 27 23:24:19  krbtgt/IASTATE.EDU@IASTATE.EDU
$ 

The next login after that we don't again:

Last login: Mon Feb 27 13:24:41 on console
$ klist
klist: krb5_cc_get_principal: No credentials cache file found
$ 

Then do, then don't, then do, etc.:

Last login: Mon Feb 27 13:25:01 on console
$ klist
Credentials cache: API:502:4
        Principal: rod@IASTATE.EDU

  Issued           Expires          Principal
Feb 27 13:25:01  Feb 27 23:25:01  krbtgt/IASTATE.EDU@IASTATE.EDU

At a login when we do get a TGT and then run kdestroy and then klist, we see a new credentials cache (apparently reusing the TGT obtained from the command line kinit), but with new "Issued" and "Expires" dates:

$ kdestroy
$ klist
Credentials cache: API:502:9
        Principal: rod@IASTATE.EDU

  Issued           Expires          Principal
Feb 27 13:25:01  Feb 27 23:25:02  krbtgt/IASTATE.EDU@IASTATE.EDU

After we kdestroy that TGT:

$ kdestroy 
$ klist
klist: krb5_cc_get_principal: No credentials cache file found
$ 

We're back to getting a TGT again at every login:

Last login: Mon Feb 27 13:25:41 on console
$ klist
Credentials cache: API:502:10
        Principal: rod@IASTATE.EDU

  Issued           Expires          Principal
Feb 27 13:25:41  Feb 27 23:25:40  krbtgt/IASTATE.EDU@IASTATE.EDU
$ 

Logout and login several more times to show that TGT is obtained again every time:

Last login: Mon Feb 27 13:25:59 on console
$ klist
Credentials cache: API:502:11
        Principal: rod@IASTATE.EDU

  Issued           Expires          Principal
Feb 27 13:25:59  Feb 27 23:25:59  krbtgt/IASTATE.EDU@IASTATE.EDU
$ 

Last login: Mon Feb 27 13:26:23 on console
$ klist
Credentials cache: API:502:12
        Principal: rod@IASTATE.EDU

  Issued           Expires          Principal
Feb 27 13:26:22  Feb 27 23:26:22  krbtgt/IASTATE.EDU@IASTATE.EDU
$ 

More Detailed Follow-up Discovery

Newly booted machine; first login.

$ klist
Credentials cache: API:502:1
         Principal: jdwhite@IASTATE.EDU

    Issued           Expires          Principal
 Mar  2 10:20:26  Mar  2 20:20:26  krbtgt/IASTATE.EDU@IASTATE.EDU

New TGT, klist sees it. All good.
Logout, login.

Last login: Fri Mar  2 10:21:12 on console
$ klist
Credentials cache: API:502:2
        Principal: jdwhite@IASTATE.EDU

   Issued           Expires          Principal
Mar  2 10:21:11  Mar  2 20:21:11  krbtgt/IASTATE.EDU@IASTATE.EDU

Got new ccache, TGT, and klist sees it - good, but want longer TGT, so I kinit.

$ kinit -l30d jdwhite
jdwhite@IASTATE.EDU's Password: 
$ klist
Credentials cache: API:502:2
        Principal: jdwhite@IASTATE.EDU

  Issued           Expires          Principal
Mar  2 10:21:46  Apr  1 11:21:44  krbtgt/IASTATE.EDU@IASTATE.EDU
$ klist -l
      Name                  Cache name     Expires         
* jdwhite@IASTATE.EDU   502:2          Apr  1 11:21

New, longer, tickets. Same ccache. All good.
Logout, login.

Last login: Fri Mar  2 10:22:41 on console
$ klist
klist: krb5_cc_get_principal: No credentials cache file found
$ klist -A
Credentials cache: API:502:4
        Principal: jdwhite@IASTATE.EDU

  Issued           Expires          Principal
Mar  2 10:22:41  Mar  2 20:22:41  krbtgt/IASTATE.EDU@IASTATE.EDU

New :4 ccache created, klist can't see it. Old :2 ccache nowhere to be seen. This is the seemingly buggy behavior we're trying to eliminate.
Logout, login.

Last login: Fri Mar  2 10:23:57 on console
$ klist
Credentials cache: API:502:2
        Principal: jdwhite@IASTATE.EDU

  Issued           Expires          Principal
Mar  2 10:23:55  Mar  2 20:23:55  krbtgt/IASTATE.EDU@IASTATE.EDU

The old :2 ccache is back, refreshed with a new TGT, and klist can see it. In addition, a new :5 ccache is also created.

$ klist -A
Credentials cache: API:502:2
        Principal: jdwhite@IASTATE.EDU

  Issued           Expires          Principal
Mar  2 10:23:55  Mar  2 20:23:55  krbtgt/IASTATE.EDU@IASTATE.EDU


Credentials cache: API:502:5
        Principal: jdwhite@IASTATE.EDU

  Issued           Expires          Principal
Mar  2 10:23:57  Mar  2 20:23:57  krbtgt/IASTATE.EDU@IASTATE.EDU

$ klist -l
    Name                  Cache name     Expires         
* jdwhite@IASTATE.EDU   502:2          Mar  2 20:23:55   
  jdwhite@IASTATE.EDU   502:5          Mar  2 20:23:57   

This gives us a working environment; klist can see the ccache with a a newly-acquired TGT. The additional :5 ccache seems benign.
Logout, login

$ klist
klist: krb5_cc_get_principal: No credentials cache file found
$ klist -A
Credentials cache: API:502:6
        Principal: jdwhite@IASTATE.EDU

  Issued           Expires          Principal
Mar  2 10:25:31  Mar  2 20:25:31  krbtgt/IASTATE.EDU@IASTATE.EDU

No sign of either the :2 or the :5 ccache. :6 ccache gets created, but klist can't see it. Again, this is the seemingly buggy behavior we're trying to eliminate.
Logout, login.

Last login: Fri Mar  2 10:26:34 on console
$ klist
Credentials cache: API:502:2
        Principal: jdwhite@IASTATE.EDU

  Issued           Expires          Principal
Mar  2 10:26:33  Mar  2 20:26:33  krbtgt/IASTATE.EDU@IASTATE.EDU
$ klist -A
Credentials cache: API:502:2
        Principal: jdwhite@IASTATE.EDU

  Issued           Expires          Principal
Mar  2 10:26:33  Mar  2 20:26:33  krbtgt/IASTATE.EDU@IASTATE.EDU


Credentials cache: API:502:7
        Principal: jdwhite@IASTATE.EDU

  Issued           Expires          Principal
Mar  2 10:26:34  Mar  2 20:26:34  krbtgt/IASTATE.EDU@IASTATE.EDU

:2 ccache is now back and pointed to. New :7 ccache is created. Note that the :2 ccache keeps getting updated and only lags a couple seconds behind the newly created ccache (:7 in the above example). This suggests that the :2 ccache is getting updated at each login and then a different process (perhaps outside the pam stack) is obtaining the second ccache.

When the original :2 ccache disappears every other login, a new ccache is being created, klist can't see it. When the :2 ccache does appear, klist can see it and we have a second newly-created and populated ccache.

So, after performing a 'kinit', we're always obtaining a new ccache at login, klist can't ever see it. Instead, klist sees 'kinit' ccache (:2 in this document) but only every other login.

Summary

Getting a TGT from the Login Window and getting a TGT from the command line don't work together. Why would someone want to do a kinit from the command line after logging in? The TGT from the Login Window always defaults to 10 hours even if a longer ticket lifetime is specified in /Library/Preferences/edu.mit.Kerberos. This is another bug. The only way to get a longer ticket lifetime is to kinit again and either specify a longer ticket lifetime on the command line or if not specified on the command line, kinit honors what is specified in /Library/Preferences/edu.mit.Kerberos.

Rod Eldridge
Network Infrastructure, Authentication, & Directory Services (NIADS) Team
Mac OS X Dev Team
IT Services, Iowa State University of Science and Technology

Jason White
NIADS Team (Network Infrastructure, Authentication, & Directory Services)
IT Services, The Iowa State University of Science and Technology