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