One of the projects I’ve been working on lately has required me to investigate the way PAM handles external authentication. The setup is a bunch of different boxes running Solaris, Linux and FreeBSD, but all authenticating from a single central Kerberos domain. There’s also LDAP in the mix, but it’s not actually relevant, so I’ll ignore it for now.
The problem comes when you want to lock out an account on a machine. By this, I mean the account still exists in the passwd file (for whatever reason, it needs to stay there) and the account still exists within the Kerberos domain because it can log on to other machines.
What are the options? The PAM setup probably looks a little something like this:
auth sufficient pam_krb5 auth required pam_unix account required pam_krb5 account required pam_unix
This setup allows the user to authenticate with just their Kerberos credential, but they must pass both modules in the account section (the pam_krb5 one here doesn’t do much though).
So we can put whatever we want in the shadow password entry on the machine, it won’t affect the authentication – it never even gets there. But what about the account section? Can this do anything?
After some investigation and source code checking I came up with the following:
- On Solaris one can put *LK* in the shadow password field. This causes the pam_unix module to reject the login in the account stage.
- On FreeBSD one can do the same as Solaris but with *LOCKED*.
- On Linux you can put what you want in the field but pam_unix won’t take any notice.
If you’re thinking right now “hey, you can just put an exclamation mark in the shadow password field to lock the account out” you’re wrong. What this does on a standalone system is ensure that no possible password can decrypt to match this string which results in locking the account out. But, when we have external authentication it’s meaningless.
So what’s the solution? There’s another field we can use – the shadow password expiry field. This is a time stamp in seconds since the epoch at which the password expires. The default setting of 0 means no expiry. Simply setting this to 1 (or any number smaller than now) results in the account being locked out. This seems like it’ll work across all three operating systems I’m testing, although I’m yet to finish my analysis.
I am a little disappointed with the Linux PAM module. It’s a simple test to do, so I can’t see any reason why it shouldn’t be added.
Update 2nd November 2009:
I’ve since discovered that what I said above about the “default setting of 0 means no expiry” is incorrect. In fact, it varies on different operating systems. I got misled by the behaviour on Ubuntu 9.04 because of a Debian patch which made 0 mean no expiry, but which has been removed in Ubuntu 9.10 (details here).
Consequently my advice now is to set the shadow password expiry field to 1 to lock the account, and to unset it to unlock the account. This appears to work on all the operating systems I’ve tested it on.