Fixme: libpam-script is now at http://freshmeat.net/projects/pam_script/
Right,
This mail is going to be long, you've been warned. What i'm going to describe is how to migrate from any existing pam authentication system to kerberos (specifically heimdal kerberos, though mit kerberos should work just as well for this bit). Then, i'm going to describe how to migrate from an old kerberos realm to a new kerberos realm. Disclaimer: if you break something following this, you get to keep both pieces -) Also, this assumes you're using debian or ubuntu, though any other linux distro should be pretty similar.
You're currently using some pam-based authentication system (pam_unix (aka /etc/shadow), pam_ldap, pam_nis, etc). You've decided you want to migrate to using kerberos for auth. The problem is that your existing auth system probably doesn't give you access to the users' passwords (this /is/ a good thing, just inconvenient right now -), otherwise you could just write a script to automatically add the users to the kerberos realm with their current passwords.
So, unless you feel like adding the users to the realm with random passwords and somehow getting these passwords sent out to them, you need some way to set the user's kerberos password using their existing password. The one place that this is available is via pam during the login process. So, if we had a pam module that took the password of a successfully authenticated user, and added them to the kerberos realm if needed, we'd have a seamless migration path.
pam_script[0][1] is such a module. Combined with 2 scripts, it can do all the heavy lifting for us: http://diamond.nonado.net/misc/krb5_migrate/ . Install heimdal-kdc as usual (i'm not going to cover any of the general setup stuff here), install expect (required for the scripts), install libpam-script, install the scripts to /etc/security. The following should do it on debian at least.
apt-get install heimdal-kdc libpam-krb5
#configure heimdal-kdc as normal
apt-get install subversion
svn checkout http://libpam-script.googlecode.com/svn/trunk/ libpam-script
cd libpam-script
debuild -B
cd ..
dpkg -i libpam-script_0.1.9_i386.deb
cd /etc/security
wget http://diamond.nonado.net/misc/krb5_migrate/krb5_migrate.exp
wget http://diamond.nonado.net/misc/krb5_migrate/krb5_migrate.sh
apt-get install expect
chmod +x krb5_migrate.sh
Then change /etc/pam.d/common-auth to look something like this[2]:
auth sufficient pam_krb5.so
auth requisite pam_unix.so nullok_secure use_first_pass
auth optional pam_script.so runas=root expose=1 onauth=/etc/security/krb5_migrate.sh
(Note: the last line might be wrapped by my mail client, adjust your sets accordingly)
where pam_unix.so is the existing authentication system. Now, the next time a user logs in, if they authenticate properly, pam_script will run krb5_migrate.sh. All going well, that will add a kerberos principal with the username and password of the current user. From then on, they'll be authenticated by pam_krb5.so, and voila they're now migrated. If you run
tail -f /var/log/{auth,heimdal-kdc}.log
you should see messages like:
==> /var/log/heimdal-kdc.log <==
2006-08-23T10:32:18 UNKNOWN -- diamond@NEWREALM: No such entry in the database
==> /var/log/auth.log <==
Aug 23 10:32:19 fluff sshd[11777]: PAM-script: Real User is: diamond
Aug 23 10:32:19 fluff sshd[11777]: PAM-script: Command is: /etc/security/krb5_migrate.sh
Aug 23 10:32:19 fluff sshd[11777]: PAM-script: Executing uid:gid is: 0:0
Aug 23 10:32:19 fluff sshd[11777]: Accepted password for diamond from 192.168.2.152 port 32775 ssh2
Aug 23 10:32:19 fluff sshd[11789]: (pam_unix) session opened for user diamond by (uid=0)
The next time they log in, the heimdal-kdc won't print 'UNKNOWN -- diamond@NEWREALM: No such entry in the database' as the principal should now exist.
You're currently using a kerberos realm (referred to here as OLDREALM ) for auth, but for whatever reason you want to migrate the principals to a new realm (NEWREALM). In my case this was simply because the dns domain has changed completely, and it was more elegant to change the realm name with it, and because i wanted to know if it was possible -) As of kerberos 5, you cannot change the realm of an existing principal, as the entire user@REALM string is used as a salt for the password, so more involved methods are required.
So, here's how you go about it. First, you need to have OLDREALM and NEWREALM both set up. You also need your /etc/krb5.conf set up with both realms, with the default realm set to NEWREALM. Initialise NEWREALM on the kdc:
kadmin -l init NEWREALM
and install pam_script + scripts as above.
In order to handle this migration, we need to be able to attempt to authenticate users against both username@OLDREALM and username@NEWREALM via pam_krb5. By default, pam_krb5 does not have this functionality, it will just use whatever realm is set as default in /etc/krb5.conf. So, i've created a small patch[3] against pam_krb5 to allow you to specifiy an alternative realm parameter.
This allows us to setup /etc/pam.d/common-auth to look something like this [4]:
auth sufficient pam_krb5.so
auth requisite pam_krb5.so use_first_pass alt_realm=OLDREALM
auth optional pam_script.so runas=root expose=1 onauth=/etc/security/krb5_migrate.sh
(Note: the last line might be wrapped by my mail client, adjust your sets accordingly)
This will attempt to auth users against the NEWREALM. If that fails, it will then try against OLDREALM. If (and only if) that succeeds, it will run the migration script.
Et voila, every time a user who only in OLDREALM logs in, they'll be migrated to NEWREALM with their existing password, transparently, and will auth against NEWREALM in the future. Whenever all the users are migrated, you can remove pam_script, the pam_krb5.so entry that refers to OLDREALM, and *@OLDREALM from the kdc db.
The scripts i've provided obviously only work with a local kdc. Modifying them to work with a remote kdc using command-limited ssh-keys is left as an exercise for the reader -)
Steve