]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/Gadgets.cc
Merged from trunk
[thirdparty/squid.git] / src / acl / Gadgets.cc
1 /*
2 * $Id$
3 *
4 * DEBUG: section 28 Access Control
5 * AUTHOR: Duane Wessels
6 *
7 * This file contains ACL routines that are not part of the
8 * ACL class, nor any other class yet, and that need to be
9 * factored into appropriate places. They are here to reduce
10 * unneeded dependencies between the ACL class and the rest
11 * of squid.
12 *
13 * SQUID Web Proxy Cache http://www.squid-cache.org/
14 * ----------------------------------------------------------
15 *
16 * Squid is the result of efforts by numerous individuals from
17 * the Internet community; see the CONTRIBUTORS file for full
18 * details. Many organizations have provided support for Squid's
19 * development; see the SPONSORS file for full details. Squid is
20 * Copyrighted (C) 2001 by the Regents of the University of
21 * California; see the COPYRIGHT file for full details. Squid
22 * incorporates software developed and/or copyrighted by other
23 * sources; see the CREDITS file for full details.
24 *
25 * This program is free software; you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License as published by
27 * the Free Software Foundation; either version 2 of the License, or
28 * (at your option) any later version.
29 *
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
34 *
35 * You should have received a copy of the GNU General Public License
36 * along with this program; if not, write to the Free Software
37 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
38 *
39 */
40
41 #include "squid.h"
42 #include "acl/Acl.h"
43 #include "acl/Checklist.h"
44 #include "acl/Strategised.h"
45 #include "acl/Gadgets.h"
46 #include "ConfigParser.h"
47 #include "errorpage.h"
48 #include "globals.h"
49 #include "HttpRequest.h"
50 #include "Mem.h"
51 #include "protos.h"
52
53
54 /* does name lookup, returns page_id */
55 err_type
56 aclGetDenyInfoPage(acl_deny_info_list ** head, const char *name, int redirect_allowed)
57 {
58 acl_deny_info_list *A = NULL;
59
60 debugs(28, 8, HERE << "got called for " << name);
61
62 for (A = *head; A; A = A->next) {
63 acl_name_list *L = NULL;
64
65 if (!redirect_allowed && strchr(A->err_page_name, ':') ) {
66 debugs(28, 8, HERE << "Skip '" << A->err_page_name << "' 30x redirects not allowed as response here.");
67 continue;
68 }
69
70 for (L = A->acl_list; L; L = L->next) {
71 if (!strcmp(name, L->name)) {
72 debugs(28, 8, HERE << "match on " << name);
73 return A->err_page_id;
74 }
75
76 }
77 }
78
79 debugs(28, 8, "aclGetDenyInfoPage: no match");
80 return ERR_NONE;
81 }
82
83 /* does name lookup, returns if it is a proxy_auth acl */
84 int
85 aclIsProxyAuth(const char *name)
86 {
87 debugs(28, 5, "aclIsProxyAuth: called for " << name);
88
89 if (NULL == name)
90 return false;
91
92 ACL *a;
93
94 if ((a = ACL::FindByName(name))) {
95 debugs(28, 5, "aclIsProxyAuth: returning " << a->isProxyAuth());
96 return a->isProxyAuth();
97 }
98
99 debugs(28, 3, "aclIsProxyAuth: WARNING, called for nonexistent ACL");
100 return false;
101 }
102
103
104 /* maex@space.net (05.09.96)
105 * get the info for redirecting "access denied" to info pages
106 * TODO (probably ;-)
107 * currently there is no optimization for
108 * - more than one deny_info line with the same url
109 * - a check, whether the given acl really is defined
110 * - a check, whether an acl is added more than once for the same url
111 */
112
113 void
114 aclParseDenyInfoLine(acl_deny_info_list ** head)
115 {
116 char *t = NULL;
117 acl_deny_info_list *A = NULL;
118 acl_deny_info_list *B = NULL;
119 acl_deny_info_list **T = NULL;
120 acl_name_list *L = NULL;
121 acl_name_list **Tail = NULL;
122
123 /* first expect a page name */
124
125 if ((t = strtok(NULL, w_space)) == NULL) {
126 debugs(28, DBG_CRITICAL, "aclParseDenyInfoLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
127 debugs(28, DBG_CRITICAL, "aclParseDenyInfoLine: missing 'error page' parameter.");
128 return;
129 }
130
131 A = (acl_deny_info_list *)memAllocate(MEM_ACL_DENY_INFO_LIST);
132 A->err_page_id = errorReservePageId(t);
133 A->err_page_name = xstrdup(t);
134 A->next = (acl_deny_info_list *) NULL;
135 /* next expect a list of ACL names */
136 Tail = &A->acl_list;
137
138 while ((t = strtok(NULL, w_space))) {
139 L = (acl_name_list *)memAllocate(MEM_ACL_NAME_LIST);
140 xstrncpy(L->name, t, ACL_NAME_SZ);
141 *Tail = L;
142 Tail = &L->next;
143 }
144
145 if (A->acl_list == NULL) {
146 debugs(28, DBG_CRITICAL, "aclParseDenyInfoLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
147 debugs(28, DBG_CRITICAL, "aclParseDenyInfoLine: deny_info line contains no ACL's, skipping");
148 memFree(A, MEM_ACL_DENY_INFO_LIST);
149 return;
150 }
151
152 for (B = *head, T = head; B; T = &B->next, B = B->next)
153
154 ; /* find the tail */
155 *T = A;
156 }
157
158 void
159 aclParseAccessLine(ConfigParser &parser, acl_access ** head)
160 {
161 char *t = NULL;
162 acl_access *A = NULL;
163 acl_access *B = NULL;
164 acl_access **T = NULL;
165
166 /* first expect either 'allow' or 'deny' */
167
168 if ((t = strtok(NULL, w_space)) == NULL) {
169 debugs(28, DBG_CRITICAL, "aclParseAccessLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
170 debugs(28, DBG_CRITICAL, "aclParseAccessLine: missing 'allow' or 'deny'.");
171 return;
172 }
173
174 A = new acl_access;
175
176 if (!strcmp(t, "allow"))
177 A->allow = ACCESS_ALLOWED;
178 else if (!strcmp(t, "deny"))
179 A->allow = ACCESS_DENIED;
180 else {
181 debugs(28, DBG_CRITICAL, "aclParseAccessLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
182 debugs(28, DBG_CRITICAL, "aclParseAccessLine: expecting 'allow' or 'deny', got '" << t << "'.");
183 delete A;
184 return;
185 }
186
187 aclParseAclList(parser, &A->aclList);
188
189 if (A->aclList == NULL) {
190 debugs(28, DBG_CRITICAL, "" << cfg_filename << " line " << config_lineno << ": " << config_input_line);
191 debugs(28, DBG_CRITICAL, "aclParseAccessLine: Access line contains no ACL's, skipping");
192 delete A;
193 return;
194 }
195
196 A->cfgline = xstrdup(config_input_line);
197 /* Append to the end of this list */
198
199 for (B = *head, T = head; B; T = &B->next, B = B->next);
200 *T = A;
201
202 /* We lock _acl_access structures in ACLChecklist::matchNonBlocking() */
203 }
204
205 void
206 aclParseAclList(ConfigParser &parser, ACLList ** head)
207 {
208 ACLList **Tail = head; /* sane name in the use below */
209 ACL *a = NULL;
210 char *t;
211
212 /* next expect a list of ACL names, possibly preceeded
213 * by '!' for negation */
214
215 while ((t = strtok(NULL, w_space))) {
216 ACLList *L = new ACLList;
217
218 if (*t == '!') {
219 L->negated (true);
220 ++t;
221 }
222
223 debugs(28, 3, "aclParseAclList: looking for ACL name '" << t << "'");
224 a = ACL::FindByName(t);
225
226 if (a == NULL) {
227 debugs(28, DBG_CRITICAL, "aclParseAclList: ACL name '" << t << "' not found.");
228 delete L;
229 parser.destruct();
230 continue;
231 }
232
233 L->_acl = a;
234 *Tail = L;
235 Tail = &L->next;
236 }
237 }
238
239
240
241 /*********************/
242 /* Destroy functions */
243 /*********************/
244
245 void
246 aclDestroyAcls(ACL ** head)
247 {
248 ACL *next = NULL;
249
250 debugs(28, 8, "aclDestroyACLs: invoked");
251
252 for (ACL *a = *head; a; a = next) {
253 next = a->next;
254 delete a;
255 }
256
257 *head = NULL;
258 }
259
260 void
261 aclDestroyAclList(ACLList ** head)
262 {
263 ACLList *l;
264 debugs(28, 8, "aclDestroyAclList: invoked");
265
266 for (l = *head; l; l = *head) {
267 *head = l->next;
268 delete l;
269 }
270 }
271
272 void
273 aclDestroyAccessList(acl_access ** list)
274 {
275 acl_access *l = NULL;
276 acl_access *next = NULL;
277
278 for (l = *list; l; l = next) {
279 debugs(28, 3, "aclDestroyAccessList: '" << l->cfgline << "'");
280 next = l->next;
281 aclDestroyAclList(&l->aclList);
282 safe_free(l->cfgline);
283 cbdataFree(l);
284 }
285
286 *list = NULL;
287 }
288
289 /* maex@space.net (06.09.1996)
290 * destroy an acl_deny_info_list */
291
292 void
293 aclDestroyDenyInfoList(acl_deny_info_list ** list)
294 {
295 acl_deny_info_list *a = NULL;
296 acl_deny_info_list *a_next = NULL;
297 acl_name_list *l = NULL;
298 acl_name_list *l_next = NULL;
299
300 debugs(28, 8, "aclDestroyDenyInfoList: invoked");
301
302 for (a = *list; a; a = a_next) {
303 for (l = a->acl_list; l; l = l_next) {
304 l_next = l->next;
305 safe_free(l);
306 }
307
308 a_next = a->next;
309 xfree(a->err_page_name);
310 memFree(a, MEM_ACL_DENY_INFO_LIST);
311 }
312
313 *list = NULL;
314 }