Recipe 4.1 Creating a PAM-Aware Application

4.1.1 Problem

You want to write a program that uses PAM for authentication.

4.1.2 Solution

Select (or create) a PAM configuration in /etc/pam.d. Then use the PAM API to perform authentication with respect to that configuration. For example, the following application uses the su configuration, which means every user but root must supply his login password:

#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <pwd.h>
#include <sys/types.h>
#include <stdio.h>
#define MY_CONFIG "su"
static struct pam_conv conv = { misc_conv, NULL };

main( )
  pam_handle_t *pamh;
  int result;
  struct passwd *pw;
  if ((pw = getpwuid(getuid( ))) == NULL)
  else if ((result = pam_start(MY_CONFIG, pw->pw_name, &conv, &pamh)) != PAM_SUCCESS)
    fprintf(stderr, "start failed: %d\n", result);
  else if ((result = pam_authenticate(pamh, 0)) != PAM_SUCCESS)
    fprintf(stderr, "authenticate failed: %d\n", result);
  else if ((result = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS)
    fprintf(stderr, "acct_mgmt failed: %d\n", result);
  else if ((result = pam_end(pamh, result)) != PAM_SUCCESS)
    fprintf(stderr, "end failed: %d\n", result);
    Run_My_Big_Application( );            /* Run your application code */

Compile the program, linking with libraries libpam and libpam_misc:

$ gcc myprogram.c -lpam -lpam_misc

4.1.3 Discussion

The PAM libraries include functions to start PAM and check authentication credentials. Notice how the details of authentication are completely hidden from the application: simply reference your desired PAM module (in this case, su) and examine the function return values. Even after your application is compiled, you can change the authentication behavior by editing configurations in /etc/pam.d. Such is the beauty of PAM.

4.1.4 See Also

pam_start(3), pam_end(3), pam_authenticate(3), pam_acct_mgmt(3). The Linux PAM Developer's Guide is at

    Chapter 9. Testing and Monitoring