[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