1 /*****************************************************************************
2 * FIDOGATE --- Gateway UNIX Mail/News <-> FIDO NetMail/EchoMail
3 *
4 * $Id: acl.c,v 4.3 2000/10/18 21:53:57 mj Exp $
5 *
6 *****************************************************************************/
7
8 #include "fidogate.h"
9
10
11
12 #ifdef AI_8
13
14
15 /*
16 * Local prototypes
17 */
18 static Acl *acl_parse_line (char *);
19 static int acl_do_file (char *);
20 static char *acl_lookup (char *);
21 static void pna_notify_init (char *);
22
23
24 /*
25 * ACL list
26 */
27 static Acl *acl_list = NULL;
28 static Acl *acl_last = NULL;
29
30 static char **pna_notify_list = NULL;
31 static char **ngrp_pat_list = NULL;
32
33
34
acl_parse_line(char * buf)35 static Acl *acl_parse_line(char *buf)
36 {
37 Acl *p;
38
39 char *f, *n;
40
41 f = strtok(buf, " \t"); /* E-Mail address pattern */
42 n = strtok(NULL, " \t"); /* Newsgroup pattern */
43 if(f==NULL || n==NULL)
44 return NULL;
45
46 if(strieq(f, "include"))
47 {
48 acl_do_file(n);
49 return NULL;
50 }
51
52 if(strieq(f, "PostingNotAllowedNotify"))
53 {
54 pna_notify_init(n);
55 return NULL;
56 }
57
58 p = (Acl *)xmalloc(sizeof(Acl));
59 p->next = NULL;
60 p->email_pat = strsave(f);
61 p->ngrp_pat = strsave(n);
62
63 debug(15, "acl: %s %s", p->email_pat, p->ngrp_pat);
64
65 return p;
66 }
67
68
69
acl_do_file(char * name)70 static int acl_do_file(char *name)
71 {
72 FILE *fp;
73 Acl *p;
74
75 debug(14, "Reading ACL file %s", name);
76
77 fp = fopen_expand_name(name, R_MODE_T, FALSE);
78 if(!fp)
79 return ERROR;
80
81 while(cf_getline(buffer, BUFFERSIZE, fp))
82 {
83 p = acl_parse_line(buffer);
84 if(!p)
85 continue;
86
87 /* Put into linked list */
88 if(acl_list)
89 acl_last->next = p;
90 else
91 acl_list = p;
92 acl_last = p;
93 }
94
95 fclose(fp);
96
97 return OK;
98 }
99
100
acl_init(void)101 void acl_init(void)
102 {
103 acl_do_file( cf_p_acl() );
104 }
105
106
acl_lookup(char * email)107 char *acl_lookup(char *email)
108 {
109 Acl *p;
110 char *ngrp = NULL;
111
112 for(p=acl_list; p; p=p->next)
113 {
114 if(wildmat(email, p->email_pat))
115 ngrp = p->ngrp_pat;
116 }
117
118 debug(7, "acl_lookup(): From=%s, ngrp=%s", email, ngrp);
119
120 return ngrp;
121 }
122
123
acl_ngrp(RFCAddr rfc_from)124 void acl_ngrp(RFCAddr rfc_from)
125 {
126 char email[MAXINETADDR];
127
128 BUF_COPY(email, s_rfcaddr_to_asc(&rfc_from, FALSE));
129 list_init(&ngrp_pat_list, acl_lookup(email));
130 }
131
132
acl_ngrp_lookup(char * list)133 int acl_ngrp_lookup(char *list)
134 {
135 static char **ngrp_list = NULL;
136
137 list_init(&ngrp_list, list);
138 return list_match(FALSE, ngrp_pat_list, ngrp_list);
139 }
140
141
142
pna_notify_init(char * list)143 void pna_notify_init(char *list)
144 {
145 list_init(&pna_notify_list, list);
146 }
147
148
pna_notify(char * email)149 int pna_notify(char *email)
150 {
151 static char **email_list = NULL;
152
153 list_init(&email_list, email);
154 return list_match(FALSE, pna_notify_list, email_list);
155 }
156
157
158
159 /*=================================================================*/
160 /* This is part of INN 1.7.2 */
161 /* Modify by Andy Igoshin */
162
163 /* =()<#define DISPOSE(p) free((@<POINTER>@ *)p)>()= */
164 #define DISPOSE(p) free((void *)p)
165
166 #define NEW(T, c) \
167 ((T *)xmalloc((unsigned int)(sizeof (T) * (c))))
168
169 /*
170 ** <ctype.h> usually includes \n, which is not what we want.
171 */
172 #define ISWHITE(c) ((c) == ' ' || (c) == '\t')
173
174
175
176 /*
177 ** Parse a string into a NULL-terminated array of words; return number
178 ** of words. If argvp isn't NULL, it and what it points to will be
179 ** DISPOSE'd.
180 */
181 int
Argify(line,argvp)182 Argify(line, argvp)
183 char *line;
184 char ***argvp;
185 {
186 register char **argv;
187 register char *p;
188 register int i;
189
190 if (*argvp != NULL) {
191 DISPOSE(*argvp[0]);
192 DISPOSE(*argvp);
193 }
194
195 /* Copy the line, which we will split up. */
196 while (ISWHITE(*line))
197 line++;
198 i = strlen(line);
199 p = strsave(line);
200
201 /* Allocate worst-case amount of space. */
202 for (*argvp = argv = NEW(char*, i + 2); *p; ) {
203 /* Mark start of this word, find its end. */
204 for (*argv++ = p; *p && !ISWHITE(*p); )
205 p++;
206 if (*p == '\0')
207 break;
208
209 /* Nip off word, skip whitespace. */
210 for (*p++ = '\0'; ISWHITE(*p); )
211 p++;
212 }
213 *argv = NULL;
214 return argv - *argvp;
215 }
216
217
218
219 /*
220 ** Parse a newsgroups line, return TRUE if there were any.
221 */
list_init(char *** argvp,char * list)222 int list_init(char ***argvp, char *list)
223 {
224 register char *p;
225
226 if(!list)
227 return FALSE;
228
229 for (p = list; *p; p++)
230 if (*p == ',')
231 *p = ' ';
232
233 return Argify(list, argvp) != 0;
234 }
235
236
237
238 /*
239 ** Match a list of newsgroup specifiers against a list of newsgroups.
240 ** func is called to see if there is a match.
241 */
list_match(register int match,char ** Pats,char ** list)242 int list_match(register int match, char **Pats, char **list)
243 {
244 register int i;
245 register char *p;
246
247 if (!Pats)
248 return FALSE;
249 if (!list)
250 return FALSE;
251 if (Pats[0] == NULL)
252 return FALSE;
253
254 for ( ; *list; list++) {
255 for (i = 0; (p = Pats[i]) != NULL; i++) {
256 if (p[0] == '!') {
257 if (wildmat(*list, ++p))
258 match = FALSE;
259 }
260 else if (wildmat(*list, p))
261 match = TRUE;
262 }
263 }
264
265 if (match)
266 return TRUE;
267
268 return FALSE;
269 }
270
271
272 #endif /**AI_8**/
273