]> git.ipfire.org Git - thirdparty/squid.git/blame - src/acl_noncore.cc
Extracted transaction state storage and related checks from ACLChecklist into
[thirdparty/squid.git] / src / acl_noncore.cc
CommitLineData
d295d770 1/*
262a0e14 2 * $Id$
d295d770 3 *
4 * DEBUG: section 28 Access Control
5 * AUTHOR: Duane Wessels
6 *
26ac0430 7 * This file contains ACL routines that are not part of the
d295d770 8 * ACL class, nor any other class yet, and that need to be
26ac0430 9 * factored into appropriate places. They are here to reduce
d295d770 10 * unneeded dependencies between the ACL class and the rest
11 * of squid.
26ac0430 12 *
d295d770 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.
26ac0430 29 *
d295d770 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.
26ac0430 34 *
d295d770 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.h"
43#include "ACLChecklist.h"
d295d770 44#include "ConfigParser.h"
aa839030 45#include "errorpage.h"
a9f20260 46#include "HttpRequest.h"
d295d770 47
48
49/* does name lookup, returns page_id */
50err_type
9ce7856a 51aclGetDenyInfoPage(acl_deny_info_list ** head, const char *name, int redirect_allowed)
d295d770 52{
53 acl_deny_info_list *A = NULL;
d295d770 54
99697e8e 55 debugs(28, 8, HERE << "got called for " << name);
d295d770 56
9ce7856a 57 for (A = *head; A; A = A->next) {
58 acl_name_list *L = NULL;
d295d770 59
99697e8e
AJ
60 if (!redirect_allowed && strchr(A->err_page_name, ':') ) {
61 debugs(28, 8, HERE << "Skip '" << A->err_page_name << "' 30x redirects not allowed as response here.");
d295d770 62 continue;
63 }
64
9ce7856a 65 for (L = A->acl_list; L; L = L->next) {
d295d770 66 if (!strcmp(name, L->name)) {
99697e8e 67 debugs(28, 8, HERE << "match on " << name);
d295d770 68 return A->err_page_id;
69 }
70
d295d770 71 }
d295d770 72 }
73
bf8fe701 74 debugs(28, 8, "aclGetDenyInfoPage: no match");
d295d770 75 return ERR_NONE;
76}
77
78/* does name lookup, returns if it is a proxy_auth acl */
79int
80aclIsProxyAuth(const char *name)
81{
bf8fe701 82 debugs(28, 5, "aclIsProxyAuth: called for " << name);
d295d770 83
84 if (NULL == name)
85 return false;
86
87 ACL *a;
88
89 if ((a = ACL::FindByName(name))) {
bf8fe701 90 debugs(28, 5, "aclIsProxyAuth: returning " << a->isProxyAuth());
d295d770 91 return a->isProxyAuth();
92 }
93
bf8fe701 94 debugs(28, 3, "aclIsProxyAuth: WARNING, called for nonexistent ACL");
d295d770 95 return false;
96}
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
108void
109aclParseDenyInfoLine(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) {
bf8fe701 121 debugs(28, 0, "aclParseDenyInfoLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
122 debugs(28, 0, "aclParseDenyInfoLine: missing 'error page' parameter.");
d295d770 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) {
bf8fe701 141 debugs(28, 0, "aclParseDenyInfoLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
142 debugs(28, 0, "aclParseDenyInfoLine: deny_info line contains no ACL's, skipping");
d295d770 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
153void
a9f20260 154aclParseAccessLine(ConfigParser &parser, acl_access ** head)
d295d770 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) {
bf8fe701 164 debugs(28, 0, "aclParseAccessLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
165 debugs(28, 0, "aclParseAccessLine: missing 'allow' or 'deny'.");
d295d770 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 {
bf8fe701 176 debugs(28, 0, "aclParseAccessLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
177 debugs(28, 0, "aclParseAccessLine: expecting 'allow' or 'deny', got '" << t << "'.");
d295d770 178 delete A;
179 return;
180 }
181
a9f20260 182 aclParseAclList(parser, &A->aclList);
d295d770 183
184 if (A->aclList == NULL) {
bf8fe701 185 debugs(28, 0, "" << cfg_filename << " line " << config_lineno << ": " << config_input_line);
186 debugs(28, 0, "aclParseAccessLine: Access line contains no ACL's, skipping");
d295d770 187 delete A;
188 return;
189 }
190
191 A->cfgline = xstrdup(config_input_line);
192 /* Append to the end of this list */
193
3d0ac046 194 for (B = *head, T = head; B; T = &B->next, B = B->next);
d295d770 195 *T = A;
196
197 /* We lock _acl_access structures in ACLChecklist::check() */
198}
199
200void
76cd39d7 201aclParseAclList(ConfigParser &parser, ACLList ** head)
d295d770 202{
76cd39d7 203 ACLList **Tail = head; /* sane name in the use below */
d295d770 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))) {
76cd39d7 211 ACLList *L = new ACLList;
d295d770 212
213 if (*t == '!') {
214 L->negated (true);
215 t++;
216 }
217
bf8fe701 218 debugs(28, 3, "aclParseAccessLine: looking for ACL name '" << t << "'");
d295d770 219 a = ACL::FindByName(t);
220
221 if (a == NULL) {
bf8fe701 222 debugs(28, 0, "aclParseAccessLine: ACL name '" << t << "' not found.");
d295d770 223 delete L;
a9f20260 224 parser.destruct();
d295d770 225 continue;
226 }
227
228 L->_acl = a;
229 *Tail = L;
230 Tail = &L->next;
231 }
232}
233
234
235
236/*********************/
237/* Destroy functions */
238/*********************/
239
240void
241aclDestroyAcls(ACL ** head)
242{
243 ACL *next = NULL;
244
bf8fe701 245 debugs(28, 8, "aclDestroyACLs: invoked");
d295d770 246
247 for (ACL *a = *head; a; a = next) {
248 next = a->next;
249 delete a;
250 }
251
252 *head = NULL;
253}
254
255void
76cd39d7 256aclDestroyAclList(ACLList ** head)
d295d770 257{
76cd39d7 258 ACLList *l;
bf8fe701 259 debugs(28, 8, "aclDestroyAclList: invoked");
d295d770 260
261 for (l = *head; l; l = *head) {
262 *head = l->next;
263 delete l;
264 }
265}
266
267void
268aclDestroyAccessList(acl_access ** list)
269{
270 acl_access *l = NULL;
271 acl_access *next = NULL;
272
273 for (l = *list; l; l = next) {
bf8fe701 274 debugs(28, 3, "aclDestroyAccessList: '" << l->cfgline << "'");
d295d770 275 next = l->next;
276 aclDestroyAclList(&l->aclList);
277 safe_free(l->cfgline);
278 cbdataFree(l);
279 }
280
281 *list = NULL;
282}
283
284/* maex@space.net (06.09.1996)
e1f7507e 285 * destroy an acl_deny_info_list */
d295d770 286
287void
288aclDestroyDenyInfoList(acl_deny_info_list ** list)
289{
290 acl_deny_info_list *a = NULL;
291 acl_deny_info_list *a_next = NULL;
292 acl_name_list *l = NULL;
293 acl_name_list *l_next = NULL;
294
bf8fe701 295 debugs(28, 8, "aclDestroyDenyInfoList: invoked");
d295d770 296
297 for (a = *list; a; a = a_next) {
298 for (l = a->acl_list; l; l = l_next) {
299 l_next = l->next;
300 safe_free(l);
301 }
302
303 a_next = a->next;
304 xfree(a->err_page_name);
305 memFree(a, MEM_ACL_DENY_INFO_LIST);
306 }
307
308 *list = NULL;
309}
310
311/*
312 * This function traverses all ACL elements referenced
26ac0430 313 * by an access list (presumably 'http_access'). If
d295d770 314 * it finds a PURGE method ACL, then it returns TRUE,
315 * otherwise FALSE.
316 */
317/* XXX: refactor this more sensibly. perhaps have the parser detect it ? */
318int
319aclPurgeMethodInUse(acl_access * a)
320{
321 return a->containsPURGE();
322}