]> 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)
committerAki Tuomi <aki.tuomi@dovecot.fi>
Sun, 4 Feb 2018 11:34:25 +0000 (13:34 +0200)
src/auth/auth-request.c
src/auth/auth-settings.c
src/auth/auth-settings.h
src/auth/passdb-cache.c

index 9caa5ecf56974132c61e60a87548671550f11214..24a84ccb7d8b77bd9992ad0af2cba0289975ae3d 100644 (file)
@@ -928,6 +928,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;
                }
        }
 
@@ -1077,7 +1078,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 a4b53b69338feadc403c01e600af0d7d55c5b73c..6a6d8b7dfd7cfeacb4793f824e1ceac7a4898184 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),
@@ -282,6 +283,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 25572358238edd7520f9a58dc344ed886e0e67e5..bfb71929fb6d0c7ae9724fb63ec046edfe2c9587 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 b8a61943af32b44bd9f0afcda513a932f0cc431c..86d0fb01a5b02dc437f15c2e6c9654a18c3a65c4 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);
@@ -105,6 +137,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;
 }