26 RCSID(
"$Id: 4ce620fd72d54fafe0e94993d07a86eb0e9683ab $")
28 #include <freeradius-devel/server/module_rlm.h>
29 #include <freeradius-devel/unlang/xlat_priv.h>
30 #include <freeradius-devel/unlang/xlat.h>
31 #include <freeradius-devel/unlang/xlat_func.h>
46 xlat_t const *a = one, *b = two;
50 a_len = strlen(a->
name);
51 b_len = strlen(b->name);
53 ret =
CMP(a_len, b_len);
54 if (ret != 0)
return ret;
56 ret = memcmp(a->
name, b->name, a_len);
71 xlat_t const *a = one, *b = two;
73 return CMP((uintptr_t)a->
func, (uintptr_t)b->func);
136 if (ret != 0)
return ret;
139 if (ret != 0)
return ret;
142 if (ret != 0)
return ret;
145 if (ret != 0)
return ret;
148 if (ret != 0)
return ret;
169 for (arg_a_p = a, arg_b_p = b;
171 arg_a_p++, arg_b_p++) {
174 ret = xlat_arg_cmp_no_escape(arg_a_p, arg_b_p);
175 if (ret != 0)
return ret;
178 return CMP(arg_a_p, arg_b_p);
189 ERROR(
"%s: Invalid xlat name", __FUNCTION__);
228 ERROR(
"%s: Invalid xlat name", __FUNCTION__);
233 if ((len == 1) && (strchr(
"InscCdDeGHlmMStTY", *
name) != NULL))
goto invalid_name;
240 ERROR(
"%s: Invalid character '%c' in dynamic expansion name '%s'", __FUNCTION__,
name[
used],
name);
250 ERROR(
"%s: Cannot re-define internal expansion %s", __FUNCTION__,
name);
254 if (c->
func != func) {
255 ERROR(
"%s: Cannot change callback function for %s", __FUNCTION__,
name);
269 .return_type = return_type,
284 ERROR(
"%s: Failed inserting xlat registration for %s", __FUNCTION__, c->
name);
303 TALLOC_FREE(x->
mctx);
305 memcpy(our_mctx, mctx,
sizeof(*our_mctx));
319 "%s - concat type must be string or octets", x->
name))
return -1;
331 "Set required in the preceding entry", x->
name))
return -1;
368 bool seen_optional =
false;
375 "required arguments must be at the "
376 "start of the argument list"))
return -1;
378 seen_optional =
true;
491 char const *thread_inst_type,
size_t thread_inst_size,
528 (void) talloc_get_type_abort(c,
xlat_t);
543 if (!c->
mctx)
continue;
559 ERROR(
"%s: Failed to create tree", __FUNCTION__);
static int const char char buffer[256]
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
fr_dcursor_eval_t void const * uctx
#define fr_assert_fail(_msg,...)
Calls panic_action ifndef NDEBUG, else logs error.
#define fr_cond_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
@ FR_TYPE_OCTETS
Raw octets.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for instantiation calls.
static void thread_detach(UNUSED void *uctx)
Explicitly cleanup module/xlat resources.
static int thread_instantiate(TALLOC_CTX *ctx, fr_event_list_t *el, UNUSED void *uctx)
Create module and xlat per-thread instances.
void fr_rb_iter_delete_inorder(fr_rb_iter_inorder_t *iter)
Remove the current node from the tree.
void * fr_rb_iter_next_inorder(fr_rb_iter_inorder_t *iter)
Return the next node.
void * fr_rb_iter_init_inorder(fr_rb_iter_inorder_t *iter, fr_rb_tree_t *tree)
Initialise an in-order iterator.
uint32_t fr_rb_num_elements(fr_rb_tree_t *tree)
#define fr_rb_inline_talloc_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black that verifies elements are of a specific talloc type.
int fr_rb_replace(void **old, fr_rb_tree_t *tree, void const *data))
bool fr_rb_delete(fr_rb_tree_t *tree, void const *data)
void * fr_rb_find(fr_rb_tree_t const *tree, void const *data)
Iterator structure for in-order traversal of an rbtree.
The main red black tree structure.
static int instantiate(module_inst_ctx_t const *mctx)
size_t fr_sbuff_adv_past_allowed(fr_sbuff_t *sbuff, size_t len, bool const allowed[static UINT8_MAX+1], fr_sbuff_term_t const *tt)
Wind position past characters in the allowed set.
#define FR_SBUFF_IN(_start, _len_or_end)
#define fr_sbuff_used(_sbuff_or_marker)
char const * name
Instance name e.g. user_database.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
fr_aka_sim_id_type_t type
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
int talloc_link_ctx(TALLOC_CTX *parent, TALLOC_CTX *child)
Link two different parent and child contexts, so the child is freed before the parent.
fr_type_t type
Type to cast argument to.
int(* xlat_thread_detach_t)(xlat_thread_inst_ctx_t const *xctx)
xlat thread detach callback
int(* xlat_detach_t)(xlat_inst_ctx_t const *xctx)
xlat detach callback
void * uctx
Argument to pass to escape callback.
bool required
Argument must be present, and non-empty.
xlat_escape_func_t func
Function to handle tainted values.
xlat_arg_parser_variadic_t variadic
All additional boxes should be processed using this definition.
bool concat
Concat boxes together.
bool single
Argument must only contain a single box.
bool always_escape
Pass all arguments to escape function not just tainted ones.
@ XLAT_INPUT_ARGS
Ingests a number of arguments.
@ XLAT_INPUT_UNPROCESSED
No input argument processing.
xlat_action_t(* xlat_func_t)(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
xlat callback function
bool pure
has no external side effects, true for BOX, LITERAL, and some functions
int(* xlat_thread_instantiate_t)(xlat_thread_inst_ctx_t const *xctx)
Allocate new thread instance data for an xlat instance.
bool impure_func
xlat contains an impure function
int(* xlat_instantiate_t)(xlat_inst_ctx_t const *xctx)
Allocate new instance data for an xlat instance.
Definition for a single argument consumend by an xlat function.
static size_t char fr_sbuff_t size_t inlen
uintptr_t fr_value_box_safe_for_t
Escaping that's been applied to a value box.
static int _xlat_func_talloc_free(xlat_t *xlat)
Remove an xlat function from the function tree.
void xlat_purify_func_set(xlat_t *xlat, xlat_purify_t func)
Set a resolve routine for an xlat function.
void xlat_func_free(void)
static int8_t xlat_name_cmp(void const *one, void const *two)
Compare two xlat_t by the registered name.
void xlat_func_flags_set(xlat_t *x, xlat_func_flags_t flags)
Specify flags that alter the xlat's behaviour.
void xlat_func_resolve_set(xlat_t *xlat, xlat_resolve_t func)
Set a resolve routine for an xlat function.
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
xlat_t * xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function.
void xlat_func_call_env_set(xlat_t *x, call_env_method_t const *env_method)
Register call environment of an xlat.
void xlat_func_unregister_module(module_instance_t const *inst)
static fr_rb_tree_t * xlat_root
xlat_t * xlat_func_find(char const *in, ssize_t inlen)
void xlat_func_print_set(xlat_t *xlat, xlat_print_t func)
Set a print routine for an xlat function.
int8_t xlat_func_cmp(void const *one, void const *two)
Compare two xlat_t by the underlying function.
void _xlat_func_safe_for_set(xlat_t *xlat, fr_value_box_safe_for_t safe_for)
Set the escaped values for output boxes.
void xlat_mctx_set(xlat_t *x, module_inst_ctx_t const *mctx)
Associate a module calling ctx with the xlat.
static int xlat_arg_parser_validate(xlat_t *x, xlat_arg_parser_t const *arg, bool last)
Verify xlat arg specifications are valid.
void xlat_func_unregister(char const *name)
Unregister an xlat function.
void _xlat_func_thread_instantiate_set(xlat_t const *xlat, xlat_thread_instantiate_t thread_instantiate, char const *thread_inst_type, size_t thread_inst_size, xlat_thread_detach_t thread_detach, void *uctx)
Register an async xlat.
void _xlat_func_instantiate_set(xlat_t const *xlat, xlat_instantiate_t instantiate, char const *inst_type, size_t inst_size, xlat_detach_t detach, void *uctx)
Set global instantiation/detach callbacks.
static void _xlat_func_tree_free(void *xlat)
Callback for the rbtree to clear out any xlats still registered.
xlat_t * xlat_func_find_module(module_inst_ctx_t const *mctx, char const *name)
int(* xlat_purify_t)(xlat_exp_t *xlat, void *inst, request_t *request)
Custom function purify the result of an xlat function.
int(* xlat_resolve_t)(xlat_exp_t *xlat, void *inst, xlat_res_rules_t const *xr_rules)
Custom function to perform resolution of arguments.
fr_slen_t(* xlat_print_t)(fr_sbuff_t *in, xlat_exp_t const *self, void *inst, fr_sbuff_escape_rules_t const *e_rules)
Custom function to print xlat debug.
@ XLAT_FUNC_FLAG_INTERNAL
char const * name
Name of xlat function.
char const * thread_inst_type
C type of thread instance structure.
module_inst_ctx_t * mctx
Original module instantiation ctx if this xlat was registered by a module.
bool const xlat_func_chars[UINT8_MAX+1]
bool internal
If true, cannot be redefined.
xlat_func_t func
async xlat function (async unsafe).
xlat_instantiate_t instantiate
Instantiation function.
size_t thread_inst_size
Size of the thread instance data to pre-allocate.
xlat_detach_t detach
Destructor for when xlat instances are freed.
void * thread_uctx
uctx to pass to instantiation functions.
call_env_method_t const * call_env_method
Optional tmpl expansions performed before calling the xlat.
size_t inst_size
Size of instance data to pre-allocate.
xlat_arg_parser_t const * args
Definition of args consumed.
xlat_resolve_t resolve
function to call when resolving
xlat_thread_instantiate_t thread_instantiate
Thread instantiation function.
char const * inst_type
C type of instance structure.
xlat_input_type_t input_type
Type of input used.
fr_value_box_safe_for_t return_safe_for
Escaped value to set in output boxes.
xlat_thread_detach_t thread_detach
Destructor for when xlat thread instance data is freed.
xlat_purify_t purify
function to call when purifying the node.
xlat_flags_t flags
various flags
xlat_print_t print
function to call when printing
void * uctx
uctx to pass to instantiation functions.