Extending Authentication in the Solaris 9 Operating Environment Using Pluggable Authentication Modules (PAM): Part II
This article is part two of a two-part series. Part one, published in the September issue of Sun BluePrintsTM Online, detailed the benefits of Pluggable Authentication Module (PAM), its components, and the PAM Lightweight Directory Access Protocol (LDAP) module. This article details the PAM application programming interface (API) and the PAM service provider interface (SPI). Also included are procedures on how to effectively write PAM modules when using the SolarisTM 9 Operating Environment (Solaris 9 OE).
By writing these PAM service modules, it is possible to extend the capability of the Solaris 9 OE authentication mechanisms in a number of different ways. The PAM interface in the Solaris 9 OE provides a set of APIs that can be used by third-party applications to extend authentication capabilities. By using the PAM layer, applications authenticate to the system without worrying about what authentication method has been chosen by the system administrator for any given client. For example, it is possible for a system administrator to prevent users from choosing new passwords that resemble their old password.
A PAM module is a shared object that is developed and written using the C programming language. The module is dynamically selected based on the contents of the pam.conf(4) configuration file. This is an extremely efficient mechanism that enables the selection of the most appropriate authentication mechanism for a particular environmentwithout sacrificing functionality or the need to depend on third-party or unsupported software.
Developing a PAM module is not as difficult as you might think. The PAM API has a rich set of features, and is fairly intuitive to learn and use. Online documentation is also available (see http://docs.sun.com).
This article addresses the following topics:
Details of the PAM API
Details of the PAM SPI
Details on how to write a PAM service module
Details on how to test a PAM service module
The PAM API
As presented in Part I, PAM is composed of a number of components including:
PAM API (pam(3PAM)) used by applications to perform authentication and authentication token (password) changes.
PAM framework used to export the API.
PAM SPI (pam_sm(3PAM)) used by the PAM framework to call on behalf of an API request.
PAM service modules (pam_*(5)) used to export the PAM SPI.
The PAM framework, includes the PAM library (libpam.so.1), which consists of an interface library and multiple authentication service modules that are the layer implementing the PAM API.
It is outside the scope of this article to detail every single API and function. However, the most commonly used and well-known APIs are presented here. The PAM API can be grouped into five functional categories:
PAM framework functions
Authentication functions
Account management functions
Session management function
Password management functions
These functions enable an application to invoke the PAM service modules and to communicate information to these modules. The functions are described in the following sections.
PAM Framework Functions
These framework functions are PAM transaction routines for establishing and terminating a PAM session.
pam_start() function takes, as arguments, the name of the application calling PAM, the name of the user to be authenticated, and the address of the callback conversation structure provided by the caller. It returns a handle for use with subsequent calls to the PAM library.
pam_end() function is called to terminate the authentication transaction identified by pamh and to free any storage area allocated by the authentication module. The argument, status, is passed to the cleanup() function stored within the PAM handle, and is used to determine what module-specific state must be purged.
pam_get_item() and pam_set_item() functions are PAM routines that enable both applications and the PAM service modules to access and update common PAM information such as service name, user name, remote host name, remote user name, and so on, from the PAM handle.
TABLE 1 details the items that may be manipulated by these functions.
TABLE 1 Setting PAM Items
Item Name |
Description |
PAM_SERVICE | Service (application) name |
PAM_USER | User name |
PAM_RUSER | Remote user name |
PAM_TTY | TTY name |
PAM_RHOST | Remote host name |
PAM_CONV | pam_conv structure |
PAM_AUTHTOK | Authenticated token |
PAM_OLDAUTHTOK | Old authentication token |
PAM_REPOSITORY | Specifies which repository is to be updated. |
PAM_USER_PROMPT | Prompt the module should use if asking for a username. |
pam_getenv(), pam_getenvlist(), and pam_putenv() functions enable applications and PAM modules to set and retrieve environment variables that are to be used for the user session.
pam_strerror() function returns a textual representation of a PAM error, much like the strerror(3c)error.
PAM Authentication Functions
These authentication functions are used to authenticate the user and the current process.
pam_authenticate() function called to verify the identity of the current user.
pam_setcred() function called to set the credentials of the current process associated with the authentication handle supplied.
Typically, this process is done after the user has been authenticated (after the pam_authenticate() function succeeds).
Account Management Function
This account management function is used to validate the users account information. It typically includes checking for password and account expiration, valid login times, and etc.
pam_acct_mgmt()
Session Management Functions
These session management functions are called on the initiation and termination of a login session.
pam_open_session()
pam_close_session()
The pam_unix_session module implements these calls to update the /var/adm/lastlog information. These functions can also support session auditing.
Password Management Function
This password management function is called to change the authentication token (password) associated with the user.
pam_chauthtok()