From b49488bc884454323553bb95b01a7765312fb515 Mon Sep 17 00:00:00 2001 From: Olaf Mandel Date: Thu, 23 May 2019 16:09:44 +0000 Subject: pam_succeed_if: Request user data only when needed Allow for conditions that just check the user field to also work for users not known to the system. Before this caused a PAM_USER_UNKNOWN even if no extra data for an existing user was needed. E.g. auth sufficient pam_succeed_if.so user = NotKnownToSystem modules/pam_succeed_if/pam_succeed_if.c (evaluate): Change the pwd parameter to an input/output parameter. Lazily request pwd with pam_modutil_getpwnam() if needed and return PAM_USER_UNKNOWN on failure. modules/pam_succeed_if/pam_succeed_if.c (pam_sm_authenticate): Don't request the pwd if !use_uid anymore and shift the output from audit to after the evaluate() call. Also make sure not to give the normal failure message if the lazy pwd loading failed. --- modules/pam_succeed_if/pam_succeed_if.c | 43 ++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 17 deletions(-) (limited to 'modules') diff --git a/modules/pam_succeed_if/pam_succeed_if.c b/modules/pam_succeed_if/pam_succeed_if.c index aac3eeb0..afa61b3e 100644 --- a/modules/pam_succeed_if/pam_succeed_if.c +++ b/modules/pam_succeed_if/pam_succeed_if.c @@ -259,7 +259,7 @@ evaluate_notinnetgr(const pam_handle_t* pamh, const char *host, const char *user static int evaluate(pam_handle_t *pamh, int debug, const char *left, const char *qual, const char *right, - struct passwd *pwd, const char *user) + struct passwd **pwd, const char *user) { char buf[LINE_MAX] = ""; const char *attribute = left; @@ -270,22 +270,35 @@ evaluate(pam_handle_t *pamh, int debug, snprintf(buf, sizeof(buf), "%s", user); left = buf; } + /* Get information about the user if needed. */ + if ((*pwd == NULL) && + ((strcasecmp(left, "uid") == 0) || + (strcasecmp(left, "gid") == 0) || + (strcasecmp(left, "shell") == 0) || + (strcasecmp(left, "home") == 0) || + (strcasecmp(left, "dir") == 0) || + (strcasecmp(left, "homedir") == 0))) { + *pwd = pam_modutil_getpwnam(pamh, user); + if (*pwd == NULL) { + return PAM_USER_UNKNOWN; + } + } if (strcasecmp(left, "uid") == 0) { - snprintf(buf, sizeof(buf), "%lu", (unsigned long) pwd->pw_uid); + snprintf(buf, sizeof(buf), "%lu", (unsigned long) (*pwd)->pw_uid); left = buf; } if (strcasecmp(left, "gid") == 0) { - snprintf(buf, sizeof(buf), "%lu", (unsigned long) pwd->pw_gid); + snprintf(buf, sizeof(buf), "%lu", (unsigned long) (*pwd)->pw_gid); left = buf; } if (strcasecmp(left, "shell") == 0) { - snprintf(buf, sizeof(buf), "%s", pwd->pw_shell); + snprintf(buf, sizeof(buf), "%s", (*pwd)->pw_shell); left = buf; } if ((strcasecmp(left, "home") == 0) || (strcasecmp(left, "dir") == 0) || (strcasecmp(left, "homedir") == 0)) { - snprintf(buf, sizeof(buf), "%s", pwd->pw_dir); + snprintf(buf, sizeof(buf), "%s", (*pwd)->pw_dir); left = buf; } if (strcasecmp(left, "service") == 0) { @@ -415,7 +428,7 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, { const void *prompt; const char *user; - struct passwd *pwd; + struct passwd *pwd = NULL; int ret, i, count, use_uid, debug; const char *left, *right, *qual; int quiet_fail, quiet_succ, audit; @@ -471,15 +484,7 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, 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; - } + /* Postpone requesting password data until it is needed */ } /* Walk the argument list. */ @@ -520,9 +525,13 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, count++; ret = evaluate(pamh, debug, left, qual, right, - pwd, user); + &pwd, user); + if (ret == PAM_USER_UNKNOWN && audit) + pam_syslog(pamh, LOG_NOTICE, + "error retrieving information about user %s", + user); if (ret != PAM_SUCCESS) { - if(!quiet_fail) + if(!quiet_fail && ret != PAM_USER_UNKNOWN) pam_syslog(pamh, LOG_INFO, "requirement \"%s %s %s\" " "not met by user \"%s\"", -- cgit v1.2.3