]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth_cache_negative_ttl is now also used for password mismatches.
authorTimo Sirainen <tss@iki.fi>
Thu, 4 Mar 2010 18:19:02 +0000 (20:19 +0200)
committerTimo Sirainen <tss@iki.fi>
Thu, 4 Mar 2010 18:19:02 +0000 (20:19 +0200)
--HG--
branch : HEAD

doc/example-config/conf.d/auth.conf
src/auth/auth-cache.c
src/auth/auth-cache.h
src/auth/auth-request.c
src/auth/passdb-cache.c

index 5be18b001d4ea54ce139c934b87c096843504de4..148e45fc1cecdba5edcd1cd63a34e4b3edea0c0a 100644 (file)
@@ -11,7 +11,8 @@
 # authentication was successful, but this one wasn't, the cache isn't used.
 # For now this works only with plaintext authentication.
 #auth_cache_ttl = 1 hour
-# TTL for negative hits (user not found). 0 disables caching them completely.
+# TTL for negative hits (user not found, password mismatch).
+# 0 disables caching them completely.
 #auth_cache_negative_ttl = 1 hour
 
 # Space separated list of realms for SASL authentication mechanisms that need
index 5f54c4803be72d185fb5b741c96429b1ee904039..50dbfdaade40dce65839cf3d53cec6d68e90fc56 100644 (file)
@@ -162,14 +162,16 @@ void auth_cache_clear(struct auth_cache *cache)
 const char *
 auth_cache_lookup(struct auth_cache *cache, const struct auth_request *request,
                  const char *key, struct auth_cache_node **node_r,
-                 bool *expired_r)
+                 bool *expired_r, bool *neg_expired_r)
 {
        string_t *str;
        struct auth_cache_node *node;
        const char *value;
        unsigned int ttl_secs;
+       time_t now;
 
        *expired_r = FALSE;
+       *neg_expired_r = FALSE;
 
        /* %! is prepended automatically. it contains the passdb ID number. */
        str = t_str_new(256);
@@ -187,7 +189,8 @@ auth_cache_lookup(struct auth_cache *cache, const struct auth_request *request,
        value = node->data + strlen(node->data) + 1;
        ttl_secs = *value == '\0' ? cache->neg_ttl_secs : cache->ttl_secs;
 
-       if (node->created < time(NULL) - (time_t)ttl_secs) {
+       now = time(NULL);
+       if (node->created < now - (time_t)ttl_secs) {
                /* TTL expired */
                *expired_r = TRUE;
        } else {
@@ -197,6 +200,8 @@ auth_cache_lookup(struct auth_cache *cache, const struct auth_request *request,
                        auth_cache_node_link_head(cache, node);
                }
        }
+       if (node->created < now - (time_t)cache->neg_ttl_secs)
+               *neg_expired_r = TRUE;
 
        if (node_r != NULL)
                *node_r = node;
index 269be3912c3e87b61adfa7363aa5545850ee4bbe..d82507cb3d1f39c1d79e390c208ab2c16eee2421 100644 (file)
@@ -37,7 +37,7 @@ void auth_cache_clear(struct auth_cache *cache);
 const char *
 auth_cache_lookup(struct auth_cache *cache, const struct auth_request *request,
                  const char *key, struct auth_cache_node **node_r,
-                 bool *expired_r);
+                 bool *expired_r, bool *neg_expired_r);
 /* Insert key => value into cache. "" value means negative cache entry. */
 void auth_cache_insert(struct auth_cache *cache, struct auth_request *request,
                       const char *key, const char *value, bool last_success);
index d2fef0ce4eea3db5867e7686d7913bfb536dbf22..df0cc2e052d001a222912802718a1d6d52733e1b 100644 (file)
@@ -675,10 +675,10 @@ static bool auth_request_lookup_user_cache(struct auth_request *request,
 {
        const char *value;
        struct auth_cache_node *node;
-       bool expired;
+       bool expired, neg_expired;
 
        value = auth_cache_lookup(passdb_cache, request, key, &node,
-                                 &expired);
+                                 &expired, &neg_expired);
        if (value == NULL || (expired && !use_expired))
                return FALSE;
 
index be971a9e6c049248daa297534b87961351d5ddb6..54e4c7305d9a88562272068675cb3451c189ee62 100644 (file)
@@ -30,13 +30,14 @@ bool passdb_cache_verify_plain(struct auth_request *request, const char *key,
        const char *value, *cached_pw, *scheme, *const *list;
        struct auth_cache_node *node;
        int ret;
-       bool expired;
+       bool expired, neg_expired;
 
        if (passdb_cache == NULL || key == NULL)
                return FALSE;
 
        /* value = password \t ... */
-       value = auth_cache_lookup(passdb_cache, request, key, &node, &expired);
+       value = auth_cache_lookup(passdb_cache, request, key, &node,
+                                 &expired, &neg_expired);
        if (value == NULL || (expired && !use_expired)) {
                auth_request_log_debug(request, "cache",
                                       value == NULL ? "miss" : "expired");
@@ -65,9 +66,11 @@ bool passdb_cache_verify_plain(struct auth_request *request, const char *key,
                ret = auth_request_password_verify(request, password, cached_pw,
                                                   scheme, "cache");
 
-               if (ret == 0 && node->last_success) {
-                       /* the last authentication was successful. assume that
-                          the password was changed and cache is expired. */
+               if (ret == 0 && (node->last_success || neg_expired)) {
+                       /* a) the last authentication was successful. assume
+                          that the password was changed and cache is expired.
+                          b) negative TTL reached, use it for password
+                          mismatches too. */
                        node->last_success = FALSE;
                        return FALSE;
                }
@@ -91,12 +94,13 @@ bool passdb_cache_lookup_credentials(struct auth_request *request,
 {
        const char *value, *const *list;
        struct auth_cache_node *node;
-       bool expired;
+       bool expired, neg_expired;
 
        if (passdb_cache == NULL)
                return FALSE;
 
-       value = auth_cache_lookup(passdb_cache, request, key, &node, &expired);
+       value = auth_cache_lookup(passdb_cache, request, key, &node,
+                                 &expired, &neg_expired);
        if (value == NULL || (expired && !use_expired)) {
                auth_request_log_debug(request, "cache",
                                       value == NULL ? "miss" : "expired");