1: #ifndef lint 2: static char *sccsid = "@(#)access.c 1.19 (Berkeley) 2/6/88"; 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: #ifdef LOG 45: char hostname[256]; 46: #endif 47: 48: host_access(canread, canpost, canxfer, gdlist) 49: int *canread, *canpost, *canxfer; 50: char *gdlist; 51: { 52: int sockt; 53: int length; 54: struct sockaddr sa; 55: int match; 56: int count; 57: char hostornet[MAXHOSTNAMELEN]; 58: char host_name[MAXHOSTNAMELEN]; 59: char net_name[MAXHOSTNAMELEN]; 60: char snet_name[MAXHOSTNAMELEN]; 61: char readperm[MAXBUFLEN]; 62: char postperm[MAXBUFLEN]; 63: char groups[MAXBUFLEN]; 64: char line[MAXBUFLEN]; 65: register char *cp; 66: register FILE *acs_fp; 67: 68: gdlist[0] = '\0'; 69: 70: #ifdef DEBUG 71: *canread = *canpost = *canxfer = 1; 72: return; 73: #endif 74: 75: *canread = *canpost = *canxfer = 0; 76: 77: sockt = fileno(stdin); 78: length = sizeof (sa); 79: 80: #ifdef EXCELAN 81: if (raddr(current_peer.sin_addr) == NULL) { 82: #else 83: if (getpeername(sockt, &sa, &length) < 0) { 84: #endif 85: if (isatty(sockt)) { 86: #ifdef LOG 87: (void) strcpy(hostname, "stdin"); 88: #endif 89: *canread = 1; 90: } else { 91: #ifdef SYSLOG 92: syslog(LOG_ERR, "host_access: getpeername: %m"); 93: #endif 94: #ifdef LOG 95: (void) strcpy(hostname, "unknown"); 96: #endif 97: } 98: return; 99: } 100: #ifdef EXCELAN 101: else bcopy(¤t_peer,&sa,length); 102: #endif 103: 104: switch (sa.sa_family) { 105: case AF_INET: 106: inet_netnames(sockt, &sa, net_name, snet_name, host_name); 107: break; 108: 109: #ifdef DECNET 110: case AF_DECnet: 111: dnet_netnames(sockt, &sa, net_name, snet_name, host_name); 112: break; 113: #endif 114: 115: default: 116: #ifdef SYSLOG 117: syslog(LOG_ERR, "unknown address family %ld", sa.sa_family); 118: #endif 119: return; 120: }; 121: 122: /* Normalize host name to lower case */ 123: 124: for (cp = host_name; *cp; cp++) 125: if (isupper(*cp)) 126: *cp = tolower(*cp); 127: 128: #ifdef LOG 129: syslog(LOG_INFO, "%s connect\n", host_name); 130: (void) strcpy(hostname, host_name); 131: #endif 132: 133: /* 134: * We now we have host_name, snet_name, and net_name. 135: * Our strategy at this point is: 136: * 137: * for each line, get the first word 138: * 139: * If it matches "host_name", we have a direct 140: * match; parse and return. 141: * 142: * If it matches "snet_name", we have a subnet match; 143: * parse and set flags. 144: * 145: * If it matches "net_name", we have a net match; 146: * parse and set flags. 147: * 148: * If it matches the literal "default", note we have 149: * a net match; parse. 150: */ 151: 152: acs_fp = fopen(accessfile, "r"); 153: if (acs_fp == NULL) { 154: #ifdef SYSLOG 155: syslog(LOG_ERR, "access: fopen %s: %m", accessfile); 156: #endif 157: return; 158: } 159: 160: while (fgets(line, sizeof(line), acs_fp) != NULL) { 161: if ((cp = index(line, '\n')) != NULL) 162: *cp = '\0'; 163: if ((cp = index(line, '#')) != NULL) 164: *cp = '\0'; 165: if (*line == '\0') 166: continue; 167: 168: count = sscanf(line, "%s %s %s %s", 169: hostornet, readperm, postperm, groups); 170: 171: if (count < 4) { 172: if (count < 3) 173: continue; 174: groups[0] = '\0'; /* No groups specified */ 175: } 176: 177: if (!strcasecmp(hostornet, host_name)) { 178: *canread = (readperm[0] == 'r' || readperm[0] == 'R'); 179: *canxfer = (*canread || readperm[0] == 'X' 180: || readperm[0] == 'x'); 181: *canpost = (postperm[0] == 'p' || postperm[0] == 'P'); 182: (void) strcpy(gdlist, groups); 183: break; 184: } 185: 186: if (*snet_name && !strcasecmp(hostornet, snet_name)) { 187: match = SNETMATCH; 188: *canread = (readperm[0] == 'r' || readperm[0] == 'R'); 189: *canxfer = (*canread || readperm[0] == 'X' 190: || readperm[0] == 'x'); 191: *canpost = (postperm[0] == 'p' || postperm[0] == 'P'); 192: (void) strcpy(gdlist, groups); 193: } 194: 195: if (match != SNETMATCH && (!strcasecmp(hostornet, net_name) || 196: !strcasecmp(hostornet, "default"))) { 197: match = NETMATCH; 198: *canread = (readperm[0] == 'r' || readperm[0] == 'R'); 199: *canxfer = (*canread || readperm[0] == 'X' 200: || readperm[0] == 'x'); 201: *canpost = (postperm[0] == 'p' || postperm[0] == 'P'); 202: (void) strcpy(gdlist, groups); 203: } 204: } 205: 206: (void) fclose(acs_fp); 207: }