Configuring PAM, Part Two

Configuring PAM can be tricky. Look at some examples and learn what rationales work for customizing your own.
Last month’s column covered the basics of the Pluggable Authentication Module(PAM) system, which provides authentication services to Linux programs. PAM-enabled applications call PAM to authenticate users, enabling login servers, screen savers, password utilities, and others to interact with any authentication tools you care to configure — the standard /etc/passwd file, a Lightweight Directory Access Protocol (LDAP) server, a Windows domain controller, or anything else that PAM supports.
Unfortunately, despite the fact that standard Linux PAM configurations generally work transparently, PAM is complex enough that modifying a working system (to add a new protocol or change the behavior of the login subsystem) is tricky. So, this month, let’s look at some working configurations and modifications to these configurations. With these examples and last month’s basic PAM description, you should be better able to tweak or completely overhaul your PAM configuration.
Before you begin, you should be aware that modifying your PAM configuration is potentially risky. If you get it wrong, you might not be able to log in again to fix the problem! Back up any PAM-related file before modifying it, and keep a root console open at all times. This should enable you to back out of any changes that don’t work as intended. In a worst-case scenario, you can reboot your system using an emergency disk and copy the backups of PAM files to restore your system to an operational state.

Some Generic PAM Configurations

All major Linux distributions use PAM by default. In almost all distros, the directory /etc/pam.d/ contains the PAM configuration files. Each of these files — cups, gdm, imap, login, passwd, samba, sshd, su, sudo, system-auth, useradd, xdm, and xscreensaver — specify one or more PAM stacks (as described last month) that tell PAM how to authenticate users of a particular server or program.
For instance, the file /etc/pam.d/login controls PAM’s actions on behalf of the login program, the software that processes text-mode logins. /etc/pam.d/su does the same for the su program, and /etc/pam.d/samba tells PAM how to authenticate Samba users. (Samba actually provides its own authentication system, so it seldom uses PAM. Samba uses PAM only when Samba is configured to accept unencrypted passwords.)
One important special case is the file /etc/pam.d/system-auth, which is the standard control file for the pam_stack.so module, as described shortly in “Using the pam_stack.so Module.” Many distributions use this module as a way of putting common PAM options in one file, which can simplify configuration.
An example PAM configuration is shown in Listing One. (Long lines are wrapped with a trailing slash (/).) It shows the /etc/pam.d/login file from a SuSE Linux system. Each stack — auth, account, password, and session — enumerates the PAM modules that PAM should call whenever login requests certain actions, such as password authentication. (If you examine your own login file and find references to the pam_stack.so module, you should consult the upcoming section, “Using the pam_stack.so Module,” for more information.)
Listing One: A sample login PAM configuration file

auth requisite pam_unix2.so nullok
auth required pam_securetty.so
auth required pam_nologin.so
auth required pam_env.so
auth required pam_mail.so

account required pam_unix2.so

password required pam_pwcheck.so nullok
password required pam_unix2.so nullok \
use_first_pass use_authtok

session required pam_unix2.so none
session required pam_limits.so

Sometimes modules don’t perform tasks that are obviously related to the primary function of a stack. Some modules are placed within a stack for convenience.
For example, in Listing One, the call to pam_mail.so in the auth stack doesn’t have perform any authentication; pam_mail.so checks for new email and informs the user of its presence. Having PAM do this job is just a convenient way to ensure that it’s done.
Most of the modules used in Listing One were described last month. However, one new module is pam_nologin.so, which checks for the /etc/nologin file. If it’s present, the module denies login privileges to all users except root and displays the contents of the /etc/nologin file.
One key point is that the pam_unix2.so module is called as a requisite module in the auth stack, while the remaining modules are required. As described last month, if a requisite module fails (say, because the user entered the wrong password), PAM bypasses the remaining modules in that stack. In contrast, a required module causes the remaining modules to execute, although the stack as a whole will fail. In Listing One, this configuration causes the non-authentication auth modules to be bypassed if the user enters the wrong password, which might be useful in case one of those modules does something it shouldn’t do in the event of an authentication failure. Not all authentication stacks take this precaution, though.
Some login configuration files are structured very differently from the one shown in Listing One. Many call pam_unix.so rather than pam_unix2.so (the latter is a variant of the former) and many arrange the order of their calls differently. Some distributions favor the use of required, whereas others use requisite more often.

Using the pam_stack.so Module

Many distributions make heavy use of the pam_stack.so module. Listing Two shows a typical login configuration that employs this module, taken from a Gentoo system (with slight modifications for clarity).
Listing Two: A sample login PAM configuration file using pam_stack.so


auth required pam_securetty.so
auth required pam_stack.so \
auth required pam_nologin.so

account required pam_stack.so \

password required pam_stack.so \

session required pam_stack.so \
session optional pam_console.so

This configuration replaces calls to pam_unix.so or pam_unix2.so with a call to pam_stack.so, passing that module the name of a configuration file via the service option. This file, in turn, describes the modules that should be called for each stack, as shown in Listing Three.
Listing Three: A sample system-auth PAM configuration file


auth required pam_env.so
auth required pam_unix.so likeauth nullok

account required pam_unix.so

password required pam_cracklib.so retry=3
password required pam_unix.so nullok md5 \
shadow use_authtok

session required pam_limits.so
session required pam_unix.so use_first_pass

In practice, the pam_stack.so module returns success or failure depending on the success or failure result of the modules defined in its configuration file (typically system-auth). If you’re configuring only one service, chances are this approach would have no benefits; however, if your system is typical, it runs quite a few services that employ PAM. Changing all of them when you add an authentication tool that should be used by all can be tedious and is potentially error-prone. Having all of the services call one module that can be independently configured simplifies matters.
You may notice, though, that Listing Two calls modules other than pam_stack.so. The reason is that you may have cause to customize the modules called for specific services.
For instance, the login file shown in Listing Two calls pam_nologin.so after calling pam_stack.so. The pam_nologin.so module blocks non- root logins when the /etc/nologin file is present, which is a security measure you might employ on a server for shell logins, but not for Post Office Protocol (POP) email retrieval, to name just one example. Thus, putting this call in the file for the login service itself rather than in system-auth makes sense.

Adding a Network Authentication Tool

One common type of PAM configuration change is adding a network authentication tool, such as modules to enable a Linux system to authenticate users with the help of an LDAP server or a Windows NT domain controller. (The February 2005 “Guru Guidance” column, available at http://www.linux-mag.com/2005-02/guru_01.html, covered NT domain authentication in more detail.) To begin making such a change, you should first determine whether or not your system uses the pam_stack.so module. If it doesn’t, you should make your changes directly to the files for the login services you want to employ the new authentication tool. This may mean changing just one or two files or several. On the other hand, if your system currently uses pam_stack.so, you have a choice of implementing changes piecemeal (thus enabling you to control which services use the new authentication tool) or by editing the /etc/pam.d/system-auth file to affect all authentication services.
To add a new authentication tool, you must add a reference to its module to the relevant stack or stacks. The auth stack is the one that most obviously must be modified, but the account stack is also important for authentication. If you’re modifying a system-auth file, you may also want to add references to the new module to that file’s session and password stacks. Alternatively, you could modify the configuration files for tools that should be able to use these services from the new protocol, such as the passwd file for the passwd utility.
The big question, though, is how you should modify the stack. Details vary depending on how your system is currently configured and how you want the new system to behave. Generally speaking, though, you should do several things:
*Add the new module reference just before the existing one (pam_unix.so or pam_unix2.so).
*Make the reference to the new module sufficient. This way, if it works, authentication succeeds and the stack stops executing, bypassing the old authentication method. If the new module fails, the old one is still called. This is handy for accounts that should be managed locally, such as root.
*Add the try_first_pass or use_first_pass option to the old (pam_unix.so or pam_unix2.so) module. This prevents the system from displaying a double password prompt in the event the user isn’t listed in the new authentication tool.
As an example, consider Listing Three’ s auth stack. You could modify it to call the pam_ldap.so stack (for authenticating against an LDAP server) as follows:
auth required pam_env.so
auth sufficient pam_ldap.so
auth required pam_unix.so likeauth \
nullok try_first_pass
Because this is a system-auth configuration, it applies to all programs that rely on PAM for authentication. The new system tries LDAP authentication first. If it succeeds, the pam_stack.so module succeeds and pam_unix.so isn’t called; if LDAP authentication fails, pam_unix.so is called, and its outcome determines the success of the pam_stack.so module.
One tricky point relates to stacks, such as the auth stack shown in Listing One, in which important supplemental modules appear after the call to the original authentication module. If you follow the procedure just outlined, authentication continues to work as intended for local authentication; however, if the new authentication module succeeds, its sufficient nature means that the supplemental modules Are bypassed. You can work around this problem in a couple of ways:
*Move the supplemental modules to appear before the actual authentication modules. This often works, but changing the order might have some undesirable consequences. Try to check for correct functioning of all of these modules in the cases of both successes and failures by both authentication tools.
*Replace the call to pam_unix.so or pam_unix2.so with a call to pam_stack.so and implement a system-auth file that calls both the old and the new authentication module. The advantage of this option is that it causes both authentication modules to operate in unison, returning a single response code to the main stack, which can simplify configuration. Actually implementing this change requires more work, though.
In any event, you should remember to change both the auth and the account stacks for tools that use PAM mainly for authentication (login, pop, sshd, xdm, gdm, and so on). Other tools, such as the passwd configuration, require other changes instead of or in addition to these stacks.
You should also be aware that changes such as these may require additional non-PAM changes to your system. Most notably, you may need to modify your Name Service Switch (NSS) configuration, which verifies the existence of the account. How to do this depends on the network authentication tool you’re using.

Adding Useful Login Modules

Another type of PAM modification doesn’t change the login authentication at all; instead, it involves adding modules that perform extra tasks. Last month’s column summarized several of these modules, which perform various useful tasks such as creating user home directories and performing password strength checks.
Adding such a module is usually fairly straightforward: drop it into the existing stack. (Be sure to put it in the correct stack, though; some work only in certain stacks.) In most cases, you configure these modules as required. Modules that aren’t designed to grant or deny users access to the system typically return success codes in all cases, so a required code won’t cause spurious login failures.
Should you add an extra module before or after the actual authentication modules? In most cases, either placement works, at least if you’ve got just one authentication module. Placing supplementary modules before authentication modules can be helpful if you’ve got multiple authentication modules, one of which is marked as sufficient, as described earlier.

Special Considerations for Password Stacks

Password services, such as passwd, deserve a bit more coverage. Typically, when adding a new authentication method, you must modify the auth, account, and password stacks in passwd. The auth and account stacks are required to gain access to the password-setting feature — that is, they control the authentication in which you enter your existing password. Thus, the changes to these stacks are as described earlier.
Changes to the password stack are a bit different. Specifically, you typically add a new line for the new service, as with the changes to the auth and account stacks, but you should make the new entry optional rather than sufficient. This results in a configuration in which password changes succeed even for users who are defined locally but not on the remote server. You should leave the default (pam_unix.so or pam_unix2.so) line as is (except for adding the use_first_pass option, if it’s not already present); although you might think its required nature would cause problems for accounts that don’t exist locally, it doesn’t.

Roderick W. Smith is the author or co-author of over a dozen books, including Linux in a Windows World and Linux Power Tools. He can be reached at class="emailaddress">rodsmith@rodsbooks.com.

Comments are closed.