1: /*
   2:  * Copyright (c) 1983 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #if defined(LIBC_SCCS) && !defined(lint)
   8: static char sccsid[] = "@(#)rcmd.c	5.11 (Berkeley) 5/6/86";
   9: #endif LIBC_SCCS and not lint
  10: 
  11: #include <stdio.h>
  12: #include <ctype.h>
  13: #include <pwd.h>
  14: #include <sys/param.h>
  15: #include <sys/file.h>
  16: #include <sys/signal.h>
  17: #include <sys/socket.h>
  18: #include <sys/stat.h>
  19: 
  20: #include <netinet/in.h>
  21: 
  22: #include <netdb.h>
  23: #include <errno.h>
  24: 
  25: extern  errno;
  26: char    *index(), *sprintf();
  27: 
  28: rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
  29:     char **ahost;
  30:     u_short rport;
  31:     char *locuser, *remuser, *cmd;
  32:     int *fd2p;
  33: {
  34:     int s, timo = 1, pid, oldmask;
  35:     struct sockaddr_in sin, sin2, from;
  36:     char c;
  37:     int lport = IPPORT_RESERVED - 1;
  38:     struct hostent *hp;
  39: 
  40:     pid = getpid();
  41:     hp = gethostbyname(*ahost);
  42:     if (hp == 0) {
  43:         fprintf(stderr, "%s: unknown host\n", *ahost);
  44:         return (-1);
  45:     }
  46:     *ahost = hp->h_name;
  47:     oldmask = sigblock(sigmask(SIGURG));
  48:     for (;;) {
  49:         s = rresvport(&lport);
  50:         if (s < 0) {
  51:             if (errno == EAGAIN)
  52:                 fprintf(stderr, "socket: All ports in use\n");
  53:             else
  54:                 perror("rcmd: socket");
  55:             sigsetmask(oldmask);
  56:             return (-1);
  57:         }
  58:         fcntl(s, F_SETOWN, pid);
  59:         sin.sin_family = hp->h_addrtype;
  60:         bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
  61:         sin.sin_port = rport;
  62:         if (connect(s, (caddr_t)&sin, sizeof (sin), 0) >= 0)
  63:             break;
  64:         (void) close(s);
  65:         if (errno == EADDRINUSE) {
  66:             lport--;
  67:             continue;
  68:         }
  69:         if (errno == ECONNREFUSED && timo <= 16) {
  70:             sleep(timo);
  71:             timo *= 2;
  72:             continue;
  73:         }
  74:         if (hp->h_addr_list[1] != NULL) {
  75:             int oerrno = errno;
  76: 
  77:             fprintf(stderr,
  78:                 "connect to address %s: ", inet_ntoa(sin.sin_addr));
  79:             errno = oerrno;
  80:             perror(0);
  81:             hp->h_addr_list++;
  82:             bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr,
  83:                 hp->h_length);
  84:             fprintf(stderr, "Trying %s...\n",
  85:                 inet_ntoa(sin.sin_addr));
  86:             continue;
  87:         }
  88:         perror(hp->h_name);
  89:         sigsetmask(oldmask);
  90:         return (-1);
  91:     }
  92:     lport--;
  93:     if (fd2p == 0) {
  94:         write(s, "", 1);
  95:         lport = 0;
  96:     } else {
  97:         char num[8];
  98:         int s2 = rresvport(&lport), s3;
  99:         int len = sizeof (from);
 100: 
 101:         if (s2 < 0)
 102:             goto bad;
 103:         listen(s2, 1);
 104:         (void) sprintf(num, "%d", lport);
 105:         if (write(s, num, strlen(num)+1) != strlen(num)+1) {
 106:             perror("write: setting up stderr");
 107:             (void) close(s2);
 108:             goto bad;
 109:         }
 110:         s3 = accept(s2, &from, &len, 0);
 111:         (void) close(s2);
 112:         if (s3 < 0) {
 113:             perror("accept");
 114:             lport = 0;
 115:             goto bad;
 116:         }
 117:         *fd2p = s3;
 118:         from.sin_port = ntohs((u_short)from.sin_port);
 119:         if (from.sin_family != AF_INET ||
 120:             from.sin_port >= IPPORT_RESERVED) {
 121:             fprintf(stderr,
 122:                 "socket: protocol failure in circuit setup.\n");
 123:             goto bad2;
 124:         }
 125:     }
 126:     (void) write(s, locuser, strlen(locuser)+1);
 127:     (void) write(s, remuser, strlen(remuser)+1);
 128:     (void) write(s, cmd, strlen(cmd)+1);
 129:     if (read(s, &c, 1) != 1) {
 130:         perror(*ahost);
 131:         goto bad2;
 132:     }
 133:     if (c != 0) {
 134:         while (read(s, &c, 1) == 1) {
 135:             (void) write(2, &c, 1);
 136:             if (c == '\n')
 137:                 break;
 138:         }
 139:         goto bad2;
 140:     }
 141:     sigsetmask(oldmask);
 142:     return (s);
 143: bad2:
 144:     if (lport)
 145:         (void) close(*fd2p);
 146: bad:
 147:     (void) close(s);
 148:     sigsetmask(oldmask);
 149:     return (-1);
 150: }
 151: 
 152: rresvport(alport)
 153:     int *alport;
 154: {
 155:     struct sockaddr_in sin;
 156:     int s;
 157: 
 158:     sin.sin_family = AF_INET;
 159:     sin.sin_addr.s_addr = INADDR_ANY;
 160:     s = socket(AF_INET, SOCK_STREAM, 0);
 161:     if (s < 0)
 162:         return (-1);
 163:     for (;;) {
 164:         sin.sin_port = htons((u_short)*alport);
 165:         if (bind(s, (caddr_t)&sin, sizeof (sin)) >= 0)
 166:             return (s);
 167:         if (errno != EADDRINUSE) {
 168:             (void) close(s);
 169:             return (-1);
 170:         }
 171:         (*alport)--;
 172:         if (*alport == IPPORT_RESERVED/2) {
 173:             (void) close(s);
 174:             errno = EAGAIN;     /* close */
 175:             return (-1);
 176:         }
 177:     }
 178: }
 179: 
 180: ruserok(rhost, superuser, ruser, luser)
 181:     char *rhost;
 182:     int superuser;
 183:     char *ruser, *luser;
 184: {
 185:     FILE *hostf;
 186:     char fhost[MAXHOSTNAMELEN];
 187:     int first = 1;
 188:     register char *sp, *p;
 189:     int baselen = -1;
 190: 
 191:     sp = rhost;
 192:     p = fhost;
 193:     while (*sp) {
 194:         if (*sp == '.') {
 195:             if (baselen == -1)
 196:                 baselen = sp - rhost;
 197:             *p++ = *sp++;
 198:         } else {
 199:             *p++ = isupper(*sp) ? tolower(*sp++) : *sp++;
 200:         }
 201:     }
 202:     *p = '\0';
 203:     hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r");
 204: again:
 205:     if (hostf) {
 206:         if (!_validuser(hostf, fhost, luser, ruser, baselen)) {
 207:             (void) fclose(hostf);
 208:             return(0);
 209:         }
 210:         (void) fclose(hostf);
 211:     }
 212:     if (first == 1) {
 213:         struct stat sbuf;
 214:         struct passwd *pwd;
 215:         char pbuf[MAXPATHLEN];
 216: 
 217:         first = 0;
 218:         if ((pwd = getpwnam(luser)) == NULL)
 219:             return(-1);
 220:         (void)strcpy(pbuf, pwd->pw_dir);
 221:         (void)strcat(pbuf, "/.rhosts");
 222:         if ((hostf = fopen(pbuf, "r")) == NULL)
 223:             return(-1);
 224:         (void)fstat(fileno(hostf), &sbuf);
 225:         if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) {
 226:             fclose(hostf);
 227:             return(-1);
 228:         }
 229:         goto again;
 230:     }
 231:     return (-1);
 232: }
 233: 
 234: _validuser(hostf, rhost, luser, ruser, baselen)
 235: char *rhost, *luser, *ruser;
 236: FILE *hostf;
 237: int baselen;
 238: {
 239:     char *user;
 240:     char ahost[MAXHOSTNAMELEN];
 241:     register char *p;
 242: 
 243:     while (fgets(ahost, sizeof (ahost), hostf)) {
 244:         p = ahost;
 245:         while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
 246:             *p = isupper(*p) ? tolower(*p) : *p;
 247:             p++;
 248:         }
 249:         if (*p == ' ' || *p == '\t') {
 250:             *p++ = '\0';
 251:             while (*p == ' ' || *p == '\t')
 252:                 p++;
 253:             user = p;
 254:             while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
 255:                 p++;
 256:         } else
 257:             user = p;
 258:         *p = '\0';
 259:         if (_checkhost(rhost, ahost, baselen) &&
 260:             !strcmp(ruser, *user ? user : luser)) {
 261:             return (0);
 262:         }
 263:     }
 264:     return (-1);
 265: }
 266: 
 267: _checkhost(rhost, lhost, len)
 268: char *rhost, *lhost;
 269: int len;
 270: {
 271:     static char ldomain[MAXHOSTNAMELEN + 1];
 272:     static char *domainp = NULL;
 273:     register char *cp;
 274: 
 275:     if (len == -1)
 276:         return(!strcmp(rhost, lhost));
 277:     if (strncmp(rhost, lhost, len))
 278:         return(0);
 279:     if (!strcmp(rhost, lhost))
 280:         return(1);
 281:     if (*(lhost + len) != '\0')
 282:         return(0);
 283:     if (!domainp) {
 284:         if (gethostname(ldomain, sizeof(ldomain)) == -1) {
 285:             domainp = (char *)1;
 286:             return(0);
 287:         }
 288:         ldomain[MAXHOSTNAMELEN] = NULL;
 289:         if ((domainp = index(ldomain, '.') + 1) == (char *)1)
 290:             return(0);
 291:         cp = domainp;
 292:         while (*cp) {
 293:             *cp = isupper(*cp) ? tolower(*cp) : *cp;
 294:             cp++;
 295:         }
 296:     }
 297:     if (domainp == (char *)1)
 298:         return(0);
 299:     return(!strcmp(domainp, rhost + len +1));
 300: }

Defined functions

_checkhost defined in line 267; used 1 times
_validuser defined in line 234; used 2 times
rresvport defined in line 152; used 4 times

Defined variables

sccsid defined in line 8; never used
Last modified: 1986-05-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1565
Valid CSS Valid XHTML 1.0 Strict