Book Image

Pluggable Authentication Modules: The Definitive Guide to PAM for Linux SysAdmins and C Developers

By : Kenneth Geisshirt
Book Image

Pluggable Authentication Modules: The Definitive Guide to PAM for Linux SysAdmins and C Developers

By: Kenneth Geisshirt

Overview of this book

<p>PAM-aware applications reduce the complexity of authentication. With PAM you can use the same user database for every login process. PAM also supports different authentication processes as required. Moreover, PAM is a well-defined API, and PAM-aware applications will not break if you change the underlying authentication configuration.<br /><br />The PAM framework is widely used by most Linux distributions for authentication purposes. Originating from Solaris 2.6 ten years ago, PAM is used today by most proprietary and free UNIX operating systems including GNU/Linux, FreeBSD, and Solaris, following both the design concept and the practical details. PAM is thus a unifying technology for authentication mechanisms in UNIX. <br /><br />PAM is a modular and flexible authentication management layer that sits between Linux applications and the native underlying authentication system. PAM can be implemented with various applications without having to recompile the applications to specifically support PAM.</p>
Table of Contents (13 chapters)

Vault – Secure Database


The vault program is an example of a PAM-aware application. It provides access to a small database where users can store key/value pairs. The database behind vault is the GNU dbm, and it is not a sophisticated usage of it. The program is somewhat dependent on Linux-PAM due to the fact that the program uses the conversation function provided by Linux-PAM.

/*
 * vault.c - access to a secure data vault
 *
 * Kenneth Geisshirt <http://kenneth.geisshirt.dk/>
 *
 */

#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <stdio.h>
#include <unistd.h>
#include <gdbm.h>
#include <sys/types.h>
#include <sys/stat.h>

static struct pam_conv conv = {
  misc_conv,
  NULL
};


int main(int argc, char *argv[]) {

  pam_handle_t *pamh = NULL;  /** PAM data structure **/
  int retval;
  GDBM_FILE dbh;
  datum key, data;
  int flags;

  char *user = getlogin();

  /** Creating and initializing a PAM session **/
  retval = pam_start("vault", user, &conv, &pamh);
  if (retval == PAM_SUCCESS) 
    /** Authenticate user **/
    retval = pam_authenticate(pamh, 0);

  if (retval == PAM_SUCCESS) {
    dbh = gdbm_open("vault.db", 512, GDBM_WRCREAT, S_IREAD|S_IWRITE, NULL); 
    
    if (argc == 3) {
      key.dptr = strdup(argv[1]);
      key.dsize = strlen(argv[1])+1;
      data.dptr = strdup(argv[2]);
      data.dsize = strlen(argv[2])+1;
      gdbm_store(dbh, key, data, GDBM_REPLACE);
    } else {
      key.dptr = strdup(argv[1]);
      key.dsize = strlen(argv[1])+1;
      data = gdbm_fetch(dbh, key);
      printf("%s:%s\n", key.dptr, data.dptr);
    }
    gdbm_close(dbh);
  } 

  fprintf(stderr, "%s\n", pam_strerror(pamh, retval));

  /** Destroy the PAM session **/
  pam_end(pamh, retval);
}