]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: sasl-server - Change mechanism passdb callbacks to use just one type
authorStephan Bosch <stephan.bosch@open-xchange.com>
Tue, 7 Mar 2023 13:29:38 +0000 (14:29 +0100)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Thu, 9 Oct 2025 08:41:22 +0000 (08:41 +0000)
13 files changed:
src/auth/auth-request.c
src/auth/auth-sasl-mech-apop.c
src/auth/sasl-server-mech-cram-md5.c
src/auth/sasl-server-mech-digest-md5.c
src/auth/sasl-server-mech-gssapi.c
src/auth/sasl-server-mech-otp.c
src/auth/sasl-server-mech-plain-common.c
src/auth/sasl-server-mech-plain-common.h
src/auth/sasl-server-mech-scram.c
src/auth/sasl-server-private.h
src/auth/sasl-server-protected.h
src/auth/sasl-server-request.c
src/auth/sasl-server.h

index abc5f6e1528d62a82780aec01fe59c69e2ebb6be..b0b41106b56bf6721b7f2682c01c37e84057c14f 100644 (file)
@@ -15,7 +15,7 @@
 #include "hostpid.h"
 #include "settings.h"
 #include "master-service.h"
-#include "sasl-server-protected.h" // FIXME: remove
+#include "sasl-server-private.h" // FIXME: remove
 #include "auth-cache.h"
 #include "auth-request.h"
 #include "auth-request-handler.h"
index f25359f4c14083b718ec68bbf5cde27eea38f67d..cb4c710ebda12af9197726ceed409f5cd33a778b 100644 (file)
@@ -42,22 +42,22 @@ static bool verify_credentials(struct apop_auth_request *request,
 }
 
 static void
-apop_credentials_callback(enum passdb_result result,
-                         const unsigned char *credentials, size_t size,
-                         struct sasl_server_mech_request *auth_request)
+apop_credentials_callback(struct sasl_server_mech_request *auth_request,
+                         const struct sasl_passdb_result *result)
 {
        struct apop_auth_request *request =
                container_of(auth_request, struct apop_auth_request,
                             auth_request);
 
-       switch (result) {
-       case PASSDB_RESULT_OK:
-               if (verify_credentials(request, credentials, size))
+       switch (result->status) {
+       case SASL_PASSDB_RESULT_OK:
+               if (verify_credentials(request, result->credentials.data,
+                                      result->credentials.size))
                        sasl_server_request_success(auth_request, "", 0);
                else
                        sasl_server_request_failure(auth_request);
                break;
-       case PASSDB_RESULT_INTERNAL_FAILURE:
+       case SASL_PASSDB_RESULT_INTERNAL_FAILURE:
                sasl_server_request_internal_failure(auth_request);
                break;
        default:
index f4b691bf4d0bd9dfee84182125f225d74c05556b..c40c776242bc3b07b5603f3c05aedaa9446621d7 100644 (file)
@@ -110,13 +110,13 @@ parse_cram_response(struct cram_auth_request *request,
 }
 
 static void
-credentials_callback(enum passdb_result result,
-                    const unsigned char *credentials, size_t size,
-                    struct sasl_server_mech_request *auth_request)
+credentials_callback(struct sasl_server_mech_request *auth_request,
+                    const struct sasl_passdb_result *result)
 {
-       switch (result) {
+       switch (result->status) {
        case SASL_PASSDB_RESULT_OK:
-               verify_credentials(auth_request, credentials, size);
+               verify_credentials(auth_request, result->credentials.data,
+                                  result->credentials.size);
                break;
        case SASL_PASSDB_RESULT_INTERNAL_FAILURE:
                sasl_server_request_internal_failure(auth_request);
index 3a6a91e7afff694f1d3aa116d467695a50400643..678ebe47f475489290d0632d94f83a690efffd1a 100644 (file)
@@ -529,13 +529,13 @@ parse_digest_response(struct digest_auth_request *request,
 }
 
 static void
-credentials_callback(enum passdb_result result,
-                    const unsigned char *credentials, size_t size,
-                    struct sasl_server_mech_request *auth_request)
+credentials_callback(struct sasl_server_mech_request *auth_request,
+                    const struct sasl_passdb_result *result)
 {
-       switch (result) {
+       switch (result->status) {
        case SASL_PASSDB_RESULT_OK:
-               verify_credentials(auth_request, credentials, size);
+               verify_credentials(auth_request, result->credentials.data,
+                                  result->credentials.size);
                break;
        case SASL_PASSDB_RESULT_INTERNAL_FAILURE:
                sasl_server_request_internal_failure(auth_request);
index 2ec148b8779c343544533458ebd49a78651d64f4..3606d2b87eb351f205171393dd57c7ba3c81c320 100644 (file)
@@ -488,10 +488,8 @@ mech_gssapi_userok(struct gssapi_auth_request *request, const char *login_user)
 }
 
 static void
-gssapi_credentials_callback(enum passdb_result result,
-                           const unsigned char *credentials ATTR_UNUSED,
-                           size_t size ATTR_UNUSED,
-                           struct sasl_server_mech_request *auth_request)
+gssapi_credentials_callback(struct sasl_server_mech_request *auth_request,
+                           const struct sasl_passdb_result *result)
 {
        struct gssapi_auth_request *request =
                container_of(auth_request, struct gssapi_auth_request,
@@ -500,7 +498,7 @@ gssapi_credentials_callback(enum passdb_result result,
        /* We don't care much whether the lookup succeeded or not because GSSAPI
           does not strictly require a passdb. But if a passdb is configured,
           now the k5principals field will have been filled in. */
-       switch (result) {
+       switch (result->status) {
        case SASL_PASSDB_RESULT_INTERNAL_FAILURE:
                sasl_server_request_internal_failure(auth_request);
                return;
@@ -509,7 +507,6 @@ gssapi_credentials_callback(enum passdb_result result,
                /* User is explicitly disabled, don't allow it to log in */
                sasl_server_request_failure(auth_request);
                return;
-       case PASSDB_RESULT_NEXT: /* FIXME: To be removed */
        case SASL_PASSDB_RESULT_SCHEME_NOT_AVAILABLE:
        case SASL_PASSDB_RESULT_USER_UNKNOWN:
        case SASL_PASSDB_RESULT_PASSWORD_MISMATCH:
index 9bebf531dc29745dd81f56ad96b5558250023822..3a26407faba3594fe5dd5a09a57f41fa03cd9fb3 100644 (file)
@@ -109,17 +109,17 @@ otp_send_challenge(struct otp_auth_request *request,
 }
 
 static void
-otp_credentials_callback(enum passdb_result result,
-                        const unsigned char *credentials, size_t size,
-                        struct sasl_server_mech_request *auth_request)
+otp_credentials_callback(struct sasl_server_mech_request *auth_request,
+                        const struct sasl_passdb_result *result)
 {
        struct otp_auth_request *request =
                container_of(auth_request, struct otp_auth_request,
                             auth_request);
 
-       switch (result) {
+       switch (result->status) {
        case SASL_PASSDB_RESULT_OK:
-               otp_send_challenge(request, credentials, size);
+               otp_send_challenge(request, result->credentials.data,
+                                  result->credentials.size);
                break;
        case SASL_PASSDB_RESULT_INTERNAL_FAILURE:
                sasl_server_request_internal_failure(auth_request);
@@ -168,14 +168,14 @@ mech_otp_auth_phase1(struct otp_auth_request *request,
 }
 
 static void
-otp_set_credentials_callback(bool success,
-                            struct sasl_server_mech_request *auth_request)
+otp_set_credentials_callback(struct sasl_server_mech_request *auth_request,
+                            const struct sasl_passdb_result *result)
 {
        struct otp_auth_request *request =
                container_of(auth_request, struct otp_auth_request,
                             auth_request);
 
-       if (success)
+       if (result->status == SASL_PASSDB_RESULT_OK)
                sasl_server_request_success(auth_request, "", 0);
        else {
                sasl_server_request_internal_failure(auth_request);
index 201fc940f4d2190eeb15821c7af0a51c3125f105..f0c60b2ca6589a7ddd68b3abad9a848cdef3c41f 100644 (file)
@@ -6,9 +6,10 @@
 #include "sasl-server-mech-plain-common.h"
 
 void sasl_server_mech_plain_verify_callback(
-       enum passdb_result result, struct sasl_server_mech_request *request)
+       struct sasl_server_mech_request *request,
+       const struct sasl_passdb_result *result)
 {
-       switch (result) {
+       switch (result->status) {
        case SASL_PASSDB_RESULT_OK:
                sasl_server_request_success(request, "", 0);
                break;
index 82bb1740d666386b47671839cce133598c03f113..125798cbad95852b1435dd3b64f4a446ee8ef67b 100644 (file)
@@ -2,6 +2,7 @@
 #define SASL_SERVER_MECH_PLAIN_COMMON_H
 
 void sasl_server_mech_plain_verify_callback(
-       enum passdb_result result, struct sasl_server_mech_request *request);
+       struct sasl_server_mech_request *request,
+       const struct sasl_passdb_result *result);
 
 #endif
index 3f7a906d2ba693beb916c90526bbae583867a069..00ba1504cd2ed07ee5484a58a5fb753cd59a9868 100644 (file)
@@ -18,9 +18,8 @@ struct scram_auth_request {
 };
 
 static void
-credentials_callback(enum passdb_result result,
-                    const unsigned char *credentials, size_t size,
-                    struct sasl_server_mech_request *auth_request)
+credentials_callback(struct sasl_server_mech_request *auth_request,
+                    const struct sasl_passdb_result *result)
 {
        struct scram_auth_request *request =
                container_of(auth_request, struct scram_auth_request,
@@ -31,11 +30,12 @@ credentials_callback(enum passdb_result result,
        size_t output_len;
        bool end;
 
-       switch (result) {
+       switch (result->status) {
        case SASL_PASSDB_RESULT_OK:
                if (auth_scram_credentials_parse(key_data->hmethod,
                                                 request->password_scheme,
-                                                credentials, size,
+                                                result->credentials.data,
+                                                result->credentials.size,
                                                 &key_data->iter_count,
                                                 &key_data->salt,
                                                 key_data->stored_key,
index b234384a177ebe5ee3dc65b8a252e88b8a845e64..88432be6bcafa1552be4ebdca764191308a09673 100644 (file)
@@ -3,8 +3,17 @@
 
 #include "sasl-server-protected.h"
 
+enum sasl_server_passdb_type {
+       SASL_SERVER_PASSDB_TYPE_VERIFY_PLAIN,
+       SASL_SERVER_PASSDB_TYPE_LOOKUP_CREDENTIALS,
+       SASL_SERVER_PASSDB_TYPE_SET_CREDENTIALS,
+};
+
 struct sasl_server_request {
        struct sasl_server_mech_request *mech;
+
+       enum sasl_server_passdb_type passdb_type;
+       sasl_server_mech_passdb_callback_t *passdb_callback;
 };
 
 #endif
index 459da9272e7f891849d8c6117c83a5b670235940..bf5d94d6b78905e625589f3c22917c9d1e37aab3 100644 (file)
@@ -10,16 +10,8 @@ struct auth_request;
 struct sasl_server_mech_request;
 
 typedef void
-sasl_server_verify_plain_callback_t(enum passdb_result result,
-                                   struct sasl_server_mech_request *req);
-typedef void
-sasl_server_lookup_credentials_callback_t(enum passdb_result result,
-                                         const unsigned char *credentials,
-                                         size_t size,
-                                         struct sasl_server_mech_request *req);
-typedef void
-sasl_server_set_credentials_callback_t(bool success,
-                                      struct sasl_server_mech_request *req);
+sasl_server_mech_passdb_callback_t(struct sasl_server_mech_request *req,
+                                  const struct sasl_passdb_result *result);
 
 struct sasl_server_mech_def {
        const char *mech_name;
@@ -58,11 +50,6 @@ struct sasl_server_mech_request {
 
        // FIXME: To be removed
        struct auth_request *request;
-       union {
-               sasl_server_verify_plain_callback_t *verify_plain;
-               sasl_server_lookup_credentials_callback_t *lookup_credentials;
-               sasl_server_set_credentials_callback_t *set_credentials;
-       } private_callback;
 };
 
 /*
@@ -124,13 +111,13 @@ void sasl_server_request_internal_failure(
 
 void sasl_server_request_verify_plain(
        struct sasl_server_mech_request *mreq, const char *password,
-       sasl_server_verify_plain_callback_t *callback);
+       sasl_server_mech_passdb_callback_t *callback);
 void sasl_server_request_lookup_credentials(
        struct sasl_server_mech_request *mreq, const char *scheme,
-       sasl_server_lookup_credentials_callback_t *callback);
+       sasl_server_mech_passdb_callback_t *callback);
 void sasl_server_request_set_credentials(
        struct sasl_server_mech_request *mreq,
        const char *scheme, const char *data,
-       sasl_server_set_credentials_callback_t *callback);
+       sasl_server_mech_passdb_callback_t *callback);
 
 #endif
index 73d64c5502ccd78263f081a37c45c652cacdb9b8..0559398d4bc4af5c95be406bce71977971535c35 100644 (file)
@@ -203,42 +203,85 @@ void sasl_server_request_internal_failure(
                mreq, SASL_SERVER_OUTPUT_INTERNAL_FAILURE, "", 0);
 }
 
+static enum sasl_passdb_result_status
+translate_result_status(enum passdb_result result)
+{
+       switch (result) {
+       case PASSDB_RESULT_INTERNAL_FAILURE:;
+               return SASL_PASSDB_RESULT_INTERNAL_FAILURE;
+       case PASSDB_RESULT_SCHEME_NOT_AVAILABLE:
+               return SASL_PASSDB_RESULT_SCHEME_NOT_AVAILABLE;
+       case PASSDB_RESULT_USER_UNKNOWN:
+               return SASL_PASSDB_RESULT_USER_UNKNOWN;
+       case PASSDB_RESULT_USER_DISABLED:
+               return SASL_PASSDB_RESULT_USER_DISABLED;
+       case PASSDB_RESULT_PASS_EXPIRED:
+               return SASL_PASSDB_RESULT_PASS_EXPIRED;
+       case PASSDB_RESULT_PASSWORD_MISMATCH:
+               return SASL_PASSDB_RESULT_PASSWORD_MISMATCH;
+       case PASSDB_RESULT_NEXT:
+       case PASSDB_RESULT_OK:
+               return SASL_PASSDB_RESULT_OK;
+       }
+       i_unreached();
+}
+
 static void
-verify_plain_callback(enum passdb_result result, struct auth_request *request)
+verify_plain_callback(enum passdb_result status, struct auth_request *request)
 {
        struct sasl_server_mech_request *mreq = request->sasl;
+       struct sasl_server_request *req = mreq->req;
+
+       i_assert(req->passdb_type == SASL_SERVER_PASSDB_TYPE_VERIFY_PLAIN);
 
-       mreq->private_callback.verify_plain(result, request->sasl);
+       const struct sasl_passdb_result result = {
+               .status = translate_result_status(status),
+       };
+       req->passdb_callback(mreq, &result);
 }
 
 void sasl_server_request_verify_plain(
        struct sasl_server_mech_request *mreq, const char *password,
-       sasl_server_verify_plain_callback_t *callback)
+       sasl_server_mech_passdb_callback_t *callback)
 {
        struct auth_request *request = mreq->request;
+       struct sasl_server_request *req = mreq->req;
 
-       mreq->private_callback.verify_plain = callback;
+       req->passdb_type = SASL_SERVER_PASSDB_TYPE_VERIFY_PLAIN;
+       req->passdb_callback = callback;
        auth_sasl_request_verify_plain(request, password, verify_plain_callback);
 }
 
 static void
-lookup_credentials_callback(enum passdb_result result,
+lookup_credentials_callback(enum passdb_result status,
                            const unsigned char *credentials,
                            size_t size, struct auth_request *request)
 {
        struct sasl_server_mech_request *mreq = request->sasl;
+       struct sasl_server_request *req = mreq->req;
+
+       i_assert(req->passdb_type ==
+                SASL_SERVER_PASSDB_TYPE_LOOKUP_CREDENTIALS);
 
-       mreq->private_callback.lookup_credentials(result, credentials, size,
-                                                 mreq);
+       const struct sasl_passdb_result result = {
+               .status = translate_result_status(status),
+               .credentials = {
+                       .data = credentials,
+                       .size = size,
+               },
+       };
+       req->passdb_callback(mreq, &result);
 }
 
 void sasl_server_request_lookup_credentials(
        struct sasl_server_mech_request *mreq, const char *scheme,
-       sasl_server_lookup_credentials_callback_t *callback)
+       sasl_server_mech_passdb_callback_t *callback)
 {
        struct auth_request *request = mreq->request;
+       struct sasl_server_request *req = mreq->req;
 
-       mreq->private_callback.lookup_credentials = callback;
+       req->passdb_type = SASL_SERVER_PASSDB_TYPE_LOOKUP_CREDENTIALS;
+       req->passdb_callback = callback;
        auth_sasl_request_lookup_credentials(request, scheme, 
                                             lookup_credentials_callback);
 }
@@ -247,18 +290,28 @@ static void
 set_credentials_callback(bool success, struct auth_request *request)
 {
        struct sasl_server_mech_request *mreq = request->sasl;
+       struct sasl_server_request *req = mreq->req;
 
-       mreq->private_callback.set_credentials(success, mreq);
+       i_assert(req->passdb_type == SASL_SERVER_PASSDB_TYPE_SET_CREDENTIALS);
+
+       const struct sasl_passdb_result result = {
+               .status = (success ?
+                          SASL_PASSDB_RESULT_OK :
+                          SASL_PASSDB_RESULT_INTERNAL_FAILURE),
+       };
+       req->passdb_callback(mreq, &result);
 }
 
 void sasl_server_request_set_credentials(
        struct sasl_server_mech_request *mreq,
        const char *scheme, const char *data,
-       sasl_server_set_credentials_callback_t *callback)
+       sasl_server_mech_passdb_callback_t *callback)
 {
        struct auth_request *request = mreq->request;
+       struct sasl_server_request *req = mreq->req;
 
-       mreq->private_callback.set_credentials = callback;
+       req->passdb_type = SASL_SERVER_PASSDB_TYPE_SET_CREDENTIALS;
+       req->passdb_callback = callback;
        auth_sasl_request_set_credentials(request, scheme, data,
                                          set_credentials_callback);
 }
index b33edad2cc066ab01937990075fe769a49da84d8..882e1fda17bf91dc0fcd054c96e826a1e61e3113 100644 (file)
@@ -5,18 +5,19 @@
 
 struct sasl_server_mech_def;
 struct sasl_server_mech_request;
+struct sasl_server_request;
 struct sasl_server_req_ctx;
 
 enum sasl_passdb_result_status {
-       SASL_PASSDB_RESULT_INTERNAL_FAILURE = PASSDB_RESULT_INTERNAL_FAILURE,
-       SASL_PASSDB_RESULT_SCHEME_NOT_AVAILABLE = PASSDB_RESULT_SCHEME_NOT_AVAILABLE,
+       SASL_PASSDB_RESULT_INTERNAL_FAILURE = -1,
+       SASL_PASSDB_RESULT_SCHEME_NOT_AVAILABLE = -2,
 
-       SASL_PASSDB_RESULT_USER_UNKNOWN = PASSDB_RESULT_USER_UNKNOWN,
-       SASL_PASSDB_RESULT_USER_DISABLED = PASSDB_RESULT_USER_DISABLED,
-       SASL_PASSDB_RESULT_PASS_EXPIRED = PASSDB_RESULT_PASS_EXPIRED,
+       SASL_PASSDB_RESULT_USER_UNKNOWN = -3,
+       SASL_PASSDB_RESULT_USER_DISABLED = -4,
+       SASL_PASSDB_RESULT_PASS_EXPIRED = -5,
 
-       SASL_PASSDB_RESULT_PASSWORD_MISMATCH = PASSDB_RESULT_PASSWORD_MISMATCH,
-       SASL_PASSDB_RESULT_OK = PASSDB_RESULT_OK,
+       SASL_PASSDB_RESULT_PASSWORD_MISMATCH = 0,
+       SASL_PASSDB_RESULT_OK = 1,
 };
 
 enum sasl_mech_passdb_need {
@@ -52,6 +53,15 @@ struct sasl_server_output {
        size_t data_size;
 };
 
+struct sasl_passdb_result {
+       enum sasl_passdb_result_status status;
+
+       struct {
+               const unsigned char *data;
+               size_t size;
+       } credentials;
+};
+
 /*
  * Request
  */