1: #ifndef lint 2: static char *sccsid = "@(#)access.c 1.4 (Berkeley) 3/12/86"; 3: #endif 4: 5: #include "common.h" 6: #include <sys/socket.h> 7: #include <netinet/in.h> 8: #include <arpa/inet.h> 9: #include <netdb.h> 10: 11: /* 12: * host_access -- determine if the client has permission to 13: * read, transfer, and/or post news. read->transfer. 14: * 15: * Parameters: "read" is a pointer to storage for 16: * an integer, which we set to 1 if the 17: * client can read news, 0 otherwise. 18: * 19: * "post" is a pointer to storage for 20: * an integer,which we set to 1 if the 21: * client can post news, 0 otherwise. 22: * 23: * Returns: Nothing. 24: * 25: * Side effects: None. 26: */ 27: 28: #ifdef LOG 29: char hostname[256]; 30: #endif 31: 32: host_access(canread, canpost, canxfer) 33: int *canread, *canpost, *canxfer; 34: { 35: char hostornet[MAX_STRLEN]; 36: char readperm[MAX_STRLEN], postperm[MAX_STRLEN]; 37: char host_name[MAX_STRLEN], net_name[MAX_STRLEN]; 38: char line[MAX_STRLEN]; 39: char *cp; 40: int ncanread, ncanpost, ncanxfer; 41: int netmatch; 42: int count, sockt, length; 43: unsigned long net_addr; 44: struct netent *np; 45: struct sockaddr_in sin; 46: struct hostent *hp; 47: FILE *acs_fp; 48: 49: *canread = *canpost = *canxfer = 0; 50: 51: sockt = fileno(stdin); 52: length = sizeof (struct sockaddr_in); 53: #ifdef DEBUG 54: *canread = *canpost = *canxfer = 1; 55: return; 56: #endif 57: 58: if (getpeername(sockt, (struct sockaddr *) &sin, &length) < 0) { 59: if (isatty(sockt)) { 60: #ifdef LOG 61: (void) strcpy(hostname, "stdin"); 62: #endif 63: *canread = 1; 64: } else { 65: syslog(LOG_ERR, "host_access: getpeername: %m"); 66: #ifdef LOG 67: (void) strcpy(hostname, "unknown"); 68: #endif 69: } 70: return; 71: } 72: 73: /* 74: * At this point, sin.sin_addr.s_addr is the address of 75: * the host in network order. 76: */ 77: 78: net_addr = inet_netof(sin.sin_addr); /* net_addr in host order */ 79: 80: np = getnetbyaddr(net_addr, AF_INET); 81: if (np != NULL) 82: (void) strcpy(net_name, np->n_name); 83: else 84: (void) strcpy(net_name,inet_ntoa(*(struct in_addr *)&net_addr)); 85: 86: hp = gethostbyaddr((char *) &sin.sin_addr.s_addr, sizeof(long), 87: AF_INET); 88: if (hp != NULL) 89: (void) strcpy(host_name, hp->h_name); 90: else 91: (void) strcpy(host_name, inet_ntoa(sin.sin_addr)); 92: 93: #ifdef LOG 94: syslog(LOG_INFO, "%s connect\n", host_name); 95: (void) strcpy(hostname, host_name); 96: #endif 97: 98: /* 99: * So, now we have host_name and net_name. 100: * Our strategy at this point is: 101: * 102: * for each line, get the first word 103: * 104: * If it matches "host_name", we have a direct 105: * match; parse and return. 106: * 107: * If it matches "net_name", we have a net match; 108: * parse and set flags. 109: * 110: * If it matches the literal "default", note we have 111: * a net match; parse. 112: */ 113: 114: acs_fp = fopen(ACCESS_FILE, "r"); 115: if (acs_fp == NULL) 116: return; 117: 118: while (fgets(line, sizeof(line), acs_fp) != NULL) { 119: if ((cp = index(line, '\n')) != NULL) 120: *cp = '\0'; 121: if ((cp = index(line, '#')) != NULL) 122: *cp = '\0'; 123: if (*line == '\0') 124: continue; 125: 126: count = sscanf(line, "%s %s %s", hostornet, readperm, postperm); 127: 128: if (count < 3) 129: continue; 130: 131: if (strcmp(hostornet, host_name) == 0) { 132: *canread = (readperm[0] == 'r' || readperm[0] == 'R'); 133: *canxfer = (*canread || readperm[0] == 'X' 134: || readperm[0] == 'x'); 135: *canpost = (postperm[0] == 'p' || postperm[0] == 'P'); 136: (void) fclose(acs_fp); 137: return; 138: } 139: 140: if (strcmp(hostornet, net_name) == 0 || 141: strcmp(hostornet, "default") == 0) { 142: netmatch = 1; 143: ncanread = (readperm[0] == 'r' || readperm[0] == 'R'); 144: ncanxfer = (ncanread || readperm[0] == 'X' 145: || readperm[0] == 'x'); 146: ncanpost = (postperm[0] == 'p' || postperm[0] == 'P'); 147: } 148: } 149: 150: (void) fclose(acs_fp); 151: 152: if (netmatch) { 153: *canread = ncanread; 154: *canpost = ncanpost; 155: *canxfer = ncanxfer; 156: } 157: }