|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T a
Length: 5691 (0x163b) Types: TextFile Names: »access.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit └─⟦cfd40dc56⟧ »EurOpenD3/news/nntp/nntp.1.5.8.tar.Z« └─⟦2ec98eca6⟧ └─⟦this⟧ »server/access.c« └─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit └─⟦5cced586a⟧ »EurOpenD3/news/nntp/nntp.1.5.7.tar.Z« └─⟦7340f105e⟧ └─⟦this⟧ »./server/access.c«
#ifndef lint static char *sccsid = "@(#)access.c 1.21 (Berkeley) 11/04/89"; #endif #include "common.h" #ifdef EXCELAN #include <netinet/in.h> #endif #include <sys/socket.h> #define SNETMATCH 1 #define NETMATCH 2 /* * host_access -- determine if the client has permission to * read, transfer, and/or post news. read->transfer. * We switch on socket family so as to isolate network dependent code. * * Parameters: "canread" is a pointer to storage for * an integer, which we set to 1 if the * client can read news, 0 otherwise. * * "canpost" is a pointer to storage for * an integer,which we set to 1 if the * client can post news, 0 otherwise. * * "canxfer" is a pointer to storage for * an integer,which we set to 1 if the * client can transfer news, 0 otherwise. * * "gdlist" is a comma separated list of * newsgroups/distributions which the client * can access. * * Returns: Nothing. * * Side effects: None. */ #ifdef EXCELAN extern struct sockaddr_in current_peer; #endif #ifdef LOG char hostname[256]; #endif host_access(canread, canpost, canxfer, gdlist) int *canread, *canpost, *canxfer; char *gdlist; { int sockt; int length; struct sockaddr sa; int match; int count; char hostornet[MAXHOSTNAMELEN]; char host_name[MAXHOSTNAMELEN]; char net_name[MAXHOSTNAMELEN]; char snet_name[MAXHOSTNAMELEN]; char readperm[MAXBUFLEN]; char postperm[MAXBUFLEN]; char groups[MAXBUFLEN]; char line[MAXBUFLEN]; register char *cp; register FILE *acs_fp; gdlist[0] = '\0'; #ifdef DEBUG *canread = *canpost = *canxfer = 1; return; #endif *canread = *canpost = *canxfer = 0; sockt = fileno(stdin); length = sizeof (sa); #ifdef EXCELAN if (raddr(current_peer.sin_addr) == NULL) { #else if (getpeername(sockt, &sa, &length) < 0) { #endif if (isatty(sockt)) { #ifdef LOG (void) strcpy(hostname, "stdin"); #endif *canread = 1; } else { #ifdef SYSLOG syslog(LOG_ERR, "host_access: getpeername: %m"); #endif #ifdef LOG (void) strcpy(hostname, "unknown"); #endif } return; } #ifdef EXCELAN else bcopy(¤t_peer,&sa,length); #endif switch (sa.sa_family) { case AF_INET: inet_netnames(sockt, &sa, net_name, snet_name, host_name); break; #ifdef DECNET case AF_DECnet: dnet_netnames(sockt, &sa, net_name, snet_name, host_name); break; #endif default: #ifdef SYSLOG syslog(LOG_ERR, "unknown address family %ld", sa.sa_family); #endif return; }; /* Normalize host name to lower case */ for (cp = host_name; *cp; cp++) if (isupper(*cp)) *cp = tolower(*cp); #ifdef LOG syslog(LOG_INFO, "%s connect\n", host_name); (void) strcpy(hostname, host_name); #endif /* * We now we have host_name, snet_name, and net_name. * Our strategy at this point is: * * for each line, get the first word * * If it matches "host_name", we have a direct * match; parse and return. * * If it matches "snet_name", we have a subnet match; * parse and set flags. * * If it matches "net_name", we have a net match; * parse and set flags. * * If it matches the literal "default", note we have * a net match; parse. */ acs_fp = fopen(accessfile, "r"); if (acs_fp == NULL) { #ifdef SYSLOG syslog(LOG_ERR, "access: fopen %s: %m", accessfile); #endif return; } while (fgets(line, sizeof(line), acs_fp) != NULL) { if ((cp = index(line, '\n')) != NULL) *cp = '\0'; if ((cp = index(line, '#')) != NULL) *cp = '\0'; if (*line == '\0') continue; count = sscanf(line, "%s %s %s %s", hostornet, readperm, postperm, groups); if (count < 4) { if (count < 3) continue; groups[0] = '\0'; /* No groups specified */ } #ifdef DOMAINMATCH if (domainmatch(hostornet,host_name)) { #else if (!strcasecmp(hostornet, host_name)) { #endif *canread = (readperm[0] == 'r' || readperm[0] == 'R'); *canxfer = (*canread || readperm[0] == 'X' || readperm[0] == 'x'); *canpost = (postperm[0] == 'p' || postperm[0] == 'P'); (void) strcpy(gdlist, groups); break; } if (*snet_name && !strcasecmp(hostornet, snet_name)) { match = SNETMATCH; *canread = (readperm[0] == 'r' || readperm[0] == 'R'); *canxfer = (*canread || readperm[0] == 'X' || readperm[0] == 'x'); *canpost = (postperm[0] == 'p' || postperm[0] == 'P'); (void) strcpy(gdlist, groups); } if (match != SNETMATCH && (!strcasecmp(hostornet, net_name) || !strcasecmp(hostornet, "default"))) { match = NETMATCH; *canread = (readperm[0] == 'r' || readperm[0] == 'R'); *canxfer = (*canread || readperm[0] == 'X' || readperm[0] == 'x'); *canpost = (postperm[0] == 'p' || postperm[0] == 'P'); (void) strcpy(gdlist, groups); } } /* * The access check is expects there to be spaces between the group names. * In the access file, there are commas between the groupnames. * Here, we change the commas to spaces. */ { char *pointer=gdlist; while (*pointer) { if (*pointer == ',') *pointer=' '; pointer++; } } (void) fclose(acs_fp); } #ifdef DOMAINMATCH domainmatch(domainsuffix,hostname) char *domainsuffix,*hostname; { char *i; int dlen; #ifdef SYSLOG char * lineptr; lineptr = domainsuffix; #endif if (!strcasecmp(domainsuffix,hostname)) return (1); if (*domainsuffix++ != '*') return (0); if (*domainsuffix++ != '.' ){ #ifdef SYSLOG syslog(LOG_ERR, "%s: no period following asterisk: %s", accessfile, lineptr); #endif return (0); } dlen = strlen(domainsuffix); hostname += (strlen(hostname)-strlen(domainsuffix)); if (!strcasecmp(domainsuffix,hostname)) return (1); return (0); } #endif DOMAINMATCH