diff options
author | Olaf Mandel <o.mandel@menlosystems.com> | 2019-05-23 16:09:44 +0000 |
---|---|---|
committer | Tomáš Mráz <t8m@users.noreply.github.com> | 2019-05-23 19:48:24 +0200 |
commit | b49488bc884454323553bb95b01a7765312fb515 (patch) | |
tree | 682a7c4947e570890fca08765775b3c61d12648a /modules/pam_succeed_if | |
parent | b136bff25e93be6f11de74aca03569022364b973 (diff) | |
download | pam-b49488bc884454323553bb95b01a7765312fb515.tar.gz pam-b49488bc884454323553bb95b01a7765312fb515.tar.bz2 pam-b49488bc884454323553bb95b01a7765312fb515.zip |
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.
Diffstat (limited to 'modules/pam_succeed_if')
-rw-r--r-- | modules/pam_succeed_if/pam_succeed_if.c | 43 |
1 files changed, 26 insertions, 17 deletions
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\"", |