]> git.ipfire.org Git - thirdparty/squid.git/blob - src/auth/AclMaxUserIp.cc
Merge from trunk
[thirdparty/squid.git] / src / auth / AclMaxUserIp.cc
1 /*
2 * DEBUG: section 28 Access Control
3 * AUTHOR: Duane Wessels
4 */
5
6 #include "squid.h"
7 #include "acl/FilledChecklist.h"
8 #include "auth/Acl.h"
9 #include "auth/AclMaxUserIp.h"
10 #include "auth/UserRequest.h"
11 #include "ConfigParser.h"
12 #include "Debug.h"
13 #include "Parsing.h"
14 #include "wordlist.h"
15
16 ACLFlag ACLMaxUserIP::SupportedFlags[] = {ACL_F_STRICT, ACL_F_END};
17
18 ACLMaxUserIP::ACLMaxUserIP(char const *theClass) :
19 ACL(SupportedFlags),
20 class_(theClass),
21 maximum(0)
22 {}
23
24 ACLMaxUserIP::ACLMaxUserIP(ACLMaxUserIP const &old) :
25 class_(old.class_),
26 maximum(old.maximum)
27 {
28 flags = old.flags;
29 }
30
31 ACLMaxUserIP::~ACLMaxUserIP()
32 {}
33
34 ACL *
35 ACLMaxUserIP::clone() const
36 {
37 return new ACLMaxUserIP(*this);
38 }
39
40 char const *
41 ACLMaxUserIP::typeString() const
42 {
43 return class_;
44 }
45
46 bool
47 ACLMaxUserIP::empty() const
48 {
49 return false;
50 }
51
52 bool
53 ACLMaxUserIP::valid() const
54 {
55 return maximum > 0;
56 }
57
58 void
59 ACLMaxUserIP::parse()
60 {
61 if (maximum) {
62 debugs(28, DBG_IMPORTANT, "Attempting to alter already set User max IP acl");
63 return;
64 }
65
66 char *t = ConfigParser::strtokFile();
67
68 if (!t)
69 return;
70
71 debugs(28, 5, "aclParseUserMaxIP: First token is " << t);
72
73 maximum = xatoi(t);
74
75 debugs(28, 5, "aclParseUserMaxIP: Max IP address's " << maximum);
76
77 return;
78 }
79
80 /*
81 * aclMatchUserMaxIP - check for users logging in from multiple IP's
82 * 0 : No match
83 * 1 : Match
84 */
85 int
86 ACLMaxUserIP::match(Auth::UserRequest::Pointer auth_user_request, Ip::Address const &src_addr)
87 {
88 /*
89 * the logic for flush the ip list when the limit is hit vs keep
90 * it sorted in most recent access order and just drop the oldest
91 * one off is currently undecided (RBC)
92 */
93
94 if (authenticateAuthUserRequestIPCount(auth_user_request) <= maximum)
95 return 0;
96
97 debugs(28, DBG_IMPORTANT, "aclMatchUserMaxIP: user '" << auth_user_request->username() << "' tries to use too many IP addresses (max " << maximum << " allowed)!");
98
99 /* this is a match */
100 if (flags.isSet(ACL_F_STRICT)) {
101 /*
102 * simply deny access - the user name is already associated with
103 * the request
104 */
105 /* remove _this_ ip, as it is the culprit for going over the limit */
106 authenticateAuthUserRequestRemoveIp(auth_user_request, src_addr);
107 debugs(28, 4, "aclMatchUserMaxIP: Denying access in strict mode");
108 } else {
109 /*
110 * non-strict - remove some/all of the cached entries
111 * ie to allow the user to move machines easily
112 */
113 authenticateAuthUserRequestClearIp(auth_user_request);
114 debugs(28, 4, "aclMatchUserMaxIP: Denying access in non-strict mode - flushing the user ip cache");
115 }
116
117 return 1;
118 }
119
120 int
121 ACLMaxUserIP::match(ACLChecklist *cl)
122 {
123 ACLFilledChecklist *checklist = Filled(cl);
124 allow_t answer = AuthenticateAcl(checklist);
125 int ti;
126
127 // convert to tri-state ACL match 1,0,-1
128 switch (answer) {
129 case ACCESS_ALLOWED:
130 // check for a match
131 ti = match(checklist->auth_user_request, checklist->src_addr);
132 checklist->auth_user_request = NULL;
133 return ti;
134
135 case ACCESS_DENIED:
136 return 0; // non-match
137
138 case ACCESS_DUNNO:
139 case ACCESS_AUTH_REQUIRED:
140 default:
141 // If the answer is not allowed or denied (matches/not matches) and
142 // async authentication is not in progress, then we are done.
143 if (checklist->keepMatching())
144 checklist->markFinished(answer, "AuthenticateAcl exception");
145 return -1; // other
146 }
147 }
148
149 SBufList
150 ACLMaxUserIP::dump() const
151 {
152 SBufList sl;
153 if (!maximum)
154 return sl;
155 SBuf s;
156 s.Printf("%d", maximum);
157 sl.push_back(s);
158 return sl;
159 }