2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 28 Access Control */
12 #include "acl/Checklist.h"
13 #include "acl/Options.h"
14 #include "acl/UserData.h"
15 #include "ConfigParser.h"
16 #include "debug/Stream.h"
18 #include "sbuf/Algorithms.h"
21 Acl::BooleanOptionValue
ACLUserData::CaseInsensitive_
;
24 ACLUserData::match(char const *user
)
26 debugs(28, 7, "user is " << user
<< ", case_insensitive is " << flags
.case_insensitive
);
28 if (user
== nullptr || strcmp(user
, "-") == 0)
32 debugs(28, 7, "aclMatchUser: user REQUIRED and auth-info present.");
36 bool result
= (userDataNames
.find(SBuf(user
)) != userDataNames
.end());
37 debugs(28, 7, "returning " << result
);
42 ACLUserData::dump() const
47 sl
.push_back(SBuf("REQUIRED"));
51 if (flags
.case_insensitive
)
52 sl
.push_back(SBuf("-i"));
54 sl
.insert(sl
.end(), userDataNames
.begin(), userDataNames
.end());
56 debugs(28,5, "ACLUserData dump output: " <<
57 JoinContainerToSBuf(userDataNames
.begin(), userDataNames
.end(),
63 CaseSensitiveSBufCompare(const SBuf
&lhs
, const SBuf
&rhs
)
65 return (lhs
.cmp(rhs
) < 0);
69 CaseInsensitveSBufCompare(const SBuf
&lhs
, const SBuf
&rhs
)
71 return (lhs
.caseCmp(rhs
) < 0);
74 ACLUserData::ACLUserData() :
75 userDataNames(CaseSensitiveSBufCompare
)
77 flags
.case_insensitive
= false;
78 flags
.required
= false;
82 ACLUserData::lineOptions()
84 static auto MyCaseSensitivityOption
= Acl::CaseSensitivityOption();
85 static const Acl::Options MyOptions
= { &MyCaseSensitivityOption
};
86 MyCaseSensitivityOption
.linkWith(&CaseInsensitive_
);
93 debugs(28, 2, "parsing user list");
94 flags
.case_insensitive
= bool(CaseInsensitive_
);
97 if ((t
= ConfigParser::strtokFile())) {
99 debugs(28, 5, "first token is " << s
);
101 if (s
.cmp("-i",2) == 0) {
102 debugs(28, 5, "Going case-insensitive");
103 flags
.case_insensitive
= true;
104 // due to how the std::set API work, if we want to change
105 // the comparison function we have to create a new std::set
106 UserDataNames_t
newUdn(CaseInsensitveSBufCompare
);
107 newUdn
.insert(userDataNames
.begin(), userDataNames
.end());
108 swap(userDataNames
,newUdn
);
109 } else if (s
.cmp("REQUIRED") == 0) {
110 debugs(28, 5, "REQUIRED-type enabled");
111 flags
.required
= true;
113 if (flags
.case_insensitive
)
116 debugs(28, 6, "Adding user " << s
);
117 userDataNames
.insert(s
);
121 debugs(28, 3, "Case-insensitive-switch is " << flags
.case_insensitive
);
122 /* we might inherit from a previous declaration */
124 debugs(28, 4, "parsing following tokens");
126 while ((t
= ConfigParser::strtokFile())) {
128 debugs(28, 6, "Got token: " << s
);
130 if (flags
.case_insensitive
)
133 debugs(28, 6, "Adding user " << s
);
134 userDataNames
.insert(s
);
137 if (flags
.required
&& !userDataNames
.empty()) {
138 debugs(28, DBG_PARSE_NOTE(1), "WARNING: detected attempt to add usernames to an acl of type REQUIRED");
139 userDataNames
.clear();
142 debugs(28,4, "ACL contains " << userDataNames
.size() << " users");
146 ACLUserData::empty() const
148 debugs(28,6,"required: " << flags
.required
<< ", number of users: " << userDataNames
.size());
151 return userDataNames
.empty();