|
|
1.1 root 1: #ifndef lint
2: static char *sccsid = "@(#)access.c 1.16 (Berkeley) 10/15/87";
3: #endif
4:
5: #include "common.h"
6: #include <sys/socket.h>
7:
8: #define SNETMATCH 1
9: #define NETMATCH 2
10:
11: /*
12: * host_access -- determine if the client has permission to
13: * read, transfer, and/or post news. read->transfer.
14: * We switch on socket family so as to isolate network dependent code.
15: *
16: * Parameters: "canread" is a pointer to storage for
17: * an integer, which we set to 1 if the
18: * client can read news, 0 otherwise.
19: *
20: * "canpost" is a pointer to storage for
21: * an integer,which we set to 1 if the
22: * client can post news, 0 otherwise.
23: *
24: * "canxfer" is a pointer to storage for
25: * an integer,which we set to 1 if the
26: * client can transfer news, 0 otherwise.
27: *
28: * "gdlist" is a comma separated list of
29: * newsgroups/distributions which the client
30: * can access.
31: *
32: * Returns: Nothing.
33: *
34: * Side effects: None.
35: */
36:
37: #ifdef LOG
38: char hostname[256];
39: #endif
40:
41: host_access(canread, canpost, canxfer, gdlist)
42: int *canread, *canpost, *canxfer;
43: char *gdlist;
44: {
45: int sockt;
46: int length;
47: struct sockaddr sa;
48: int match;
49: int count;
50: char hostornet[MAX_STRLEN];
51: char readperm[MAX_STRLEN];
52: char postperm[MAX_STRLEN];
53: char groups[MAX_STRLEN];
54: char host_name[MAX_STRLEN];
55: char net_name[MAX_STRLEN];
56: char snet_name[MAX_STRLEN];
57: char line[MAX_STRLEN];
58: register char *cp;
59: register FILE *acs_fp;
60:
61: gdlist[0] = '\0';
62:
63: #ifdef DEBUG
64: *canread = *canpost = *canxfer = 1;
65: return;
66: #endif
67:
68: *canread = *canpost = *canxfer = 0;
69:
70: sockt = fileno(stdin);
71: length = sizeof (sa);
72:
73: if (getpeername(sockt, &sa, &length) < 0) {
74: if (isatty(sockt)) {
75: #ifdef LOG
76: (void) strcpy(hostname, "stdin");
77: #endif
78: *canread = 1;
79: } else {
80: #ifdef SYSLOG
81: syslog(LOG_ERR, "host_access: getpeername: %m");
82: #endif
83: #ifdef LOG
84: (void) strcpy(hostname, "unknown");
85: #endif
86: }
87: return;
88: }
89:
90: switch (sa.sa_family) {
91: case AF_INET:
92: inet_netnames(sockt, &sa, net_name, snet_name, host_name);
93: break;
94:
95: #ifdef DECNET
96: case AF_DECnet:
97: dnet_netnames(sockt, &sa, net_name, snet_name, host_name);
98: break;
99: #endif
100:
101: default:
102: #ifdef SYSLOG
103: syslog(LOG_ERR, "unknown address family %ld", sa.sa_family);
104: #endif
105: return;
106: };
107:
108: /* Normalize host name to lower case */
109:
110: for (cp = host_name; *cp; cp++)
111: if (isupper(*cp))
112: *cp = tolower(*cp);
113:
114: #ifdef LOG
115: syslog(LOG_INFO, "%s connect\n", host_name);
116: (void) strcpy(hostname, host_name);
117: #endif
118:
119: /*
120: * We now we have host_name, snet_name, and net_name.
121: * Our strategy at this point is:
122: *
123: * for each line, get the first word
124: *
125: * If it matches "host_name", we have a direct
126: * match; parse and return.
127: *
128: * If it matches "snet_name", we have a subnet match;
129: * parse and set flags.
130: *
131: * If it matches "net_name", we have a net match;
132: * parse and set flags.
133: *
134: * If it matches the literal "default", note we have
135: * a net match; parse.
136: */
137:
138: acs_fp = fopen(accessfile, "r");
139: if (acs_fp == NULL) {
140: #ifdef SYSLOG
141: syslog(LOG_ERR, "access: fopen %s: %m", accessfile);
142: #endif
143: return;
144: }
145:
146: while (fgets(line, sizeof(line), acs_fp) != NULL) {
147: if ((cp = index(line, '\n')) != NULL)
148: *cp = '\0';
149: if ((cp = index(line, '#')) != NULL)
150: *cp = '\0';
151: if (*line == '\0')
152: continue;
153:
154: count = sscanf(line, "%s %s %s %s",
155: hostornet, readperm, postperm, groups);
156:
157: if (count < 4) {
158: if (count < 3)
159: continue;
160: groups[0] = '\0'; /* No groups specified */
161: }
162:
163: if (streql(hostornet, host_name)) {
164: *canread = (readperm[0] == 'r' || readperm[0] == 'R');
165: *canxfer = (*canread || readperm[0] == 'X'
166: || readperm[0] == 'x');
167: *canpost = (postperm[0] == 'p' || postperm[0] == 'P');
168: (void) strcpy(gdlist, groups);
169: break;
170: }
171:
172: if (*snet_name && streql(hostornet, snet_name)) {
173: match = SNETMATCH;
174: *canread = (readperm[0] == 'r' || readperm[0] == 'R');
175: *canxfer = (*canread || readperm[0] == 'X'
176: || readperm[0] == 'x');
177: *canpost = (postperm[0] == 'p' || postperm[0] == 'P');
178: (void) strcpy(gdlist, groups);
179: }
180:
181: if (match != SNETMATCH && (streql(hostornet, net_name) ||
182: streql(hostornet, "default"))) {
183: match = NETMATCH;
184: *canread = (readperm[0] == 'r' || readperm[0] == 'R');
185: *canxfer = (*canread || readperm[0] == 'X'
186: || readperm[0] == 'x');
187: *canpost = (postperm[0] == 'p' || postperm[0] == 'P');
188: (void) strcpy(gdlist, groups);
189: }
190: }
191:
192: (void) fclose(acs_fp);
193: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.