]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Switch mschap from fr_pool_t to slab allocation for conneciton ctx
authorNick Porter <nick@portercomputing.co.uk>
Tue, 3 Dec 2024 11:11:09 +0000 (11:11 +0000)
committerNick Porter <nick@portercomputing.co.uk>
Thu, 5 Dec 2024 10:32:09 +0000 (10:32 +0000)
src/modules/rlm_mschap/auth_wbclient.c
src/modules/rlm_mschap/rlm_mschap.c
src/modules/rlm_mschap/rlm_mschap.h

index db6ca66e1b22e7dd55f26e96f0fb8a9ef6e80e29..82578bf2e4accc18e9a605150d7875c2b14371e1 100644 (file)
@@ -84,7 +84,7 @@ static char *wbclient_normalise_username(TALLOC_CTX *ctx, struct wbcContext *wb_
  * @param[in] challenge                MS CHAP challenge.
  * @param[in] response         MS CHAP response.
  * @param[out] nthashhash      Hash returned on success.
- * @param[in] env_data         Call_env data for current authentication.
+ * @param[in] auth_ctx         data for current authentication.
  * @return
  *     - 0 success.
  *     - -1 auth failure.
@@ -95,6 +95,7 @@ int do_auth_wbclient(rlm_mschap_t const *inst, request_t *request,
                     uint8_t nthashhash[NT_DIGEST_LENGTH], mschap_auth_ctx_t *auth_ctx)
 {
        int                             ret = -1;
+       winbind_ctx_t                   *wbctx = NULL;
        struct wbcContext               *wb_ctx = NULL;
        struct wbcAuthUserParams        authparams;
        wbcErr                          err;
@@ -139,11 +140,12 @@ int do_auth_wbclient(rlm_mschap_t const *inst, request_t *request,
        /*
         * Send auth request across to winbind
         */
-       wb_ctx = fr_pool_connection_get(inst->wb_pool, request);
-       if (wb_ctx == NULL) {
+       wbctx = mschap_slab_reserve(auth_ctx->t->slab);
+       if (!wbctx) {
                RERROR("Unable to get winbind connection from pool");
                goto finish;
        }
+       wb_ctx = wbctx->ctx;
 
        RDEBUG2("Sending authentication request user \"%pV\" domain \"%pV\"",
                &env_data->wb_username, &env_data->wb_domain);
@@ -200,7 +202,7 @@ release:
                talloc_free(normalised_username);
        }
 
-       fr_pool_connection_release(inst->wb_pool, request, wb_ctx);
+       mschap_slab_release(wbctx);
 
        /*
         * Try and give some useful feedback on what happened. There are only
index c09a15a5f27d05269bf53b329086f459a89931ae..dc0257c7cfb9591914d585e3f6431ea14f9d2b9d 100644 (file)
@@ -84,10 +84,20 @@ static const conf_parser_t passchange_config[] = {
        CONF_PARSER_TERMINATOR
 };
 
+#ifdef WITH_AUTH_WINBIND
+static conf_parser_t reuse_winbind_config[] = {
+       { FR_CONF_OFFSET("min", fr_slab_config_t, min_elements), .dflt = "10" },
+       { FR_CONF_OFFSET("max", fr_slab_config_t, max_elements), .dflt = "100" },
+       { FR_CONF_OFFSET("cleanup_interval", fr_slab_config_t, interval), .dflt = "30s" },
+       CONF_PARSER_TERMINATOR
+};
+#endif
+
 static const conf_parser_t winbind_config[] = {
        { FR_CONF_OFFSET("username", rlm_mschap_t, wb_username) },
 #ifdef WITH_AUTH_WINBIND
        { FR_CONF_OFFSET("retry_with_normalised_username", rlm_mschap_t, wb_retry_with_normalised_username), .dflt = "no" },
+       { FR_CONF_OFFSET_SUBSECTION("reuse", 0, rlm_mschap_t, reuse, reuse_winbind_config) },
 #endif
        CONF_PARSER_TERMINATOR
 };
@@ -762,36 +772,26 @@ static xlat_action_t mschap_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out,
 
 #ifdef WITH_AUTH_WINBIND
 /*
- *     Free connection pool winbind context
+ *     Free winbind context
  */
-static int _mod_conn_free(struct wbcContext **wb_ctx)
+static int _mod_ctx_free(winbind_ctx_t *wbctx)
 {
-       wbcCtxFree(*wb_ctx);
-
+       wbcCtxFree(wbctx->ctx);
        return 0;
 }
 
 /*
- *     Create connection pool winbind context
+ *     Create winbind context
  */
-static void *mod_conn_create(TALLOC_CTX *ctx, UNUSED void *instance, UNUSED fr_time_delta_t timeout)
+static int winbind_ctx_alloc(winbind_ctx_t *wbctx, UNUSED void *uctx)
 {
-       /* Needed by ERROR() */
-       module_inst_ctx_t       *mctx = MODULE_INST_CTX(talloc_get_type_abort(instance, module_instance_t));
-       struct wbcContext       **wb_ctx;
-
-       wb_ctx = talloc_zero(ctx, struct wbcContext *);
-       *wb_ctx = wbcCtxCreate();
-
-       if (*wb_ctx == NULL) {
-               ERROR("failed to create winbind context");
-               talloc_free(wb_ctx);
-               return NULL;
+       wbctx->ctx = wbcCtxCreate();
+       if (!wbctx->ctx) {
+               fr_strerror_printf("Unable to create winbind context");
+               return -1;
        }
-
-       talloc_set_destructor(wb_ctx, _mod_conn_free);
-
-       return *wb_ctx;
+       talloc_set_destructor(wbctx, _mod_ctx_free);
+       return 0;
 }
 #endif
 
@@ -1216,7 +1216,7 @@ static int CC_HINT(nonnull) do_mschap(rlm_mschap_t const *inst, request_t *reque
        /*
         *      Process auth via the wbclient library
         */
-               return do_auth_wbclient(inst, request, challenge, response, nthashhash, auth_ctx->env_data);
+               return do_auth_wbclient(inst, request, challenge, response, nthashhash, auth_ctx);
 #endif
        default:
                /* We should never reach this line */
@@ -2224,6 +2224,9 @@ static int mschap_new_pass_decrypt(request_t *request, mschap_auth_ctx_t *auth_c
 static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
 {
        rlm_mschap_t const      *inst = talloc_get_type_abort_const(mctx->mi->data, rlm_mschap_t);
+#ifdef WITH_AUTH_WINBIND
+       rlm_mschap_thread_t     *t = talloc_get_type_abort(mctx->thread, rlm_mschap_thread_t);
+#endif
        mschap_auth_call_env_t  *env_data = talloc_get_type_abort(mctx->env_data, mschap_auth_call_env_t);
        mschap_auth_ctx_t       *auth_ctx;
 
@@ -2238,6 +2241,9 @@ static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result,
                .inst = inst,
                .method = inst->method,
                .env_data = env_data,
+#ifdef WITH_AUTH_WINBIND
+               .t = t,
+#endif
        };
 
        /*
@@ -2365,12 +2371,6 @@ static int mod_instantiate(module_inst_ctx_t const *mctx)
        if (inst->wb_username) {
 #ifdef WITH_AUTH_WINBIND
                inst->method = AUTH_WBCLIENT;
-
-               inst->wb_pool = module_rlm_connection_pool_init(conf, UNCONST(module_instance_t *, mctx->mi), mod_conn_create, NULL, NULL, NULL, NULL);
-               if (!inst->wb_pool) {
-                       cf_log_err(conf, "Unable to initialise winbind connection pool");
-                       return -1;
-               }
 #else
                cf_log_err(conf, "'winbind' auth not enabled at compiled time");
                return -1;
@@ -2457,24 +2457,28 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx)
        return 0;
 }
 
-/*
- *     Tidy up instance
- */
-static int mod_detach(
-#ifndef WITH_AUTH_WINBIND
-                     UNUSED
-#endif
-                     module_detach_ctx_t const *mctx)
-{
 #ifdef WITH_AUTH_WINBIND
-       rlm_mschap_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_mschap_t);
+static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
+{
+       rlm_mschap_t const      *inst = talloc_get_type_abort(mctx->mi->data, rlm_mschap_t);
+       rlm_mschap_thread_t     *t = talloc_get_type_abort(mctx->thread, rlm_mschap_thread_t);
 
-       fr_pool_free(inst->wb_pool);
-#endif
+       t->inst = inst;
+       if (!(t->slab = mschap_slab_list_alloc(t, mctx->el, &inst->reuse, winbind_ctx_alloc, NULL, NULL, false, false))) {
+               ERROR("Connection handle pool instantiation failed");
+               return -1;
+       }
 
        return 0;
 }
 
+static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
+{
+       rlm_mschap_thread_t     *t = talloc_get_type_abort(mctx->thread, rlm_mschap_thread_t);
+       talloc_free(t->slab);
+       return 0;
+}
+#endif
 
 extern module_rlm_t rlm_mschap;
 module_rlm_t rlm_mschap = {
@@ -2485,7 +2489,11 @@ module_rlm_t rlm_mschap = {
                .config         = module_config,
                .bootstrap      = mod_bootstrap,
                .instantiate    = mod_instantiate,
-               .detach         = mod_detach
+#ifdef WITH_AUTH_WINBIND
+               .thread_inst_size       = sizeof(rlm_mschap_thread_t),
+               .thread_instantiate     = mod_thread_instantiate,
+               .thread_detach          = mod_thread_detach
+#endif
        },
        .method_group = {
                .bindings = (module_method_binding_t[]){
index 80473919ebb4796cc4f6419930c70d803ec546d2..a90d61621f82047e786e07051d5fea1079b4a6ff 100644 (file)
@@ -6,12 +6,11 @@ RCSIDH(rlm_mschap_h, "$Id$")
 #include "mschap.h"
 
 #include <freeradius-devel/util/dict.h>
+#include <freeradius-devel/util/slab.h>
 #include <freeradius-devel/server/tmpl.h>
 
 #ifdef WITH_AUTH_WINBIND
 #  include <wbclient.h>
-
-#include <freeradius-devel/server/pool.h>
 #endif
 
 /* Method of authentication we are going to use */
@@ -58,14 +57,27 @@ typedef struct {
        MSCHAP_AUTH_METHOD      method;
        char const              *wb_username;
 #ifdef WITH_AUTH_WINBIND
-       fr_pool_t               *wb_pool;
        bool                    wb_retry_with_normalised_username;
+       fr_slab_config_t        reuse;
 #endif
 #ifdef __APPLE__
        bool                    open_directory;
 #endif
 } rlm_mschap_t;
 
+#ifdef WITH_AUTH_WINBIND
+typedef struct {
+       struct wbcContext       *ctx;
+} winbind_ctx_t;
+
+FR_SLAB_TYPES(mschap, winbind_ctx_t);
+FR_SLAB_FUNCS(mschap, winbind_ctx_t)
+
+typedef struct {
+       rlm_mschap_t const      *inst;          //!< Instance of rlm_mschap.
+       mschap_slab_list_t      *slab;          //!< Slab list for winbind handles.
+} rlm_mschap_thread_t;
+#endif
 typedef struct {
        tmpl_t const    *username;
        tmpl_t const    *chap_error;