Securing Applications on Linux with PAM

The basic concepts of PAM (Pluggable Authentication Module), developing a PAM-enabled application, a PAM authentication module and writing the PAM configuration file.
Setting the User Credentials

Generally, an authentication module may have access to more information about a user than what is contained in their authentication token. The pam_sm_setcred function is used to make such information available to the application. A basic implementation of the pam_sm_setcred is shown in Listing 3. In this sample implementation of this function, we simply make available to the application the return code of the call to pam_sm_authenticate().

Listing 3. A Basic Implementation of pam_sm_setcred

Conversing with the Application

The converse() function acts as a front end for module-application conversations. A sample implementation of converse() is shown in Listing 4.

Listing 4. A Sample Implementation of converse()

The pointer to the conversation function is obtained using pam_get_item(pamh,PAM_CONV,&item). Using the pointer, the module now can start communicating directly with the application.

Taking Care of Statically Loaded Modules

Modules may be statically linked to libpam. In fact, this should be true of all the modules distributed with the basic PAM distribution. To be statically linked, a module needs to export information about the functions it contains in a manner that does not clash with other modules.

The extra code necessary to build a static module should be delimited with #ifdef PAM_STATIC and #endif. The static code should define a single structure, struct pam_module. This is called _pam_modname_modstruct, where modname is the name of the module used in the filesystem, minus the leading directory name (generally /usr/lib/security/) and the suffix (generally .so).

#ifdef PAM_STATIC
struct pam_module _pam_unix_auth_modstruct = {
    "pam_unix_auth",
    pam_sm_authenticate,
    pam_sm_setcred,
    NULL,
    NULL,
    NULL,
    NULL,
};
#endif

Now our module is ready to be compiled as static or dynamic. Compile the module using the following command:

gcc -fPIC -c pam_module-name.c
ld -x --shared -o pam_module-name.so pam_module-name.o

Securing the Application: the PAM Configuration File

The local configuration of those aspects of system security controlled by Linux-PAM is contained in one of two places, either the single system file (/etc/pam.conf) or the /etc/pam.d/ directory.

A general configuration line of the /etc/pam.conf file has the form: service-name module-type control-flag module-path arguments.

We can also specify the PAM configuration for an application in a separate file in the /etc/pam.d folder, in which case the configuration file has the form: module-type control-flag module-path arguments. The service-name becomes the name of the configuration file. Frequently the service-name is the conventional name of the given application, for example, azServer.

Module Type

Four module types exist: auth, account, session and password.

  • auth: determines whether the user is who he claims to be, usually done with a password, but may be determined by a more sophisticated means, such as biometrics.

  • account: determines whether the user is allowed to access the service, whether his passwords have expired and so on.

  • password: provides a mechanism for the user to change his authentication token. Again, this is usually his password.

  • session: things that should be done before and/or after the user is authenticated. This might include things such as mounting/unmounting the user home directory, logging the login/logout and restricting/unrestricting the services available to the user.

In addition, there are four control flags: required, requisite, sufficient and optional.

  • Required: indicates that the success of the module is required for the module-type facility to succeed. Failure of this module will not be apparent to the user until all of the remaining modules (of the same module type) have been executed.

  • Requisite: same as required, except that in the case of a module failure, it directly returns the result to the application.

  • Sufficient: if this module has succeeded and all previous required modules have succeeded, then no more subsequent required modules are invoked.

  • Optional: marks the module as not critical to the success or failure of the user's application for service. Its value is taken into consideration only in the absence of any definite successes or failures of previous or subsequent stacked modules.

The pathname of the dynamically loadable object file (the pluggable module itself) is the module path. If the first character of the module path is /, it is assumed to be a complete path. If this is not the case, the given module path is appended to the default module path, /usr/lib/security.

The arguments are a list of tokens passed to the module when it is invoked, much like arguments to a typical Linux shell command. Generally, valid arguments are optional and specific to any given module.

Finally, to write the configuration file, edit the /etc/pam.conf file to add the following line of code:

check_user  auth  required  /lib/security/pam_unix.so

This indicates that for the service-names, check_user and auth module-type are required. The module to be loaded to support this authentication method is pam_unix.so, which is found in the directory /lib/security/.

Resources

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

getPassword function is incorrect

prashanth's picture

Hi
your getPassword function is incorrect

while((i = getch()) != '\n')
buf[i++] = i;
is incorrect

Very crisp and to the point.

Sunil's picture

Very crisp and to the point. Great work !

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState