home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / tmp9 / rcmd.c < prev    next >
C/C++ Source or Header  |  1997-02-23  |  6KB  |  301 lines

  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. }
  301.