27RCSID(
"$Id: e0a8bebd9fdf71efe3306ea85c5e3c8f697d3289 $")
 
   29#define _TMPL_PRIVATE 1 
   31#include <freeradius-devel/server/tmpl.h> 
   32#include <freeradius-devel/server/base.h> 
   33#include <freeradius-devel/protocol/freeradius/freeradius.internal.h> 
   35#include <freeradius-devel/util/base16.h> 
   36#include <freeradius-devel/util/skip.h> 
   42#include <freeradius-devel/unlang/xlat_priv.h> 
   53#define TMPL_REQUEST_REF_DEF(_name, _ref) \ 
   54static tmpl_request_t _name ## _entry = { \ 
   57                        .next = &_name.head.entry, \ 
   58                        .prev = &_name.head.entry \ 
   63FR_DLIST_HEAD(tmpl_request_list) _name = { \ 
   65                .offset = offsetof(tmpl_request_t, entry), \ 
   67                        .next = &_name ## _entry.entry.entry, \ 
   68                        .prev = &_name ## _entry.entry.entry, \ 
 
   99#define DEFAULT_RULES tmpl_rules_t default_rules = { .attr = { .list_def = request_attr_request }} 
  101#define CHECK_T_RULES do { \ 
  103                t_rules = &default_rules; \ 
 
  169#define UNRESOLVED_SET(_flags) (*(_flags) = (*(_flags) | TMPL_FLAG_UNRESOLVED)) 
  170#define RESOLVED_SET(_flags) (*(_flags) = (*(_flags) & ~TMPL_FLAG_UNRESOLVED)) 
  181                                                                     fr_sbuff_parse_rules_t 
const *p_rules)
 
  187        if (!p_rules || !p_rules->terminals) 
return false;      
 
  189        fr_sbuff_marker(&m, 
in);
 
  192        fr_sbuff_marker_release(&m);
 
 
  207                        fprintf(fp, 
"\t[%u] %s null%s%s%s\n",
 
  216                fprintf(fp, 
"\t[%u] %s %s %s%s%s%s (%p) attr %u\n ",
 
  227                fprintf(fp, 
"\t    is_raw     : %s\n", 
ar_is_raw(ar) ? 
"yes" : 
"no");
 
  228                fprintf(fp, 
"\t    is_unknown : %s", 
ar_is_unknown(ar) ? 
"yes" : 
"no");
 
  229                if (ar->ar_parent) fprintf(fp, 
"\t    parent     : %s (%p)", ar->ar_parent->name, ar->ar_parent);
 
  238                fprintf(fp, 
"\t[%u] %s %s%s%s%s\n",
 
  245                if (ar->ar_parent)                      fprintf(fp, 
"\t    parent     : %s", ar->ar_parent->name);
 
  246                if (ar->ar_unresolved_namespace)        fprintf(fp, 
"\t    namespace  : %s", ar->ar_unresolved_namespace->name);
 
  250                fprintf(fp, 
"\t[%u] Bad type %s(%u)",
 
 
  261        fprintf(fp, 
"attribute references:\n");
 
  265        while ((ar = tmpl_attr_list_next(ar_head, ar))) {
 
 
  282                fprintf(fp, 
"%s can't print tmpls of type %s\n", __FUNCTION__,
 
  287        fprintf(fp, 
"tmpl_t %s (%.8x) \"%pV\" (%p)\n",
 
  295        fprintf(fp, 
"request references:");
 
  300        while ((rr = tmpl_request_list_next(&
vpt->data.attribute.rr, rr))) {
 
  301                fprintf(fp, 
"\t[%u] %s (%u)\n", i,
 
 
  322        fprintf(fp, 
"tmpl_t %s (%.8x) \"%pR\" (%p)\n",
 
  347                fprintf(fp, 
"\texpansion  : %s\n", str);
 
  355                fprintf(fp, 
"\tpattern    : %s\n", 
vpt->name);
 
  362                                fprintf(fp, 
"\tunescaped  : %s\n", 
vpt->data.unescaped);
 
  363                                fprintf(fp, 
"\tlen        : %zu\n", talloc_array_length(
vpt->data.unescaped) - 1);
 
  365                                fprintf(fp, 
"\tunresolved : %s\n", 
vpt->name);
 
  366                                fprintf(fp, 
"\tlen        : %zu\n", 
vpt->len);
 
  369                        fprintf(fp, 
"debug nyi\n");
 
 
  420static inline CC_HINT(always_inline) CC_HINT(
nonnull(2,3))
 
  430        while ((rr = tmpl_request_list_next(
in, rr))) {
 
  435                tmpl_request_list_insert_tail(
out, n_rr);
 
 
  443static inline CC_HINT(always_inline) CC_HINT(
nonnull(2,3))
 
  450        tmpl_request_list_talloc_init(rql);
 
 
  464        while ((rr = tmpl_request_list_next(rql, rr))) {
 
 
  491        if (!a || !tmpl_request_list_initialised(a) || tmpl_request_list_empty(a)) a = &tmpl_request_def_current;
 
  492        if (!b || !tmpl_request_list_initialised(b) || tmpl_request_list_empty(b)) b = &tmpl_request_def_current;
 
  497        if (a == b) 
return 0;
 
  500                a_rr = tmpl_request_list_next(a, a_rr);
 
  501                b_rr = tmpl_request_list_next(b, b_rr);
 
  503                if (!a_rr || !b_rr) 
return CMP(tmpl_request_list_num_elements(a), tmpl_request_list_num_elements(b));
 
 
  525                                                   fr_sbuff_parse_rules_t 
const *p_rules,
 
  534        unsigned int            depth = 0;
 
  540        at_rules = &t_rules->
attr;
 
  550                if (at_rules->namespace) {
 
  551                        *
namespace = at_rules->namespace;
 
  562        if (!tmpl_request_list_initialised(
out)) tmpl_request_list_talloc_init(
out);
 
  564        fr_sbuff_marker(&m, &our_in);
 
  584                        if ((
depth == 0) && at_rules->request_def) {
 
  605                                tmpl_request_list_talloc_free_to_tail(
out, tail);
 
  613                if (
namespace && t_rules && t_rules->
parent) {
 
  614                        t_rules = t_rules->
parent;
 
  622                                if (t_rules->
attr.namespace) {
 
  623                                        *
namespace = t_rules->attr.namespace;
 
  643                tmpl_request_list_insert_tail(
out, rr);
 
 
  695        tmpl_request_list_talloc_init(rql);
 
 
  735                tmpl_request_list_talloc_init(&
vpt->data.attribute.rr);
 
 
  754        char const      *old = NULL;
 
  761        vpt->len = talloc_array_length(
vpt->name) - 1;
 
 
  799        vpt->len = talloc_array_length(
vpt->name) - 1;
 
 
  810        vpt->rules.attr.dict_def = dict;
 
 
  820        vpt->rules.escape = *escape;
 
 
  849        memset(
vpt, 0, 
sizeof(*
vpt));
 
  854        vpt->len = talloc_array_length(
vpt->name) - 1;
 
 
  878        memset(
vpt, 0, 
sizeof(*
vpt));
 
  881        if (t_rules) 
vpt->rules = *t_rules;
 
 
  900        memset(
vpt, 0, 
sizeof(*
vpt));
 
  903        if (t_rules) 
vpt->rules = *t_rules;
 
 
  946        memset(
vpt, 0, 
sizeof(*
vpt));
 
 
 1035        if (tmpl_attr_list_num_elements(
tmpl_attr(dst)) > 0) tmpl_attr_list_talloc_reverse_free(
tmpl_attr(dst));
 
 1037        while ((src_ar = tmpl_attr_list_next(
tmpl_attr(src), src_ar))) {
 
 1040                switch (src_ar->
type) {
 
 1042                        dst_ar->ar_da = src_ar->ar_da;
 
 1053                        dst_ar->ar_unresolved = 
talloc_bstrdup(dst_ar, src_ar->ar_unresolved);
 
 1059                dst_ar->ar_num = src_ar->ar_num;
 
 1060                dst_ar->ar_filter_type = src_ar->ar_filter_type;
 
 1068        tmpl_request_list_talloc_reverse_free(&dst->data.attribute.rr);
 
 1074        dst->rules = src->rules;
 
 
 1100        if (da->flags.is_unknown) {
 
 
 1133                                fr_strerror_const(
"New leaf da and old leaf da do not share the same ancestor");
 
 1143                talloc_free_children(ref);
 
 1159        if (da->flags.is_unknown) {
 
 
 1190        if (tmpl_attr_list_num_elements(
tmpl_attr(
vpt)) == 0) 
return;
 
 
 1219        tmpl_request_list_talloc_reverse_free(&
vpt->data.attribute.rr);
 
 
 1252        if (da->flags.is_unknown) {
 
 1270                                   STRINGIFY(
sizeof(attr)) 
" bytes, got %zu bytes", (
size_t)-slen);
 
 
 1307        switch (ar->ar_num) {
 
 
 1343                fr_sbuff_set_to_start(&our_name);
 
 1351                fr_sbuff_next(&our_name);
 
 1356                fr_sbuff_next(&our_name);
 
 1380                if ((ar->ar_num > 1000) || (ar->ar_num < 0)) {
 
 1381                        fr_strerror_printf(
"Invalid array index '%hi' (should be between 0-1000)", ar->ar_num);
 
 1410                fr_sbuff_parse_rules_t p_rules;
 
 1416                t_rules.
attr = *at_rules;
 
 1433                        t_rules.
attr.namespace = ar->ar_da;
 
 1436                p_rules = (fr_sbuff_parse_rules_t) {
 
 1437                        .terminals = &filter_terminals,
 
 1445                if (slen < 0) 
goto error;
 
 1448                        fr_strerror_const(
"Condition in attribute index cannot depend on functions which call external databases");
 
 1462                fr_sbuff_parse_rules_t p_rules;
 
 1465                if (!fr_sbuff_is_str(&our_name, 
"%{", 2)) {
 
 1472                t_rules.
attr = *at_rules;
 
 1474                p_rules = (fr_sbuff_parse_rules_t) {
 
 1475                        .terminals = &filter_terminals,
 
 1483                if (slen < 0) 
goto error;
 
 1486                        fr_strerror_const(
"Expression in attribute index cannot depend on functions which call external databases");
 
 1502                if (fr_sbuff_is_str(&our_name, 
"n]", 2)) {
 
 1504                        fr_sbuff_next(&our_name);
 
 1515                fr_sbuff_parse_rules_t p_rules;
 
 1520                t_rules.
attr = *at_rules;
 
 1527                p_rules = (fr_sbuff_parse_rules_t) {
 
 1528                        .terminals = &filter_terminals,
 
 1538                if (slen <= 0) 
goto error;
 
 
 1573static inline CC_HINT(
nonnull(3,4))
 
 1626static inline CC_HINT(
nonnull(3,6))
 
 1649                slen = fr_sbuff_out_abstrncpy_allowed(ar, &unresolved,
 
 1658                                tmpl_attr_list_talloc_free_to_tail(
tmpl_attr(
vpt), ar_curr);
 
 1671                        .ar_unresolved = unresolved,
 
 1672                        .ar_unresolved_namespace = 
namespace,
 
 
 1716                .ar_parent = da->parent,
 
 
 1762        fr_sbuff_marker(&m_s, 
name);
 
 1769                fr_sbuff_marker_release(&m_s);
 
 1797                                                                   name, p_rules ? p_rules->terminals : NULL,
 
 1808                        our_parent = da->parent;
 
 1810                        if (!our_parent->flags.is_root) {
 
 1831                                                  p_rules ? p_rules->terminals : NULL);
 
 1842                        ar = tmpl_attr_list_tail(&
vpt->data.attribute.ar);
 
 1849                                                                  p_rules ? p_rules->terminals : NULL);
 
 1852                                        our_parent = internal_root;
 
 1862                        if (!da->flags.local && namespace->flags.local) 
namespace = our_parent = 
fr_dict_root(da->dict);
 
 1868                        if (da->parent != our_parent) {
 
 1881                if (our_parent->flags.is_unknown) 
break;
 
 1912                        our_parent = 
namespace = 
fr_dict_root(at_rules->dict_def);
 
 1928                namespace = fr_dict_unlocal(namespace);
 
 1942                if (da) 
goto alloc_ar;
 
 1962                switch (namespace->type) {
 
 1982                        .ar_parent = our_parent,
 
 2001        fr_sbuff_marker_release(&m_s);
 
 2022                .ar_parent = our_parent,
 
 2044        if (da->flags.local && (ar->ar_num > 0)) {
 
 2056        fr_sbuff_marker_release(&m_s);
 
 2057        fr_sbuff_marker(&m_s, 
name);
 
 2086                                our_parent = 
namespace = ref;
 
 2089                                our_parent = 
namespace = 
parent;
 
 2092                                our_parent = 
namespace = 
fr_dict_root(at_rules->dict_def);
 
 2095                                our_parent = 
namespace = NULL;
 
 2104                        namespace = our_parent = da;
 
 2117                                           "\"struct\", \"tlv\", \"vendor\", \"vsa\" or \"group\", got \"%s\"",
 
 2128                                tmpl_attr_list_talloc_free_tail(&
vpt->data.attribute.ar); 
 
 2155        fr_sbuff_marker_release(&m_s);
 
 
 2202                               fr_sbuff_parse_rules_t 
const *p_rules,
 
 2208        bool                            is_raw = 
false;
 
 2216        at_rules = &t_rules->
attr;
 
 2248                                                &
vpt->data.attribute.rr,
 
 2260        fr_sbuff_marker(&m_l, &our_name);
 
 2267                                          namespace, 
namespace,
 
 2268                                          &our_name, p_rules, at_rules, 0);
 
 2269        if (ret < 0) 
goto error;
 
 2287                bool            is_local = ar->ar_da->flags.local;
 
 2291                        if (!ar->ar_da->flags.local ||
 
 2292                            (ar->ar_da->flags.local && is_local)) 
continue;
 
 2366        vpt->rules = *t_rules;  
 
 2375        if (t_rules->
attr.request_def) {
 
 2415                fr_sbuff_set_to_start(&our_name);
 
 
 2445        name_len = strlen(
name);
 
 2447        if (slen <= 0) 
return slen;
 
 2451        if (slen != name_len) {
 
 
 2479                                         fr_sbuff_parse_rules_t 
const *p_rules)
 
 2496                                     cast, allow_enum ? t_rules->
enumv : NULL,
 
 2497                                     &our_in, p_rules) < 0) {
 
 
 2527                                        fr_sbuff_parse_rules_t 
const *p_rules)
 
 2546        vpt->data.literal.vb_bool = a_bool;
 
 
 2565                                          fr_sbuff_parse_rules_t 
const *p_rules)
 
 2605        MEM(bin = talloc_realloc_size(
vpt, bin, binlen));       
 
 
 2624                                        fr_sbuff_parse_rules_t 
const *p_rules)
 
 2631        uint8_t         addr[4] = {}, prefix = 32;
 
 2636                if (
count == 3) 
break;
 
 2669        vpt->data.literal.vb_ip.af = AF_INET;
 
 2670        vpt->data.literal.vb_ip.prefix = prefix;
 
 2677                ipaddr &= ~((
uint32_t) 0) << (32 - prefix);
 
 2679        vpt->data.literal.vb_ip.addr.v4.s_addr = htonl(ipaddr);
 
 
 2697                                        fr_sbuff_parse_rules_t 
const *p_rules)
 
 2704        char                    *sep_a, *sep_b;
 
 2706        static bool ipv6_chars[
UINT8_MAX + 1] = {
 
 2707                [
'0'] = 
true, [
'1'] = 
true, [
'2'] = 
true, [
'3'] = 
true, [
'4'] = 
true,
 
 2708                [
'5'] = 
true, [
'6'] = 
true, [
'7'] = 
true, [
'8'] = 
true, [
'9'] = 
true,
 
 2709                [
'a'] = 
true, [
'b'] = 
true, [
'c'] = 
true, [
'd'] = 
true, [
'e'] = 
true,
 
 2711                [
'A'] = 
true, [
'B'] = 
true, [
'C'] = 
true, [
'D'] = 
true, [
'E'] = 
true,
 
 2713                [
':'] = 
true, [
'.'] = 
true 
 2720        fr_sbuff_marker(&m, &our_in);
 
 2740        if (sep_a && (!(sep_b = memchr(
fr_sbuff_current(&m), 
':', len)) || (sep_b > sep_a))) {
 
 2760                if ((len < 1) || (len > IFNAMSIZ)) {
 
 
 2815                                       fr_sbuff_parse_rules_t 
const *p_rules)
 
 2864        memcpy(vb->vb_ether, 
buff, 
sizeof(vb->vb_ether));
 
 
 2882                                           fr_sbuff_parse_rules_t 
const *p_rules)
 
 2896                if (slen <= 0) 
return 0;
 
 2907                if (a_int >= INT8_MIN) {
 
 2909                        vb->vb_int8 = (int8_t)a_int;
 
 2910                } 
else if (a_int >= INT16_MIN) {
 
 2912                        vb->vb_int16 = (int16_t)a_int;
 
 2913                } 
else if (a_int >= INT32_MIN) {
 
 2915                        vb->vb_int32 = (int32_t)a_int;
 
 2918                        vb->vb_int64 = (int64_t)a_int;
 
 2927                if (slen <= 0) 
return slen;
 
 2939                        vb->vb_uint8 = (
uint8_t)a_uint;
 
 2940                } 
else if (a_uint <= UINT16_MAX) {
 
 2943                } 
else if (a_uint <= UINT32_MAX) {
 
 2948                        vb->vb_uint64 = (uint64_t)a_uint;
 
 
 2958                                       fr_sbuff_parse_rules_t 
const *p_rules)
 
 2967        if (slen <= 0) 
return 0;
 
 2978        vb->vb_float64 = a_float;
 
 
 2986                                     fr_sbuff_parse_rules_t 
const *p_rules)
 
 2995        if (slen <= 0) 
return 0;
 
 3001        vb->vb_time_delta = a_delta;
 
 
 3031                               fr_sbuff_parse_rules_t 
const *p_rules,
 
 3052        } 
else if (t_rules->
enumv &&
 
 3086                                          "'quoted literal', \"%{expansion}\", or enum value");
 
 3105        if (t_rules->
enumv) {
 
 3116                        vpt->data.literal.enumv = t_rules->
enumv;
 
 
 3167                            fr_sbuff_parse_rules_t 
const *p_rules,
 
 3221                                hoisted = node->vpt;
 
 3223                                (void) talloc_steal(ctx, hoisted);
 
 3244                                                                                    t_rules, 
true, p_rules);
 
 3255                        my_t_rules.
cast = my_t_rules.
enumv->type;
 
 3265                        if (slen > 0) 
goto done_bareword;
 
 3285                if (slen > 0) 
goto done_bareword;
 
 3296                if (slen > 0) 
goto done_bareword;
 
 3303                if (slen > 0) 
goto done_bareword;
 
 3310                if (slen > 0) 
goto done_bareword;
 
 3314                if (slen > 0) 
goto done_bareword;
 
 3321                if (slen > 0) 
goto done_bareword;
 
 3328                if (slen > 0) 
goto done_bareword;
 
 3339                if (slen > 0) 
goto done_bareword;
 
 3347                if (slen > 0) 
goto done_bareword;
 
 3383                                                  "'quoted literal', \"%{expansion}\", or enum value");
 
 3401                vpt->data.unescaped = str;
 
 3416                slen = fr_sbuff_out_aunescape_until(
vpt, &str, &our_in, SIZE_MAX,
 
 3417                                                    p_rules ? p_rules->terminals : NULL,
 
 3418                                                    p_rules ? p_rules->escapes : NULL);
 
 3420                vpt->data.unescaped = str;
 
 3444                                                               t_rules, 
false, p_rules);
 
 3457                                vpt->data.unescaped = str;      
 
 3489                if ((slen <= 0) || !
head) {
 
 3520                        fr_sbuff_set_to_start(&our_in); 
 
 3542                        vpt->data.unescaped = str;      
 
 
 3584        vpt->rules = 
in->rules;
 
 3607                vpt->data.reg_flags = 
in->data.reg_flags;
 
 3620                        if (
unlikely(tmpl_regex_compile(
vpt, 
vpt->data.reg.subcaptures) < 0)) 
goto error;
 
 3635                if (!
vpt->data.xlat.ex) 
goto error;
 
 
 3687        fr_sbuff_marker(&m, &our_in);
 
 3704        if (rules) rules->
cast = cast;
 
 
 3741        switch (
vpt->type) {
 
 3777                        if (da->type == dst_type) {
 
 3778                                if (da->flags.has_value) 
goto done;
 
 3781                        src_type = da->type;
 
 3789                if (src_type == dst_type) {
 
 3810        vpt->rules.cast = dst_type;
 
 
 3832        slen = regex_flags_parse(&
err, &
vpt->data.reg_flags, 
in, terminals, 
true);
 
 3865static inline CC_HINT(always_inline)
 
 3868                           char const *unescaped, 
size_t unescaped_len)
 
 3879        switch (existing_quote) {
 
 3882                return existing_quote;
 
 
 3910        switch (
vpt->type) {
 
 3913                char *unescaped = 
vpt->data.unescaped;
 
 3932                                                (
uint8_t const *)unescaped, talloc_array_length(unescaped) - 1,
 
 3933                                                false) < 0) 
return -1;
 
 3937                                                  unescaped, talloc_array_length(unescaped) - 1,
 
 3938                                                  NULL) < 0) 
return -1;
 
 3942                                             unescaped, talloc_array_length(unescaped) - 1);
 
 
 4029        dict_def = 
vpt->rules.attr.dict_def;
 
 4045                                                                      talloc_array_length(ar->ar_unresolved) - 1),
 
 4048                                                         vpt->rules.attr.allow_foreign);
 
 4068                        next->ar_parent = da;
 
 4069                        next->ar_unresolved_namespace = da;
 
 4076        while ((ar = tmpl_attr_list_next(
tmpl_attr(
vpt), ar))) {
 
 4100                                                               talloc_array_length(ar->ar_unresolved) - 1),
 
 4117                                                                               talloc_array_length(ar->ar_unresolved) - 1),
 
 4133                fr_assert(ar->ar_parent && !ar->ar_parent->flags.is_unknown);
 
 4141                        next->ar_parent = da;
 
 4142                        next->ar_unresolved_namespace = da;
 
 4155                        ar->ar_parent = prev->ar_parent;
 
 
 4182static inline CC_HINT(always_inline)
 
 4187                                .tr_rules = tr_rules,
 
 4188                                .allow_unresolved = false
 
 
 4221        if (!tr_rules) tr_rules = &default_tr_rules;
 
 4235                fr_strerror_printf(
"mismatch between parse-time enumv '%s' and resolution-time enumv '%s'",
 
 4259                if (ret < 0) 
return ret;
 
 4281                if (!enumv) enumv = tr_rules->
enumv;
 
 4293                                dst_type = enumv->type;
 
 4298                        } 
else if (strncmp(
vpt->data.unescaped, 
"::", 2) != 0) {
 
 4302                                fr_strerror_printf(
"Failed resolving data '%s' - it is not an attribute name or a quoted string", 
vpt->data.unescaped);
 
 
 4352        switch (
vpt->type) {
 
 4373                tmpl_request_list_talloc_free(&
vpt->data.attribute.rr);
 
 4385                TALLOC_FREE(
vpt->data.xlat.ex);
 
 4394        memcpy(
vpt, &tmp, 
sizeof(*
vpt));
 
 
 4403        switch (ref->
type) {
 
 4409                ref->ar_unknown->flags.is_unknown = 1;
 
 
 4455        if (
vpt->rules.at_runtime) 
return 1;
 
 4463        while ((ar = tmpl_attr_list_next(
tmpl_attr(
vpt), ar))) {
 
 4479                unknown = ar->ar_unknown;
 
 4481                if (!known) 
return -1;
 
 4489                    (next->ar_da->parent == unknown)) {
 
 4491                                                                 known) < 0) 
return -1;
 
 4492                        next->ar_parent = known;
 
 
 4556        if (!
vpt) 
return -1;
 
 4569        if (
type != da->type) {
 
 4576        if (memcmp(flags, &da->flags, 
sizeof(*flags)) != 0) {
 
 
 4595        char    *unescaped = 
vpt->data.unescaped;
 
 4601        slen = regex_compile(
vpt, &
vpt->data.reg.ex,
 
 4602                             unescaped, talloc_array_length(unescaped) - 1,
 
 4603                             &
vpt->data.reg_flags, subcaptures, 
vpt->rules.at_runtime);
 
 4604        if (slen <= 0) 
return vpt->quote != 
T_BARE_WORD ? slen - 1 : slen;      
 
 4607        vpt->data.reg.src = unescaped;                  
 
 4608        vpt->data.reg.subcaptures = subcaptures;
 
 4630                rr = tmpl_request_list_next(rql, rr);
 
 
 4660        switch (
vpt->type) {
 
 4675        if (slen < 0) 
return slen;
 
 4692        while ((ar = tmpl_attr_list_next(
tmpl_attr(
vpt), ar))) {
 
 4710                                depth = ar->ar_parent->depth - 1;       
 
 4715                                depth = ar->ar_parent->depth;
 
 4736                        for (i = 
depth; (
unsigned int)i < ar->
ar_da->depth; i++) {
 
 4754                        unsigned int    i, 
depth;
 
 4761                        if (ar->ar_parent && !ar->ar_parent->flags.is_root) {
 
 4763                                if (ar->ar_parent->flags.is_root) {
 
 4766                                        depth = ar->ar_parent->depth - 1;
 
 4769                                for (i = 
depth; i < ar->ar_parent->depth; i++) {
 
 4786                        switch (ar->ar_num) {
 
 4809                        (void) 
xlat_print(&our_out, ar->ar_cond, NULL);
 
 
 4848        switch (
vpt->type) {
 
 4868                fr_sbuff_terminate(
out);
 
 4894                fr_sbuff_terminate(
out);
 
 
 4937#ifdef WITH_VERIFY_PTR 
 4950        for (i = 0; i < len; i++) {
 
 4951                if (ptr[i] != 0x00) 
return ptr + i;
 
 4960#define CHECK_ZEROED(_vpt, _field) is_zeroed(((uint8_t const *)&(_vpt)->data) + sizeof((_vpt)->data._field), sizeof((_vpt)->data) - sizeof((_vpt)->data._field)) 
 4966#define PRINT_NON_ZEROED(_vpt, _field, _nz_ptr) \ 
 4968        DEBUG("Expected live portion %p-%p (0-%zu)", \ 
 4970              (uint8_t const *)&(_vpt)->data + sizeof((_vpt)->data._field), \ 
 4971              sizeof((_vpt)->data._field)); \ 
 4972        DEBUG("Expected zero portion %p-%p (%zu-%zu)", \ 
 4973              (uint8_t const *)&(_vpt)->data + sizeof((_vpt)->data._field), \ 
 4974              (uint8_t const *)&(_vpt)->data + sizeof((_vpt)->data), \ 
 4975              sizeof((_vpt)->data._field), sizeof((_vpt)->data)); \ 
 4976        HEX_MARKER1((uint8_t const *)&vpt->data, sizeof(vpt->data), nz - (uint8_t const *)&vpt->data, "non-zero memory", ""); \ 
 5000        while ((slow = tmpl_attr_list_next(
tmpl_attr(
vpt), slow)) &&
 
 5008                                    "CONSISTENCY CHECK FAILED %s[%u]:  Looping reference list found.  " 
 5009                                    "Fast pointer hit slow pointer at \"%s\"",
 
 5012                                    slow->da ? slow->da->
name : 
"(null-attr)");
 
 5027                                                     "TMPL_TYPE_ATTR known attribute \"%s\" " 
 5028                                                     "occurred after unknown attribute %s " 
 5032                                                     ar->unknown.
da->name);
 
 5034                        if (seen_unresolved) {
 
 5037                                                     "TMPL_TYPE_ATTR known attribute \"%s\" " 
 5038                                                     "occurred after unresolved attribute \"%s\"" 
 5045                                            "CONSISTENCY CHECK FAILED %s[%u]: attr ref missing parent",
 
 5053                                                     "TMPL_TYPE_ATTR unspecified attribute " 
 5054                                                     "occurred after unknown attribute %s " 
 5057                                                     ar->unknown.
da->name);
 
 5059                        if (seen_unresolved) {
 
 5062                                                     "TMPL_TYPE_ATTR unspecified attribute " 
 5063                                                     "occurred after unresolved attribute \"%s\"" 
 5071                        seen_unresolved = ar;
 
 5073                                            "CONSISTENCY CHECK FAILED %s[%u]: unresolved attr ref missing namespace",
 
 5079                        if (seen_unresolved) {
 
 5082                                                     "TMPL_TYPE_ATTR unknown attribute \"%s\" " 
 5083                                                     "occurred after unresolved attribute %s " 
 5109                                     "TMPL_TYPE_UNINITIALISED (uninitialised)", 
file, 
line);
 
 5114                                     "(outside range of tmpl_type_table)", 
file, 
line, 
vpt->type);
 
 5120                fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%u]: Quote type '%c' (%i) was set for NULL name",
 
 5125                fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%u]: No quoting type was set for name \"%.*s\"",
 
 5137        switch (
vpt->type) {
 
 5139                if (!
vpt->data.unescaped) {
 
 5141                                             "unescaped field is NULL", 
file, 
line);
 
 5146                if (!
vpt->data.xlat.ex) {
 
 5148                                             "has a NULL xlat.ex field", 
file, 
line);
 
 5154                                             "does not have 'needs resolving' flag set", 
file, 
line);
 
 5159                if (!
vpt->data.xlat.ex) {
 
 5161                                             "has a NULL xlat.ex field", 
file, 
line);
 
 5188                if ((tmpl_attr_list_num_elements(
tmpl_attr(
vpt)) > 0) &&
 
 5199                if ((nz = CHECK_ZEROED(
vpt, attribute))) {
 
 5200                        PRINT_NON_ZEROED(
vpt, attribute, nz);
 
 5202                                             "has non-zero bytes after the data.attribute struct in the union",
 
 5214                                                     "da is marked as unknown, but address is not equal to the template's " 
 5230                                                     "attribute \"%s\" (%s) not rooted in a dictionary",
 
 5238                                                     "dictionary pointer %p \"%s\" (%s) " 
 5239                                                     "and global dictionary pointer %p \"%s\" (%s) differ",
 
 5252                if ((nz = CHECK_ZEROED(
vpt, literal))) {
 
 5253                        PRINT_NON_ZEROED(
vpt, literal, nz);
 
 5255                                             "has non-zero bytes after the data.literal struct in the union",
 
 5261                                             "FR_TYPE_NULL (uninitialised)", 
file, 
line);
 
 5294                fr_fatal_assert_fail(
"CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_REGEX_XLAT_UNRESOLVED - No regex support",
 
 5301                if (tmpl_regex(
vpt) == NULL) {
 
 5303                                             "reg.ex field was NULL", 
file, 
line);
 
 5324#define return_P(_x) fr_strerror_const(_x);goto return_p 
 5355        while (isspace((
uint8_t) *p) && (p < end)) p++;
 
 5356        if (p >= end) 
return p - 
in;
 
 5371                        while ((q < end) && (isalnum((
int) *q) || (*q == 
'.') || (*q == 
'_') || (*q == 
'-'))) {
 
 5416                        if ((*p == 
'}') || (*p == 
')')) {
 
 5417                                bool match = (*p == 
close);
 
 5425                                        *outlen = p - (*out);
 
 5434                                        return_P(
"End of string after escape");
 
 5441                        if ((p[0] == 
'%') && ((p[1] == 
'{') || (p[1] == 
'('))) {
 
 5443                                        return_P(
"End of string after expansion");
 
 5454                        if ((*p == 
'{') || (*p == 
'(')) {
 
 5468                return_P(
"Unterminated expansion");
 
 5496                if ((
inlen > 3) && (p[0] == quote) && (p[1] == quote)) {
 
 5505                        if (p >= end) 
goto unterminated;
 
 5515                                        *outlen = p - (*out);
 
 5521                                if (((end - p) >= 3) && (p[1] == quote) && (p[2] == quote)) {
 
 5522                                        *outlen = p - (*out);
 
 5534                                        return_P(
"End of string after escape");
 
 5577                                } 
else if ((p[1] == 
'E') &&
 
 5631                        if ((*p == 
'-') || (*p == 
':')) {
 
 5632                                if (p[1] == 
'=') 
break;
 
 5641                        if ((*p == 
'.') || (*p == 
'/') || (*p == 
'_') || (*p == 
'*') ||
 
 5642                            (*p == 
']') || (*p == 
'@')) {
 
 5650                        if ((p == 
in) && (*p == 
'[')) {
 
 5658                        if (((*p >= 
'a') && (*p <= 
'z')) ||
 
 5659                            ((*p >= 
'A') && (*p <= 
'Z')) ||
 
 5660                            ((*p >= 
'0') && (*p <= 
'9'))) {
 
 5668                        if (*(
uint8_t const *)p > 0x80) {
 
 5680                                        return_P(
"Invalid location for '['");
 
 5689                                if ((*p == 
'#') || (*p == 
'*') || (*p == 
'n')) {
 
 5724                if ((*p == 
'"') || (*p == 
'\'') || (*p == 
'`')) {
 
 5725                        return_P(
"Unexpected start of string");
 
 5729                        return_P(
"Empty string is invalid");
 
 5732                *outlen = p - (*out);
 
 
 5748        switch (
vpt->type) {
 
 
 5789        if (
vpt->rules.attr.request_def) {
 
 5799                out->attr.namespace = da;
 
 5810        if ((dict != internal) && (dict != 
out->attr.dict_def)) {
 
 5811                out->attr.dict_def = dict;
 
 5812                out->attr.namespace = ref;
 
 
 5827        FR_FAULT_LOG(
"\tnamespace         = %s", at_rules->namespace ? at_rules->namespace->name : 
"");
 
 
static int const char char buffer[256]
static int const char * fmt
#define fr_base16_decode(_err, _out, _in, _no_trailing)
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define L(_str)
Helper for initialising arrays of string literals.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
#define CMP_RETURN(_a, _b, _field)
Return if the comparison is not 0 (is unequal)
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
static char const * skip_word(char const *text)
#define fr_dbuff_init(_out, _start, _len_or_end)
Initialise an dbuff for encoding or decoding.
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
#define fr_fatal_assert_fail(_msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
#define fr_assert_fail(_msg,...)
Calls panic_action ifndef NDEBUG, else logs error.
#define FR_FAULT_LOG(_fmt,...)
#define fr_fatal_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
fr_slen_t fr_dict_attr_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_attr_t const *parent, fr_sbuff_t *name, fr_sbuff_term_t const *tt))
unsigned int name_only
this attribute should always be referred to by name.
fr_slen_t fr_dict_enum_name_from_substr(fr_sbuff_t *out, fr_sbuff_parse_error_t *err, fr_sbuff_t *in, fr_sbuff_term_t const *tt)
Extract an enumeration name from a string.
fr_dict_t * fr_dict_unconst(fr_dict_t const *dict)
Coerce to non-const.
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_attr_t const * fr_dict_attr_common_parent(fr_dict_attr_t const *a, fr_dict_attr_t const *b, bool is_ancestor)
Find a common ancestor that two TLV type attributes share.
static fr_dict_attr_t * fr_dict_attr_unknown_vendor_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int vendor)
bool const fr_dict_attr_allowed_chars[UINT8_MAX+1]
Characters allowed in a single dictionary attribute name.
static fr_dict_attr_t * fr_dict_attr_unknown_copy(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
fr_dict_attr_t const * fr_dict_attr_unknown_add(fr_dict_t *dict, fr_dict_attr_t const *old)
Converts an unknown to a known by adding it to the internal dictionaries.
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *attr))
Locate a fr_dict_attr_t by its name.
fr_dict_attr_t * fr_dict_attr_unconst(fr_dict_attr_t const *da)
Coerce to non-const.
fr_dict_attr_t * fr_dict_attr_unknown_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da))
Copy a known or unknown attribute to produce an unknown attribute with the specified name.
static fr_dict_attr_t * fr_dict_attr_unknown_raw_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int attr)
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
int fr_dict_attr_unknown_parent_to_known(fr_dict_attr_t *da, fr_dict_attr_t const *parent)
Fixup the parent of an unknown attribute using an equivalent known attribute.
fr_value_box_t const  * value
Enum value (what name maps to).
void fr_dict_attr_unknown_free(fr_dict_attr_t const **da)
Free dynamically allocated (unknown attributes)
fr_dict_t const * fr_dict_internal(void)
fr_slen_t fr_dict_attr_search_by_qualified_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_t const *dict_def, fr_sbuff_t *name, fr_sbuff_term_t const *tt, bool internal, bool foreign))
Locate a qualified fr_dict_attr_t by its name and a dictionary qualifier.
fr_slen_t fr_dict_attr_search_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_t const *dict_def, fr_sbuff_t *name, fr_sbuff_term_t const *tt, bool internal, bool foreign))
Locate a fr_dict_attr_t by its name in the top level namespace of a dictionary.
static fr_slen_t fr_dict_enum_name_afrom_substr(TALLOC_CTX *ctx, char **out, fr_sbuff_parse_error_t *err, fr_sbuff_t *in, fr_sbuff_term_t const *tt) 1(fr_dict_enum_name_from_substr
#define FR_DICT_MAX_TLV_STACK
Maximum TLV stack size.
fr_dict_attr_err_t
Errors returned by attribute lookup functions.
@ FR_DICT_ATTR_OK
No error.
@ FR_DICT_ATTR_NOT_DESCENDENT
Attribute is not a descendent of the parent attribute.
@ FR_DICT_ATTR_NO_CHILDREN
Child lookup in attribute with no children.
int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, unsigned int attr, fr_type_t type, fr_dict_attr_flags_t const *flags))
Add an attribute to the dictionary.
fr_dict_attr_t const * fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr)
Check if a child attribute exists in a parent using an attribute number.
#define fr_dict_attr_is_key_field(_da)
fr_dict_enum_value_t const * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
#define FR_DICT_ATTR_MAX_NAME_LEN
Maximum length of a attribute name.
Values of the encryption flags.
Value of an enumerated attribute.
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 unsigned int fr_dlist_num_elements(fr_dlist_head_t const *head)
Return the number of elements in the dlist.
#define FR_DLIST_HEAD(_name)
Expands to the type name used for the head wrapper structure.
#define FR_IPADDR_STRLEN
Like INET6_ADDRSTRLEN but includes space for the textual Zone ID.
static char * stack[MAX_STACK]
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_INT8
8 Bit signed integer.
@ FR_TYPE_ETHERNET
48 Bit Mac-Address.
@ FR_TYPE_IPV6_PREFIX
IPv6 Prefix.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_MAX
Number of defined data types.
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_INT64
64 Bit signed integer.
@ FR_TYPE_INT16
16 Bit signed integer.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_INT32
32 Bit signed integer.
@ FR_TYPE_UINT64
64 Bit unsigned integer.
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
@ FR_TYPE_IPV4_PREFIX
IPv4 Prefix.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_VSA
Vendor-Specific, for RADIUS attribute 26.
@ FR_TYPE_OCTETS
Raw octets.
@ FR_TYPE_GROUP
A grouping of other attributes.
@ FR_TYPE_FLOAT64
Double precision floating point.
@ FR_SBUFF_PARSE_ERROR_NOT_FOUND
String does not contain a token matching the output type.
@ FR_SBUFF_PARSE_ERROR_FORMAT
Format of data was invalid.
@ FR_SBUFF_PARSE_OK
No error.
static uint8_t depth(fr_minmax_heap_index_t i)
char * fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
void fr_proto_da_stack_build_partial(fr_da_stack_t *stack, fr_dict_attr_t const *parent, fr_dict_attr_t const *da)
Complete the DA stack for a child attribute.
fr_dict_attr_t const  * request_attr_request
fr_dict_attr_t const  * request_attr_control
fr_dict_attr_t const  * request_attr_local
fr_dict_attr_t const  * request_attr_state
fr_dict_attr_t const  * request_attr_reply
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.
bool const sbuff_char_class_hex[UINT8_MAX+1]
bool fr_sbuff_is_terminal(fr_sbuff_t *in, fr_sbuff_term_t const *tt)
Efficient terminal string search.
size_t fr_sbuff_adv_past_strcase(fr_sbuff_t *sbuff, char const *needle, size_t needle_len)
Return true and advance past the end of the needle if needle occurs next in the sbuff.
size_t fr_sbuff_adv_until(fr_sbuff_t *sbuff, size_t len, fr_sbuff_term_t const *tt, char escape_chr)
Wind position until we hit a character in the terminal set.
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_TABLE_STR_RETURN(_sbuff, _table, _number, _def)
#define fr_sbuff_adv_past_str_literal(_sbuff, _needle)
#define fr_sbuff_is_str_literal(_sbuff, _str)
#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_adv_past_strcase_literal(_sbuff, _needle)
#define fr_sbuff_current(_sbuff_or_marker)
#define FR_SBUFF_REPARSE(_sbuff_or_marker)
#define FR_SBUFF_IN_ESCAPE_BUFFER_RETURN(...)
#define FR_SBUFF_TERMS(...)
Initialise a terminal structure with a list of sorted strings.
#define FR_SBUFF_IN_STRCPY_LITERAL_RETURN(_sbuff, _str)
#define fr_sbuff_extend(_sbuff_or_marker)
#define FR_SBUFF_RETURN(_func, _sbuff,...)
#define fr_sbuff_is_char(_sbuff_or_marker, _c)
#define FR_SBUFF_ERROR_RETURN(_sbuff_or_marker)
#define FR_SBUFF_SET_RETURN(_dst, _src)
#define FR_SBUFF_IN_SPRINTF_RETURN(...)
#define FR_SBUFF(_sbuff_or_marker)
#define FR_SBUFF_IN_BSTRNCPY_RETURN(...)
#define fr_sbuff_advance(_sbuff_or_marker, _len)
#define fr_sbuff_out(_err, _out, _in)
#define fr_sbuff_switch(_sbuff_or_marker, _eob)
#define FR_SBUFF_OUT(_start, _len_or_end)
#define fr_sbuff_used(_sbuff_or_marker)
#define fr_sbuff_in_strcpy_literal(_sbuff, _str)
#define FR_SBUFF_IN_STRCPY_RETURN(...)
#define FR_SBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max)
#define FR_SBUFF_IN_BSTRCPY_BUFFER_RETURN(...)
Set of terminal elements.
#define tmpl_contains_xlat(vpt)
#define TMPL_VERIFY(_vpt)
#define tmpl_value_length(_tmpl)
static char const * tmpl_type_to_str(tmpl_type_t type)
Return a static string containing the type name.
#define tmpl_is_uninitialised(vpt)
Helpers to verify the type of tmpl_t.
#define tmpl_is_attr_unresolved(vpt)
enum requests_ref_e tmpl_request_ref_t
static bool tmpl_attr_tail_is_unspecified(tmpl_t const *vpt)
Return true if the last attribute reference is "unspecified".
#define tmpl_rules_enumv(_tmpl)
static bool tmpl_attr_tail_is_normal(tmpl_t const *vpt)
Return true if the last attribute reference is "normal".
#define tmpl_value(_tmpl)
#define ar_is_unknown(_ar)
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)
fr_value_box_safe_for_t literals_safe_for
safe_for value assigned to literal values in xlats, execs, and data.
#define tmpl_is_attr(vpt)
fr_dict_attr_t const  * enumv
Enumeration attribute used to resolve enum values.
tmpl_rules_t const  * parent
for parent / child relationships
#define tmpl_value_enumv(_tmpl)
static fr_dict_attr_t const * tmpl_list(tmpl_t const *vpt)
static bool tmpl_attr_is_list_attr(tmpl_attr_t const *ar)
Return true if the tmpl_attr is one of the list types.
#define ar_filter_is_num(_ar)
#define tmpl_rules_cast(_tmpl)
@ TMPL_TYPE_REGEX_UNCOMPILED
Regex where compilation is possible but hasn't been performed yet.
@ TMPL_TYPE_MAX
Marker for the last tmpl type.
@ TMPL_TYPE_ATTR_UNRESOLVED
An attribute reference that we couldn't resolve but looked valid.
@ TMPL_TYPE_ATTR
Reference to one or more attributes.
@ TMPL_TYPE_XLAT
Pre-parsed xlat expansion.
@ TMPL_TYPE_EXEC
Callout to an external script or program.
@ TMPL_TYPE_REGEX_XLAT_UNRESOLVED
A regular expression with unresolved xlat functions or attribute references.
@ TMPL_TYPE_DATA
Value in native boxed format.
@ TMPL_TYPE_REGEX
Compiled (and possibly JIT'd) regular expression.
@ TMPL_TYPE_DATA_UNRESOLVED
Unparsed literal string.
@ TMPL_TYPE_XLAT_UNRESOLVED
A xlat expansion with unresolved xlat functions or attribute references.
@ TMPL_TYPE_REGEX_XLAT
A regex containing xlat expansions.
@ TMPL_TYPE_EXEC_UNRESOLVED
An exec with unresolved xlat function or attribute references.
@ TMPL_TYPE_UNINITIALISED
Uninitialised.
#define tmpl_is_regex_xlat(vpt)
#define tmpl_assert_type(_cond)
Convenience macro for printing a meaningful assert message when we get a bad tmpl type.
#define tmpl_contains_attr(vpt)
#define TMPL_FLAG_REGEX
Is a type of regular expression.
#define ar_filter_is_cond(_ar)
tmpl_xlat_rules_t xlat
Rules/data for parsing xlats.
static char const * tmpl_attr_tail_unresolved(tmpl_t const *vpt)
Return the last attribute reference unresolved da.
bool at_runtime
Produce an ephemeral/runtime tmpl.
static bool tmpl_is_list(tmpl_t const *vpt)
#define TMPL_ATTR_VERIFY(_vpt)
bool force_dict_def
Use supplied dict_def even if original vpt->rules->dict_def was not NULL.
#define tmpl_is_data(vpt)
fr_dict_t const  * dict_def
Alternative default dictionary to use if vpt->rules->dict_def is NULL.
static size_t tmpl_attr_num_elements(tmpl_t const *vpt)
The number of attribute references contained within a tmpl.
#define tmpl_value_type(_tmpl)
@ TMPL_ATTR_ERROR_INVALID_ARRAY_INDEX
Invalid array index.
@ TMPL_ATTR_ERROR_LIST_NOT_ALLOWED
List qualifier is not allowed here.
@ TMPL_ATTR_ERROR_UNRESOLVED_NOT_ALLOWED
Attribute couldn't be found in the dictionaries.
@ TMPL_ATTR_ERROR_BAD_CAST
Specified cast was invalid.
@ TMPL_ATTR_ERROR_INVALID_NAME
Attribute ref length is zero, or longer than the maximum.
@ TMPL_ATTR_ERROR_MISSING_TERMINATOR
Unexpected text found after attribute reference.
@ TMPL_ATTR_ERROR_LIST_MISSING
List qualifier is required, but missing.
@ TMPL_ATTR_ERROR_NONE
No error.
@ TMPL_ATTR_ERROR_FOREIGN_NOT_ALLOWED
Attribute resolved in a dictionary different to the one specified.
@ TMPL_ATTR_ERROR_UNKNOWN_NOT_ALLOWED
Attribute specified as OID, could not be found in the dictionaries, and is disallowed because 'disall...
@ TMPL_ATTR_ERROR_FILTER_NOT_ALLOWED
Filters disallowed by rules.
@ TMPL_ATTR_ERROR_EMPTY
Attribute ref contains no data.
@ TMPL_ATTR_ERROR_NESTING_TOO_DEEP
Too many levels of nesting.
#define tmpl_is_data_unresolved(vpt)
fr_type_t cast
Whether there was an explicit cast.
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
@ TMPL_ATTR_LIST_REQUIRE
Attribute refs are required to have a list.
@ TMPL_ATTR_LIST_ALLOW
Attribute refs are allowed to have a list.
@ TMPL_ATTR_LIST_FORBID
Attribute refs are forbidden from having a list.
enum tmpl_type_e tmpl_type_t
Types of tmpl_t.
static fr_dict_attr_t const * tmpl_attr_tail_unknown(tmpl_t const *vpt)
Return the last attribute reference unknown da.
#define tmpl_is_regex(vpt)
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.
static bool tmpl_attr_tail_is_raw(tmpl_t const *vpt)
Return true if the last attribute reference is "raw".
@ REQUEST_OUTER
request_t containing the outer layer of the EAP conversation.
@ REQUEST_PARENT
Parent (whatever it is).
@ REQUEST_UNKNOWN
Unknown request.
@ REQUEST_CURRENT
The current request (default).
struct tmpl_rules_s tmpl_rules_t
#define tmpl_is_regex_xlat_unresolved(vpt)
#define tmpl_is_regex_uncompiled(vpt)
fr_dict_attr_t const  * enumv
for resolving T_BARE_WORD
#define TMPL_MAX_REQUEST_REF_NESTING
The maximum number of request references allowed.
@ TMPL_ATTR_TYPE_UNSPEC
No attribute was specified as this level only a filter.
@ TMPL_ATTR_TYPE_NORMAL
Normal, resolved, attribute ref.
@ TMPL_ATTR_TYPE_UNKNOWN
We have an attribute number but it doesn't match anything in the dictionary, or isn't a child of the ...
@ TMPL_ATTR_TYPE_UNRESOLVED
We have a name, but nothing else to identify the attribute.
@ TMPL_ATTR_FILTER_TYPE_TMPL
Filter is a tmpl.
@ TMPL_ATTR_FILTER_TYPE_INDEX
Filter is an index type.
@ TMPL_ATTR_FILTER_TYPE_CONDITION
Filter is a condition.
@ TMPL_ATTR_FILTER_TYPE_NONE
No filter present.
@ TMPL_ATTR_FILTER_TYPE_EXPR
Filter is an expression.
fr_event_list_t * runtime_el
The eventlist to use for runtime instantiation of xlats.
#define tmpl_needs_resolving(vpt)
tmpl_attr_filter_type_t _CONST type
Type of filter this is.
#define ar_filter_is_none(_ar)
Similar to tmpl_rules_t, but used to specify parameters that may change during subsequent resolution ...
Optional arguments passed to vp_tmpl functions.
static char buff[sizeof("18446744073709551615")+3]
ssize_t fr_skip_condition(char const *start, char const *end, bool const terminal[static UINT8_MAX+1], bool *eol)
Skip a conditional expression.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
fr_aka_sim_id_type_t type
Define entry and head types for tmpl request references.
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.
uint8_t disallow_filters
disallow filters.
uint8_t allow_unresolved
Allow attributes that look valid but were not found in the dictionaries.
uint8_t allow_foreign
Allow arguments not found in dict_def.
fr_dict_t const  * dict_def
Default dictionary to use with unqualified attribute references.
uint8_t allow_wildcard
Allow the special case of .
uint8_t allow_unknown
Allow unknown attributes i.e.
An element in a list of nested attribute references.
unsigned int _CONST resolve_only
This reference and those before it.
unsigned int _CONST is_raw
fr_dict_attr_t const  *_CONST da
Resolved dictionary attribute.
fr_dict_attr_t const  *_CONST parent
The parent we used when trying to resolve the attribute originally.
tmpl_attr_filter_t _CONST filter
Filter associated with the attribute reference.
tmpl_attr_type_t _CONST type
is a raw reference
Define manipulation functions for the attribute reference list.
tmpl_request_ref_t _CONST request
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
An element in an arbitrarily ordered array of name to num mappings.
An element in a lexicographically sorted array of name to num mappings.
char * talloc_bstrdup(TALLOC_CTX *ctx, char const *in)
Binary safe strdup function.
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
#define talloc_get_type_abort_const
static int talloc_const_free(void const *ptr)
Free const'd memory.
#define talloc_pooled_object(_ctx, _type, _num_subobjects, _total_subobjects_size)
fr_slen_t fr_time_delta_from_substr(fr_time_delta_t *out, fr_sbuff_t *in, fr_time_res_t hint, bool no_trailing, fr_sbuff_term_t const *tt)
Create fr_time_delta_t from a string.
A time delta, a difference in time measured in nanoseconds.
Escaping rules for tmpls.
int8_t tmpl_request_ref_list_cmp(FR_DLIST_HEAD(tmpl_request_list) const *a, FR_DLIST_HEAD(tmpl_request_list) const *b)
Compare a list of request qualifiers.
static ssize_t tmpl_afrom_time_delta(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules)
void tmpl_request_ref_list_debug(FR_DLIST_HEAD(tmpl_request_list) const *rql)
Dump a request list to stderr.
fr_slen_t tmpl_request_ref_list_print(fr_sbuff_t *out, FR_DLIST_HEAD(tmpl_request_list) const *rql)
void tmpl_attr_set_list(tmpl_t *vpt, fr_dict_attr_t const *list)
tmpl_t * tmpl_init_shallow(tmpl_t *vpt, tmpl_type_t type, fr_token_t quote, char const *name, ssize_t len, tmpl_rules_t const *t_rules)
Initialise a tmpl without copying the input name string.
fr_slen_t tmpl_request_ref_list_afrom_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, FR_DLIST_HEAD(tmpl_request_list) **out, fr_sbuff_t *in)
Parse one or more request references, allocing a new list and adding the references to it.
static fr_table_num_sorted_t const attr_num_table[]
Special attribute reference indexes.
void tmpl_unresolve(tmpl_t *vpt)
Reset the tmpl, leaving only the name in place.
void tmpl_set_xlat(tmpl_t *vpt, xlat_exp_head_t *xlat)
Change the default dictionary in the tmpl's resolution rules.
static void tmpl_type_init(tmpl_t *vpt, tmpl_type_t type)
Initialise fields inside a tmpl depending on its type.
#define RESOLVED_SET(_flags)
static fr_slen_t tmpl_attr_ref_afrom_unresolved_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t *vpt, fr_dict_attr_t const *parent, fr_dict_attr_t const *namespace, fr_sbuff_t *name, tmpl_attr_rules_t const *at_rules)
Parse an unresolved attribute, i.e.
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.
void tmpl_set_name_printf(tmpl_t *vpt, fr_token_t quote, char const *fmt,...)
Set the name on a pre-initialised tmpl.
int tmpl_attr_set_da(tmpl_t *vpt, fr_dict_attr_t const *da)
Replace the current attribute reference.
void tmpl_attr_ref_debug(FILE *fp, const tmpl_attr_t *ar, int i)
static fr_table_num_ordered_t const attr_table[]
Attr ref types.
static int tmpl_xlat_resolve(tmpl_t *vpt, tmpl_res_rules_t const *tr_rules)
Resolve an unresolved xlat, i.e.
fr_table_num_sorted_t const tmpl_request_ref_table[]
Map keywords to tmpl_request_ref_t values.
void tmpl_attr_debug(FILE *fp, tmpl_t const *vpt)
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.
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.
int tmpl_attr_unknown_add(tmpl_t *vpt)
Add an unknown fr_dict_attr_t specified by a tmpl_t to the main dictionary.
fr_slen_t tmpl_attr_print(fr_sbuff_t *out, tmpl_t const *vpt)
Print an attribute or list tmpl_t to a string.
void tmpl_set_escape(tmpl_t *vpt, tmpl_escape_t const *escape)
Set escape parameters for the tmpl output.
bool tmpl_async_required(tmpl_t const *vpt)
Return whether or not async is required for this tmpl.
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.
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.
static fr_slen_t tmpl_attr_ref_from_unspecified_substr(tmpl_attr_t *ar, tmpl_attr_error_t *err, tmpl_t *vpt, fr_sbuff_t *name, tmpl_attr_rules_t const *at_rules)
static void attr_to_raw(tmpl_t *vpt, tmpl_attr_t *ref)
tmpl_t * tmpl_init_printf(tmpl_t *vpt, tmpl_type_t type, fr_token_t quote, char const *fmt,...)
Initialise a tmpl using a format string to create the name.
static void tmpl_attr_insert(tmpl_t *vpt, tmpl_attr_t *ar)
Insert an attribute reference into a tmpl.
void tmpl_attr_ref_list_debug(FILE *fp, FR_DLIST_HEAD(tmpl_attr_list) const *ar_head)
int tmpl_cast_set(tmpl_t *vpt, fr_type_t dst_type)
Set a cast for a tmpl.
static fr_slen_t tmpl_afrom_ipv4_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules)
Parse bareword as an IPv4 address or prefix.
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.
int tmpl_attr_afrom_list(TALLOC_CTX *ctx, tmpl_t **out, tmpl_t const *list, fr_dict_attr_t const *da)
Create a new tmpl from a list tmpl and a da.
void tmpl_attr_to_raw(tmpl_t *vpt)
Convert the leaf attribute of a tmpl to a unknown/raw type.
tmpl_t * tmpl_copy(TALLOC_CTX *ctx, tmpl_t const *in)
Copy a tmpl.
void tmpl_attr_rewrite_leaf_num(tmpl_t *vpt, int16_t to)
Rewrite the leaf's instance number.
static bool tmpl_substr_terminal_check(fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules)
Verify, after skipping whitespace, that a substring ends in a terminal char, or ends without further ...
static const bool array_terminal[UINT8_MAX+1]
static void tmpl_request_ref_list_copy(TALLOC_CTX *ctx, FR_DLIST_HEAD(tmpl_request_list) *out, FR_DLIST_HEAD(tmpl_request_list) const *in)
Allocate a new request reference and add it to the end of the attribute reference list.
static void tmpl_attr_rules_debug(tmpl_attr_rules_t const *at_rules)
ssize_t tmpl_preparse(char const **out, size_t *outlen, char const *in, size_t inlen, fr_token_t *type)
Preparse a string in preparation for passing it to tmpl_afrom_substr()
#define TMPL_REQUEST_REF_DEF(_name, _ref)
Define a global variable for specifying a default request reference.
#define UNRESOLVED_SET(_flags)
void tmpl_set_name_shallow(tmpl_t *vpt, fr_token_t quote, char const *name, ssize_t len)
Set the name on a pre-initialised tmpl.
static int tmpl_attr_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t *vpt, fr_dict_attr_t const *parent, fr_dict_attr_t const *namespace, fr_sbuff_t *name, fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *at_rules, unsigned int depth)
Parse an attribute reference, either an OID or attribute name.
static fr_slen_t tmpl_afrom_ipv6_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules)
Parse bareword as an IPv6 address or prefix.
static fr_slen_t tmpl_afrom_bool_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules)
Parse a truth value.
static tmpl_attr_t * tmpl_attr_add(tmpl_t *vpt, tmpl_attr_type_t type)
Allocate a new attribute reference and add it to the end of the attribute reference list.
static size_t attr_num_table_len
void tmpl_debug(FILE *fp, tmpl_t const *vpt)
ssize_t tmpl_afrom_attr_str(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t **out, char const *name, tmpl_rules_t const *t_rules)
Parse a string into a TMPL_TYPE_ATTR_* type tmpl_t.
ssize_t tmpl_cast_from_substr(tmpl_rules_t *rules, fr_sbuff_t *in)
Parse a cast specifier.
static tmpl_t * tmpl_alloc_null(TALLOC_CTX *ctx)
Create a new heap allocated tmpl_t.
static fr_slen_t tmpl_request_ref_list_from_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, FR_DLIST_HEAD(tmpl_request_list) *out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, fr_dict_attr_t const **namespace)
Parse one or more request references, writing the list to out.
void tmpl_rules_debug(tmpl_rules_t const *rules)
int tmpl_attr_copy(tmpl_t *dst, tmpl_t const *src)
Copy a list of attribute and request references from one tmpl to another.
static ssize_t tmpl_afrom_ether_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules)
Try and parse signed or unsigned integers.
static ssize_t tmpl_afrom_float_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules)
static fr_slen_t tmpl_afrom_octets_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules)
Parse bareword as an octet string.
size_t tmpl_type_table_len
static int tmpl_attr_resolve(tmpl_t *vpt, tmpl_res_rules_t const *tr_rules)
Resolve an unresolved attribute.
static ssize_t tmpl_afrom_enum(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules)
int tmpl_attr_set_leaf_da(tmpl_t *vpt, fr_dict_attr_t const *da)
Replace the leaf attribute only.
fr_slen_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_token_t tmpl_cast_quote(fr_token_t existing_quote, fr_type_t type, fr_dict_attr_t const *enumv, char const *unescaped, size_t unescaped_len)
Determine the correct quoting after a cast.
fr_dict_attr_t const  * tmpl_attr_unspec
Placeholder attribute for uses of unspecified attribute references.
static fr_slen_t tmpl_afrom_value_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_token_t quote, tmpl_rules_t const *t_rules, bool allow_enum, fr_sbuff_parse_rules_t const *p_rules)
Create TMPL_TYPE_DATA from a string.
int tmpl_resolve(tmpl_t *vpt, tmpl_res_rules_t const *tr_rules)
Attempt to resolve functions and attributes in xlats and attribute references.
void tmpl_set_dict_def(tmpl_t *vpt, fr_dict_t const *dict)
Change the default dictionary in the tmpl's resolution rules.
tmpl_t * tmpl_init(tmpl_t *vpt, tmpl_type_t type, fr_token_t quote, char const *name, ssize_t len, tmpl_rules_t const *t_rules)
Initialise a tmpl using a literal string to create the name.
static void tmpl_request_ref_list_acopy(TALLOC_CTX *ctx, FR_DLIST_HEAD(tmpl_request_list) **out, FR_DLIST_HEAD(tmpl_request_list) const *in)
Allocate a new request reference list and copy request references into it.
fr_slen_t tmpl_print(fr_sbuff_t *out, tmpl_t const *vpt, fr_sbuff_escape_rules_t const *e_rules)
Print a tmpl_t to a string.
static fr_slen_t tmpl_afrom_integer_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules)
Try and parse signed or unsigned integers.
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...
fr_slen_t tmpl_print_quoted(fr_sbuff_t *out, tmpl_t const *vpt)
Print a tmpl_t to a string with quotes.
static void tmpl_attr_ref_fixup(TALLOC_CTX *ctx, tmpl_t *vpt, fr_dict_attr_t const *da, fr_dict_attr_t const *parent)
static fr_slen_t tmpl_attr_parse_filter(tmpl_attr_error_t *err, tmpl_attr_t *ar, fr_sbuff_t *name, tmpl_attr_rules_t const *at_rules)
Parse array subscript and in future other filters.
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.
#define DEFAULT_RULES
Default parser rules.
fr_table_num_ordered_t const tmpl_type_table[]
Map tmpl_type_t values to descriptive strings.
static size_t attr_table_len
int tmpl_attr_tail_unresolved_add(fr_dict_t *dict_def, tmpl_t *vpt, fr_type_t type, fr_dict_attr_flags_t const *flags)
Add an unresolved fr_dict_attr_t specified by a tmpl_t to the main dictionary.
size_t tmpl_request_ref_table_len
fr_table_num_sorted_t const fr_token_quotes_table[]
const char fr_token_quote[T_TOKEN_LAST]
Convert tokens back to a quoting character.
@ T_SOLIDUS_QUOTED_STRING
bool xlat_needs_resolving(xlat_exp_head_t const *head)
Check to see if the expansion needs resolving.
bool xlat_is_literal(xlat_exp_head_t const *head)
Check to see if the expansion consists entirely of value-box elements.
fr_slen_t xlat_tokenize_condition(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_slen_t xlat_print(fr_sbuff_t *in, xlat_exp_head_t const *node, fr_sbuff_escape_rules_t const *e_rules)
Reconstitute an xlat expression from its constituent nodes.
bool xlat_impure_func(xlat_exp_head_t const *head)
fr_slen_t xlat_tokenize(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)
Tokenize an xlat expansion.
static fr_slen_t xlat_aprint(TALLOC_CTX *ctx, char **out, xlat_exp_head_t const *head, fr_sbuff_escape_rules_t const *e_rules) 1(xlat_print
bool xlat_to_string(TALLOC_CTX *ctx, char **str, xlat_exp_head_t **head)
Convert an xlat node to an unescaped literal string and free the original node.
#define xlat_copy(_ctx, _out, _in)
int xlat_resolve(xlat_exp_head_t *head, xlat_res_rules_t const *xr_rules)
Walk over an xlat tree recursively, resolving any unresolved functions or references.
int xlat_finalize(xlat_exp_head_t *head, fr_event_list_t *runtime_el)
Bootstrap static xlats, or instantiate ephemeral ones.
fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in, xlat_arg_parser_t const *xlat_args, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, bool spaces))
Tokenize an xlat expansion into a series of XLAT_TYPE_CHILD arguments.
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))
Structure for holding the stack of dictionary attributes being encoded.
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const_push(_msg)
#define fr_strerror_const(_msg)
fr_table_num_ordered_t const fr_type_table[]
Map data types to names representing those types.
bool fr_type_cast(fr_type_t dst, fr_type_t src)
Return if we're allowed to cast the types.
bool const fr_type_numeric[FR_TYPE_MAX+1]
bool const fr_type_structural[FR_TYPE_MAX+1]
#define FR_TYPE_STRUCTURAL_EXCEPT_GROUP
#define fr_type_is_non_leaf(_x)
#define fr_type_is_octets(_x)
#define fr_type_is_structural(_x)
#define fr_type_is_string(_x)
#define FR_TYPE_STRUCTURAL
#define fr_type_is_null(_x)
#define fr_type_is_leaf(_x)
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
ssize_t fr_value_box_print(fr_sbuff_t *out, fr_value_box_t const *data, fr_sbuff_escape_rules_t const *e_rules)
Print one boxed value to a string.
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_cast_in_place(TALLOC_CTX *ctx, fr_value_box_t *vb, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv)
Convert one type of fr_value_box_t to another in place.
void fr_value_box_memdup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, uint8_t const *src, size_t len, bool tainted)
Assign a buffer to a box, but don't copy it.
void fr_value_box_copy_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *src)
Perform a shallow copy of a value_box.
ssize_t fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, char const *in, size_t inlen, fr_sbuff_unescape_rules_t const *erules)
fr_sbuff_escape_rules_t * fr_value_escape_by_quote[T_TOKEN_LAST]
int fr_value_box_steal(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t *src)
Copy value data verbatim moving any buffers to the specified context.
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
ssize_t fr_value_box_from_substr(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *rules)
Convert string value to a fr_value_box_t type.
int fr_value_box_memdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, uint8_t const *src, size_t len, bool tainted)
Copy a buffer to a fr_value_box_t.
#define fr_value_box_mark_safe_for(_box, _safe_for)
static fr_slen_t fr_value_box_aprint(TALLOC_CTX *ctx, char **out, fr_value_box_t const *data, fr_sbuff_escape_rules_t const *e_rules) 1(fr_value_box_print
#define fr_box_strvalue_len(_val, _len)
static size_t char fr_sbuff_t size_t inlen
#define fr_value_box_init(_vb, _type, _enumv, _tainted)
Initialise a fr_value_box_t.
static size_t char ** out
#define xlat_exp_head_alloc(_ctx)
@ XLAT_TMPL
xlat attribute
xlat_type_t _CONST type
type of this expansion.
static xlat_exp_t * xlat_exp_head(xlat_exp_head_t const *head)