Configuring PAM, Part One

Start using the Pluggable Authentication Modules(PAM) system to manage login authentication. (You can also read http://www.linux-mag.com/2000-06/guru_01.html.)
Most Linux administrators pay little attention to the Pluggable Authentication Modules(PAM) system. It’s one of those nebulous things that never gives you cause to investigate it further. In a way, that’s a tribute to PAM: it does what it was designed to do well enough that it causes few headaches in a standard configuration.
Still, PAM is an important part of Linux authentication. It handles password verification, and the pluggable and modules parts of its name mean that you can change how your system authenticates users by plugging in new PAM modules. This is a powerful capability that lets you to tie Linux to a Lightweight Directory Access Protocol (LDAP) server, a Windows NT domain controller, or many other network or alternative local authentication systems, without reconfiguring all of your login servers.
Unfortunately, PAM’s configuration can be a bit tricky. PAM is usually set up in a way that works in default distribution configurations, but changing those configurations can create unexpected problems. That’s where this column comes in. This month, let’s look at the format of the PAM configuration files, the nature of PAM module stacks, common PAM modules, and common PAM module options. Next month’s column will continuethe discussion, presenting several example configurations and describing how to change them while avoiding the pitfalls that lurk for the unwary.[ To find more about PAM, you can also read http://www.linux-mag.com/2000-06/guru_01.html.]

The Role of PAM

Before proceeding further, you should understand just what PAM is and why you might want to adjust your PAM configuration. As already noted, PAM is part of the system’s authentication procedure. In the old days, every program that needed to authenticate users would accept a password, encrypt it, read the password file /etc/passwd, and compare the encrypted password the user provided to the encrypted password stored in /etc/passwd. If the two matched, access was granted; otehrwise, access was denied.
This approach had several problems. For one thing, /etc/passwd had to be world-readable for non-authentication purposes, so storing passwords in it was a major risk. Today, passwords are usually stored in shadowed form, which means they’re kept out of /etc/passwd and in /etc/shadow in Linux. (PAM actually plays a role in this, but non-PAM solutions could do the job, as well.)
Another problem with the traditional approach is that all of the programs that authenticate users had to agree on a common method, such as the encryption algorithm used to encrypt passwords and the file in which they’re stored. If you wanted to change these details, you’d have to update all of the programs that interact with passwords– login, sshd, passwd, xdm, Samba, and many more. Needless to say, this could be a real problem.
Enter PAM. It serves as a buffer between the authentication methods and the programs that do the authentication. The programs need only call PAM, and PAM takes care of the details. Thus, to change your authentication procedures, you need only change PAM; the programs that accept passwords need not be altered. In fact, PAM’s modular nature means that you can add new modules to add authentication methods at any time without changing the core PAM software.
This design provides a great deal of flexibility. As they say, though, the devil is in the details, and PAM’s flexibility means that it has a lot of details. These details can interact in odd ways that can cause a great deal of frustration if you don’t understand them.

PAM Configuration Files

Most modern Linux distributions use files in /etc/pam.d/ to configure PAM. Each file in this directory is named after the program that it serves. Packages can provide default PAM configuration files, and you can tweak the configurations to choose specific authentication techniques for individual protocols. For instance, you could use local authentication tools for su but access an LDAP server for SSH logins.
The purpose of the configuration files is to create one or more module stacks that are used for each program. A module stack is a series of PAM modules that are called to service a particular program’s PAM interactions. Each module performs one specific task, such as verifying a password against a network server or checking whether a user has new mail. Modules can also be used to execute non-authentication tasks as part of the login procedure, which can sometimes be a convenience.
The format of the /etc/pam.d/* configuration files consists of a series of lines, each with four fields:
management_group control_flag module[options]
Each of these fields has a specific meaning:
*management_group holds a code identifying the type of PAM service it controls: auth for authentication (verifying a password, typically), account for account management (non-password account access rules, such as checking whether the user is permitted to use the requested service), session for session management (housekeeping tasks associated with logging in or out), or password for password maintenance (changing the password, for instance).
*control_flag field describes how PAM should react to the module’s return codes. Possible values are requisite, required, sufficient, and optional. These values are described in more detail shortly, in “PAM Module Stacks.”
*The third field, module, is the filename of the module, either alone or as a complete path. If a complete path isn’t provided, PAM usually looks in /lib/security/ for its modules. Some common modules are described shortly, in “Common PAM Modules.”
*options is optional, and contains options that are passed to modules. These are described shortly, in “Common Module Options.”
Most PAM-using services have their own PAM configuration files, and to change how all of these PAM clients respond, you must change the configuration files for all of them. One file deserves special attention, though: /etc/pam.d/system-auth. This file defines a set of standard module stacks that can be called via the pam_stack.so module. The intent is to provide a sort of one-stop-shopping for PAM changes. by altering system-auth, you change how most or all of your services respond, which greatly simplifies configuration. Not all distributions use this configuration by default, but many (including Fedora, Gentoo, Mandrake, and Red Hat) do.
Older systems often used a single /etc/pam.conf configuration file. This file worked just like the /etc/pam.d/ configuration files, except that every line in the file had a leading entry to identify the program to which the configuration applied. Because this setup is quite rare today, it’s not described here, but if you run across an old system that uses it, you can still modify it much as you’d modify a modern system– just add that extra column in the configuration file.

PAM Module Stacks

A PAM configuration file consists of a series of module stacks, which are collections of modules in the same managment group. When a program asks for the type of help handled by the management group, PAM calls each module in turn, and ultimately returns a code depending on the return value of each module and the control_flag value associated with each module.
For instance, a typical auth stack looks like this:
auth required pam_env.so
auth required pam_unix.so likeauth nullok
The presence of this module stack in a service’s configuration means that the pam_env.so and pam_unix.so modules are called, in turn, whenever PAM is asked to authenticate a user. Each of these modules has its own specific task to perform, as described shortly.
Each module in a stack returns a success or failure code. These codes interact with the module’s control flag (required for both of the modules in the preceding example) to influence the stack’s final result, as summarized in Table One.
Table One: Module Control Flags and Return Codes
Control Flag Success Result Failure Result
requisite Stack continues to execute Stack immediately terminates in failure
required Stack continues to execute Stack continues to execute, but terminates in failure
sufficient Stack immediately terminates in success, unless a prior required module has failed Stack continues to execute
optional Stack continues to execute Stack continues to execute, and fails only if other modules are missing or give inconclusive results
Ideally, the outcome of the different modules won’t conflict. If they do, the rules can be confusing. For instance, suppose you want to configure the computer to authenticate users using either the local password database (interpreted by pam_unix.so) or via a Kerberos server (interpreted by pam_krb5.so). You might try modifying the earlier example stack to create a stack like this:
auth  required    pam_env.so
auth required pam_unix.so likeauth nullok
auth sufficient pam_krb5.so try_first_pass
(This stack also includes the pam_env.so and pam_deny.so modules, which you can ignore for now.) This example specifies that the pam_krb5.so module is sufficient, the goal being to enable logins via the local database if the Kerberos server is down or for accounts that aren’t stored there. The trouble is that the required status of pam_unix.so means that the user must be authenticated locally. This rather defeats the purpose of the exercise, because the Kerberos modulehas no effect. To work as desired, you must set both of these modules to sufficient:
auth  required    pam_env.so
auth sufficient pam_unix.so likeauth nullok
auth sufficient pam_krb5.so try_first_pass
The trouble then is that, when either module succeeds, it bypasses any subsequent modules. In this example, none are present, but some default configurations include extra modules in their authentication stacks. Sometimes bypassing these subsequent modules isn’t a problem, but sometimes it is. (Next month’s column presents working PAM configurations that use multiple authentication methods.)
Most services that use PAM require the help of multiple stacks. Typical login services use the auth, account, and session stacks, and some even define at least one password module. Depending on your goal, you might need to change just one stack or many.

Common PAM Modules

PAM ships with a wide variety of modules that help implement many features. In addition, some programs ship with their own PAM modules to extend PAM’s features. Most modules work with more than one management group; they perform one task when called as part of one stack and another task when called as part of another management group stack.
Table Two summarizes some of the more important standard PAM modules. This list is far from comprehensive, though.
Table Two: Common PAM Modules
Module filename Management groups Effect
pam_unix.so auth, account, session, and password Authenticates users based on their /etc/passwd and /etc/shadow file entries.
pam_unix2.so auth, account, session, and password A variant of pam_unix.so with some extra features.
pam_securetty.so auth Blocks root logins unless the PAM_TTY environment variable is set to a string in the /etc/securetty file.
pam_env.so auth Sets environment variables from the /etc/security/pam_env.conf file.
pam_mail.so auth and session Checks for mail in the directory specified by the dir= directory option and informs the user of the result.
pam_lastlog.so auth Displays information on the user’s last login.
pam_deny.so auth, account, session, and password Always indicates a failure. This is useful in certain stack designs to block logins when earlier modules return ambiguous results.
pam_limits.so session Places limits on a user’s CPU use, memory consumption, and so on, based on the contents of the /etc/security/limits.conf file.
pam_mkhomedir.so session Creates a home directory for the user, if one doesn’t already exist. Handy when login users are authenticated using a network login server.
pam_pwcheck.so password Checks the password using rules in /etc/login.defs to improve security on user password changes.
pam_cracklib.so password Checks the password against a dictionary to be sure it’s minimally good.
pam_stack.so auth, account, session, and password Calls the stack in system-auth and returns its results.
If you peruse your PAM configuration files, chances are you’ll see many of these modules. You might also recognize the effects of some of these modules, such as the notice about new mail provided by the pam_mail.so module.

Common Module Options

Most PAM modules accept options, and many of these options are usable on many PAM modules. The more common of these include:
*debug. This option creates extra debugging output, which is typically sent to your system log files.
*try_first_pass. Most auth modules accept this option, which causes the module to try to use the password solicited by a previous module in the stack. If this password doesn’t work, the module displays a new password prompt.
*use_first_pass. This option works much like try_first_pass, except that it does not display a second password prompt if the first password fails; in that case, the module returns a failure code.
*use_authtok. This option enables modules in an auth stack to deliver the password down the line as an authentication token.
*nullok. Ordinarily, modules that deal with passwords refuse empty (null) passwords. This option tells them to accept such passwords.
*shadow. Modules that accept this option respond by paying closer attention to certain shadow password features, such as password aging and expiration data.
For the most part, you should leave the options alone when tweaking your PAM configuration. Sometimes, though, you might want to use a new option, particularly when adding authentication tools. For instance, try_first_pass or use_first_pass is almost always used in conjunction with a second authentication module in an auth stack.

Coming Next Month

This month’s information should help you interpret your existing PAM configurations, and if you’re feeling adventurous, you might try some tweaks. If you do, be sure to test them thoroughly. Be sure to test both correct and incorrect logins, including logins for non-existent accounts! Also, keep a root login active at all times so that you can undo any changes that disable logins on your system.
Next months’ column describes some working configurations, which should help you put all this information to more practical use.

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.