4
* DEBUG: section 28 Access Control
5
* AUTHOR: Duane Wessels
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
13
* SQUID Web Proxy Cache http://www.squid-cache.org/
14
* ----------------------------------------------------------
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.
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.
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.
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.
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 "HttpRequest.h"
51
/* does name lookup, returns page_id */
53
aclGetDenyInfoPage(acl_deny_info_list ** head, const char *name, int redirect_allowed)
55
acl_deny_info_list *A = NULL;
57
debugs(28, 8, HERE << "got called for " << name);
59
for (A = *head; A; A = A->next) {
60
acl_name_list *L = NULL;
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.");
67
for (L = A->acl_list; L; L = L->next) {
68
if (!strcmp(name, L->name)) {
69
debugs(28, 8, HERE << "match on " << name);
70
return A->err_page_id;
76
debugs(28, 8, "aclGetDenyInfoPage: no match");
80
/* does name lookup, returns if it is a proxy_auth acl */
82
aclIsProxyAuth(const char *name)
84
debugs(28, 5, "aclIsProxyAuth: called for " << name);
91
if ((a = ACL::FindByName(name))) {
92
debugs(28, 5, "aclIsProxyAuth: returning " << a->isProxyAuth());
93
return a->isProxyAuth();
96
debugs(28, 3, "aclIsProxyAuth: WARNING, called for nonexistent ACL");
101
/* maex@space.net (05.09.96)
102
* get the info for redirecting "access denied" to info pages
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
111
aclParseDenyInfoLine(acl_deny_info_list ** head)
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;
120
/* first expect a page name */
122
if ((t = strtok(NULL, w_space)) == NULL) {
123
debugs(28, 0, "aclParseDenyInfoLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
124
debugs(28, 0, "aclParseDenyInfoLine: missing 'error page' parameter.");
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 */
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);
142
if (A->acl_list == NULL) {
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");
145
memFree(A, MEM_ACL_DENY_INFO_LIST);
149
for (B = *head, T = head; B; T = &B->next, B = B->next)
151
; /* find the tail */
156
aclParseAccessLine(ConfigParser &parser, acl_access ** head)
159
acl_access *A = NULL;
160
acl_access *B = NULL;
161
acl_access **T = NULL;
163
/* first expect either 'allow' or 'deny' */
165
if ((t = strtok(NULL, w_space)) == NULL) {
166
debugs(28, 0, "aclParseAccessLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
167
debugs(28, 0, "aclParseAccessLine: missing 'allow' or 'deny'.");
173
if (!strcmp(t, "allow"))
174
A->allow = ACCESS_ALLOWED;
175
else if (!strcmp(t, "deny"))
176
A->allow = ACCESS_DENIED;
178
debugs(28, 0, "aclParseAccessLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
179
debugs(28, 0, "aclParseAccessLine: expecting 'allow' or 'deny', got '" << t << "'.");
184
aclParseAclList(parser, &A->aclList);
186
if (A->aclList == NULL) {
187
debugs(28, 0, "" << cfg_filename << " line " << config_lineno << ": " << config_input_line);
188
debugs(28, 0, "aclParseAccessLine: Access line contains no ACL's, skipping");
193
A->cfgline = xstrdup(config_input_line);
194
/* Append to the end of this list */
196
for (B = *head, T = head; B; T = &B->next, B = B->next);
199
/* We lock _acl_access structures in ACLChecklist::check() */
203
aclParseAclList(ConfigParser &parser, ACLList ** head)
205
ACLList **Tail = head; /* sane name in the use below */
209
/* next expect a list of ACL names, possibly preceeded
210
* by '!' for negation */
212
while ((t = strtok(NULL, w_space))) {
213
ACLList *L = new ACLList;
220
debugs(28, 3, "aclParseAclList: looking for ACL name '" << t << "'");
221
a = ACL::FindByName(t);
224
debugs(28, 0, "aclParseAclList: ACL name '" << t << "' not found.");
238
/*********************/
239
/* Destroy functions */
240
/*********************/
243
aclDestroyAcls(ACL ** head)
247
debugs(28, 8, "aclDestroyACLs: invoked");
249
for (ACL *a = *head; a; a = next) {
258
aclDestroyAclList(ACLList ** head)
261
debugs(28, 8, "aclDestroyAclList: invoked");
263
for (l = *head; l; l = *head) {
270
aclDestroyAccessList(acl_access ** list)
272
acl_access *l = NULL;
273
acl_access *next = NULL;
275
for (l = *list; l; l = next) {
276
debugs(28, 3, "aclDestroyAccessList: '" << l->cfgline << "'");
278
aclDestroyAclList(&l->aclList);
279
safe_free(l->cfgline);
286
/* maex@space.net (06.09.1996)
287
* destroy an acl_deny_info_list */
290
aclDestroyDenyInfoList(acl_deny_info_list ** list)
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;
297
debugs(28, 8, "aclDestroyDenyInfoList: invoked");
299
for (a = *list; a; a = a_next) {
300
for (l = a->acl_list; l; l = l_next) {
306
xfree(a->err_page_name);
307
memFree(a, MEM_ACL_DENY_INFO_LIST);