summaryrefslogtreecommitdiff
path: root/modules/pam_succeed_if
diff options
context:
space:
mode:
authorOlaf Mandel <o.mandel@menlosystems.com>2019-05-23 16:09:44 +0000
committerTomáš Mráz <t8m@users.noreply.github.com>2019-05-23 19:48:24 +0200
commitb49488bc884454323553bb95b01a7765312fb515 (patch)
tree682a7c4947e570890fca08765775b3c61d12648a /modules/pam_succeed_if
parentb136bff25e93be6f11de74aca03569022364b973 (diff)
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.c43
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\"",