]>
Commit | Line | Data |
---|---|---|
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 | |
19 | namespace Auth { | |
20 | ||
51087401 AJ |
21 | class CredentialCacheRr : public RegisteredRunner |
22 | { | |
23 | public: | |
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 | ||
46 | private: | |
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 | 54 | CBDATA_CLASS_INIT(CredentialsCache); |
c2eec79f | 55 | |
455bb54d | 56 | CredentialsCache::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 | ||
64 | Auth::User::Pointer | |
638cfbc4 | 65 | CredentialsCache::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 | ||
74 | void | |
638cfbc4 | 75 | CredentialsCache::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 | ||
83 | void | |
638cfbc4 | 84 | CredentialsCache::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 | 104 | void |
e5827d49 | 105 | CredentialsCache::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 | 114 | std::vector<Auth::User::Pointer> |
638cfbc4 | 115 | CredentialsCache::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 |
129 | void |
130 | CredentialsCache::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 | 139 | void |
51087401 | 140 | CredentialsCache::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 |