static int get_ruser(pam_handle_t *pamh, char *ruserbuf, size_t ruserbuflen) { const void *ruser; struct passwd *pwd; if (ruserbuf == NULL || ruserbuflen < 1) return -2; /* Get the name of the source user. */ if (pam_get_item(pamh, PAM_RUSER, &ruser) != PAM_SUCCESS) { ruser = NULL; } if ((ruser == NULL) || (strlen(ruser) == 0)) { /* Barring that, use the current RUID. */ pwd = pam_modutil_getpwuid(pamh, getuid()); if (pwd != NULL) { ruser = pwd->pw_name; } } else { /* * This ruser is used by format_timestamp_name as a component * of constructed timestamp pathname, so ".", "..", and '/' * are disallowed to avoid potential path traversal issues. */ if (!strcmp(ruser, ".") || !strcmp(ruser, "..") || strchr(ruser, '/')) { ruser = NULL; } } if (ruser == NULL || strlen(ruser) >= ruserbuflen) { *ruserbuf = '\0'; return -1; } strcpy(ruserbuf, ruser); return 0; }
PAM_EXTERN int pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { const void *prompt; const char *user; struct passwd *pwd; int ret, i, count, use_uid, debug; const char *left, *right, *qual; int quiet_fail, quiet_succ, audit; /* Get the user prompt. */ ret = pam_get_item(pamh, PAM_USER_PROMPT, &prompt); if ((ret != PAM_SUCCESS) || (prompt == NULL) || (strlen(prompt) == 0)) { prompt = "login: "******"debug") == 0) { debug++; } if (strcmp(argv[i], "use_uid") == 0) { use_uid++; } if (strcmp(argv[i], "quiet") == 0) { quiet_fail++; quiet_succ++; } if (strcmp(argv[i], "quiet_fail") == 0) { quiet_fail++; } if (strcmp(argv[i], "quiet_success") == 0) { quiet_succ++; } if (strcmp(argv[i], "audit") == 0) { audit++; } } if (use_uid) { /* Get information about the user. */ pwd = pam_modutil_getpwuid(pamh, getuid()); if (pwd == NULL) { pam_syslog(pamh, LOG_CRIT, "error retrieving information about user %lu", (unsigned long)getuid()); return PAM_USER_UNKNOWN; } user = pwd->pw_name; } else { /* Get the user's name. */ ret = pam_get_user(pamh, &user, prompt); if ((ret != PAM_SUCCESS) || (user == NULL)) { pam_syslog(pamh, LOG_CRIT, "error retrieving user name: %s", pam_strerror(pamh, ret)); return ret; } /* Get information about the user. */ pwd = pam_modutil_getpwnam(pamh, user); if (pwd == NULL) { if(audit) pam_syslog(pamh, LOG_NOTICE, "error retrieving information about user %s", user); return PAM_USER_UNKNOWN; } } /* Walk the argument list. */ count = 0; left = qual = right = NULL; for (i = 0; i < argc; i++) { if (strcmp(argv[i], "debug") == 0) { continue; } if (strcmp(argv[i], "use_uid") == 0) { continue; } if (strcmp(argv[i], "quiet") == 0) { continue; } if (strcmp(argv[i], "quiet_fail") == 0) { continue; } if (strcmp(argv[i], "quiet_success") == 0) { continue; } if (strcmp(argv[i], "audit") == 0) { continue; } if (left == NULL) { left = argv[i]; continue; } if (qual == NULL) { qual = argv[i]; continue; } if (right == NULL) { right = argv[i]; if (right == NULL) continue; count++; ret = evaluate(pamh, debug, left, qual, right, pwd, user); if (ret != PAM_SUCCESS) { if(!quiet_fail) pam_syslog(pamh, LOG_INFO, "requirement \"%s %s %s\" " "not met by user \"%s\"", left, qual, right, user); left = qual = right = NULL; break; } else if(!quiet_succ) pam_syslog(pamh, LOG_INFO, "requirement \"%s %s %s\" " "was met by user \"%s\"", left, qual, right, user); left = qual = right = NULL; continue; } } if (left || qual || right) { ret = PAM_SERVICE_ERR; pam_syslog(pamh, LOG_CRIT, "incomplete condition detected"); } else if (count == 0) { pam_syslog(pamh, LOG_INFO, "no condition detected; module succeeded"); } return ret; }