From: Stephan Bosch Date: Tue, 24 Oct 2023 01:51:37 +0000 (+0200) Subject: auth: sasl-server-mech - Add facilities for maintaining global mechanism state X-Git-Tag: 2.4.2~187 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ffbe1f448768b436b07a45818f6c703c130f2472;p=thirdparty%2Fdovecot%2Fcore.git auth: sasl-server-mech - Add facilities for maintaining global mechanism state --- diff --git a/src/auth/sasl-server-mech.c b/src/auth/sasl-server-mech.c index 438ea121a6..90a6decd01 100644 --- a/src/auth/sasl-server-mech.c +++ b/src/auth/sasl-server-mech.c @@ -45,6 +45,44 @@ void sasl_server_mech_generic_auth_initial( } } +/* + * Global data + */ + +static struct sasl_server_mech_data * +sasl_server_mech_data_init(struct sasl_server *server, + struct sasl_server_mech_def_reg *mech_dreg) +{ + struct sasl_server_mech_data *mdata; + const struct sasl_server_mech_def *mech_def = mech_dreg->def; + + if (mech_def->funcs->data_new == NULL) + return NULL; + if (mech_dreg->data != NULL) + return mech_dreg->data; + + mech_dreg->data = mdata = mech_def->funcs->data_new(server->pool); + mdata->pool = server->pool; + mdata->server = server; + mdata->def = mech_def; + + return mdata; +} + +static void +sasl_server_mech_data_deinit(struct sasl_server_mech_def_reg *mech_dreg) +{ + struct sasl_server_mech_data *mdata = mech_dreg->data; + + if (mdata == NULL) + return; + mech_dreg->data = NULL; + + if (mdata->def->funcs->data_free == NULL) + return; + mdata->def->funcs->data_free(mdata); +} + /* * Registry */ @@ -168,6 +206,7 @@ sasl_server_mech_register_common(struct sasl_server_instance *sinst, mech = sasl_server_mech_create(sinst, def); mech->reg = mech_reg; + mech->data = sasl_server_mech_data_init(sinst->server, mech_dreg); mech_reg->mech = mech; return mech; @@ -227,6 +266,7 @@ static void sasl_server_mech_reg_free(struct sasl_server_mech_reg *mech_reg) DLLIST2_REMOVE(&server->mechs_head, &server->mechs_tail, mech_dreg); + sasl_server_mech_data_deinit(mech_dreg); mech_dreg->def = NULL; } } @@ -292,6 +332,11 @@ void sasl_server_instance_mech_registry_free( sasl_server_mech_reg_list_free(sinst->mechs_hidden); } +void sasl_server_mech_registry_free(struct sasl_server *server) +{ + i_assert(server->mechs_head == NULL); +} + /* * Iterator */ diff --git a/src/auth/sasl-server-private.h b/src/auth/sasl-server-private.h index 7e65426a0e..953ce3c9d9 100644 --- a/src/auth/sasl-server-private.h +++ b/src/auth/sasl-server-private.h @@ -80,4 +80,6 @@ struct sasl_server { void sasl_server_instance_mech_registry_free( struct sasl_server_instance *sinst); +void sasl_server_mech_registry_free(struct sasl_server *server); + #endif diff --git a/src/auth/sasl-server-protected.h b/src/auth/sasl-server-protected.h index 2df4340b55..5abe4cd934 100644 --- a/src/auth/sasl-server-protected.h +++ b/src/auth/sasl-server-protected.h @@ -8,6 +8,7 @@ struct auth_request; struct sasl_server_mech_funcs; struct sasl_server_mech_def; +struct sasl_server_mech_data; struct sasl_server_mech_request; typedef void @@ -22,6 +23,10 @@ struct sasl_server_mech_funcs { const unsigned char *data, size_t data_size); void (*auth_free)(struct sasl_server_mech_request *req); + /* Global data shared between server instances */ + struct sasl_server_mech_data *(*data_new)(pool_t pool); + void (*data_free)(struct sasl_server_mech_data *mdata); + struct sasl_server_mech *(*mech_new)(pool_t pool); void (*mech_free)(struct sasl_server_mech *mech); }; @@ -50,11 +55,19 @@ struct mechanisms_register { buffer_t *handshake_cbind; }; +struct sasl_server_mech_data { + struct sasl_server *server; + pool_t pool; + + const struct sasl_server_mech_def *def; +}; + struct sasl_server_mech { struct sasl_server_instance *sinst; struct sasl_server_mech_reg *reg; pool_t pool; struct event *event; + struct sasl_server_mech_data *data; const struct sasl_server_mech_def *def; }; diff --git a/src/auth/sasl-server.c b/src/auth/sasl-server.c index f120287031..7b48e0a30d 100644 --- a/src/auth/sasl-server.c +++ b/src/auth/sasl-server.c @@ -109,6 +109,8 @@ void sasl_server_deinit(struct sasl_server **_server) i_assert(server->instances == NULL); i_assert(server->requests == 0); + sasl_server_mech_registry_free(server); + event_unref(&server->event); pool_unref(&server->pool); }