1: /*
   2:  * Copyright (c) 1983 Regents of the University of California.
   3:  * All rights reserved.
   4:  *
   5:  * Redistribution and use in source and binary forms are permitted
   6:  * provided that the above copyright notice and this paragraph are
   7:  * duplicated in all such forms and that any documentation,
   8:  * advertising materials, and other materials related to such
   9:  * distribution and use acknowledge that the software was developed
  10:  * by the University of California, Berkeley.  The name of the
  11:  * University may not be used to endorse or promote products derived
  12:  * from this software without specific prior written permission.
  13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16:  */
  17: 
  18: #if defined(LIBC_SCCS) && !defined(lint)
  19: static char sccsid[] = "@(#)rcmd.c	5.20.1 (2.11BSD) 1999/10/24";
  20: #endif /* LIBC_SCCS and not lint */
  21: 
  22: #include <stdio.h>
  23: #include <ctype.h>
  24: #include <pwd.h>
  25: #include <string.h>
  26: #include <sys/param.h>
  27: #include <sys/file.h>
  28: #include <sys/signal.h>
  29: #include <sys/socket.h>
  30: #include <sys/stat.h>
  31: 
  32: #include <netinet/in.h>
  33: 
  34: #include <netdb.h>
  35: #include <errno.h>
  36: 
  37: rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
  38:     char **ahost;
  39:     u_short rport;
  40:     char *locuser, *remuser, *cmd;
  41:     int *fd2p;
  42: {
  43:     int s, timo = 1, pid;
  44:     sigset_t oldmask, nmask;
  45:     struct sockaddr_in sin, sin2, from;
  46:     char c;
  47:     int lport = IPPORT_RESERVED - 1;
  48:     struct hostent *hp;
  49:     fd_set reads;
  50: 
  51:     pid = getpid();
  52:     hp = gethostbyname(*ahost);
  53:     if (hp == 0) {
  54:         herror(*ahost);
  55:         return (-1);
  56:     }
  57:     *ahost = hp->h_name;
  58:     sigemptyset(&nmask);
  59:     sigaddset(&nmask, SIGURG);
  60:     (void)sigprocmask(SIG_BLOCK, &nmask, &oldmask);
  61: 
  62:     for (;;) {
  63:         s = rresvport(&lport);
  64:         if (s < 0) {
  65:             if (errno == EAGAIN)
  66:                 fprintf(stderr, "socket: All ports in use\n");
  67:             else
  68:                 perror("rcmd: socket");
  69:             sigprocmask(SIG_SETMASK, &oldmask, NULL);
  70:             return (-1);
  71:         }
  72:         fcntl(s, F_SETOWN, pid);
  73:         sin.sin_family = hp->h_addrtype;
  74:         bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
  75:         sin.sin_port = rport;
  76:         if (connect(s, (caddr_t)&sin, sizeof (sin), 0) >= 0)
  77:             break;
  78:         (void) close(s);
  79:         if (errno == EADDRINUSE) {
  80:             lport--;
  81:             continue;
  82:         }
  83:         if (errno == ECONNREFUSED && timo <= 16) {
  84:             sleep(timo);
  85:             timo *= 2;
  86:             continue;
  87:         }
  88:         if (hp->h_addr_list[1] != NULL) {
  89:             int oerrno = errno;
  90: 
  91:             fprintf(stderr,
  92:                 "connect to address %s: ", inet_ntoa(sin.sin_addr));
  93:             errno = oerrno;
  94:             perror(0);
  95:             hp->h_addr_list++;
  96:             bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr,
  97:                 hp->h_length);
  98:             fprintf(stderr, "Trying %s...\n",
  99:                 inet_ntoa(sin.sin_addr));
 100:             continue;
 101:         }
 102:         perror(hp->h_name);
 103:         sigprocmask(SIG_SETMASK, &oldmask, NULL);
 104:         return (-1);
 105:     }
 106:     lport--;
 107:     if (fd2p == 0) {
 108:         write(s, "", 1);
 109:         lport = 0;
 110:     } else {
 111:         char num[8];
 112:         int s2 = rresvport(&lport), s3;
 113:         int len = sizeof (from);
 114: 
 115:         if (s2 < 0)
 116:             goto bad;
 117:         listen(s2, 1);
 118:         (void) sprintf(num, "%d", lport);
 119:         if (write(s, num, strlen(num)+1) != strlen(num)+1) {
 120:             perror("write: setting up stderr");
 121:             (void) close(s2);
 122:             goto bad;
 123:         }
 124:         FD_ZERO(&reads);
 125:         FD_SET(s, &reads);
 126:         FD_SET(s2, &reads);
 127:         errno = 0;
 128:         if (select(32, &reads, 0, 0, 0) < 1 ||
 129:             !FD_ISSET(s2, &reads)) {
 130:             if (errno != 0)
 131:                 perror("select: setting up stderr");
 132:             else
 133:                 fprintf(stderr,
 134:                 "select: protocol failure in circuit setup.\n");
 135:             (void) close(s2);
 136:             goto bad;
 137:         }
 138:         s3 = accept(s2, &from, &len, 0);
 139:         (void) close(s2);
 140:         if (s3 < 0) {
 141:             perror("accept");
 142:             lport = 0;
 143:             goto bad;
 144:         }
 145:         *fd2p = s3;
 146:         from.sin_port = ntohs((u_short)from.sin_port);
 147:         if (from.sin_family != AF_INET ||
 148:             from.sin_port >= IPPORT_RESERVED ||
 149:             from.sin_port < IPPORT_RESERVED / 2) {
 150:             fprintf(stderr,
 151:                 "socket: protocol failure in circuit setup.\n");
 152:             goto bad2;
 153:         }
 154:     }
 155:     (void) write(s, locuser, strlen(locuser)+1);
 156:     (void) write(s, remuser, strlen(remuser)+1);
 157:     (void) write(s, cmd, strlen(cmd)+1);
 158:     if (read(s, &c, 1) != 1) {
 159:         perror(*ahost);
 160:         goto bad2;
 161:     }
 162:     if (c != 0) {
 163:         while (read(s, &c, 1) == 1) {
 164:             (void) write(2, &c, 1);
 165:             if (c == '\n')
 166:                 break;
 167:         }
 168:         goto bad2;
 169:     }
 170:     sigprocmask(SIG_SETMASK, &oldmask, NULL);
 171:     return (s);
 172: bad2:
 173:     if (lport)
 174:         (void) close(*fd2p);
 175: bad:
 176:     (void) close(s);
 177:     sigprocmask(SIG_SETMASK, &oldmask, NULL);
 178:     return (-1);
 179: }
 180: 
 181: rresvport(alport)
 182:     int *alport;
 183: {
 184:     struct sockaddr_in sin;
 185:     int s;
 186: 
 187:     sin.sin_family = AF_INET;
 188:     sin.sin_addr.s_addr = INADDR_ANY;
 189:     s = socket(AF_INET, SOCK_STREAM, 0);
 190:     if (s < 0)
 191:         return (-1);
 192:     for (;;) {
 193:         sin.sin_port = htons((u_short)*alport);
 194:         if (bind(s, (caddr_t)&sin, sizeof (sin)) >= 0)
 195:             return (s);
 196:         if (errno != EADDRINUSE) {
 197:             (void) close(s);
 198:             return (-1);
 199:         }
 200:         (*alport)--;
 201:         if (*alport == IPPORT_RESERVED/2) {
 202:             (void) close(s);
 203:             errno = EAGAIN;     /* close */
 204:             return (-1);
 205:         }
 206:     }
 207: }
 208: 
 209: int _check_rhosts_file = 1;
 210: 
 211: ruserok(rhost, superuser, ruser, luser)
 212:     char *rhost;
 213:     int superuser;
 214:     char *ruser, *luser;
 215: {
 216:     FILE *hostf;
 217:     char fhost[MAXHOSTNAMELEN];
 218:     int first = 1;
 219:     register char *sp, *p;
 220:     int baselen = -1;
 221: 
 222:     sp = rhost;
 223:     p = fhost;
 224:     while (*sp) {
 225:         if (*sp == '.') {
 226:             if (baselen == -1)
 227:                 baselen = sp - rhost;
 228:             *p++ = *sp++;
 229:         } else {
 230:             *p++ = isupper(*sp) ? tolower(*sp++) : *sp++;
 231:         }
 232:     }
 233:     *p = '\0';
 234:     hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r");
 235: again:
 236:     if (hostf) {
 237:         if (!_validuser(hostf, fhost, luser, ruser, baselen)) {
 238:             (void) fclose(hostf);
 239:             return(0);
 240:         }
 241:         (void) fclose(hostf);
 242:     }
 243:     if (first == 1 && (_check_rhosts_file || superuser)) {
 244:         struct stat sbuf;
 245:         struct passwd *pwd;
 246:         char pbuf[MAXPATHLEN];
 247: 
 248:         first = 0;
 249:         if ((pwd = getpwnam(luser)) == NULL)
 250:             return(-1);
 251:         (void)strcpy(pbuf, pwd->pw_dir);
 252:         (void)strcat(pbuf, "/.rhosts");
 253:         if ((hostf = fopen(pbuf, "r")) == NULL)
 254:             return(-1);
 255:         /*
 256: 		 * if owned by someone other than user or root or if
 257: 		 * writeable by anyone but the owner, quit
 258: 		 */
 259:         if (fstat(fileno(hostf), &sbuf) ||
 260:             sbuf.st_uid && sbuf.st_uid != pwd->pw_uid ||
 261:             sbuf.st_mode&022) {
 262:             fclose(hostf);
 263:             return(-1);
 264:         }
 265:         goto again;
 266:     }
 267:     return (-1);
 268: }
 269: 
 270: /* don't make static, used by lpd(8) */
 271: _validuser(hostf, rhost, luser, ruser, baselen)
 272:     char *rhost, *luser, *ruser;
 273:     FILE *hostf;
 274:     int baselen;
 275: {
 276:     char *user;
 277:     char ahost[MAXHOSTNAMELEN];
 278:     register char *p;
 279: 
 280:     while (fgets(ahost, sizeof (ahost), hostf)) {
 281:         p = ahost;
 282:         while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
 283:             *p = isupper(*p) ? tolower(*p) : *p;
 284:             p++;
 285:         }
 286:         if (*p == ' ' || *p == '\t') {
 287:             *p++ = '\0';
 288:             while (*p == ' ' || *p == '\t')
 289:                 p++;
 290:             user = p;
 291:             while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
 292:                 p++;
 293:         } else
 294:             user = p;
 295:         *p = '\0';
 296:         if (_checkhost(rhost, ahost, baselen) &&
 297:             !strcmp(ruser, *user ? user : luser)) {
 298:             return (0);
 299:         }
 300:     }
 301:     return (-1);
 302: }
 303: 
 304: static
 305: _checkhost(rhost, lhost, len)
 306:     char *rhost, *lhost;
 307:     int len;
 308: {
 309:     static char ldomain[MAXHOSTNAMELEN + 1];
 310:     static char *domainp = NULL;
 311:     static int nodomain = 0;
 312:     register char *cp;
 313: 
 314:     if (len == -1)
 315:         return(!strcmp(rhost, lhost));
 316:     if (strncmp(rhost, lhost, len))
 317:         return(0);
 318:     if (!strcmp(rhost, lhost))
 319:         return(1);
 320:     if (*(lhost + len) != '\0')
 321:         return(0);
 322:     if (nodomain)
 323:         return(0);
 324:     if (!domainp) {
 325:         if (gethostname(ldomain, sizeof(ldomain)) == -1) {
 326:             nodomain = 1;
 327:             return(0);
 328:         }
 329:         ldomain[MAXHOSTNAMELEN] = NULL;
 330:         if ((domainp = index(ldomain, '.')) == (char *)NULL) {
 331:             nodomain = 1;
 332:             return(0);
 333:         }
 334:         for (cp = ++domainp; *cp; ++cp)
 335:             if (isupper(*cp))
 336:                 *cp = tolower(*cp);
 337:     }
 338:     return(!strcmp(domainp, rhost + len +1));
 339: }

Defined functions

_checkhost defined in line 304; used 1 times
_validuser defined in line 271; used 2 times
ruserok defined in line 211; used 2 times

Defined variables

_check_rhosts_file defined in line 209; used 1 times
sccsid defined in line 19; never used
Last modified: 1999-10-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3494
Valid CSS Valid XHTML 1.0 Strict