From 0fcbbd7beaeac8c7ed613ed7c766c6ec5eee15ec Mon Sep 17 00:00:00 2001 From: Jacques Vidrine Date: Sun, 27 Mar 2005 13:59:44 +0000 Subject: 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 --- libexec/rexecd/rexecd.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/libexec/rexecd/rexecd.c b/libexec/rexecd/rexecd.c index ea8977f616c6b..b947d2126fbcf 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)) || -- cgit v1.3