]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/UserData.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / acl / UserData.cc
1 /*
2 * Copyright (C) 1996-2020 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 /* DEBUG: section 28 Access Control */
10
11 #include "squid.h"
12 #include "acl/Checklist.h"
13 #include "acl/UserData.h"
14 #include "ConfigParser.h"
15 #include "Debug.h"
16 #include "globals.h"
17 #include "sbuf/Algorithms.h"
18 #include "util.h"
19
20 const Acl::ParameterFlags &
21 ACLUserData::supportedFlags() const
22 {
23 static const Acl::ParameterFlags flagNames = { "-i", "+i" };
24 return flagNames;
25 }
26
27 bool
28 ACLUserData::match(char const *user)
29 {
30 debugs(28, 7, "user is " << user << ", case_insensitive is " << flags.case_insensitive);
31
32 if (user == NULL || strcmp(user, "-") == 0)
33 return 0;
34
35 if (flags.required) {
36 debugs(28, 7, "aclMatchUser: user REQUIRED and auth-info present.");
37 return 1;
38 }
39
40 bool result = (userDataNames.find(SBuf(user)) != userDataNames.end());
41 debugs(28, 7, "returning " << result);
42 return result;
43 }
44
45 SBufList
46 ACLUserData::dump() const
47 {
48 SBufList sl;
49
50 if (flags.required) {
51 sl.push_back(SBuf("REQUIRED"));
52 return sl;
53 }
54
55 if (flags.case_insensitive)
56 sl.push_back(SBuf("-i"));
57
58 sl.insert(sl.end(), userDataNames.begin(), userDataNames.end());
59
60 debugs(28,5, "ACLUserData dump output: " <<
61 JoinContainerToSBuf(userDataNames.begin(), userDataNames.end(),
62 SBuf(" ")));
63 return sl;
64 }
65
66 static bool
67 CaseSensitiveSBufCompare(const SBuf &lhs, const SBuf &rhs)
68 {
69 return (lhs.cmp(rhs) < 0);
70 }
71
72 static bool
73 CaseInsensitveSBufCompare(const SBuf &lhs, const SBuf &rhs)
74 {
75 return (lhs.caseCmp(rhs) < 0);
76 }
77
78 ACLUserData::ACLUserData() :
79 userDataNames(CaseSensitiveSBufCompare)
80 {
81 flags.case_insensitive = false;
82 flags.required = false;
83 }
84
85 void
86 ACLUserData::parse()
87 {
88 debugs(28, 2, "parsing user list");
89
90 char *t = NULL;
91 if ((t = ConfigParser::strtokFile())) {
92 SBuf s(t);
93 debugs(28, 5, "first token is " << s);
94
95 if (s.cmp("-i",2) == 0) {
96 debugs(28, 5, "Going case-insensitive");
97 flags.case_insensitive = true;
98 // due to how the std::set API work, if we want to change
99 // the comparison function we have to create a new std::set
100 UserDataNames_t newUdn(CaseInsensitveSBufCompare);
101 newUdn.insert(userDataNames.begin(), userDataNames.end());
102 swap(userDataNames,newUdn);
103 } else if (s.cmp("REQUIRED") == 0) {
104 debugs(28, 5, "REQUIRED-type enabled");
105 flags.required = true;
106 } else {
107 if (flags.case_insensitive)
108 s.toLower();
109
110 debugs(28, 6, "Adding user " << s);
111 userDataNames.insert(s);
112 }
113 }
114
115 debugs(28, 3, "Case-insensitive-switch is " << flags.case_insensitive);
116 /* we might inherit from a previous declaration */
117
118 debugs(28, 4, "parsing following tokens");
119
120 while ((t = ConfigParser::strtokFile())) {
121 SBuf s(t);
122 debugs(28, 6, "Got token: " << s);
123
124 if (flags.case_insensitive)
125 s.toLower();
126
127 debugs(28, 6, "Adding user " << s);
128 userDataNames.insert(s);
129 }
130
131 if (flags.required && !userDataNames.empty()) {
132 debugs(28, DBG_PARSE_NOTE(1), "WARNING: detected attempt to add usernames to an acl of type REQUIRED");
133 userDataNames.clear();
134 }
135
136 debugs(28,4, "ACL contains " << userDataNames.size() << " users");
137 }
138
139 bool
140 ACLUserData::empty() const
141 {
142 debugs(28,6,"required: " << flags.required << ", number of users: " << userDataNames.size());
143 if (flags.required)
144 return false;
145 return userDataNames.empty();
146 }
147
148 ACLData<char const *> *
149 ACLUserData::clone() const
150 {
151 return new ACLUserData;
152 }
153