]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Straighten the reconfigure and rotate sequences auth handling.
authorAmos Jeffries <squid3@treenet.co.nz>
Mon, 26 Apr 2010 07:07:44 +0000 (19:07 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Mon, 26 Apr 2010 07:07:44 +0000 (19:07 +1200)
* 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.

12 files changed:
src/auth/Config.h
src/auth/Gadgets.cc
src/auth/Gadgets.h
src/auth/basic/auth_basic.cc
src/auth/basic/auth_basic.h
src/auth/digest/auth_digest.cc
src/auth/digest/auth_digest.h
src/auth/negotiate/auth_negotiate.cc
src/auth/negotiate/auth_negotiate.h
src/auth/ntlm/auth_ntlm.cc
src/auth/ntlm/auth_ntlm.h
src/main.cc

index 71855b81d7e835fc408f5f43fb25b6c6df711f84..8ea2eca233c39c45f1f330aa9595988525e41a15 100644 (file)
@@ -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.
index 7948bac290e489aeff60e5275678353fb4d911fb..d9a312c4b357b37f9abcd764f29b0acc63e75c91 100644 (file)
@@ -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):
index 78016189f883adab7121d3c2a12c92e389fd5585..11de64c42c0c0bf43c017e888d308d2657cdb84f 100644 (file)
@@ -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);
index 21e55619fdb79e280e25841ca5c2beaf7c1a4216..024520a8151c59f44c531ca2954dc0dce7d9e1ca 100644 (file)
@@ -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()
index 6b506c1281a25aee6b08a44121852ef606848f8a..992b56aa5fcfbcaf5772453a217d988dc71bce76 100644 (file)
@@ -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 *);
index da650fc1bdebb59ac4d038da5d7631bb5425d9e0..5a6bbe071d18add512b0877e51cf9535872d13fd 100644 (file)
@@ -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()
index a37e4bfd55f599b05592827ed4a6679072ede915..de67901043edec8773b547f24a2313e0ff577352 100644 (file)
@@ -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 *);
index 9b9b6f97b2bacb921f447f2ee4c2736fcd5d80bc..bac4eaf1401201827a395b4f26a8f0cfb4fd2c3d 100644 (file)
@@ -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()
 {
index baa1bf12114064f71da03a78ad1413c3693cedbd..f5d414b0f31b5ef177b9ab65eb42f6fca31c71a0 100644 (file)
@@ -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 *);
index 5d149fdc1a88bd3a96fb10a4df1f65615e2f75c3..e5340f1ffefaa4751f9fb8df1511dc4e0ef1aab6 100644 (file)
@@ -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()
index 0a4e01639077b3c74dbc2ab3da0e8fc3497a7ab7..2a2514e5e1ddb00ea957c946e7c276c82c76f700 100644 (file)
@@ -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 *);
index 1896a08e115b7b546b3d45d5f35a655d4ba47498..fb5cb8fb6d8d4fc5b095aca1c826fc98305fcc4f 100644 (file)
@@ -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);