]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: passdb-cache - Verify credentials with worker when enabled
authorAki Tuomi <aki.tuomi@dovecot.fi>
Mon, 8 Jan 2018 13:08:10 +0000 (15:08 +0200)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Mon, 29 Jan 2018 09:32:09 +0000 (11:32 +0200)
src/auth/auth-request.c
src/auth/auth-settings.c
src/auth/auth-settings.h
src/auth/passdb-cache.c

index 5c8e5f9d0bff8649d9b9481e7cf0e4b6be8b244c..13f8f44a28d5f92541acce4c6363185875db611d 100644 (file)
@@ -942,6 +942,7 @@ void auth_request_verify_plain_callback(enum passdb_result result,
                                              &result, TRUE)) {
                        auth_request_log_info(request, AUTH_SUBSYS_DB,
                                "Falling back to expired data from cache");
+                       return;
                }
        }
 
@@ -1090,7 +1091,6 @@ void auth_request_verify_plain_continue(struct auth_request *request,
        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;
        }
 
index 7ff024b0efea9b24df82bc3ab9b8acfc6ca5c8d7..fc5276151971d3e5a4a3bcce6018732809d75c01 100644 (file)
@@ -230,6 +230,7 @@ static const struct setting_define auth_setting_defines[] = {
        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),
@@ -284,6 +285,7 @@ static const struct auth_settings auth_default_settings = {
        .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",
index 3c69a6733de42ba21373f5474df24f0aec228afd..07ade86a62a9f82716fa77ba6e58bedcd46ad15a 100644 (file)
@@ -44,6 +44,7 @@ struct auth_settings {
        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;
index f85ca1dd94ee68104d0ee7c1a70f255792a042c5..dc52350c0373c30f6ff8a20e6abc25ef823d7a70 100644 (file)
@@ -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 @@ passdb_cache_lookup(struct auth_request *request, const char *key,
        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 @@ bool passdb_cache_verify_plain(struct auth_request *request, const char *key,
                /* 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 @@ bool passdb_cache_verify_plain(struct auth_request *request, const char *key,
                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);
@@ -106,6 +138,8 @@ bool passdb_cache_verify_plain(struct auth_request *request, const char *key,
 
        *result_r = ret > 0 ? PASSDB_RESULT_OK :
                PASSDB_RESULT_PASSWORD_MISMATCH;
+
+       auth_request_verify_plain_callback_finish(*result_r, request);
        return TRUE;
 }