Writing PAM Modules, Part Twoby Jennifer Vesperman
PAM stands for Pluggable Authentication Modules, and is a way of 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 Two of a three-part article on writing PAM modules. Part One discussed the background information needed to write modules, and Part Three discusses the critical functions the module must supply. This part discusses the support code a module author will need to use.
Packages and Files
These articles describe a C++ application because most large-scale application development is in that language, and its differences from the C language, while distinct, are not extreme. You can develop a Linux-PAM capable module in any language, provided you can call the necessary C functions.
To start with, you'll need the development files. In a Debian system,
apt-get install libpam0g-dev. This installs the relevant source files in the right places for g++ to find them.
You will need to #include <security/pam_modules.h>.
When compiling, you'll need to link against the
libpam files. My
g++ -omodule_name -lpam sourcefile.
In case the module is linked statically, the four module types need to be #defined before security/pam_modules.h is #included.
#define PAM_SM_ACCOUNT #define PAM_SM_AUTH #define PAM_SM_PASSWORD #define PAM_SM_SESSION
Setting and Getting PAM Items
Most of the information a module needs can be found or passed through PAM items. These items are related to a specific PAM session, which is identified with a PAM handle. The PAM handle is passed to each of the module's major functions as a parameter.
pam_get_item() functions to store or retrieve PAM items.
extern int pam_set_item(pam_handle_t *pamh, int item_type, const void *item);
extern int pam_get_item(const pam_handle_t *pamh, int item_type, const void **item);
The available PAM item types can be arranged into groups.
About the application:
- The PAM name of the application, not necessarily the name the user sees.
- The conversation structure. (See the next section.)
- The pointer to the
PAM_FAIL_DELAYfunction. Some applications replace the default PAM version.
About the user:
- The username to be authenticated against. It is usually safer to use
pam_get_user()rather than asking for this directly.
- The prompt the module should use if asking for a username.
- The user requesting authentication, usually the username of the user calling the application.
About the machine:
- The hostname of the machine requesting authentication.
- The terminal name (console-based apps) or
$DISPLAY(GUI based apps). You can retrieve the terminal name with
- The authentication token. This should be ignored by anything other than authentication and password changing modules, and only used in the functions
- The previous authentication token. This should only be used by
pam_sm_chauthtok()in the password module type.
PAM_SUCCESS, the PAM item functions can return