From 8933edf83ca81012c10a3e7f36fb92c59e0a4584 Mon Sep 17 00:00:00 2001 From: Arran Cudbard-Bell Date: Sun, 12 May 2024 11:08:01 -0600 Subject: [PATCH] Fixup rlm_modules that did instantiatey things in bootstrap --- src/modules/rlm_always/rlm_always.c | 76 ++-- src/modules/rlm_brotli/rlm_brotli.c | 4 +- .../rlm_cache_rbtree/rlm_cache_rbtree.c | 187 +++++----- src/modules/rlm_cache/rlm_cache.c | 24 +- src/modules/rlm_chap/rlm_chap.c | 2 +- src/modules/rlm_cipher/rlm_cipher.c | 14 +- src/modules/rlm_csv/rlm_csv.c | 2 +- src/modules/rlm_date/rlm_date.c | 4 +- src/modules/rlm_delay/rlm_delay.c | 3 +- src/modules/rlm_dhcpv4/rlm_dhcpv4.c | 140 ++++---- src/modules/rlm_eap/rlm_eap.c | 42 +-- src/modules/rlm_escape/rlm_escape.c | 4 +- src/modules/rlm_exec/rlm_exec.c | 36 +- src/modules/rlm_icmp/rlm_icmp.c | 53 +-- src/modules/rlm_idn/rlm_idn.c | 3 +- src/modules/rlm_json/rlm_json.c | 30 +- src/modules/rlm_ldap/rlm_ldap.c | 328 +++++++++--------- src/modules/rlm_linelog/rlm_linelog.c | 5 +- src/modules/rlm_mschap/rlm_mschap.c | 6 +- src/modules/rlm_perl/rlm_perl.c | 21 +- src/modules/rlm_radius/rlm_radius.c | 4 +- src/modules/rlm_radius/rlm_radius_udp.c | 12 +- src/modules/rlm_radutmp/rlm_radutmp.c | 64 +++- src/modules/rlm_redis/rlm_redis.c | 12 +- src/modules/rlm_rest/rlm_rest.c | 5 +- .../drivers/rlm_sql_mysql/rlm_sql_mysql.c | 4 +- .../drivers/rlm_sql_oracle/rlm_sql_oracle.c | 4 +- .../rlm_sql_postgresql/rlm_sql_postgresql.c | 4 +- .../drivers/rlm_sql_sqlite/rlm_sql_sqlite.c | 11 +- src/modules/rlm_sql/rlm_sql.c | 215 +++++++----- src/modules/rlm_sqlcounter/rlm_sqlcounter.c | 128 +++---- src/modules/rlm_sqlippool/rlm_sqlippool.c | 11 +- src/modules/rlm_tacacs/rlm_tacacs.c | 4 +- src/modules/rlm_test/rlm_test.c | 6 +- src/modules/rlm_totp/rlm_totp.c | 77 ++-- src/modules/rlm_unbound/rlm_unbound.c | 15 +- src/modules/rlm_unix/rlm_unix.c | 15 +- src/modules/rlm_winbind/rlm_winbind.c | 4 +- src/modules/rlm_yubikey/rlm_yubikey.c | 2 +- src/process/dhcpv6/base.c | 4 +- src/process/radius/base.c | 7 +- src/process/tacacs/base.c | 20 +- src/process/ttls/base.c | 7 +- 43 files changed, 854 insertions(+), 765 deletions(-) diff --git a/src/modules/rlm_always/rlm_always.c b/src/modules/rlm_always/rlm_always.c index 87524f5a67..4b00ebd299 100644 --- a/src/modules/rlm_always/rlm_always.c +++ b/src/modules/rlm_always/rlm_always.c @@ -27,20 +27,30 @@ RCSID("$Id$") #define LOG_PREFIX mctx->mi->name #include +#include #include #include +/* + * Instance data is mprotected for runtime + * this is fine for the majority of module + * instances, but not for rlm_always. + * + * This struct is allocated outside of the + */ +typedef struct { + rlm_rcode_t rcode; //!< The integer constant representing rcode_str. + bool force; //!< If true, we force the rcode. +} rlm_always_mutable_t; + /* * The instance data for rlm_always is the list of fake values we are * going to return. */ typedef struct { - char const *rcode_str; //!< The base value. - module_instance_t *mi; - - rlm_rcode_t rcode; //!< The integer constant representing rcode_str. - uint32_t simulcount; - bool mpp; + char const *rcode_str; //!< The base value. + module_instance_t *mi; + rlm_always_mutable_t *mutable; } rlm_always_t; /* @@ -48,8 +58,6 @@ typedef struct { */ static const conf_parser_t module_config[] = { { FR_CONF_OFFSET("rcode", rlm_always_t, rcode_str), .dflt = "fail" }, - { FR_CONF_OFFSET("simulcount", rlm_always_t, simulcount), .dflt = "0" }, - { FR_CONF_OFFSET("mpp", rlm_always_t, mpp), .dflt = "no" }, CONF_PARSER_TERMINATOR }; @@ -115,20 +123,22 @@ done: } -static int mod_bootstrap(module_inst_ctx_t const *mctx) +/* + * Just return the rcode ... this function is autz, auth, acct, and + * preacct! + */ +static unlang_action_t CC_HINT(nonnull) mod_always_return(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request) { - rlm_always_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_always_t); - xlat_t *xlat; + rlm_always_t const *inst = talloc_get_type_abort_const(mctx->mi->data, rlm_always_t); - inst->mi = module_rlm_by_name(NULL, mctx->mi->name); - if (!inst->mi) { - cf_log_err(mctx->mi->conf, "Can't find the module instance data for this module: %s", mctx->mi->name); - return -1; - } + RETURN_MODULE_RCODE(inst->mutable->rcode); +} - xlat = xlat_func_register_module(inst, mctx, NULL, always_xlat, FR_TYPE_STRING); - xlat_func_args_set(xlat, always_xlat_args); +static int mod_detach(module_detach_ctx_t const *mctx) +{ + rlm_always_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_always_t); + talloc_free(inst->mutable); return 0; } @@ -136,11 +146,23 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) { rlm_always_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_always_t); + inst->mi = module_rlm_by_name(NULL, mctx->mi->name); + if (!inst->mi) { + cf_log_err(mctx->mi->conf, "Can't find the module instance data for this module: %s", mctx->mi->name); + return -1; + } + + /* + * Allocate this outside of the module instance data, + * as that gets mprotected + */ + MEM(inst->mutable = talloc_zero(NULL, rlm_always_mutable_t)); + /* * Convert the rcode string to an int */ - inst->rcode = fr_table_value_by_str(rcode_table, inst->rcode_str, RLM_MODULE_NOT_SET); - if (inst->rcode == RLM_MODULE_NOT_SET) { + inst->mutable->rcode = fr_table_value_by_str(rcode_table, inst->rcode_str, RLM_MODULE_NOT_SET); + if (inst->mutable->rcode == RLM_MODULE_NOT_SET) { cf_log_err(mctx->mi->conf, "rcode value \"%s\" is invalid", inst->rcode_str); return -1; } @@ -148,15 +170,14 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) return 0; } -/* - * Just return the rcode ... this function is autz, auth, acct, and - * preacct! - */ -static unlang_action_t CC_HINT(nonnull) mod_always_return(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request) +static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_always_t const *inst = talloc_get_type_abort_const(mctx->mi->data, rlm_always_t); + xlat_t *xlat; - RETURN_MODULE_RCODE(inst->rcode); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, NULL, always_xlat, FR_TYPE_STRING); + xlat_func_args_set(xlat, always_xlat_args); + + return 0; } extern module_rlm_t rlm_always; @@ -168,6 +189,7 @@ module_rlm_t rlm_always = { .config = module_config, .bootstrap = mod_bootstrap, .instantiate = mod_instantiate, + .detach = mod_detach }, .method_names = (module_method_name_t[]){ { .name1 = CF_IDENT_ANY, .name2 = CF_IDENT_ANY, .method = mod_always_return }, diff --git a/src/modules/rlm_brotli/rlm_brotli.c b/src/modules/rlm_brotli/rlm_brotli.c index 38130e9851..3cf663de5a 100644 --- a/src/modules/rlm_brotli/rlm_brotli.c +++ b/src/modules/rlm_brotli/rlm_brotli.c @@ -383,11 +383,11 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) { xlat_t *xlat; - if (unlikely((xlat = xlat_func_register_module(NULL, mctx, "compress", brotli_xlat_compress, + if (unlikely((xlat = xlat_func_register_module(mctx->mi->boot, mctx, "compress", brotli_xlat_compress, FR_TYPE_OCTETS)) == NULL)) return -1; xlat_func_args_set(xlat, brotli_xlat_compress_args); - if (unlikely((xlat = xlat_func_register_module(NULL, mctx, "decompress", brotli_xlat_decompress, + if (unlikely((xlat = xlat_func_register_module(mctx->mi->boot, mctx, "decompress", brotli_xlat_decompress, FR_TYPE_OCTETS)) == NULL)) return -1; xlat_func_args_set(xlat, brotli_xlat_decompress_args); diff --git a/src/modules/rlm_cache/drivers/rlm_cache_rbtree/rlm_cache_rbtree.c b/src/modules/rlm_cache/drivers/rlm_cache_rbtree/rlm_cache_rbtree.c index 0ac8522834..ff379f9248 100644 --- a/src/modules/rlm_cache/drivers/rlm_cache_rbtree/rlm_cache_rbtree.c +++ b/src/modules/rlm_cache/drivers/rlm_cache_rbtree/rlm_cache_rbtree.c @@ -28,17 +28,21 @@ #include "../../rlm_cache.h" typedef struct { - fr_rb_tree_t *cache; //!< Tree for looking up cache keys. - fr_heap_t *heap; //!< For managing entry expiry. + fr_rb_tree_t *cache; //!< Tree for looking up cache keys. + fr_heap_t *heap; //!< For managing entry expiry. - pthread_mutex_t mutex; //!< Protect the tree from multiple readers/writers. + pthread_mutex_t mutex; //!< Protect the tree from multiple readers/writers. +} rlm_cache_rbtree_mutable_t; + +typedef struct { + rlm_cache_rbtree_mutable_t *mutable; //!< Mutable instance data. } rlm_cache_rbtree_t; typedef struct { - rlm_cache_entry_t fields; //!< Entry data. + rlm_cache_entry_t fields; //!< Entry data. - fr_rb_node_t node; //!< Entry used for lookups. - fr_heap_index_t heap_id; //!< Offset used for expiry heap. + fr_rb_node_t node; //!< Entry used for lookups. + fr_heap_index_t heap_id; //!< Offset used for expiry heap. } rlm_cache_rb_entry_t; /** Compare two entries by key @@ -64,68 +68,6 @@ static int8_t cache_heap_cmp(void const *one, void const *two) return fr_unix_time_cmp(a->expires, b->expires); } -/** Cleanup a cache_rbtree instance - * - */ -static int mod_detach(module_detach_ctx_t const *mctx) -{ - rlm_cache_rbtree_t *driver = talloc_get_type_abort(mctx->mi->data, rlm_cache_rbtree_t); - - if (driver->cache) { - fr_rb_iter_inorder_t iter; - void *data; - - for (data = fr_rb_iter_init_inorder(&iter, driver->cache); - data; - data = fr_rb_iter_next_inorder(&iter)) { - fr_rb_iter_delete_inorder(&iter); - talloc_free(data); - } - } - - pthread_mutex_destroy(&driver->mutex); - - return 0; -} - -/** Create a new cache_rbtree instance - * - * @param[in] mctx Data required for instantiation. - * @return - * - 0 on success. - * - -1 on failure. - */ -static int mod_instantiate(module_inst_ctx_t const *mctx) -{ - rlm_cache_rbtree_t *driver = talloc_get_type_abort(mctx->mi->data, rlm_cache_rbtree_t); - int ret; - - /* - * The cache. - */ - driver->cache = fr_rb_inline_talloc_alloc(driver, rlm_cache_rb_entry_t, node, cache_entry_cmp, NULL); - if (!driver->cache) { - ERROR("Failed to create cache"); - return -1; - } - - /* - * The heap of entries to expire. - */ - driver->heap = fr_heap_talloc_alloc(driver, cache_heap_cmp, rlm_cache_rb_entry_t, heap_id, 0); - if (!driver->heap) { - ERROR("Failed to create heap for the cache"); - return -1; - } - - if ((ret = pthread_mutex_init(&driver->mutex, NULL)) < 0) { - ERROR("Failed initializing mutex: %s", fr_syserror(ret)); - return -1; - } - - return 0; -} - /** Custom allocation function for the driver * * Allows allocation of cache entry structures with additional fields. @@ -157,19 +99,20 @@ static cache_status_t cache_entry_find(rlm_cache_entry_t **out, request_t *request, UNUSED void *handle, fr_value_box_t const *key) { rlm_cache_rbtree_t *driver = talloc_get_type_abort(instance, rlm_cache_rbtree_t); + rlm_cache_rbtree_mutable_t *mutable = driver->mutable; rlm_cache_entry_t find = {}; rlm_cache_entry_t *c; - fr_assert(driver->cache); + fr_assert(mutable->cache); /* * Clear out old entries */ - c = fr_heap_peek(driver->heap); + c = fr_heap_peek(mutable->heap); if (c && (fr_unix_time_lt(c->expires, fr_time_to_unix_time(request->packet->timestamp)))) { - fr_heap_extract(&driver->heap, c); - fr_rb_delete(driver->cache, c); + fr_heap_extract(&mutable->heap, c); + fr_rb_delete(mutable->cache, c); talloc_free(c); } @@ -178,7 +121,7 @@ static cache_status_t cache_entry_find(rlm_cache_entry_t **out, /* * Is there an entry for this key? */ - c = fr_rb_find(driver->cache, &find); + c = fr_rb_find(mutable->cache, &find); if (!c) { *out = NULL; return CACHE_MISS; @@ -206,11 +149,11 @@ static cache_status_t cache_entry_expire(UNUSED rlm_cache_config_t const *config fr_value_box_copy_shallow(NULL, &find.key, key); - c = fr_rb_find(driver->cache, &find); + c = fr_rb_find(driver->mutable->cache, &find); if (!c) return CACHE_MISS; - fr_heap_extract(&driver->heap, c); - fr_rb_delete(driver->cache, c); + fr_heap_extract(&driver->mutable->heap, c); + fr_rb_delete(driver->mutable->cache, c); talloc_free(c); return CACHE_OK; @@ -237,19 +180,19 @@ static cache_status_t cache_entry_insert(rlm_cache_config_t const *config, void /* * Allow overwriting */ - if (!fr_rb_insert(driver->cache, c)) { + if (!fr_rb_insert(driver->mutable->cache, c)) { status = cache_entry_expire(config, instance, request, handle, &c->key); if ((status != CACHE_OK) && !fr_cond_assert(0)) return CACHE_ERROR; - if (!fr_rb_insert(driver->cache, c)) { + if (!fr_rb_insert(driver->mutable->cache, c)) { RERROR("Failed adding entry"); return CACHE_ERROR; } } - if (fr_heap_insert(&driver->heap, UNCONST(rlm_cache_entry_t *, c)) < 0) { - fr_rb_delete(driver->cache, c); + if (fr_heap_insert(&driver->mutable->heap, UNCONST(rlm_cache_entry_t *, c)) < 0) { + fr_rb_delete(driver->mutable->cache, c); RERROR("Failed adding entry to expiry heap"); return CACHE_ERROR; @@ -274,13 +217,13 @@ static cache_status_t cache_entry_set_ttl(UNUSED rlm_cache_config_t const *confi if (!request) return CACHE_ERROR; #endif - if (!fr_cond_assert(fr_heap_extract(&driver->heap, c) == 0)) { + if (!fr_cond_assert(fr_heap_extract(&driver->mutable->heap, c) == 0)) { RERROR("Entry not in heap"); return CACHE_ERROR; } - if (fr_heap_insert(&driver->heap, c) < 0) { - fr_rb_delete(driver->cache, c); /* make sure we don't leak entries... */ + if (fr_heap_insert(&driver->mutable->heap, c) < 0) { + fr_rb_delete(driver->mutable->cache, c); /* make sure we don't leak entries... */ RERROR("Failed updating entry TTL. Entry was forcefully expired"); return CACHE_ERROR; } @@ -300,7 +243,7 @@ static uint64_t cache_entry_count(UNUSED rlm_cache_config_t const *config, void if (!request) return CACHE_ERROR; - return fr_rb_num_elements(driver->cache); + return fr_rb_num_elements(driver->mutable->cache); } /** Lock the rbtree @@ -314,7 +257,7 @@ static int cache_acquire(void **handle, UNUSED rlm_cache_config_t const *config, { rlm_cache_rbtree_t *driver = talloc_get_type_abort(instance, rlm_cache_rbtree_t); - pthread_mutex_lock(&driver->mutex); + pthread_mutex_lock(&driver->mutable->mutex); *handle = request; /* handle is unused, this is just for sanity checking */ @@ -334,11 +277,83 @@ static void cache_release(UNUSED rlm_cache_config_t const *config, void *instanc { rlm_cache_rbtree_t *driver = talloc_get_type_abort(instance, rlm_cache_rbtree_t); - pthread_mutex_unlock(&driver->mutex); + pthread_mutex_unlock(&driver->mutable->mutex); RDEBUG3("Mutex released"); } +/** Cleanup a cache_rbtree instance + * + */ +static int mod_detach(module_detach_ctx_t const *mctx) +{ + rlm_cache_rbtree_t *driver = talloc_get_type_abort(mctx->mi->data, rlm_cache_rbtree_t); + rlm_cache_rbtree_mutable_t *mutable = driver->mutable; + + if (mutable->cache) { + fr_rb_iter_inorder_t iter; + void *data; + + for (data = fr_rb_iter_init_inorder(&iter, mutable->cache); + data; + data = fr_rb_iter_next_inorder(&iter)) { + fr_rb_iter_delete_inorder(&iter); + talloc_free(data); + } + } + + pthread_mutex_destroy(&mutable->mutex); + + TALLOC_FREE(driver->mutable); + + return 0; +} + +/** Create a new cache_rbtree instance + * + * @param[in] mctx Data required for instantiation. + * @return + * - 0 on success. + * - -1 on failure. + */ +static int mod_instantiate(module_inst_ctx_t const *mctx) +{ + rlm_cache_rbtree_t *driver = talloc_get_type_abort(mctx->mi->data, rlm_cache_rbtree_t); + rlm_cache_rbtree_mutable_t *mutable; + int ret; + + MEM(mutable = talloc_zero(NULL, rlm_cache_rbtree_mutable_t)); + + /* + * The cache. + */ + mutable->cache = fr_rb_inline_talloc_alloc(mutable, rlm_cache_rb_entry_t, node, cache_entry_cmp, NULL); + if (!mutable->cache) { + ERROR("Failed to create cache"); + error: + talloc_free(mutable); + goto error; + } + + /* + * The heap of entries to expire. + */ + mutable->heap = fr_heap_talloc_alloc(mutable, cache_heap_cmp, rlm_cache_rb_entry_t, heap_id, 0); + if (!mutable->heap) { + ERROR("Failed to create heap for the cache"); + goto error; + } + + if ((ret = pthread_mutex_init(&mutable->mutex, NULL)) < 0) { + ERROR("Failed initializing mutex: %s", fr_syserror(ret)); + goto error; + } + + driver->mutable = mutable; + + return 0; +} + extern rlm_cache_driver_t rlm_cache_rbtree; rlm_cache_driver_t rlm_cache_rbtree = { .common = { diff --git a/src/modules/rlm_cache/rlm_cache.c b/src/modules/rlm_cache/rlm_cache.c index 03ff26ea5e..e709de72bf 100644 --- a/src/modules/rlm_cache/rlm_cache.c +++ b/src/modules/rlm_cache/rlm_cache.c @@ -1441,6 +1441,14 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) rlm_cache_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_cache_t); CONF_SECTION *conf = mctx->mi->conf; + /* + * Non optional fields and callbacks + */ + fr_assert(inst->driver->common.name); + fr_assert(inst->driver->find); + fr_assert(inst->driver->insert); + fr_assert(inst->driver->expire); + if (!fr_time_delta_ispos(inst->config.ttl)) { cf_log_err(conf, "Must set 'ttl' to non-zero"); return -1; @@ -1459,27 +1467,22 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) */ static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_cache_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_cache_t ); xlat_t *xlat; - - inst->driver = (rlm_cache_driver_t const *)inst->driver_submodule->exported; + rlm_cache_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_cache_t); /* - * Non optional fields and callbacks + * Needs to be set here for callenv parsing */ - fr_assert(inst->driver->common.name); - fr_assert(inst->driver->find); - fr_assert(inst->driver->insert); - fr_assert(inst->driver->expire); + inst->driver = (rlm_cache_driver_t const *)inst->driver_submodule->exported; /* * Register the cache xlat function */ - xlat = xlat_func_register_module(inst, mctx, NULL, cache_xlat, FR_TYPE_VOID); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, NULL, cache_xlat, FR_TYPE_VOID); xlat_func_args_set(xlat, cache_xlat_args); xlat_func_call_env_set(xlat, &cache_method_env); - xlat = xlat_func_register_module(inst, mctx, "ttl.get", cache_ttl_get_xlat, FR_TYPE_VOID); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, "ttl.get", cache_ttl_get_xlat, FR_TYPE_VOID); xlat_func_call_env_set(xlat, &cache_method_env); return 0; @@ -1497,6 +1500,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) module_rlm_t rlm_cache = { .common = { .magic = MODULE_MAGIC_INIT, + .flags = MODULE_TYPE_DYNAMIC_UNSAFE, .name = "cache", .inst_size = sizeof(rlm_cache_t), .config = module_config, diff --git a/src/modules/rlm_chap/rlm_chap.c b/src/modules/rlm_chap/rlm_chap.c index 8be472e10b..7db176f631 100644 --- a/src/modules/rlm_chap/rlm_chap.c +++ b/src/modules/rlm_chap/rlm_chap.c @@ -361,7 +361,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) { xlat_t *xlat; - if (unlikely((xlat = xlat_func_register_module(NULL, mctx, "password", xlat_func_chap_password, + if (unlikely((xlat = xlat_func_register_module(mctx->mi->boot, mctx, "password", xlat_func_chap_password, FR_TYPE_OCTETS)) == NULL)) return -1; xlat_func_args_set(xlat, xlat_func_chap_password_args); xlat_func_call_env_set(xlat, &chap_xlat_method_env); diff --git a/src/modules/rlm_cipher/rlm_cipher.c b/src/modules/rlm_cipher/rlm_cipher.c index 11a85327d2..5050668911 100644 --- a/src/modules/rlm_cipher/rlm_cipher.c +++ b/src/modules/rlm_cipher/rlm_cipher.c @@ -1277,8 +1277,8 @@ static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx) */ static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_cipher_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_cipher_t); - CONF_SECTION *conf = mctx->mi->conf; + rlm_cipher_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_cipher_t); + CONF_SECTION *conf = mctx->mi->conf; switch (inst->type) { case RLM_CIPHER_TYPE_RSA: @@ -1299,13 +1299,13 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * Register decrypt xlat */ - xlat = xlat_func_register_module(inst, mctx, "decrypt", cipher_rsa_decrypt_xlat, FR_TYPE_STRING); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, "decrypt", cipher_rsa_decrypt_xlat, FR_TYPE_STRING); xlat_func_mono_set(xlat, cipher_rsa_decrypt_xlat_arg); /* * Verify sign xlat */ - xlat = xlat_func_register_module(inst, mctx, "verify", cipher_rsa_verify_xlat, FR_TYPE_BOOL); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, "verify", cipher_rsa_verify_xlat, FR_TYPE_BOOL); xlat_func_args_set(xlat, cipher_rsa_verify_xlat_arg); } @@ -1331,20 +1331,20 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * Register encrypt xlat */ - xlat = xlat_func_register_module(inst, mctx, "encrypt", cipher_rsa_encrypt_xlat, FR_TYPE_OCTETS); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, "encrypt", cipher_rsa_encrypt_xlat, FR_TYPE_OCTETS); xlat_func_mono_set(xlat, cipher_rsa_encrypt_xlat_arg); /* * Register sign xlat */ - xlat = xlat_func_register_module(inst, mctx, "sign", cipher_rsa_sign_xlat, FR_TYPE_OCTETS); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, "sign", cipher_rsa_sign_xlat, FR_TYPE_OCTETS); xlat_func_mono_set(xlat, cipher_rsa_sign_xlat_arg); /* * FIXME: These should probably be split into separate xlats * so we can optimise for return types. */ - xlat = xlat_func_register_module(inst, mctx, "certificate", cipher_certificate_xlat, FR_TYPE_VOID); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, "certificate", cipher_certificate_xlat, FR_TYPE_VOID); xlat_func_args_set(xlat, cipher_certificate_xlat_args); } break; diff --git a/src/modules/rlm_csv/rlm_csv.c b/src/modules/rlm_csv/rlm_csv.c index d849ad3d04..a6f0c54290 100644 --- a/src/modules/rlm_csv/rlm_csv.c +++ b/src/modules/rlm_csv/rlm_csv.c @@ -1052,7 +1052,7 @@ module_rlm_t rlm_csv = { .common = { .magic = MODULE_MAGIC_INIT, .name = "csv", - .flags = 0, + .flags = MODULE_TYPE_DYNAMIC_UNSAFE, .inst_size = sizeof(rlm_csv_t), .config = module_config, .bootstrap = mod_bootstrap, diff --git a/src/modules/rlm_date/rlm_date.c b/src/modules/rlm_date/rlm_date.c index 38a2395075..005aa010e0 100644 --- a/src/modules/rlm_date/rlm_date.c +++ b/src/modules/rlm_date/rlm_date.c @@ -27,7 +27,6 @@ #include #include #include -#include #include typedef struct { @@ -232,10 +231,9 @@ static xlat_action_t xlat_date_convert(TALLOC_CTX *ctx, fr_dcursor_t *out, static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_date_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_date_t ); xlat_t *xlat; - xlat = xlat_func_register_module(inst, mctx, NULL, xlat_date_convert, FR_TYPE_VOID); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, NULL, xlat_date_convert, FR_TYPE_VOID); xlat_func_args_set(xlat, xlat_date_convert_args); return 0; diff --git a/src/modules/rlm_delay/rlm_delay.c b/src/modules/rlm_delay/rlm_delay.c index 8cacbc4dec..c15b3e12e8 100644 --- a/src/modules/rlm_delay/rlm_delay.c +++ b/src/modules/rlm_delay/rlm_delay.c @@ -262,10 +262,9 @@ yield: static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_delay_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_delay_t); xlat_t *xlat; - xlat = xlat_func_register_module(inst, mctx, NULL, xlat_delay, FR_TYPE_TIME_DELTA); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, NULL, xlat_delay, FR_TYPE_TIME_DELTA); xlat_func_args_set(xlat, xlat_delay_args); return 0; } diff --git a/src/modules/rlm_dhcpv4/rlm_dhcpv4.c b/src/modules/rlm_dhcpv4/rlm_dhcpv4.c index 8b1dc2fd43..8a0bbe6c8a 100644 --- a/src/modules/rlm_dhcpv4/rlm_dhcpv4.c +++ b/src/modules/rlm_dhcpv4/rlm_dhcpv4.c @@ -31,8 +31,6 @@ RCSID("$Id$") #include -#include - static fr_dict_t const *dict_dhcpv4; static fr_dict_t const *dict_freeradius; @@ -100,47 +98,6 @@ static const conf_parser_t module_config[] = { CONF_PARSER_TERMINATOR }; -/** Bootstrap the module - * - * Bootstrap I/O and type submodules. - * - * @param[in] mctx data for this module - * @return - * - 0 on success. - * - -1 on failure. - */ -static int mod_bootstrap(module_inst_ctx_t const *mctx) -{ - rlm_dhcpv4_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_dhcpv4_t); - CONF_SECTION *conf = mctx->mi->conf; - - /* - * Ensure that we have a destination address. - */ - if (inst->config.ipaddr.af == AF_UNSPEC) { - cf_log_err(conf, "A value must be given for 'ipaddr'"); - return -1; - } - - if (inst->config.ipaddr.af != AF_INET) { - cf_log_err(conf, "DHCPv4 can only use IPv4 addresses in 'ipaddr'"); - return -1; - } - - if (!inst->config.port) { - cf_log_err(conf, "A value must be given for 'port'"); - return -1; - } - - /* - * Clamp max_packet_size - */ - FR_INTEGER_BOUND_CHECK("max_packet_size", inst->max_packet_size, >=, DEFAULT_PACKET_SIZE); - FR_INTEGER_BOUND_CHECK("max_packet_size", inst->max_packet_size, <=, MAX_PACKET_SIZE); - - return 0; -} - typedef struct { request_t *request; bool sent; @@ -155,32 +112,6 @@ static void dhcpv4_queue_resume(bool sent, void *rctx) unlang_interpret_mark_runnable(d->request); } -/** Instantiate thread data for the submodule. - * - */ -static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx) -{ - rlm_dhcpv4_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_dhcpv4_t); - rlm_dhcpv4_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_dhcpv4_thread_t); - CONF_SECTION *conf = mctx->mi->conf; - - t->buffer = talloc_array(t, uint8_t, inst->max_packet_size); - if (!t->buffer) { - cf_log_err(conf, "Failed allocating buffer"); - return -1; - } - - t->buffer_size = inst->max_packet_size; - - t->uq = fr_udp_queue_alloc(t, &inst->config, mctx->el, dhcpv4_queue_resume); - if (!t->uq) { - cf_log_err(conf, "Failed allocating outbound udp queue - %s", fr_strerror()); - return -1; - } - - return 0; -} - static unlang_action_t dhcpv4_resume(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request) { rlm_dhcpv4_delay_t *d = talloc_get_type_abort(mctx->rctx, rlm_dhcpv4_delay_t); @@ -194,7 +125,6 @@ static unlang_action_t dhcpv4_resume(rlm_rcode_t *p_result, module_ctx_t const * RETURN_MODULE_OK; } - /** Send packets outbound. * */ @@ -321,13 +251,81 @@ static unlang_action_t CC_HINT(nonnull) mod_process(rlm_rcode_t *p_result, modul return unlang_module_yield(request, dhcpv4_resume, NULL, 0, d); } + +/** Instantiate thread data for the submodule. + * + */ +static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx) +{ + rlm_dhcpv4_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_dhcpv4_t); + rlm_dhcpv4_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_dhcpv4_thread_t); + CONF_SECTION *conf = mctx->mi->conf; + + t->buffer = talloc_array(t, uint8_t, inst->max_packet_size); + if (!t->buffer) { + cf_log_err(conf, "Failed allocating buffer"); + return -1; + } + + t->buffer_size = inst->max_packet_size; + + t->uq = fr_udp_queue_alloc(t, &inst->config, mctx->el, dhcpv4_queue_resume); + if (!t->uq) { + cf_log_err(conf, "Failed allocating outbound udp queue - %s", fr_strerror()); + return -1; + } + + return 0; +} + +/** Bootstrap the module + * + * Bootstrap I/O and type submodules. + * + * @param[in] mctx data for this module + * @return + * - 0 on success. + * - -1 on failure. + */ +static int mod_instantiate(module_inst_ctx_t const *mctx) +{ + rlm_dhcpv4_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_dhcpv4_t); + CONF_SECTION *conf = mctx->mi->conf; + + /* + * Ensure that we have a destination address. + */ + if (inst->config.ipaddr.af == AF_UNSPEC) { + cf_log_err(conf, "A value must be given for 'ipaddr'"); + return -1; + } + + if (inst->config.ipaddr.af != AF_INET) { + cf_log_err(conf, "DHCPv4 can only use IPv4 addresses in 'ipaddr'"); + return -1; + } + + if (!inst->config.port) { + cf_log_err(conf, "A value must be given for 'port'"); + return -1; + } + + /* + * Clamp max_packet_size + */ + FR_INTEGER_BOUND_CHECK("max_packet_size", inst->max_packet_size, >=, DEFAULT_PACKET_SIZE); + FR_INTEGER_BOUND_CHECK("max_packet_size", inst->max_packet_size, <=, MAX_PACKET_SIZE); + + return 0; +} + extern module_rlm_t rlm_dhcpv4; module_rlm_t rlm_dhcpv4 = { .common = { .magic = MODULE_MAGIC_INIT, .name = "dhcpv4", .inst_size = sizeof(rlm_dhcpv4_t), - .bootstrap = mod_bootstrap, + .instantiate = mod_instantiate, .config = module_config, diff --git a/src/modules/rlm_eap/rlm_eap.c b/src/modules/rlm_eap/rlm_eap.c index 056d7d3f83..f5361020ac 100644 --- a/src/modules/rlm_eap/rlm_eap.c +++ b/src/modules/rlm_eap/rlm_eap.c @@ -1054,34 +1054,8 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) { rlm_eap_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_eap_t); size_t i; + size_t j, loaded, count = 0; - inst->auth_type = fr_dict_enum_by_name(attr_auth_type, mctx->mi->name, -1); - if (!inst->auth_type) { - WARN("Failed to find 'authenticate %s {...}' section. EAP authentication will likely not work", - mctx->mi->name); - } - - /* - * Create our own random pool. - */ - for (i = 0; i < 256; i++) inst->rand_pool.randrsl[i] = fr_rand(); - fr_isaac_init(&inst->rand_pool, 1); - inst->rand_pool.randcnt = 0; - - return 0; -} - -static int mod_bootstrap(module_inst_ctx_t const *mctx) -{ - rlm_eap_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_eap_t); - size_t i, j, loaded, count = 0; - - /* - * Load and bootstrap the submodules now - * We have to do that here instead of in a parse function - * Because the submodule might want to look at its parent - * and we haven't completed our own bootstrap phase yet. - */ loaded = talloc_array_length(inst->type_submodules); /* @@ -1178,6 +1152,19 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) } } + inst->auth_type = fr_dict_enum_by_name(attr_auth_type, mctx->mi->name, -1); + if (!inst->auth_type) { + WARN("Failed to find 'authenticate %s {...}' section. EAP authentication will likely not work", + mctx->mi->name); + } + + /* + * Create our own random pool. + */ + for (i = 0; i < 256; i++) inst->rand_pool.randrsl[i] = fr_rand(); + fr_isaac_init(&inst->rand_pool, 1); + inst->rand_pool.randcnt = 0; + return 0; } @@ -1207,7 +1194,6 @@ module_rlm_t rlm_eap = { .config = module_config, .onload = mod_load, .unload = mod_unload, - .bootstrap = mod_bootstrap, .instantiate = mod_instantiate, }, .method_names = (module_method_name_t[]){ diff --git a/src/modules/rlm_escape/rlm_escape.c b/src/modules/rlm_escape/rlm_escape.c index ec82daa984..394db3d997 100644 --- a/src/modules/rlm_escape/rlm_escape.c +++ b/src/modules/rlm_escape/rlm_escape.c @@ -195,11 +195,11 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) { xlat_t *xlat; - xlat = xlat_func_register_module(NULL, mctx, "escape", escape_xlat, FR_TYPE_STRING); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, "escape", escape_xlat, FR_TYPE_STRING); xlat_func_mono_set(xlat, escape_xlat_arg); xlat_func_flags_set(xlat, XLAT_FUNC_FLAG_PURE); - xlat = xlat_func_register_module(NULL, mctx, "unescape", unescape_xlat, FR_TYPE_STRING); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, "unescape", unescape_xlat, FR_TYPE_STRING); xlat_func_mono_set(xlat, unescape_xlat_arg); xlat_func_flags_set(xlat, XLAT_FUNC_FLAG_PURE); diff --git a/src/modules/rlm_exec/rlm_exec.c b/src/modules/rlm_exec/rlm_exec.c index c40c0d493c..a2eca08365 100644 --- a/src/modules/rlm_exec/rlm_exec.c +++ b/src/modules/rlm_exec/rlm_exec.c @@ -442,24 +442,10 @@ static unlang_action_t CC_HINT(nonnull) mod_exec_dispatch_oneshot(rlm_rcode_t *p NULL, 0, &m->box); } -/* - * Do any per-module initialization that is separate to each - * configured instance of the module. e.g. set up connections - * to external databases, read configuration files, set up - * dictionary entries, etc. - * - * If configuration information is given in the config section - * that must be referenced in later calls, store a handle to it - * in *instance otherwise put a null pointer there. - */ -static int mod_bootstrap(module_inst_ctx_t const *mctx) +static int mob_instantiate(module_inst_ctx_t const *mctx) { rlm_exec_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_exec_t); CONF_SECTION *conf = mctx->mi->conf; - xlat_t *xlat; - - xlat = xlat_func_register_module(NULL, mctx, NULL, exec_xlat_oneshot, FR_TYPE_STRING); - xlat_func_args_set(xlat, exec_xlat_args); if (inst->input_list && !tmpl_is_list(inst->input_list)) { cf_log_perr(conf, "Invalid input list '%s'", inst->input_list->name); @@ -506,6 +492,25 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) return 0; } +/* + * Do any per-module initialization that is separate to each + * configured instance of the module. e.g. set up connections + * to external databases, read configuration files, set up + * dictionary entries, etc. + * + * If configuration information is given in the config section + * that must be referenced in later calls, store a handle to it + * in *instance otherwise put a null pointer there. + */ +static int mod_bootstrap(module_inst_ctx_t const *mctx) +{ + xlat_t *xlat; + + xlat = xlat_func_register_module(mctx->mi->boot, mctx, NULL, exec_xlat_oneshot, FR_TYPE_STRING); + xlat_func_args_set(xlat, exec_xlat_args); + + return 0; +} /* * The module name should be the only globally exported symbol. @@ -524,6 +529,7 @@ module_rlm_t rlm_exec = { .inst_size = sizeof(rlm_exec_t), .config = module_config, .bootstrap = mod_bootstrap, + .instantiate = mob_instantiate }, .method_names = (module_method_name_t[]){ { .name1 = CF_IDENT_ANY, .name2 = CF_IDENT_ANY, .method = mod_exec_dispatch_oneshot, diff --git a/src/modules/rlm_icmp/rlm_icmp.c b/src/modules/rlm_icmp/rlm_icmp.c index 13d4b5f3d1..cdcb289b9c 100644 --- a/src/modules/rlm_icmp/rlm_icmp.c +++ b/src/modules/rlm_icmp/rlm_icmp.c @@ -372,6 +372,22 @@ static void mod_icmp_error(fr_event_list_t *el, UNUSED int sockfd, UNUSED int fl t->fd = -1; } +/** Destroy thread data for the submodule. + * + */ +static int mod_thread_detach(module_thread_inst_ctx_t const *mctx) +{ + rlm_icmp_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_icmp_thread_t); + + if (t->fd < 0) return 0; + + (void) fr_event_fd_delete(mctx->el, t->fd, FR_EVENT_FILTER_IO); + close(t->fd); + t->fd = -1; + + return 0; +} + /** Instantiate thread data for the submodule. * */ @@ -491,17 +507,28 @@ static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx) return 0; } +static int mod_instantiate(module_inst_ctx_t const *mctx) +{ + rlm_icmp_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_icmp_t); + + FR_TIME_DELTA_BOUND_CHECK("timeout", inst->timeout, >=, fr_time_delta_from_msec(100)); /* 1/10s minimum timeout */ + FR_TIME_DELTA_BOUND_CHECK("timeout", inst->timeout, <=, fr_time_delta_from_sec(10)); + + return 0; +} + static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_icmp_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_icmp_t); xlat_t *xlat; - xlat = xlat_func_register_module(inst, mctx, NULL, xlat_icmp, FR_TYPE_BOOL); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, NULL, xlat_icmp, FR_TYPE_BOOL); xlat_func_args_set(xlat, xlat_icmp_args); - FR_TIME_DELTA_BOUND_CHECK("timeout", inst->timeout, >=, fr_time_delta_from_msec(100)); /* 1/10s minimum timeout */ - FR_TIME_DELTA_BOUND_CHECK("timeout", inst->timeout, <=, fr_time_delta_from_sec(10)); + return 0; +} +static int mod_load(void) +{ #ifdef __linux__ # ifndef HAVE_CAPABILITY_H if ((geteuid() != 0)) PWARN("Server not built with cap interface, opening raw sockets will likely fail"); @@ -520,22 +547,6 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) } -/** Destroy thread data for the submodule. - * - */ -static int mod_thread_detach(module_thread_inst_ctx_t const *mctx) -{ - rlm_icmp_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_icmp_thread_t); - - if (t->fd < 0) return 0; - - (void) fr_event_fd_delete(mctx->el, t->fd, FR_EVENT_FILTER_IO); - close(t->fd); - t->fd = -1; - - return 0; -} - /* * The module name should be the only globally exported symbol. * That is, everything else should be 'static'. @@ -552,7 +563,9 @@ module_rlm_t rlm_icmp = { .name = "icmp", .inst_size = sizeof(rlm_icmp_t), .config = module_config, + .onload = mod_load, .bootstrap = mod_bootstrap, + .instantiate = mod_instantiate, .thread_inst_size = sizeof(rlm_icmp_thread_t), .thread_inst_type = "rlm_icmp_thread_t", .thread_instantiate = mod_thread_instantiate, diff --git a/src/modules/rlm_idn/rlm_idn.c b/src/modules/rlm_idn/rlm_idn.c index 99f89ef2bd..2250f7bd4d 100644 --- a/src/modules/rlm_idn/rlm_idn.c +++ b/src/modules/rlm_idn/rlm_idn.c @@ -150,10 +150,9 @@ static xlat_action_t xlat_idna(TALLOC_CTX *ctx, fr_dcursor_t *out, static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_idn_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_idn_t); xlat_t *xlat; - xlat = xlat_func_register_module(inst, mctx, NULL, xlat_idna, FR_TYPE_STRING); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, NULL, xlat_idna, FR_TYPE_STRING); xlat_func_mono_set(xlat, xlat_idna_arg); xlat_func_flags_set(xlat, XLAT_FUNC_FLAG_PURE); diff --git a/src/modules/rlm_json/rlm_json.c b/src/modules/rlm_json/rlm_json.c index ae57a8b4d4..b39464505b 100644 --- a/src/modules/rlm_json/rlm_json.c +++ b/src/modules/rlm_json/rlm_json.c @@ -39,8 +39,6 @@ RCSID("$Id$") #include #include -#include - #ifndef HAVE_JSON # error "rlm_json should not be built unless json-c is available" #endif @@ -327,7 +325,7 @@ static xlat_action_t json_encode_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, * - 0 on success. * - -1 on failure. */ -static int mod_map_proc_instantiate(CONF_SECTION *cs, UNUSED void *mod_inst, void *proc_inst, +static int mod_map_proc_instantiate(CONF_SECTION *cs, UNUSED void const *mod_inst, void *proc_inst, tmpl_t const *src, map_list_t const *maps) { rlm_json_jpath_cache_t *cache_inst = proc_inst; @@ -453,7 +451,7 @@ static int _json_map_proc_get_value(TALLOC_CTX *ctx, fr_pair_list_t *out, reques * @param maps Head of the map list. * @return UNLANG_ACTION_CALCULATE_RESULT */ -static unlang_action_t mod_map_proc(rlm_rcode_t *p_result, UNUSED void *mod_inst, void *proc_inst, request_t *request, +static unlang_action_t mod_map_proc(rlm_rcode_t *p_result, UNUSED void const *mod_inst, void *proc_inst, request_t *request, fr_value_box_list_t *json, map_list_t const *maps) { rlm_rcode_t rcode = RLM_MODULE_UPDATED; @@ -553,16 +551,12 @@ finish: RETURN_MODULE_RCODE(rcode); } -static int mod_bootstrap(module_inst_ctx_t const *mctx) +static int mod_instantiate(module_inst_ctx_t const *mctx) { - rlm_json_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_json_t); + rlm_json_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_json_t); CONF_SECTION *conf = mctx->mi->conf; - xlat_t *xlat; fr_json_format_t *format = inst->format; - xlat = xlat_func_register_module(inst, mctx, "encode", json_encode_xlat, FR_TYPE_STRING); - xlat_func_mono_set(xlat, json_encode_xlat_arg); - /* * Check the output format type and warn on unused * format options @@ -574,7 +568,18 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) } fr_json_format_verify(format, true); - if (map_proc_register(inst, "json", mod_map_proc, + return 0; +} + +static int mod_bootstrap(module_inst_ctx_t const *mctx) +{ + rlm_json_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_json_t); + xlat_t *xlat; + + xlat = xlat_func_register_module(mctx->mi->boot, mctx, "encode", json_encode_xlat, FR_TYPE_STRING); + xlat_func_mono_set(xlat, json_encode_xlat_arg); + + if (map_proc_register(mctx->mi->boot, inst, "json", mod_map_proc, mod_map_proc_instantiate, sizeof(rlm_json_jpath_cache_t), 0) < 0) return -1; return 0; } @@ -620,6 +625,7 @@ module_rlm_t rlm_json = { .unload = mod_unload, .config = module_config, .inst_size = sizeof(rlm_json_t), - .bootstrap = mod_bootstrap + .bootstrap = mod_bootstrap, + .instantiate = mod_instantiate } }; diff --git a/src/modules/rlm_ldap/rlm_ldap.c b/src/modules/rlm_ldap/rlm_ldap.c index ee47a92f80..616062d440 100644 --- a/src/modules/rlm_ldap/rlm_ldap.c +++ b/src/modules/rlm_ldap/rlm_ldap.c @@ -49,6 +49,11 @@ USES_APPLE_DEPRECATED_API #include #include "rlm_ldap.h" +typedef struct { + fr_dict_attr_t const *group_da; + fr_dict_attr_t const *cache_da; +} rlm_ldap_boot_t; + typedef struct { fr_value_box_t password; tmpl_t const *password_tmpl; @@ -1139,7 +1144,7 @@ static xlat_action_t ldap_profile_xlat(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor /* * Verify the result of the map. */ -static int ldap_map_verify(CONF_SECTION *cs, UNUSED void *mod_inst, UNUSED void *proc_inst, +static int ldap_map_verify(CONF_SECTION *cs, UNUSED void const *mod_inst, UNUSED void *proc_inst, tmpl_t const *src, UNUSED map_list_t const *maps) { if (!src) { @@ -1277,10 +1282,10 @@ static int map_ctx_free(ldap_map_ctx_t *map_ctx) * @param[in] maps Head of the map list. * @return UNLANG_ACTION_CALCULATE_RESULT */ -static unlang_action_t mod_map_proc(rlm_rcode_t *p_result, void *mod_inst, UNUSED void *proc_inst, request_t *request, +static unlang_action_t mod_map_proc(rlm_rcode_t *p_result, void const *mod_inst, UNUSED void *proc_inst, request_t *request, fr_value_box_list_t *url, map_list_t const *maps) { - rlm_ldap_t *inst = talloc_get_type_abort(mod_inst, rlm_ldap_t); + rlm_ldap_t const *inst = talloc_get_type_abort_const(mod_inst, rlm_ldap_t); fr_ldap_thread_t *thread = talloc_get_type_abort(module_rlm_thread_by_data(inst)->data, fr_ldap_thread_t); LDAPURLDesc *ldap_url; @@ -2227,157 +2232,6 @@ static int parse_sub_section(module_inst_ctx_t const *mctx, return 0; } -/** Initialise thread specific data structure - * - */ -static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx) -{ - rlm_ldap_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_ldap_t); - fr_ldap_thread_t *t = talloc_get_type_abort(mctx->thread, fr_ldap_thread_t); - fr_ldap_thread_trunk_t *ttrunk; - - /* - * Initialise tree for connection trunks used by this thread - */ - MEM(t->trunks = fr_rb_inline_talloc_alloc(t, fr_ldap_thread_trunk_t, node, fr_ldap_trunk_cmp, NULL)); - - t->config = &inst->handle_config; - t->trunk_conf = &inst->trunk_conf; - t->bind_trunk_conf = &inst->bind_trunk_conf; - t->el = mctx->el; - - /* - * Launch trunk for module default connection - */ - ttrunk = fr_thread_ldap_trunk_get(t, inst->handle_config.server, inst->handle_config.admin_identity, - inst->handle_config.admin_password, NULL, &inst->handle_config); - if (!ttrunk) { - ERROR("Unable to launch LDAP trunk"); - return -1; - } - - /* - * Set up a per-thread LDAP trunk to use for bind auths - */ - t->bind_trunk = fr_thread_ldap_bind_trunk_get(t); - - MEM(t->binds = fr_rb_inline_talloc_alloc(t, fr_ldap_bind_auth_ctx_t, node, fr_ldap_bind_auth_cmp, NULL)); - - return 0; -} - -/** Clean up thread specific data structure - * - */ -static int mod_thread_detach(module_thread_inst_ctx_t const *mctx) -{ - fr_ldap_thread_t *t = talloc_get_type_abort(mctx->thread, fr_ldap_thread_t); - void **trunks_to_free; - int i; - - if (fr_rb_flatten_inorder(NULL, &trunks_to_free, t->trunks) < 0) return -1; - - for (i = talloc_array_length(trunks_to_free) - 1; i >= 0; i--) talloc_free(trunks_to_free[i]); - talloc_free(trunks_to_free); - talloc_free(t->trunks); - - return 0; -} - -/** Bootstrap the module - * - * Define attributes. - * - * @param[in] mctx configuration data. - * @return - * - 0 on success. - * - < 0 on failure. - */ -static int mod_bootstrap(module_inst_ctx_t const *mctx) -{ - rlm_ldap_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_ldap_t); - CONF_SECTION *conf = mctx->mi->conf; - char buffer[256]; - char const *group_attribute; - xlat_t *xlat; - - inst->handle_config.name = talloc_typed_asprintf(inst, "rlm_ldap (%s)", mctx->mi->name); - - if (inst->group.attribute) { - group_attribute = inst->group.attribute; - } else if (cf_section_name2(conf)) { - snprintf(buffer, sizeof(buffer), "%s-LDAP-Group", mctx->mi->name); - group_attribute = buffer; - } else { - group_attribute = "LDAP-Group"; - } - - inst->group.da = fr_dict_attr_by_name(NULL, fr_dict_root(dict_freeradius), group_attribute); - - /* - * If the group attribute was not in the dictionary, create it - */ - if (!inst->group.da) { - fr_dict_attr_flags_t flags; - - memset(&flags, 0, sizeof(flags)); - if (fr_dict_attr_add(fr_dict_unconst(dict_freeradius), fr_dict_root(dict_freeradius), - group_attribute, -1, FR_TYPE_STRING, &flags) < 0) { - PERROR("Error creating group attribute"); - return -1; - - } - inst->group.da = fr_dict_attr_by_name(NULL, fr_dict_root(dict_freeradius), group_attribute); - } - - /* - * Setup the cache attribute - */ - if (inst->group.cache_attribute) { - fr_dict_attr_flags_t flags; - - memset(&flags, 0, sizeof(flags)); - if (fr_dict_attr_add(fr_dict_unconst(dict_freeradius), fr_dict_root(dict_freeradius), - inst->group.cache_attribute, -1, FR_TYPE_STRING, &flags) < 0) { - PERROR("Error creating cache attribute"); - return -1; - - } - inst->group.cache_da = fr_dict_attr_by_name(NULL, fr_dict_root(dict_freeradius), inst->group.cache_attribute); - } else { - inst->group.cache_da = inst->group.da; /* Default to the group_da */ - } - - /* - * Trunks used for bind auth can only have one request in flight per connection. - */ - inst->bind_trunk_conf.target_req_per_conn = 1; - inst->bind_trunk_conf.max_req_per_conn = 1; - - /* - * Set sizes for trunk request pool. - */ - inst->bind_trunk_conf.req_pool_headers = 2; - inst->bind_trunk_conf.req_pool_size = sizeof(fr_ldap_bind_auth_ctx_t) + sizeof(fr_ldap_sasl_ctx_t); - - xlat = xlat_func_register_module(NULL, mctx, NULL, ldap_xlat, FR_TYPE_STRING); - xlat_func_mono_set(xlat, ldap_xlat_arg); - - if (unlikely(!(xlat = xlat_func_register_module(NULL, mctx, "memberof", ldap_memberof_xlat, - FR_TYPE_BOOL)))) return -1; - xlat_func_args_set(xlat, ldap_memberof_xlat_arg); - xlat_func_call_env_set(xlat, &xlat_memberof_method_env); - - if (unlikely(!(xlat = xlat_func_register_module(NULL, mctx, "profile", ldap_profile_xlat, - FR_TYPE_BOOL)))) return -1; - xlat_func_args_set(xlat, ldap_xlat_arg); - xlat_func_call_env_set(xlat, &xlat_profile_method_env); - - map_proc_register(inst, mctx->mi->name, mod_map_proc, ldap_map_verify, 0, LDAP_URI_SAFE_FOR); - - return 0; -} - static int ldap_update_section_parse(TALLOC_CTX *ctx, call_env_parsed_head_t *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, UNUSED char const *section_name1, UNUSED char const *section_name2, UNUSED void const *data, call_env_parser_t const *rule) @@ -2471,6 +2325,63 @@ static int ldap_group_filter_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t cons return 0; } +/** Clean up thread specific data structure + * + */ +static int mod_thread_detach(module_thread_inst_ctx_t const *mctx) +{ + fr_ldap_thread_t *t = talloc_get_type_abort(mctx->thread, fr_ldap_thread_t); + void **trunks_to_free; + int i; + + if (fr_rb_flatten_inorder(NULL, &trunks_to_free, t->trunks) < 0) return -1; + + for (i = talloc_array_length(trunks_to_free) - 1; i >= 0; i--) talloc_free(trunks_to_free[i]); + talloc_free(trunks_to_free); + talloc_free(t->trunks); + + return 0; +} + +/** Initialise thread specific data structure + * + */ +static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx) +{ + rlm_ldap_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_ldap_t); + fr_ldap_thread_t *t = talloc_get_type_abort(mctx->thread, fr_ldap_thread_t); + fr_ldap_thread_trunk_t *ttrunk; + + /* + * Initialise tree for connection trunks used by this thread + */ + MEM(t->trunks = fr_rb_inline_talloc_alloc(t, fr_ldap_thread_trunk_t, node, fr_ldap_trunk_cmp, NULL)); + + t->config = &inst->handle_config; + t->trunk_conf = &inst->trunk_conf; + t->bind_trunk_conf = &inst->bind_trunk_conf; + t->el = mctx->el; + + /* + * Launch trunk for module default connection + */ + ttrunk = fr_thread_ldap_trunk_get(t, inst->handle_config.server, inst->handle_config.admin_identity, + inst->handle_config.admin_password, NULL, &inst->handle_config); + if (!ttrunk) { + ERROR("Unable to launch LDAP trunk"); + return -1; + } + + /* + * Set up a per-thread LDAP trunk to use for bind auths + */ + t->bind_trunk = fr_thread_ldap_bind_trunk_get(t); + + MEM(t->binds = fr_rb_inline_talloc_alloc(t, fr_ldap_bind_auth_ctx_t, node, fr_ldap_bind_auth_cmp, NULL)); + + return 0; +} + /** Instantiate the module * * Creates a new instance of the module reading parameters from a configuration section. @@ -2482,11 +2393,29 @@ static int ldap_group_filter_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t cons */ static int mod_instantiate(module_inst_ctx_t const *mctx) { - size_t i; + size_t i; - CONF_SECTION *options; - rlm_ldap_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_ldap_t); - CONF_SECTION *conf = mctx->mi->conf; + CONF_SECTION *options; + rlm_ldap_boot_t const *boot = talloc_get_type_abort(mctx->mi->data, rlm_ldap_boot_t); + rlm_ldap_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_ldap_t); + CONF_SECTION *conf = mctx->mi->conf; + + inst->group.da = boot->group_da; + inst->group.cache_da = boot->cache_da; + + inst->handle_config.name = talloc_typed_asprintf(inst, "rlm_ldap (%s)", mctx->mi->name); + + /* + * Trunks used for bind auth can only have one request in flight per connection. + */ + inst->bind_trunk_conf.target_req_per_conn = 1; + inst->bind_trunk_conf.max_req_per_conn = 1; + + /* + * Set sizes for trunk request pool. + */ + inst->bind_trunk_conf.req_pool_headers = 2; + inst->bind_trunk_conf.req_pool_size = sizeof(fr_ldap_bind_auth_ctx_t) + sizeof(fr_ldap_sasl_ctx_t); options = cf_section_find(conf, "options", NULL); if (!options || !cf_pair_find(options, "chase_referrals")) { @@ -2673,6 +2602,87 @@ error: return -1; } +/** Bootstrap the module + * + * Define attributes. + * + * @param[in] mctx configuration data. + * @return + * - 0 on success. + * - < 0 on failure. + */ +static int mod_bootstrap(module_inst_ctx_t const *mctx) +{ + rlm_ldap_boot_t *boot = talloc_get_type_abort(mctx->mi->boot, rlm_ldap_boot_t); + rlm_ldap_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_ldap_t); + CONF_SECTION *conf = mctx->mi->conf; + char buffer[256]; + char const *group_attribute; + xlat_t *xlat; + + if (inst->group.attribute) { + group_attribute = inst->group.attribute; + } else if (cf_section_name2(conf)) { + snprintf(buffer, sizeof(buffer), "%s-LDAP-Group", mctx->mi->name); + group_attribute = buffer; + } else { + group_attribute = "LDAP-Group"; + } + + boot->group_da = fr_dict_attr_by_name(NULL, fr_dict_root(dict_freeradius), group_attribute); + + /* + * If the group attribute was not in the dictionary, create it + */ + if (!boot->group_da) { + fr_dict_attr_flags_t flags; + + memset(&flags, 0, sizeof(flags)); + if (fr_dict_attr_add(fr_dict_unconst(dict_freeradius), fr_dict_root(dict_freeradius), + group_attribute, -1, FR_TYPE_STRING, &flags) < 0) { + PERROR("Error creating group attribute"); + return -1; + + } + boot->group_da = fr_dict_attr_by_name(NULL, fr_dict_root(dict_freeradius), group_attribute); + } + + /* + * Setup the cache attribute + */ + if (inst->group.cache_attribute) { + fr_dict_attr_flags_t flags; + + memset(&flags, 0, sizeof(flags)); + if (fr_dict_attr_add(fr_dict_unconst(dict_freeradius), fr_dict_root(dict_freeradius), + inst->group.cache_attribute, -1, FR_TYPE_STRING, &flags) < 0) { + PERROR("Error creating cache attribute"); + return -1; + + } + boot->cache_da = fr_dict_attr_by_name(NULL, fr_dict_root(dict_freeradius), inst->group.cache_attribute); + } else { + boot->cache_da = boot->group_da; /* Default to the group_da */ + } + + xlat = xlat_func_register_module(mctx->mi->boot, mctx, NULL, ldap_xlat, FR_TYPE_STRING); + xlat_func_mono_set(xlat, ldap_xlat_arg); + + if (unlikely(!(xlat = xlat_func_register_module(mctx->mi->boot, mctx, "memberof", ldap_memberof_xlat, + FR_TYPE_BOOL)))) return -1; + xlat_func_args_set(xlat, ldap_memberof_xlat_arg); + xlat_func_call_env_set(xlat, &xlat_memberof_method_env); + + if (unlikely(!(xlat = xlat_func_register_module(mctx->mi->boot, mctx, "profile", ldap_profile_xlat, + FR_TYPE_BOOL)))) return -1; + xlat_func_args_set(xlat, ldap_xlat_arg); + xlat_func_call_env_set(xlat, &xlat_profile_method_env); + + map_proc_register(mctx->mi->boot, inst, mctx->mi->name, mod_map_proc, ldap_map_verify, 0, LDAP_URI_SAFE_FOR); + + return 0; +} + static int mod_load(void) { xlat_t *xlat; @@ -2708,6 +2718,8 @@ module_rlm_t rlm_ldap = { .magic = MODULE_MAGIC_INIT, .name = "ldap", .flags = 0, + .boot_size = sizeof(rlm_ldap_boot_t), + .boot_type = "rlm_ldap_boot_t", .inst_size = sizeof(rlm_ldap_t), .config = module_config, .onload = mod_load, diff --git a/src/modules/rlm_linelog/rlm_linelog.c b/src/modules/rlm_linelog/rlm_linelog.c index 760b065b33..dd7b179f75 100644 --- a/src/modules/rlm_linelog/rlm_linelog.c +++ b/src/modules/rlm_linelog/rlm_linelog.c @@ -1033,15 +1033,14 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_linelog_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_linelog_t); - xlat_t *xlat; + xlat_t *xlat; static xlat_arg_parser_t const linelog_xlat_args[] = { { .required = true, .concat = true, .type = FR_TYPE_STRING }, XLAT_ARG_PARSER_TERMINATOR }; - xlat = xlat_func_register_module(inst, mctx, NULL, linelog_xlat, FR_TYPE_SIZE); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, NULL, linelog_xlat, FR_TYPE_SIZE); xlat_func_mono_set(xlat, linelog_xlat_args); xlat_func_call_env_set(xlat, &linelog_xlat_method_env ); diff --git a/src/modules/rlm_mschap/rlm_mschap.c b/src/modules/rlm_mschap/rlm_mschap.c index 7aca6ea770..395224e61f 100644 --- a/src/modules/rlm_mschap/rlm_mschap.c +++ b/src/modules/rlm_mschap/rlm_mschap.c @@ -46,7 +46,6 @@ RCSID("$Id$") #include #include -#include #include "rlm_mschap.h" #include "mschap.h" @@ -2488,10 +2487,9 @@ done_mppe_check: static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_mschap_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_mschap_t); - xlat_t *xlat; + xlat_t *xlat; - xlat = xlat_func_register_module(inst, mctx, NULL, mschap_xlat, FR_TYPE_VOID); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, NULL, mschap_xlat, FR_TYPE_VOID); xlat_func_args_set(xlat, mschap_xlat_args); xlat_func_call_env_set(xlat, &mschap_xlat_method_env); diff --git a/src/modules/rlm_perl/rlm_perl.c b/src/modules/rlm_perl/rlm_perl.c index 627482ed74..c48cfc8f53 100644 --- a/src/modules/rlm_perl/rlm_perl.c +++ b/src/modules/rlm_perl/rlm_perl.c @@ -581,16 +581,6 @@ static void perl_parse_config(CONF_SECTION *cs, int lvl, HV *rad_hv) DEBUG("%*s}", indent_section, " "); } -static int mod_bootstrap(module_inst_ctx_t const *mctx) -{ - xlat_t *xlat; - - xlat = xlat_func_register_module(NULL, mctx, NULL, perl_xlat, FR_TYPE_VOID); - xlat_func_args_set(xlat, perl_xlat_args); - - return 0; -} - static void perl_vp_to_svpvn_element(request_t *request, AV *av, fr_pair_t const *vp, int *i, const char *hash_name, const char *list_name) { @@ -1108,6 +1098,16 @@ static int mod_detach(module_detach_ctx_t const *mctx) } DIAG_ON(nested-externs) +static int mod_bootstrap(module_inst_ctx_t const *mctx) +{ + xlat_t *xlat; + + xlat = xlat_func_register_module(mctx->mi->boot, mctx, NULL, perl_xlat, FR_TYPE_VOID); + xlat_func_args_set(xlat, perl_xlat_args); + + return 0; +} + static int mod_load(void) { char const **embed_c; /* Stupid Perl and lack of const consistency */ @@ -1155,7 +1155,6 @@ static void mod_unload(void) PERL_SYS_TERM(); } - /* * The module name should be the only globally exported symbol. * That is, everything else should be 'static'. diff --git a/src/modules/rlm_radius/rlm_radius.c b/src/modules/rlm_radius/rlm_radius.c index 679b155dd6..86f4a78e3f 100644 --- a/src/modules/rlm_radius/rlm_radius.c +++ b/src/modules/rlm_radius/rlm_radius.c @@ -452,7 +452,7 @@ static unlang_action_t CC_HINT(nonnull) mod_process(rlm_rcode_t *p_result, modul return unlang_module_yield(request, inst->io->resume, mod_radius_signal, 0, rctx); } -static int mod_bootstrap(module_inst_ctx_t const *mctx) +static int mod_instantiate(module_inst_ctx_t const *mctx) { size_t i, num_types; rlm_radius_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_radius_t); @@ -661,7 +661,7 @@ module_rlm_t rlm_radius = { .onload = mod_load, .unload = mod_unload, - .bootstrap = mod_bootstrap, + .instantiate = mod_instantiate, }, .method_names = (module_method_name_t[]){ { .name1 = CF_IDENT_ANY, .name2 = CF_IDENT_ANY, .method = mod_process }, diff --git a/src/modules/rlm_radius/rlm_radius_udp.c b/src/modules/rlm_radius/rlm_radius_udp.c index ae0c8634c9..da4fbb46c2 100644 --- a/src/modules/rlm_radius/rlm_radius_udp.c +++ b/src/modules/rlm_radius/rlm_radius_udp.c @@ -69,7 +69,7 @@ typedef struct { bool send_buff_is_set; //!< Whether we were provided with a send_buf bool replicate; //!< Copied from parent->replicate - fr_trunk_conf_t *trunk_conf; //!< trunk configuration + fr_trunk_conf_t trunk_conf; //!< trunk configuration } rlm_radius_udp_t; typedef struct { @@ -2780,15 +2780,10 @@ static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx) .request_free = request_free }; - inst->trunk_conf = &inst->parent->trunk_conf; - - inst->trunk_conf->req_pool_headers = 4; /* One for the request, one for the buffer, one for the tracking binding, one for Proxy-State VP */ - inst->trunk_conf->req_pool_size = sizeof(udp_request_t) + inst->max_packet_size + sizeof(radius_track_entry_t ***) + sizeof(fr_pair_t) + 20; - thread->el = mctx->el; thread->inst = inst; thread->trunk = fr_trunk_alloc(thread, mctx->el, inst->replicate ? &io_funcs_replicate : &io_funcs, - inst->trunk_conf, inst->parent->name, thread, false); + &inst->trunk_conf, inst->parent->name, thread, false); if (!thread->trunk) return -1; return 0; @@ -2884,6 +2879,9 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) FR_INTEGER_BOUND_CHECK("send_buff", inst->send_buff, <=, (1 << 30)); } + memcpy(&inst->trunk_conf, &inst->parent->trunk_conf, sizeof(inst->trunk_conf)); + inst->trunk_conf.req_pool_headers = 4; /* One for the request, one for the buffer, one for the tracking binding, one for Proxy-State VP */ + inst->trunk_conf.req_pool_size = sizeof(udp_request_t) + inst->max_packet_size + sizeof(radius_track_entry_t ***) + sizeof(fr_pair_t) + 20; return 0; } diff --git a/src/modules/rlm_radutmp/rlm_radutmp.c b/src/modules/rlm_radutmp/rlm_radutmp.c index c23e00171c..b0174cdb0a 100644 --- a/src/modules/rlm_radutmp/rlm_radutmp.c +++ b/src/modules/rlm_radutmp/rlm_radutmp.c @@ -49,10 +49,14 @@ struct nas_port_s { }; typedef struct { - NAS_PORT *nas_port_list; - bool check_nas; - uint32_t permission; - bool caller_id_ok; + NAS_PORT *nas_port_list; +} rlm_radutmp_mutable_t; + +typedef struct { + rlm_radutmp_mutable_t *mutable; + bool check_nas; + uint32_t permission; + bool caller_id_ok; } rlm_radutmp_t; typedef struct { @@ -67,6 +71,16 @@ static const conf_parser_t module_config[] = { CONF_PARSER_TERMINATOR }; +static const call_env_method_t method_env = { + FR_CALL_ENV_METHOD_OUT(rlm_radutmp_env_t), + .env = (call_env_parser_t[]) { + { FR_CALL_ENV_OFFSET("filename", FR_TYPE_STRING, CALL_ENV_FLAG_REQUIRED, rlm_radutmp_env_t, filename) }, + { FR_CALL_ENV_OFFSET("username", FR_TYPE_STRING, CALL_ENV_FLAG_REQUIRED, rlm_radutmp_env_t, username), + .pair.dflt = "%{User-Name}", .pair.dflt_quote = T_DOUBLE_QUOTED_STRING }, + CALL_ENV_TERMINATOR + } +}; + static fr_dict_t const *dict_radius; extern fr_dict_autoload_t rlm_radutmp_dict[]; @@ -407,7 +421,7 @@ static unlang_action_t CC_HINT(nonnull) mod_accounting(rlm_rcode_t *p_result, mo /* * Find the entry for this NAS / portno combination. */ - if ((cache = nas_port_find(inst->nas_port_list, ut.nas_address, ut.nas_port)) != NULL) { + if ((cache = nas_port_find(inst->mutable->nas_port_list, ut.nas_address, ut.nas_port)) != NULL) { if (lseek(fd, (off_t)cache->offset, SEEK_SET) < 0) { rcode = RLM_MODULE_FAIL; goto finish; @@ -490,13 +504,13 @@ static unlang_action_t CC_HINT(nonnull) mod_accounting(rlm_rcode_t *p_result, mo * easier than searching through the entire file. */ if (!cache) { - cache = talloc_zero(inst, NAS_PORT); + cache = talloc_zero(inst->mutable, NAS_PORT); if (cache) { cache->nasaddr = ut.nas_address; cache->port = ut.nas_port; cache->offset = off; - cache->next = inst->nas_port_list; - inst->nas_port_list = cache; + cache->next = inst->mutable->nas_port_list; + inst->mutable->nas_port_list = cache; } } @@ -538,15 +552,27 @@ static unlang_action_t CC_HINT(nonnull) mod_accounting(rlm_rcode_t *p_result, mo RETURN_MODULE_RCODE(rcode); } -static const call_env_method_t method_env = { - FR_CALL_ENV_METHOD_OUT(rlm_radutmp_env_t), - .env = (call_env_parser_t[]) { - { FR_CALL_ENV_OFFSET("filename", FR_TYPE_STRING, CALL_ENV_FLAG_REQUIRED, rlm_radutmp_env_t, filename) }, - { FR_CALL_ENV_OFFSET("username", FR_TYPE_STRING, CALL_ENV_FLAG_REQUIRED, rlm_radutmp_env_t, username), - .pair.dflt = "%{User-Name}", .pair.dflt_quote = T_DOUBLE_QUOTED_STRING }, - CALL_ENV_TERMINATOR - } -}; +static int mod_instantiate(module_inst_ctx_t const *mctx) +{ + rlm_radutmp_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_radutmp_t); + + /* + * Must be in the NULL ctx so it doesn't + * end up in a protected page. + */ + inst->mutable = talloc_zero(NULL, rlm_radutmp_mutable_t); + + return 0; +} + +static int mod_detach(module_detach_ctx_t const *mctx) +{ + rlm_radutmp_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_radutmp_t); + + talloc_free(inst->mutable); + + return 0; +} /* globally exported name */ extern module_rlm_t rlm_radutmp; @@ -556,7 +582,9 @@ module_rlm_t rlm_radutmp = { .name = "radutmp", .flags = MODULE_TYPE_THREAD_UNSAFE, .inst_size = sizeof(rlm_radutmp_t), - .config = module_config + .config = module_config, + .instantiate = mod_instantiate, + .detach = mod_detach }, .method_names = (module_method_name_t[]){ { .name1 = "accounting", .name2 = CF_IDENT_ANY, .method = mod_accounting, diff --git a/src/modules/rlm_redis/rlm_redis.c b/src/modules/rlm_redis/rlm_redis.c index ce4bcd6ec9..8738b91bc7 100644 --- a/src/modules/rlm_redis/rlm_redis.c +++ b/src/modules/rlm_redis/rlm_redis.c @@ -860,19 +860,19 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_redis_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_redis_t); - xlat_t *xlat; + rlm_redis_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_redis_t); + xlat_t *xlat; - xlat = xlat_func_register_module(inst, mctx, NULL, redis_xlat, FR_TYPE_VOID); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, NULL, redis_xlat, FR_TYPE_VOID); xlat_func_args_set(xlat, redis_args); /* * %redis.node([, idx]) */ - if (unlikely((xlat = xlat_func_register_module(inst, mctx, "node", redis_node_xlat, FR_TYPE_STRING)) == NULL)) return -1; + if (unlikely((xlat = xlat_func_register_module(mctx->mi->boot, mctx, "node", redis_node_xlat, FR_TYPE_STRING)) == NULL)) return -1; xlat_func_args_set(xlat, redis_node_xlat_args); - if (unlikely((xlat = xlat_func_register_module(inst, mctx, "remap", redis_remap_xlat, FR_TYPE_STRING)) == NULL)) return -1; + if (unlikely((xlat = xlat_func_register_module(mctx->mi->boot, mctx, "remap", redis_remap_xlat, FR_TYPE_STRING)) == NULL)) return -1; xlat_func_args_set(xlat, redis_remap_xlat_args); /* @@ -880,7 +880,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) * that'll call that function specifically. */ talloc_foreach(inst->lua.funcs, func) { - if (unlikely((xlat = xlat_func_register_module(inst, mctx, func->name, redis_lua_func_xlat, FR_TYPE_VOID)) == NULL)) return -1; + if (unlikely((xlat = xlat_func_register_module(mctx->mi->boot, mctx, func->name, redis_lua_func_xlat, FR_TYPE_VOID)) == NULL)) return -1; xlat_func_args_set(xlat, redis_lua_func_args); xlat_func_instantiate_set(xlat, redis_lua_func_instantiate, redis_lua_func_inst_t, NULL, func); } diff --git a/src/modules/rlm_rest/rlm_rest.c b/src/modules/rlm_rest/rlm_rest.c index d37a6f4175..afe3a55443 100644 --- a/src/modules/rlm_rest/rlm_rest.c +++ b/src/modules/rlm_rest/rlm_rest.c @@ -1344,10 +1344,9 @@ static int instantiate(module_inst_ctx_t const *mctx) static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_rest_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_rest_t); - xlat_t *xlat; + xlat_t *xlat; - xlat = xlat_func_register_module(inst, mctx, NULL, rest_xlat, FR_TYPE_STRING); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, NULL, rest_xlat, FR_TYPE_STRING); xlat_func_args_set(xlat, rest_xlat_args); xlat_func_call_env_set(xlat, &rest_call_env_xlat); diff --git a/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c b/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c index 849711c355..ba2b629bf7 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c @@ -141,7 +141,7 @@ static int _sql_socket_destructor(rlm_sql_mysql_conn_t *conn) return 0; } -static int mod_bootstrap(module_inst_ctx_t const *mctx) +static int mod_instantiate(module_inst_ctx_t const *mctx) { rlm_sql_mysql_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_sql_mysql_t); int warnings; @@ -778,7 +778,7 @@ rlm_sql_driver_t rlm_sql_mysql = { .onload = mod_load, .unload = mod_unload, .config = driver_config, - .bootstrap = mod_bootstrap + .instantiate = mod_instantiate }, .flags = RLM_SQL_RCODE_FLAGS_ALT_QUERY, .sql_socket_init = sql_socket_init, diff --git a/src/modules/rlm_sql/drivers/rlm_sql_oracle/rlm_sql_oracle.c b/src/modules/rlm_sql/drivers/rlm_sql_oracle/rlm_sql_oracle.c index 56fe6a65fa..0f257fb135 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_oracle/rlm_sql_oracle.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_oracle/rlm_sql_oracle.c @@ -166,7 +166,7 @@ static int mod_detach(module_detach_ctx_t const *mctx) return 0; } -static int mod_bootstrap(module_inst_ctx_t const *mctx) +static int mod_instantiate(module_inst_ctx_t const *mctx) { rlm_sql_t const *parent = talloc_get_type_abort(mctx->mi->parent->data, rlm_sql_t); rlm_sql_config_t const *config = &parent->config; @@ -630,7 +630,7 @@ rlm_sql_driver_t rlm_sql_oracle = { .magic = MODULE_MAGIC_INIT, .inst_size = sizeof(rlm_sql_oracle_t), .config = driver_config, - .bootstrap = mod_bootstrap, + .instantiate = mod_instantiate, .detach = mod_detach }, .sql_socket_init = sql_socket_init, diff --git a/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c b/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c index 364de3453a..5734117389 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c @@ -544,7 +544,7 @@ static size_t sql_escape_func(request_t *request, char *out, size_t outlen, char return ret; } -static int mod_bootstrap(module_inst_ctx_t const *mctx) +static int mod_instantiate(module_inst_ctx_t const *mctx) { rlm_sql_t const *parent = talloc_get_type_abort(mctx->mi->parent->data, rlm_sql_t); rlm_sql_config_t const *config = &parent->config; @@ -675,7 +675,7 @@ rlm_sql_driver_t rlm_sql_postgresql = { .inst_size = sizeof(rlm_sql_postgresql_t), .onload = mod_load, .config = driver_config, - .bootstrap = mod_bootstrap + .instantiate = mod_instantiate }, .flags = RLM_SQL_RCODE_FLAGS_ALT_QUERY, .sql_socket_init = sql_socket_init, diff --git a/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c b/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c index 52500df2c0..d1cb7dadc6 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c @@ -668,7 +668,7 @@ static int sql_affected_rows(rlm_sql_handle_t *handle, return -1; } -static int mod_bootstrap(module_inst_ctx_t const *mctx) +static int mod_instantiate(module_inst_ctx_t const *mctx) { rlm_sql_t const *parent = talloc_get_type_abort(mctx->mi->parent->data, rlm_sql_t); rlm_sql_config_t const *config = &parent->config; @@ -684,9 +684,10 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) } /* - * mod_bootstrap() will try to create the database if it doesn't exist, up to and - * including creating the directory it should live in, in which case we get to call - * fr_dirfd() again. Hence failing this first fr_dirfd() just means the database isn't there. + * We will try to create the database if it doesn't exist, up to and + * including creating the directory it should live in, in which case + * we get to call fr_dirfd() again. Hence failing this first fr_dirfd() + * just means the database isn't there. */ if (fr_dirfd(&fd, &r, inst->filename) < 0) { exists = false; @@ -818,7 +819,7 @@ rlm_sql_driver_t rlm_sql_sqlite = { .inst_size = sizeof(rlm_sql_sqlite_t), .config = driver_config, .onload = mod_load, - .bootstrap = mod_bootstrap + .instantiate = mod_instantiate }, .flags = RLM_SQL_RCODE_FLAGS_ALT_QUERY, .sql_socket_init = sql_socket_init, diff --git a/src/modules/rlm_sql/rlm_sql.c b/src/modules/rlm_sql/rlm_sql.c index b75c515256..b3695e55ec 100644 --- a/src/modules/rlm_sql/rlm_sql.c +++ b/src/modules/rlm_sql/rlm_sql.c @@ -45,9 +45,15 @@ RCSID("$Id$") extern module_rlm_t rlm_sql; +static int submodule_parse(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule); + +typedef struct { + fr_dict_attr_t const *group_da; +} rlm_sql_boot_t; + static const conf_parser_t module_config[] = { { FR_CONF_OFFSET_TYPE_FLAGS("driver", FR_TYPE_VOID, 0, rlm_sql_t, driver_submodule), .dflt = "null", - .func = module_rlm_submodule_parse }, + .func = submodule_parse }, { FR_CONF_OFFSET("server", rlm_sql_config_t, sql_server), .dflt = "" }, /* Must be zero length so drivers can determine if it was set */ { FR_CONF_OFFSET("port", rlm_sql_config_t, sql_port), .dflt = "0" }, { FR_CONF_OFFSET("login", rlm_sql_config_t, sql_login), .dflt = "" }, @@ -226,6 +232,20 @@ static const call_env_method_t group_xlat_method_env = { } }; +int submodule_parse(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule) +{ + rlm_sql_t *inst = talloc_get_type_abort(parent, rlm_sql_t); + module_instance_t *mi; + int ret; + + if (unlikely(ret = module_rlm_submodule_parse(ctx, out, parent, ci, rule) < 0)) return ret; + + mi = talloc_get_type_abort(*((void **)out), module_instance_t); + inst->driver = (rlm_sql_driver_t const *)mi->exported; /* Public symbol exported by the submodule */ + + return 0; +} + static int _sql_escape_uxtx_free(void *uctx) { return talloc_free(uctx); @@ -513,7 +533,7 @@ static int _sql_map_proc_get_value(TALLOC_CTX *ctx, fr_pair_list_t *out, /* * Verify the result of the map. */ -static int sql_map_verify(CONF_SECTION *cs, UNUSED void *mod_inst, UNUSED void *proc_inst, +static int sql_map_verify(CONF_SECTION *cs, UNUSED void const *mod_inst, UNUSED void *proc_inst, tmpl_t const *src, UNUSED map_list_t const *maps) { if (!src) { @@ -538,7 +558,7 @@ static int sql_map_verify(CONF_SECTION *cs, UNUSED void *mod_inst, UNUSED void * * @param maps Head of the map list. * @return UNLANG_ACTION_CALCULATE_RESULT */ -static unlang_action_t mod_map_proc(rlm_rcode_t *p_result, void *mod_inst, UNUSED void *proc_inst, request_t *request, +static unlang_action_t mod_map_proc(rlm_rcode_t *p_result, void const *mod_inst, UNUSED void *proc_inst, request_t *request, fr_value_box_list_t *query, map_list_t const *maps) { rlm_sql_t *inst = talloc_get_type_abort(mod_inst, rlm_sql_t); @@ -1763,17 +1783,90 @@ static int mod_detach(module_detach_ctx_t const *mctx) return 0; } -static int mod_bootstrap(module_inst_ctx_t const *mctx) +static int mod_instantiate(module_inst_ctx_t const *mctx) { + rlm_sql_boot_t const *boot = talloc_get_type_abort(mctx->mi->boot, rlm_sql_boot_t); rlm_sql_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_sql_t); CONF_SECTION *conf = mctx->mi->conf; + + /* + * We can't modify the inst field in bootstrap, and there's no + * point in making rlm_sql_boot_t available everywhere. + */ + inst->group_da = boot->group_da; + + inst->name = mctx->mi->name; /* Need this for functions in sql.c */ + + /* + * We need authorize_group_check_query or authorize_group_reply_query + * if group_membership_query is set. + * + * Or we need group_membership_query if authorize_group_check_query or + * authorize_group_reply_query is set. + */ + if (!cf_pair_find(conf, "group_membership_query")) { + if (cf_pair_find(conf, "authorize_group_check_query")) { + WARN("Ignoring authorize_group_check_query as group_membership_query is not configured"); + } + + if (cf_pair_find(conf, "authorize_group_reply_query")) { + WARN("Ignoring authorize_group_reply_query as group_membership_query is not configured"); + } + + if (!inst->config.read_groups) { + WARN("Ignoring read_groups as group_membership_query is not configured"); + inst->config.read_groups = false; + } + } /* allow the group check / reply queries to be NULL */ + + /* + * Cache the SQL-User-Name fr_dict_attr_t, so we can be slightly + * more efficient about creating SQL-User-Name attributes. + */ + inst->sql_user = attr_sql_user_name; + + /* + * Export these methods, too. This avoids RTDL_GLOBAL. + */ + inst->query = rlm_sql_query; + inst->select = rlm_sql_select_query; + inst->fetch_row = rlm_sql_fetch_row; + + /* + * Either use the module specific escape function + * or our default one. + */ + inst->sql_escape_func = inst->driver->sql_escape_func ? + inst->driver->sql_escape_func : + sql_escape_func; + inst->box_escape_func = sql_box_escape; + + inst->ef = module_rlm_exfile_init(inst, conf, 256, fr_time_delta_from_sec(30), true, NULL, NULL); + if (!inst->ef) { + cf_log_err(conf, "Failed creating log file context"); + return -1; + } + + /* + * Initialise the connection pool for this instance + */ + INFO("Attempting to connect to database \"%s\"", inst->config.sql_db); + + inst->pool = module_rlm_connection_pool_init(conf, inst, sql_mod_conn_create, NULL, NULL, NULL, NULL); + if (!inst->pool) return -1; + + return 0; +} + +static int mod_bootstrap(module_inst_ctx_t const *mctx) +{ + rlm_sql_boot_t *boot = talloc_get_type_abort(mctx->mi->boot, rlm_sql_boot_t); + rlm_sql_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_sql_t); + CONF_SECTION *conf = mctx->mi->conf; xlat_t *xlat; xlat_arg_parser_t *sql_xlat_arg; rlm_sql_escape_uctx_t *uctx; - inst->name = mctx->mi->name; /* Need this for functions in sql.c */ - inst->driver = (rlm_sql_driver_t const *)inst->driver_submodule->exported; /* Public symbol exported by the submodule */ - /* * Register the group comparison attribute */ @@ -1797,9 +1890,9 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) return -1; } - inst->group_da = fr_dict_attr_search_by_qualified_oid(NULL, dict_freeradius, group_attribute, - false, false); - if (!inst->group_da) { + boot->group_da = fr_dict_attr_search_by_qualified_oid(NULL, dict_freeradius, group_attribute, + false, false); + if (!boot->group_da) { cf_log_perr(conf, "Failed resolving group attribute"); return -1; } @@ -1809,7 +1902,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) * register function automatically adds the * module instance name as a prefix. */ - xlat = xlat_func_register_module(inst, mctx, "group", sql_group_xlat, FR_TYPE_BOOL); + xlat = xlat_func_register_module(boot, mctx, "group", sql_group_xlat, FR_TYPE_BOOL); if (!xlat) { cf_log_perr(conf, "Failed registering %s expansion", group_attribute); return -1; @@ -1820,12 +1913,12 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) * The xlat escape function needs access to inst - so * argument parser details need to be defined here */ - sql_xlat_arg = talloc_zero_array(inst, xlat_arg_parser_t, 2); - sql_xlat_arg[0].type = FR_TYPE_STRING; - sql_xlat_arg[0].required = true; - sql_xlat_arg[0].concat = true; - sql_xlat_arg[0].func = NULL; /* No real escaping done - we do strcmp() on it */ - sql_xlat_arg[0].uctx = NULL; + sql_xlat_arg = talloc_zero_array(xlat, xlat_arg_parser_t, 2); + sql_xlat_arg[0] = (xlat_arg_parser_t){ + .type = FR_TYPE_STRING, + .required = true, + .concat = true + }; sql_xlat_arg[1] = (xlat_arg_parser_t)XLAT_ARG_PARSER_TERMINATOR; xlat_func_mono_set(xlat, sql_xlat_arg); @@ -1834,7 +1927,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * Register the SQL xlat function */ - xlat = xlat_func_register_module(inst, mctx, NULL, sql_xlat, FR_TYPE_VOID); /* Returns an integer sometimes */ + xlat = xlat_func_register_module(boot, mctx, NULL, sql_xlat, FR_TYPE_VOID); /* Returns an integer sometimes */ if (!xlat) { cf_log_perr(conf, "Failed registering %s expansion", mctx->mi->name); return -1; @@ -1845,15 +1938,17 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) * The xlat escape function needs access to inst - so * argument parser details need to be defined here */ - sql_xlat_arg = talloc_zero_array(inst, xlat_arg_parser_t, 2); + sql_xlat_arg = talloc_zero_array(xlat, xlat_arg_parser_t, 2); uctx = talloc_zero(sql_xlat_arg, rlm_sql_escape_uctx_t); *uctx = (rlm_sql_escape_uctx_t){ .sql = inst, .handle = NULL }; - sql_xlat_arg[0].type = FR_TYPE_STRING; - sql_xlat_arg[0].required = true; - sql_xlat_arg[0].concat = true; - sql_xlat_arg[0].func = sql_xlat_escape; - sql_xlat_arg[0].safe_for = (fr_value_box_safe_for_t)inst->driver; - sql_xlat_arg[0].uctx = uctx; + sql_xlat_arg[0] = (xlat_arg_parser_t){ + .type = FR_TYPE_STRING, + .required = true, + .concat = true, + .func = sql_xlat_escape, + .safe_for = (fr_value_box_safe_for_t)inst->driver, + .uctx = uctx + }; sql_xlat_arg[1] = (xlat_arg_parser_t)XLAT_ARG_PARSER_TERMINATOR; xlat_func_mono_set(xlat, sql_xlat_arg); @@ -1861,73 +1956,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * Register the SQL map processor function */ - if (inst->driver->sql_fields) map_proc_register(inst, mctx->mi->name, mod_map_proc, sql_map_verify, 0, (fr_value_box_safe_for_t)inst->driver); - - return 0; -} - -static int mod_instantiate(module_inst_ctx_t const *mctx) -{ - rlm_sql_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_sql_t); - CONF_SECTION *conf = mctx->mi->conf; - - /* - * We need authorize_group_check_query or authorize_group_reply_query - * if group_membership_query is set. - * - * Or we need group_membership_query if authorize_group_check_query or - * authorize_group_reply_query is set. - */ - if (!cf_pair_find(conf, "group_membership_query")) { - if (cf_pair_find(conf, "authorize_group_check_query")) { - WARN("Ignoring authorize_group_check_query as group_membership_query is not configured"); - } - - if (cf_pair_find(conf, "authorize_group_reply_query")) { - WARN("Ignoring authorize_group_reply_query as group_membership_query is not configured"); - } - - if (!inst->config.read_groups) { - WARN("Ignoring read_groups as group_membership_query is not configured"); - inst->config.read_groups = false; - } - } /* allow the group check / reply queries to be NULL */ - - /* - * Cache the SQL-User-Name fr_dict_attr_t, so we can be slightly - * more efficient about creating SQL-User-Name attributes. - */ - inst->sql_user = attr_sql_user_name; - - /* - * Export these methods, too. This avoids RTDL_GLOBAL. - */ - inst->query = rlm_sql_query; - inst->select = rlm_sql_select_query; - inst->fetch_row = rlm_sql_fetch_row; - - /* - * Either use the module specific escape function - * or our default one. - */ - inst->sql_escape_func = inst->driver->sql_escape_func ? - inst->driver->sql_escape_func : - sql_escape_func; - inst->box_escape_func = sql_box_escape; - - inst->ef = module_rlm_exfile_init(inst, conf, 256, fr_time_delta_from_sec(30), true, NULL, NULL); - if (!inst->ef) { - cf_log_err(conf, "Failed creating log file context"); - return -1; - } - - /* - * Initialise the connection pool for this instance - */ - INFO("Attempting to connect to database \"%s\"", inst->config.sql_db); - - inst->pool = module_rlm_connection_pool_init(conf, inst, sql_mod_conn_create, NULL, NULL, NULL, NULL); - if (!inst->pool) return -1; + if (inst->driver->sql_fields) map_proc_register(mctx->mi->boot, inst, mctx->mi->name, mod_map_proc, sql_map_verify, 0, (fr_value_box_safe_for_t)inst->driver); return 0; } @@ -1937,6 +1966,8 @@ module_rlm_t rlm_sql = { .common = { .magic = MODULE_MAGIC_INIT, .name = "sql", + .boot_size = sizeof(rlm_sql_boot_t), + .boot_type = "rlm_sql_boot_t", .inst_size = sizeof(rlm_sql_t), .config = module_config, .bootstrap = mod_bootstrap, diff --git a/src/modules/rlm_sqlcounter/rlm_sqlcounter.c b/src/modules/rlm_sqlcounter/rlm_sqlcounter.c index d880d7be07..77cc598f9b 100644 --- a/src/modules/rlm_sqlcounter/rlm_sqlcounter.c +++ b/src/modules/rlm_sqlcounter/rlm_sqlcounter.c @@ -440,6 +440,57 @@ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, mod return UNLANG_ACTION_PUSHED_CHILD; } +/** Custom call_env parser to tokenize the SQL query xlat used for counter retrieval + */ +static int call_env_query_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, + UNUSED char const *section_name1, UNUSED char const *section_name2, + void const *data, UNUSED call_env_parser_t const *rule) +{ + rlm_sqlcounter_t const *inst = talloc_get_type_abort_const(data, rlm_sqlcounter_t); + CONF_PAIR const *to_parse = cf_item_to_pair(ci); + char *query; + xlat_exp_head_t *ex; + + query = talloc_asprintf(NULL, "%%%s(\"%s\")", inst->sql_name, cf_pair_value(to_parse)); + + if (xlat_tokenize(ctx, &ex, + &FR_SBUFF_IN(query, talloc_array_length(query)), + &(fr_sbuff_parse_rules_t){ + .escapes = &(fr_sbuff_unescape_rules_t) { + .name = "xlat", + .chr = '\\', + .subs = { + ['%'] = '%', + ['\\'] = '\\', + }, + }}, t_rules, 0) < 0) { + talloc_free(query); + return -1; + } + talloc_free(query); + + if (xlat_needs_resolving(ex) && + (xlat_resolve(ex, &(xlat_res_rules_t){ .allow_unresolved = false }) < 0)) { + talloc_free(ex); + return -1; + } + + *(void**)out = ex; + return 0; +} + +static const call_env_method_t sqlcounter_call_env = { + FR_CALL_ENV_METHOD_OUT(sqlcounter_call_env_t), + .env = (call_env_parser_t[]){ + { FR_CALL_ENV_PARSE_ONLY_OFFSET("query", FR_TYPE_VOID, CALL_ENV_FLAG_REQUIRED | CALL_ENV_FLAG_PARSE_ONLY, sqlcounter_call_env_t, query_xlat), + .pair.func = call_env_query_parse }, + { FR_CALL_ENV_PARSE_ONLY_OFFSET("reply_name", FR_TYPE_VOID, CALL_ENV_FLAG_PARSE_ONLY, sqlcounter_call_env_t, reply_attr) }, + { FR_CALL_ENV_PARSE_ONLY_OFFSET("reply_message_name", FR_TYPE_VOID, CALL_ENV_FLAG_PARSE_ONLY, sqlcounter_call_env_t, reply_msg_attr) }, + CALL_ENV_TERMINATOR + } +}; + + /* * Do any per-module initialization that is separate to each * configured instance of the module. e.g. set up connections @@ -454,9 +505,20 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) { rlm_sqlcounter_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_sqlcounter_t); CONF_SECTION *conf = mctx->mi->conf; - + module_instance_t const *sql_inst; fr_assert(inst->query && *inst->query); + sql_inst = module_rlm_by_name(NULL, inst->sql_name); + if (!sql_inst) { + cf_log_err(conf, "Module \"%s\" not found", inst->sql_name); + return -1; + } + + if (!talloc_get_type(sql_inst->data, rlm_sql_t)) { + cf_log_err(conf, "\"%s\" is not an instance of rlm_sql", inst->sql_name); + return -1; + } + inst->reset_time = fr_time_wrap(0); if (find_next_reset(inst, fr_time()) == -1) { @@ -491,80 +553,18 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_sqlcounter_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_sqlcounter_t); + rlm_sqlcounter_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_sqlcounter_t); CONF_SECTION *conf = mctx->mi->conf; fr_dict_attr_flags_t flags = (fr_dict_attr_flags_t) { .internal = 1, .length = 8 }; - module_instance_t const *sql_inst; ATTR_CHECK(start_attr, "reset_period_start") ATTR_CHECK(end_attr, "reset_period_end") ATTR_CHECK(counter_attr, "counter") ATTR_CHECK(limit_attr, "check") - sql_inst = module_rlm_by_name(NULL, inst->sql_name); - if (!sql_inst) { - cf_log_err(conf, "Module \"%s\" not found", inst->sql_name); - return -1; - } - - if (!talloc_get_type(sql_inst->data, rlm_sql_t)) { - cf_log_err(conf, "\"%s\" is not an instance of rlm_sql", inst->sql_name); - return -1; - } - return 0; } -/** Custom call_env parser to tokenize the SQL query xlat used for counter retrieval - */ -static int call_env_query_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, - UNUSED char const *section_name1, UNUSED char const *section_name2, - void const *data, UNUSED call_env_parser_t const *rule) -{ - rlm_sqlcounter_t const *inst = talloc_get_type_abort_const(data, rlm_sqlcounter_t); - CONF_PAIR const *to_parse = cf_item_to_pair(ci); - char *query; - xlat_exp_head_t *ex; - - query = talloc_asprintf(NULL, "%%%s(\"%s\")", inst->sql_name, cf_pair_value(to_parse)); - - if (xlat_tokenize(ctx, &ex, - &FR_SBUFF_IN(query, talloc_array_length(query)), - &(fr_sbuff_parse_rules_t){ - .escapes = &(fr_sbuff_unescape_rules_t) { - .name = "xlat", - .chr = '\\', - .subs = { - ['%'] = '%', - ['\\'] = '\\', - }, - }}, t_rules, 0) < 0) { - talloc_free(query); - return -1; - } - talloc_free(query); - - if (xlat_needs_resolving(ex) && - (xlat_resolve(ex, &(xlat_res_rules_t){ .allow_unresolved = false }) < 0)) { - talloc_free(ex); - return -1; - } - - *(void**)out = ex; - return 0; -} - -static const call_env_method_t sqlcounter_call_env = { - FR_CALL_ENV_METHOD_OUT(sqlcounter_call_env_t), - .env = (call_env_parser_t[]){ - { FR_CALL_ENV_PARSE_ONLY_OFFSET("query", FR_TYPE_VOID, CALL_ENV_FLAG_REQUIRED | CALL_ENV_FLAG_PARSE_ONLY, sqlcounter_call_env_t, query_xlat), - .pair.func = call_env_query_parse }, - { FR_CALL_ENV_PARSE_ONLY_OFFSET("reply_name", FR_TYPE_VOID, CALL_ENV_FLAG_PARSE_ONLY, sqlcounter_call_env_t, reply_attr) }, - { FR_CALL_ENV_PARSE_ONLY_OFFSET("reply_message_name", FR_TYPE_VOID, CALL_ENV_FLAG_PARSE_ONLY, sqlcounter_call_env_t, reply_msg_attr) }, - CALL_ENV_TERMINATOR - } -}; - /* * The module name should be the only globally exported symbol. * That is, everything else should be 'static'. diff --git a/src/modules/rlm_sqlippool/rlm_sqlippool.c b/src/modules/rlm_sqlippool/rlm_sqlippool.c index 44e41e7484..82a682bdee 100644 --- a/src/modules/rlm_sqlippool/rlm_sqlippool.c +++ b/src/modules/rlm_sqlippool/rlm_sqlippool.c @@ -223,14 +223,6 @@ finish: return retval; } -static int mod_bootstrap(module_inst_ctx_t const *mctx) -{ - rlm_sqlippool_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_sqlippool_t); - inst->name = talloc_asprintf(inst, "%s - %s", mctx->mi->name, inst->sql_name); - - return 0; -} - /* * Do any per-module initialization that is separate to each * configured instance of the module. e.g. set up connections @@ -247,6 +239,8 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) rlm_sqlippool_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_sqlippool_t); CONF_SECTION *conf = mctx->mi->conf; + inst->name = talloc_asprintf(inst, "%s - %s", mctx->mi->name, inst->sql_name); + sql = module_rlm_by_name(NULL, inst->sql_name); if (!sql) { cf_log_err(conf, "failed to find sql instance named %s", @@ -712,7 +706,6 @@ module_rlm_t rlm_sqlippool = { .name = "sqlippool", .inst_size = sizeof(rlm_sqlippool_t), .config = module_config, - .bootstrap = mod_bootstrap, .instantiate = mod_instantiate }, .method_names = (module_method_name_t[]){ diff --git a/src/modules/rlm_tacacs/rlm_tacacs.c b/src/modules/rlm_tacacs/rlm_tacacs.c index 2fabac71c4..7dfca808ff 100644 --- a/src/modules/rlm_tacacs/rlm_tacacs.c +++ b/src/modules/rlm_tacacs/rlm_tacacs.c @@ -185,7 +185,7 @@ static unlang_action_t CC_HINT(nonnull) mod_process(rlm_rcode_t *p_result, modul return unlang_module_yield(request, inst->io->resume, mod_tacacs_signal, 0, rctx); } -static int mod_bootstrap(module_inst_ctx_t const *mctx) +static int mod_instantiate(module_inst_ctx_t const *mctx) { size_t i, num_types; rlm_tacacs_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_tacacs_t); @@ -262,7 +262,7 @@ module_rlm_t rlm_tacacs = { .onload = mod_load, .unload = mod_unload, - .bootstrap = mod_bootstrap, + .instantiate = mod_instantiate, }, .method_names = (module_method_name_t[]){ { .name1 = CF_IDENT_ANY, .name2 = CF_IDENT_ANY, .method = mod_process }, diff --git a/src/modules/rlm_test/rlm_test.c b/src/modules/rlm_test/rlm_test.c index 87af5b470b..8b88973402 100644 --- a/src/modules/rlm_test/rlm_test.c +++ b/src/modules/rlm_test/rlm_test.c @@ -451,7 +451,7 @@ static int mod_thread_detach(module_thread_inst_ctx_t const *mctx) */ static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_test_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_test_t); + rlm_test_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_test_t); xlat_t *xlat; /* @@ -480,10 +480,10 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) INFO("inst->tmpl_m is NULL"); } - if (!(xlat = xlat_func_register_module(inst, mctx, "passthrough", test_xlat_passthrough, FR_TYPE_VOID))) return -1; + if (!(xlat = xlat_func_register_module(mctx->mi->boot, mctx, "passthrough", test_xlat_passthrough, FR_TYPE_VOID))) return -1; xlat_func_args_set(xlat, test_xlat_passthrough_args); - if (!(xlat = xlat_func_register_module(inst, mctx, "fail", test_xlat_fail, FR_TYPE_VOID))) return -1; + if (!(xlat = xlat_func_register_module(mctx->mi->boot, mctx, "fail", test_xlat_fail, FR_TYPE_VOID))) return -1; xlat_func_args_set(xlat, test_xlat_fail_args); return 0; diff --git a/src/modules/rlm_totp/rlm_totp.c b/src/modules/rlm_totp/rlm_totp.c index 717c56171a..8d465c4663 100644 --- a/src/modules/rlm_totp/rlm_totp.c +++ b/src/modules/rlm_totp/rlm_totp.c @@ -57,7 +57,6 @@ static const call_env_method_t method_env = { /* Define a structure for the configuration variables */ typedef struct rlm_totp_t { - char const *name; //!< name of this instance */ fr_totp_t totp; //! configuration entries passed to libfreeradius-totp } rlm_totp_t; @@ -71,49 +70,6 @@ static const conf_parser_t module_config[] = { CONF_PARSER_TERMINATOR }; -static int mod_bootstrap(module_inst_ctx_t const *mctx) -{ - rlm_totp_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_totp_t); - CONF_SECTION *conf = mctx->mi->conf; - - inst->name = cf_section_name2(conf); - if (!inst->name) inst->name = cf_section_name1(conf); - - return 0; -} - -/* - * Do any per-module initialization that is separate to each - * configured instance of the module. e.g. set up connections - * to external databases, read configuration files, set up - * dictionary entries, etc. - * - * If configuration information is given in the config section - * that must be referenced in later calls, store a handle to it - * in *instance otherwise put a null pointer there. - */ -static int mod_instantiate(module_inst_ctx_t const *mctx) -{ - rlm_totp_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_totp_t); - - FR_INTEGER_BOUND_CHECK("time_step", inst->totp.time_step, >=, 5); - FR_INTEGER_BOUND_CHECK("time_step", inst->totp.time_step, <=, 120); - - FR_INTEGER_BOUND_CHECK("lookback_steps", inst->totp.lookback_steps, >=, 1); - FR_INTEGER_BOUND_CHECK("lookback_steps", inst->totp.lookback_steps, <=, 10); - - FR_INTEGER_BOUND_CHECK("lookforward_steps", inst->totp.lookforward_steps, <=, 10); - - FR_INTEGER_BOUND_CHECK("lookback_interval", inst->totp.lookback_interval, <=, inst->totp.time_step); - - FR_INTEGER_BOUND_CHECK("otp_length", inst->totp.otp_length, >=, 6); - FR_INTEGER_BOUND_CHECK("otp_length", inst->totp.otp_length, <=, 8); - - if (inst->totp.otp_length == 7) inst->totp.otp_length = 8; - - return 0; -} - /* * Do the authentication */ @@ -175,6 +131,38 @@ static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, } } +/* + * Do any per-module initialization that is separate to each + * configured instance of the module. e.g. set up connections + * to external databases, read configuration files, set up + * dictionary entries, etc. + * + * If configuration information is given in the config section + * that must be referenced in later calls, store a handle to it + * in *instance otherwise put a null pointer there. + */ +static int mod_instantiate(module_inst_ctx_t const *mctx) +{ + rlm_totp_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_totp_t); + + FR_INTEGER_BOUND_CHECK("time_step", inst->totp.time_step, >=, 5); + FR_INTEGER_BOUND_CHECK("time_step", inst->totp.time_step, <=, 120); + + FR_INTEGER_BOUND_CHECK("lookback_steps", inst->totp.lookback_steps, >=, 1); + FR_INTEGER_BOUND_CHECK("lookback_steps", inst->totp.lookback_steps, <=, 10); + + FR_INTEGER_BOUND_CHECK("lookforward_steps", inst->totp.lookforward_steps, <=, 10); + + FR_INTEGER_BOUND_CHECK("lookback_interval", inst->totp.lookback_interval, <=, inst->totp.time_step); + + FR_INTEGER_BOUND_CHECK("otp_length", inst->totp.otp_length, >=, 6); + FR_INTEGER_BOUND_CHECK("otp_length", inst->totp.otp_length, <=, 8); + + if (inst->totp.otp_length == 7) inst->totp.otp_length = 8; + + return 0; +} + /* * The module name should be the only globally exported symbol. * That is, everything else should be 'static'. @@ -191,7 +179,6 @@ module_rlm_t rlm_totp = { .name = "totp", .inst_size = sizeof(rlm_totp_t), .config = module_config, - .bootstrap = mod_bootstrap, .instantiate = mod_instantiate }, .method_names = (module_method_name_t[]){ diff --git a/src/modules/rlm_unbound/rlm_unbound.c b/src/modules/rlm_unbound/rlm_unbound.c index fbcfb5c3d3..fa0dcd0870 100644 --- a/src/modules/rlm_unbound/rlm_unbound.c +++ b/src/modules/rlm_unbound/rlm_unbound.c @@ -36,7 +36,6 @@ RCSID("$Id$") #include "log.h" typedef struct { - char const *name; uint32_t timeout; char const *filename; //!< Unbound configuration file @@ -220,7 +219,7 @@ static void xlat_unbound_callback(void *mydata, int rcode, void *packet, int pac */ fr_value_box_t *priority_vb; if (rdlength < 3) { - REDEBUG("%s - Invalid data returned", ur->t->inst->name); + REDEBUG("Invalid data returned"); goto error; } MEM(priority_vb = fr_value_box_alloc_null(ur->out_ctx)); @@ -297,7 +296,7 @@ static xlat_action_t xlat_unbound_resume(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *o if (ur->timedout) return XLAT_ACTION_FAIL; #define RCODEERROR(_code, _message) case _code: \ - REDEBUG(_message, ur->t->inst->name); \ + REDEBUG(_message, xctx->mctx->mi->name); \ goto error /* Check for unbound errors */ @@ -306,7 +305,7 @@ static xlat_action_t xlat_unbound_resume(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *o break; default: - REDEBUG("%s - Unknown DNS error", ur->t->inst->name); + REDEBUG("Unknown DNS error"); error: talloc_free(ur); return XLAT_ACTION_FAIL; @@ -486,17 +485,15 @@ static int mod_thread_detach(module_thread_inst_ctx_t const *mctx) static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_unbound_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_unbound_t); - xlat_t *xlat; - - inst->name = mctx->mi->name; + rlm_unbound_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_unbound_t); + xlat_t *xlat; if (inst->timeout > 10000) { cf_log_err(mctx->mi->conf, "timeout must be 0 to 10000"); return -1; } - if(!(xlat = xlat_func_register_module(NULL, mctx, NULL, xlat_unbound, FR_TYPE_VOID))) return -1; + if(!(xlat = xlat_func_register_module(mctx->mi->boot, mctx, NULL, xlat_unbound, FR_TYPE_VOID))) return -1; xlat_func_args_set(xlat, xlat_unbound_args); return 0; diff --git a/src/modules/rlm_unix/rlm_unix.c b/src/modules/rlm_unix/rlm_unix.c index 46ee5a6050..c0fdd744ea 100644 --- a/src/modules/rlm_unix/rlm_unix.c +++ b/src/modules/rlm_unix/rlm_unix.c @@ -182,7 +182,6 @@ static xlat_action_t unix_group_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, */ static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_unix_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_unix_t); xlat_t *xlat; xlat_arg_parser_t *xlat_arg; @@ -191,7 +190,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) * function automatically adds the module instance name * as a prefix. */ - xlat = xlat_func_register_module(inst, mctx, "group", unix_group_xlat, FR_TYPE_BOOL); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, "group", unix_group_xlat, FR_TYPE_BOOL); if (!xlat) { PERROR("Failed registering group expansion"); return -1; @@ -201,12 +200,12 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) * The xlat escape function needs access to inst - so * argument parser details need to be defined here */ - xlat_arg = talloc_zero_array(inst, xlat_arg_parser_t, 2); - xlat_arg[0].type = FR_TYPE_STRING; - xlat_arg[0].required = true; - xlat_arg[0].concat = true; - xlat_arg[0].func = NULL; /* No real escaping done - we do strcmp() on it */ - xlat_arg[0].uctx = NULL; + xlat_arg = talloc_zero_array(xlat, xlat_arg_parser_t, 2); + xlat_arg[0] = (xlat_arg_parser_t) { + .type = FR_TYPE_STRING, + .required = true, + .concat = true + }; xlat_arg[1] = (xlat_arg_parser_t)XLAT_ARG_PARSER_TERMINATOR; xlat_func_mono_set(xlat, xlat_arg); diff --git a/src/modules/rlm_winbind/rlm_winbind.c b/src/modules/rlm_winbind/rlm_winbind.c index 040eafc607..9bfbdf75aa 100644 --- a/src/modules/rlm_winbind/rlm_winbind.c +++ b/src/modules/rlm_winbind/rlm_winbind.c @@ -537,7 +537,7 @@ static const call_env_method_t winbind_group_xlat_call_env = { */ static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_winbind_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_winbind_t); + rlm_winbind_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_winbind_t); CONF_SECTION *conf = mctx->mi->conf; xlat_t *xlat; @@ -546,7 +546,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) * function automatically adds the module instance name * as a prefix. */ - xlat = xlat_func_register_module(inst, mctx, "group", winbind_group_xlat, FR_TYPE_BOOL); + xlat = xlat_func_register_module(mctx->mi->boot, mctx, "group", winbind_group_xlat, FR_TYPE_BOOL); if (!xlat) { cf_log_err(conf, "Failed registering group expansion"); return -1; diff --git a/src/modules/rlm_yubikey/rlm_yubikey.c b/src/modules/rlm_yubikey/rlm_yubikey.c index 4a644dd3c0..c9f48cbe46 100644 --- a/src/modules/rlm_yubikey/rlm_yubikey.c +++ b/src/modules/rlm_yubikey/rlm_yubikey.c @@ -194,7 +194,7 @@ static void mod_unload(void) #ifndef HAVE_YUBIKEY static int mod_bootstrap(module_inst_ctx_t const *mctx) { - rlm_yubikey_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_yubikey_t); + rlm_yubikey_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_yubikey_t); if (inst->decrypt) { cf_log_err(mctx->mi->conf, "Requires libyubikey for OTP decryption"); diff --git a/src/process/dhcpv6/base.c b/src/process/dhcpv6/base.c index 5769e12cf0..dbac1aea90 100644 --- a/src/process/dhcpv6/base.c +++ b/src/process/dhcpv6/base.c @@ -756,7 +756,7 @@ static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mc return state->recv(p_result, mctx, request); } -static int mod_bootstrap(module_inst_ctx_t const *mctx) +static int mod_instantiate(module_inst_ctx_t const *mctx) { process_dhcpv6_t *inst = talloc_get_type_abort(mctx->mi->data, process_dhcpv6_t); @@ -1256,7 +1256,7 @@ fr_process_module_t process_dhcpv6 = { .config = dhcpv6_process_config, .inst_size = sizeof(process_dhcpv6_t), - .bootstrap = mod_bootstrap + .instantiate = mod_instantiate }, .process = mod_process, .compile_list = compile_list, diff --git a/src/process/radius/base.c b/src/process/radius/base.c index b0e2c636ae..0a6f927cc6 100644 --- a/src/process/radius/base.c +++ b/src/process/radius/base.c @@ -843,6 +843,8 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) { process_radius_t *inst = talloc_get_type_abort(mctx->mi->data, process_radius_t); + inst->server_cs = cf_item_to_section(cf_parent(mctx->mi->conf)); + inst->auth.state_tree = fr_state_tree_init(inst, attr_state, main_config->spawn_workers, inst->auth.max_session, inst->auth.session_timeout, inst->auth.state_server_id, fr_hash_string(cf_section_name2(inst->server_cs))); @@ -852,10 +854,9 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) static int mod_bootstrap(module_inst_ctx_t const *mctx) { - process_radius_t *inst = talloc_get_type_abort(mctx->mi->data, process_radius_t); + CONF_SECTION *server_cs = cf_item_to_section(cf_parent(mctx->mi->conf)); - inst->server_cs = cf_item_to_section(cf_parent(mctx->mi->conf)); - if (virtual_server_section_attribute_define(inst->server_cs, "authenticate", attr_auth_type) < 0) return -1; + if (virtual_server_section_attribute_define(server_cs, "authenticate", attr_auth_type) < 0) return -1; return 0; } diff --git a/src/process/tacacs/base.c b/src/process/tacacs/base.c index cbda6e4e83..493fe3cb5a 100644 --- a/src/process/tacacs/base.c +++ b/src/process/tacacs/base.c @@ -1050,11 +1050,18 @@ static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mc return state->recv(p_result, mctx, request); } - static int mod_instantiate(module_inst_ctx_t const *mctx) { process_tacacs_t *inst = talloc_get_type_abort(mctx->mi->data, process_tacacs_t); + inst->server_cs = cf_item_to_section(cf_parent(mctx->mi->conf)); + + FR_INTEGER_BOUND_CHECK("session.max_rounds", inst->auth.max_rounds, >=, 1); + FR_INTEGER_BOUND_CHECK("session.max_rounds", inst->auth.max_rounds, <=, 8); + + FR_INTEGER_BOUND_CHECK("session.max", inst->auth.max_session, >=, 64); + FR_INTEGER_BOUND_CHECK("session.max", inst->auth.max_session, <=, (1 << 18)); + inst->auth.state_tree = fr_state_tree_init(inst, attr_tacacs_state, main_config->spawn_workers, inst->auth.max_session, inst->auth.session_timeout, inst->auth.state_server_id, fr_hash_string(cf_section_name2(inst->server_cs))); @@ -1063,16 +1070,9 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) static int mod_bootstrap(module_inst_ctx_t const *mctx) { - process_tacacs_t *inst = talloc_get_type_abort(mctx->mi->data, process_tacacs_t); - - inst->server_cs = cf_item_to_section(cf_parent(mctx->mi->conf)); - if (virtual_server_section_attribute_define(inst->server_cs, "authenticate", attr_auth_type) < 0) return -1; - - FR_INTEGER_BOUND_CHECK("session.max_rounds", inst->auth.max_rounds, >=, 1); - FR_INTEGER_BOUND_CHECK("session.max_rounds", inst->auth.max_rounds, <=, 8); + CONF_SECTION *server_cs = cf_item_to_section(cf_parent(mctx->mi->conf)); - FR_INTEGER_BOUND_CHECK("session.max", inst->auth.max_session, >=, 64); - FR_INTEGER_BOUND_CHECK("session.max", inst->auth.max_session, <=, (1 << 18)); + if (virtual_server_section_attribute_define(server_cs, "authenticate", attr_auth_type) < 0) return -1; return 0; } diff --git a/src/process/ttls/base.c b/src/process/ttls/base.c index 5f90270c7c..c90764cecb 100644 --- a/src/process/ttls/base.c +++ b/src/process/ttls/base.c @@ -507,6 +507,8 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) { process_ttls_t *inst = talloc_get_type_abort(mctx->mi->data, process_ttls_t); + inst->server_cs = cf_item_to_section(cf_parent(mctx->mi->conf)); + inst->auth.state_tree = fr_state_tree_init(inst, attr_state, main_config->spawn_workers, inst->auth.session.max, inst->auth.session.timeout, inst->auth.session.state_server_id, fr_hash_string(cf_section_name2(inst->server_cs))); @@ -516,10 +518,9 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) static int mod_bootstrap(module_inst_ctx_t const *mctx) { - process_ttls_t *inst = talloc_get_type_abort(mctx->mi->data, process_ttls_t); + CONF_SECTION *server_cs = cf_item_to_section(cf_parent(mctx->mi->conf)); - inst->server_cs = cf_item_to_section(cf_parent(mctx->mi->conf)); - if (virtual_server_section_attribute_define(inst->server_cs, "authenticate", attr_auth_type) < 0) return -1; + if (virtual_server_section_attribute_define(server_cs, "authenticate", attr_auth_type) < 0) return -1; return 0; } -- 2.47.3