changeset 22793:1f78d2f2debc

auth: passdb-cache - Verify credentials with worker when enabled
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Mon, 08 Jan 2018 15:08:10 +0200
parents f37027284478
children 7d03ba768919
files src/auth/auth-request.c src/auth/auth-settings.c src/auth/auth-settings.h src/auth/passdb-cache.c
diffstat 4 files changed, 38 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth/auth-request.c	Mon Jan 08 15:00:17 2018 +0200
+++ b/src/auth/auth-request.c	Mon Jan 08 15:08:10 2018 +0200
@@ -928,6 +928,7 @@
 					      &result, TRUE)) {
 			auth_request_log_info(request, AUTH_SUBSYS_DB,
 				"Falling back to expired data from cache");
+			return;
 		}
 	}
 
@@ -1077,7 +1078,6 @@
 	cache_key = passdb_cache == NULL ? NULL : passdb->cache_key;
 	if (passdb_cache_verify_plain(request, cache_key, password,
 				      &result, FALSE)) {
-		auth_request_verify_plain_callback_finish(result, request);
 		return;
 	}
 
--- a/src/auth/auth-settings.c	Mon Jan 08 15:00:17 2018 +0200
+++ b/src/auth/auth-settings.c	Mon Jan 08 15:08:10 2018 +0200
@@ -230,6 +230,7 @@
 	DEF(SET_SIZE, cache_size),
 	DEF(SET_TIME, cache_ttl),
 	DEF(SET_TIME, cache_negative_ttl),
+	DEF(SET_BOOL, cache_verify_password_with_worker),
 	DEF(SET_STR, username_chars),
 	DEF(SET_STR, username_translation),
 	DEF(SET_STR, username_format),
@@ -282,6 +283,7 @@
 	.cache_size = 0,
 	.cache_ttl = 60*60,
 	.cache_negative_ttl = 60*60,
+	.cache_verify_password_with_worker = FALSE,
 	.username_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@",
 	.username_translation = "",
 	.username_format = "%Lu",
--- a/src/auth/auth-settings.h	Mon Jan 08 15:00:17 2018 +0200
+++ b/src/auth/auth-settings.h	Mon Jan 08 15:08:10 2018 +0200
@@ -44,6 +44,7 @@
 	uoff_t cache_size;
 	unsigned int cache_ttl;
 	unsigned int cache_negative_ttl;
+	bool cache_verify_password_with_worker;
 	const char *username_chars;
 	const char *username_translation;
 	const char *username_format;
--- a/src/auth/passdb-cache.c	Mon Jan 08 15:00:17 2018 +0200
+++ b/src/auth/passdb-cache.c	Mon Jan 08 15:08:10 2018 +0200
@@ -1,12 +1,15 @@
 /* Copyright (c) 2004-2018 Dovecot authors, see the included COPYING file */
 
 #include "auth-common.h"
+#include "str.h"
 #include "strescape.h"
 #include "restrict-process-size.h"
 #include "auth-request-stats.h"
+#include "auth-worker-server.h"
 #include "password-scheme.h"
 #include "passdb.h"
 #include "passdb-cache.h"
+#include "passdb-blocking.h"
 
 struct auth_cache *passdb_cache = NULL;
 
@@ -50,6 +53,17 @@
 	return TRUE;
 }
 
+static bool passdb_cache_verify_plain_callback(const char *reply, void *context)
+{
+	struct auth_request *request = context;
+	enum passdb_result result;
+
+	result = passdb_blocking_auth_worker_reply_parse(request, reply);
+	auth_request_verify_plain_callback_finish(result, request);
+	auth_request_unref(&request);
+	return TRUE;
+}
+
 bool passdb_cache_verify_plain(struct auth_request *request, const char *key,
 			       const char *password,
 			       enum passdb_result *result_r, bool use_expired)
@@ -70,6 +84,7 @@
 		/* negative cache entry */
 		auth_request_log_unknown_user(request, AUTH_SUBSYS_DB);
 		*result_r = PASSDB_RESULT_USER_UNKNOWN;
+		auth_request_verify_plain_callback_finish(*result_r, request);
 		return TRUE;
 	}
 
@@ -81,6 +96,23 @@
 		auth_request_log_info(request, AUTH_SUBSYS_DB,
 				      "Cached NULL password access");
 		ret = 1;
+	} else if (request->set->cache_verify_password_with_worker) {
+		string_t *str;
+
+		str = t_str_new(128);
+		str_printfa(str, "PASSW\t%u\t", request->passdb->passdb->id);
+		str_append_tabescaped(str, password);
+		str_append_c(str, '\t');
+		str_append_tabescaped(str, cached_pw);
+		str_append_c(str, '\t');
+		auth_request_export(request, str);
+
+		auth_request_log_debug(request, AUTH_SUBSYS_DB, "cache: "
+				       "validating password on worker");
+		auth_request_ref(request);
+		auth_worker_call(request->pool, request->user, str_c(str),
+				 passdb_cache_verify_plain_callback, request);
+		return TRUE;
 	} else {
 		scheme = password_get_scheme(&cached_pw);
 		i_assert(scheme != NULL);
@@ -105,6 +137,8 @@
 
 	*result_r = ret > 0 ? PASSDB_RESULT_OK :
 		PASSDB_RESULT_PASSWORD_MISMATCH;
+
+	auth_request_verify_plain_callback_finish(*result_r, request);
 	return TRUE;
 }