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