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