lib/auth_user

Procedure Model

Type:    (  )Web Page              (  )CGI Script              (X)Shared Library      (  )System API

Name: lib/auth_user

Assigned to:

Description

This suid program takes the username and password and returns a 0 if the username and password match the system password for the stated user. Any other return code indicates an error.

Implementation Skills

C, PAM

Parameter List

Username and password as string values

Called By:

user/login.cgi

Can Call:

PAM system libraries

Function Description

Example of a proper function call from a calling PERL script:

output=`/usr/local/csuite/lib/auth_user $user $passwd `;

/*****************************************************
** Library functions to interact with the Linux-PAM  **
** modules in order to update a user's password on   **
** the system.                                       **
**                                                   **
** Make sure you add the following lines to the      **
** pam.conf file (or equivalent):                    **
** cs_password auth     required                     **
**                    /lib/security/pam_unix_auth.so **
** cs_password account  required                     **
**                    /lib/security/pam_unix_acct.so **
** cs_password password required                     **
**                  /lib/security/pam_unix_passwd.so **
** cs_password session  required                     **
**                    /lib/security/pam_unix_acct.so **
**                                                   **
** Author:      Daryle Niedermayer (dpn)             **
**              daryle@gpfn.ca                       **
** Date:        2002-06-17                           **
**                                                   **
******************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <security/pam_appl.h>
#include <security/pam_misc.h>

#define CS_BAD_DATA               -2
#define CS_BAD_USAGE              -1
#define CS_SUCCESS                0

#define COPY_STRING(s) (s) ? strdup(s) : NULL

/* DEFINE STATIC EXTERNAL STRUCTURES AND VARIABLES 
   SO THAT THEY ONLY HAVE SCOPE WITHIN THE METHODS 
   AND FUNCTIONS OF THIS SOURCE FILE */
static char*        service_name = "cs_password";
static char*        user;
static char*        old_password;
static char*        new_password;
static int PAM_conv (int, const struct pam_message**,
                     struct pam_response**, void*);
static struct pam_conv PAM_converse = {PAM_conv, NULL};

/*************************************************
** PAM Conversation function                    **
*************************************************/
static int PAM_conv (
   int num_msg,
   const struct pam_message **msg,
   struct pam_response **resp, void *appdata_ptr) {

   int replies = 0;
   struct pam_response *reply = NULL;

   reply =
      malloc(sizeof(struct pam_response) * num_msg);
   if (!reply) return PAM_CONV_ERR;

   for (replies = 0; replies < num_msg; replies++) {
      if (! strcmp(msg[replies]->msg,"Password: "))
         reply[replies].resp =
            COPY_STRING(old_password);
      if (! strcmp(msg[replies]->msg,
         "(current) UNIX password: "))
         reply[replies].resp =
            COPY_STRING(old_password);
   }

   *resp = reply;
   return PAM_SUCCESS;
}

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

/* DEFINITIONS */
   pam_handle_t*    pamh = NULL;
   int              retval;
   char*            pw_check;
   char*            dict_path = "/usr/lib/cracklib_dict";

/* DETERMINE IF VARIABLE COUNT IS CORRECT */
   if (argc != 3) {
      printf("Usage: auth_user <USER> <PASSWORD>\n");
      exit (CS_BAD_USAGE);
   }

/* PARSE PARAMETERS FROM INPUTS */
   user         = argv[1];        
   old_password = argv[2];

   if (!(user && old_password && strlen(user) && strlen(old_password)))
      exit (CS_BAD_DATA);

/* GET A HANDLE TO A PAM INSTANCE */
   retval = pam_start(service_name, user, &PAM_converse, &pamh);

/* IS THE USER REALLY A USER? */
   if (retval == PAM_SUCCESS)
      retval = pam_authenticate(pamh, 0);
   else return retval;

/* IS USER PERMITTED ACCESS? */
   if (retval == PAM_SUCCESS)
      retval = pam_acct_mgmt(pamh, 0);
   else return retval;

/* CLEAN UP OUR HANDLES AND VARIABLES */
   if (pam_end(pamh, retval) != PAM_SUCCESS)
      pamh = NULL;
   else return retval;
  
   exit (CS_SUCCESS);
}

Possible Exit Conditions and Return Values

This function returns a number of possible values:

  1. CS_BAD_DATA  = -2 is returned if any of the username or passwords are null length strings or do not exist.
  2. CS_BAD_USAGE = -1is returned if an invalid number of parameters is passed to the function.
  3. CS_SUCCESS = 0 is returned if the function successfully authenticated the user with the supplied parameters.
  4. Any other positive integer indicates a PAM error. The meaning of the error value can be determined by referencing the /usr/include/security/_pam_types.h header file.

Sign Off by:

Project Manager