]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: sasl-server - Define server instance object
authorStephan Bosch <stephan.bosch@open-xchange.com>
Wed, 22 Mar 2023 15:58:02 +0000 (16:58 +0100)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Thu, 9 Oct 2025 08:41:22 +0000 (08:41 +0000)
src/auth/auth-sasl.c
src/auth/auth-sasl.h
src/auth/auth.c
src/auth/auth.h
src/auth/sasl-server-private.h
src/auth/sasl-server-request.c
src/auth/sasl-server.c
src/auth/sasl-server.h

index e7e740b9bb579853844c83387a6911aed038086e..9bcbd5f9c5cc70392dcb0bb576235bc91d4f3830 100644 (file)
@@ -9,7 +9,7 @@
 #include "auth-request.h"
 #include "auth-request-handler.h"
 
-struct sasl_server *auth_sasl_server;
+static struct sasl_server *auth_sasl_server;
 
 /*
  * Request
@@ -291,7 +291,9 @@ auth_sasl_translate_protocol_name(struct auth_request *request)
 void auth_sasl_request_init(struct auth_request *request,
                            const struct sasl_server_mech_def *mech)
 {
-       sasl_server_request_create(&request->sasl.req, auth_sasl_server, mech,
+       struct auth *auth = auth_request_get_auth(request);
+
+       sasl_server_request_create(&request->sasl.req, auth->sasl_inst, mech,
                                   auth_sasl_translate_protocol_name(request),
                                   request->mech_event);
 }
@@ -369,6 +371,25 @@ auth_sasl_mech_module_find(const char *name)
        return NULL;
 }
 
+/*
+ * Instance
+ */
+
+void auth_sasl_instance_init(struct auth *auth)
+{
+       const struct sasl_server_settings sasl_set = {
+               .event_parent = auth_event,
+       };
+
+       auth->sasl_inst =
+               sasl_server_instance_create(auth_sasl_server, &sasl_set);
+}
+
+void auth_sasl_instance_deinit(struct auth *auth)
+{
+       sasl_server_instance_unref(&auth->sasl_inst);
+}
+
 /*
  * Global
  */
index 727f4429e17a6453552b839d496a53d14c950075..1031d6964442315f959016b163d115712104cbe9 100644 (file)
@@ -7,13 +7,12 @@
 #define AUTH_SASL_MAX_MECH_NAME_LEN 64
 
 struct auth_request;
+struct auth_settings;
 
 struct auth_sasl_mech_module {
        const char *mech_name;
 };
 
-extern struct sasl_server *auth_sasl_server;
-
 /*
  * Request
  */
@@ -37,6 +36,13 @@ void auth_sasl_mech_unregister_module(
 const struct auth_sasl_mech_module *
 auth_sasl_mech_module_find(const char *name);
 
+/*
+ * Instance
+ */
+
+void auth_sasl_instance_init(struct auth *auth);
+void auth_sasl_instance_deinit(struct auth *auth);
+
 /*
  * Global
  */
index 59d14ea1b2e6d5221c1ade4c30751c9605811947..7fb92186328b10ae13143c00d6fdf4d3d1553e7a 100644 (file)
@@ -6,6 +6,7 @@
 #include "userdb.h"
 #include "passdb.h"
 #include "auth.h"
+#include "auth-sasl.h"
 #include "dns-lookup.h"
 
 #define AUTH_DNS_IDLE_TIMEOUT_MSECS (1000*60)
@@ -359,6 +360,9 @@ auth_preinit(const struct auth_settings *set, const char *protocol,
                /* use a dummy userdb static. */
                auth_userdb_preinit(auth, &userdb_dummy_set);
        }
+
+       auth_sasl_instance_init(auth);
+
        return auth;
 }
 
@@ -408,6 +412,7 @@ static void auth_deinit(struct auth *auth)
 
 static void auth_free(struct auth *auth)
 {
+       auth_sasl_instance_deinit(auth);
        settings_free(auth->protocol_set);
        pool_unref(&auth->pool);
 }
index cfde068679139aed7723d2f6a774a0f691de8a86..1e3fc155c72f3504aecfca451d43a9495cade61d 100644 (file)
@@ -6,6 +6,8 @@
 
 #define PASSWORD_HIDDEN_STR "<hidden>"
 
+struct sasl_server_instance;
+
 ARRAY_DEFINE_TYPE(auth, struct auth *);
 extern ARRAY_TYPE(auth) auths;
 
@@ -77,6 +79,8 @@ struct auth {
        const struct auth_settings *protocol_set;
 
        const struct mechanisms_register *reg;
+       struct sasl_server_instance *sasl_inst;
+
        struct auth_passdb *masterdbs;
        struct auth_passdb *passdbs;
        struct auth_userdb *userdbs;
index feac242ee8665a5870bc949173487017e28aa7b8..e9576b123c88b0acd47cf0eacf32996546d3952b 100644 (file)
@@ -11,7 +11,7 @@ enum sasl_server_passdb_type {
 
 struct sasl_server_request {
        pool_t pool;
-       struct sasl_server *server;
+       struct sasl_server_instance *sinst;
        struct sasl_server_req_ctx *rctx;
        struct sasl_server_mech_request *mech;
 
@@ -19,11 +19,23 @@ struct sasl_server_request {
        sasl_server_mech_passdb_callback_t *passdb_callback;
 };
 
+struct sasl_server_instance {
+       struct sasl_server *server;
+       pool_t pool;
+       int refcount;
+       struct sasl_server_instance *prev, *next;
+       struct event *event;
+
+       unsigned int requests;
+};
+
 struct sasl_server {
        pool_t pool;
        struct event *event;
        const struct sasl_server_request_funcs *funcs;
 
+       struct sasl_server_instance *instances;
+
        unsigned int requests;
 };
 
index 0c469ad8f83a6fc82cd0604adb24d47318eec27b..149c124d89bb9ab337c5e87b4ad099fa7f596251 100644 (file)
  */
 
 void sasl_server_request_create(struct sasl_server_req_ctx *rctx,
-                               struct sasl_server *server,
+                               struct sasl_server_instance *sinst,
                                const struct sasl_server_mech_def *mech,
                                const char *protocol,
                                struct event *event_parent)
 {
+       struct sasl_server *server = sinst->server;
        struct auth_request *request =
                container_of(rctx, struct auth_request, sasl.req);
        struct sasl_server_request *req;
@@ -25,9 +26,10 @@ void sasl_server_request_create(struct sasl_server_req_ctx *rctx,
        pool = request->pool;
        req = p_new(pool, struct sasl_server_request, 1);
        req->pool = pool;
-       req->server = server;
+       req->sinst = sinst;
        req->rctx = rctx;
 
+       sinst->requests++;
        server->requests++;
 
        struct sasl_server_mech_request *mreq;
@@ -57,9 +59,12 @@ void sasl_server_request_destroy(struct sasl_server_req_ctx *rctx)
        if (req == NULL)
                return;
 
-       struct sasl_server *server = req->server;
+       struct sasl_server_instance *sinst = req->sinst;
+       struct sasl_server *server = sinst->server;
        struct sasl_server_mech_request *mreq = req->mech;
 
+       i_assert(sinst->requests > 0);
+       sinst->requests--;
        i_assert(server->requests > 0);
        server->requests--;
 
@@ -120,7 +125,7 @@ bool sasl_server_request_set_authid(struct sasl_server_mech_request *mreq,
                                    const char *authid)
 {
        struct sasl_server_request *req = mreq->req;
-       struct sasl_server *server = req->server;
+       struct sasl_server *server = req->sinst->server;
        const struct sasl_server_request_funcs *funcs = server->funcs;
 
        i_assert(funcs->request_set_authid != NULL);
@@ -131,7 +136,7 @@ bool sasl_server_request_set_authzid(struct sasl_server_mech_request *mreq,
                                     const char *authzid)
 {
        struct sasl_server_request *req = mreq->req;
-       struct sasl_server *server = req->server;
+       struct sasl_server *server = req->sinst->server;
        const struct sasl_server_request_funcs *funcs = server->funcs;
 
        i_assert(funcs->request_set_authzid != NULL);
@@ -142,7 +147,7 @@ void sasl_server_request_set_realm(struct sasl_server_mech_request *mreq,
                                   const char *realm)
 {
        struct sasl_server_request *req = mreq->req;
-       struct sasl_server *server = req->server;
+       struct sasl_server *server = req->sinst->server;
        const struct sasl_server_request_funcs *funcs = server->funcs;
 
        i_assert(funcs->request_set_realm != NULL);
@@ -154,7 +159,7 @@ bool sasl_server_request_get_extra_field(struct sasl_server_mech_request *mreq,
                                         const char **field_r)
 {
        struct sasl_server_request *req = mreq->req;
-       struct sasl_server *server = req->server;
+       struct sasl_server *server = req->sinst->server;
        const struct sasl_server_request_funcs *funcs = server->funcs;
 
        if (funcs->request_get_extra_field == NULL) {
@@ -168,7 +173,7 @@ void sasl_server_request_start_channel_binding(
        struct sasl_server_mech_request *mreq, const char *type)
 {
        struct sasl_server_request *req = mreq->req;
-       struct sasl_server *server = req->server;
+       struct sasl_server *server = req->sinst->server;
        const struct sasl_server_request_funcs *funcs = server->funcs;
 
        i_assert(funcs->request_start_channel_binding != NULL);
@@ -179,7 +184,7 @@ int sasl_server_request_accept_channel_binding(
        struct sasl_server_mech_request *mreq, buffer_t **data_r)
 {
        struct sasl_server_request *req = mreq->req;
-       struct sasl_server *server = req->server;
+       struct sasl_server *server = req->sinst->server;
        const struct sasl_server_request_funcs *funcs = server->funcs;
 
        i_assert(funcs->request_accept_channel_binding != NULL);
@@ -190,7 +195,7 @@ void sasl_server_request_output(struct sasl_server_mech_request *mreq,
                                const void *data, size_t data_size)
 {
        struct sasl_server_request *req = mreq->req;
-       struct sasl_server *server = req->server;
+       struct sasl_server *server = req->sinst->server;
        const struct sasl_server_request_funcs *funcs = server->funcs;
 
        const struct sasl_server_output output = {
@@ -206,7 +211,7 @@ void sasl_server_request_success(struct sasl_server_mech_request *mreq,
                                 const void *data, size_t data_size)
 {
        struct sasl_server_request *req = mreq->req;
-       struct sasl_server *server = req->server;
+       struct sasl_server *server = req->sinst->server;
        const struct sasl_server_request_funcs *funcs = server->funcs;
 
        const struct sasl_server_output output = {
@@ -224,7 +229,7 @@ sasl_server_request_failure_common(struct sasl_server_mech_request *mreq,
                                   const void *data, size_t data_size)
 {
        struct sasl_server_request *req = mreq->req;
-       struct sasl_server *server = req->server;
+       struct sasl_server *server = req->sinst->server;
        const struct sasl_server_request_funcs *funcs = server->funcs;
 
        const struct sasl_server_output output = {
@@ -272,7 +277,7 @@ void sasl_server_request_verify_plain(
        sasl_server_mech_passdb_callback_t *callback)
 {
        struct sasl_server_request *req = mreq->req;
-       struct sasl_server *server = req->server;
+       struct sasl_server *server = req->sinst->server;
        const struct sasl_server_request_funcs *funcs = server->funcs;
 
        req->passdb_type = SASL_SERVER_PASSDB_TYPE_VERIFY_PLAIN;
@@ -299,7 +304,7 @@ void sasl_server_request_lookup_credentials(
        sasl_server_mech_passdb_callback_t *callback)
 {
        struct sasl_server_request *req = mreq->req;
-       struct sasl_server *server = req->server;
+       struct sasl_server *server = req->sinst->server;
        const struct sasl_server_request_funcs *funcs = server->funcs;
 
        req->passdb_type = SASL_SERVER_PASSDB_TYPE_LOOKUP_CREDENTIALS;
@@ -326,7 +331,7 @@ void sasl_server_request_set_credentials(
        sasl_server_mech_passdb_callback_t *callback)
 {
        struct sasl_server_request *req = mreq->req;
-       struct sasl_server *server = req->server;
+       struct sasl_server *server = req->sinst->server;
        const struct sasl_server_request_funcs *funcs = server->funcs;
 
        req->passdb_type = SASL_SERVER_PASSDB_TYPE_SET_CREDENTIALS;
index ebd79606285079076fc1e6bc493f664a5959e0e1..25cc5cf9f9711f855af0b2526bbf7ff8d961c131 100644 (file)
@@ -1,6 +1,7 @@
 /* Copyright (c) 2023 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "llist.h"
 
 #include "sasl-server-private.h"
 
@@ -8,6 +9,65 @@ static struct event_category event_category_sasl_server = {
        .name = "sasl-server"
 };
 
+/*
+ * Instance
+ */
+
+struct sasl_server_instance *
+sasl_server_instance_create(struct sasl_server *server,
+                           const struct sasl_server_settings *set)
+{
+       struct sasl_server_instance *sinst;
+       pool_t pool;
+
+       pool = pool_alloconly_create(
+               MEMPOOL_GROWING"sasl_server_instance", 2048);
+       sinst = p_new(pool, struct sasl_server_instance, 1);
+       sinst->pool = pool;
+       sinst->refcount = 1;
+       sinst->server = server;
+
+       if (set->event_parent == NULL)
+               sinst->event = event_create(server->event);
+       else {
+               sinst->event = event_create(set->event_parent);
+               event_add_category(sinst->event, &event_category_sasl_server);
+               event_set_append_log_prefix(sinst->event, "sasl: ");
+       }
+
+       DLLIST_PREPEND(&server->instances, sinst);
+
+       return sinst;
+}
+
+void sasl_server_instance_ref(struct sasl_server_instance *sinst)
+{
+       i_assert(sinst->refcount > 0);
+       sinst->refcount++;
+}
+
+void sasl_server_instance_unref(struct sasl_server_instance **_sinst)
+{
+       struct sasl_server_instance *sinst = *_sinst;
+
+       if (sinst == NULL)
+               return;
+       *_sinst = NULL;
+
+       i_assert(sinst->refcount > 0);
+       if (--sinst->refcount > 0)
+               return;
+
+       struct sasl_server *server = sinst->server;
+
+       i_assert(sinst->requests == 0);
+
+       DLLIST_REMOVE(&server->instances, sinst);
+
+       event_unref(&sinst->event);
+       pool_unref(&sinst->pool);
+}
+
 /*
  * Server
  */
@@ -40,6 +100,7 @@ void sasl_server_deinit(struct sasl_server **_server)
                return;
        *_server = NULL;
 
+       i_assert(server->instances == NULL);
        i_assert(server->requests == 0);
 
        event_unref(&server->event);
index 3538f74d06ee45f73d170a8b7c9cbfda0443a1fc..ae5773dd4fe141cfc53073117676cc70b3f93c84 100644 (file)
@@ -7,6 +7,7 @@ struct sasl_passdb_result;
 struct sasl_server_mech_def;
 struct sasl_server_request;
 struct sasl_server_req_ctx;
+struct sasl_server_instance;
 struct sasl_server;
 
 enum sasl_passdb_result_status {
@@ -67,6 +68,11 @@ struct sasl_passdb_result {
        } credentials;
 };
 
+struct sasl_server_settings {
+       /* Event to use for the SASL server instance. */
+       struct event *event_parent;
+};
+
 /*
  * Request
  */
@@ -120,7 +126,7 @@ struct sasl_server_request_funcs {
 };
 
 void sasl_server_request_create(struct sasl_server_req_ctx *rctx,
-                               struct sasl_server *server,
+                               struct sasl_server_instance *sinst,
                                const struct sasl_server_mech_def *mech,
                                const char *protocol,
                                struct event *event_parent);
@@ -131,6 +137,16 @@ void sasl_server_request_initial(struct sasl_server_req_ctx *rctx,
 void sasl_server_request_input(struct sasl_server_req_ctx *rctx,
                               const unsigned char *data, size_t data_size);
 
+/*
+ * Instance
+ */
+
+struct sasl_server_instance *
+sasl_server_instance_create(struct sasl_server *server,
+                           const struct sasl_server_settings *set);
+void sasl_server_instance_ref(struct sasl_server_instance *sinst);
+void sasl_server_instance_unref(struct sasl_server_instance **_sinst);
+
 /*
  * Server
  */