PAM is a collection of modules that essentially form a barrier between a service on your system, and the user of the service. The modules can have widely varying purposes, from disallowing a login to users from a particular UNIX group (or netgroup, or subnet...), to implementing resource limits so that your 'research' group can't hog system resources.
PAM is used by major commercial UNIX flavors such as AIX, HP-UX and Solaris, as well as the major free versions of UNIX, like FreeBSD. Almost all distributions of Linux also implement PAM, though I believe Slackware is still the one notable holdout in this area.
The power, flexibility and ubiquity of PAM is a boon for developers of Linux applications, since instead of writing a full-fledged authentication layer for their program, they can simply write a hook into PAM, and administrators can configure it along with the rest of the system services using PAM. This, in turn, makes the lives of administrators much easier, since we only have to learn PAM, instead of learning and trying to remember a separate configuration model for every system we decide to run.
I'll be looking at pam as it applies to Linux systems. Solaris and other commercial UNIX systems have a slightly different configuration model, centered around a single file, /etc/pam.conf. Though conceptually the two implementations are just about identical, the Linux model uses a different configuration file for each service which uses PAM. On most Linux systems, these configuration files live in /etc/pam.d, and are named after the service - for example, the 'login' configuration file is called /etc/pam.d/login. Let's have a quick look at a version of that file:
auth required /lib/security/pam_securetty.so
auth required /lib/security/pam_nologin.so
auth sufficient /lib/security/pam_ldap.so
auth required /lib/security/pam_unix_auth.so try_first_pass
account sufficient /lib/security/pam_ldap.so
account required /lib/security/pam_unix_acct.so
password required /lib/security/pam_cracklib.so
password required /lib/security/pam_ldap.so
password required /lib/security/pam_pwdb.so use_first_pass
session required /lib/security/pam_unix_session.so
PAM Management Realms
The first thing I'd like you to notice in the file is the leftmost column, which, in all, contains four unique words, which represent four realms of PAM management: auth, account, password and session. While there are many modules which support more than one of these realms (indeed, pam_unix supports all of them), others, like pam_cracklib for instance, are only suited for one (the 'password' facility in pam_cracklib's case). Knowing what these four realms are responsible for is extrememly important if you want to make effective use of PAM. Below is a quick explanation of how I tend to think about these keywords in practice:
The middle column holds a keyword that essentially determines what PAM should do if the module either succeeds or fails. These keywords are called 'controls' in PAM-speak. Note that this keyword is not an indicator to the module, but to the underlying PAM library. In probably 90% of the cases, you can use one of the common keywords (requisite, required, sufficient or optional). However, this is only the tip of the iceberg in terms of unleashing the flexibility and power of PAM. You could actually use more complicated syntax to account for seemingly any situation. Here are the valid simple 'one-word' keywords PAM understands:
In the rightmost column we see the actual path to the module that gets invoked. Note that in our sample config, four separate modules are listed for the 'auth' realm. This is referred to as 'stacking' in PAM lingo. If you're thinking that this implies that ordering of the stacked modules is significant, you're right. Also, in addition to the more complex options you can pass to the PAM library in the center column, there are, likewise, options that you can feed to the module itself. This can be seen in our example config file, where the pam_unix.so module takes the 'try_first_pass' argument. Furthermore, many modules are meant to be used with an accompanying configuration file of some sort, allowing for more complex options that would make the PAM config file a big mess otherwise.
Drilling Down: What's Going On?Now that we have a grip on how to basically parse a configuration file at a high level, let's drill down and see exactly what's going on in our example file. We'll have a look at the module stack for the 'auth' realm, detailing what will happen given a number of scenarios.
In our example file, we have four modules stacked for the auth realm:
auth required /lib/security/pam_securetty.so
auth required /lib/security/pam_env.so
auth sufficient /lib/security/pam_ldap.so
auth required /lib/security/pam_unix.so try_first_pass
As the modules are invoked in order, here is what will happen:
Depending on the feedback and corrections submitted for this article, I'm happy to go into PAM further or with some other focus in a future article. If you've done something amazing with PAM or notice a common problem users have with PAM that hasn't been discussed here, please send me email (njcajun - linuxlaboratory dot org) or post a comment.
Note: Comments are owned by the poster. We are not responsible for their content.
Re:PAM modules
Posted by: njcajun on February 16, 2004 01:40 AMAnything having to do with logging is a good example. logrotate, and syslog have the needs of most admins covered, and it's a little tough to see the usefulness of putting this in PAM, since most applications already have a logging interface that is easy to write and easily configurable by and admin. The idea of PAM is to allow developers to write a PAM interface (which is simple) so that admins can configure authentication/session restraints as they see fit (also pretty simple).
You're right in saying that PAM is NOT a 'security system'. It's only ONE PART of a system's security. You cannot simply configure PAM and say 'ok, all locked down'. It's not that simple, and it's never been a goal of anyone's to MAKE it that simple. Look into tools like tcpwrappers, bastille, tripwire, the compat libs, the iptables manpage, and the documentation for the latest kernel (all of it.. no - really). Everything you want to do is available. However, it's not all under the PAM umbrella. Nor does any admin want it to be, since building interfaces for firewalls, logging config, system password constraints, file access controls, etc., would make PAM the 'windows registry' of the Linux world. Too much responsibility is not good, and antithetical to the UNIX mantra of 'do one thing, and do it well'.
There are some other things you said that I don't think are factual. For example, 'blocking after x number of attempts' is possible already - though possibly not for all modules. Forcing password changes is also possible already with PAM. Forcing a specific sequence of password requirements is pretty much there - have a look at using pam_cracklib with pam_pwcheck. In my environment, we still had a little code to write to enforce everything we wanted (ie, you have to use a number, and it can't be the first or last character in the password), but it did a lot of jobs we were doing with code before.
Your items numbered 7 and 8 about using a different password algorithm should be available through bastille. ]
I'd write more, but I do have to run...
All of this said, I'll most likely be covering some of the above mentioned tools in future articles.<nobr> <wbr></nobr>:)
#