[Dovecot] cache_key assertion error 1.0.rc15

Frank Cusack fcusack at fcusack.com
Mon Nov 20 21:53:59 UTC 2006


On November 20, 2006 11:38:30 AM -0800 Frank Cusack <fcusack at fcusack.com> 
wrote:
> On November 19, 2006 11:59:50 PM -0800 Frank Cusack <fcusack at fcusack.com>
> wrote:
>> On November 19, 2006 8:58:54 PM -0800 Frank Cusack <fcusack at fcusack.com>
>> wrote:
>>> I just added auth caching with pam, and I'm getting this error:
>>>
>>> dovecot: [ID 107833 mail.error] auth(default): file passdb.c: line 178
>>> (passdb_init): assertion failed: (passdb->passdb->default_pass_scheme !=
>>> NULL || passdb->passdb->cache_key == NULL)
>
> Looked into the source and I see that pam doesn't actually implement any
> caching.

Here is my first go at fixing it.  It almost works.

- cache is initialized correctly
- user password is cached correctly until ttl expires

Once the ttl expires, dovecot attempts to use the cached password to
authenticate.  This fails in my environment.  Then (after trying PAM
with the cached password, even though ttl has expired) dovecot prompts
the user for the password, however it never sends the request to PAM.

Some combination of waiting and trying again gets it working again, I
haven't quite figure that one out.  Might be waiting for the ttl expiry
on the second (failed) request.

I think the after-ttl-expiry problems are due to a broken cache
implementation, not really a problem with my patch.  But maybe I need to
do something to clear the cache?  I didn't see anything like that in
passdb-passwd.c.

-frank
-------------- next part --------------
--- dovecot-1.0.beta15/src/auth/passdb-pam.c.orig	2006-11-20 12:40:23.237421000 -0800
+++ dovecot-1.0.beta15/src/auth/passdb-pam.c	2006-11-20 12:39:32.050764000 -0800
@@ -59,6 +59,8 @@ typedef linux_const void *pam_item_t;
 #  define USERPASS_USER_FIXED		3
 #endif
 
+#define PAM_PASS_SCHEME "PLAIN"
+
 struct pam_passdb_module {
 	struct passdb_module module;
 
@@ -219,14 +221,6 @@ static int pam_auth(struct auth_request 
 	        }
 	}
 
-	status = pam_get_item(pamh, PAM_USER, (linux_const void **)&item);
-	if (status != PAM_SUCCESS) {
-		*error = t_strdup_printf("pam_get_item() failed: %s",
-					 pam_strerror(pamh, status));
-		return status;
-	}
-        auth_request_set_field(request, "user", item, NULL);
-
 	return PAM_SUCCESS;
 }
 
@@ -298,7 +292,7 @@ pam_verify_plain_child(struct auth_reque
 	if (str != NULL) 
 		buffer_append(buf, str, strlen(str));
 
-	/* Don't send larger writes than what would block. truncated error
+	/* Don't send larger writes than would be atomic. truncated error
 	   message isn't that bad.. */
         size = I_MIN(buf->used, PIPE_BUF);
 	if ((ret = write(fd, buf->data, size)) != (int)size) {
@@ -430,6 +424,10 @@ pam_verify_plain(struct auth_request *re
 	pam_auth_request->request = request;
 	pam_auth_request->callback = callback;
 
+	/* save the password so cache can use it */
+	auth_request_set_field(request, "password", password,
+			       PAM_PASS_SCHEME);
+
 	pam_auth_request->io =
 		io_add(fd[0], IO_READ, pam_child_input, pam_auth_request);
 }
@@ -474,10 +472,11 @@ pam_preinit(struct auth_passdb *auth_pas
 	return &module->module;
 }
 
-static void pam_init(struct passdb_module *_module __attr_unused__,
+static void pam_init(struct passdb_module *_module,
 		     const char *args __attr_unused__)
 {
 	lib_signals_set_handler(SIGCHLD, TRUE, sigchld_handler, NULL);
+	_module->default_pass_scheme = PAM_PASS_SCHEME;
 }
 
 static void pam_deinit(struct passdb_module *_module __attr_unused__)


More information about the dovecot mailing list