#include <stdio.h> /* PAM definitions for applications */ #include <security/pam_appl.h> /* Linux-PAM specific application helper library contains sample text based conversation function. */ #include <security/pam_misc.h> /* * static data for application */ /* PAM handle for continuity with library */ static pam_handle_t *pamh=NULL; static struct pam_conv login_conversation = { /* example conversation function in * libpam_misc */ misc_conv, /* trivial application specific data */ NULL }; /* this function is used to terminate the * application. */ static void Failed(int pam_error) { /* textual error */ fprintf(stderr,"Sorry: %s\n", pam_strerror(pam_error)); if (NULL != pamh) /* shutdown PAM */ pam_end(pamh, pam_error); /* exit with error */ exit(1); } /* * login-type application */ void main() { /* keep track of PAM errors */ int retval; /* to refer to user's name */ const char *username=NULL; /* PAM environment variable list */ const char * const *environment=NULL; /* login function to initialize terminal etc */ Login_Initialize(); /* * Initialize libpam; library silently * consults /etc/pam.conf and loads * the appropriate authentication modules */ retval = pam_start("login", username, &login_conversation, &pamh); if (NULL == pamh || PAM_SUCCESS != retval) /* something went wrong */ Failed(retval); /* default prompt */ pam_set_item(pamh, PAM_USER_PROMPT, "login: "); /* * attempt authentication until the modules * become exhausted or we succeed */ do { /* delay for failures */ pam_fail_delay(pamh, 1000000 /* usec */); /* require entered username */ pam_set_item(pamh, PAM_USER, NULL); /* attempt to authenticate user */ retval = pam_authenticate(pamh, 0); if (PAM_MAXTRIES == retval) /* the modules do not want login to * retry */ Failed(retval); } while (PAM_SUCCESS != retval); /* * The user has been authenticated. Check if * they are allowed to login at this time with * the account management.. */ retval = pam_acct_mgmt(pamh, 0); switch (retval) { /* user's password(s) need renewing */ case PAM_AUTHTOKEN_REQD: retval = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); if (PAM_SUCCESS == retval) /* password safely updated */ break; default: Failed(retval); } /* * open a PAM session for the user */ retval = pam_open_session(pamh, 0); /* * Establish the user's credentials */ /* build the user's environment */ pam_putenv(pamh, "SYSTEM=Linux"); /* obtain username from PAM */ pam_get_item(pamh, PAM_USER, &username); /* set login specific user identity (initgroups etc..) */ Initialize_User(username); /* PAM specific credentials */ pam_setcred(pamh, PAM_CRED_ESTABLISH); /* * invoke user shell and wait for it to * terminate */ /* get environment from PAM */ environment = pam_getenvlist(pamh); /* run interactive user shell */ Do_User_Session(username, environment); /* * The user has finished interacting with the * system. Tidy up. */ /* drop user credentials */ pam_setcred(pamh, PAM_CRED_DELETE); /* close PAM session */ pam_close_session(pamh, 0); /* close the library */ pam_end(pamh, PAM_SUCCESS); /* to avoid potential confusion */ pamh = NULL; /* exit successfully */ exit(0); }