]>
Commit | Line | Data |
---|---|---|
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 | ||
f7f3304a | 41 | #include "squid-old.h" |
c15d448c AR |
42 | #include "acl/Acl.h" |
43 | #include "acl/Checklist.h" | |
44 | #include "acl/Strategised.h" | |
45 | #include "acl/Gadgets.h" | |
d295d770 | 46 | #include "ConfigParser.h" |
aa839030 | 47 | #include "errorpage.h" |
a9f20260 | 48 | #include "HttpRequest.h" |
d295d770 | 49 | |
50 | ||
51 | /* does name lookup, returns page_id */ | |
52 | err_type | |
9ce7856a | 53 | aclGetDenyInfoPage(acl_deny_info_list ** head, const char *name, int redirect_allowed) |
d295d770 | 54 | { |
55 | acl_deny_info_list *A = NULL; | |
d295d770 | 56 | |
99697e8e | 57 | debugs(28, 8, HERE << "got called for " << name); |
d295d770 | 58 | |
9ce7856a | 59 | for (A = *head; A; A = A->next) { |
60 | acl_name_list *L = NULL; | |
d295d770 | 61 | |
99697e8e AJ |
62 | if (!redirect_allowed && strchr(A->err_page_name, ':') ) { |
63 | debugs(28, 8, HERE << "Skip '" << A->err_page_name << "' 30x redirects not allowed as response here."); | |
d295d770 | 64 | continue; |
65 | } | |
66 | ||
9ce7856a | 67 | for (L = A->acl_list; L; L = L->next) { |
d295d770 | 68 | if (!strcmp(name, L->name)) { |
99697e8e | 69 | debugs(28, 8, HERE << "match on " << name); |
d295d770 | 70 | return A->err_page_id; |
71 | } | |
72 | ||
d295d770 | 73 | } |
d295d770 | 74 | } |
75 | ||
bf8fe701 | 76 | debugs(28, 8, "aclGetDenyInfoPage: no match"); |
d295d770 | 77 | return ERR_NONE; |
78 | } | |
79 | ||
80 | /* does name lookup, returns if it is a proxy_auth acl */ | |
81 | int | |
82 | aclIsProxyAuth(const char *name) | |
83 | { | |
bf8fe701 | 84 | debugs(28, 5, "aclIsProxyAuth: called for " << name); |
d295d770 | 85 | |
86 | if (NULL == name) | |
87 | return false; | |
88 | ||
89 | ACL *a; | |
90 | ||
91 | if ((a = ACL::FindByName(name))) { | |
bf8fe701 | 92 | debugs(28, 5, "aclIsProxyAuth: returning " << a->isProxyAuth()); |
d295d770 | 93 | return a->isProxyAuth(); |
94 | } | |
95 | ||
bf8fe701 | 96 | debugs(28, 3, "aclIsProxyAuth: WARNING, called for nonexistent ACL"); |
d295d770 | 97 | return false; |
98 | } | |
99 | ||
100 | ||
101 | /* maex@space.net (05.09.96) | |
102 | * get the info for redirecting "access denied" to info pages | |
103 | * TODO (probably ;-) | |
104 | * currently there is no optimization for | |
105 | * - more than one deny_info line with the same url | |
106 | * - a check, whether the given acl really is defined | |
107 | * - a check, whether an acl is added more than once for the same url | |
108 | */ | |
109 | ||
110 | void | |
111 | aclParseDenyInfoLine(acl_deny_info_list ** head) | |
112 | { | |
113 | char *t = NULL; | |
114 | acl_deny_info_list *A = NULL; | |
115 | acl_deny_info_list *B = NULL; | |
116 | acl_deny_info_list **T = NULL; | |
117 | acl_name_list *L = NULL; | |
118 | acl_name_list **Tail = NULL; | |
119 | ||
120 | /* first expect a page name */ | |
121 | ||
122 | if ((t = strtok(NULL, w_space)) == NULL) { | |
bf8fe701 | 123 | debugs(28, 0, "aclParseDenyInfoLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line); |
124 | debugs(28, 0, "aclParseDenyInfoLine: missing 'error page' parameter."); | |
d295d770 | 125 | return; |
126 | } | |
127 | ||
128 | A = (acl_deny_info_list *)memAllocate(MEM_ACL_DENY_INFO_LIST); | |
129 | A->err_page_id = errorReservePageId(t); | |
130 | A->err_page_name = xstrdup(t); | |
131 | A->next = (acl_deny_info_list *) NULL; | |
132 | /* next expect a list of ACL names */ | |
133 | Tail = &A->acl_list; | |
134 | ||
135 | while ((t = strtok(NULL, w_space))) { | |
136 | L = (acl_name_list *)memAllocate(MEM_ACL_NAME_LIST); | |
137 | xstrncpy(L->name, t, ACL_NAME_SZ); | |
138 | *Tail = L; | |
139 | Tail = &L->next; | |
140 | } | |
141 | ||
142 | if (A->acl_list == NULL) { | |
bf8fe701 | 143 | debugs(28, 0, "aclParseDenyInfoLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line); |
144 | debugs(28, 0, "aclParseDenyInfoLine: deny_info line contains no ACL's, skipping"); | |
d295d770 | 145 | memFree(A, MEM_ACL_DENY_INFO_LIST); |
146 | return; | |
147 | } | |
148 | ||
149 | for (B = *head, T = head; B; T = &B->next, B = B->next) | |
150 | ||
151 | ; /* find the tail */ | |
152 | *T = A; | |
153 | } | |
154 | ||
155 | void | |
a9f20260 | 156 | aclParseAccessLine(ConfigParser &parser, acl_access ** head) |
d295d770 | 157 | { |
158 | char *t = NULL; | |
159 | acl_access *A = NULL; | |
160 | acl_access *B = NULL; | |
161 | acl_access **T = NULL; | |
162 | ||
163 | /* first expect either 'allow' or 'deny' */ | |
164 | ||
165 | if ((t = strtok(NULL, w_space)) == NULL) { | |
bf8fe701 | 166 | debugs(28, 0, "aclParseAccessLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line); |
167 | debugs(28, 0, "aclParseAccessLine: missing 'allow' or 'deny'."); | |
d295d770 | 168 | return; |
169 | } | |
170 | ||
171 | A = new acl_access; | |
172 | ||
173 | if (!strcmp(t, "allow")) | |
174 | A->allow = ACCESS_ALLOWED; | |
175 | else if (!strcmp(t, "deny")) | |
176 | A->allow = ACCESS_DENIED; | |
177 | else { | |
bf8fe701 | 178 | debugs(28, 0, "aclParseAccessLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line); |
179 | debugs(28, 0, "aclParseAccessLine: expecting 'allow' or 'deny', got '" << t << "'."); | |
d295d770 | 180 | delete A; |
181 | return; | |
182 | } | |
183 | ||
a9f20260 | 184 | aclParseAclList(parser, &A->aclList); |
d295d770 | 185 | |
186 | if (A->aclList == NULL) { | |
bf8fe701 | 187 | debugs(28, 0, "" << cfg_filename << " line " << config_lineno << ": " << config_input_line); |
188 | debugs(28, 0, "aclParseAccessLine: Access line contains no ACL's, skipping"); | |
d295d770 | 189 | delete A; |
190 | return; | |
191 | } | |
192 | ||
193 | A->cfgline = xstrdup(config_input_line); | |
194 | /* Append to the end of this list */ | |
195 | ||
3d0ac046 | 196 | for (B = *head, T = head; B; T = &B->next, B = B->next); |
d295d770 | 197 | *T = A; |
198 | ||
2efeb0b7 | 199 | /* We lock _acl_access structures in ACLChecklist::matchNonBlocking() */ |
d295d770 | 200 | } |
201 | ||
202 | void | |
76cd39d7 | 203 | aclParseAclList(ConfigParser &parser, ACLList ** head) |
d295d770 | 204 | { |
76cd39d7 | 205 | ACLList **Tail = head; /* sane name in the use below */ |
d295d770 | 206 | ACL *a = NULL; |
207 | char *t; | |
208 | ||
209 | /* next expect a list of ACL names, possibly preceeded | |
210 | * by '!' for negation */ | |
211 | ||
212 | while ((t = strtok(NULL, w_space))) { | |
76cd39d7 | 213 | ACLList *L = new ACLList; |
d295d770 | 214 | |
215 | if (*t == '!') { | |
216 | L->negated (true); | |
217 | t++; | |
218 | } | |
219 | ||
8b215224 | 220 | debugs(28, 3, "aclParseAclList: looking for ACL name '" << t << "'"); |
d295d770 | 221 | a = ACL::FindByName(t); |
222 | ||
223 | if (a == NULL) { | |
8b215224 | 224 | debugs(28, 0, "aclParseAclList: ACL name '" << t << "' not found."); |
d295d770 | 225 | delete L; |
a9f20260 | 226 | parser.destruct(); |
d295d770 | 227 | continue; |
228 | } | |
229 | ||
230 | L->_acl = a; | |
231 | *Tail = L; | |
232 | Tail = &L->next; | |
233 | } | |
234 | } | |
235 | ||
236 | ||
237 | ||
238 | /*********************/ | |
239 | /* Destroy functions */ | |
240 | /*********************/ | |
241 | ||
242 | void | |
243 | aclDestroyAcls(ACL ** head) | |
244 | { | |
245 | ACL *next = NULL; | |
246 | ||
bf8fe701 | 247 | debugs(28, 8, "aclDestroyACLs: invoked"); |
d295d770 | 248 | |
249 | for (ACL *a = *head; a; a = next) { | |
250 | next = a->next; | |
251 | delete a; | |
252 | } | |
253 | ||
254 | *head = NULL; | |
255 | } | |
256 | ||
257 | void | |
76cd39d7 | 258 | aclDestroyAclList(ACLList ** head) |
d295d770 | 259 | { |
76cd39d7 | 260 | ACLList *l; |
bf8fe701 | 261 | debugs(28, 8, "aclDestroyAclList: invoked"); |
d295d770 | 262 | |
263 | for (l = *head; l; l = *head) { | |
264 | *head = l->next; | |
265 | delete l; | |
266 | } | |
267 | } | |
268 | ||
269 | void | |
270 | aclDestroyAccessList(acl_access ** list) | |
271 | { | |
272 | acl_access *l = NULL; | |
273 | acl_access *next = NULL; | |
274 | ||
275 | for (l = *list; l; l = next) { | |
bf8fe701 | 276 | debugs(28, 3, "aclDestroyAccessList: '" << l->cfgline << "'"); |
d295d770 | 277 | next = l->next; |
278 | aclDestroyAclList(&l->aclList); | |
279 | safe_free(l->cfgline); | |
280 | cbdataFree(l); | |
281 | } | |
282 | ||
283 | *list = NULL; | |
284 | } | |
285 | ||
286 | /* maex@space.net (06.09.1996) | |
e1f7507e | 287 | * destroy an acl_deny_info_list */ |
d295d770 | 288 | |
289 | void | |
290 | aclDestroyDenyInfoList(acl_deny_info_list ** list) | |
291 | { | |
292 | acl_deny_info_list *a = NULL; | |
293 | acl_deny_info_list *a_next = NULL; | |
294 | acl_name_list *l = NULL; | |
295 | acl_name_list *l_next = NULL; | |
296 | ||
bf8fe701 | 297 | debugs(28, 8, "aclDestroyDenyInfoList: invoked"); |
d295d770 | 298 | |
299 | for (a = *list; a; a = a_next) { | |
300 | for (l = a->acl_list; l; l = l_next) { | |
301 | l_next = l->next; | |
302 | safe_free(l); | |
303 | } | |
304 | ||
305 | a_next = a->next; | |
306 | xfree(a->err_page_name); | |
307 | memFree(a, MEM_ACL_DENY_INFO_LIST); | |
308 | } | |
309 | ||
310 | *list = NULL; | |
311 | } |