[dovecot-cvs] dovecot/src/auth auth-cache.c, 1.18, 1.19 auth-cache.h, 1.6, 1.7 auth-request.c, 1.65, 1.66 passdb-cache.c, 1.17, 1.18
tss at dovecot.org
tss at dovecot.org
Fri Oct 13 17:37:18 UTC 2006
Update of /var/lib/cvs/dovecot/src/auth
In directory talvi:/tmp/cvs-serv26557/src/auth
Modified Files:
auth-cache.c auth-cache.h auth-request.c passdb-cache.c
Log Message:
auth_cache: Try to handle changing passwords automatically: If password
verification fails, but the last one had succeeded, don't use the cache.
This works only with plaintext auth.
Index: auth-cache.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-cache.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- auth-cache.c 31 May 2006 11:03:53 -0000 1.18
+++ auth-cache.c 13 Oct 2006 16:37:14 -0000 1.19
@@ -11,16 +11,9 @@
#include <time.h>
-struct cache_node {
- struct cache_node *prev, *next;
- time_t created;
- uint32_t alloc_size;
- char data[4]; /* key \0 value \0 */
-};
-
struct auth_cache {
struct hash_table *hash;
- struct cache_node *head, *tail;
+ struct auth_cache_node *head, *tail;
size_t size_left;
unsigned int ttl_secs;
@@ -56,7 +49,7 @@
}
static void
-auth_cache_node_unlink(struct auth_cache *cache, struct cache_node *node)
+auth_cache_node_unlink(struct auth_cache *cache, struct auth_cache_node *node)
{
if (node->prev != NULL)
node->prev->next = node->next;
@@ -74,7 +67,8 @@
}
static void
-auth_cache_node_link_head(struct auth_cache *cache, struct cache_node *node)
+auth_cache_node_link_head(struct auth_cache *cache,
+ struct auth_cache_node *node)
{
node->prev = cache->head;
node->next = NULL;
@@ -87,7 +81,7 @@
}
static void
-auth_cache_node_destroy(struct auth_cache *cache, struct cache_node *node)
+auth_cache_node_destroy(struct auth_cache *cache, struct auth_cache_node *node)
{
auth_cache_node_unlink(cache, node);
@@ -153,12 +147,13 @@
hash_clear(cache->hash, FALSE);
}
-const char *auth_cache_lookup(struct auth_cache *cache,
- const struct auth_request *request,
- const char *key, bool *expired_r)
+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)
{
string_t *str;
- struct cache_node *node;
+ struct auth_cache_node *node;
*expired_r = FALSE;
@@ -185,15 +180,18 @@
}
}
+ if (node_r != NULL)
+ *node_r = node;
+
return node->data + strlen(node->data) + 1;
}
void auth_cache_insert(struct auth_cache *cache,
const struct auth_request *request,
- const char *key, const char *value)
+ const char *key, const char *value, bool last_success)
{
string_t *str;
- struct cache_node *node;
+ struct auth_cache_node *node;
size_t data_size, alloc_size, value_len = strlen(value);
str = t_str_new(256);
@@ -202,7 +200,8 @@
auth_request_str_escape));
data_size = str_len(str) + 1 + value_len + 1;
- alloc_size = sizeof(struct cache_node) - sizeof(node->data) + data_size;
+ alloc_size = sizeof(struct auth_cache_node) -
+ sizeof(node->data) + data_size;
/* make sure we have enough space */
while (cache->size_left < alloc_size)
@@ -218,6 +217,7 @@
node = i_malloc(alloc_size);
node->created = time(NULL);
node->alloc_size = alloc_size;
+ node->last_success = last_success;
memcpy(node->data, str_data(str), str_len(str));
memcpy(node->data + str_len(str) + 1, value, value_len);
Index: auth-cache.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-cache.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- auth-cache.h 14 Jan 2006 18:47:20 -0000 1.6
+++ auth-cache.h 13 Oct 2006 16:37:14 -0000 1.7
@@ -1,6 +1,18 @@
#ifndef __AUTH_CACHE_H
#define __AUTH_CACHE_H
+struct auth_cache_node {
+ struct auth_cache_node *prev, *next;
+
+ time_t created;
+ /* Total number of bytes used by this node */
+ uint32_t alloc_size:31;
+ /* TRUE if the user gave the correct password the last time. */
+ uint32_t last_success:1;
+
+ char data[4]; /* key \0 value \0 */
+};
+
struct auth_cache;
struct auth_request;
@@ -18,13 +30,15 @@
void auth_cache_clear(struct auth_cache *cache);
/* Look key from cache. key should be the same string as returned by
- auth_cache_parse_key(). */
-const char *auth_cache_lookup(struct auth_cache *cache,
- const struct auth_request *request,
- const char *key, bool *expired_r);
+ auth_cache_parse_key(). Returned node can't be used after any other
+ auth_cache_*() calls. */
+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);
/* Insert key => value into cache. */
void auth_cache_insert(struct auth_cache *cache,
const struct auth_request *request,
- const char *key, const char *value);
+ const char *key, const char *value, bool last_success);
#endif
Index: auth-request.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-request.c,v
retrieving revision 1.65
retrieving revision 1.66
diff -u -d -r1.65 -r1.66
--- auth-request.c 16 Aug 2006 20:48:35 -0000 1.65
+++ auth-request.c 13 Oct 2006 16:37:14 -0000 1.66
@@ -216,7 +216,7 @@
/* lookup failed. */
if (result == PASSDB_RESULT_USER_UNKNOWN) {
auth_cache_insert(passdb_cache, request,
- passdb->cache_key, "");
+ passdb->cache_key, "", FALSE);
}
return;
}
@@ -258,7 +258,8 @@
str_append_c(str, '\t');
str_append(str, "nodelay");
}
- auth_cache_insert(passdb_cache, request, passdb->cache_key, str_c(str));
+ auth_cache_insert(passdb_cache, request, passdb->cache_key, str_c(str),
+ result == PASSDB_RESULT_OK);
}
static bool auth_request_master_lookup_finish(struct auth_request *request)
Index: passdb-cache.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-cache.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- passdb-cache.c 22 Jan 2006 11:33:27 -0000 1.17
+++ passdb-cache.c 13 Oct 2006 16:37:14 -0000 1.18
@@ -37,6 +37,7 @@
enum passdb_result *result_r, int use_expired)
{
const char *value, *cached_pw, *scheme, *const *list;
+ struct auth_cache_node *node;
int ret;
bool expired;
@@ -44,7 +45,7 @@
return FALSE;
/* value = password \t ... */
- value = auth_cache_lookup(passdb_cache, request, key, &expired);
+ value = auth_cache_lookup(passdb_cache, request, key, &node, &expired);
if (value == NULL || (expired && !use_expired))
return FALSE;
@@ -72,6 +73,14 @@
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. */
+ node->last_success = FALSE;
+ return FALSE;
+ }
+ node->last_success = ret > 0;
+
*result_r = ret > 0 ? PASSDB_RESULT_OK :
PASSDB_RESULT_PASSWORD_MISMATCH;
return TRUE;
@@ -84,12 +93,13 @@
bool use_expired)
{
const char *value, *const *list;
+ struct auth_cache_node *node;
bool expired;
if (passdb_cache == NULL)
return FALSE;
- value = auth_cache_lookup(passdb_cache, request, key, &expired);
+ value = auth_cache_lookup(passdb_cache, request, key, &node, &expired);
if (value == NULL || (expired && !use_expired))
return FALSE;
More information about the dovecot-cvs
mailing list