/* pam_sslmount.so 1.0 * (c) 2003 by Martin Walter * based on pam_storepw by F. Lohoff and pam_pwdfile.c by C. P. Botha * needs external perl program sslmount */ #define PAM_SM_AUTH #include #include #include #include #include #include #include #include #include #include #include #include #define _XOPEN_SOURCE #include /* logging function ripped from pam_listfile.c */ static void _pam_log(int err, const char *format, ...) { va_list args; va_start(args, format); openlog("pam_sslmount", LOG_CONS|LOG_PID, LOG_AUTH); vsyslog(err, format, args); va_end(args); closelog(); } /* expected hook for auth service */ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { char *passwd, *user; int p[2],status; pid_t pid; if (argc < 1 || argv[0][0] != '/') { _pam_log(LOG_ERR,"error: full path to sslmount expected as first argument"); return PAM_AUTH_ERR; } pam_get_item(pamh, PAM_AUTHTOK, (void *) &passwd); pam_get_item(pamh, PAM_USER, (void*) &user); if (!passwd || !user) { _pam_log(LOG_ERR,"no password or user to write - got stacked wrong ?"); return PAM_AUTHINFO_UNAVAIL; } if (pipe(p)) { _pam_log(LOG_ERR,"can't open pipe"); return PAM_AUTHINFO_UNAVAIL; } if (pid=fork()) { close(p[0]); write(p[1],passwd,strlen(passwd)); close(p[1]); if (pid == waitpid(pid,&status,0) && WIFEXITED(status)) { if (WEXITSTATUS(status)) { _pam_log(LOG_ERR,"sslmount failed"); return PAM_AUTH_ERR; } _pam_log(LOG_ERR,"sslmount succeeded"); return PAM_SUCCESS; } _pam_log(LOG_ERR,"waitpid failed"); return PAM_AUTH_ERR; } close(0); dup(p[0]); close(p[0]); close(p[1]); execl(argv[0],argv[0],user,NULL); _pam_log(LOG_ERR,"error: exec of first argument (sslmount) failed"); exit(1); } /* another expected hook */ PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) { return PAM_SUCCESS; } #ifdef PAM_STATIC struct pam_module _pam_listfile_modstruct = { "pam_pwdfile", pam_sm_authenticate, pam_sm_setcred, NULL, NULL, NULL, NULL, }; #endif