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