int pam_setcred(pam_handle_t *pamh, int flags) { int retval; D(("pam_setcred called")); IF_NO_PAMH("pam_setcred", pamh, PAM_SYSTEM_ERR); if (__PAM_FROM_MODULE(pamh)) { D(("called from module!?")); return PAM_SYSTEM_ERR; } if (! flags) { flags = PAM_ESTABLISH_CRED; } retval = _pam_dispatch(pamh, flags, PAM_SETCRED); #if HAVE_LIBAUDIT retval = _pam_auditlog(pamh, PAM_SETCRED, retval, flags); #endif D(("pam_setcred exit")); return retval; }
int pam_close_session(pam_handle_t *pamh, int flags) { int retval; D(("called")); IF_NO_PAMH("pam_close_session", pamh, PAM_SYSTEM_ERR); if (__PAM_FROM_MODULE(pamh)) { D(("called from module!?")); return PAM_SYSTEM_ERR; } retval = _pam_dispatch(pamh, flags, PAM_CLOSE_SESSION); #if HAVE_LIBAUDIT retval = _pam_auditlog(pamh, PAM_CLOSE_SESSION, retval, flags); #endif #ifdef PAM_STATS if (retval != PAM_SUCCESS) { char usr[MAX_PAM_STATS_USR_SIZE]; char buf[MAX_PAM_STATS_BUF_SIZE]; usr[MAX_PAM_STATS_USR_SIZE-1]='\0'; strncpy(usr,(retval == PAM_USER_UNKNOWN)?"unknown":pamh->user, MAX_PAM_STATS_USR_SIZE-1); memset(buf,'\0',MAX_PAM_STATS_BUF_SIZE); snprintf(buf, MAX_PAM_STATS_BUF_SIZE-1, "statsd -a incr pam_failed_%s %s \\;" " push pam_last_failure_%s %s \"%s\" 0 \\;" " incr pam_users %s\\;" " incr pam_services %s", usr, pamh->service_name, usr, pamh->service_name, pam_strerror(pamh, retval), usr, pamh->service_name); if (system(buf) == -1) { pam_syslog(pamh, LOG_INFO, "%s - failed", buf); } } #endif return retval; }
int pam_acct_mgmt(pam_handle_t *pamh, int flags) { int retval; D(("called")); IF_NO_PAMH("pam_acct_mgmt", pamh, PAM_SYSTEM_ERR); if (__PAM_FROM_MODULE(pamh)) { D(("called from module!?")); return PAM_SYSTEM_ERR; } retval = _pam_dispatch(pamh, flags, PAM_ACCOUNT); #ifdef HAVE_LIBAUDIT retval = _pam_auditlog(pamh, PAM_ACCOUNT, retval, flags); #endif return retval; }
int _pam_dispatch(pam_handle_t *pamh, int flags, int choice) { struct handler *h = NULL; int retval = PAM_SYSTEM_ERR, use_cached_chain; _pam_boolean resumed; IF_NO_PAMH("_pam_dispatch", pamh, PAM_SYSTEM_ERR); if (__PAM_FROM_MODULE(pamh)) { D(("called from a module!?")); goto end; } /* Load all modules, resolve all symbols */ if ((retval = _pam_init_handlers(pamh)) != PAM_SUCCESS) { pam_syslog(pamh, LOG_ERR, "unable to dispatch function"); goto end; } use_cached_chain = _PAM_PLEASE_FREEZE; switch (choice) { case PAM_AUTHENTICATE: h = pamh->handlers.conf.authenticate; break; case PAM_SETCRED: h = pamh->handlers.conf.setcred; use_cached_chain = _PAM_MAY_BE_FROZEN; break; case PAM_ACCOUNT: h = pamh->handlers.conf.acct_mgmt; break; case PAM_OPEN_SESSION: h = pamh->handlers.conf.open_session; break; case PAM_CLOSE_SESSION: h = pamh->handlers.conf.close_session; use_cached_chain = _PAM_MAY_BE_FROZEN; break; case PAM_CHAUTHTOK: h = pamh->handlers.conf.chauthtok; break; default: pam_syslog(pamh, LOG_ERR, "undefined fn choice; %d", choice); retval = PAM_ABORT; goto end; } if (h == NULL) { /* there was no handlers.conf... entry; will use * handlers.other... */ switch (choice) { case PAM_AUTHENTICATE: h = pamh->handlers.other.authenticate; break; case PAM_SETCRED: h = pamh->handlers.other.setcred; break; case PAM_ACCOUNT: h = pamh->handlers.other.acct_mgmt; break; case PAM_OPEN_SESSION: h = pamh->handlers.other.open_session; break; case PAM_CLOSE_SESSION: h = pamh->handlers.other.close_session; break; case PAM_CHAUTHTOK: h = pamh->handlers.other.chauthtok; break; } } /* Did a module return an "incomplete state" last time? */ if (pamh->former.choice != PAM_NOT_STACKED) { if (pamh->former.choice != choice) { pam_syslog(pamh, LOG_ERR, "application failed to re-exec stack [%d:%d]", pamh->former.choice, choice); retval = PAM_ABORT; goto end; } resumed = PAM_TRUE; } else { resumed = PAM_FALSE; _pam_clear_grantors(h); } __PAM_TO_MODULE(pamh); /* call the list of module functions */ pamh->choice = choice; retval = _pam_dispatch_aux(pamh, flags, h, resumed, use_cached_chain); resumed = PAM_FALSE; __PAM_TO_APP(pamh); /* Should we recall where to resume next time? */ if (retval == PAM_INCOMPLETE) { D(("module [%d] returned PAM_INCOMPLETE")); pamh->former.choice = choice; } else { pamh->former.choice = PAM_NOT_STACKED; } end: #ifdef HAVE_LIBAUDIT if (choice != PAM_CHAUTHTOK || flags & PAM_UPDATE_AUTHTOK || retval != PAM_SUCCESS) { retval = _pam_auditlog(pamh, choice, retval, flags, h); } #endif return retval; }
int pam_authenticate(pam_handle_t *pamh, int flags) { int retval; D(("pam_authenticate called")); IF_NO_PAMH("pam_authenticate", pamh, PAM_SYSTEM_ERR); if (__PAM_FROM_MODULE(pamh)) { D(("called from module!?")); return PAM_SYSTEM_ERR; } if (pamh->former.choice == PAM_NOT_STACKED) { _pam_sanitize(pamh); _pam_start_timer(pamh); /* we try to make the time for a failure independent of the time it takes to fail */ } retval = _pam_dispatch(pamh, flags, PAM_AUTHENTICATE); if (retval != PAM_INCOMPLETE) { _pam_sanitize(pamh); _pam_await_timer(pamh, retval); /* if unsuccessful then wait now */ D(("pam_authenticate exit")); } else { D(("will resume when ready")); } #ifdef PRELUDE prelude_send_alert(pamh, retval); #endif #if HAVE_LIBAUDIT retval = _pam_auditlog(pamh, PAM_AUTHENTICATE, retval, flags); #endif #ifdef CONFIG_PROP_STATSD_STATSD if (retval != PAM_SUCCESS) { char usr[MAX_PAM_STATS_USR_SIZE]; char buf[MAX_PAM_STATS_BUF_SIZE]; struct pam_data *data; char *u = NULL; /* The pam_sg module has stored module data so we * can tell whether this is a valid user. If not * we log stats under "unknown". The proper mechanism * for accessing module data bars access from within * application code so we are going around it. This is * a kludge, but the best one possible for now. */ data = pamh->data; while (data) { if (!strcmp(data->name, pamh->user)) { u = (char *)(data->data); break; } data = data->next; } /* Don't log stats if the module info is unavailable * or the PAM system itself failed during auth */ if ((u != NULL) && strcmp(u, "PAM_SYSTEM_ERR")) { u = ((u != NULL) && !strcmp(u, "PAM_USER_UNKNOWN")) ? "unknown":pamh->user; //u = ((u != NULL) && !strcmp(u, "USER_NOTFOUND")) ? "unknown":pamh->user; usr[MAX_PAM_STATS_USR_SIZE-1]='\0'; strncpy(usr,u,MAX_PAM_STATS_USR_SIZE-1); /* OK, start logging stats */ memset(buf,'\0',MAX_PAM_STATS_BUF_SIZE); snprintf(buf, MAX_PAM_STATS_BUF_SIZE-1, "statsd incr pam_failed_%s %s", usr,pamh->service_name); if (system(buf) == -1) { pam_syslog(pamh, LOG_INFO, "%s failed", buf); } snprintf(buf, MAX_PAM_STATS_BUF_SIZE-1, "statsd push pam_last_failure_%s %s \"%s\" 0", usr,pamh->service_name, pam_strerror(pamh, retval)); if (system(buf) == -1) { pam_syslog(pamh, LOG_INFO, "%s failed", buf); } snprintf(buf, MAX_PAM_STATS_BUF_SIZE-1, "statsd incr pam_users %s",usr); if (system(buf) == -1) { pam_syslog(pamh, LOG_INFO, "%s - failed", buf); } snprintf(buf, MAX_PAM_STATS_BUF_SIZE-1, "statsd incr pam_services %s",pamh->service_name); if (system(buf) == -1) { pam_syslog(pamh, LOG_INFO, "%s - failed", buf); } } } #endif return retval; }