diff options
author | nectar <nectar@FreeBSD.org> | 2005-04-05 14:55:33 +0000 |
---|---|---|
committer | nectar <nectar@FreeBSD.org> | 2005-04-05 14:55:33 +0000 |
commit | 6435ce940d56f3abecd7ff6812b8dce00e260ee7 (patch) | |
tree | 7d9c408dbba7b46426c33fe54d7d9886ab86fa85 /libexec | |
parent | 1a524b80b34a5e6d7602be28236024ee7dfd3c2e (diff) | |
download | FreeBSD-src-6435ce940d56f3abecd7ff6812b8dce00e260ee7.zip FreeBSD-src-6435ce940d56f3abecd7ff6812b8dce00e260ee7.tar.gz |
DES pointed out that the PAM layer may change the target user name
during authentication. Thus we need to call getpwnam *after* the user
has been authenticated. Colin mentioned that we should also move the
check for root in that case.
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/rexecd/rexecd.c | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/libexec/rexecd/rexecd.c b/libexec/rexecd/rexecd.c index b947d21..18149fe 100644 --- a/libexec/rexecd/rexecd.c +++ b/libexec/rexecd/rexecd.c @@ -86,6 +86,8 @@ char default_shell[] = _PATH_BSHELL; static void doit(struct sockaddr *); static void getstr(char *, int, const char *); static void error(const char *fmt, ...); +static struct passwd *xgetpwnam(const char *, struct passwd *, char **, + size_t *); int no_uid_0 = 1; @@ -192,25 +194,16 @@ doit(struct sockaddr *fromp) getstr(cmdbuf, maxcmdlen, "command"); (void) alarm(0); - pwdbuflen = BUFSIZ; + pwdbuflen = 0; pwdbuf = NULL; - pwd = NULL; - r = ERANGE; - while (pwd == NULL && r == ERANGE) { - pwdbuflen <<= 1; - if ((pwdbuf = reallocf(pwdbuf, pwdbuflen)) == NULL) { - syslog(LOG_ERR, "Cannot allocate memory"); - error("Cannot allocate memory.\n"); - exit(1); - } - r = getpwnam_r(user, &pwd_storage, pwdbuf, pwdbuflen, &pwd); - } - if (pwd == NULL || (pwd->pw_uid == 0 && no_uid_0) || - !pam_ok(pam_start("rexecd", user, &pamc, &pamh)) || + if (!pam_ok(pam_start("rexecd", user, &pamc, &pamh)) || !pam_ok(pam_set_item(pamh, PAM_RHOST, remote)) || !pam_ok(pam_set_item(pamh, PAM_AUTHTOK, pass)) || !pam_ok(pam_authenticate(pamh, pam_flags)) || - !pam_ok(pam_acct_mgmt(pamh, pam_flags))) { + !pam_ok(pam_acct_mgmt(pamh, pam_flags)) || + !pam_ok(pam_get_item(pamh, PAM_USER, (const void **)&user)) || + (pwd = xgetpwnam(user, &pwd_storage, &pwdbuf, + &pwdbuflen)) == NULL || (pwd->pw_uid == 0 && no_uid_0)) { syslog(LOG_ERR, "%s LOGIN REFUSED from %s", user, remote); error("Login incorrect.\n"); exit(1); @@ -335,3 +328,27 @@ getstr(char *buf, int cnt, const char *field) } } while (c != 0); } + +static struct passwd * +xgetpwnam(const char *user, struct passwd *pwd_storage, char **pwdbuf, + size_t *pwdbuflen) +{ + struct passwd *pwd; + size_t needed; + int rv; + + needed = (*pwdbuflen == 0) ? BUFSIZ : *pwdbuflen; + pwd = NULL; + do { + if (needed != *pwdbuflen) { + if ((*pwdbuf = reallocf(*pwdbuf, needed)) == NULL) { + syslog(LOG_ERR, "Cannot allocate memory"); + error("Cannot allocate memory.\n"); + exit(1); + } else + *pwdbuflen = needed; + } + rv = getpwnam_r(user, pwd_storage, *pwdbuf, *pwdbuflen, &pwd); + } while (pwd == NULL && rv == ERANGE && (needed <<= 1)); + return pwd; +} |