I’ve discovered unknown terrors while researching and writing PAM Mastery. Well, terrors previously unknown to me, at least. I’m certain that the OpenPAM and Linux-PAM developers are very much aware of them. (I’m also certain that they’re part of the reason DES keeps his hair cut so short, so that he can’t yank it out of his head in bloody chunks.)
Part of the writing process was building a giant spreadsheet listing operating systems, PAM versions, and which modules appear in each OS. Strictly speaking, OpenPAM proper contains very few modules. Most “OpenPAM” modules actually originate from FreeBSD. But people are free to use them, so they generally get lumped into the “OpenPAM module” bucket.
One module that’s conspicuous by its absence in pam_listfile. Pam_listfile.so lets you accept or reject access based on the username’s presence in a file. It’s much like the traditional BSD /etc/ftpusers functionality.
It’s a reasonable enough module. And I’m told that pam_listfile.so can be compiled to work on FreeBSD, but nobody’s bothered to submit a port. How to make it work is a perennial question on the FreeBSD mailing lists.
The good news is, you can easily emulate pam_listfile.so on FreeBSD using pam_exec. Pam_exec runs a command as part of the PAM chain. If the command returns 0, the module says to grant access. If the command returns 1, the module says to deny access. (Whether PAM obeys this instruction or not depends on the type of statement.)
Here I implement basic pam_listfile.so functionality in a shell script, pam_listfile.sh.
Enable pam_listfile.sh as an auth rule.
auth required pam_exec /usr/local/scripts/pam_listfile.sh
Now all you need is a script. This version of the script permits access if the username appears in /etc/validusers.
/usr/bin/grep ^$PAM_USER$ /etc/validusers
And here’s a version that rejects access if the username appears in /etc/validusers, exactly like /etc/ftpusers. It’s a huge change, adding an entire exclamation point.
! /usr/bin/grep ^$PAM_USER$ /etc/validusers
You could add more functions as you need. The important thing is to return either 0 or not-zero.
PAM Mastery is over half finished. I’ve completed the parts on “this is how PAM works” and have moved on to “here are some cool PAM modules that you might want to use.”