diff options
author | nectar <nectar@FreeBSD.org> | 2005-03-27 13:59:44 +0000 |
---|---|---|
committer | nectar <nectar@FreeBSD.org> | 2005-03-27 13:59:44 +0000 |
commit | 8f12f32e0d4ded7da93c1c245fdea193710d065a (patch) | |
tree | fe6d8e90fc0908556db12ed10c3cbf645f18ab13 /libexec | |
parent | c0a05846489060f7e7bb314d80fa25121366ecfc (diff) | |
download | FreeBSD-src-8f12f32e0d4ded7da93c1c245fdea193710d065a.zip FreeBSD-src-8f12f32e0d4ded7da93c1c245fdea193710d065a.tar.gz |
When PAM support was added to rexecd in revision 1.29 (just prior to
5.0-RELEASE), a visually elusive bug was introduced. A comparison
operator was changed to assignment. As a result, rexecd behaved
always as if the `-i' option had been specified. It would allow root
logins. This commit corrects the situation in the obvious way.
A separate bug was introduced at the same time. The PAM library
functions are called between the invocation of getpwnam(3) and the use
of the returned static object. Since many PAM library functions
result in additional getpwnam(3) calls, the contents of the returned
static object could be changed from under rexecd. With this commit,
getpwnam_r(3) is used instead.
Other PAM-using applications should be reviewed for similar errors in
getpw* usage.
Security: rexecd's documented default policy of disallowing root
logins was not enforced.
Reviewed by: cperciva
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/rexecd/rexecd.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/libexec/rexecd/rexecd.c b/libexec/rexecd/rexecd.c index ea8977f..b947d21 100644 --- a/libexec/rexecd/rexecd.c +++ b/libexec/rexecd/rexecd.c @@ -135,7 +135,9 @@ doit(struct sockaddr *fromp) char *cmdbuf, *cp; int maxcmdlen; char user[16], pass[16]; - struct passwd *pwd; + struct passwd *pwd, pwd_storage; + char *pwdbuf; + int pwdbuflen; int fd, r, sd; u_short port; int pv[2], pid, cc, nfds; @@ -190,7 +192,20 @@ doit(struct sockaddr *fromp) getstr(cmdbuf, maxcmdlen, "command"); (void) alarm(0); - if ((pwd = getpwnam(user)) == NULL || (pwd->pw_uid = 0 && no_uid_0) || + pwdbuflen = BUFSIZ; + 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)) || !pam_ok(pam_set_item(pamh, PAM_RHOST, remote)) || !pam_ok(pam_set_item(pamh, PAM_AUTHTOK, pass)) || |