]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: Changed passdb { continue-ok } handling for credentials lookups.
authorTimo Sirainen <tss@iki.fi>
Sat, 17 Jan 2015 00:40:11 +0000 (02:40 +0200)
committerTimo Sirainen <tss@iki.fi>
Sat, 17 Jan 2015 00:40:11 +0000 (02:40 +0200)
If the last passdb after it doesn't return credentials, use the first
passdb's credentials. This allows implementing plugins that modify the
passdb result without actually changing the credentials.

src/auth/auth-request.c
src/auth/auth-request.h
src/auth/passdb.c

index 1afd884ba6be0df0f459549cafdf3dc25aa6fb01..fc39c8733f6cd44b5f461dd99b5679073e34b8e2 100644 (file)
@@ -800,10 +800,29 @@ auth_request_lookup_credentials_finish(enum passdb_result result,
 {
        if (!auth_request_handle_passdb_callback(&result, request)) {
                /* try next passdb */
+               if (request->skip_password_check &&
+                   request->delayed_credentials == NULL) {
+                       /* passdb continue* rule after a successful lookup.
+                          remember these credentials and use them later on. */
+                       unsigned char *dup;
+
+                       dup = p_malloc(request->pool, size);
+                       memcpy(dup, credentials, size);
+                       request->delayed_credentials = dup;
+                       request->delayed_credentials_size = size;
+               }
                auth_request_lookup_credentials(request,
                        request->credentials_scheme,
                        request->private_callback.lookup_credentials);
        } else {
+               if (request->delayed_credentials != NULL && size == 0) {
+                       /* we did multiple passdb lookups, but the last one
+                          didn't provide any credentials (e.g. just wanted to
+                          add some extra fields). so use the first passdb's
+                          credentials instead. */
+                       credentials = request->delayed_credentials;
+                       size = request->delayed_credentials_size;
+               }
                if (request->set->debug_passwords &&
                    result == PASSDB_RESULT_OK) {
                        auth_request_log_debug(request, AUTH_SUBSYS_DB,
index 02e6eb4024bc62c034b5f9700513fc9171e7678f..08441ab7b7655528f2a76cda483c397bf26a4f18 100644 (file)
@@ -89,7 +89,9 @@ struct auth_request {
                set_credentials_callback_t *set_credentials;
                 userdb_callback_t *userdb;
        } private_callback;
-        const char *credentials_scheme;
+       const char *credentials_scheme;
+       const unsigned char *delayed_credentials;
+       size_t delayed_credentials_size;
 
        void *context;
 
index b804a54744e15d7ef91d2903c44398f8401cd6b8..f917895733073749dc0e8854541c4e2edbd2cfc7 100644 (file)
@@ -155,6 +155,10 @@ void passdb_handle_credentials(enum passdb_result result,
        } else if (*auth_request->credentials_scheme == '\0') {
                /* We're doing a passdb lookup (not authenticating).
                   Pass through a NULL password without an error. */
+       } else if (auth_request->delayed_credentials != NULL) {
+               /* We already have valid credentials from an earlier
+                  passdb lookup. auth_request_lookup_credentials_finish()
+                  will use them. */
        } else {
                auth_request_log_info(auth_request, AUTH_SUBSYS_DB,
                        "Requested %s scheme, but we have a NULL password",