]> git.ipfire.org Git - thirdparty/squid.git/blob - src/auth/CredentialsCache.cc
Split RegisteredRunner cache management away from cache manager class
[thirdparty/squid.git] / src / auth / CredentialsCache.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 29 Authenticator */
10
11 #include "squid.h"
12 #include "acl/Gadgets.h"
13 #include "auth/CredentialsCache.h"
14 #include "base/RunnersRegistry.h"
15 #include "Debug.h"
16 #include "event.h"
17 #include "SquidConfig.h"
18 #include "SquidTime.h"
19
20 namespace Auth {
21
22 class CredentialCacheRr : public RegisteredRunner
23 {
24 public:
25 explicit CredentialCacheRr(const char *n, CredentialsCache * const c) :
26 name(n),
27 whichCache(c)
28 {}
29
30 virtual ~CredentialCacheRr() {
31 debugs(29, 5, "Terminating username cache: " << name);
32 // invalidate the CBDATA reference.
33 // causes Auth::*::User::Cache() to produce nil / invalid pointer
34 delete whichCache.get();
35 }
36
37 virtual void endingShutdown() override {
38 debugs(29, 5, "Clearing username cache: " << name);
39 whichCache->reset();
40 }
41
42 virtual void syncConfig() override {
43 if (!whichCache.valid())
44 return;
45
46 debugs(29, 5, "Reconfiguring username cache: " << name);
47 whichCache->doConfigChangeCleanup();
48 }
49
50 private:
51 /// name of the cache being managed, for logs
52 const char *name;
53
54 /// reference to the scheme cache which is being managed
55 CbcPointer<CredentialsCache> whichCache;
56 };
57
58 CBDATA_CLASS_INIT(CredentialsCache);
59
60 CredentialsCache::CredentialsCache(const char *name) :
61 gcScheduled_(false),
62 cacheCleanupEventName("User cache cleanup: ")
63 {
64 debugs(29, 5, "initializing " << name << " username cache");
65 cacheCleanupEventName.append(name);
66 RegisterRunner(new Auth::CredentialCacheRr(name, this));
67 }
68
69 Auth::User::Pointer
70 CredentialsCache::lookup(const SBuf &userKey) const
71 {
72 debugs(29, 6, "lookup for " << userKey);
73 auto p = store_.find(userKey);
74 if (p == store_.end())
75 return User::Pointer(nullptr);
76 return p->second;
77 }
78
79 void
80 CredentialsCache::Cleanup(void *data)
81 {
82 debugs(29, 5, "checkpoint");
83 // data is this in disguise
84 CredentialsCache *self = static_cast<CredentialsCache *>(data);
85 self->cleanup();
86 }
87
88 void
89 CredentialsCache::cleanup()
90 {
91 // cache entries with expiretime <= expirationTime are to be evicted
92 const time_t expirationTime = current_time.tv_sec - ::Config.authenticateTTL;
93
94 const auto end = store_.end();
95 for (auto i = store_.begin(); i != end;) {
96 debugs(29, 6, "considering " << i->first << "(expires in " <<
97 (expirationTime - i->second->expiretime) << " sec)");
98 if (i->second->expiretime <= expirationTime) {
99 debugs(29, 6, "evicting " << i->first);
100 i = store_.erase(i); //erase advances i
101 } else {
102 ++i;
103 }
104 }
105 scheduleCleanup();
106 }
107
108 void
109 CredentialsCache::insert(Auth::User::Pointer anAuth_user)
110 {
111 debugs(29, 6, "adding " << anAuth_user->userKey());
112 store_[anAuth_user->userKey()] = anAuth_user;
113 scheduleCleanup();
114 }
115
116 // generates the list of cached usernames in a format that is convenient
117 // to merge with equivalent lists obtained from other CredentialsCaches.
118 std::vector<Auth::User::Pointer>
119 CredentialsCache::sortedUsersList() const
120 {
121 std::vector<Auth::User::Pointer> rv(size(), nullptr);
122 std::transform(store_.begin(), store_.end(), rv.begin(),
123 [](StoreType::value_type v) { return v.second; }
124 );
125 std::sort(rv.begin(), rv.end(),
126 [](const Auth::User::Pointer &lhs, const Auth::User::Pointer &rhs) {
127 return strcmp(lhs->username(), rhs->username()) < 0;
128 }
129 );
130 return rv;
131 }
132
133 void
134 CredentialsCache::scheduleCleanup()
135 {
136 if (!gcScheduled_ && store_.size()) {
137 gcScheduled_ = true;
138 eventAdd(cacheCleanupEventName.c_str(), &CredentialsCache::Cleanup,
139 this, ::Config.authenticateGCInterval, 1);
140 }
141 }
142
143 void
144 CredentialsCache::doConfigChangeCleanup()
145 {
146 // purge expired entries entirely
147 cleanup();
148 // purge the ACL match data stored in the credentials
149 for (auto i : store_) {
150 aclCacheMatchFlush(&i.second->proxy_match_cache);
151 }
152 }
153
154 } /* namespace Auth */
155