From: Nick Porter Date: Thu, 5 Dec 2024 11:33:24 +0000 (+0000) Subject: Switch rlm_winbind from fr_pool_t to slab allocation for connection ctx X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=00f258770712cc24f4c60087ef344bc126ee9738;p=thirdparty%2Ffreeradius-server.git Switch rlm_winbind from fr_pool_t to slab allocation for connection ctx --- diff --git a/src/modules/rlm_winbind/auth_wbclient_pap.c b/src/modules/rlm_winbind/auth_wbclient_pap.c index cb91a2ea976..e96159eed40 100644 --- a/src/modules/rlm_winbind/auth_wbclient_pap.c +++ b/src/modules/rlm_winbind/auth_wbclient_pap.c @@ -37,9 +37,9 @@ RCSID("$Id$") /** PAP authentication direct to winbind via Samba's libwbclient library * - * @param[in] inst Module instance * @param[in] request The current request * @param[in] env The call_env for the current winbind authentication + * @param[in] t The module thread instance data. * * @return * - 0 Success @@ -47,9 +47,10 @@ RCSID("$Id$") * - -648 Password expired * */ -int do_auth_wbclient_pap(rlm_winbind_t const *inst, request_t *request, winbind_auth_call_env_t *env) +int do_auth_wbclient_pap(request_t *request, winbind_auth_call_env_t *env, rlm_winbind_thread_t *t) { int ret = -1; + winbind_ctx_t *wbctx; struct wbcContext *wb_ctx; struct wbcAuthUserParams authparams; wbcErr err; @@ -94,19 +95,19 @@ int do_auth_wbclient_pap(rlm_winbind_t const *inst, request_t *request, winbind_ /* * Send auth request across to winbind */ - wb_ctx = fr_pool_connection_get(inst->wb_pool, request); - if (wb_ctx == NULL) { - RERROR("Unable to get winbind connection from pool"); + wbctx = winbind_slab_reserve(t->slab); + if (!wbctx) { + RERROR("Unable to get winbind context"); goto done; } + wb_ctx = wbctx->ctx; RDEBUG2("Sending authentication request user='%s' domain='%s'", authparams.account_name, authparams.domain_name); err = wbcCtxAuthenticateUserEx(wb_ctx, &authparams, &info, &error); - fr_pool_connection_release(inst->wb_pool, request, wb_ctx); - + winbind_slab_release(wbctx); /* * Try and give some useful feedback on what happened. There are only diff --git a/src/modules/rlm_winbind/auth_wbclient_pap.h b/src/modules/rlm_winbind/auth_wbclient_pap.h index b749b7f53b6..bf97fb9442c 100644 --- a/src/modules/rlm_winbind/auth_wbclient_pap.h +++ b/src/modules/rlm_winbind/auth_wbclient_pap.h @@ -4,4 +4,4 @@ RCSIDH(auth_wbclient_h, "$Id$") -int do_auth_wbclient_pap(rlm_winbind_t const *inst, request_t *request, winbind_auth_call_env_t *env); +int do_auth_wbclient_pap(request_t *request, winbind_auth_call_env_t *env, rlm_winbind_thread_t *t); diff --git a/src/modules/rlm_winbind/rlm_winbind.c b/src/modules/rlm_winbind/rlm_winbind.c index 95d0fc72d82..90ab216eca6 100644 --- a/src/modules/rlm_winbind/rlm_winbind.c +++ b/src/modules/rlm_winbind/rlm_winbind.c @@ -42,8 +42,16 @@ static const conf_parser_t group_config[] = { CONF_PARSER_TERMINATOR }; +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 +}; + static const conf_parser_t module_config[] = { { FR_CONF_POINTER("group", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) group_config }, + { FR_CONF_OFFSET_SUBSECTION("reuse", 0, rlm_winbind_t, reuse, reuse_winbind_config) }, CONF_PARSER_TERMINATOR }; @@ -86,9 +94,10 @@ typedef struct { * - 1 failure or user is not in group */ static bool winbind_check_group(rlm_winbind_t const *inst, request_t *request, char const *name, - winbind_group_xlat_call_env_t *env) + winbind_group_xlat_call_env_t *env, rlm_winbind_thread_t *t) { bool rcode = false; + winbind_ctx_t *wbctx; struct wbcContext *wb_ctx; wbcErr err; uint32_t num_groups, i; @@ -125,13 +134,14 @@ static bool winbind_check_group(rlm_winbind_t const *inst, request_t *request, c } /* - * Get a libwbclient connection from the pool + * Get a libwbclient context */ - wb_ctx = fr_pool_connection_get(inst->wb_pool, request); - if (wb_ctx == NULL) { - RERROR("Unable to get winbind connection from the pool"); + wbctx = winbind_slab_reserve(t->slab); + if (!wbctx) { + RERROR("Unable to get winbind context"); goto error; } + wb_ctx = wbctx->ctx; RDEBUG2("Trying to find user \"%s\" in group \"%s\"", username, name); @@ -221,7 +231,7 @@ static bool winbind_check_group(rlm_winbind_t const *inst, request_t *request, c finish: wbcFreeMemory(wb_groups); - fr_pool_connection_release(inst->wb_pool, request, wb_ctx); + winbind_slab_release(wbctx); error: talloc_free(username_buff); @@ -245,6 +255,7 @@ static xlat_action_t winbind_group_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, { rlm_winbind_t const *inst = talloc_get_type_abort(xctx->mctx->mi->data, rlm_winbind_t); winbind_group_xlat_call_env_t *env = talloc_get_type_abort(xctx->env_data, winbind_group_xlat_call_env_t); + rlm_winbind_thread_t *t = talloc_get_type_abort(xctx->mctx->thread, rlm_winbind_thread_t); fr_value_box_t *arg = fr_value_box_list_head(in); char const *p = arg->vb_strvalue; fr_value_box_t *vb; @@ -252,53 +263,36 @@ static xlat_action_t winbind_group_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, fr_skip_whitespace(p); MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_BOOL, attr_expr_bool_enum)); - vb->vb_bool = winbind_check_group(inst, request, p, env); + vb->vb_bool = winbind_check_group(inst, request, p, env, t); fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } -/** Free connection pool winbind context - * - * @param[in] wb_ctx libwbclient context - * @return 0 +/* + * 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 - * - * @param[in] ctx talloc context - * @param[in] instance Module instance (unused) - * @param[in] timeout Connection timeout - * - * @return pointer to libwbclient 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) { - struct wbcContext **wb_ctx; - - wb_ctx = talloc_zero(ctx, struct wbcContext *); - *wb_ctx = wbcCtxCreate(); - - if (*wb_ctx == NULL) { - PERROR("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; } - static xlat_arg_parser_t const winbind_group_xlat_arg[] = { { .required = true, .type = FR_TYPE_STRING, .concat = true }, XLAT_ARG_PARSER_TERMINATOR @@ -316,13 +310,6 @@ static xlat_arg_parser_t const winbind_group_xlat_arg[] = { static int mod_instantiate(module_inst_ctx_t const *mctx) { rlm_winbind_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_winbind_t); - CONF_SECTION *conf = mctx->mi->conf; - - inst->wb_pool = module_rlm_connection_pool_init(conf, inst, mod_conn_create, NULL, NULL, NULL, NULL); - if (!inst->wb_pool) { - cf_log_err(conf, "Unable to initialise winbind connection pool"); - return -1; - } inst->auth_type = fr_dict_enum_by_name(attr_auth_type, mctx->mi->name, -1); if (!inst->auth_type) { @@ -334,23 +321,6 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) } -/** Tidy up module instance - * - * Frees up the libwbclient connection pool. - * - * @param[in] mctx data for this module - * @return 0 - */ -static int mod_detach(module_detach_ctx_t const *mctx) -{ - rlm_winbind_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_winbind_t); - - fr_pool_free(inst->wb_pool); - - return 0; -} - - /** Authorize for libwbclient/winbind authentication * * Checks there is a password available so we can authenticate @@ -395,8 +365,8 @@ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, mod */ static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request) { - rlm_winbind_t const *inst = talloc_get_type_abort_const(mctx->mi->data, rlm_winbind_t); winbind_auth_call_env_t *env = talloc_get_type_abort(mctx->env_data, winbind_auth_call_env_t); + rlm_winbind_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_winbind_thread_t); /* * Make sure the supplied password isn't empty @@ -420,7 +390,7 @@ static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, * many debug outputs or errors as the auth function is * chatty enough. */ - if (do_auth_wbclient_pap(inst, request, env) == 0) { + if (do_auth_wbclient_pap(request, env, t) == 0) { RDEBUG2("User authenticated successfully using winbind"); RETURN_MODULE_OK; } @@ -556,6 +526,27 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) return 0; } +static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx) +{ + rlm_winbind_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_winbind_t); + rlm_winbind_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_winbind_thread_t); + + t->inst = inst; + if (!(t->slab = winbind_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_winbind_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_winbind_thread_t); + talloc_free(t->slab); + return 0; +} + /* * The module name should be the only globally exported symbol. * That is, everything else should be 'static'. @@ -574,7 +565,9 @@ module_rlm_t rlm_winbind = { .config = module_config, .instantiate = mod_instantiate, .bootstrap = mod_bootstrap, - .detach = mod_detach + .thread_inst_size = sizeof(rlm_winbind_thread_t), + .thread_instantiate = mod_thread_instantiate, + .thread_detach = mod_thread_detach, }, .method_group = { .bindings = (module_method_binding_t[]){ diff --git a/src/modules/rlm_winbind/rlm_winbind.h b/src/modules/rlm_winbind/rlm_winbind.h index e20041a558a..473cca3fdf7 100644 --- a/src/modules/rlm_winbind/rlm_winbind.h +++ b/src/modules/rlm_winbind/rlm_winbind.h @@ -3,19 +3,31 @@ #include "config.h" #include -#include +#include /* * Structure for the module configuration. */ typedef struct { - fr_pool_t *wb_pool; - fr_dict_enum_value_t *auth_type; + fr_dict_enum_value_t *auth_type; /* group config */ bool group_add_domain; + fr_slab_config_t reuse; } rlm_winbind_t; +typedef struct { + struct wbcContext *ctx; +} winbind_ctx_t; + +FR_SLAB_TYPES(winbind, winbind_ctx_t) +FR_SLAB_FUNCS(winbind, winbind_ctx_t) + +typedef struct { + rlm_winbind_t const *inst; //!< Instance of rlm_winbind + winbind_slab_list_t *slab; //!< Slab list for winbind handles. +} rlm_winbind_thread_t; + typedef struct { fr_value_box_t username; fr_value_box_t domain;