From 0bcb69087f2ea686829fdedd4f6132811a2c332e Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Mon, 26 Apr 2010 19:07:44 +1200 Subject: [PATCH] Straighten the reconfigure and rotate sequences auth handling. * Add a hook into auth API to only restart the helpers instead of dropping auth state. * Make reconfigure drop idle state and reset the config for new requests to use the new config details. This makes auth settings alterable with just a reconfigure now. --- src/auth/Config.h | 6 +++++ src/auth/Gadgets.cc | 39 +++++++++++++++++----------- src/auth/Gadgets.h | 16 ++++++++++-- src/auth/basic/auth_basic.cc | 11 ++++++++ src/auth/basic/auth_basic.h | 5 ++-- src/auth/digest/auth_digest.cc | 12 +++++++++ src/auth/digest/auth_digest.h | 1 + src/auth/negotiate/auth_negotiate.cc | 11 ++++++++ src/auth/negotiate/auth_negotiate.h | 1 + src/auth/ntlm/auth_ntlm.cc | 11 ++++++++ src/auth/ntlm/auth_ntlm.h | 1 + src/main.cc | 17 ++++++------ 12 files changed, 102 insertions(+), 29 deletions(-) diff --git a/src/auth/Config.h b/src/auth/Config.h index 71855b81d7..8ea2eca233 100644 --- a/src/auth/Config.h +++ b/src/auth/Config.h @@ -105,6 +105,12 @@ public: */ virtual bool configured() const = 0; + /** + * Shutdown just the auth helpers. + * For use by log rotate etc. where auth needs to stay running, with the helpers restarted. + */ + virtual void rotateHelpers(void) = 0; + /** * Responsible for writing to the StoreEntry the configuration parameters that a user * would put in a config file to recreate the running configuration. diff --git a/src/auth/Gadgets.cc b/src/auth/Gadgets.cc index 7948bac290..d9a312c4b3 100644 --- a/src/auth/Gadgets.cc +++ b/src/auth/Gadgets.cc @@ -109,23 +109,32 @@ authenticateInit(Auth::authConfig * config) } void -authenticateShutdown(void) +authenticateRotate(void) { - debugs(29, 2, HERE << "Shutting down auth schemes"); - /* free the cache if we are shutting down */ - if (shutting_down) { - hash_first(proxy_auth_username_cache); - AuthUserHashPointer *usernamehash; - while ((usernamehash = ((AuthUserHashPointer *) hash_next(proxy_auth_username_cache)))) { - debugs(29, 5, HERE << "Clearing entry for user: " << usernamehash->user()->username()); - hash_remove_link(proxy_auth_username_cache, (hash_link *)usernamehash); - delete usernamehash; - } - AuthScheme::FreeAll(); - } else { - for (AuthScheme::iterator i = (AuthScheme::GetSchemes()).begin(); i != (AuthScheme::GetSchemes()).end(); ++i) - (*i)->done(); + for (Auth::authConfig::iterator i = Auth::TheConfig.begin(); i != Auth::TheConfig.end(); ++i) + if ((*i)->configured()) + (*i)->rotateHelpers(); +} + +void +authenticateReset(void) +{ + debugs(29, 2, HERE << "Reset authentication State."); + + /* free all username cache entries */ + hash_first(proxy_auth_username_cache); + AuthUserHashPointer *usernamehash; + while ((usernamehash = ((AuthUserHashPointer *) hash_next(proxy_auth_username_cache)))) { + debugs(29, 5, HERE << "Clearing entry for user: " << usernamehash->user()->username()); + hash_remove_link(proxy_auth_username_cache, (hash_link *)usernamehash); + delete usernamehash; } + + /* schedule shutdown of the helpers */ + authenticateRotate(); + + /* free current global config details too. */ + Auth::TheConfig.clean(); } AuthUserHashPointer::AuthUserHashPointer(AuthUser::Pointer anAuth_user): diff --git a/src/auth/Gadgets.h b/src/auth/Gadgets.h index 78016189f8..11de64c42c 100644 --- a/src/auth/Gadgets.h +++ b/src/auth/Gadgets.h @@ -81,8 +81,20 @@ typedef void AUTHSSTATS(StoreEntry *); /// \ingroup AuthAPI extern void authenticateInit(Auth::authConfig *); -/// \ingroup AuthAPI -extern void authenticateShutdown(void); + +/** \ingroup AuthAPI + * Remove all idle authentication state. Intended for use by reconfigure. + * + * Removes the username cache contents and global configuration state. + * Stops just short of detaching the auth components completely. + * + * Currently active requests should finish. Howevee new requests will not use + * authentication unless something causes the global config to be rebuilt. + * Such as a configure load action adding config and re-running authenticateInit(). + */ +extern void authenticateReset(void); + +extern void authenticateRotate(void); /// \ingroup AuthAPI extern void authenticateFreeProxyAuthUserACLResults(void *data); diff --git a/src/auth/basic/auth_basic.cc b/src/auth/basic/auth_basic.cc index 21e55619fd..024520a815 100644 --- a/src/auth/basic/auth_basic.cc +++ b/src/auth/basic/auth_basic.cc @@ -125,6 +125,17 @@ AuthBasicConfig::fixHeader(AuthUserRequest::Pointer auth_user_request, HttpReply } } +void +AuthBasicConfig::rotateHelpers() +{ + /* schedule closure of existing helpers */ + if (basicauthenticators) { + helperShutdown(basicauthenticators); + } + + /* NP: dynamic helper restart will ensure they start up again as needed. */ +} + /** shutdown the auth helpers and free any allocated configuration details */ void AuthBasicConfig::done() diff --git a/src/auth/basic/auth_basic.h b/src/auth/basic/auth_basic.h index 6b506c1281..992b56aa5f 100644 --- a/src/auth/basic/auth_basic.h +++ b/src/auth/basic/auth_basic.h @@ -42,9 +42,7 @@ public: bool valid() const; void makeLoggingInstance(AuthUserRequest::Pointer auth_user_request); -#if 0 - AuthUser::Pointer makeCachedFrom(); -#endif + /** Update the cached password for a username. */ void updateCached(BasicUser *from); virtual int32_t ttl() const; @@ -80,6 +78,7 @@ public: virtual bool configured() const; virtual AuthUserRequest::Pointer decode(char const *proxy_auth); virtual void done(); + virtual void rotateHelpers(); virtual void dump(StoreEntry *, const char *, AuthConfig *); virtual void fixHeader(AuthUserRequest::Pointer, HttpReply *, http_hdr_type, HttpRequest *); virtual void init(AuthConfig *); diff --git a/src/auth/digest/auth_digest.cc b/src/auth/digest/auth_digest.cc index da650fc1bd..5a6bbe071d 100644 --- a/src/auth/digest/auth_digest.cc +++ b/src/auth/digest/auth_digest.cc @@ -498,6 +498,18 @@ authDigestUserFindUsername(const char *username) return NULL; } +void +AuthDigestConfig::rotateHelpers() +{ + /* schedule closure of existing helpers */ + if (digestauthenticators) { + helperShutdown(digestauthenticators); + } + + /* NP: dynamic helper restart will ensure they start up again as needed. */ +} + + /** delete the digest request structure. Does NOT delete related structures */ void digestScheme::done() diff --git a/src/auth/digest/auth_digest.h b/src/auth/digest/auth_digest.h index a37e4bfd55..de67901043 100644 --- a/src/auth/digest/auth_digest.h +++ b/src/auth/digest/auth_digest.h @@ -86,6 +86,7 @@ public: virtual bool configured() const; virtual AuthUserRequest::Pointer decode(char const *proxy_auth); virtual void done(); + virtual void rotateHelpers(); virtual void dump(StoreEntry *, const char *, AuthConfig *); virtual void fixHeader(AuthUserRequest::Pointer, HttpReply *, http_hdr_type, HttpRequest *); virtual void init(AuthConfig *); diff --git a/src/auth/negotiate/auth_negotiate.cc b/src/auth/negotiate/auth_negotiate.cc index 9b9b6f97b2..bac4eaf140 100644 --- a/src/auth/negotiate/auth_negotiate.cc +++ b/src/auth/negotiate/auth_negotiate.cc @@ -78,6 +78,17 @@ static hash_table *proxy_auth_cache = NULL; * */ +void +AuthNegotiateConfig::rotateHelpers() +{ + /* schedule closure of existing helpers */ + if (negotiateauthenticators) { + helperStatefulShutdown(negotiateauthenticators); + } + + /* NP: dynamic helper restart will ensure they start up again as needed. */ +} + void AuthNegotiateConfig::done() { diff --git a/src/auth/negotiate/auth_negotiate.h b/src/auth/negotiate/auth_negotiate.h index baa1bf1211..f5d414b0f3 100644 --- a/src/auth/negotiate/auth_negotiate.h +++ b/src/auth/negotiate/auth_negotiate.h @@ -51,6 +51,7 @@ public: virtual bool configured() const; virtual AuthUserRequest::Pointer decode(char const *proxy_auth); virtual void done(); + virtual void rotateHelpers(); virtual void dump(StoreEntry *, const char *, AuthConfig *); virtual void fixHeader(AuthUserRequest::Pointer, HttpReply *, http_hdr_type, HttpRequest *); virtual void init(AuthConfig *); diff --git a/src/auth/ntlm/auth_ntlm.cc b/src/auth/ntlm/auth_ntlm.cc index 5d149fdc1a..e5340f1ffe 100644 --- a/src/auth/ntlm/auth_ntlm.cc +++ b/src/auth/ntlm/auth_ntlm.cc @@ -65,6 +65,17 @@ static hash_table *proxy_auth_cache = NULL; * */ +void +AuthNTLMConfig::rotateHelpers() +{ + /* schedule closure of existing helpers */ + if (ntlmauthenticators) { + helperStatefulShutdown(ntlmauthenticators); + } + + /* NP: dynamic helper restart will ensure they start up again as needed. */ +} + /* free any allocated configuration details */ void AuthNTLMConfig::done() diff --git a/src/auth/ntlm/auth_ntlm.h b/src/auth/ntlm/auth_ntlm.h index 0a4e016390..2a2514e5e1 100644 --- a/src/auth/ntlm/auth_ntlm.h +++ b/src/auth/ntlm/auth_ntlm.h @@ -42,6 +42,7 @@ public: virtual bool configured() const; virtual AuthUserRequest::Pointer decode(char const *proxy_auth); virtual void done(); + virtual void rotateHelpers(); virtual void dump(StoreEntry *, const char *, AuthConfig *); virtual void fixHeader(AuthUserRequest::Pointer, HttpReply *, http_hdr_type, HttpRequest *); virtual void init(AuthConfig *); diff --git a/src/main.cc b/src/main.cc index 1896a08e11..fb5cb8fb6d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -212,7 +212,12 @@ SignalEngine::doShutdown(time_t wait) WIN32_svcstatusupdate(SERVICE_STOP_PENDING, (wait + 1) * 1000); #endif + /* run the closure code which can be shared with reconfigure */ serverConnectionsClose(); + + /* detach the auth components (only do this on full shutdown) */ + AuthScheme::FreeAll(); + eventAdd("SquidShutdown", &StopEventLoop, this, (double) (wait + 1), 1, false); } @@ -693,9 +698,7 @@ mainReconfigureStart(void) #endif redirectShutdown(); - authenticateShutdown(); /* destroys any unused auth schemas */ - InitAuthSchemes(); /* create new ones required for config parsing */ - + authenticateReset(); externalAclShutdown(); storeDirCloseSwapLogs(); storeLogClose(); @@ -794,11 +797,7 @@ mainRotate(void) dnsShutdown(); #endif redirectShutdown(); - - /* TODO: should only terminate the helpers they are using. nothing else. */ - authenticateShutdown(); /* destroys any unused auth schemas */ - InitAuthSchemes(); /* create new ones required for config parsing */ - + authenticateRotate(); externalAclShutdown(); _db_rotate_log(); /* cache.log */ @@ -1724,7 +1723,7 @@ SquidShutdown() DelayPools::FreePools(); #endif - authenticateShutdown(); + authenticateReset(); #if USE_WIN32_SERVICE WIN32_svcstatusupdate(SERVICE_STOP_PENDING, 10000); -- 2.47.2