From: Timo Sirainen Date: Thu, 4 Mar 2010 18:19:02 +0000 (+0200) Subject: auth_cache_negative_ttl is now also used for password mismatches. X-Git-Tag: 2.0.beta4~132 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=145d2eef238ed8bbff635e3b06951a83f0ee5a03;p=thirdparty%2Fdovecot%2Fcore.git auth_cache_negative_ttl is now also used for password mismatches. --HG-- branch : HEAD --- diff --git a/doc/example-config/conf.d/auth.conf b/doc/example-config/conf.d/auth.conf index 5be18b001d..148e45fc1c 100644 --- a/doc/example-config/conf.d/auth.conf +++ b/doc/example-config/conf.d/auth.conf @@ -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 diff --git a/src/auth/auth-cache.c b/src/auth/auth-cache.c index 5f54c4803b..50dbfdaade 100644 --- a/src/auth/auth-cache.c +++ b/src/auth/auth-cache.c @@ -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; diff --git a/src/auth/auth-cache.h b/src/auth/auth-cache.h index 269be3912c..d82507cb3d 100644 --- a/src/auth/auth-cache.h +++ b/src/auth/auth-cache.h @@ -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); diff --git a/src/auth/auth-request.c b/src/auth/auth-request.c index d2fef0ce4e..df0cc2e052 100644 --- a/src/auth/auth-request.c +++ b/src/auth/auth-request.c @@ -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; diff --git a/src/auth/passdb-cache.c b/src/auth/passdb-cache.c index be971a9e6c..54e4c7305d 100644 --- a/src/auth/passdb-cache.c +++ b/src/auth/passdb-cache.c @@ -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");