home *** CD-ROM | disk | FTP | other *** search
/ Serving the Web / ServingTheWeb1995.disc1of1.iso / linux / slacksrce / d / libc / libc-4.6 / libc-4 / libc-linux / inet / rcmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-31  |  11.7 KB  |  530 lines

  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.17 (Berkeley) 6/27/88";
  20. #endif /* LIBC_SCCS and not lint */
  21.  
  22. #include "inetprivate.h"
  23. #include <pwd.h>
  24. #include <sys/file.h>
  25. #include <sys/signal.h>
  26. #include <sys/stat.h>
  27.  
  28. #if NLS
  29. #include "nl_types.h"
  30. #endif
  31.  
  32. #ifdef YP
  33. #include <rpcsvc/ypclnt.h>
  34. extern void setnetgrent(const char *);
  35. extern void endnetgrent(void);
  36. extern int getnetgrent(char **, char **, char **);
  37. static char *nisdomain = NULL;
  38. static int _checknetgrouphost(const char *, const char *, int);
  39. static int _checknetgroupuser(const char *, const char *);
  40. #endif
  41.  
  42. int
  43. rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
  44.     char **ahost;
  45.     unsigned short rport;
  46.     const char *locuser, *remuser, *cmd;
  47.     int *fd2p;
  48. {
  49.     int s, timo = 1;
  50. #ifdef F_SETOWN
  51.     pid_t pid;
  52. #endif
  53. #ifdef _POSIX_SOURCE
  54.     sigset_t set, oset;
  55. #else
  56.     long oldmask;
  57. #endif
  58.     struct sockaddr_in sin, from;
  59.     char c;
  60.     int lport = IPPORT_RESERVED - 1;
  61.     struct hostent *hp;
  62.  
  63. #if NLS
  64.     libc_nls_init();
  65. #endif
  66.  
  67. #ifdef F_SETOWN
  68.     pid = getpid();
  69. #endif
  70.     hp = gethostbyname(*ahost);
  71.     if (hp == 0) {
  72. #if NLS
  73.         fprintf(stderr, "%s: %s\n", *ahost,
  74.                               catgets(_libc_cat, HerrorListSet,
  75.                       2, "unknown host"));
  76. #else
  77.         fprintf(stderr, "%s: unknown host\n", *ahost);
  78. #endif
  79.         return (-1);
  80.     }
  81.     *ahost = hp->h_name;
  82. #ifdef SIGURG
  83. #ifdef _POSIX_SOURCE
  84.     sigemptyset (&set);
  85.     sigaddset (&set, SIGURG);
  86.     sigprocmask (SIG_BLOCK, &set, &oset);
  87. #else
  88.     oldmask = sigblock(sigmask(SIGURG));
  89. #endif
  90. #endif
  91.     for (;;) {
  92.         s = rresvport(&lport);
  93.         if (s < 0) {
  94.             if (errno == EAGAIN)
  95. #if NLS
  96.                 fprintf(stderr, "socket: %s\n",
  97.                     catgets(_libc_cat, NetMiscSet,
  98.                         NetMiscAllPortsInUse,
  99.                         "All ports in use"));
  100. #else
  101.                 fprintf(stderr, "socket: All ports in use\n");
  102. #endif
  103.             else
  104. #if NLS
  105.                 perror(catgets(_libc_cat, NetMiscSet,
  106.                            NetMiscRcmdSocket,
  107.                            "rcmd: socket"));
  108. #else
  109.                 perror("rcmd: socket");
  110. #endif
  111. #ifdef SIGURG
  112. #ifdef _POSIX_SOURCE
  113.              sigprocmask (SIG_SETMASK, &oset,
  114.                 (sigset_t *)NULL);
  115. #else
  116.             sigsetmask(oldmask);
  117. #endif
  118. #endif
  119.             return (-1);
  120.         }
  121. #ifdef F_SETOWN
  122.         fcntl(s, F_SETOWN, pid);
  123. #endif
  124.         sin.sin_family = hp->h_addrtype;
  125.         bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
  126.         sin.sin_port = rport;
  127.         if (connect(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
  128.             break;
  129.         (void) close(s);
  130.         if (errno == EADDRINUSE) {
  131.             lport--;
  132.             continue;
  133.         }
  134.         if (errno == ECONNREFUSED && timo <= 16) {
  135.             sleep(timo);
  136.             timo *= 2;
  137.             continue;
  138.         }
  139.         if (hp->h_addr_list[1] != NULL) {
  140.             int oerrno = errno;
  141.  
  142.             fprintf(stderr,
  143. #if NLS
  144.                 "%s %s: ", catgets(_libc_cat, NetMiscSet,
  145.                            NetMiscAllPortsInUse,
  146.                            "connect to address"),
  147.                        inet_ntoa(sin.sin_addr));
  148.  
  149. #else
  150.  
  151.                 "connect to address %s: ", inet_ntoa(sin.sin_addr));
  152. #endif
  153.             errno = oerrno;
  154.             perror(0);
  155.             hp->h_addr_list++;
  156.             bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr,
  157.                 hp->h_length);
  158.  
  159. #if NLS
  160.             fprintf(stderr, catgets(_libc_cat, NetMiscSet,
  161.                         NetMiscTrying,
  162.                         "Trying %s...\n"),
  163. #else
  164.             fprintf(stderr,    "Trying %s...\n",
  165. #endif
  166.                 inet_ntoa(sin.sin_addr));
  167.             continue;
  168.         }
  169.         perror(hp->h_name);
  170. #ifdef SIGURG
  171. #ifdef _POSIX_SOURCE
  172.         sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
  173. #else
  174.         sigsetmask(oldmask);
  175. #endif
  176. #endif
  177.         return (-1);
  178.     }
  179.     lport--;
  180.     if (fd2p == 0) {
  181.         write(s, "", 1);
  182.         lport = 0;
  183.     } else {
  184.         char num[8];
  185.         int s2 = rresvport(&lport), s3;
  186.         int len = sizeof (from);
  187.  
  188.         if (s2 < 0)
  189.             goto bad;
  190.         listen(s2, 1);
  191.         (void) snprintf(num, sizeof(num), "%d", lport);
  192.         if (write(s, num, strlen(num)+1) != strlen(num)+1) {
  193. #if NLS
  194.             perror(catgets(_libc_cat, NetMiscSet,
  195.                        NetMiscSettingUpStderr,
  196.                        "write: setting up stderr"));
  197. #else
  198.             perror("write: setting up stderr");
  199. #endif
  200.             (void) close(s2);
  201.             goto bad;
  202.         }
  203.         s3 = accept(s2, (struct sockaddr *)&from, &len);
  204.         (void) close(s2);
  205.         if (s3 < 0) {
  206. #if NLS
  207.             perror(catgets(_libc_cat, NetMiscSet,
  208.                        NetMiscAccept,
  209.                        "accept"));
  210. #else
  211.             perror("accept");
  212. #endif
  213.             lport = 0;
  214.             goto bad;
  215.         }
  216.         *fd2p = s3;
  217.         from.sin_port = ntohs((u_short)from.sin_port);
  218.         if (from.sin_family != AF_INET ||
  219.             from.sin_port >= IPPORT_RESERVED) {
  220.             fprintf(stderr,
  221. #if NLS
  222.                 "%s\n",
  223.                 catgets(_libc_cat, NetMiscSet,
  224.                     NetMiscProtocolFailure,
  225.                     "socket: protocol failure in circuit setup."));
  226. #else
  227.                 "socket: protocol failure in circuit setup.\n");
  228. #endif
  229.             goto bad2;
  230.         }
  231.     }
  232.     (void) write(s, locuser, strlen(locuser)+1);
  233.     (void) write(s, remuser, strlen(remuser)+1);
  234.     (void) write(s, cmd, strlen(cmd)+1);
  235.     if (read(s, &c, 1) != 1) {
  236.         perror(*ahost);
  237.         goto bad2;
  238.     }
  239.     if (c != 0) {
  240.         while (read(s, &c, 1) == 1) {
  241.             (void) write(2, &c, 1);
  242.             if (c == '\n')
  243.                 break;
  244.         }
  245.         goto bad2;
  246.     }
  247. #ifdef SIGURG
  248. #ifdef _POSIX_SOURCE
  249.     sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
  250. #else
  251.     sigsetmask(oldmask);
  252. #endif
  253. #endif
  254.     return (s);
  255. bad2:
  256.     if (lport)
  257.         (void) close(*fd2p);
  258. bad:
  259.     (void) close(s);
  260. #ifdef SIGURG
  261. #ifdef _POSIX_SOURCE
  262.     sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
  263. #else
  264.     sigsetmask(oldmask);
  265. #endif
  266. #endif
  267.     return (-1);
  268. }
  269.  
  270. int
  271. rresvport(alport)
  272.     int *alport;
  273. {
  274.     struct sockaddr_in sin;
  275.     int s;
  276.  
  277.     sin.sin_family = AF_INET;
  278.     sin.sin_addr.s_addr = INADDR_ANY;
  279.     s = socket(AF_INET, SOCK_STREAM, 0);
  280.     if (s < 0)
  281.         return (-1);
  282.     for (;;) {
  283.         sin.sin_port = htons((u_short)*alport);
  284.         if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
  285.             return (s);
  286.         if (errno != EADDRINUSE) {
  287.             (void) close(s);
  288.             return (-1);
  289.         }
  290.         (*alport)--;
  291.         if (*alport == IPPORT_RESERVED/2) {
  292.             (void) close(s);
  293.             errno = EAGAIN;        /* close */
  294.             return (-1);
  295.         }
  296.     }
  297. }
  298.  
  299. int
  300. ruserok(const char *rhost, int superuser, const char *ruser,
  301.     const char *luser)
  302. {
  303.     FILE *hostf;
  304.     char fhost[MAXHOSTNAMELEN];
  305.     int first = 1;
  306.     register const char *sp;
  307.     register char *p;
  308.     int baselen = -1;
  309.     uid_t saveuid;
  310.  
  311.     saveuid = geteuid();
  312.     sp = rhost;
  313.     p = fhost;
  314.     while (*sp) {
  315.         if (*sp == '.') {
  316.             if (baselen == -1)
  317.                 baselen = sp - rhost;
  318.             *p++ = *sp++;
  319.         } else {
  320.             *p++ = isupper(*sp) ? tolower(*sp++) : *sp++;
  321.         }
  322.     }
  323.     *p = '\0';
  324.     hostf = superuser ? (FILE *)0 : fopen(_PATH_HEQUIV, "r");
  325. again:
  326.     if (hostf) {
  327.         if (!_validuser(hostf, fhost, luser, ruser, baselen)) {
  328.             (void) fclose(hostf);
  329.             seteuid(saveuid);
  330.             return(0);
  331.         }
  332.         (void) fclose(hostf);
  333.     }
  334.     if (first == 1) {
  335.         struct stat sbuf;
  336.         struct passwd *pwd;
  337.         char pbuf[MAXPATHLEN];
  338.  
  339.         first = 0;
  340.         if ((pwd = getpwnam(luser)) == NULL)
  341.             return(-1);
  342.         (void)strcpy(pbuf, pwd->pw_dir);
  343.         (void)strcat(pbuf, "/.rhosts");
  344.         (void)seteuid(pwd->pw_uid);
  345.         if ((hostf = fopen(pbuf, "r")) == NULL) {
  346.             seteuid(saveuid);
  347.             return(-1);
  348.         }
  349.         (void)fstat(fileno(hostf), &sbuf);
  350.         if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) {
  351.             fclose(hostf);
  352.             seteuid(saveuid);
  353.             return(-1);
  354.         }
  355.         goto again;
  356.     }
  357.     seteuid(saveuid);
  358.     return (-1);
  359. }
  360.  
  361. int
  362. _validuser(FILE *hostf, const char *rhost, const char *luser,
  363.     const char *ruser, int baselen)
  364. {
  365.     char *user;
  366.     char ahost[MAXHOSTNAMELEN];
  367.     register char *p;
  368. #ifdef YP
  369.     int hostvalid = 0;
  370.     int uservalid = 0;
  371. #endif
  372.  
  373.     while (fgets(ahost, sizeof (ahost), hostf)) {
  374.         p = ahost;
  375.         while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
  376.             *p = isupper(*p) ? tolower(*p) : *p;
  377.             p++;
  378.         }
  379.         if (*p == ' ' || *p == '\t') {
  380.             *p++ = '\0';
  381.             while (*p == ' ' || *p == '\t')
  382.                 p++;
  383.             user = p;
  384.             while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
  385.                 p++;
  386.         } else
  387.             user = p;
  388.         *p = '\0';
  389. #ifdef YP
  390.             /* disable host from -hostname entry */
  391.         if ('-' == ahost[0] && '@' != ahost[1]
  392.             && _checkhost(rhost, &ahost[1], baselen))
  393.           return -1;
  394.             /* disable host from -@netgroup entry for host */
  395.         if ('-' == ahost[0] && '@' == ahost[1] && '\0' != ahost[2]
  396.             && _checknetgrouphost(rhost, &ahost[2], baselen))
  397.           return -1;
  398.             /* disable user from -user entry */
  399.         if ('\0' != *user && user[0] == '-' && user[1] != '@'
  400.             && !strcmp(&user[1], ruser))
  401.           return -1;
  402.             /* disable user from -@netgroup entry for user */
  403.         if ('\0' != *user && user[0] == '-' && user[1] == '@'
  404.             && user[2] != '\0' && _checknetgroupuser(ruser, &user[2]))
  405.           return -1;
  406.             /* enable host from +@netgroup entry for host */
  407.         if ('+' == ahost[0] && '@' == ahost[1] && '\0' != ahost[2])
  408.           hostvalid = _checknetgrouphost(rhost, &ahost[2], baselen);
  409.         else
  410.           hostvalid = _checkhost(rhost, ahost, baselen);
  411.             /* enable user from +@netgroup entry for user */
  412.         if ('\0' != *user && user[0] == '+'
  413.             && user[1] == '@' && user[2] != '\0')
  414.           uservalid = _checknetgroupuser(ruser, &user[2]);
  415.         else
  416.           uservalid = !strcmp(ruser, *user ? user : luser);
  417.         
  418.         if (hostvalid && uservalid)
  419.           return 0;
  420. #else
  421.         if (_checkhost(rhost, ahost, baselen) &&
  422.             !strcmp(ruser, *user ? user : luser)) {
  423.           return (0);
  424.         }
  425. #endif /* YP */
  426.     }
  427.     return (-1);
  428. }
  429.  
  430. int
  431. _checkhost(const char *rhost, const char *lhost, int len)
  432. {
  433.     static char ldomain[MAXHOSTNAMELEN + 1];
  434.     static char *domainp = NULL;
  435.     static int nodomain = 0;
  436.     register char *cp;
  437.  
  438.     if (len == -1)
  439.         return(!strcmp(rhost, lhost));
  440.     if (strncmp(rhost, lhost, len))
  441.         return(0);
  442.     if (!strcmp(rhost, lhost))
  443.         return(1);
  444.     if (*(lhost + len) != '\0')
  445.         return(0);
  446.     if (nodomain)
  447.         return(0);
  448.     if (!domainp) {
  449.         if (gethostname(ldomain, sizeof(ldomain)) == -1) {
  450.             nodomain = 1;
  451.             return(0);
  452.         }
  453.         ldomain[MAXHOSTNAMELEN] = (char) 0;
  454.         if ((domainp = index(ldomain, '.')) == (char *)NULL) {
  455.             nodomain = 1;
  456.             return(0);
  457.         }
  458.         for (cp = ++domainp; *cp; ++cp)
  459.             if (isupper(*cp))
  460.                 *cp = tolower(*cp);
  461.     }
  462.     return(!strcmp(domainp, rhost + len +1));
  463. }
  464.  
  465. #ifdef YP
  466. static int
  467. _checknetgrouphost(const char *rhost, const char *netgr, int baselen)
  468. {
  469.   char *host, *user, *domain;
  470.   int status;
  471.   
  472.   if (NULL == nisdomain)
  473.     yp_get_default_domain(&nisdomain);
  474.   
  475.   setnetgrent(netgr);
  476.   while (1)
  477.     {
  478.       while (1 == (status = getnetgrent(&host, &user, &domain))
  479.              && NULL == host
  480.              && NULL != domain
  481.              && 0 != strcmp(domain, nisdomain))
  482.         ;  /* find valid host entry */
  483.       
  484.       if (0 == status || NULL == host)
  485.         {
  486.           endnetgrent();
  487.           return 0;
  488.         }
  489.  
  490.       if(1 == _checkhost(rhost, host, baselen))
  491.         {
  492.           endnetgrent();
  493.           return 1;
  494.         }
  495.     }
  496. }
  497.  
  498. static int
  499. _checknetgroupuser(const char *ruser, const char *netgr)
  500. {
  501.   char *host, *user, *domain;
  502.   int status;
  503.   
  504.   if (NULL == nisdomain)
  505.     yp_get_default_domain(&nisdomain);
  506.   
  507.   setnetgrent(netgr);
  508.   while (1)
  509.     {
  510.       while (1 == (status = getnetgrent(&host, &user, &domain))
  511.              && NULL == user
  512.              && NULL != domain
  513.              && 0 != strcmp(domain, nisdomain))
  514.         ;  /* find valid user entry */
  515.       
  516.       if (0 == status || NULL == user)
  517.         {
  518.           endnetgrent();
  519.           return 0;
  520.         }
  521.  
  522.       if(0 == strcmp(ruser, user))
  523.         {
  524.           endnetgrent();
  525.           return 1;
  526.         }
  527.     }
  528. }
  529. #endif /* YP */
  530.