AccessCheck.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9#include "squid.h"
10#include "AccessLogEntry.h"
11#include "acl/FilledChecklist.h"
14#include "adaptation/Config.h"
16#include "adaptation/Service.h"
18#include "base/AsyncJobCalls.h"
19#include "base/TextException.h"
20#include "ConfigParser.h"
21#include "globals.h"
22#include "HttpReply.h"
23#include "HttpRequest.h"
24
26cbdata_type Adaptation::AccessCheck::CBDATA_AccessCheck = CBDATA_UNKNOWN;
29bool
31 HttpRequest *req, HttpReply *rep,
32 const AccessLogEntryPointer &al, Adaptation::Initiator *initiator)
33{
34
35 if (Config::Enabled) {
36 // the new check will call the callback and delete self, eventually
37 AsyncJob::Start(new AccessCheck( // we do not store so not a CbcPointer
38 ServiceFilter(method, vp, req, rep, al), initiator));
39 return true;
40 }
41
42 debugs(83, 3, "adaptation off, skipping");
43 return false;
44}
45
47 Adaptation::Initiator *initiator):
48 AsyncJob("AccessCheck"), filter(aFilter),
49 theInitiator(initiator),
50 acl_checklist(nullptr)
51{
52#if ICAP_CLIENT
54 if (h != nullptr)
55 h->start("ACL");
56#endif
57
58 debugs(93, 5, "AccessCheck constructed for " << filter);
59}
60
62{
63#if ICAP_CLIENT
64 Adaptation::Icap::History::Pointer h = filter.request->icapHistory();
65 if (h != nullptr)
66 h->stop("ACL");
67#endif
68}
69
70void
72{
74
75 if (!usedDynamicRules())
76 check();
77}
78
80bool
82{
83 Adaptation::History::Pointer ah = filter.request->adaptHistory();
84 if (!ah)
85 return false; // dynamic rules not enabled or not triggered
86
87 const auto services = ah->extractCurrentServices(filter); // updates history
88 if (services.empty()) {
89 debugs(85, 5, "no service-proposed rules for " << filter);
90 return false;
91 }
92
93 debugs(85,3, "using stored service-proposed rules: " << services);
94
95 ServiceGroupPointer g = new DynamicServiceChain(services, filter);
96 callBack(g);
97 Must(done());
98 return true;
99}
100
102void
104{
105 debugs(93, 4, "start checking");
106
107 typedef AccessRules::iterator ARI;
108 for (ARI i = AllRules().begin(); i != AllRules().end(); ++i) {
109 AccessRule *r = *i;
110 if (isCandidate(*r)) {
111 debugs(93, 5, "check: rule '" << r->id << "' is a candidate");
112 candidates.push_back(r->id);
113 }
114 }
115
116 checkCandidates();
117}
118
119// XXX: Here and everywhere we call FindRule(topCandidate()):
120// Once we identified the candidate, we should not just ignore it
121// if reconfigure changes rules. We should either lock the rule to
122// prevent reconfigure from stealing it or restart the check with
123// new rules. Throwing an exception may also be appropriate.
124void
126{
127 debugs(93, 4, "has " << candidates.size() << " rules");
128
129 while (!candidates.empty()) {
130 if (AccessRule *r = FindRule(topCandidate())) {
131 /* BUG 2526: what to do when r->acl is empty?? */
132 // XXX: we do not have access to conn->rfc931 here.
133 acl_checklist = new ACLFilledChecklist(r->acl, filter.request, dash_str);
134 if ((acl_checklist->reply = filter.reply))
135 HTTPMSGLOCK(acl_checklist->reply);
136 acl_checklist->al = filter.al;
137 acl_checklist->syncAle(filter.request, nullptr);
138 acl_checklist->nonBlockingCheck(AccessCheckCallbackWrapper, this);
139 return;
140 }
141
142 candidates.erase(candidates.begin()); // the rule apparently went away (reconfigure)
143 }
144
145 debugs(93, 4, "NO candidates left");
146 callBack(nullptr);
147 Must(done());
148}
149
150void
152{
153 debugs(93, 8, "callback answer=" << answer);
154 AccessCheck *ac = (AccessCheck*)data;
155
156 /* TODO: AYJ 2008-06-12: If answer == ACCESS_AUTH_REQUIRED
157 * we should be kicking off an authentication before continuing
158 * with this request. see bug 2400 for details.
159 */
160
161 // convert to async call to get async call protections and features
163 AsyncCall::Pointer call =
164 asyncCall(93,7, "Adaptation::AccessCheck::noteAnswer",
165 MyDialer(ac, &Adaptation::AccessCheck::noteAnswer, answer));
166 ScheduleCallHere(call);
167
168}
169
171void
173{
174 Must(!candidates.empty()); // the candidate we were checking must be there
175 debugs(93,5, topCandidate() << " answer=" << answer);
176
177 if (answer.allowed()) { // the rule matched
178 ServiceGroupPointer g = topGroup();
179 if (g != nullptr) { // the corresponding group found
180 callBack(g);
181 Must(done());
182 return;
183 }
184 }
185
186 // no match or the group disappeared during reconfiguration
187 candidates.erase(candidates.begin());
188 checkCandidates();
189}
190
193void
195{
196 debugs(93,3, g);
197 CallJobHere1(93, 5, theInitiator, Adaptation::Initiator,
198 noteAdaptationAclCheckDone, g);
199 mustStop("done"); // called back or will never be able to call back
200}
201
204{
206 if (candidates.size()) {
207 if (AccessRule *r = FindRule(topCandidate())) {
208 g = FindGroup(r->groupId);
209 debugs(93,5, "top group for " << r->id << " is " << g);
210 } else {
211 debugs(93,5, "no rule for " << topCandidate());
212 }
213 } else {
214 debugs(93,5, "no candidates"); // should not happen
215 }
216
217 return g;
218}
219
222bool
224{
225 debugs(93,7, "checking candidacy of " << r.id << ", group " <<
226 r.groupId);
227
229
230 if (!g) {
231 debugs(93,7, "lost " << r.groupId << " group in rule" << r.id);
232 return false;
233 }
234
235 const bool wants = g->wants(filter);
236 debugs(93,7, r.groupId << (wants ? " wants" : " ignores"));
237 return wants;
238}
239
#define ScheduleCallHere(call)
Definition: AsyncCall.h:166
RefCount< AsyncCallT< Dialer > > asyncCall(int aDebugSection, int aDebugLevel, const char *aName, const Dialer &aDialer)
Definition: AsyncCall.h:156
#define CallJobHere1(debugSection, debugLevel, job, Class, method, arg1)
Definition: AsyncJobCalls.h:63
#define Must(condition)
Definition: TextException.h:75
static const cbdata_type CBDATA_UNKNOWN
Definition: cbdata.h:196
int cbdata_type
Definition: cbdata.h:195
bool allowed() const
Definition: Acl.h:156
const ServiceFilter filter
Definition: AccessCheck.h:47
ServiceGroupPointer topGroup() const
Definition: AccessCheck.cc:203
void callBack(const ServiceGroupPointer &g)
Definition: AccessCheck.cc:194
void noteAnswer(Acl::Answer answer)
process the results of the ACL check
Definition: AccessCheck.cc:172
bool usedDynamicRules()
not done until mustStop
Definition: AccessCheck.cc:81
void check()
Walk the access rules list to find rules with applicable service groups.
Definition: AccessCheck.cc:103
bool isCandidate(AccessRule &r)
Definition: AccessCheck.cc:223
void start() override
called by AsyncStart; do not call directly
Definition: AccessCheck.cc:71
static bool Start(Method method, VectPoint vp, HttpRequest *req, HttpReply *, const AccessLogEntryPointer &, Adaptation::Initiator *)
Definition: AccessCheck.cc:30
AccessCheck(const ServiceFilter &aFilter, Adaptation::Initiator *)
Definition: AccessCheck.cc:46
static void AccessCheckCallbackWrapper(Acl::Answer, void *)
Definition: AccessCheck.cc:151
static bool Enabled
Definition: Config.h:42
a temporary service chain built upon another service request
DynamicGroupCfg extractCurrentServices(const ServiceFilter &)
returns and forgets planned/future services matching the given filter
Definition: History.cc:165
information used to search for adaptation services
Definition: ServiceFilter.h:23
HttpRequest * request
HTTP request being adapted or cause; may be nil.
Definition: ServiceFilter.h:34
bool wants(const ServiceFilter &filter) const
static void Start(const Pointer &job)
Definition: AsyncJob.cc:37
virtual void start()
called by AsyncStart; do not call directly
Definition: AsyncJob.cc:59
Adaptation::Icap::History::Pointer icapHistory() const
Returns possibly nil history, creating it if icap logging is enabled.
Definition: HttpRequest.cc:389
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:194
const char * dash_str
void HTTPMSGLOCK(Http::Message *a)
Definition: Message.h:161
AccessRules & AllRules()
Definition: AccessRule.cc:61
ServiceGroupPointer FindGroup(const ServiceGroup::Id &id)
AccessRule * FindRule(const AccessRule::Id &id)
Definition: AccessRule.cc:69

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors