X-Git-Url: https://git.saurik.com/apple/libinfo.git/blobdiff_plain/3b7c7bd7aae68ec949fb3f4ef1d58b96033e40df..84e6ee29846bd48cc36d74aeb5c13c52a59c5a55:/util.subproj/rcmd.c diff --git a/util.subproj/rcmd.c b/util.subproj/rcmd.c index 4345fb7..02c497b 100644 --- a/util.subproj/rcmd.c +++ b/util.subproj/rcmd.c @@ -66,9 +66,7 @@ static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94"; #include #include -#include #include -#include #include #include @@ -79,12 +77,13 @@ static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94"; #include #include #include +#include #ifdef YP #include #include #include #endif -#include +#include /* wrapper for KAME-special getnameinfo() */ #ifndef NI_WITHSCOPEID @@ -96,6 +95,7 @@ static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94"; #endif extern int innetgr __P(( const char *, const char *, const char *, const char * )); +extern int bindresvport_sa(int, struct sockaddr *); #define max(a, b) ((a > b) ? a : b) @@ -107,17 +107,6 @@ int __ivaliduser_sa __P((FILE *, const struct sockaddr *, socklen_t, static int __icheckhost __P((const struct sockaddr *, socklen_t, const char *)); - -int -rcmd(ahost, rport, locuser, remuser, cmd, fd2p) - char **ahost; - in_port_t rport; - const char *locuser, *remuser, *cmd; - int *fd2p; -{ - return rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, AF_INET); -} - int rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af) char **ahost; @@ -244,7 +233,7 @@ rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af) } else { char num[8]; int s2 = rresvport_af(&lport, ai->ai_family), s3; - int len = ai->ai_addrlen; + unsigned int len = ai->ai_addrlen; int nfds; if (s2 < 0) @@ -345,6 +334,16 @@ bad: return (-1); } +int +rcmd(ahost, rport, locuser, remuser, cmd, fd2p) + char **ahost; + in_port_t rport; + const char *locuser, *remuser, *cmd; + int *fd2p; +{ + return rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, AF_INET); +} + int rresvport(port) int *port; @@ -404,56 +403,8 @@ rresvport_af(alport, family) int __check_rhosts_file = 1; char *__rcmd_errstr; -int -ruserok(rhost, superuser, ruser, luser) - const char *rhost, *ruser, *luser; - int superuser; -{ - struct addrinfo hints, *res, *r; - int error; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; /*dummy*/ - error = getaddrinfo(rhost, "0", &hints, &res); - if (error) - return (-1); - - for (r = res; r; r = r->ai_next) { - if (iruserok_sa(r->ai_addr, r->ai_addrlen, superuser, ruser, - luser) == 0) { - freeaddrinfo(res); - return (0); - } - } - freeaddrinfo(res); - return (-1); -} - -/* - * New .rhosts strategy: We are passed an ip address. We spin through - * hosts.equiv and .rhosts looking for a match. When the .rhosts only - * has ip addresses, we don't have to trust a nameserver. When it - * contains hostnames, we spin through the list of addresses the nameserver - * gives us and look for a match. - * - * Returns 0 if ok, -1 if not ok. - */ -int -iruserok(raddr, superuser, ruser, luser) - unsigned long raddr; - int superuser; - const char *ruser, *luser; -{ - struct sockaddr_in sin; - - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_len = sizeof(struct sockaddr_in); - memcpy(&sin.sin_addr, &raddr, sizeof(sin.sin_addr)); - return iruserok_sa((struct sockaddr *)&sin, sin.sin_len, superuser, - ruser, luser); -} +/* Guess at the size of a password buffer for getpwnam_r (see lookup.subproj/lu_group.c) */ +#define MAXPWBUF (MAXLOGNAME + 1 + _PASSWORD_LEN + 1 + MAXPATHLEN + 1 + MAXPATHLEN + 1 + 4098) /* * AF independent extension of iruserok. @@ -469,13 +420,14 @@ iruserok_sa(ra, rlen, superuser, ruser, luser) { register char *cp; struct stat sbuf; - struct passwd *pwd; + struct passwd p, *pwd; FILE *hostf; uid_t uid; - int first; + int first, status; char pbuf[MAXPATHLEN]; const struct sockaddr *raddr; struct sockaddr_storage ss; + char pwbuf[MAXPWBUF]; /* avoid alignment issue */ if (rlen > sizeof(ss)) @@ -495,8 +447,14 @@ again: } if (first == 1 && (__check_rhosts_file || superuser)) { first = 0; - if ((pwd = getpwnam(luser)) == NULL) - return (-1); + + memset(&p, 0, sizeof(struct passwd)); + memset(pwbuf, 0, sizeof(pwbuf)); + pwd = NULL; + + status = getpwnam_r(luser, &p, pwbuf, MAXPWBUF, &pwd); + if (status != 0) return -1; + (void)strcpy(pbuf, pwd->pw_dir); (void)strcat(pbuf, "/.rhosts"); @@ -538,6 +496,57 @@ again: return (-1); } +int +ruserok(rhost, superuser, ruser, luser) + const char *rhost, *ruser, *luser; + int superuser; +{ + struct addrinfo hints, *res, *r; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + error = getaddrinfo(rhost, "0", &hints, &res); + if (error) + return (-1); + + for (r = res; r; r = r->ai_next) { + if (iruserok_sa(r->ai_addr, r->ai_addrlen, superuser, ruser, + luser) == 0) { + freeaddrinfo(res); + return (0); + } + } + freeaddrinfo(res); + return (-1); +} + +/* + * New .rhosts strategy: We are passed an ip address. We spin through + * hosts.equiv and .rhosts looking for a match. When the .rhosts only + * has ip addresses, we don't have to trust a nameserver. When it + * contains hostnames, we spin through the list of addresses the nameserver + * gives us and look for a match. + * + * Returns 0 if ok, -1 if not ok. + */ +int +iruserok(raddr, superuser, ruser, luser) + unsigned long raddr; + int superuser; + const char *ruser, *luser; +{ + struct sockaddr_in sin; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_len = sizeof(struct sockaddr_in); + memcpy(&sin.sin_addr, &raddr, sizeof(sin.sin_addr)); + return iruserok_sa((struct sockaddr *)&sin, sin.sin_len, superuser, + ruser, luser); +} + /* * XXX * Don't make static, used by lpd(8). @@ -632,10 +641,12 @@ __ivaliduser_sa(hostf, raddr, salen, luser, ruser) #else #define ypdomain NULL #endif - /* We need to get the damn hostname back for netgroup matching. */ - if (getnameinfo(raddr, salen, hname, sizeof(hname), NULL, 0, - NI_NAMEREQD) != 0) - return (-1); + /* + * We try to get the hostname back for netgroup matching. + * However, the .rosts file may contain IP addresses as well + * as names, so a name is not always required. + */ + getnameinfo(raddr, salen, hname, sizeof(hname), NULL, 0, NI_NAMEREQD); while (fgets(buf, sizeof(buf), hostf)) { p = buf;