#define LOG_PREFIX mctx->mi->name
#include <freeradius-devel/server/base.h>
+#include <freeradius-devel/server/module.h>
#include <freeradius-devel/server/module_rlm.h>
#include <freeradius-devel/unlang/xlat_func.h>
+/*
+ * 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;
/*
*/
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
};
}
-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;
}
{
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;
}
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;
.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 },
{
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);
#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
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.
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);
}
/*
* 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;
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;
/*
* 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;
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;
}
if (!request) return CACHE_ERROR;
- return fr_rb_num_elements(driver->cache);
+ return fr_rb_num_elements(driver->mutable->cache);
}
/** Lock the rbtree
{
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 */
{
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 = {
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;
*/
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;
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,
{
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);
*/
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:
/*
* 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);
}
/*
* 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;
.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,
#include <freeradius-devel/server/base.h>
#include <freeradius-devel/server/module_rlm.h>
#include <freeradius-devel/unlang/xlat_func.h>
-#include <ctype.h>
#include <time.h>
typedef struct {
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;
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;
}
#include <freeradius-devel/unlang/module.h>
-#include <ctype.h>
-
static fr_dict_t const *dict_dhcpv4;
static fr_dict_t const *dict_freeradius;
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;
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);
RETURN_MODULE_OK;
}
-
/** Send packets outbound.
*
*/
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,
{
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);
/*
}
}
+ 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;
}
.config = module_config,
.onload = mod_load,
.unload = mod_unload,
- .bootstrap = mod_bootstrap,
.instantiate = mod_instantiate,
},
.method_names = (module_method_name_t[]){
{
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);
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);
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.
.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,
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.
*
*/
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");
}
-/** 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'.
.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,
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);
#include <freeradius-devel/unlang/xlat_func.h>
#include <freeradius-devel/json/base.h>
-#include <ctype.h>
-
#ifndef HAVE_JSON
# error "rlm_json should not be built unless json-c is available"
#endif
* - 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;
* @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;
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
}
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;
}
.unload = mod_unload,
.config = module_config,
.inst_size = sizeof(rlm_json_t),
- .bootstrap = mod_bootstrap
+ .bootstrap = mod_bootstrap,
+ .instantiate = mod_instantiate
}
};
#include <ldap.h>
#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;
/*
* 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) {
* @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;
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)
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.
*/
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")) {
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;
.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,
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 );
#include <freeradius-devel/unlang/xlat_func.h>
#include <sys/wait.h>
-#include <ctype.h>
#include "rlm_mschap.h"
#include "mschap.h"
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);
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)
{
}
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 */
PERL_SYS_TERM();
}
-
/*
* The module name should be the only globally exported symbol.
* That is, everything else should be 'static'.
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);
.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 },
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 {
.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;
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;
}
};
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 {
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[];
/*
* 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;
* 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;
}
}
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;
.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,
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(<key>[, 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);
/*
* 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);
}
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);
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;
.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,
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;
.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,
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;
.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,
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;
}
/*
- * 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;
.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,
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 = "" },
}
};
+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);
/*
* 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) {
* @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);
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
*/
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;
}
* 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;
* 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);
/*
* 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;
* 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);
/*
* 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;
}
.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,
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
{
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) {
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'.
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
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",
.name = "sqlippool",
.inst_size = sizeof(rlm_sqlippool_t),
.config = module_config,
- .bootstrap = mod_bootstrap,
.instantiate = mod_instantiate
},
.method_names = (module_method_name_t[]){
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);
.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 },
*/
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;
/*
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;
/* 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;
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
*/
}
}
+/*
+ * 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'.
.name = "totp",
.inst_size = sizeof(rlm_totp_t),
.config = module_config,
- .bootstrap = mod_bootstrap,
.instantiate = mod_instantiate
},
.method_names = (module_method_name_t[]){
#include "log.h"
typedef struct {
- char const *name;
uint32_t timeout;
char const *filename; //!< Unbound configuration file
*/
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));
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 */
break;
default:
- REDEBUG("%s - Unknown DNS error", ur->t->inst->name);
+ REDEBUG("Unknown DNS error");
error:
talloc_free(ur);
return XLAT_ACTION_FAIL;
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;
*/
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;
* 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;
* 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);
*/
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;
* 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;
#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");
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);
.config = dhcpv6_process_config,
.inst_size = sizeof(process_dhcpv6_t),
- .bootstrap = mod_bootstrap
+ .instantiate = mod_instantiate
},
.process = mod_process,
.compile_list = compile_list,
{
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)));
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;
}
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)));
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;
}
{
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)));
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;
}