29 RCSID(
"$Id: 7d9c49a868a34a5de1cfd267e1bfecc533d1f3ba $")
31 #include <freeradius-devel/server/exec.h>
32 #include <freeradius-devel/server/exec_legacy.h>
33 #include <freeradius-devel/server/map.h>
34 #include <freeradius-devel/server/paircmp.h>
35 #include <freeradius-devel/server/tmpl.h>
36 #include <freeradius-devel/server/tmpl_dcursor.h>
38 #include <freeradius-devel/unlang/interpret.h>
40 #include <freeradius-devel/util/debug.h>
41 #include <freeradius-devel/util/base16.h>
42 #include <freeradius-devel/util/pair_legacy.h>
43 #include <freeradius-devel/util/misc.h>
45 #include <freeradius-devel/protocol/radius/rfc2865.h>
46 #include <freeradius-devel/protocol/freeradius/freeradius.internal.h>
62 RDEBUG2(
">>> MAP TYPES LHS: %s, RHS: %s",
67 RDEBUG2(
">>> MAP NAMES %s %s", map->
lhs->name, map->
rhs->name);
79 map = talloc_zero(ctx,
map_t);
83 map_list_init(&map->
child);
113 char const *attr, *
value, *marker_subject;
114 char *unescaped_value = NULL;
115 fr_sbuff_parse_rules_t
const *p_rules;
121 TALLOC_CTX *child_ctx = NULL;
141 if (!rhs_rules) rhs_rules = lhs_rules;
161 marker_subject = attr;
177 marker_subject = attr;
193 if (!input_rhs_rules) {
196 my_rhs_rules = *input_rhs_rules;
198 rhs_rules = &my_rhs_rules;
214 slen = fr_sbuff_out_aunescape_until(child_ctx, &unescaped_value,
215 &
FR_SBUFF_IN(
value, talloc_array_length(
value) - 1), SIZE_MAX, p_rules->terminals, p_rules->escapes);
217 marker_subject =
value;
220 value = unescaped_value;
233 slen = talloc_array_length(
value) - 1;
243 marker_subject =
value;
251 slen = talloc_array_length(
value) - 1;
262 my_rhs_rules.
enumv = NULL;
271 marker_subject =
value;
303 cast_type = da->type;
317 TALLOC_FREE(child_ctx);
324 TALLOC_FREE(child_ctx);
430 fr_sbuff_parse_rules_t
const *p_rules)
451 fr_sbuff_marker(&m_lhs, &our_in);
463 our_lhs_rules = *lhs_rules;
465 memset(&our_lhs_rules, 0,
sizeof(our_lhs_rules));
486 fr_strerror_const(
"Unexpected location for relative attribute - no parent attribute exists");
501 if (!
parent)
goto lhs_root;
531 fr_sbuff_marker(&m_op, &our_in);
553 fr_strerror_const(
"Comparison operators cannot be used inside of structural data types");
564 fr_sbuff_marker(&m_rhs, &our_in);
580 fr_strerror_const(
"Regular expressions cannot be used for structural attributes");
593 fr_strerror_const(
"Comparison operators cannot be used for structural attributes");
628 goto check_for_child;
656 if (!map->
rhs)
goto error_adj;
724 (void) talloc_steal(
parent, map);
726 map_list_insert_tail(&
parent->child, map);
753 unsigned int max,
bool update,
bool edit)
758 unsigned int total = 0;
760 TALLOC_CTX *parent_ctx;
763 TALLOC_CTX *tmp_ctx = NULL;
783 if (!p)
goto do_children;
790 cf_log_err(ci,
"Default request specified in mapping section is invalid");
798 cf_log_err(ci,
"Default list \"%s\" specified in mapping section is invalid", p);
815 if (total++ == max) {
823 map_list_talloc_reverse_free(
out);
835 map_list_t child_list;
837 map_list_init(&child_list);
864 cf_log_err(ci,
"Failed parsing attribute reference for list %s - %s",
875 cf_log_err(ci,
"Left side of group '%s' is NOT an attribute reference",
906 if (
dict !=
internal) {
909 child_lhs_rules.
attr.namespace = ref;
915 child_lhs_rules.
attr.namespace = NULL;
930 &child_lhs_rules, rhs_rules, validate,
uctx, max,
false, edit) < 0) {
931 map_list_talloc_free(&child_list);
935 map_list_move(&map->
child, &child_list);
942 cf_log_err(ci,
"Entry is not in \"attribute = value\" format");
965 our_rhs_rules = rhs_rules;
971 our_rhs_rules = &child_rhs_rules;
975 if (
map_afrom_cp(parent_ctx, &map,
parent, cp, &child_lhs_rules, our_rhs_rules, edit) < 0) {
976 cf_log_err(ci,
"Failed creating map from '%s = %s'",
986 if (validate && (validate(map,
uctx) < 0))
goto error;
990 map_list_insert_tail(
out, map);
1024 update = (name2 && (strcmp(name2,
"update") == 0));
1028 return _map_afrom_cs(ctx,
out,
parent, cs, lhs_rules, rhs_rules, validate,
uctx, max, update,
false);
1054 return _map_afrom_cs(ctx,
out,
parent, cs, lhs_rules, rhs_rules, validate,
uctx, max,
false,
true);
1080 char const *attr, *marker_subject;
1104 &
FR_SBUFF_IN(attr, talloc_array_length(attr) - 1),
1112 marker_subject = attr;
1134 if (slen <= 0)
goto marker;
1142 if (slen <= 0)
goto marker;
1173 unsigned int total = 0;
1175 TALLOC_CTX *parent_ctx;
1186 if (total++ == max) {
1193 map_list_talloc_reverse_free(
out);
1215 if (validate && (validate(map,
uctx) < 0))
goto error;
1218 map_list_insert_tail(
out, map);
1325 lhs_rules, rhs_rules, NULL) < 0) {
1368 if (!map->
lhs)
goto oom;
1382 if (!map->
lhs)
goto oom;
1384 switch (
vp->vp_type) {
1418 char *expanded = NULL;
1444 request, map->
rhs->name, input_pairs ? input_pairs : NULL,
1448 REDEBUG(
"Exec failed with code (%i)", result);
1453 switch (map->
lhs->type) {
1461 RPEDEBUG(
"Failed parsing exec output");
1544 for (child = map_list_next(&map->
child, NULL);
1546 child = map_list_next(&map->
child, child)) {
1555 if (
map_to_vp(
n, &list, request, child, NULL) < 0) {
1579 if (!from)
return 0;
1600 switch (map->
rhs->type) {
1676 RPEDEBUG(
"Attribute conversion failed");
1749 #define DEBUG_OVERWRITE(_old, _new) \
1751 if (RDEBUG_ENABLED3) {\
1754 fr_pair_aprint_value_quoted(request, &our_old, _old, T_DOUBLE_QUOTED_STRING); \
1755 fr_pair_aprint_value_quoted(request, &our_new, _new, T_DOUBLE_QUOTED_STRING); \
1757 RDEBUG3("--> overwriting %s with %s", our_old, our_new); \
1759 talloc_free(our_old); \
1760 talloc_free(our_new); \
1803 tmp_ctx = talloc_pool(request, 1024);
1808 switch (map->
lhs->type) {
1827 slen =
tmpl_aexpand(request, &attr_str, request, map->
lhs, NULL, NULL);
1829 RPEDEBUG(
"Left side expansion failed");
1838 .dict_def = request->dict,
1844 RPEDEBUG(
"Left side expansion result \"%s\" is not an attribute reference", attr_str);
1851 memcpy(&exp_map, map,
sizeof(exp_map));
1852 exp_map.
lhs = exp_lhs;
1868 REDEBUG(
"Left side \"%.*s\" of map should be an attr or list but is an %s",
1869 (
int)map->
lhs->len, map->
lhs->name,
1877 RPEDEBUG(
"Mapping \"%.*s\" -> \"%.*s\" cannot be performed due to error in left side of map",
1878 (
int)map->
rhs->len, map->
rhs->name, (
int)map->
lhs->len, map->
lhs->name);
1886 REDEBUG(
"Mapping \"%.*s\" -> \"%.*s\" cannot be performed due to to invalid list qualifier \"%s\" in left side of map",
1887 (
int)map->
rhs->len, map->
rhs->name, (
int)map->
lhs->len, map->
lhs->name,
1903 rcode = func(
parent, &src_list, request, map, ctx);
1909 RDEBUG2(
"%.*s skipped: No values available", (
int)map->
lhs->len, map->
lhs->name);
1919 #ifndef WITH_VERIFY_PTR
1990 if (!dst)
goto finish;
2044 if (!found)
goto finish;
2066 if (!found)
goto finish;
2082 RDEBUG3(
"Refusing to overwrite (use :=)");
2166 ERROR(
"Not yet supported");
2258 else if (cmp < 0)
continue;
2330 fr_sbuff_terminate(
out);
2352 char *rhs = NULL, *
value = NULL;
2361 switch (map->
rhs->type) {
2382 switch (
vp->vp_type) {
2407 switch (map->
lhs->type) {
2440 char const *lhs,
char const *op_str,
char const *rhs,
2455 my_rules = *lhs_rules;
2456 lhs_rules = &my_rules;
2475 fr_strerror_const(
"Unexpected location for relative attribute - no parent attribute exists");
2483 while (*lhs ==
'.') {
2484 if (!
parent)
goto no_parent;
2495 fr_strerror_const(
"Comparison operators cannot be used inside of structural data types");
2500 fr_strerror_const(
"Invalid operator inside of structural data type - must be '='");
2544 my_rules = *rhs_rules;
2554 my_rules.
enumv = NULL;
2565 if (rhs[0] ==
'"') {
2569 }
else if (rhs[0] ==
'\'') {
2575 len = strlen(rhs + 1);
2577 if (rhs[1] != rhs[0]) {
2588 if (slen < 0)
goto error;
2599 }
else if (rhs[0] ==
'&') {
2606 my_rules.
enumv = NULL;
2609 if (slen <= 0)
goto error;
2632 if (slen <= 0)
goto error;
static int const char char buffer[256]
#define L(_str)
Helper for initialising arrays of string literals.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
Common header for all CONF_* types.
Configuration AVP similar to a fr_pair_t.
A section grouping multiple CONF_PAIR.
bool cf_item_is_pair(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_PAIR.
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
CONF_ITEM * cf_section_to_item(CONF_SECTION const *cs)
Cast a CONF_SECTION to a CONF_ITEM.
fr_token_t cf_pair_attr_quote(CONF_PAIR const *pair)
Return the value (lhs) quoting of a pair.
char const * cf_pair_attr(CONF_PAIR const *pair)
Return the attr of a CONF_PAIR.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
fr_token_t cf_pair_operator(CONF_PAIR const *pair)
Return the operator of a pair.
CONF_ITEM * cf_pair_to_item(CONF_PAIR const *cp)
Cast a CONF_PAIR to a CONF_ITEM.
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
fr_token_t cf_pair_value_quote(CONF_PAIR const *pair)
Return the value (rhs) quoting of a pair.
bool cf_item_is_section(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_SECTION.
fr_token_t cf_section_name2_quote(CONF_SECTION const *cs)
Return the quoting of the name2 identifier.
char const * cf_section_name1(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
#define cf_log_err(_cf, _fmt,...)
#define cf_log_perr(_cf, _fmt,...)
#define cf_item_next(_ci, _curr)
static void * fr_dcursor_remove(fr_dcursor_t *cursor)
Remove the current item.
return fr_dcursor_filter_next(cursor, eval, uctx)
fr_dcursor_eval_t void const * uctx
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
static void * fr_dcursor_head(fr_dcursor_t *cursor)
Rewind cursor to the start of the list.
static void * fr_dcursor_current(fr_dcursor_t *cursor)
Return the item the cursor current points to.
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
static char const * spaces
fr_dict_t const * fr_dict_by_da(fr_dict_attr_t const *da)
Attempt to locate the protocol dictionary containing an attribute.
fr_dict_t const * fr_dict_internal(void)
static fr_dict_attr_t const * fr_dict_attr_ref(fr_dict_attr_t const *da)
Return the reference associated with a group type attribute.
static void fr_dlist_talloc_free_head(fr_dlist_head_t *list_head)
Free the first item in the list.
static void fr_dlist_talloc_free(fr_dlist_head_t *head)
Free all items in a doubly linked list (with talloc)
static unsigned int fr_dlist_num_elements(fr_dlist_head_t const *head)
Return the number of elements in the dlist.
static void * fr_dlist_tail(fr_dlist_head_t const *list_head)
Return the TAIL item of a list or NULL if the list is empty.
static void fr_dlist_talloc_free_tail(fr_dlist_head_t *list_head)
Free the last item in the list.
static void * fr_dlist_head(fr_dlist_head_t const *list_head)
Return the HEAD item of a list or NULL if the list is empty.
#define fr_dlist_talloc_init(_head, _type, _field)
Initialise the head structure of a doubly linked list.
Head of a doubly linked list.
#define EXEC_TIMEOUT
Default wait time for exec calls (in seconds).
int radius_exec_program_legacy(char *out, size_t outlen, request_t *request, char const *cmd, fr_pair_list_t *input_pairs, bool exec_wait, bool shell_escape, fr_time_delta_t timeout)
Execute a program.
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define RPEDEBUG(fmt,...)
#define RINDENT()
Indent R* messages by one level.
static int _map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, map_t *parent, CONF_SECTION *cs, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, map_validate_t validate, void *uctx, unsigned int max, bool update, bool edit)
static int map_value_afrom_cp(TALLOC_CTX *ctx, map_t **out, map_t *parent, CONF_PAIR *cp, tmpl_rules_t const *t_rules)
Convert CONFIG_PAIR (which may contain refs) to map_t.
#define DEBUG_OVERWRITE(_old, _new)
int map_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, map_t const *map, UNUSED void *uctx)
Convert a map to a fr_pair_t.
int map_afrom_cs_edit(TALLOC_CTX *ctx, map_list_t *out, CONF_SECTION *cs, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, map_validate_t validate, void *uctx, unsigned int max)
Convert a config section into an attribute map for editing.
fr_table_num_sorted_t const map_assignment_op_table[]
fr_sbuff_parse_rules_t const map_parse_rules_bareword_quoted
static map_t * map_alloc(TALLOC_CTX *ctx, map_t *parent)
ssize_t map_afrom_substr(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, fr_sbuff_t *in, fr_table_num_sorted_t const *op_table, size_t op_table_len, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, fr_sbuff_parse_rules_t const *p_rules)
Parse sbuff into (which may contain refs) to map_t.
static int _map_list_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, map_t *parent, CONF_SECTION *cs, tmpl_rules_t const *t_rules, map_validate_t validate, void *uctx, unsigned int max)
int map_afrom_cp(TALLOC_CTX *ctx, map_t **out, map_t *parent, CONF_PAIR *cp, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *input_rhs_rules, bool edit)
Convert CONFIG_PAIR (which may contain refs) to map_t.
static fr_table_num_sorted_t const cond_quote_table[]
int map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, CONF_SECTION *cs, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, map_validate_t validate, void *uctx, unsigned int max)
Convert a config section into an attribute map.
int map_afrom_value_box(TALLOC_CTX *ctx, map_t **out, char const *lhs, fr_token_t lhs_quote, tmpl_rules_t const *lhs_rules, fr_token_t op, fr_value_box_t *rhs, bool steal_rhs_buffs)
Convert a value box to a map.
int map_afrom_vp(TALLOC_CTX *ctx, map_t **out, fr_pair_t *vp, tmpl_rules_t const *rules)
Convert a fr_pair_t into a map.
int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t func, void *ctx)
Convert map_t to fr_pair_t (s) and add them to a request_t.
static int map_exec_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, map_t const *map)
Process map which has exec as a src.
static size_t cond_quote_table_len
int map_list_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, CONF_SECTION *cs, tmpl_rules_t const *t_rules, map_validate_t validate, void *uctx, unsigned int max)
Convert a config section into a list of { a, b, c, d, ...
int map_afrom_attr_str(TALLOC_CTX *ctx, map_t **out, char const *vp_str, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules)
Convert a value pair string to valuepair map.
int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, request_t *request, char const *lhs, char const *op_str, char const *rhs, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules)
Convert a fr_pair_t into a map.
ssize_t map_print(fr_sbuff_t *out, map_t const *map)
Print a map to a string.
size_t map_assignment_op_table_len
fr_sbuff_parse_rules_t const * map_parse_rules_quoted[T_TOKEN_LAST]
void map_debug_log(request_t *request, map_t const *map, fr_pair_t const *vp)
void fr_canonicalize_error(TALLOC_CTX *ctx, char **sp, char **text, ssize_t slen, char const *fmt)
Canonicalize error strings, removing tabs, and generate spaces for error marker.
int(* radius_map_getvalue_t)(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, map_t const *map, void *uctx)
int(* map_validate_t)(map_t *map, void *ctx)
@ TMPL_ATTR_REF_PREFIX_NO
Attribute refs have no '&' prefix.
@ TMPL_ATTR_REF_PREFIX_AUTO
Attribute refs may have a '&' prefix.
@ TMPL_ATTR_REF_PREFIX_YES
Attribute refs must have '&' prefix.
fr_slen_t tmpl_print(fr_sbuff_t *out, tmpl_t const *vpt, tmpl_attr_prefix_t ar_prefix, fr_sbuff_escape_rules_t const *e_rules)
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_GROUP
A grouping of other attributes.
bool fr_pair_matches_da(void const *item, void const *uctx)
Evaluation function for matching if vp matches a given da.
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from)
Duplicate a list of pairs.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
int fr_pair_delete_by_child_num(fr_pair_list_t *list, fr_dict_attr_t const *parent, unsigned int attr)
Delete matching pairs from the specified list.
int fr_pair_value_copy(fr_pair_t *dst, fr_pair_t *src)
Copy the value from one pair to another.
int fr_pair_reinit_from_da(fr_pair_list_t *list, fr_pair_t *vp, fr_dict_attr_t const *da)
Re-initialise an attribute with a different da.
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp)
Copy a single valuepair.
int fr_pair_value_from_str(fr_pair_t *vp, char const *value, size_t inlen, fr_sbuff_unescape_rules_t const *uerules, bool tainted)
Convert string value to native attribute value.
int8_t fr_pair_cmp_by_da(void const *a, void const *b)
Order attributes by their da, and tag.
void fr_pair_list_move_op(fr_pair_list_t *to, fr_pair_list_t *from, fr_token_t op)
Move pairs from source list to destination list respecting operator.
int paircmp_pairs(UNUSED request_t *request, fr_pair_t const *check, fr_pair_t *vp)
Compares check and vp by value.
fr_dict_attr_t const * request_attr_request
fr_dict_attr_t const * request_attr_control
bool fr_sbuff_next_if_char(fr_sbuff_t *sbuff, char c)
Return true if the current char matches, and if it does, advance.
#define fr_sbuff_start(_sbuff_or_marker)
#define fr_sbuff_out_by_longest_prefix(_match_len, _out, _table, _sbuff, _def)
#define FR_SBUFF_IN_CHAR_RETURN(_sbuff,...)
#define fr_sbuff_set(_dst, _src)
#define FR_SBUFF_IN(_start, _len_or_end)
#define fr_sbuff_adv_past_whitespace(_sbuff, _len, _tt)
#define FR_SBUFF_TERMS(...)
Initialise a terminal structure with a list of sorted strings.
#define FR_SBUFF_RETURN(_func, _sbuff,...)
#define FR_SBUFF_ERROR_RETURN(_sbuff_or_marker)
#define FR_SBUFF_IN_SPRINTF_RETURN(...)
#define FR_SBUFF(_sbuff_or_marker)
#define FR_SBUFF_OUT(_start, _len_or_end)
#define FR_SBUFF_IN_STRCPY_RETURN(...)
Set of terminal elements.
Set of parsing rules for *unescape_until functions.
static int16_t tmpl_attr_tail_num(tmpl_t const *vpt)
Return the last attribute reference's attribute number.
void tmpl_attr_set_list(tmpl_t *vpt, fr_dict_attr_t const *list)
#define tmpl_is_xlat(vpt)
void tmpl_set_name_printf(tmpl_t *vpt, fr_token_t quote, char const *fmt,...))
Set the name on a pre-initialised tmpl.
void tmpl_set_xlat(tmpl_t *vpt, xlat_exp_head_t *xlat)
Change the default dictionary in the tmpl's resolution rules.
void tmpl_attr_set_request_ref(tmpl_t *vpt, FR_DLIST_HEAD(tmpl_request_list) const *request_def)
Set the request for an attribute ref.
TALLOC_CTX * tmpl_list_ctx(request_t *request, fr_dict_attr_t const *list)
Return the correct TALLOC_CTX to alloc fr_pair_t in, for a list.
int tmpl_resolve(tmpl_t *vpt, tmpl_res_rules_t const *tr_rules))
Attempt to resolve functions and attributes in xlats and attribute references.
#define tmpl_value(_tmpl)
TALLOC_CTX * list_ctx
Where to allocate new attributes if building out from the current extents of the tree.
static char const * tmpl_list_name(fr_dict_attr_t const *list, char const *def)
Return the name of a tmpl list or def if list not provided.
int tmpl_afrom_value_box(TALLOC_CTX *ctx, tmpl_t **out, fr_value_box_t *data, bool steal)
Create a tmpl_t from a fr_value_box_t.
int tmpl_attr_unknown_add(tmpl_t *vpt)
Add an unknown fr_dict_attr_t specified by a tmpl_t to the main dictionary.
static bool tmpl_attr_tail_is_unknown(tmpl_t const *vpt)
Return true if the last attribute reference is "unknown".
#define tmpl_contains_regex(vpt)
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
int tmpl_extents_build_to_leaf_parent(fr_dlist_head_t *leaf, fr_dlist_head_t *interior, tmpl_t const *vpt)
Allocate interior pairs.
#define tmpl_is_attr(vpt)
#define tmpl_is_exec(vpt)
fr_dict_attr_t const * enumv
Enumeration attribute used to resolve enum values.
void tmpl_rules_child_init(TALLOC_CTX *ctx, tmpl_rules_t *out, tmpl_rules_t const *parent, tmpl_t *vpt)
Initialize a set of rules from a parent set of rules, and a parsed tmpl_t.
int tmpl_extents_find(TALLOC_CTX *ctx, fr_dlist_head_t *leaf, fr_dlist_head_t *interior, request_t *request, tmpl_t const *vpt))
Determines points where the reference list extends beyond the current pair tree.
#define tmpl_rules_cast(_tmpl)
ssize_t tmpl_afrom_attr_str(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t **out, char const *name, tmpl_rules_t const *rules))
Parse a string into a TMPL_TYPE_ATTR_* type tmpl_t.
void tmpl_set_name(tmpl_t *vpt, fr_token_t quote, char const *name, ssize_t len)
Set the name on a pre-initialised tmpl.
@ TMPL_TYPE_ATTR
Reference to one or more attributes.
@ TMPL_TYPE_XLAT
Pre-parsed xlat expansion.
@ TMPL_TYPE_NULL
Has no value.
@ TMPL_TYPE_EXEC
Callout to an external script or program.
@ TMPL_TYPE_DATA
Value in native boxed format.
@ TMPL_TYPE_DATA_UNRESOLVED
Unparsed literal string.
static bool tmpl_attr_tail_da_is_leaf(tmpl_t const *vpt)
Return true if the the last attribute reference is a leaf attribute.
#define tmpl_contains_attr(vpt)
static bool tmpl_attr_tail_da_is_structural(tmpl_t const *vpt)
Return true if the the last attribute reference is a structural attribute.
int tmpl_copy_pairs(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, tmpl_t const *vpt))
Copy pairs matching a tmpl_t in the current request_t.
ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_token_t quote, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Convert an arbitrary string into a tmpl_t.
static fr_slen_t e_rules fr_slen_t tmpl_print_quoted(fr_sbuff_t *out, tmpl_t const *vpt, tmpl_attr_prefix_t ar_prefix)
Print a tmpl_t to a string with quotes.
fr_pair_list_t * tmpl_list_head(request_t *request, fr_dict_attr_t const *list)
Resolve attribute fr_pair_list_t value to an attribute list.
tmpl_xlat_rules_t xlat
Rules/data for parsing xlats.
bool at_runtime
Produce an ephemeral/runtime tmpl.
static bool tmpl_is_list(tmpl_t const *vpt)
ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t **out, fr_sbuff_t *name, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Parse a string into a TMPL_TYPE_ATTR_* type tmpl_t.
int tmpl_cast_in_place(tmpl_t *vpt, fr_type_t type, fr_dict_attr_t const *enumv))
Convert tmpl_t of type TMPL_TYPE_DATA_UNRESOLVED or TMPL_TYPE_DATA to TMPL_TYPE_DATA of type specifie...
#define tmpl_is_data(vpt)
fr_dict_t const * dict_def
Alternative default dictionary to use if vpt->rules->dict_def is NULL.
fr_slen_t tmpl_request_ref_list_afrom_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, FR_DLIST_HEAD(tmpl_request_list) _CONST **out, fr_sbuff_t *in)
#define tmpl_value_type(_tmpl)
int tmpl_request_ptr(request_t **request, FR_DLIST_HEAD(tmpl_request_list) const *rql)
Resolve a tmpl_request_ref_t to a request_t.
#define tmpl_is_data_unresolved(vpt)
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
fr_pair_list_t * list
List that we tried to evaluate ar in and failed.
@ TMPL_ATTR_LIST_REQUIRE
Attribute refs are required to have a list.
@ TMPL_ATTR_LIST_FORBID
Attribute refs are forbidden from having a list.
#define tmpl_is_null(vpt)
int tmpl_attr_set_leaf_da(tmpl_t *vpt, fr_dict_attr_t const *da)
Replace the leaf attribute only.
struct tmpl_res_rules_s tmpl_res_rules_t
static fr_dict_attr_t const * tmpl_list(tmpl_t const *vpt)
#define tmpl_aexpand(_ctx, _out, _request, _vpt, _escape, _escape_ctx)
Expand a tmpl to a C type, allocing a new buffer to hold the string.
tmpl_t * tmpl_alloc(TALLOC_CTX *ctx, tmpl_type_t type, fr_token_t quote, char const *name, ssize_t len)
Create a new heap allocated tmpl_t.
fr_slen_t tmpl_attr_list_from_substr(fr_dict_attr_t const **da_p, fr_sbuff_t *in)
Parse one a single list reference.
fr_event_list_t * runtime_el
The eventlist to use for runtime instantiation of xlats.
#define tmpl_needs_resolving(vpt)
int tmpl_cast_set(tmpl_t *vpt, fr_type_t type)
Set a cast for a tmpl.
static char const * tmpl_type_to_str(tmpl_type_t type)
Return a static string containing the type name.
Describes the current extents of a pair tree in relation to the tree described by a tmpl_t.
Similar to tmpl_rules_t, but used to specify parameters that may change during subsequent resolution ...
Optional arguments passed to vp_tmpl functions.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
fr_aka_sim_id_type_t type
fr_token_t op
The operator that controls insertion of the dst attribute.
tmpl_t * lhs
Typically describes the attribute to add, modify or compare.
map_list_t child
parent map, for nested ones
tmpl_t * rhs
Typically describes a literal value or a src attribute to copy or compare.
CONF_ITEM * ci
Config item that the map was created from.
tmpl_attr_list_presence_t list_presence
Whether the attribute reference can have a list, forbid it, or require it.
fr_dict_attr_t const * list_def
Default list to use with unqualified attribute reference.
fr_dict_t const * dict_def
Default dictionary to use with unqualified attribute references.
tmpl_attr_prefix_t prefix
Whether the attribute reference requires a prefix.
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
An element in a lexicographically sorted array of name to num mappings.
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
static TALLOC_CTX * talloc_init_const(char const *name)
Allocate a top level chunk with a constant name.
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
void tmpl_dcursor_clear(tmpl_dcursor_ctx_t *cc)
Clear any temporary state allocations.
#define tmpl_dcursor_init(_err, _ctx, _cc, _cursor, _request, _vpt)
Maintains state between cursor calls.
const bool fr_assignment_op[T_TOKEN_LAST]
char const * fr_token_name(int token)
fr_table_num_ordered_t const fr_tokens_table[]
const char fr_token_quote[T_TOKEN_LAST]
Convert tokens back to a quoting character.
char const * fr_tokens[T_TOKEN_LAST]
const bool fr_comparison_op[T_TOKEN_LAST]
@ T_SOLIDUS_QUOTED_STRING
ssize_t xlat_aeval_compiled(TALLOC_CTX *ctx, char **out, request_t *request, xlat_exp_head_t const *head, xlat_escape_legacy_t escape, void const *escape_ctx))
fr_slen_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules)
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
fr_pair_t * fr_pair_list_tail(fr_pair_list_t const *list)
Get the tail of a valuepair list.
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
void fr_pair_list_sort(fr_pair_list_t *list, fr_cmp_t cmp)
Sort a doubly linked list of fr_pair_ts using merge sort.
#define fr_pair_list_foreach(_list_head, _iter)
Iterate over the contents of a fr_pair_list_t.
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src)
Appends a list of fr_pair_t from a temporary list to a destination list.
void fr_pair_list_prepend(fr_pair_list_t *dst, fr_pair_list_t *src)
Move a list of fr_pair_t from a temporary list to the head of a destination list.
static fr_slen_t fr_pair_aprint_value_quoted(TALLOC_CTX *ctx, char **out, fr_pair_t const *vp, fr_token_t quote) 1(fr_pair_print_value_quoted
#define fr_pair_dcursor_init(_cursor, _list)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
char const * fr_strerror(void)
Get the last library error.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
#define fr_type_is_structural(_x)
#define FR_TYPE_STRUCTURAL
#define fr_type_is_leaf(_x)
fr_sbuff_parse_rules_t const value_parse_rules_solidus_quoted
int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert one type of fr_value_box_t to another.
fr_sbuff_parse_rules_t const * value_parse_rules_quoted[T_TOKEN_LAST]
Parse rules for quoted strings.
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
int fr_value_box_cmp_op(fr_token_t op, fr_value_box_t const *a, fr_value_box_t const *b)
Compare two attributes using an operator.
fr_sbuff_parse_rules_t const value_parse_rules_single_quoted
int fr_value_box_strdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Copy a nul terminated string to a fr_value_box_t.
FR_SBUFF_SET_RETURN(sbuff, &our_sbuff)
fr_sbuff_parse_rules_t const value_parse_rules_bareword_quoted
fr_sbuff_parse_rules_t const value_parse_rules_backtick_quoted
fr_sbuff_parse_rules_t const * value_parse_rules_unquoted[T_TOKEN_LAST]
Parse rules for non-quoted strings.
fr_sbuff_unescape_rules_t fr_value_unescape_single
fr_sbuff_parse_rules_t const value_parse_rules_double_quoted
static size_t char ** out