Writing PAM Modules, Part Three

PAM stands for Pluggable Authentication Modules and is a system for providing application independence for authentication. A PAM-enabled application calls a stack of PAM modules to run authentication, open and close sessions, and check account validity.

This is part three of a three-part series on writing PAM modules.
Part one discussed the background information needed to write modules. Part two covered supporting code, including the conversation structure.

PAM modules are grouped into four module types, though there are six critical functions. Applications call each of the functions as they need them, but system administrators can only choose functions by their module type.

Required Functions

An application needs to completely fulfil the requirements for at least one of the module types. It should, but is not required to, respond to a request for the other module types with PAM_SERVICE_ERR or PAM_IGNORE.

The four types are: account, authentication, password, and session.

All of these functions have a flag parameter. The PAM_SILENT flag is valid for any function, and tells the module not to pass any text errors or warnings to the application. Flags may be logically ORed together.

Account

This module type establishes whether the user can gain access at this time. The module should assume that the user has previously been authenticated. The module may verify whether or not a password has expired, and may return PAM_NEW_AUTHTOK_REQD if it has.

The flag PAM_DISALLOW_NULL_AUTHTOK tells the module to check whether or not there is a NULL authentication token in the token database. If so, return PAM_AUTH_ERR.

If the module succeeds, it should return PAM_SUCCESS. Other valid responses are:

PAM_ACCT_EXPIRED

PAM_AUTH_ERR

PAM_NEW_AUTHTOK_REQD

PAM_USER_UNKNOWN

Authentication

User Validation

The first part of an authentication module is the actual user validation.

The flag PAM_DISALLOW_NULL_AUTHTOK tells the module to check whether or not there is a NULL authentication token in the token database. If so, return PAM_AUTH_ERR. Without this flag, the module can return PAM_SUCCESS in these cases without prompting the user for a token.

If the module succeeds, it should return PAM_SUCCESS. Other valid responses are:

PAM_AUTH_ERR

PAM_AUTHINFO_UNAVAIL

PAM_CRED_INSUFFICIENT

PAM_MAXTRIES

PAM_USER_UNKNOWN

Credential Setting

The second part of authentication is setting the user's credentials. Such credentials may be a Kerberos ticket, or Unix group membership. Only set credentials that are appropriate to the module you're writing.

If the module succeeds, it should return PAM_SUCCESS. Other valid responses are:

PAM_CRED_ERR

PAM_CRED_EXPIRED

PAM_CRED_UNAVAIL

PAM_USER_UNKNOWN

Password

This module type sets or resets the authentication token. Linux-PAM calls the module twice, once to verify that everything is ready and once to change the token itself.

Valid flags:

PAM_CHANGE_EXPIRED_AUTHTOK

User's authentication token should only be changed if it has expired.

PAM_PRELIM_CHECK

This verifies that the module is being asked for a readiness status, to ensure that the module is currently capable of updating the user's authentication token. If not, the module should return PAM_TRY_AGAIN.