char const *name2; //!< The packet type i.e Access-Request, Access-Reject.
module_method_t method; //!< Module method to call
- call_method_env_t const *method_env; //!< Call specific conf parsing.
+ call_env_method_t const *method_env; //!< Call specific conf parsing.
};
#define MODULE_NAME_TERMINATOR { NULL }
*
* If the module exists but the method doesn't exist, then `method` is set to NULL.
*/
-module_instance_t *module_rlm_by_name_and_method(module_method_t *method, call_method_env_t const **method_env,
+module_instance_t *module_rlm_by_name_and_method(module_method_t *method, call_env_method_t const **method_env,
char const **name1, char const **name2,
char const *name)
{
*
* @{
*/
-module_instance_t *module_rlm_by_name_and_method(module_method_t *method, call_method_env_t const ** method_env,
+module_instance_t *module_rlm_by_name_and_method(module_method_t *method, call_env_method_t const ** method_env,
char const **name1, char const **name2,
char const *asked_name);
#include <freeradius-devel/unlang/interpret.h>
#include "call_env.h"
-/** Parse per call env
- *
- * Used for config options which must be parsed in the context in which
- * the module is being called.
- *
- * @param[in] ctx To allocate parsed environment in.
- * @param[out] parsed Where to write parsed environment.
- * @param[in] name Module name for error messages.
- * @param[in] dict_def Default dictionary to use when tokenizing tmpls.
- * @param[in] cs Module config.
- * @param[in] call_env to parse.
- * @return
- * - 0 on success;
- * - <0 on failure;
- */
-int call_env_parse(TALLOC_CTX *ctx, call_env_parsed_head_t *parsed, char const *name, fr_dict_t const *dict_def,
- CONF_SECTION const *cs, call_env_t const *call_env) {
- CONF_PAIR const *cp, *next;
- call_env_parsed_t *call_env_parsed;
- ssize_t len, opt_count, multi_index;
- char const *value;
- fr_token_t quote;
- fr_type_t type;
-
- while (call_env->name) {
- if (FR_BASE_TYPE(call_env->type) == FR_TYPE_SUBSECTION) {
- CONF_SECTION const *subcs;
- subcs = cf_section_find(cs, call_env->name, call_env->section.ident2);
- if (!subcs) {
- if (!call_env->section.required) goto next;
- cf_log_err(cs, "Module %s missing required section %s", name, call_env->name);
- return -1;
- }
-
- if (call_env_parse(ctx, parsed, name, dict_def, subcs, call_env->section.subcs) < 0) return -1;
- goto next;
- }
-
- cp = cf_pair_find(cs, call_env->name);
-
- if (!cp && !call_env->dflt) {
- if (!call_env->pair.required) goto next;
-
- cf_log_err(cs, "Module %s missing required option %s", name, call_env->name);
- return -1;
- }
-
- /*
- * Check for additional conf pairs and error
- * if there is one and multi is not allowed.
- */
- if (!call_env->pair.multi && ((next = cf_pair_find_next(cs, cp, call_env->name)))) {
- cf_log_err(cf_pair_to_item(next), "Invalid duplicate configuration item '%s'", call_env->name);
- return -1;
- }
-
- opt_count = cf_pair_count(cs, call_env->name);
- if (opt_count == 0) opt_count = 1;
-
- for (multi_index = 0; multi_index < opt_count; multi_index ++) {
- MEM(call_env_parsed = talloc_zero(ctx, call_env_parsed_t));
- call_env_parsed->rule = call_env;
- call_env_parsed->opt_count = opt_count;
- call_env_parsed->multi_index = multi_index;
- if (call_env->pair.type == CALL_ENV_TYPE_TMPL_ONLY) call_env_parsed->tmpl_only = true;
-
- if (cp) {
- value = cf_pair_value(cp);
- len = talloc_array_length(value) - 1;
- quote = call_env->pair.force_quote ? call_env->dflt_quote : cf_pair_value_quote(cp);
- } else {
- value = call_env->dflt;
- len = strlen(value);
- quote = call_env->dflt_quote;
- }
-
- type = FR_BASE_TYPE(call_env->type);
- if (tmpl_afrom_substr(call_env_parsed, &call_env_parsed->tmpl, &FR_SBUFF_IN(value, len),
- quote, NULL, &(tmpl_rules_t){
- .cast = (type == FR_TYPE_VOID ? FR_TYPE_NULL : type),
- .attr = {
- .list_def = request_attr_request,
- .dict_def = dict_def
- }
- }) < 0) {
- error:
- talloc_free(call_env_parsed);
- cf_log_perr(cp, "Failed to parse configuration item '%s = %s'", call_env->name, value);
- return -1;
- }
-
- /*
- * Ensure only valid TMPL types are produced.
- */
- switch (call_env_parsed->tmpl->type) {
- case TMPL_TYPE_DATA:
- case TMPL_TYPE_EXEC:
- case TMPL_TYPE_XLAT:
- if (call_env->type & FR_TYPE_ATTRIBUTE) {
- cf_log_perr(cp, "'%s' expands to %s - attribute reference required", value,
- fr_table_str_by_value(tmpl_type_table, call_env_parsed->tmpl->type,
- "<INVALID>"));
- goto error;
- }
- FALL_THROUGH;
-
- case TMPL_TYPE_ATTR:
- break;
-
- default:
- cf_log_err(cp, "'%s' expands to invalid tmpl type %s", value,
- fr_table_str_by_value(tmpl_type_table, call_env_parsed->tmpl->type, "<INVALID>"));
- goto error;
- }
-
- call_env_parsed_insert_tail(parsed, call_env_parsed);
-
- cp = cf_pair_find_next(cs, cp, call_env->name);
- }
- next:
- call_env++;
- }
-
- return 0;
-}
-
-/** Perform a quick assessment of how many parsed call env will be produced.
- *
- * @param[in,out] vallen Where to write the sum of the length of pair values.
- * @param[in] cs Conf section to search for pairs.
- * @param[in] call_env to parse.
- * @return Number of parsed_call_env expected to be required.
- */
-size_t call_env_count(size_t *vallen, CONF_SECTION const *cs, call_env_t const *call_env) {
- size_t pair_count, tmpl_count = 0;
- CONF_PAIR const *cp;
-
- while (call_env->name) {
- if (FR_BASE_TYPE(call_env->type) == FR_TYPE_SUBSECTION) {
- CONF_SECTION const *subcs;
- subcs = cf_section_find(cs, call_env->name, call_env->section.ident2);
- if (!subcs) goto next;
-
- tmpl_count += call_env_count(vallen, subcs, call_env->section.subcs);
- goto next;
- }
- pair_count = 0;
- cp = NULL;
- while ((cp = cf_pair_find_next(cs, cp, call_env->name))) {
- pair_count++;
- *vallen += talloc_array_length(cf_pair_value(cp));
- }
- if (!pair_count && call_env->dflt) {
- pair_count = 1;
- *vallen += strlen(call_env->dflt);
- }
- tmpl_count += pair_count;
- next:
- call_env++;
- }
-
- return tmpl_count;
-}
/** Parse the result of call_env tmpl expansion
*/
*
*/
typedef struct {
- call_env_result_t *result; //!< Where to write the return code of callenv expansion.
+ call_env_result_t *result; //!< Where to write the return code of callenv expansion.
call_env_parsed_head_t const *parsed; //!< Head of the parsed list of tmpls to expand.
- call_env_parsed_t const *last_expanded; //!< The last expanded tmpl.
- fr_value_box_list_t tmpl_expanded; //!< List to write value boxes to as tmpls are expanded.
- void **data; //!< Final destination structure for value boxes.
+ call_env_parsed_t const *last_expanded; //!< The last expanded tmpl.
+ fr_value_box_list_t tmpl_expanded; //!< List to write value boxes to as tmpls are expanded.
+ void **data; //!< Final destination structure for value boxes.
} call_env_ctx_t;
static unlang_action_t call_env_expand_repeat(rlm_rcode_t *p_result, int *priority, request_t *request, void *uctx);
if (env->multi_index == 0) {
void *array;
MEM(array = _talloc_zero_array((*call_env_ctx->data), env->rule->pair.size,
- env->opt_count, env->rule->pair.type_name));
+ env->count, env->rule->pair.type_name));
*out = array;
}
ctx = *out;
* @param[in] call_env Call environment being expanded.
* @param[in] call_env_parsed Parsed tmpls for the call environment.
*/
-unlang_action_t call_env_expand(TALLOC_CTX *ctx, request_t *request, call_env_result_t *env_result, void **env_data, call_method_env_t const *call_env,
+unlang_action_t call_env_expand(TALLOC_CTX *ctx, request_t *request, call_env_result_t *env_result, void **env_data, call_env_method_t const *call_env,
call_env_parsed_head_t const *call_env_parsed)
{
call_env_ctx_t *call_env_ctx;
return unlang_function_push(request, call_env_expand_start, call_env_expand_repeat, NULL, 0, UNLANG_SUB_FRAME,
call_env_ctx);
}
+
+/** Parse per call env
+ *
+ * Used for config options which must be parsed in the context in which
+ * the module is being called.
+ *
+ * @param[in] ctx To allocate parsed environment in.
+ * @param[out] parsed Where to write parsed environment.
+ * @param[in] name Module name for error messages.
+ * @param[in] dict_def Default dictionary to use when tokenizing tmpls.
+ * @param[in] cs Module config.
+ * @param[in] call_env to parse.
+ * @return
+ * - 0 on success;
+ * - <0 on failure;
+ */
+int call_env_parse(TALLOC_CTX *ctx, call_env_parsed_head_t *parsed, char const *name, fr_dict_t const *dict_def,
+ CONF_SECTION const *cs, call_env_parser_t const *call_env) {
+ CONF_PAIR const *cp, *next;
+ call_env_parsed_t *call_env_parsed;
+ ssize_t len, count, multi_index;
+ char const *value;
+ fr_token_t quote;
+ fr_type_t type;
+
+ while (call_env->name) {
+ if (FR_BASE_TYPE(call_env->type) == FR_TYPE_SUBSECTION) {
+ CONF_SECTION const *subcs;
+ subcs = cf_section_find(cs, call_env->name, call_env->section.ident2);
+ if (!subcs) {
+ if (!call_env->section.required) goto next;
+ cf_log_err(cs, "Module %s missing required section %s", name, call_env->name);
+ return -1;
+ }
+
+ if (call_env_parse(ctx, parsed, name, dict_def, subcs, call_env->section.subcs) < 0) return -1;
+ goto next;
+ }
+
+ cp = cf_pair_find(cs, call_env->name);
+
+ if (!cp && !call_env->dflt) {
+ if (!call_env->pair.required) goto next;
+
+ cf_log_err(cs, "Module %s missing required option %s", name, call_env->name);
+ return -1;
+ }
+
+ /*
+ * Check for additional conf pairs and error
+ * if there is one and multi is not allowed.
+ */
+ if (!call_env->pair.multi && ((next = cf_pair_find_next(cs, cp, call_env->name)))) {
+ cf_log_err(cf_pair_to_item(next), "Invalid duplicate configuration item '%s'", call_env->name);
+ return -1;
+ }
+
+ count = cf_pair_count(cs, call_env->name);
+ if (count == 0) count = 1;
+
+ for (multi_index = 0; multi_index < count; multi_index ++) {
+ MEM(call_env_parsed = talloc_zero(ctx, call_env_parsed_t));
+ call_env_parsed->rule = call_env;
+ call_env_parsed->count = count;
+ call_env_parsed->multi_index = multi_index;
+ if (call_env->pair.type == CALL_ENV_TYPE_TMPL_ONLY) call_env_parsed->tmpl_only = true;
+
+ if (cp) {
+ value = cf_pair_value(cp);
+ len = talloc_array_length(value) - 1;
+ quote = call_env->pair.force_quote ? call_env->dflt_quote : cf_pair_value_quote(cp);
+ } else {
+ value = call_env->dflt;
+ len = strlen(value);
+ quote = call_env->dflt_quote;
+ }
+
+ type = FR_BASE_TYPE(call_env->type);
+ if (tmpl_afrom_substr(call_env_parsed, &call_env_parsed->tmpl, &FR_SBUFF_IN(value, len),
+ quote, NULL, &(tmpl_rules_t){
+ .cast = (type == FR_TYPE_VOID ? FR_TYPE_NULL : type),
+ .attr = {
+ .list_def = request_attr_request,
+ .dict_def = dict_def
+ }
+ }) < 0) {
+ error:
+ talloc_free(call_env_parsed);
+ cf_log_perr(cp, "Failed to parse configuration item '%s = %s'", call_env->name, value);
+ return -1;
+ }
+
+ /*
+ * Ensure only valid TMPL types are produced.
+ */
+ switch (call_env_parsed->tmpl->type) {
+ case TMPL_TYPE_DATA:
+ case TMPL_TYPE_EXEC:
+ case TMPL_TYPE_XLAT:
+ if (call_env->type & FR_TYPE_ATTRIBUTE) {
+ cf_log_perr(cp, "'%s' expands to %s - attribute reference required", value,
+ fr_table_str_by_value(tmpl_type_table, call_env_parsed->tmpl->type,
+ "<INVALID>"));
+ goto error;
+ }
+ FALL_THROUGH;
+
+ case TMPL_TYPE_ATTR:
+ break;
+
+ default:
+ cf_log_err(cp, "'%s' expands to invalid tmpl type %s", value,
+ fr_table_str_by_value(tmpl_type_table, call_env_parsed->tmpl->type, "<INVALID>"));
+ goto error;
+ }
+
+ call_env_parsed_insert_tail(parsed, call_env_parsed);
+
+ cp = cf_pair_find_next(cs, cp, call_env->name);
+ }
+ next:
+ call_env++;
+ }
+
+ return 0;
+}
+
+/** Perform a quick assessment of how many parsed call env will be produced.
+ *
+ * @param[in,out] names_len Where to write the sum of bytes required to represent
+ * the strings which will be parsed as tmpls. This is required
+ * to pre-allocate space for the tmpl name buffers.
+ * @param[in] cs Conf section to search for pairs.
+ * @param[in] call_env to parse.
+ * @return Number of parsed_call_env expected to be required.
+ */
+size_t call_env_count(size_t *names_len, CONF_SECTION const *cs, call_env_parser_t const *call_env)
+{
+ size_t pair_count, tmpl_count = 0;
+ CONF_PAIR const *cp;
+
+ while (call_env->name) {
+ if (FR_BASE_TYPE(call_env->type) == FR_TYPE_SUBSECTION) {
+ CONF_SECTION const *subcs;
+ subcs = cf_section_find(cs, call_env->name, call_env->section.ident2);
+ if (!subcs) goto next;
+
+ tmpl_count += call_env_count(names_len, subcs, call_env->section.subcs);
+ goto next;
+ }
+ pair_count = 0;
+ cp = NULL;
+ while ((cp = cf_pair_find_next(cs, cp, call_env->name))) {
+ pair_count++;
+ *names_len += talloc_array_length(cf_pair_value(cp));
+ }
+ if (!pair_count && call_env->dflt) {
+ pair_count = 1;
+ *names_len += strlen(call_env->dflt);
+ }
+ tmpl_count += pair_count;
+ next:
+ call_env++;
+ }
+
+ return tmpl_count;
+}
#include <freeradius-devel/util/dlist.h>
-typedef struct call_env_s call_env_t;
+typedef struct call_env_parser_s call_env_parser_t;
typedef struct call_env_parsed_s call_env_parsed_t;
-typedef struct call_method_env_s call_method_env_t;
+typedef struct call_env_method_s call_env_method_t;
FR_DLIST_TYPES(call_env_parsed)
FR_DLIST_TYPEDEFS(call_env_parsed, call_env_parsed_head_t, call_env_parsed_entry_t)
* This allows the conf pairs to be evaluated within the appropriate context
* and use the appropriate dictionaries for where the module is in use.
*/
-struct call_env_s {
+struct call_env_parser_s {
char const *name; //!< Of conf pair to pass to tmpl_tokenizer.
char const *dflt; //!< Default string to pass to the tmpl_tokenizer if no CONF_PAIR found.
fr_token_t dflt_quote; //!< Default quoting for the default string.
struct {
char const *ident2; //!< Second identifier for a section
- call_env_t const *subcs; //!< Nested definitions for subsection.
+ call_env_parser_t const *subcs; //!< Nested definitions for subsection.
bool required; //!< Section is required.
} section;
};
#define CALL_ENV_TERMINATOR { NULL }
struct call_env_parsed_s {
- call_env_parsed_entry_t entry; //!< Entry in list of parsed call_env.
- tmpl_t *tmpl; //!< Tmpl produced from parsing conf pair.
- size_t opt_count; //!< Number of instances found of this option.
- size_t multi_index; //!< Array index for this instance.
- call_env_t const *rule; //!< Used to produce this.
- bool tmpl_only; //!< Don't evaluate before module / xlat call.
- ///< Only the tmpl reference is needed.
+ call_env_parsed_entry_t entry; //!< Entry in list of parsed call_env_parsers.
+ tmpl_t *tmpl; //!< Tmpl produced from parsing conf pair.
+ size_t count; //!< Number of CONF_PAIRs found, matching the #call_env_parser_t.
+ size_t multi_index; //!< Array index for this instance.
+ call_env_parser_t const *rule; //!< Used to produce this.
+ bool tmpl_only; //!< Don't evaluate before module / xlat call.
+ ///< Only the tmpl reference is needed.
};
FR_DLIST_FUNCS(call_env_parsed, call_env_parsed_t, entry)
-struct call_method_env_s {
+/** Helper macro for populating the size/type fields of a #call_env_method_t from the output structure type
+ */
+#define FR_CALL_ENV_METHOD_OUT(_inst) \
+ .inst_size = sizeof(_inst), \
+ .inst_type = STRINGIFY(_inst) \
+
+struct call_env_method_s {
size_t inst_size; //!< Size of per call env.
char const *inst_type; //!< Type of per call env.
- call_env_t const *env; //!< Parsing rules for call method env.
+ call_env_parser_t const *env; //!< Parsing rules for call method env.
};
/** Derive whether tmpl can only emit a single box.
.offset = offsetof(_struct, _field), \
.dflt = _dflt, \
.dflt_quote = _dflt_quote, \
- .pair = { .required = _required, \
- .concat = FR_CALL_ENV_CONCAT(_concat, _cast_type), \
- .single = FR_CALL_ENV_SINGLE(_struct, _field, _concat), \
- .multi = FR_CALL_ENV_MULTI(_struct, _field), \
- .nullable = _nullable, \
- .type = FR_CALL_ENV_DST_TYPE(_struct, _field), \
- .size = FR_CALL_ENV_DST_SIZE(_struct, _field), \
- .type_name = FR_CALL_ENV_DST_TYPE_NAME(_struct, _field), \
- .tmpl_offset = -1 }
+ .pair = { \
+ .required = _required, \
+ .concat = FR_CALL_ENV_CONCAT(_concat, _cast_type), \
+ .single = FR_CALL_ENV_SINGLE(_struct, _field, _concat), \
+ .multi = FR_CALL_ENV_MULTI(_struct, _field), \
+ .nullable = _nullable, \
+ .type = FR_CALL_ENV_DST_TYPE(_struct, _field), \
+ .size = FR_CALL_ENV_DST_SIZE(_struct, _field), \
+ .type_name = FR_CALL_ENV_DST_TYPE_NAME(_struct, _field), \
+ .tmpl_offset = -1 \
+ }
/** Version of the above which sets optional field for pointer to tmpl
*/
.offset = offsetof(_struct, _field), \
.dflt = _dflt, \
.dflt_quote = _dflt_quote, \
- .pair = { .required = _required, \
- .concat = FR_CALL_ENV_CONCAT(_concat, _cast_type), \
- .single = FR_CALL_ENV_SINGLE(_struct, _field, _concat), \
- .multi = FR_CALL_ENV_MULTI(_struct, _field), \
- .nullable = _nullable, \
- .type = FR_CALL_ENV_DST_TYPE(_struct, _field), \
- .size = FR_CALL_ENV_DST_SIZE(_struct, _field), \
- .type_name = FR_CALL_ENV_DST_TYPE_NAME(_struct, _field), \
- .tmpl_offset = offsetof(_struct, _tmpl_field) }
+ .pair = { \
+ .required = _required, \
+ .concat = FR_CALL_ENV_CONCAT(_concat, _cast_type), \
+ .single = FR_CALL_ENV_SINGLE(_struct, _field, _concat), \
+ .multi = FR_CALL_ENV_MULTI(_struct, _field), \
+ .nullable = _nullable, \
+ .type = FR_CALL_ENV_DST_TYPE(_struct, _field), \
+ .size = FR_CALL_ENV_DST_SIZE(_struct, _field), \
+ .type_name = FR_CALL_ENV_DST_TYPE_NAME(_struct, _field), \
+ .tmpl_offset = offsetof(_struct, _tmpl_field) \
+ }
/** Version of the above which only sets the field for a pointer to the tmpl
*/
.type = _cast_type, \
.dflt = _dflt, \
.dflt_quote = _dflt_quote, \
- .pair = { .required = _required, \
- .type = CALL_ENV_TYPE_TMPL_ONLY, \
- .tmpl_offset = offsetof(_struct, _tmpl_field) }
+ .pair = { \
+ .required = _required, \
+ .type = CALL_ENV_TYPE_TMPL_ONLY, \
+ .tmpl_offset = offsetof(_struct, _tmpl_field) \
+ }
#define FR_CALL_ENV_SUBSECTION(_name, _ident2, _subcs, _required ) \
.name = _name, \
.type = FR_TYPE_SUBSECTION, \
- .section = { .ident2 = _ident2, \
- .subcs = _subcs, \
- .required = _required }
+ .section = { \
+ .ident2 = _ident2, \
+ .subcs = _subcs, \
+ .required = _required \
+ }
-int call_env_parse(TALLOC_CTX *ctx, call_env_parsed_head_t *parsed, char const *name, fr_dict_t const *dict_def,
- CONF_SECTION const *cs, call_env_t const *call_env) CC_HINT(nonnull);
+unlang_action_t call_env_expand(TALLOC_CTX *ctx, request_t *request, call_env_result_t *result, void **env_data, call_env_method_t const *call_env,
+ call_env_parsed_head_t const *call_env_parsed);
-size_t call_env_count(size_t *vallen, CONF_SECTION const *cs, call_env_t const *call_env);
+int call_env_parse(TALLOC_CTX *ctx, call_env_parsed_head_t *parsed, char const *name, fr_dict_t const *dict_def,
+ CONF_SECTION const *cs, call_env_parser_t const *call_env) CC_HINT(nonnull);
-unlang_action_t call_env_expand(TALLOC_CTX *ctx, request_t *request, call_env_result_t *result, void **env_data, call_method_env_t const *call_env,
- call_env_parsed_head_t const *call_env_parsed);
+size_t call_env_count(size_t *names_len, CONF_SECTION const *cs, call_env_parser_t const *call_env);
#ifdef __cplusplus
}
static unlang_t *compile_module(unlang_t *parent, unlang_compile_t *unlang_ctx,
CONF_ITEM *ci, module_instance_t *inst, module_method_t method,
- call_method_env_t const *method_env, char const *realname)
+ call_env_method_t const *method_env, char const *realname)
{
module_rlm_t const *mrlm = module_rlm_from_module(inst->module);
unlang_t *c;
* Parse the method environment for this module / method
*/
if (method_env) {
- size_t count, vallen = 0;
+ size_t count, names_len = 0;
/*
* Firstly assess how many parsed env there will be and create a talloc pool to hold them.
* The pool size is a rough estimate based on each tmpl also allocating at least two children,
* for which we allow twice the length of the value to be parsed.
*/
- count = call_env_count(&vallen, inst->dl_inst->conf, method_env->env);
+ count = call_env_count(&names_len, inst->dl_inst->conf, method_env->env);
+
+ /*
+ * Pre-allocated headers:
+ * 1 header for the call_env_parsed_t, 1 header for the tmpl_t, 1 header for the name,
+ * one header for the value.
+ *
+ * Pre-allocated memory:
+ * ((sizeof(call_env_parsed_t) + sizeof(tmpl_t)) * count) + (names of tmpls * 2)... Not sure what
+ * the * 2 is for, maybe for slop?
+ */
MEM(single->call_env_ctx = _talloc_pooled_object(single, 0, "call_env_ctx", count * 4,
- (sizeof(call_env_parsed_t) + sizeof(tmpl_t)) * count + vallen * 2));
+ ((sizeof(call_env_parsed_t) + sizeof(tmpl_t)) * count) + (names_len * 2)));
call_env_parsed_init(&single->call_env_parsed);
if (call_env_parse(single->call_env_ctx, &single->call_env_parsed, single->self.name,
bool policy;
unlang_op_compile_t compile;
unlang_t *c;
- call_method_env_t const *method_env = NULL;
+ call_env_method_t const *method_env = NULL;
if (cf_item_is_section(ci)) {
cs = cf_item_to_section(ci);
unlang_t self; //!< Common fields in all #unlang_t tree nodes.
module_instance_t *instance; //!< Global instance of the module we're calling.
module_method_t method; //!< The entry point into the module.
- call_method_env_t const *method_env; //!< Call environment for this method.
+ call_env_method_t const *method_env; //!< Call environment for this method.
call_env_parsed_head_t call_env_parsed; //!< The per call parsed call environment.
TALLOC_CTX *call_env_ctx; //!< A talloc pooled object for parsed call env
///< to be allocated from.
* @param[in,out] x to have it's module method env registered.
* @param[in] env to be registered.
*/
-void xlat_func_call_env_set(xlat_t *x, call_method_env_t const *env)
+void xlat_func_call_env_set(xlat_t *x, call_env_method_t const *env)
{
x->call_env = env;
}
int xlat_func_mono_set(xlat_t *xlat, xlat_arg_parser_t const *arg) CC_HINT(nonnull);
-void xlat_func_call_env_set(xlat_t *x, call_method_env_t const *env) CC_HINT(nonnull);
+void xlat_func_call_env_set(xlat_t *x, call_env_method_t const *env) CC_HINT(nonnull);
void xlat_func_flags_set(xlat_t *x, xlat_func_flags_t flags) CC_HINT(nonnull);
* If the xlat has a call env defined, parse it.
*/
if (call->func->call_env) {
- size_t count, vallen = 0;
+ size_t count, names_len = 0;
CONF_SECTION *cs = call->func->mctx->inst->conf;
- call_method_env_t const *call_env = call->func->call_env;
+ call_env_method_t const *call_env = call->func->call_env;
- count = call_env_count(&vallen, cs, call_env->env);
+ count = call_env_count(&names_len, cs, call_env->env);
MEM(xi->call_env_ctx = _talloc_pooled_object(xi, 0, "call_env_ctx", count * 4,
- (sizeof(call_env_parsed_t) + sizeof(tmpl_t)) * count + vallen * 2));
+ (sizeof(call_env_parsed_t) + sizeof(tmpl_t)) * count + names_len * 2));
call_env_parsed_init(&xi->call_env_parsed);
if (call_env_parse(xi->call_env_ctx, &xi->call_env_parsed, call->func->mctx->inst->name,
call->dict, call->func->mctx->inst->conf, call_env->env) < 0) {
xlat_input_type_t input_type; //!< Type of input used.
xlat_arg_parser_t const *args; //!< Definition of args consumed.
- call_method_env_t const *call_env; //!< Optional tmpl expansions performed before calling the
+ call_env_method_t const *call_env; //!< Optional tmpl expansions performed before calling the
///< xlat. Typically used for xlats which refer to tmpls
///< in their module config.
#include <freeradius-devel/server/rcode.h>
#include <freeradius-devel/util/debug.h>
#include <freeradius-devel/unlang/xlat_func.h>
+#include <freeradius-devel/unlang/call_env.h>
#include "rlm_cache.h"
fr_value_box_t *key;
} cache_call_env_t;
-static const call_method_env_t cache_common_env = {
- .inst_size = sizeof(cache_call_env_t),
- .inst_type = "cache_call_env_t",
- .env = (call_env_t[]) {
+static const call_env_method_t cache_method_env = {
+ FR_CALL_ENV_METHOD_OUT(cache_call_env_t),
+ .env = (call_env_parser_t[]) {
{ FR_CALL_ENV_OFFSET("key", FR_TYPE_STRING, cache_call_env_t, key,
NULL, T_INVALID, true, false, true) },
CALL_ENV_TERMINATOR
*/
xlat = xlat_func_register_module(inst, mctx, mctx->inst->name, cache_xlat, FR_TYPE_VOID);
xlat_func_args_set(xlat, cache_xlat_args);
- xlat_func_call_env_set(xlat, &cache_common_env);
+ xlat_func_call_env_set(xlat, &cache_method_env);
return 0;
}
.detach = mod_detach
},
.method_names = (module_method_name_t[]){
- { .name1 = "status", .name2 = CF_IDENT_ANY, .method = mod_method_status, .method_env = &cache_common_env },
- { .name1 = "load", .name2 = CF_IDENT_ANY, .method = mod_method_load, .method_env = &cache_common_env },
- { .name1 = "store", .name2 = CF_IDENT_ANY, .method = mod_method_store, .method_env = &cache_common_env },
- { .name1 = "clear", .name2 = CF_IDENT_ANY, .method = mod_method_clear, .method_env = &cache_common_env },
- { .name1 = "ttl", .name2 = CF_IDENT_ANY, .method = mod_method_ttl, .method_env = &cache_common_env },
- { .name1 = CF_IDENT_ANY, .name2 = CF_IDENT_ANY, .method = mod_cache_it, .method_env = &cache_common_env },
+ { .name1 = "status", .name2 = CF_IDENT_ANY, .method = mod_method_status, .method_env = &cache_method_env },
+ { .name1 = "load", .name2 = CF_IDENT_ANY, .method = mod_method_load, .method_env = &cache_method_env },
+ { .name1 = "store", .name2 = CF_IDENT_ANY, .method = mod_method_store, .method_env = &cache_method_env },
+ { .name1 = "clear", .name2 = CF_IDENT_ANY, .method = mod_method_clear, .method_env = &cache_method_env },
+ { .name1 = "ttl", .name2 = CF_IDENT_ANY, .method = mod_method_ttl, .method_env = &cache_method_env },
+ { .name1 = CF_IDENT_ANY, .name2 = CF_IDENT_ANY, .method = mod_cache_it, .method_env = &cache_method_env },
MODULE_NAME_TERMINATOR
}
};
#include <freeradius-devel/server/module_rlm.h>
#include <freeradius-devel/util/chap.h>
#include <freeradius-devel/unlang/xlat_func.h>
+#include <freeradius-devel/unlang/call_env.h>
typedef struct {
fr_dict_enum_value_t *auth_type;
CONF_PARSER_TERMINATOR
};
-#define CHAP_CALL_ENV(_x) static const call_method_env_t chap_ ## _x ## _method_env = { \
- .inst_size = sizeof (chap_ ## _x ## _call_env_t), \
- .inst_type = "chap_" STRINGIFY(_x) "_call_env_t", \
- .env = _x ## _call_env \
-}
-
typedef struct {
fr_value_box_t chap_challenge;
} chap_xlat_call_env_t;
-static const call_env_t xlat_call_env[] = {
- { FR_CALL_ENV_OFFSET("chap_challenge", FR_TYPE_OCTETS | FR_TYPE_ATTRIBUTE, chap_xlat_call_env_t,
- chap_challenge, "&Chap-Challenge", T_BARE_WORD, true, true, true) },
- CALL_ENV_TERMINATOR
+static const call_env_method_t chap_xlat_method_env = { \
+ FR_CALL_ENV_METHOD_OUT(chap_xlat_call_env_t),
+ .env = (call_env_parser_t[]){
+ { FR_CALL_ENV_OFFSET("chap_challenge", FR_TYPE_OCTETS | FR_TYPE_ATTRIBUTE, chap_xlat_call_env_t,
+ chap_challenge, "&Chap-Challenge", T_BARE_WORD, true, true, true) },
+ CALL_ENV_TERMINATOR
+ }
};
-CHAP_CALL_ENV(xlat);
-
typedef struct {
fr_value_box_t chap_password;
fr_value_box_t chap_challenge;
tmpl_t *chap_challenge_tmpl;
} chap_autz_call_env_t;
-static const call_env_t autz_call_env[] = {
- { FR_CALL_ENV_OFFSET("chap_password", FR_TYPE_OCTETS | FR_TYPE_ATTRIBUTE, chap_autz_call_env_t,
- chap_password, "&Chap-Password", T_BARE_WORD, true, true, true) },
- { FR_CALL_ENV_TMPL_OFFSET("chap_challenge", FR_TYPE_OCTETS | FR_TYPE_ATTRIBUTE, chap_autz_call_env_t,
- chap_challenge, chap_challenge_tmpl, "&Chap-Challenge", T_BARE_WORD, true, true, true) },
- CALL_ENV_TERMINATOR
+static const call_env_method_t chap_autz_method_env = { \
+ FR_CALL_ENV_METHOD_OUT(chap_autz_call_env_t),
+ .env = (call_env_parser_t[]){
+ { FR_CALL_ENV_OFFSET("chap_password", FR_TYPE_OCTETS | FR_TYPE_ATTRIBUTE, chap_autz_call_env_t,
+ chap_password, "&Chap-Password", T_BARE_WORD, true, true, true) },
+ { FR_CALL_ENV_TMPL_OFFSET("chap_challenge", FR_TYPE_OCTETS | FR_TYPE_ATTRIBUTE, chap_autz_call_env_t,
+ chap_challenge, chap_challenge_tmpl, "&Chap-Challenge", T_BARE_WORD, true, true, true) },
+ CALL_ENV_TERMINATOR
+ }
};
-CHAP_CALL_ENV(autz);
-
typedef struct {
fr_value_box_t username;
fr_value_box_t chap_password;
fr_value_box_t chap_challenge;
} chap_auth_call_env_t;
-static const call_env_t auth_call_env[] = {
- { FR_CALL_ENV_OFFSET("username", FR_TYPE_STRING | FR_TYPE_ATTRIBUTE, chap_auth_call_env_t,
- username, "&User-Name", T_BARE_WORD, true, false, true) },
- { FR_CALL_ENV_OFFSET("chap_password", FR_TYPE_OCTETS | FR_TYPE_ATTRIBUTE, chap_auth_call_env_t,
- chap_password, "&Chap-Password", T_BARE_WORD, true, true, true) },
- { FR_CALL_ENV_OFFSET("chap_challenge", FR_TYPE_OCTETS | FR_TYPE_ATTRIBUTE, chap_auth_call_env_t,
- chap_challenge, "&Chap-Challenge", T_BARE_WORD, true, true, true) },
- CALL_ENV_TERMINATOR
+static const call_env_method_t chap_auth_method_env = { \
+ FR_CALL_ENV_METHOD_OUT(chap_auth_call_env_t),
+ .env = (call_env_parser_t[]){
+ { FR_CALL_ENV_OFFSET("username", FR_TYPE_STRING | FR_TYPE_ATTRIBUTE, chap_auth_call_env_t,
+ username, "&User-Name", T_BARE_WORD, true, false, true) },
+ { FR_CALL_ENV_OFFSET("chap_password", FR_TYPE_OCTETS | FR_TYPE_ATTRIBUTE, chap_auth_call_env_t,
+ chap_password, "&Chap-Password", T_BARE_WORD, true, true, true) },
+ { FR_CALL_ENV_OFFSET("chap_challenge", FR_TYPE_OCTETS | FR_TYPE_ATTRIBUTE, chap_auth_call_env_t,
+ chap_challenge, "&Chap-Challenge", T_BARE_WORD, true, true, true) },
+ CALL_ENV_TERMINATOR
+ }
};
-CHAP_CALL_ENV(auth);
-
static fr_dict_t const *dict_freeradius;
extern fr_dict_autoload_t rlm_chap_dict[];
#include <freeradius-devel/server/exec.h>
#include <freeradius-devel/server/main_config.h>
#include <freeradius-devel/unlang/interpret.h>
+#include <freeradius-devel/unlang/call_env.h>
#include <freeradius-devel/util/debug.h>
#include <freeradius-devel/server/pairmove.h>
#include <freeradius-devel/unlang/xlat_func.h>
#include <freeradius-devel/unlang/xlat.h>
#include <freeradius-devel/unlang/module.h>
+
/*
* Define a structure for our module configuration.
*/
tmpl_t *program;
} exec_call_env_t;
-static const call_env_t exec_call_env[] = {
- { FR_CALL_ENV_TMPL_ONLY_OFFSET("program", FR_TYPE_STRING, exec_call_env_t, program, NULL,
- T_BACK_QUOTED_STRING, false), .pair.force_quote = true },
- CALL_ENV_TERMINATOR
-};
-
-static const call_method_env_t exec_method_env = {
- .inst_size = sizeof(exec_call_env_t),
- .inst_type = "exec_call_env_t",
- .env = exec_call_env
+static const call_env_method_t exec_method_env = {
+ FR_CALL_ENV_METHOD_OUT(exec_call_env_t),
+ .env = (call_env_parser_t[]){
+ { FR_CALL_ENV_TMPL_ONLY_OFFSET("program", FR_TYPE_STRING, exec_call_env_t, program, NULL,
+ T_BACK_QUOTED_STRING, false), .pair.force_quote = true },
+ CALL_ENV_TERMINATOR
+ }
};
static xlat_action_t exec_xlat_oneshot_wait_resume(TALLOC_CTX *ctx, fr_dcursor_t *out,
#include <freeradius-devel/server/pairmove.h>
#include <freeradius-devel/server/users_file.h>
#include <freeradius-devel/util/htrie.h>
+#include <freeradius-devel/unlang/call_env.h>
#include <ctype.h>
#include <fcntl.h>
* @todo - Whilst this causes `key` to be evaluated on a per-call basis,
* it is still evaluated during module instantiation to determine the tree type in use
* so more restructuring is needed to make the module protocol agnostic.
+ *
+ * Or we need to regenerate the tree on every call.
*/
-static const call_env_t call_env[] = {
- { FR_CALL_ENV_OFFSET("key", FR_TYPE_VOID, rlm_files_env_t, key, "%{%{Stripped-User-Name}:-%{User-Name}}",
- T_DOUBLE_QUOTED_STRING, true, false, false) },
- CALL_ENV_TERMINATOR
-};
-
-static const call_method_env_t method_env = {
- .inst_size = sizeof(rlm_files_env_t),
- .inst_type = "rlm_files_env_t",
- .env = call_env
+static const call_env_method_t method_env = {
+ FR_CALL_ENV_METHOD_OUT(rlm_files_env_t),
+ .env = (call_env_parser_t[]){
+ { FR_CALL_ENV_OFFSET("key", FR_TYPE_VOID, rlm_files_env_t, key, "%{%{Stripped-User-Name} || %{User-Name}}",
+ T_DOUBLE_QUOTED_STRING, true, false, false) },
+ CALL_ENV_TERMINATOR
+ },
};
/* globally exported name */
#include <freeradius-devel/server/map_proc.h>
#include <freeradius-devel/server/module_rlm.h>
+#include <freeradius-devel/unlang/call_env.h>
#include <freeradius-devel/unlang/xlat_func.h>
#include <freeradius-devel/unlang/action.h>
#include <freeradius-devel/unlang/xlat.h>
fr_value_box_t profile_filter; //!< Filter to use when searching for users.
} ldap_xlat_profile_call_env_t;
-static const call_env_t sasl_call_env[] = {
+static const call_env_parser_t sasl_call_env[] = {
{ FR_CALL_ENV_OFFSET("mech", FR_TYPE_STRING, ldap_auth_call_env_t, user_sasl_mech,
NULL, T_INVALID, false, false, false) },
{ FR_CALL_ENV_OFFSET("authname", FR_TYPE_STRING, ldap_auth_call_env_t, user_sasl_authname,
CONF_PARSER_TERMINATOR
};
-static const call_env_t autz_profile_call_env[] = {
+static const call_env_parser_t autz_profile_call_env[] = {
{ FR_CALL_ENV_OFFSET("default", FR_TYPE_STRING, ldap_autz_call_env_t, default_profile,
NULL, T_INVALID, false, false, true) },
{ FR_CALL_ENV_OFFSET("filter", FR_TYPE_STRING, ldap_autz_call_env_t, profile_filter,
};
#define user_call_env(_prefix, _struct, ...) \
-static const call_env_t _prefix ## _user_call_env[] = { \
+static const call_env_parser_t _prefix ## _user_call_env[] = { \
{ FR_CALL_ENV_OFFSET("base_dn", FR_TYPE_STRING, _struct, user_base, \
"", T_SINGLE_QUOTED_STRING, true, false, true) }, \
{ FR_CALL_ENV_OFFSET("filter", FR_TYPE_STRING, _struct, user_filter, \
CONF_PARSER_TERMINATOR
};
-static const call_env_t autz_group_call_env[] = {
+static const call_env_parser_t autz_group_call_env[] = {
{ FR_CALL_ENV_OFFSET("base_dn", FR_TYPE_STRING, ldap_autz_call_env_t, group_base,
NULL, T_INVALID, false, false, true) },
CALL_ENV_TERMINATOR
};
-static const call_env_t memberof_group_call_env[] = {
+static const call_env_parser_t memberof_group_call_env[] = {
{ FR_CALL_ENV_OFFSET("base_dn", FR_TYPE_STRING, ldap_xlat_memberof_call_env_t, group_base,
NULL, T_INVALID, false, false, true) },
CALL_ENV_TERMINATOR
CONF_PARSER_TERMINATOR
};
-static const call_method_env_t authenticate_method_env = {
- .inst_size = sizeof(ldap_auth_call_env_t),
- .inst_type = "ldap_auth_call_env_t",
- .env = (call_env_t[]) {
+static const call_env_method_t authenticate_method_env = {
+ FR_CALL_ENV_METHOD_OUT(ldap_auth_call_env_t),
+ .env = (call_env_parser_t[]) {
{ FR_CALL_ENV_SUBSECTION("user", NULL, auth_user_call_env, true) },
CALL_ENV_TERMINATOR
}
};
-static const call_method_env_t authorize_method_env = {
- .inst_size = sizeof(ldap_autz_call_env_t),
- .inst_type = "ldap_autz_call_env_t",
- .env = (call_env_t[]) {
+static const call_env_method_t authorize_method_env = {
+ FR_CALL_ENV_METHOD_OUT(ldap_autz_call_env_t),
+ .env = (call_env_parser_t[]) {
{ FR_CALL_ENV_SUBSECTION("user", NULL, autz_user_call_env, true) },
{ FR_CALL_ENV_SUBSECTION("group", NULL, autz_group_call_env, false) },
{ FR_CALL_ENV_SUBSECTION("profile", NULL, autz_profile_call_env, false) },
}
};
-static const call_method_env_t usermod_method_env = {
- .inst_size = sizeof(ldap_usermod_call_env_t),
- .inst_type = "ldap_usermod_call_env_t",
- .env = (call_env_t[]) {
+static const call_env_method_t usermod_method_env = {
+ FR_CALL_ENV_METHOD_OUT(ldap_usermod_call_env_t),
+ .env = (call_env_parser_t[]) {
{ FR_CALL_ENV_SUBSECTION("user", NULL, usermod_user_call_env, true) },
CALL_ENV_TERMINATOR
}
};
-static const call_method_env_t xlat_memberof_method_env = {
- .inst_size = sizeof(ldap_xlat_memberof_call_env_t),
- .inst_type = "ldap_xlat_memberof_call_env_t",
- .env = (call_env_t[]) {
+static const call_env_method_t xlat_memberof_method_env = {
+ FR_CALL_ENV_METHOD_OUT(ldap_xlat_memberof_call_env_t),
+ .env = (call_env_parser_t[]) {
{ FR_CALL_ENV_SUBSECTION("user", NULL, memberof_user_call_env, true) },
{ FR_CALL_ENV_SUBSECTION("group", NULL, memberof_group_call_env, false) },
CALL_ENV_TERMINATOR
}
};
-static const call_method_env_t xlat_profile_method_env = {
- .inst_size = sizeof(ldap_xlat_profile_call_env_t),
- .inst_type = "ldap_xlat_profile_call_env_t",
- .env = (call_env_t[]) {
+static const call_env_method_t xlat_profile_method_env = {
+ FR_CALL_ENV_METHOD_OUT(ldap_xlat_profile_call_env_t),
+ .env = (call_env_parser_t[]) {
{ FR_CALL_ENV_SUBSECTION("profile", NULL,
- ((call_env_t[]) {
+ ((call_env_parser_t[]) {
{ FR_CALL_ENV_OFFSET("filter", FR_TYPE_STRING, ldap_xlat_profile_call_env_t, profile_filter,
"(&)", T_SINGLE_QUOTED_STRING, false, false, true ) }, //!< Correct filter for when the DN is known.
CALL_ENV_TERMINATOR
*/
/* MPPE support from Takahiro Wagatsuma <waga@sic.shibaura-it.ac.jp> */
+
RCSID("$Id$")
#define LOG_PREFIX mctx->inst->name
#include <freeradius-devel/util/misc.h>
#include <freeradius-devel/util/sha1.h>
+#include <freeradius-devel/unlang/call_env.h>
#include <freeradius-devel/unlang/xlat_func.h>
#include <sys/wait.h>
CONF_PARSER_TERMINATOR
};
-#define MSCHAP_CALL_ENV(_x) static const call_env_t _x ## _attr_call_env[] = { \
- { FR_CALL_ENV_SUBSECTION("attributes", NULL, _x ## _call_env, true) }, \
- CALL_ENV_TERMINATOR \
-}; \
-static const call_method_env_t mschap_ ## _x ## _method_env = { \
- .inst_size = sizeof(mschap_ ## _x ## _call_env_t), \
- .inst_type = "mschap_" STRINGIFY(_x) "_call_env_t", \
- .env = _x ## _attr_call_env \
+#define MSCHAP_CALL_ENV(_x) \
+static const call_env_method_t mschap_ ## _x ## _method_env = { \
+ FR_CALL_ENV_METHOD_OUT(mschap_ ## _x ## _call_env_t), \
+ .env = (call_env_parser_t[]){ \
+ { FR_CALL_ENV_SUBSECTION("attributes", NULL, _x ## _call_env, true) }, \
+ CALL_ENV_TERMINATOR \
+ } \
}
#define MSCHAP_COMMON_CALL_ENV(_x) \
tmpl_t const *chap2_response;
} mschap_xlat_call_env_t;
-static const call_env_t xlat_call_env[] = {
+static const call_env_parser_t xlat_call_env[] = {
{ FR_CALL_ENV_TMPL_ONLY_OFFSET("username", FR_TYPE_STRING | FR_TYPE_ATTRIBUTE, mschap_xlat_call_env_t,
username, "&User-Name", T_BARE_WORD, true) },
MSCHAP_COMMON_CALL_ENV(xlat),
MSCHAP_CALL_ENV(xlat);
-static const call_env_t auth_call_env[] = {
+static const call_env_parser_t auth_call_env[] = {
{ FR_CALL_ENV_TMPL_ONLY_OFFSET("username", FR_TYPE_STRING | FR_TYPE_ATTRIBUTE, mschap_auth_call_env_t,
username, "&User-Name", T_BARE_WORD, true) },
MSCHAP_COMMON_CALL_ENV(auth),
tmpl_t const *chap2_cpw;
} mschap_autz_call_env_t;
-static const call_env_t autz_call_env[] = {
+static const call_env_parser_t autz_call_env[] = {
MSCHAP_COMMON_CALL_ENV(autz),
MSCHAP_OPT_CALL_ENV(chap2_cpw, autz),
CALL_ENV_TERMINATOR
#include <freeradius-devel/util/md5.h>
#include <freeradius-devel/util/sha1.h>
+#include <freeradius-devel/unlang/call_env.h>
+
#include <freeradius-devel/protocol/freeradius/freeradius.internal.password.h>
#include <ctype.h>
tmpl_t *password_tmpl;
} pap_call_env_t;
-static const call_env_t pap_call_env[] = {
- { FR_CALL_ENV_TMPL_OFFSET("password_attribute", FR_TYPE_STRING | FR_TYPE_ATTRIBUTE, pap_call_env_t, password,
- password_tmpl, "&User-Password", T_BARE_WORD, true, true, true) },
-
- CALL_ENV_TERMINATOR
-};
-
-static const call_method_env_t pap_method_env = {
+static const call_env_method_t pap_method_env = {
.inst_size = sizeof(pap_call_env_t),
.inst_type = "pap_call_env_t",
- .env = pap_call_env
+ .env = (call_env_parser_t[]) {
+ { FR_CALL_ENV_TMPL_OFFSET("password_attribute", FR_TYPE_STRING | FR_TYPE_ATTRIBUTE, pap_call_env_t, password,
+ password_tmpl, "&User-Password", T_BARE_WORD, true, true, true) },
+ CALL_ENV_TERMINATOR
+ }
};
static fr_dict_t const *dict_freeradius;
* @copyright 2015 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
* @copyright 2015 The FreeRADIUS server project
*/
-
RCSID("$Id$")
#include <freeradius-devel/server/base.h>
#include <freeradius-devel/redis/base.h>
#include <freeradius-devel/redis/cluster.h>
+
+#include <freeradius-devel/unlang/call_env.h>
+
#include "redis_ippool.h"
/** rlm_redis module instance
///< Option 82 gateway. Used for bulk lease cleanups.
} redis_ippool_bulk_release_call_env_t;
-
-static const call_env_t redis_ippool_alloc_call_env[] = {
- { FR_CALL_ENV_OFFSET("pool_name", FR_TYPE_STRING, redis_ippool_alloc_call_env_t, pool_name,
- NULL, T_INVALID, true, false, true) },
- { FR_CALL_ENV_OFFSET("owner", FR_TYPE_STRING, redis_ippool_alloc_call_env_t, owner,
- NULL, T_INVALID, true, false, true) },
- { FR_CALL_ENV_OFFSET("gateway", FR_TYPE_STRING, redis_ippool_alloc_call_env_t, gateway_id,
- "", T_SINGLE_QUOTED_STRING, false, true, true ) },
- { FR_CALL_ENV_OFFSET("offer_time", FR_TYPE_UINT32, redis_ippool_alloc_call_env_t, offer_time,
- NULL, T_INVALID, false, false, false) },
- { FR_CALL_ENV_OFFSET("lease_time", FR_TYPE_UINT32, redis_ippool_alloc_call_env_t, lease_time,
- NULL, T_INVALID, true, false, false) },
- { FR_CALL_ENV_OFFSET("requested_address", FR_TYPE_STRING, redis_ippool_alloc_call_env_t, requested_address,
- "%{%{Requested-IP-Address}:-%{Net.Src.IP}}", T_DOUBLE_QUOTED_STRING,
- true, true, false) },
- { FR_CALL_ENV_TMPL_ONLY_OFFSET("allocated_address_attr", FR_TYPE_ATTRIBUTE, redis_ippool_alloc_call_env_t,
- allocated_address_attr, NULL, T_INVALID, true ) },
- { FR_CALL_ENV_TMPL_ONLY_OFFSET("range_attr", FR_TYPE_ATTRIBUTE, redis_ippool_alloc_call_env_t,
- range_attr, "&reply.IP-Pool.Range", T_BARE_WORD, true) },
- { FR_CALL_ENV_TMPL_ONLY_OFFSET("expiry_attr", FR_TYPE_ATTRIBUTE, redis_ippool_alloc_call_env_t,
- expiry_attr, NULL, T_INVALID, false) },
- CALL_ENV_TERMINATOR
-};
-
-static const call_env_t redis_ippool_update_call_env[] = {
- { FR_CALL_ENV_OFFSET("pool_name", FR_TYPE_STRING, redis_ippool_update_call_env_t, pool_name,
- NULL, T_INVALID, true, false, true) },
- { FR_CALL_ENV_OFFSET("owner", FR_TYPE_STRING, redis_ippool_update_call_env_t, owner,
- NULL, T_INVALID, true, false, true) },
- { FR_CALL_ENV_OFFSET("gateway", FR_TYPE_STRING, redis_ippool_update_call_env_t, gateway_id,
- "", T_SINGLE_QUOTED_STRING, false, true, true ) },
- { FR_CALL_ENV_OFFSET("lease_time", FR_TYPE_UINT32, redis_ippool_update_call_env_t, lease_time,
- NULL, T_INVALID, true, false, false) },
- { FR_CALL_ENV_OFFSET("requested_address", FR_TYPE_STRING, redis_ippool_update_call_env_t, requested_address,
- "%{%{Requested-IP-Address}:-%{Net.Src.IP}}", T_DOUBLE_QUOTED_STRING,
- true, true, false) },
- { FR_CALL_ENV_TMPL_ONLY_OFFSET("allocated_address_attr", FR_TYPE_ATTRIBUTE, redis_ippool_update_call_env_t,
- allocated_address_attr, NULL, T_INVALID, true ) },
- { FR_CALL_ENV_TMPL_ONLY_OFFSET("range_attr", FR_TYPE_ATTRIBUTE, redis_ippool_update_call_env_t,
- range_attr, "&reply.IP-Pool.Range", T_BARE_WORD, true) },
- { FR_CALL_ENV_TMPL_ONLY_OFFSET("expiry_attr", FR_TYPE_ATTRIBUTE, redis_ippool_update_call_env_t,
- expiry_attr, NULL, T_INVALID, false) },
- CALL_ENV_TERMINATOR
-};
-
-static const call_env_t redis_ippool_release_call_env[] = {
- { FR_CALL_ENV_OFFSET("pool_name", FR_TYPE_STRING, redis_ippool_release_call_env_t, pool_name,
- NULL, T_INVALID, true, false, true) },
- { FR_CALL_ENV_OFFSET("owner", FR_TYPE_STRING, redis_ippool_release_call_env_t, owner,
- NULL, T_INVALID, true, false, true) },
- { FR_CALL_ENV_OFFSET("gateway", FR_TYPE_STRING, redis_ippool_release_call_env_t, gateway_id,
- "", T_SINGLE_QUOTED_STRING, false, true, true ) },
- { FR_CALL_ENV_OFFSET("requested_address", FR_TYPE_STRING, redis_ippool_release_call_env_t, requested_address,
- "%{%{Requested-IP-Address}:-%{Net.Src.IP}}", T_DOUBLE_QUOTED_STRING,
- true, true, false) },
- CALL_ENV_TERMINATOR
-};
-
-static const call_env_t redis_ippool_bulk_release_call_env[] = {
- { FR_CALL_ENV_OFFSET("pool_name", FR_TYPE_STRING, redis_ippool_bulk_release_call_env_t, pool_name,
- NULL, T_INVALID, true, false, true) },
- { FR_CALL_ENV_OFFSET("gateway", FR_TYPE_STRING, redis_ippool_bulk_release_call_env_t, gateway_id,
- "", T_SINGLE_QUOTED_STRING, false, true, true ) },
- CALL_ENV_TERMINATOR
-};
-
-static const call_method_env_t redis_ippool_alloc_method_env = {
- .inst_size = sizeof(redis_ippool_alloc_call_env_t),
- .inst_type = "redis_ippool_alloc_call_env_t",
- .env = redis_ippool_alloc_call_env
+static const call_env_method_t redis_ippool_alloc_method_env = {
+ FR_CALL_ENV_METHOD_OUT(redis_ippool_alloc_call_env_t),
+ .env = (call_env_parser_t[]){
+ { FR_CALL_ENV_OFFSET("pool_name", FR_TYPE_STRING, redis_ippool_alloc_call_env_t, pool_name,
+ NULL, T_INVALID, true, false, true) },
+ { FR_CALL_ENV_OFFSET("owner", FR_TYPE_STRING, redis_ippool_alloc_call_env_t, owner,
+ NULL, T_INVALID, true, false, true) },
+ { FR_CALL_ENV_OFFSET("gateway", FR_TYPE_STRING, redis_ippool_alloc_call_env_t, gateway_id,
+ "", T_SINGLE_QUOTED_STRING, false, true, true ) },
+ { FR_CALL_ENV_OFFSET("offer_time", FR_TYPE_UINT32, redis_ippool_alloc_call_env_t, offer_time,
+ NULL, T_INVALID, false, false, false) },
+ { FR_CALL_ENV_OFFSET("lease_time", FR_TYPE_UINT32, redis_ippool_alloc_call_env_t, lease_time,
+ NULL, T_INVALID, true, false, false) },
+ { FR_CALL_ENV_OFFSET("requested_address", FR_TYPE_STRING, redis_ippool_alloc_call_env_t, requested_address,
+ "%{%{Requested-IP-Address} || %{Net.Src.IP}}", T_DOUBLE_QUOTED_STRING,
+ true, true, false) },
+ { FR_CALL_ENV_TMPL_ONLY_OFFSET("allocated_address_attr", FR_TYPE_ATTRIBUTE, redis_ippool_alloc_call_env_t,
+ allocated_address_attr, NULL, T_INVALID, true ) },
+ { FR_CALL_ENV_TMPL_ONLY_OFFSET("range_attr", FR_TYPE_ATTRIBUTE, redis_ippool_alloc_call_env_t,
+ range_attr, "&reply.IP-Pool.Range", T_BARE_WORD, true) },
+ { FR_CALL_ENV_TMPL_ONLY_OFFSET("expiry_attr", FR_TYPE_ATTRIBUTE, redis_ippool_alloc_call_env_t,
+ expiry_attr, NULL, T_INVALID, false) },
+ CALL_ENV_TERMINATOR
+ }
};
-static const call_method_env_t redis_ippool_update_method_env = {
- .inst_size = sizeof(redis_ippool_update_call_env_t),
- .inst_type = "redis_ippool_update_call_env_t",
- .env = redis_ippool_update_call_env
+static const call_env_method_t redis_ippool_update_method_env = {
+ FR_CALL_ENV_METHOD_OUT(redis_ippool_update_call_env_t),
+ .env = (call_env_parser_t[]) {
+ { FR_CALL_ENV_OFFSET("pool_name", FR_TYPE_STRING, redis_ippool_update_call_env_t, pool_name,
+ NULL, T_INVALID, true, false, true) },
+ { FR_CALL_ENV_OFFSET("owner", FR_TYPE_STRING, redis_ippool_update_call_env_t, owner,
+ NULL, T_INVALID, true, false, true) },
+ { FR_CALL_ENV_OFFSET("gateway", FR_TYPE_STRING, redis_ippool_update_call_env_t, gateway_id,
+ "", T_SINGLE_QUOTED_STRING, false, true, true ) },
+ { FR_CALL_ENV_OFFSET("lease_time", FR_TYPE_UINT32, redis_ippool_update_call_env_t, lease_time,
+ NULL, T_INVALID, true, false, false) },
+ { FR_CALL_ENV_OFFSET("requested_address", FR_TYPE_STRING, redis_ippool_update_call_env_t, requested_address,
+ "%{%{Requested-IP-Address} || %{Net.Src.IP}}", T_DOUBLE_QUOTED_STRING,
+ true, true, false) },
+ { FR_CALL_ENV_TMPL_ONLY_OFFSET("allocated_address_attr", FR_TYPE_ATTRIBUTE, redis_ippool_update_call_env_t,
+ allocated_address_attr, NULL, T_INVALID, true ) },
+ { FR_CALL_ENV_TMPL_ONLY_OFFSET("range_attr", FR_TYPE_ATTRIBUTE, redis_ippool_update_call_env_t,
+ range_attr, "&reply.IP-Pool.Range", T_BARE_WORD, true) },
+ { FR_CALL_ENV_TMPL_ONLY_OFFSET("expiry_attr", FR_TYPE_ATTRIBUTE, redis_ippool_update_call_env_t,
+ expiry_attr, NULL, T_INVALID, false) },
+ CALL_ENV_TERMINATOR
+ }
};
-static const call_method_env_t redis_ippool_release_method_env = {
- .inst_size = sizeof(redis_ippool_release_call_env_t),
- .inst_type = "redis_ippool_release_call_env_t",
- .env = redis_ippool_release_call_env
+static const call_env_method_t redis_ippool_release_method_env = {
+ FR_CALL_ENV_METHOD_OUT(redis_ippool_release_call_env_t),
+ .env = (call_env_parser_t[]) {
+ { FR_CALL_ENV_OFFSET("pool_name", FR_TYPE_STRING, redis_ippool_release_call_env_t, pool_name,
+ NULL, T_INVALID, true, false, true) },
+ { FR_CALL_ENV_OFFSET("owner", FR_TYPE_STRING, redis_ippool_release_call_env_t, owner,
+ NULL, T_INVALID, true, false, true) },
+ { FR_CALL_ENV_OFFSET("gateway", FR_TYPE_STRING, redis_ippool_release_call_env_t, gateway_id,
+ "", T_SINGLE_QUOTED_STRING, false, true, true ) },
+ { FR_CALL_ENV_OFFSET("requested_address", FR_TYPE_STRING, redis_ippool_release_call_env_t, requested_address,
+ "%{%{Requested-IP-Address} || %{Net.Src.IP}}", T_DOUBLE_QUOTED_STRING,
+ true, true, false) },
+ CALL_ENV_TERMINATOR
+ }
};
-static const call_method_env_t redis_ippool_bulk_release_method_env = {
- .inst_size = sizeof(redis_ippool_bulk_release_call_env_t),
- .inst_type = "redis_ippool_bulk_release_call_env_t",
- .env = redis_ippool_bulk_release_call_env
+static const call_env_method_t redis_ippool_bulk_release_method_env = {
+ FR_CALL_ENV_METHOD_OUT(redis_ippool_bulk_release_call_env_t),
+ .env = (call_env_parser_t[]) {
+ { FR_CALL_ENV_OFFSET("pool_name", FR_TYPE_STRING, redis_ippool_bulk_release_call_env_t, pool_name,
+ NULL, T_INVALID, true, false, true) },
+ { FR_CALL_ENV_OFFSET("gateway", FR_TYPE_STRING, redis_ippool_bulk_release_call_env_t, gateway_id,
+ "", T_SINGLE_QUOTED_STRING, false, true, true ) },
+ CALL_ENV_TERMINATOR
+ }
};
#define EOL "\n"
#include <freeradius-devel/server/tmpl_dcursor.h>
#include <freeradius-devel/util/slab.h>
+#include <freeradius-devel/unlang/call_env.h>
+
static fr_dict_t const *dict_radius; /*dictionary for radius protocol*/
static fr_dict_t const *dict_freeradius;
return 0;
}
-static const call_env_t call_env[] = {
- { FR_CALL_ENV_TMPL_OFFSET("username", FR_TYPE_STRING, rlm_smtp_env_t, username, username_tmpl, NULL,
- T_DOUBLE_QUOTED_STRING, false, true, true) },
- { FR_CALL_ENV_OFFSET("password", FR_TYPE_STRING, rlm_smtp_env_t, password, NULL,
- T_DOUBLE_QUOTED_STRING, false, true, true) },
- CALL_ENV_TERMINATOR
-};
-
-static const call_method_env_t method_env = {
- .inst_size = sizeof(rlm_smtp_env_t),
- .inst_type = "rlm_smtp_env_t",
- .env = call_env
+static const call_env_method_t method_env = {
+ FR_CALL_ENV_METHOD_OUT(rlm_smtp_env_t),
+ .env = (call_env_parser_t[]) {
+ { FR_CALL_ENV_TMPL_OFFSET("username", FR_TYPE_STRING, rlm_smtp_env_t, username, username_tmpl, NULL,
+ T_DOUBLE_QUOTED_STRING, false, true, true) },
+ { FR_CALL_ENV_OFFSET("password", FR_TYPE_STRING, rlm_smtp_env_t, password, NULL,
+ T_DOUBLE_QUOTED_STRING, false, true, true) },
+ CALL_ENV_TERMINATOR
+ }
};
/*
#include <freeradius-devel/unlang/interpret.h>
#include <freeradius-devel/util/base32.h>
+#include <freeradius-devel/unlang/call_env.h>
+
#include "totp.h"
typedef struct {
fr_value_box_t user_password;
} rlm_totp_call_env_t;
-static const call_env_t call_env[] = {
- { FR_CALL_ENV_OFFSET("secret", FR_TYPE_STRING, rlm_totp_call_env_t, secret,
- "&control.TOTP.Secret", T_BARE_WORD, false, true, false) },
-
- { FR_CALL_ENV_OFFSET("key", FR_TYPE_STRING, rlm_totp_call_env_t, key,
- "&control.TOTP.key", T_BARE_WORD, false, true, false) },
+static const call_env_method_t method_env = {
+ FR_CALL_ENV_METHOD_OUT(rlm_totp_call_env_t),
+ .env = (call_env_parser_t[]) {
+ { FR_CALL_ENV_OFFSET("secret", FR_TYPE_STRING, rlm_totp_call_env_t, secret,
+ "&control.TOTP.Secret", T_BARE_WORD, false, true, false) },
- { FR_CALL_ENV_OFFSET("user_password", FR_TYPE_STRING, rlm_totp_call_env_t, user_password,
- "&request.TOTP.From-User", T_BARE_WORD, false, true, false) },
+ { FR_CALL_ENV_OFFSET("key", FR_TYPE_STRING, rlm_totp_call_env_t, key,
+ "&control.TOTP.key", T_BARE_WORD, false, true, false) },
- CALL_ENV_TERMINATOR
-};
+ { FR_CALL_ENV_OFFSET("user_password", FR_TYPE_STRING, rlm_totp_call_env_t, user_password,
+ "&request.TOTP.From-User", T_BARE_WORD, false, true, false) },
-static const call_method_env_t method_env = {
- .inst_size = sizeof(rlm_totp_call_env_t),
- .inst_type = "rlm_totp_call_env_t",
- .env = call_env
+ CALL_ENV_TERMINATOR
+ }
};
/* Define a structure for the configuration variables */