X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/d277808b37ff865f203f62cd7dfef4d22f577c5c..bec8d58c692d252d93d5e2c9a3aa35d7ccaa6796:/usr/src/lib/libc/net/rcmd.c diff --git a/usr/src/lib/libc/net/rcmd.c b/usr/src/lib/libc/net/rcmd.c index 2491a51bc7..16c2cc62d9 100644 --- a/usr/src/lib/libc/net/rcmd.c +++ b/usr/src/lib/libc/net/rcmd.c @@ -1,17 +1,30 @@ /* * Copyright (c) 1983 Regents of the University of California. - * All rights reserved. The Berkeley software License Agreement - * specifies the terms and conditions for redistribution. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#ifndef lint -static char sccsid[] = "@(#)rcmd.c 5.8 (Berkeley) %G%"; -#endif not lint +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)rcmd.c 5.19 (Berkeley) %G%"; +#endif /* LIBC_SCCS and not lint */ #include #include #include #include +#include +#include #include #include @@ -21,50 +34,71 @@ static char sccsid[] = "@(#)rcmd.c 5.8 (Berkeley) %G%"; #include extern errno; -char *index(), *sprintf(); +char *index(); rcmd(ahost, rport, locuser, remuser, cmd, fd2p) char **ahost; - int rport; + u_short rport; char *locuser, *remuser, *cmd; int *fd2p; { - int s, timo = 1; + int s, timo = 1, pid; + long oldmask; struct sockaddr_in sin, sin2, from; char c; int lport = IPPORT_RESERVED - 1; struct hostent *hp; + pid = getpid(); hp = gethostbyname(*ahost); if (hp == 0) { - fprintf(stderr, "%s: unknown host\n", *ahost); + herror(*ahost); return (-1); } *ahost = hp->h_name; -retry: - s = rresvport(&lport); - if (s < 0) { - if (errno == EAGAIN) - fprintf(stderr, "socket: All ports in use\n"); - else - perror("rcmd: socket"); - return (-1); - } - sin.sin_family = hp->h_addrtype; - bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); - sin.sin_port = rport; - if (connect(s, (caddr_t)&sin, sizeof (sin), 0) < 0) { + oldmask = sigblock(sigmask(SIGURG)); + for (;;) { + s = rresvport(&lport); + if (s < 0) { + if (errno == EAGAIN) + fprintf(stderr, "socket: All ports in use\n"); + else + perror("rcmd: socket"); + sigsetmask(oldmask); + return (-1); + } + fcntl(s, F_SETOWN, pid); + sin.sin_family = hp->h_addrtype; + bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length); + sin.sin_port = rport; + if (connect(s, (caddr_t)&sin, sizeof (sin), 0) >= 0) + break; (void) close(s); if (errno == EADDRINUSE) { lport--; - goto retry; + continue; } if (errno == ECONNREFUSED && timo <= 16) { sleep(timo); timo *= 2; - goto retry; + continue; + } + if (hp->h_addr_list[1] != NULL) { + int oerrno = errno; + + fprintf(stderr, + "connect to address %s: ", inet_ntoa(sin.sin_addr)); + errno = oerrno; + perror(0); + hp->h_addr_list++; + bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, + hp->h_length); + fprintf(stderr, "Trying %s...\n", + inet_ntoa(sin.sin_addr)); + continue; } perror(hp->h_name); + sigsetmask(oldmask); return (-1); } lport--; @@ -116,12 +150,14 @@ retry: } goto bad2; } + sigsetmask(oldmask); return (s); bad2: if (lport) (void) close(*fd2p); bad: (void) close(s); + sigsetmask(oldmask); return (-1); } @@ -132,6 +168,7 @@ rresvport(alport) int s; sin.sin_family = AF_INET; + sin.sin_len = sizeof(sin); sin.sin_addr.s_addr = INADDR_ANY; s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) @@ -153,6 +190,8 @@ rresvport(alport) } } +int _check_rhosts_file = 1; + ruserok(rhost, superuser, ruser, luser) char *rhost; int superuser; @@ -160,7 +199,6 @@ ruserok(rhost, superuser, ruser, luser) { FILE *hostf; char fhost[MAXHOSTNAMELEN]; - char ahost[MAXHOSTNAMELEN]; int first = 1; register char *sp, *p; int baselen = -1; @@ -180,31 +218,13 @@ ruserok(rhost, superuser, ruser, luser) hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r"); again: if (hostf) { - while (fgets(ahost, sizeof (ahost), hostf)) { - char *user; - - p = ahost; - while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') - *p++ = isupper(*p) ? tolower(*p) : *p; - if (*p == ' ' || *p == '\t') { - *p++ = '\0'; - while (*p == ' ' || *p == '\t') - p++; - user = p; - while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') - p++; - } else - user = p; - *p = '\0'; - if (_checkhost(fhost, ahost, baselen) && - !strcmp(ruser, *user ? user : luser)) { - (void) fclose(hostf); - return (0); - } + if (!_validuser(hostf, fhost, luser, ruser, baselen)) { + (void) fclose(hostf); + return(0); } (void) fclose(hostf); } - if (first == 1) { + if (first == 1 && (_check_rhosts_file || superuser)) { struct stat sbuf; struct passwd *pwd; char pbuf[MAXPATHLEN]; @@ -216,8 +236,13 @@ again: (void)strcat(pbuf, "/.rhosts"); if ((hostf = fopen(pbuf, "r")) == NULL) return(-1); - (void)fstat(fileno(hostf), &sbuf); - if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) { + /* + * if owned by someone other than user or root or if + * writeable by anyone but the owner, quit + */ + if (fstat(fileno(hostf), &sbuf) || + sbuf.st_uid && sbuf.st_uid != pwd->pw_uid || + sbuf.st_mode&022) { fclose(hostf); return(-1); } @@ -226,12 +251,48 @@ again: return (-1); } +static +_validuser(hostf, rhost, luser, ruser, baselen) + char *rhost, *luser, *ruser; + FILE *hostf; + int baselen; +{ + char *user; + char ahost[MAXHOSTNAMELEN]; + register char *p; + + while (fgets(ahost, sizeof (ahost), hostf)) { + p = ahost; + while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') { + *p = isupper(*p) ? tolower(*p) : *p; + p++; + } + if (*p == ' ' || *p == '\t') { + *p++ = '\0'; + while (*p == ' ' || *p == '\t') + p++; + user = p; + while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') + p++; + } else + user = p; + *p = '\0'; + if (_checkhost(rhost, ahost, baselen) && + !strcmp(ruser, *user ? user : luser)) { + return (0); + } + } + return (-1); +} + +static _checkhost(rhost, lhost, len) -char *rhost, *lhost; -int len; + char *rhost, *lhost; + int len; { static char ldomain[MAXHOSTNAMELEN + 1]; static char *domainp = NULL; + static int nodomain = 0; register char *cp; if (len == -1) @@ -242,19 +303,21 @@ int len; return(1); if (*(lhost + len) != '\0') return(0); + if (nodomain) + return(0); if (!domainp) { if (gethostname(ldomain, sizeof(ldomain)) == -1) { - domainp = (char *)1; + nodomain = 1; return(0); } ldomain[MAXHOSTNAMELEN] = NULL; - if ((domainp = index(ldomain, '.') + 1) == (char *)1) + if ((domainp = index(ldomain, '.')) == (char *)NULL) { + nodomain = 1; return(0); - cp = domainp; - while (*cp) - *cp++ = isupper(*cp) ? tolower(*cp) : *cp; + } + for (cp = ++domainp; *cp; ++cp) + if (isupper(*cp)) + *cp = tolower(*cp); } - if (domainp == (char *)1) - return(0); return(!strcmp(domainp, rhost + len +1)); }