From: Timo Sirainen Date: Sat, 17 Jan 2015 00:40:11 +0000 (+0200) Subject: auth: Changed passdb { continue-ok } handling for credentials lookups. X-Git-Tag: 2.2.16.rc1~143 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7d26aee0c0b6c0ce227ef4ae4f20fc86e2c423f2;p=thirdparty%2Fdovecot%2Fcore.git auth: Changed passdb { continue-ok } handling for credentials lookups. 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. --- diff --git a/src/auth/auth-request.c b/src/auth/auth-request.c index 1afd884ba6..fc39c8733f 100644 --- a/src/auth/auth-request.c +++ b/src/auth/auth-request.c @@ -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, diff --git a/src/auth/auth-request.h b/src/auth/auth-request.h index 02e6eb4024..08441ab7b7 100644 --- a/src/auth/auth-request.h +++ b/src/auth/auth-request.h @@ -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; diff --git a/src/auth/passdb.c b/src/auth/passdb.c index b804a54744..f917895733 100644 --- a/src/auth/passdb.c +++ b/src/auth/passdb.c @@ -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",