home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NNTP-1.000 / NNTP-1 / nntp.1.5.11t / server / access.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-17  |  5.9 KB  |  271 lines

  1. #ifndef lint
  2. static char    *sccsid = "@(#)$Header: access.c,v 1.23 90/08/10 22:58:39 sob Exp $";
  3. #endif
  4.  
  5. #include "common.h"
  6. #ifdef EXCELAN
  7. #include <netinet/in.h>
  8. #endif
  9. #include <sys/socket.h>
  10.  
  11. #define    SNETMATCH    1
  12. #define    NETMATCH    2
  13.  
  14. /*
  15.  * host_access -- determine if the client has permission to
  16.  * read, transfer, and/or post news.  read->transfer.
  17.  * We switch on socket family so as to isolate network dependent code.
  18.  *
  19.  *    Parameters:    "canread" is a pointer to storage for
  20.  *            an integer, which we set to 1 if the
  21.  *            client can read news, 0 otherwise.
  22.  *
  23.  *            "canpost" is a pointer to storage for
  24.  *            an integer,which we set to 1 if the
  25.  *            client can post news, 0 otherwise.
  26.  *
  27.  *            "canxfer" is a pointer to storage for
  28.  *            an integer,which we set to 1 if the
  29.  *            client can transfer news, 0 otherwise.
  30.  *
  31.  *            "gdlist" is a comma separated list of
  32.  *            newsgroups/distributions which the client
  33.  *            can access.
  34.  *
  35.  *    Returns:    Nothing.
  36.  *
  37.  *    Side effects:    None.
  38.  */
  39.  
  40. #ifdef EXCELAN
  41. extern struct sockaddr_in current_peer;
  42. #endif
  43.  
  44.  
  45. #ifdef AUTH
  46. extern    int Needauth;
  47. #endif AUTH
  48.  
  49. host_access(canread, canpost, canxfer, gdlist)
  50.     int        *canread, *canpost, *canxfer;
  51.     char        *gdlist;
  52. {
  53.     int        sockt;
  54.     int        length;
  55.     struct sockaddr    sa;
  56.     int        match = 0;
  57.     int        count;
  58.     char        hostornet[MAXHOSTNAMELEN];
  59.     char        host_name[MAXHOSTNAMELEN];
  60.     char        net_name[MAXHOSTNAMELEN];
  61.     char        snet_name[MAXHOSTNAMELEN];
  62.     char        readperm[MAXBUFLEN];
  63.     char        postperm[MAXBUFLEN];
  64.     char        groups[MAXBUFLEN];
  65.     char        line[MAXBUFLEN];
  66.     register char    *cp;
  67.     register FILE    *acs_fp;
  68.  
  69.     gdlist[0] = '\0';
  70.  
  71. #ifdef DEBUG
  72.     *canread = *canpost = *canxfer = 1;
  73.     return;
  74. #endif
  75.  
  76.     *canread = *canpost = *canxfer = 0;
  77.  
  78.     sockt = fileno(stdin);
  79.     length = sizeof (sa);
  80.  
  81. #ifdef EXCELAN
  82.     if (raddr(current_peer.sin_addr) == NULL) {
  83. #else
  84.     if (getpeername(sockt, &sa, &length) < 0) {
  85. #endif
  86.         if (isatty(sockt)) {
  87.             (void) strcpy(hostname, "stdin");
  88.             *canread = 1;
  89.         } else {
  90. #ifdef SYSLOG
  91.             syslog(LOG_ERR, "host_access: getpeername: %m");
  92. #endif
  93.             (void) strcpy(hostname, "unknown");
  94.         }
  95.         return;
  96.     }
  97. #ifdef EXCELAN
  98.     else bcopy(¤t_peer,&sa,length);
  99. #endif
  100.  
  101.     switch (sa.sa_family) {
  102.     case AF_INET:
  103.         inet_netnames(sockt, &sa, net_name, snet_name, host_name);
  104.         break;
  105.  
  106. #ifdef DECNET
  107.     case AF_DECnet:
  108.         dnet_netnames(sockt, &sa, net_name, snet_name, host_name);
  109.         break;
  110. #endif
  111.  
  112.     default:
  113. #ifdef SYSLOG
  114.         syslog(LOG_ERR, "unknown address family %ld", sa.sa_family);
  115. #endif
  116.         return;
  117.     };
  118.  
  119.     /* Normalize host name to lower case */
  120.  
  121.     for (cp = host_name; *cp; cp++)
  122.         if (isupper(*cp))
  123.             *cp = tolower(*cp);
  124.  
  125. #ifdef LOG
  126.     syslog(LOG_INFO, "%s connect\n", host_name);
  127. #endif
  128.     (void) strcpy(hostname, host_name);
  129.  
  130.     /*
  131.      * We now we have host_name, snet_name, and net_name.
  132.      * Our strategy at this point is:
  133.      *
  134.      * for each line, get the first word
  135.      *
  136.      *    If it matches "host_name", we have a direct
  137.      *        match; parse and return.
  138.      *
  139.      *    If it matches "snet_name", we have a subnet match;
  140.      *        parse and set flags.
  141.      *
  142.      *    If it matches "net_name", we have a net match;
  143.      *        parse and set flags.
  144.      *
  145.      *    If it matches the literal "default", note we have
  146.      *        a net match; parse.
  147.      */
  148.  
  149.     acs_fp = fopen(accessfile, "r");
  150.     if (acs_fp == NULL) {
  151. #ifdef SYSLOG
  152.         syslog(LOG_ERR, "access: fopen %s: %m", accessfile);
  153. #endif
  154.         return;
  155.     }
  156.  
  157.     while (fgets(line, sizeof(line), acs_fp) != NULL) {
  158.         if ((cp = index(line, '\n')) != NULL)
  159.             *cp = '\0';
  160.         if ((cp = index(line, '#')) != NULL)
  161.             *cp = '\0';
  162.         if (*line == '\0')
  163.             continue;
  164.  
  165.         count = sscanf(line, "%s %s %s %s",
  166.                 hostornet, readperm, postperm, groups);
  167.  
  168.         if (count < 4) {
  169.             if (count < 3)
  170.                 continue;
  171.             groups[0] = '\0';    /* No groups specified */
  172.         }
  173. #ifdef DOMAINMATCH
  174.          if (domainmatch(hostornet,host_name)) {
  175. #else
  176.         if (!strcasecmp(hostornet, host_name)) {
  177. #endif
  178.             *canread = (readperm[0] == 'r' || readperm[0] == 'R');
  179.             *canxfer = (readperm[0] == 'X'
  180.                          || readperm[0] == 'x');
  181.             if (readperm[0] == 'B' || readperm[0] == 'b')
  182.                 *canxfer = *canread = 1;
  183.             *canpost = (postperm[0] == 'p' || postperm[0] == 'P');
  184.             (void) strcpy(gdlist, groups);
  185.             break;
  186.         }
  187.  
  188.         if (*snet_name && !strcasecmp(hostornet, snet_name)) {
  189.             match = SNETMATCH;
  190.             *canread = (readperm[0] == 'r' || readperm[0] == 'R');
  191.             *canxfer = (readperm[0] == 'X'
  192.                          || readperm[0] == 'x');
  193.             if (readperm[0] == 'B' || readperm[0] == 'b')
  194.                 *canxfer = *canread = 1;
  195.             *canpost = (postperm[0] == 'p' || postperm[0] == 'P');
  196.             (void) strcpy(gdlist, groups);
  197.         }
  198.  
  199.         if (match != SNETMATCH && (!strcasecmp(hostornet, net_name) ||
  200.             !strcasecmp(hostornet, "default"))) {
  201.             match = NETMATCH;
  202.             *canread = (readperm[0] == 'r' || readperm[0] == 'R');
  203.             *canxfer = (readperm[0] == 'X'
  204.                          || readperm[0] == 'x');
  205.             if (readperm[0] == 'B' || readperm[0] == 'b')
  206.                 *canxfer = *canread = 1;
  207.             *canpost = (postperm[0] == 'p' || postperm[0] == 'P');
  208.             (void) strcpy(gdlist, groups);
  209.         }
  210.     }
  211. /*
  212.  * The access check expects there to be spaces between the group names.
  213.  * In the access file, there are commas between the groupnames.
  214.  * Here, we change the commas to spaces.
  215.  */
  216.          {
  217.        char *pointer=gdlist;
  218.        
  219.        while (*pointer)
  220.          {
  221.            if (*pointer == ',') *pointer=' ';
  222.            pointer++;
  223.          }
  224.      }
  225.  
  226.     (void) fclose(acs_fp);
  227.  
  228. #ifdef AUTH
  229.     Needauth = 0;
  230.     /* do we require a userid and password for this guy? */
  231.     if (isupper(readperm[0]) || isupper(postperm[0]))
  232.         Needauth = 1;
  233. #endif AUTH
  234. }
  235.  
  236. #ifdef DOMAINMATCH
  237.  
  238. domainmatch(domainsuffix,hostname)
  239. char *domainsuffix,*hostname;
  240. {
  241.      char *i;
  242.     int dlen;
  243. #ifdef SYSLOG
  244.     char * lineptr;
  245.     lineptr = domainsuffix;
  246. #endif
  247.  
  248.     if (!strcasecmp(domainsuffix,hostname)) 
  249.         return (1);
  250.  
  251.     if (*domainsuffix++ != '*')
  252.         return (0);
  253.  
  254.     if (*domainsuffix++ != '.' ){
  255. #ifdef SYSLOG
  256.         syslog(LOG_ERR, "%s: no period following asterisk: %s",
  257.              accessfile, lineptr);
  258. #endif
  259.         return (0);
  260.     }
  261.     dlen = strlen(domainsuffix);
  262.  
  263.     hostname += (strlen(hostname)-strlen(domainsuffix));
  264.  
  265.     if (!strcasecmp(domainsuffix,hostname)) 
  266.         return (1);
  267.  
  268.     return (0);
  269. }
  270. #endif DOMAINMATCH
  271.