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