From: Aki Tuomi Date: Sat, 9 Jul 2016 17:11:45 +0000 (+0300) Subject: auth: Skip authentication with noauthenticate X-Git-Tag: 2.2.26~486 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cd1786b3475c6324457995833918f4561da34bd0;p=thirdparty%2Fdovecot%2Fcore.git auth: Skip authentication with noauthenticate --- diff --git a/src/auth/auth-master-connection.c b/src/auth/auth-master-connection.c index 1b0bedafa1..73e368285b 100644 --- a/src/auth/auth-master-connection.c +++ b/src/auth/auth-master-connection.c @@ -341,6 +341,7 @@ static void pass_callback_finish(struct auth_request *auth_request, case PASSDB_RESULT_PASS_EXPIRED: str_printfa(str, "NOTFOUND\t%u", auth_request->id); break; + case PASSDB_RESULT_NEXT: case PASSDB_RESULT_PASSWORD_MISMATCH: case PASSDB_RESULT_INTERNAL_FAILURE: str_printfa(str, "FAIL\t%u", auth_request->id); diff --git a/src/auth/auth-request-handler.c b/src/auth/auth-request-handler.c index 17d52c655e..415b06d68b 100644 --- a/src/auth/auth-request-handler.c +++ b/src/auth/auth-request-handler.c @@ -305,6 +305,7 @@ auth_request_handler_reply_failure_finish(struct auth_request *request) auth_str_append_extra_fields(request, str); switch (request->passdb_result) { + case PASSDB_RESULT_NEXT: case PASSDB_RESULT_INTERNAL_FAILURE: case PASSDB_RESULT_SCHEME_NOT_AVAILABLE: case PASSDB_RESULT_USER_UNKNOWN: diff --git a/src/auth/auth-request.c b/src/auth/auth-request.c index 89ec55d869..7040fad7f6 100644 --- a/src/auth/auth-request.c +++ b/src/auth/auth-request.c @@ -485,6 +485,7 @@ static void auth_request_save_cache(struct auth_request *request, case PASSDB_RESULT_SCHEME_NOT_AVAILABLE: /* can be cached */ break; + case PASSDB_RESULT_NEXT: case PASSDB_RESULT_USER_DISABLED: case PASSDB_RESULT_PASS_EXPIRED: /* FIXME: we can't cache this now, or cache lookup would @@ -652,6 +653,11 @@ auth_request_handle_passdb_callback(enum passdb_result *result, case PASSDB_RESULT_INTERNAL_FAILURE: result_rule = request->passdb->result_internalfail; break; + case PASSDB_RESULT_NEXT: + auth_request_log_debug(request, AUTH_SUBSYS_DB, + "Not performing authentication (noauthenticate set)"); + result_rule = AUTH_DB_RULE_CONTINUE; + break; case PASSDB_RESULT_SCHEME_NOT_AVAILABLE: case PASSDB_RESULT_USER_UNKNOWN: case PASSDB_RESULT_PASSWORD_MISMATCH: @@ -692,6 +698,7 @@ auth_request_handle_passdb_callback(enum passdb_result *result, /* nopassword check is specific to a single passdb and shouldn't leak to the next one. we already added it to cache. */ auth_fields_remove(request->extra_fields, "nopassword"); + auth_fields_remove(request->extra_fields, "noauthenticate"); if (request->requested_login_user != NULL && *result == PASSDB_RESULT_OK) { @@ -706,7 +713,7 @@ auth_request_handle_passdb_callback(enum passdb_result *result, auth_request_want_skip_passdb(request, next_passdb)) next_passdb = next_passdb->next; - if (*result == PASSDB_RESULT_OK) { + if (*result == PASSDB_RESULT_OK || *result == PASSDB_RESULT_NEXT) { /* this passdb lookup succeeded, preserve its extra fields */ auth_fields_snapshot(request->extra_fields); request->snapshot_have_userdb_prefetch_set = @@ -777,6 +784,10 @@ void auth_request_verify_plain_callback(enum passdb_result result, auth_request_set_state(request, AUTH_REQUEST_STATE_MECH_CONTINUE); + if (result == PASSDB_RESULT_OK && + auth_fields_exists(request->extra_fields, "noauthenticate")) + result = PASSDB_RESULT_NEXT; + if (result != PASSDB_RESULT_INTERNAL_FAILURE) auth_request_save_cache(request, result); else { @@ -1009,6 +1020,10 @@ void auth_request_lookup_credentials_callback(enum passdb_result result, auth_request_set_state(request, AUTH_REQUEST_STATE_MECH_CONTINUE); + if (result == PASSDB_RESULT_OK && + auth_fields_exists(request->extra_fields, "noauthenticate")) + result = PASSDB_RESULT_NEXT; + if (result != PASSDB_RESULT_INTERNAL_FAILURE) auth_request_save_cache(request, result); else { @@ -2254,7 +2269,8 @@ int auth_request_password_verify(struct auth_request *request, return 0; } - if (auth_fields_exists(request->extra_fields, "nopassword")) { + if (auth_fields_exists(request->extra_fields, "nopassword") || + auth_fields_exists(request->extra_fields, "noauthenticate")) { auth_request_log_debug(request, subsystem, "Allowing any password"); return 1; diff --git a/src/auth/auth-worker-client.c b/src/auth/auth-worker-client.c index fdf72bc4c9..da0bed715d 100644 --- a/src/auth/auth-worker-client.c +++ b/src/auth/auth-worker-client.c @@ -152,7 +152,10 @@ static void verify_plain_callback(enum passdb_result result, str_printfa(str, "%u\t", request->id); if (result == PASSDB_RESULT_OK) - str_append(str, "OK"); + if (auth_fields_exists(request->extra_fields, "noauthenticate")) + str_append(str, "NEXT"); + else + str_append(str, "OK"); else str_printfa(str, "FAIL\t%d", result); if (result != PASSDB_RESULT_INTERNAL_FAILURE) { @@ -235,10 +238,13 @@ lookup_credentials_callback(enum passdb_result result, str = t_str_new(128); str_printfa(str, "%u\t", request->id); - if (result != PASSDB_RESULT_OK) + if (result != PASSDB_RESULT_OK && result != PASSDB_RESULT_NEXT) str_printfa(str, "FAIL\t%d", result); else { - str_append(str, "OK\t"); + if (result == PASSDB_RESULT_NEXT) + str_append(str, "NEXT\t"); + else + str_append(str, "OK\t"); str_append_tabescaped(str, request->user); str_append_c(str, '\t'); if (request->credentials_scheme[0] != '\0') { diff --git a/src/auth/passdb-blocking.c b/src/auth/passdb-blocking.c index 7bf6c6b390..fe8de403c5 100644 --- a/src/auth/passdb-blocking.c +++ b/src/auth/passdb-blocking.c @@ -36,6 +36,13 @@ auth_worker_reply_parse(struct auth_request *request, const char *reply) return PASSDB_RESULT_OK; } + if (strcmp(*args, "NEXT") == 0 && args[1] != NULL) { + /* NEXT \t user [\t extra] */ + auth_request_set_field(request, "user", args[1], NULL); + auth_worker_reply_parse_args(request, args + 1); + return PASSDB_RESULT_NEXT; + } + if (strcmp(*args, "FAIL") == 0 && args[1] != NULL) { int result; /* FAIL \t result [\t user \t password [\t extra]] */ diff --git a/src/auth/passdb-sql.c b/src/auth/passdb-sql.c index 81a3ba61dc..d3f391211a 100644 --- a/src/auth/passdb-sql.c +++ b/src/auth/passdb-sql.c @@ -99,7 +99,8 @@ static void sql_query_callback(struct sql_result *result, auth_request_log_error(auth_request, AUTH_SUBSYS_DB, "Password query returned multiple matches"); } else if (auth_request->passdb_password == NULL && - !auth_fields_exists(auth_request->extra_fields, "nopassword")) { + !auth_fields_exists(auth_request->extra_fields, "nopassword") && + !auth_fields_exists(auth_request->extra_fields, "noauthenticate")) { auth_request_log_info(auth_request, AUTH_SUBSYS_DB, "Empty password returned without nopassword"); passdb_result = PASSDB_RESULT_PASSWORD_MISMATCH; diff --git a/src/auth/passdb.h b/src/auth/passdb.h index 57b25391e1..922ec00912 100644 --- a/src/auth/passdb.h +++ b/src/auth/passdb.h @@ -16,6 +16,7 @@ enum passdb_result { PASSDB_RESULT_USER_UNKNOWN = -3, PASSDB_RESULT_USER_DISABLED = -4, PASSDB_RESULT_PASS_EXPIRED = -5, + PASSDB_RESULT_NEXT = -6, PASSDB_RESULT_PASSWORD_MISMATCH = 0, PASSDB_RESULT_OK = 1