I upgraded my laptop to Snow Leopard yesterday, and one thing I’m still reeling from is the changes to Kerberos. I’m not usually one to fault developers for wanting to move forward at the cost of compatibility, especially for rarely used features, so when I found that Apple made substantial changes to the user-facing side of Kerberos, I started updating my scripts and configuration to catch up.
I still have a few more bugs to track down, so i you know how to solve either of these, let me know:
- Automatically renewing tickets.
- /System/Library/LaunchAgents/com.apple.Kerberos.renew.plist appears to be a launchd job to do this, but I can’t figure out what’s supposed to trigger it.
- Triggering code on ticket acquisition/renewal.
- On older versions of OS X, you could set the libdefaults.login_logout_notification option in /Library/Preferences/edu.mit.Kerberos and cause Kerberos to call into a bundle in /Library/Kerberos Plug-Ins, but that doesn’t seem to work on Snow Leopard – the Login and Logout Notification API appears to be gone
In the mean time, after two hours of source diving later, I have solved one of my major bugs with Kerberos: de-stickifying options passed to kinit.
kinit seems to have gotten a lot of TLC in Snow Leopard—it appears to have been substantially re-written to take advantage of the Kerberos Identity Management API, which looks to be an attempt to genericize everything that made Kerberos on OS X special (multiple credential caches, system Keychain integration, etc.).
Unfortunately, one of the features it gained through this API was the ability to remember Kerberos ticket settings. In Leopard, if you changed ticket parameters in the “New Tickets” window of Kerberos.app (such as the duration of the tickets or the flags on them), those changes would be remembered the next time you used Kerberos.app to get tickets. But if you changed ticket parameters by passing flags to kinit, they would only work for one invocation.
But now, if I pass a flag like
-l1m (get tickets that last one minute), that sticks across kinit invocations:
fanty:~ evan$ kinit -l1m -r5m broder fanty:~ evan$ klist [...] Valid Starting Expires Service Principal 06/13/10 00:43:14 06/13/10 00:44:13 krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU renew until 06/13/10 00:48:13 fanty:~ evan$ kdestroy fanty:~ evan$ kinit broder fanty:~ evan$ klist [...] Valid Starting Expires Service Principal 06/13/10 00:43:26 06/13/10 00:44:26 krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU renew until 06/13/10 00:48:26
I found this undesirable, because when I pass flags to kinit, I want them to be for that invocation only, and any other time, I want my “defaults” – i.e. tickets that last as long as possible.
It turns out that the KIM API implementation on OS X takes backends into the standard OS X preferences API, and writes its settings to ~/Library/Preferences/edu.mit.Kerberos.IdentityManagement.plist. And in particular, it checks for the RememberCredentialAttributes to determine whether or not to store the preferences that are passed in. So just run
defaults write edu.mit.Kerberos.IdentityManagement RememberCredentialAttributes -bool false
to disable this feature. (Replace
true if you want to undo the change)
If you want to follow the maze of twisty passages yourself, you can grab KerberosLibraries-81.46.1.tar.gz from Apple Open Source. Here’s the relevant call chain (except for kinit, which is in KerberosClients/kinit/Sources, all paths are relative to KerberosFramework/Kerberos5/Sources):
- main (kinit.c:591)
- kim_ccache_create_new (kim/lib/kim_ccache.c:214)
- kim_ccache_create_new_with_password (kim/lib/kim_ccache.c:234)
- kim_credential_create_new_with_password (kim/lib/kim_credential.c:411)
- kim_credential_remember_prefs (kim/lib/kim_credential.c:224)
- kim_preferences_create (kim/lib/kim_preferences.c:620)
- kim_preferences_read (kim/lib/kim_preferences.c:433)
- kim_os_preferences_get_boolean_for_key (kim/lib/mac/kim_os_preferences.c:412)
- kim_os_preferences_copy_value (kim/lib/mac/kim_os_preferences.c:205)
- kim_os_preferences_copy_value_for_file (kim/lib/mac/kim_os_preferences.c:142)
Around here the linearity of the call chain starts to break down, but kim_os_preferences_get_boolean_for_key gets called with kim_preference_key_remember_options, which gets passed to kim_os_preferences_cfstring_for_key in kim_os_preferences_copy_value, returning
Eventually CFPreferencesCopyValue gets called asking for the “RememberCredentialAttributes” key in “edu.mit.Kerberos.IdentityManagement”, checking current-host/current-user, any-host/current-user, current-host/any-user, and any-host/any-user configuration settings, in that order.