26RCSIDH(call_env_h,
"$Id: cf86e6f38452907e4ca79eb0cc95edac6425397e $")
32#include <freeradius-devel/util/dlist.h>
41FR_DLIST_TYPEDEFS(call_env_parsed, call_env_parsed_head_t, call_env_parsed_entry_t)
43#include <freeradius-devel/util/value.h>
44#include <freeradius-devel/unlang/action.h>
45#include <freeradius-devel/server/cf_parse.h>
46#include <freeradius-devel/server/dl_module.h>
47#include <freeradius-devel/server/module.h>
48#include <freeradius-devel/server/request.h>
49#include <freeradius-devel/server/tmpl.h>
73typedef enum CC_HINT(flag_enum) {
106#define call_env_pair_flags(_flags) (((_flags) & (CALL_ENV_FLAG_SUBSECTION)) == 0)
112#define call_env_subsection_flags(_flags) (((_flags) & (CALL_ENV_FLAG_CONCAT | CALL_ENV_FLAG_SINGLE | CALL_ENV_FLAG_MULTI | CALL_ENV_FLAG_NULLABLE | CALL_ENV_FLAG_FORCE_QUOTE | CALL_ENV_FLAG_ATTRIBUTE | CALL_ENV_FLAG_PARSE_MISSING)) == 0)
114#define call_env_required(_flags) ((_flags) & CALL_ENV_FLAG_REQUIRED)
116#define call_env_concat(_flags) ((_flags) & CALL_ENV_FLAG_CONCAT)
118#define call_env_single(_flags) ((_flags) & CALL_ENV_FLAG_SINGLE)
120#define call_env_multi(_flags) ((_flags) & CALL_ENV_FLAG_MULTI)
122#define call_env_nullable(_flags) ((_flags) & CALL_ENV_FLAG_NULLABLE)
124#define call_env_force_quote(_flags) ((_flags) & CALL_ENV_FLAG_FORCE_QUOTE)
126#define call_env_parse_only(_flags) ((_flags) & CALL_ENV_FLAG_PARSE_ONLY)
128#define call_env_attribute(_flags) ((_flags) & CALL_ENV_FLAG_ATTRIBUTE)
130#define call_env_is_subsection(_flags) ((_flags) & CALL_ENV_FLAG_SUBSECTION)
132#define call_env_parse_missing(_flags) ((_flags) & CALL_ENV_FLAG_PARSE_MISSING)
134#define call_env_secret(_flags) ((_flags) & CALL_ENV_FLAG_SECRET)
136#define call_env_bare_word_attribute(_flags) ((_flags) & CALL_ENV_FLAG_BARE_WORD_ATTRIBUTE)
190 char const *type_name;
236#define CALL_ENV_TERMINATOR { NULL }
240#define FR_CALL_ENV_METHOD_OUT(_inst) \
241 .inst_size = sizeof(_inst), \
242 .inst_type = STRINGIFY(_inst) \
259#define CALL_ENV_PARSE_TYPE(_s, _f) \
260_Generic((((_s *)NULL)->_f), \
261 tmpl_t const * : CALL_ENV_PARSE_TYPE_TMPL, \
262 tmpl_t * : CALL_ENV_PARSE_TYPE_TMPL, \
263 fr_value_box_t const * : CALL_ENV_PARSE_TYPE_VALUE_BOX, \
264 fr_value_box_t * : CALL_ENV_PARSE_TYPE_VALUE_BOX, \
265 default : CALL_ENV_PARSE_TYPE_VOID \
270#define FR_CALL_ENV_SINGLE(_s, _f, _c) \
271_Generic((((_s *)NULL)->_f), \
272 fr_value_box_t : __builtin_choose_expr(_c, CALL_ENV_FLAG_NONE, CALL_ENV_FLAG_SINGLE), \
273 fr_value_box_t * : __builtin_choose_expr(_c, CALL_ENV_FLAG_NONE, CALL_ENV_FLAG_SINGLE), \
274 fr_value_box_list_t : CALL_ENV_FLAG_NONE, \
275 fr_value_box_list_t * : CALL_ENV_FLAG_NONE, \
276 default : CALL_ENV_FLAG_NONE \
281#define FR_CALL_ENV_MULTI(_s, _f) \
282_Generic((((_s *)NULL)->_f), \
283 fr_value_box_t : CALL_ENV_FLAG_NONE, \
284 fr_value_box_t * : CALL_ENV_FLAG_MULTI, \
285 fr_value_box_list_t : CALL_ENV_FLAG_NONE, \
286 fr_value_box_list_t * : CALL_ENV_FLAG_MULTI \
291#define FR_CALL_ENV_CONCAT(_c, _ct) \
292__builtin_choose_expr(_ct == FR_TYPE_STRING, _c, \
293__builtin_choose_expr(_ct == FR_TYPE_OCTETS, _c, \
294__builtin_choose_expr(_c, (void)0, false)))
298#define FR_CALL_ENV_DST_TYPE(_s, _f) \
299_Generic((((_s *)NULL)->_f), \
300 fr_value_box_t : CALL_ENV_RESULT_TYPE_VALUE_BOX, \
301 fr_value_box_t * : CALL_ENV_RESULT_TYPE_VALUE_BOX, \
302 fr_value_box_list_t : CALL_ENV_RESULT_TYPE_VALUE_BOX_LIST, \
303 fr_value_box_list_t * : CALL_ENV_RESULT_TYPE_VALUE_BOX_LIST \
306#define FR_CALL_ENV_DST_SIZE(_s, _f) \
307_Generic((((_s *)NULL)->_f), \
308 fr_value_box_t : sizeof(fr_value_box_t), \
309 fr_value_box_t * : sizeof(fr_value_box_t), \
310 fr_value_box_list_t : sizeof(fr_value_box_list_t), \
311 fr_value_box_list_t * : sizeof(fr_value_box_list_t), \
315#define FR_CALL_ENV_RESULT_TYPE_NAME(_s, _f) \
316_Generic((((_s *)NULL)->_f), \
317 fr_value_box_t : "fr_value_box_t", \
318 fr_value_box_t * : "fr_value_box_t", \
319 fr_value_box_list_t : "fr_value_box_list_t", \
320 fr_value_box_list_t * : "fr_value_box_list_t", \
326#define CALL_ENV_FLAGS(_cast_type, _flags, _struct, _field) \
327 (FR_CALL_ENV_CONCAT(((_flags) & CALL_ENV_FLAG_CONCAT), _cast_type) | \
328 FR_CALL_ENV_SINGLE(_struct, _field, ((_flags) & CALL_ENV_FLAG_CONCAT)) | \
329 FR_CALL_ENV_MULTI(_struct, _field) |\
330 ((_flags) & ~CALL_ENV_FLAG_CONCAT)) \
340#define FR_CALL_ENV_OFFSET(_name, _cast_type, _flags, _struct, _field) \
342 .flags = CALL_ENV_FLAGS(_cast_type, _flags, _struct, _field), \
344 .cast_type = _cast_type, \
345 .type = FR_CALL_ENV_DST_TYPE(_struct, _field), \
346 .size = FR_CALL_ENV_DST_SIZE(_struct, _field), \
347 .type_name = FR_CALL_ENV_RESULT_TYPE_NAME(_struct, _field), \
348 .offset = offsetof(_struct, _field), \
351 .type = CALL_ENV_PARSE_TYPE_TMPL \
365#define FR_CALL_ENV_PARSE_OFFSET(_name, _cast_type, _flags, _struct, _field, _parse_field) \
367 .flags = CALL_ENV_FLAGS(_cast_type, _flags, _struct, _field), \
369 .cast_type = _cast_type, \
370 .type = FR_CALL_ENV_DST_TYPE(_struct, _field), \
371 .size = FR_CALL_ENV_DST_SIZE(_struct, _field), \
372 .type_name = FR_CALL_ENV_RESULT_TYPE_NAME(_struct, _field), \
373 .offset = offsetof(_struct, _field), \
375 .offset = offsetof(_struct, _parse_field), \
376 .type = CALL_ENV_PARSE_TYPE(_struct, _parse_field) \
389#define FR_CALL_ENV_PARSE_ONLY_OFFSET(_name, _cast_type, _flags, _struct, _parse_field) \
391 .flags = (_flags) | CALL_ENV_FLAG_PARSE_ONLY, \
393 .cast_type = _cast_type, \
395 .offset = offsetof(_struct, _parse_field), \
396 .type = CALL_ENV_PARSE_TYPE(_struct, _parse_field) \
402#define FR_CALL_ENV_SUBSECTION(_name, _name2, _flags, _subcs ) \
404 .flags = CALL_ENV_FLAG_SUBSECTION | (_flags), \
412#define FR_CALL_ENV_SUBSECTION_FUNC(_name, _name2, _flags, _func) \
414 .flags = CALL_ENV_FLAG_SUBSECTION | (_flags), \
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
call_env_flags_t flags
Flags controlling parser behaviour.
int(* call_env_parse_section_t)(TALLOC_CTX *ctx, call_env_parsed_head_t *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, call_env_ctx_t const *cec, call_env_parser_t const *rule)
Callback for performing custom parsing of a CONF_SECTION.
call_env_ctx_type_t type
Type of callenv ctx.
@ CALL_ENV_CTX_TYPE_XLAT
The callenv is registered to an xlat.
@ CALL_ENV_CTX_TYPE_MODULE
The callenv is registered to a module method.
void call_env_parsed_free(call_env_parsed_head_t *parsed, call_env_parsed_t *ptr)
Remove a call_env_parsed_t from the list of parsed call envs.
char const * name
Of conf pair to pass to tmpl_tokenizer.
unlang_action_t call_env_expand(TALLOC_CTX *ctx, request_t *request, call_env_result_t *result, void **env_data, call_env_t const *call_env)
Initialise the expansion of a call environment.
call_env_result_type_t
What type of structure is produced by the evaluation phase.
@ CALL_ENV_RESULT_TYPE_VALUE_BOX_LIST
Output of the evaluation phase is a list of value boxes.
@ CALL_ENV_RESULT_TYPE_VALUE_BOX
Output of the evaluation phase is a single value box.
size_t inst_size
Size of per call env.
call_env_parser_t const * env
Parsing rules for call method env.
section_name_t const * asked
The actual name1/name2 that resolved to a module_method_binding_t.
call_env_t * call_env_alloc(TALLOC_CTX *ctx, char const *name, call_env_method_t const *call_env_method, tmpl_rules_t const *rules, CONF_SECTION *cs, call_env_ctx_t const *cec))
Given a call_env_method, parse all call_env_pair_t in the context of a specific call to an xlat or mo...
void const * uctx
User context for callback functions.
call_env_parsed_t * call_env_parsed_add(TALLOC_CTX *ctx, call_env_parsed_head_t *head, call_env_parser_t const *rule)
Allocate a new call_env_parsed_t structure and add it to the list of parsed call envs.
void call_env_parsed_set_multi_index(call_env_parsed_t *parsed, size_t count, size_t index)
Assign a count and index to a call_env_parsed_t.
char const * inst_type
Type of per call env.
void _mismatch_flags
Dummy type used to indicate bad flags.
@ CALL_ENV_FLAG_CONCAT
If the tmpl produced multiple boxes they should be concatenated.
@ CALL_ENV_FLAG_SUBSECTION
This is a subsection.
@ CALL_ENV_FLAG_SINGLE
If the tmpl produces more than one box this is an error.
@ CALL_ENV_FLAG_ATTRIBUTE
Tmpl MUST contain an attribute reference.
@ CALL_ENV_FLAG_FORCE_QUOTE
Force quote method when parsing tmpl.
@ CALL_ENV_FLAG_PARSE_ONLY
The result of parsing will not be evaluated at runtime.
@ CALL_ENV_FLAG_SECRET
The value is a secret, and should not be logged.
@ CALL_ENV_FLAG_MULTI
Multiple instances of the conf pairs are allowed.
@ CALL_ENV_FLAG_REQUIRED
Associated conf pair or section is required.
@ CALL_ENV_FLAG_PARSE_MISSING
If this subsection is missing, still parse it.
@ CALL_ENV_FLAG_BARE_WORD_ATTRIBUTE
bare words are treated as an attribute, but strings may be xlats.
@ CALL_ENV_FLAG_NULLABLE
Tmpl expansions are allowed to produce no output.
void call_env_parsed_set_data(call_env_parsed_t *parsed, void const *data)
Assign data to a call_env_parsed_t.
call_env_parsed_head_t parsed
The per call parsed call environment.
call_env_parse_type_t
What type of structure is produced by the parsing phase.
@ CALL_ENV_PARSE_TYPE_VALUE_BOX
Output of the parsing phase is a single value box (static data).
@ CALL_ENV_PARSE_TYPE_TMPL
Output of the parsing phase is a tmpl_t.
@ CALL_ENV_PARSE_TYPE_VOID
Output of the parsing phase is undefined (a custom structure).
void call_env_parsed_set_value(call_env_parsed_t *parsed, fr_value_box_t const *vb)
Assign a value box to a call_env_parsed_t.
module_instance_t const * mi
Module instance that the callenv is registered to.
int call_env_parse_pair(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, call_env_ctx_t const *cec, call_env_parser_t const *rule)
call_env_method_t const * method
The method this call env is for.
int(* call_env_parse_pair_t)(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, call_env_ctx_t const *cec, call_env_parser_t const *rule)
Callback for performing custom parsing of a CONF_PAIR.
void call_env_parsed_set_tmpl(call_env_parsed_t *parsed, tmpl_t const *tmpl)
Assign a tmpl to a call_env_parsed_t.
Structure containing both a talloc pool, a list of parsed call_env_pairs.
Common header for all CONF_* types.
A section grouping multiple CONF_PAIR.
#define FR_DLIST_TYPES(_name)
Define type specific wrapper structs for dlists.
#define FR_DLIST_TYPEDEFS(_name, _head, _entry)
Define friendly names for type specific dlist head and entry structures.
Optional arguments passed to vp_tmpl functions.
fr_aka_sim_id_type_t type
Escaping rules for tmpls.
uintptr_t fr_value_box_safe_for_t
Escaping that's been applied to a value box.
static size_t char ** out