rendered paste body#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <string.h>#include <sys/ioctl.h>#include <linux/vt.h>#include <errno.h>#include <fcntl.h>#define PAM_SM_AUTH#define PAM_SM_ACCOUNT#define PAM_SM_SESSION#define PAM_SM_PASSWORD#include <security/pam_modules.h>#include <security/_pam_macros.h>#define AUTH_DIR "/var/run/console"#define DATANAME "pam_foreground_console_file"static voidcleanup(pam_handle_t *pamh, void *filename, int err){ unlink((char *)filename); free(filename); filename = NULL;}/* --- authentication management functions --- */PAM_EXTERN intpam_sm_authenticate(pam_handle_t *pamh, int flags , int argc , const char **argv ){ return PAM_SUCCESS;}PAM_EXTERN intpam_sm_setcred(pam_handle_t *pamh , int flags , int argc , const char **argv ){ return PAM_SUCCESS;}/* --- account management functions --- */PAM_EXTERN intpam_sm_acct_mgmt(pam_handle_t *pamh , int flags , int argc , const char **argv ){ return PAM_SUCCESS;}/* --- password management --- */PAM_EXTERN intpam_sm_chauthtok(pam_handle_t *pamh , int flags , int argc , const char **argv ){ return PAM_SUCCESS;}/* --- session management --- */PAM_EXTERN intpam_sm_open_session(pam_handle_t *pamh , int flags , int argc , const char **argv ){ const char *user=NULL; struct stat finfo; char *filename; unsigned short console; int fd; struct vt_stat vtstat; size_t len; int retval; retval = pam_get_user(pamh, &user, NULL); if (retval != PAM_SUCCESS) { D(("get user returned error: %s", pam_strerror(pamh,retval))); return retval; } if (stat (AUTH_DIR, &finfo)) { if (errno != ENOENT) { D(("Can't access %s - %s\n", AUTH_DIR, strerror(errno))); goto fail; } else { if (mkdir(AUTH_DIR, 0755)) { D(("Can't mkdir %s - %s\n", AUTH_DIR, strerror(errno))); goto fail; } stat (AUTH_DIR, &finfo); } } /* Check that it's a directory */ if (!S_ISDIR(finfo.st_mode)) { D(("%s isn't a directory\n",AUTH_DIR)); goto fail; } fd = open("/dev/console", O_RDWR); if (fd < 1) { D(("Can't open console - %s\n",strerror(errno))); goto fail; } if (ioctl(fd, VT_GETSTATE, &vtstat)) { D(("ioctl failed - %s\n",strerror(errno))); goto fail; } close (fd); console = vtstat.v_active; if (console > 99) { D(("Console number too large\n")); goto fail; } len = strlen(user); len += strlen(AUTH_DIR); len += 5; filename = malloc(sizeof(char) * len); if (filename == NULL) { D(("Malloc failed\n")); goto fail; } sprintf(filename,"%s/%s:%d",AUTH_DIR,user,console); fd = open(filename,O_CREAT|O_WRONLY|O_EXCL,0644); if (fd < 1) { D(("Can't open %s - %s\n",filename,strerr(errno))); goto free; } /* HURRAH WE GET THERE IN THE END */ close(fd); /* Store the damn thing */ if (pam_set_data(pamh, DATANAME, (void *) filename, cleanup) != PAM_SUCCESS) { D(("Can't store data\n")); goto remove; } user = NULL; return PAM_SUCCESS; remove: unlink(filename); free: free(filename); close(fd); fail: user = NULL; return PAM_SESSION_ERR;}PAM_EXTERN intpam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv){ /* If errors happen here, we're screwed. So. */ void *filename; if (pam_get_data(pamh, DATANAME, (const void **) &filename) == PAM_SUCCESS) { unlink((char *)filename); } return PAM_SUCCESS;}