26RCSID(
"$Id: 5c4893883c1273767a97253fbec87bceb58671c0 $")
31#include <freeradius-devel/server/base.h>
32#include <freeradius-devel/server/tmpl_dcursor.h>
33#include <freeradius-devel/unlang/interpret.h>
34#include <freeradius-devel/unlang/xlat_priv.h>
36#include <freeradius-devel/unlang/xlat.h>
37#include <freeradius-devel/io/test_point.h>
39#include <freeradius-devel/util/base16.h>
40#include <freeradius-devel/util/dbuff.h>
41#include <freeradius-devel/util/dcursor.h>
42#include <freeradius-devel/util/pair.h>
43#include <freeradius-devel/util/table.h>
45#ifdef HAVE_OPENSSL_EVP_H
46# include <freeradius-devel/tls/openssl_user_macros.h>
47# include <openssl/evp.h>
53static char const hextab[] =
"0123456789abcdef";
73 fr_value_box_list_remove(
in, vb);
74 if (talloc_parent(vb) != ctx) {
75 (void) talloc_steal(ctx, vb);
110 vb->vb_int8 = request->log.lvl;
116 if (!lvl_vb)
goto done;
118 level = lvl_vb->vb_int8;
123 request->log.lvl = level;
172 if (slen <= 0)
return;
174 switch (
vp->vp_type) {
204 switch (
vp->vp_type) {
241 if ((pad = (11 -
type->name.len)) < 0) pad = 0;
244 RDEBUG4(
"as %s%*s: %pV",
type->name.str, pad,
" ", dst);
302 RDEBUG(
"Attributes matching \"%s\"", in_head->vb_cursor_name);
316#pragma clang diagnostic ignored "-Wgnu-designator"
326 [ 0x00 ... 0x2d ] =
true,
328 [ 0x3A ... 0x3f ] =
true,
329 [ 0x5b ... 0x5e ] =
true,
331 [ 0x7b ... 0xff ] =
true,
342 [ 0x00 ... 0x2f ] =
true,
343 [ 0x3A ... 0x3f ] =
true,
344 [ 0x5b ... 0x5e ] =
true,
346 [ 0x7b ... 0xff ] =
true,
350#define FR_FILENAME_SAFE_FOR ((uintptr_t) filename_xlat_escape)
355 fr_value_box_entry_t entry;
426 if (vb->vb_strvalue[0] ==
'.') {
462 char const *filename;
467 filename = vb->vb_strvalue;
472 dst->vb_bool = (stat(filename, &buf) == 0);
483 char const *filename;
490 filename = vb->vb_strvalue;
492 fd = open(filename, O_RDONLY);
509 if ((*p ==
'\r') || (*p ==
'\n')) {
513 if ((*p <
' ') && (*p !=
'\t')) {
515 REDEBUG(
"Invalid text in file %s", filename);
521 if ((p -
buffer) > len)
goto invalid;
541 char const *filename;
546 filename = vb->vb_strvalue;
548 if (stat(filename, &buf) < 0) {
556 dst->vb_uint64 = buf.st_size;
567 char const *filename;
572 char *p, *end, *found,
buffer[256];
576 filename = vb->vb_strvalue;
578 fd = open(filename, O_RDONLY);
584 offset = lseek(fd, 0, SEEK_END);
596 if (lseek(fd, offset, SEEK_SET) < 0) {
597 REDEBUG3(
"Failed seeking backwards from end of file %s - %s", filename,
fr_syserror(errno));
616 if (len <= 1)
goto done;
626 fr_assert(fr_value_box_list_num_elements(&num->vb_group) == 1);
628 num = fr_value_box_list_head(&num->vb_group);
631 if (!num->vb_uint32) {
634 }
else if (num->vb_uint32 <= 16) {
635 stop = num->vb_uint64;
686 if ((crlf ==
stop) && (*found <
' ')) {
746 { .required =
true, .type =
FR_TYPE_SIZE, .single =
true },
755 char const *filename;
763 filename = vb->vb_strvalue;
765 fd = open(filename, O_RDONLY);
771 if (fstat(fd, &buf) < 0) {
778 if ((
size_t)buf.st_size > max_size->vb_size) {
779 RPERROR(
"File larger than specified maximum (%"PRIu64
" vs %zu)", buf.st_size, max_size->vb_size);
786 len = read(fd,
buffer, buf.st_size);
804 char const *filename;
808 filename = vb->vb_strvalue;
813 dst->vb_bool = (unlink(filename) == 0);
825 char const *filename;
830 filename = vb->vb_strvalue;
835 fd = open(filename, O_CREAT | S_IRUSR | S_IWUSR, 0600);
837 dst->vb_bool =
false;
855 dirname = vb->vb_strvalue;
860 dst->vb_bool = (
fr_mkdir(NULL, dirname, -1, 0700, NULL, NULL) == 0);
876 dirname = vb->vb_strvalue;
881 dst->vb_bool = (rmdir(dirname) == 0);
902 while ((vb = fr_value_box_list_pop_head(
in)) != NULL) {
915 while ((vb = fr_value_box_list_pop_head(
in)) != NULL) {
920 while ((child = fr_value_box_list_pop_head(&vb->vb_group)) != NULL) {
921 child->tainted =
true;
958 fr_value_box_list_t *list;
969 if (delim_vb->vb_length == 0) {
970 REDEBUG(
"Delimiter must be greater than zero characters");
974 delim = delim_vb->vb_strvalue;
975 delim_len = delim_vb->vb_length;
977 while ((
string = fr_value_box_list_pop_head(list))) {
989 fr_sbuff_set_to_start(&sbuff);
990 fr_sbuff_marker(&m_start, &sbuff);
1011 fr_sbuff_set_to_end(&sbuff);
1047 RDEBUG(
"Attributes matching \"%s\"", in_head->vb_cursor_name);
1087 fr_value_box_list_remove(
args, in_vb);
1089 switch (in_vb->type) {
1092 RPEDEBUG(
"Failed converting %pR (%s) to an integer", in_vb,
1102 in_vb->enumv = NULL;
1124 for (p = in_vb->vb_strvalue; *p !=
'\0'; p++) {
1125 if (*p ==
'-')
break;
1136 if (in_vb->vb_length >
sizeof(uint64_t)) {
1137 fr_strerror_printf(
"Expected octets length <= %zu, got %zu",
sizeof(uint64_t), in_vb->vb_length);
1141 if (in_vb->vb_length >
sizeof(
uint32_t)) {
1143 }
else if (in_vb->vb_length >
sizeof(
uint16_t)) {
1145 }
else if (in_vb->vb_length >
sizeof(
uint8_t)) {
1172 memcpy(&ipv6int, &in_vb->vb_ipv6addr,
sizeof(ipv6int));
1213 RINFO(
"%s", vb->vb_strvalue);
1238 RDEBUG(
"%s", vb->vb_strvalue);
1263 REDEBUG(
"%s", vb->vb_strvalue);
1288 RWDEBUG(
"%s", vb->vb_strvalue);
1325 if (!dst || !*dst->vb_strvalue) {
1333 if (lvl) level = lvl->vb_uint32;
1343 MEM(dbg = talloc_memdup(request, log,
sizeof(*log)));
1350 dbg->
file = talloc_strdup(dbg,
file->vb_strvalue);
1351 dbg->
fd = open(dbg->
file, O_WRONLY | O_CREAT | O_CLOEXEC, 0600);
1407 vb->vb_bool =
false;
1412 RPEDEBUG(
"Failed parsing \"%s\" as map", fmt_vb->vb_strvalue);
1416 switch (map->
lhs->type) {
1422 REDEBUG(
"Unexpected type %s in left hand side of expression",
1427 switch (map->
rhs->type) {
1437 REDEBUG(
"Unexpected type %s in right hand side of expression",
1479 struct tm *local, local_buff;
1491 p = in_head->vb_strvalue;
1493 num = strtoul(p, &q, 10);
1494 if (!q || *q ==
'\0') {
1495 REDEBUG(
"<int> must be followed by time period (h|d|w|m|y)");
1510 local->tm_hour += num;
1515 local->tm_mday += num;
1520 local->tm_mday += (7 - local->tm_wday) + (7 * (num-1));
1526 local->tm_mon += num;
1533 local->tm_year += num;
1537 REDEBUG(
"Invalid time period '%c', must be h|d|w|m|y", *p);
1542 fr_value_box_uint64(vb, NULL, (uint64_t)(mktime(local) - now),
false);
1612 &(fr_sbuff_parse_rules_t){
1613 .escapes = &escape_rules
1617 .dict_def = request->local_dict,
1618 .list_def = request_attr_request,
1619 .allow_unknown = false,
1620 .allow_unresolved = false,
1621 .allow_foreign = false,
1624 .runtime_el = unlang_interpret_event_list(request),
1628 RPEDEBUG(
"Failed parsing expansion");
1639 if (rctx->ex->flags.needs_resolving &&
1641 RPEDEBUG(
"Unresolved expansion functions in expansion");
1682 fr_value_box_list_t *list;
1686 char const *fill_str = NULL;
1687 size_t fill_len = 0;
1694 list = &values->vb_group;
1696 pad_len = (
size_t)pad->vb_uint64;
1702 fill_str =
fill->vb_strvalue;
1703 fill_len = talloc_array_length(fill_str) - 1;
1706 if (fill_len == 0) {
1711 while ((
in = fr_value_box_list_pop_head(list))) {
1712 size_t len = talloc_array_length(
in->vb_strvalue) - 1;
1720 if (len >= pad_len)
continue;
1723 RPEDEBUG(
"Failed reallocing input data");
1728 fr_sbuff_marker(&m_data, &sbuff);
1739 if (fill_len == 1) {
1748 size_t to_copy = remaining >= fill_len ? fill_len : remaining;
1752 fr_sbuff_set_to_end(&sbuff);
1753 fr_sbuff_terminate(&sbuff);
1777 fr_value_box_list_t *list;
1782 char const *fill_str = NULL;
1783 size_t fill_len = 0;
1789 list = &values->vb_group;
1790 pad_len = (
size_t)pad->vb_uint64;
1796 fill_str =
fill->vb_strvalue;
1797 fill_len = talloc_array_length(fill_str) - 1;
1800 if (fill_len == 0) {
1805 while ((
in = fr_value_box_list_pop_head(list))) {
1806 size_t len = talloc_array_length(
in->vb_strvalue) - 1;
1813 if (len >= pad_len)
continue;
1817 RPEDEBUG(
"Failed reallocing input data");
1824 if (fill_len == 1) {
1833 if (
fr_sbuff_in_bstrncpy(&sbuff, fill_str, remaining >= fill_len ? fill_len : remaining) < 0) {
1879 RPEDEBUG(
"Base64 encoding failed");
1921 if (
in->vb_length == 0) {
1968 char const *p, *end;
1976 while ((hex = fr_value_box_list_pop_head(&list->vb_group))) {
1977 len = hex->vb_length;
1978 if ((len > 1) && (len & 0x01)) {
1979 REDEBUG(
"Input data length must be >1 and even, got %zu", len);
1983 p = hex->vb_strvalue;
1989 if ((p[0] ==
'0') && (p[1] ==
'x')) {
1997 if (p == end)
continue;
2040 struct timespec ts_in, ts_remain = {};
2046 (void)nanosleep(&ts_in, &ts_remain);
2090 RPEDEBUG(
"Failed parsing '%pV' as a numerical data type",
name);
2098 RPEDEBUG(
"Failed parsing '%pV' as a string data type",
name);
2106 RDEBUG(
"Unknown data type '%s'",
name->vb_strvalue);
2114 (void) fr_value_box_list_pop_head(
args);
2150 RPEDEBUG(
"Failed concatenating string");
2165 while ((arg = fr_value_box_list_next(
args, arg)) != NULL) {
2170 vb = fr_value_box_list_head(&arg->vb_group);
2172 p = fr_value_box_list_remove(&arg->vb_group, vb);
2179 vb = fr_value_box_list_next(&arg->vb_group, p);
2214 fr_value_box_list_t *to_concat;
2220 sep = (separator) ? separator->vb_strvalue :
"";
2221 to_concat = &list->vb_group;
2226 RPEDEBUG(
"Failed concatenating input");
2231 if (!
buff)
goto error;
2266 while ((bin = fr_value_box_list_pop_head(&list->vb_group))) {
2272 MEM(new_buff = talloc_zero_array(bin,
char, (bin->vb_length * 2) + 1));
2273 if (bin->vb_length) {
2390 while ((vb = fr_value_box_list_pop_head(
in)) != NULL) {
2408 while ((arg = fr_value_box_list_next(
in, arg)) != NULL) {
2477 fr_md4_calc(digest, in_head->vb_octets, in_head->vb_length);
2517 fr_md5_calc(digest, in_head->vb_octets, in_head->vb_length);
2605 result = in_head->vb_uint32;
2608 if (result > (1 << 30)) result = (1 << 30);
2614 vb->vb_uint64 = result;
2659 static char randstr_punc[] =
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
2660 static char randstr_salt[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmopqrstuvwxyz/.";
2666 static char randstr_otp[] =
"469ACGHJKLMNPQRUVWXYabdfhijkprstuvwxyz";
2668 char const *p, *start, *end;
2671 unsigned int result;
2682#define REPETITION_MAX 1024
2684 start = p = in_head->vb_strvalue;
2685 end = p + in_head->vb_length;
2698 reps = strtol(p, &endptr, 10);
2718 reps = strtol(p, &endptr, 10);
2729 for (i = 0; i < reps; i++) {
2736 *buff_p++ =
'a' + (result % 26);
2743 *buff_p++ =
'A' + (result % 26);
2750 *buff_p++ =
'0' + (result % 10);
2757 *buff_p++ = randstr_salt[result % (
sizeof(randstr_salt) - 3)];
2764 *buff_p++ = randstr_punc[result % (
sizeof(randstr_punc) - 1)];
2771 *buff_p++ =
'!' + (result % 95);
2778 *buff_p++ = randstr_salt[result % (
sizeof(randstr_salt) - 1)];
2786 *buff_p++ = randstr_otp[result % (
sizeof(randstr_otp) - 1)];
2794 size_t copy = (reps - i) >
sizeof(result) ?
sizeof(result) : reps - i;
2796 memcpy(buff_p, (
uint8_t *)&result, copy);
2803 REDEBUG(
"Invalid character class '%c'", *p);
2827#define UUID_CHARS(_v, _num) for (i = 0; i < _num; i++) { \
2828 buffer[j++] = fr_base16_alphabet_encode_lc[(uint8_t)((vals[_v] & 0xf0000000) >> 28)]; \
2829 vals[_v] = vals[_v] << 4; \
2851 vals[1] = (vals[1] & 0xffff0fff) | (((
uint32_t)version & 0x0f) << 12);
2862 vals[2] = vals[2] & 0x7fffffff;
2866 vals[2] = (vals[2] & 0x3fffffff) | 0x80000000;
2870 vals[2] = (vals[2] & 0x3fffffff) | 0xc0000000;
2874 vals[2] = vals[2] | 0xe0000000;
2902 for (i = 0; i < 4; i++) vals[i] =
fr_rand();
2940 for (i = 1; i < 4; i++) vals[i] =
fr_rand();
2947 vals[0] = now >> 32;
2948 vals[1] = (vals[1] & 0x0000ffff) | (now & 0xffff0000);
2985 uint64_t i, start, end, step;
2990 start = fr_value_box_list_head(&start_vb->vb_group)->vb_uint64;
2991 end = fr_value_box_list_head(&end_vb->vb_group)->vb_uint64;
2992 step = fr_value_box_list_head(&step_vb->vb_group)->vb_uint64;
2994 }
else if (end_vb) {
2995 start = fr_value_box_list_head(&start_vb->vb_group)->vb_uint64;
2996 end = fr_value_box_list_head(&end_vb->vb_group)->vb_uint64;
3001 end = fr_value_box_list_head(&start_vb->vb_group)->vb_uint64;
3006 REDEBUG(
"Invalid range - 'start' must be less than 'end'");
3011 REDEBUG(
"Invalid range - 'step' must be greater than zero");
3015 if (step > (end - start)) {
3016 REDEBUG(
"Invalid range - 'step' must allow for at least one result");
3020 if (((end - start) / step) > 1000) {
3021 REDEBUG(
"Invalid range - Too many results");
3025 for (i = start; i < end; i += step) {
3038 fr_value_box_entry_t entry;
3043 if (slen < 0)
return -1;
3080 fr_value_box_t *arg = fr_value_box_list_head(&in_head->vb_group);
3089 if (regex_request_to_sub(vb, vb, request, 0) < 0) {
3090 REDEBUG2(
"No previous regex capture");
3100 switch (arg->type) {
3110 if (fr_value_box_list_next(
in, in_head)) {
3111 REDEBUG(
"Only one subcapture argument allowed");
3121 if (regex_request_to_sub(vb, vb, request, idx.vb_uint32) < 0) {
3122 REDEBUG2(
"No previous numbered regex capture group '%u'", idx.vb_uint32);
3132#if defined(HAVE_REGEX_PCRE) || defined(HAVE_REGEX_PCRE2)
3143 RPEDEBUG(
"Failed concatenating input");
3148 if (regex_request_to_sub_named(vb, vb, request, arg->vb_strvalue) < 0) {
3149 REDEBUG2(
"No previous named regex capture group '%s'", arg->vb_strvalue);
3158 RDEBUG(
"Named regex captures are not supported (they require libpcre2)");
3191 fr_sha1_update(&sha1_ctx, in_head->vb_octets, in_head->vb_length);
3215#ifdef HAVE_OPENSSL_EVP_H
3220 uint8_t digest[EVP_MAX_MD_SIZE];
3221 unsigned int digestlen;
3228 md_ctx = EVP_MD_CTX_create();
3229 EVP_DigestInit_ex(md_ctx, md, NULL);
3231 EVP_DigestUpdate(md_ctx, in_head->vb_octets, in_head->vb_length);
3233 EVP_DigestUpdate(md_ctx, NULL, 0);
3235 EVP_DigestFinal_ex(md_ctx, digest, &digestlen);
3236 EVP_MD_CTX_destroy(md_ctx);
3246# define EVP_MD_XLAT(_md, _md_func) \
3247static xlat_action_t xlat_func_##_md(TALLOC_CTX *ctx, fr_dcursor_t *out,\
3248 xlat_ctx_t const *xctx, \
3249 request_t *request,\
3250 fr_value_box_list_t *in)\
3252 return xlat_evp_md(ctx, out, xctx, request, in, EVP_##_md_func());\
3255EVP_MD_XLAT(sha2_224, sha224)
3256EVP_MD_XLAT(sha2_256, sha256)
3257EVP_MD_XLAT(sha2_384, sha384)
3258EVP_MD_XLAT(sha2_512, sha512)
3263#ifdef HAVE_EVP_BLAKE2S256
3264EVP_MD_XLAT(blake2s_256, blake2s256)
3267#ifdef HAVE_EVP_BLAKE2B512
3268EVP_MD_XLAT(blake2b_512, blake2b512)
3271EVP_MD_XLAT(sha3_224, sha3_224)
3272EVP_MD_XLAT(sha3_256, sha3_256)
3273EVP_MD_XLAT(sha3_384, sha3_384)
3274EVP_MD_XLAT(sha3_512, sha3_512)
3313 vb->vb_size = strlen(in_head->vb_strvalue);
3350 bool relaxed =
false;
3354 if (relaxed_vb) relaxed = relaxed_vb->vb_bool;
3356 p = (
uint8_t const *)str->vb_strvalue;
3357 end = p + str->vb_length;
3361 vb->vb_bool =
false;
3409 in_head->vb_length) >= 0);
3418 { .single =
true, .required =
true, .type =
FR_TYPE_INT32 },
3441 int32_t start, end, len;
3452 RPEDEBUG(
"Failed casting value to string");
3460 if (start_vb->vb_int32 < 0) {
3461 start =
in->vb_length + start_vb->vb_int32;
3462 if (start < 0) start = 0;
3464 start = start_vb->vb_int32;
3468 if (len_vb->vb_int32 < 0) {
3469 end =
in->vb_length + len_vb->vb_int32;
3472 end = start + len_vb->vb_int32;
3473 if (end > (int32_t)
in->vb_length) end =
in->vb_length;
3476 end =
in->vb_length;
3492 memcpy(buf, &
in->vb_octets[start], len);
3505#ifdef HAVE_REGEX_PCRE2
3510 fr_regex_flags_t flags;
3511} xlat_subst_regex_inst_t;
3517 xlat_subst_regex_inst_t *
inst = talloc_get_type_abort(xctx->
inst, xlat_subst_regex_inst_t);
3535 sbuff =
FR_SBUFF_IN(patt_exp->data.vb_strvalue, patt_exp->data.vb_length);
3544 fr_sbuff_marker(&start_m, &sbuff);
3548 fr_sbuff_marker(&end_m, &sbuff);
3549 fr_sbuff_next(&sbuff);
3552 slen = regex_flags_parse(NULL, &
inst->flags,
3556 PERROR(
"Failed parsing regex flags in \"%s\"", patt_exp->data.vb_strvalue);
3561 if (regex_compile(
inst, &
inst->pattern,
3563 &
inst->flags,
true,
false) <= 0) {
3564 PERROR(
"Failed compiling regex \"%s\"", patt_exp->data.vb_strvalue);
3594 fr_value_box_list_t *
args)
3601 regex_t *pattern, *our_pattern = NULL;
3602 fr_regex_flags_t
const *flags;
3603 fr_regex_flags_t our_flags = {};
3614 if (!
inst->pattern) {
3615 sbuff =
FR_SBUFF_IN(regex_vb->vb_strvalue, regex_vb->vb_length);
3617 REDEBUG(
"Regex must not be empty");
3621 fr_sbuff_next(&sbuff);
3622 fr_sbuff_marker(&start_m, &sbuff);
3626 fr_sbuff_marker(&end_m, &sbuff);
3627 fr_sbuff_next(&sbuff);
3629 slen = regex_flags_parse(NULL, &our_flags, &sbuff, NULL,
true);
3631 RPEDEBUG(
"Failed parsing regex flags");
3638 if (regex_compile(NULL, &our_pattern,
3640 &our_flags,
true,
true) <= 0) {
3641 RPEDEBUG(
"Failed compiling regex");
3644 pattern = our_pattern;
3647 pattern =
inst->pattern;
3648 flags = &
inst->flags;
3652 if (regex_substitute(vb, &
buff, 0, pattern, flags,
3653 subject_vb->vb_strvalue, subject_vb->vb_length,
3654 rep_vb->vb_strvalue, rep_vb->vb_length, NULL) < 0) {
3655 RPEDEBUG(
"Failed performing substitution");
3696#ifdef HAVE_REGEX_PCRE2
3703 char const *p, *q, *end;
3706 char const *pattern, *rep;
3707 size_t pattern_len, rep_len;
3716 pattern = pattern_vb->vb_strvalue;
3717 if (*pattern ==
'/') {
3718#ifdef HAVE_REGEX_PCRE2
3719 switch (xlat_func_subst_regex(ctx,
out, xctx, request,
args)) {
3731 if (memchr(pattern,
'/', pattern_vb->vb_length - 1)) {
3732 REDEBUG(
"regex based substitutions require libpcre2. "
3733 "Check ${features.regex-pcre2} to determine support");
3742 pattern_len = pattern_vb->vb_length;
3743 if (pattern_len == 0) {
3748 rep = rep_vb->vb_strvalue;
3749 rep_len = rep_vb->vb_length;
3751 p = subject_vb->vb_strvalue;
3752 end = p + subject_vb->vb_length;
3758 q = memmem(p, end - p, pattern, pattern_len);
3766 p = q + pattern_len;
3770 RPEDEBUG(
"Failed creating output box");
3794 fr_value_box_list_t *
args)
3797 {
L(
"break"), SIGTRAP },
3798 {
L(
"BREAK"), SIGTRAP },
3799 {
L(
"SIGABRT"), SIGABRT },
3800 {
L(
"SIGALRM"), SIGALRM },
3802 {
L(
"SIGBUS"), SIGBUS },
3804 {
L(
"SIGCHLD"), SIGCHLD },
3805 {
L(
"SIGCONT"), SIGCONT },
3806 {
L(
"SIGFPE"), SIGFPE },
3807 {
L(
"SIGHUP"), SIGHUP },
3808 {
L(
"SIGILL"), SIGILL },
3809 {
L(
"SIGINT"), SIGINT },
3810 {
L(
"SIGKILL"), SIGKILL },
3811 {
L(
"SIGPIPE"), SIGPIPE },
3813 {
L(
"SIGPOLL"), SIGPOLL },
3815 {
L(
"SIGPROF"), SIGPROF },
3816 {
L(
"SIGQUIT"), SIGQUIT },
3817 {
L(
"SIGSEGV"), SIGSEGV },
3818 {
L(
"SIGSTOP"), SIGSTOP },
3820 {
L(
"SIGSYS"), SIGSYS },
3822 {
L(
"SIGTERM"), SIGTERM },
3824 {
L(
"SIGTRAP"), SIGTRAP },
3826 {
L(
"SIGTSTP"), SIGTSTP },
3827 {
L(
"SIGTTIN"), SIGTTIN },
3828 {
L(
"SIGTTOU"), SIGTTOU },
3829 {
L(
"SIGURG"), SIGURG },
3830 {
L(
"SIGUSR1"), SIGUSR1 },
3831 {
L(
"SIGUSR2"), SIGUSR2 },
3832 {
L(
"SIGVTALRM"), SIGVTALRM },
3833 {
L(
"SIGXCPU"), SIGXCPU },
3834 {
L(
"SIGXFSZ"), SIGXFSZ }
3836 static size_t signal_table_len =
NUM_ELEMENTS(signal_table);
3845 RERROR(
"Invalid signal \"%pV\"", signal_vb);
3848 if (raise(signal) < 0) {
3849 RERROR(
"Failed raising signal %d: %s", signal, strerror(errno));
3888 if (!arg || (strcmp(arg->vb_strvalue,
"now") == 0)) {
3891 }
else if (strcmp(arg->vb_strvalue,
"request") == 0) {
3894 }
else if (strcmp(arg->vb_strvalue,
"offset") == 0) {
3899 }
else if (strcmp(arg->vb_strvalue,
"dst") == 0) {
3904 }
else if (strcmp(arg->vb_strvalue,
"mday_offset") == 0) {
3912 nsec = (int64_t) 86400 * (tm.tm_mday - 1);
3913 nsec += when % 86400;
3921 }
else if (strcmp(arg->vb_strvalue,
"wday_offset") == 0) {
3929 nsec = (int64_t) 86400 * tm.tm_wday;
3930 nsec += when % 86400;
3942 REDEBUG(
"Invalid time specification '%s'", arg->vb_strvalue);
3947 vb->vb_date =
value;
4069 p =
UNCONST(
char *, vb->vb_strvalue);
4070 end = p + vb->vb_length;
4073 *(p) = upper ? toupper ((
int) *(p)) : tolower((
uint8_t) *(p));
4144 char const *p, *end;
4152 p = in_head->vb_strvalue;
4153 end = p + in_head->vb_length;
4176 p = in_head->vb_strvalue;
4229 char const *p, *end;
4238 p = in_head->vb_strvalue;
4239 end = p + in_head->vb_length;
4258 p = in_head->vb_strvalue;
4270 REMARKER(in_head->vb_strvalue, p - in_head->vb_strvalue,
"Non-hex char in %% sequence");
4308 void *decode_ctx = NULL;
4312 bool created =
false;
4318 if (decode_uctx->
dict && decode_uctx->
dict != request->proto_dict) {
4319 REDEBUG2(
"Can't call %%%s() when in %s namespace", xctx->
ex->call.func->name,
4327 REDEBUG2(
"Decoding context must be a structural attribute reference");
4332 REDEBUG2(
"Failed creating decoding root pair");
4335 if (ret == 0) created =
true;
4339 if (tp_decode->
test_ctx(&decode_ctx, ctx, request->proto_dict, root_da ? root_da->vb_attr : NULL) < 0) {
4345 root_da ? &
vp->vp_group : &request->request_pairs,
4346 request, decode_ctx, tp_decode->
func, &in_head->vb_group);
4349 RPERROR(
"Protocol decoding failed");
4360 vb->vb_uint32 = decoded;
4388 vb->vb_ipv4addr = htonl((
uint32_t)0xffffffff << (32 - subnet->vb_ip.prefix));
4410 vb->vb_ipv4addr = htonl( ntohl(subnet->vb_ipv4addr) | (
uint32_t)0xffffffff >> subnet->vb_ip.prefix);
4418 *(
void **) mctx->
inst = mctx->
uctx;
4445 bool tainted =
false, encode_children =
false;
4458 memcpy(&tp_encode, xctx->
inst,
sizeof(tp_encode));
4466 if (tp_encode->
test_ctx(&
encode_ctx, cursor, request->proto_dict, root_da ? root_da->vb_attr : NULL) < 0) {
4473 REDEBUG2(
"Encoding context must be a structural attribute reference");
4478 REDEBUG2(
"%s is not a child of %s",
vp->
da->name, root_da->vb_attr->name);
4481 if (root_da->vb_attr ==
vp->
da) encode_children =
true;
4487 RDEBUG2(
"Encoding attributes");
4526 if (encode_children) {
4546 RPEDEBUG(
"Protocol encoding failed");
4550 tainted |=
vp->vp_tainted;
4586 decode_uctx->
dict = dict;
4625 for (p =
name; *p !=
'\0'; p++) {
4721#define XLAT_REGISTER_ARGS(_xlat, _func, _return_type, _args) \
4723 if (unlikely((xlat = xlat_func_register(xlat_ctx, _xlat, _func, _return_type)) == NULL)) return -1; \
4724 xlat_func_args_set(xlat, _args); \
4725 xlat_func_flags_set(xlat, XLAT_FUNC_FLAG_PURE | XLAT_FUNC_FLAG_INTERNAL); \
4728#define XLAT_NEW(_x) xlat->replaced_with = _x
4777#undef XLAT_REGISTER_ARGS
4778#define XLAT_REGISTER_ARGS(_xlat, _func, _return_type, _args) \
4780 if (unlikely((xlat = xlat_func_register(xlat_ctx, _xlat, _func, _return_type)) == NULL)) return -1; \
4781 xlat_func_args_set(xlat, _args); \
4782 xlat_func_flags_set(xlat, XLAT_FUNC_FLAG_INTERNAL); \
4785#undef XLAT_REGISTER_VOID
4786#define XLAT_REGISTER_VOID(_xlat, _func, _return_type) \
4788 if (unlikely((xlat = xlat_func_register(xlat_ctx, _xlat, _func, _return_type)) == NULL)) return -1; \
4789 xlat_func_flags_set(xlat, XLAT_FUNC_FLAG_INTERNAL); \
4828#ifdef HAVE_REGEX_PCRE2
4833#ifdef HAVE_REGEX_PCRE2
4871#define XLAT_REGISTER_PURE(_xlat, _func, _return_type, _arg) \
4873 if (unlikely((xlat = xlat_func_register(xlat_ctx, _xlat, _func, _return_type)) == NULL)) return -1; \
4874 xlat_func_args_set(xlat, _arg); \
4875 xlat_func_flags_set(xlat, XLAT_FUNC_FLAG_PURE | XLAT_FUNC_FLAG_INTERNAL); \
4905 .func =
regex_xlat_escape, .safe_for = FR_REGEX_SAFE_FOR, .always_escape =
true,
4906 .variadic =
true, .concat =
true },
4923#define XLAT_REGISTER_HASH(_name, _func) do { \
4924 XLAT_REGISTER_PURE("hash." _name, _func, FR_TYPE_OCTETS, xlat_func_sha_arg); \
4925 XLAT_REGISTER_PURE(_name, _func, FR_TYPE_OCTETS, xlat_func_sha_arg); \
4926 XLAT_NEW("hash." _name); \
4931#ifdef HAVE_OPENSSL_EVP_H
4938# ifdef HAVE_EVP_BLAKE2S256
4941# ifdef HAVE_EVP_BLAKE2B512
static int const char char buffer[256]
static int const char * fmt
#define fr_base16_encode(_out, _in)
#define fr_base16_decode(_err, _out, _in, _no_trailing)
#define fr_base64_encode(_out, _in, _add_padding)
#define fr_base64_decode(_out, _in, _expect_padding, _no_trailing)
#define FR_BASE64_DEC_LENGTH(_inlen)
#define FR_BASE64_ENC_LENGTH(_inlen)
Encode/decode binary data using printable characters (base64 format)
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define L(_str)
Helper for initialising arrays of string literals.
#define fr_dbuff_used(_dbuff_or_marker)
Return the number of bytes remaining between the start of the dbuff or marker and the current positio...
#define fr_dbuff_start(_dbuff_or_marker)
Return the 'start' position of a dbuff or marker.
#define FR_DBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max)
Create a function local and thread local extensible dbuff.
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
static void * fr_dcursor_current(fr_dcursor_t *cursor)
Return the item the cursor current points to.
static void * fr_dcursor_head(fr_dcursor_t *cursor)
Rewind cursor to the start of the list.
fr_dict_t * fr_dict_global_ctx_iter_next(fr_dict_global_ctx_iter_t *iter)
char const * name
Vendor name.
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.
fr_dict_t * fr_dict_global_ctx_iter_init(fr_dict_global_ctx_iter_t *iter)
Iterate protocols by name.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
dl_t * fr_dict_dl(fr_dict_t const *dict)
uint32_t pen
Private enterprise number.
fr_dict_t const * fr_dict_internal(void)
fr_dict_vendor_t const * fr_dict_vendor_by_da(fr_dict_attr_t const *da)
Look up a vendor by one of its child attributes.
dl_loader_t * dl_loader_init(TALLOC_CTX *ctx, void *uctx, bool uctx_free, bool defer_symbol_init)
Initialise structures needed by the dynamic linker.
dl_t * dl_by_name(dl_loader_t *dl_loader, char const *name, void *uctx, bool uctx_free)
Search for a dl's shared object in various locations.
void * handle
Handle returned by dlopen.
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.
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_next(fr_dlist_head_t const *list_head, void const *ptr)
Get the next item in a list.
void fr_bio_shutdown & my
ssize_t fr_mkdir(int *fd_out, char const *path, ssize_t len, mode_t mode, fr_mkdir_func_t func, void *uctx)
Create directories that are missing in the specified path.
static xlat_action_t xlat_func_time_now(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *args)
Return the current time as a FR_TYPE_DATE.
static xlat_action_t xlat_func_next_time(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Calculate number of seconds until the next n hour(s), day(s), week(s), year(s).
static xlat_action_t xlat_func_lpad(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
lpad a string
static xlat_action_t xlat_func_bin(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Convert hex string to binary.
static xlat_action_t xlat_func_pairs_debug(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Print out attribute info.
static xlat_action_t xlat_func_subst(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Perform regex substitution.
static xlat_action_t xlat_func_urlunquote(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
URLdecode special characters.
static xlat_action_t xlat_pair_decode(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Decode any protocol attribute / options.
static xlat_action_t xlat_func_base64_decode(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Decode base64 string.
static xlat_action_t xlat_func_hmac_md5(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *in)
Generate the HMAC-MD5 of a string or attribute.
static xlat_action_t xlat_func_base64_encode(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Encode string or attribute as base64.
static xlat_action_t xlat_func_log_info(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Log something at INFO level.
static xlat_action_t xlat_func_log_warn(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Log something at WARN level.
static xlat_action_t xlat_func_map(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Processes fmt as a map string and applies it to the current request.
static xlat_action_t xlat_func_debug(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Dynamically change the debugging level for the current request.
static xlat_action_t xlat_func_log_debug(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Log something at DEBUG level.
static xlat_action_t xlat_func_log_dst(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Change the log destination to the named one.
static xlat_arg_parser_t const xlat_func_string_arg[]
Calculate any digest supported by OpenSSL EVP_MD.
static xlat_action_t xlat_func_block(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *args)
Block for the specified duration.
static xlat_action_t xlat_func_concat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Concatenate string representation of values of given attributes using separator.
static xlat_action_t xlat_func_urlquote(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *args)
URLencode special characters.
static xlat_action_t xlat_func_rpad(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Right pad a string.
static xlat_action_t xlat_func_md4(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *args)
Calculate the MD4 hash of a string or attribute.
static xlat_action_t xlat_func_explode(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Split a string into multiple new strings based on a delimiter.
static xlat_action_t xlat_func_pairs_print(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Encode attributes as a series of string attribute/value pairs.
static xlat_action_t xlat_func_time_request(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, UNUSED fr_value_box_list_t *args)
Return the request receive time as a FR_TYPE_DATE.
static xlat_action_t xlat_func_regex(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Get named subcapture value from previous regex.
static xlat_action_t xlat_func_substr(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Extract a substring from string / octets data.
static xlat_action_t xlat_func_length(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *in)
Return the on-the-wire size of the boxes in bytes.
static xlat_action_t xlat_func_immutable_attr(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Mark one or more attributes as immutable.
static xlat_action_t xlat_func_rand(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *in)
Generate a random integer value.
static xlat_action_t xlat_pair_encode(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Encode protocol attributes / options.
static xlat_action_t xlat_func_log_err(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Log something at DEBUG level.
static xlat_action_t xlat_func_hmac_sha1(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *in)
Generate the HMAC-SHA1 of a string or attribute.
static xlat_action_t xlat_func_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Dynamically evaluate an expansion string.
static xlat_action_t xlat_func_time_is_dst(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *args)
Return whether we are in daylight savings or not.
static xlat_action_t xlat_func_integer(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Print data as integer, not as VALUE.
static xlat_action_t xlat_func_time(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Return the time as a FR_TYPE_DATE.
static xlat_action_t xlat_func_toupper(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Convert a string to uppercase.
static xlat_action_t xlat_func_uuid_v7(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *args)
Generate a version 7 UUID.
static xlat_action_t xlat_func_uuid_v4(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *args)
Generate a version 4 UUID.
static xlat_action_t xlat_func_cast(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Cast one or more output value-boxes to the given type.
static xlat_action_t xlat_func_hex(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *args)
Print data as hex, not as VALUE.
static xlat_action_t xlat_func_md5(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *args)
Calculate the MD5 hash of a string or attribute.
static xlat_action_t xlat_func_subnet_netmask(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *args)
Calculate the subnet mask from a IPv4 prefix.
static xlat_action_t xlat_func_sha1(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *args)
Calculate the SHA1 hash of a string or attribute.
static xlat_action_t xlat_func_str_printable(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *args)
Return whether a string has only printable chars.
static xlat_action_t xlat_func_range(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Generate a range of uint64 numbers.
static xlat_action_t xlat_func_randstr(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Generate a string of random chars.
static xlat_action_t xlat_func_tolower(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Convert a string to lowercase.
static xlat_action_t xlat_func_subnet_broadcast(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *args)
Calculate the broadcast address from a IPv4 prefix.
static xlat_action_t xlat_func_str_utf8(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *args)
Return whether a string is valid UTF-8.
static xlat_action_t xlat_func_time_offset(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *args)
Return the current time offset from gmt.
static xlat_action_t xlat_func_strlen(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *args)
Print length of given string.
Stores the state of the current iteration operation.
int fr_hmac_md5(uint8_t digest[MD5_DIGEST_LENGTH], uint8_t const *in, size_t inlen, uint8_t const *key, size_t key_len)
Calculate HMAC using internal MD5 implementation.
int fr_hmac_sha1(uint8_t digest[static SHA1_DIGEST_LENGTH], uint8_t const *in, size_t inlen, uint8_t const *key, size_t key_len)
Calculate HMAC using internal SHA1 implementation.
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
fr_log_t * log_dst_by_name(char const *name)
Get a logging destination by name.
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
#define REDEBUG3(fmt,...)
#define REMARKER(_str, _marker_idx, _marker,...)
Output string with error marker, showing where format error occurred.
#define RMARKER(_type, _lvl, _str, _marker_idx, _marker,...)
Output string with error marker, showing where format error occurred.
#define RPEDEBUG(fmt,...)
#define RDEBUG_ENABLED4
True if request debug level 1-4 messages are enabled.
#define RIDEBUG2(fmt,...)
#define REDEBUG2(fmt,...)
#define RIDEBUG3(fmt,...)
#define RINDENT()
Indent R* messages by one level.
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_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.
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.
@ L_DST_NULL
Discard log messages.
@ L_DST_FILES
Log to a file on disk.
@ L_DBG_LVL_DISABLE
Don't print messages.
@ L_DBG_LVL_2
2nd highest priority debug messages (-xx | -X).
@ L_DBG_LVL_MAX
Lowest priority debug messages (-xxxxx | -Xxxx).
void fr_md4_calc(uint8_t out[static MD4_DIGEST_LENGTH], uint8_t const *in, size_t inlen)
Calculate the MD4 hash of the contents of a buffer.
#define MD4_DIGEST_LENGTH
#define MD5_DIGEST_LENGTH
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
@ FR_TYPE_FLOAT32
Single precision floating point.
@ 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_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_DATE
Unix time stamp, always has value >2^31.
@ FR_TYPE_COMBO_IP_PREFIX
IPv4 or IPv6 address prefix depending on length.
@ 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_SIZE
Unsigned integer capable of representing any memory address on the local system.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
@ FR_TYPE_IFID
Interface ID.
@ FR_TYPE_OCTETS
Raw octets.
@ FR_TYPE_GROUP
A grouping of other attributes.
@ FR_TYPE_FLOAT64
Double precision floating point.
void fr_md5_calc(uint8_t out[static MD5_DIGEST_LENGTH], uint8_t const *in, size_t inlen)
Perform a single digest operation on a single input buffer.
size_t fr_snprint_uint128(char *out, size_t outlen, uint128_t const num)
Write 128bit unsigned integer to buffer.
struct tm * gmtime_r(time_t const *l_clock, struct tm *result)
struct tm * localtime_r(time_t const *l_clock, struct tm *result)
fr_pair_t * fr_pair_list_parent(fr_pair_list_t const *list)
Return a pointer to the parent pair which contains this list.
int fr_pair_update_by_da_parent(fr_pair_t *parent, fr_pair_t **out, fr_dict_attr_t const *da)
Return the first fr_pair_t matching the fr_dict_attr_t or alloc a new fr_pair_t and its subtree (and ...
int fr_pair_delete(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list and free.
fr_slen_t fr_utf8_str(uint8_t const *str, ssize_t inlen)
Validate a complete UTF8 string.
size_t fr_utf8_char(uint8_t const *str, ssize_t inlen)
Checks for utf-8, taken from http://www.w3.org/International/questions/qa-forms-utf-8.
static fr_internal_encode_ctx_t encode_ctx
#define RDEBUG_ENABLED2()
uint32_t fr_rand(void)
Return a 32-bit random number.
fr_dict_attr_t const * request_attr_request
void request_log_prepend(request_t *request, fr_log_t *log_dst, fr_log_lvl_t lvl)
Prepend another logging destination to the list.
#define RAD_REQUEST_LVL_NONE
No debug messages should be printed.
char * fr_sbuff_adv_to_str(fr_sbuff_t *sbuff, size_t len, char const *needle, size_t needle_len)
Wind position to the first instance of the specified needle.
char * fr_sbuff_adv_to_chr(fr_sbuff_t *sbuff, size_t len, char c)
Wind position to first instance of specified char.
ssize_t fr_sbuff_in_bstrncpy(fr_sbuff_t *sbuff, char const *str, size_t len)
Copy bytes into the sbuff up to the first \0.
ssize_t fr_sbuff_in_sprintf(fr_sbuff_t *sbuff, char const *fmt,...)
Print using a fmt string to an sbuff.
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_set(_dst, _src)
#define FR_SBUFF_IN(_start, _len_or_end)
#define fr_sbuff_adv_past_whitespace(_sbuff, _len, _tt)
#define fr_sbuff_current(_sbuff_or_marker)
char const * name
Name for rule set to aid we debugging.
#define FR_SBUFF(_sbuff_or_marker)
#define fr_sbuff_advance(_sbuff_or_marker, _len)
#define fr_sbuff_init_in(_out, _start, _len_or_end)
#define fr_sbuff_remaining(_sbuff_or_marker)
#define fr_sbuff_len(_sbuff_or_marker)
#define FR_SBUFF_OUT(_start, _len_or_end)
#define fr_sbuff_move(_out, _in, _len)
#define fr_sbuff_used(_sbuff_or_marker)
#define fr_sbuff_behind(_sbuff_or_marker)
#define fr_sbuff_ahead(_sbuff_or_marker)
#define FR_SBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max)
Set of parsing rules for *unescape_until functions.
static char const * tmpl_type_to_str(tmpl_type_t type)
Return a static string containing the type name.
@ 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_DATA_UNRESOLVED
Unparsed literal string.
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
Optional arguments passed to vp_tmpl functions.
void fr_sha1_init(fr_sha1_ctx *context)
void fr_sha1_final(uint8_t digest[static SHA1_DIGEST_LENGTH], fr_sha1_ctx *context)
void fr_sha1_update(fr_sha1_ctx *context, uint8_t const *in, size_t len)
#define SHA1_DIGEST_LENGTH
static char buff[sizeof("18446744073709551615")+3]
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
eap_aka_sim_process_conf_t * inst
fr_aka_sim_id_type_t type
#define fr_time()
Allow us to arbitrarily manipulate time.
size_t strlcpy(char *dst, char const *src, size_t siz)
fr_log_t * parent
Log destination this was cloned from.
fr_log_dst_t dst
Log destination.
int fd
File descriptor to write messages to.
char const * file
Path to log file.
tmpl_t * lhs
Typically describes the attribute to add, modify or compare.
tmpl_t * rhs
Typically describes a literal value or a src attribute to copy or compare.
fr_dict_t const * dict_def
Default dictionary to use with unqualified attribute references.
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.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
#define fr_table_value_by_substr(_table, _name, _name_len, _def)
Convert a partial string to a value using an ordered or sorted table.
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_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
char * talloc_bstr_append(TALLOC_CTX *ctx, char *to, char const *from, size_t from_len)
Append a bstr to a bstr.
#define talloc_get_type_abort_const
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
fr_pair_decode_t func
Decoder for pairs.
fr_pair_encode_t func
Encoder for pairs.
Entry point for pair decoders.
Entry point for pair encoders.
bool fr_time_is_dst(void)
Whether or not we're daylight savings.
int fr_unix_time_from_str(fr_unix_time_t *date, char const *date_str, fr_time_res_t hint)
Convert string in various formats to a fr_unix_time_t.
fr_time_delta_t fr_time_gmtoff(void)
Get the offset to gmt.
#define fr_time_delta_to_timespec(_delta)
Convert a delta to a timespec.
static int64_t fr_time_to_msec(fr_time_t when)
Convert an fr_time_t (internal time) to number of msec since the unix epoch (wallclock time)
static int64_t fr_unix_time_to_sec(fr_unix_time_t delta)
#define fr_time_delta_wrap(_time)
static uint64_t fr_unix_time_unwrap(fr_unix_time_t time)
static fr_time_delta_t fr_time_delta_sub(fr_time_delta_t a, fr_time_delta_t b)
static fr_unix_time_t fr_time_to_unix_time(fr_time_t when)
Convert an fr_time_t (internal time) to our version of unix time (wallclock time)
static fr_time_delta_t fr_time_delta_from_timespec(struct timespec const *ts)
char const * fr_tokens[T_TOKEN_LAST]
xlat_action_t unlang_xlat_yield(request_t *request, xlat_func_t resume, xlat_func_signal_t signal, fr_signal_t sigmask, void *rctx)
Yield a request back to the interpreter from within a module.
int unlang_xlat_push(TALLOC_CTX *ctx, unlang_result_t *p_result, fr_value_box_list_t *out, request_t *request, xlat_exp_head_t const *xlat, bool top_frame)
Push a pre-compiled xlat onto the stack for evaluation.
void unlang_xlat_init(void)
Register xlat operation with the interpreter.
fr_type_t type
Type to cast argument to.
bool xlat_is_literal(xlat_exp_head_t const *head)
Check to see if the expansion consists entirely of value-box elements.
#define XLAT_ARG_PARSER_CURSOR
unsigned int concat
Concat boxes together.
@ XLAT_ARG_VARIADIC_EMPTY_KEEP
Empty argument groups are left alone, and either passed through as empty groups or null boxes.
@ XLAT_ARG_VARIADIC_EMPTY_SQUASH
Empty argument groups are removed.
xlat_arg_parser_variadic_t variadic
All additional boxes should be processed using this definition.
#define XLAT_RESULT_SUCCESS(_p_result)
#define XLAT_ARGS(_list,...)
Populate local variables with value boxes from the input list.
unsigned int required
Argument must be present, and non-empty.
unsigned int single
Argument must only contain a single box.
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.
#define XLAT_ARG_PARSER_TERMINATOR
@ XLAT_ACTION_FAIL
An xlat function failed.
@ XLAT_ACTION_YIELD
An xlat function pushed a resume frame onto the stack.
@ XLAT_ACTION_PUSH_UNLANG
An xlat function pushed an unlang frame onto the unlang stack.
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
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))
Definition for a single argument consumend by an xlat function.
static fr_slen_t fr_pair_aprint(TALLOC_CTX *ctx, char **out, fr_dict_attr_t const *parent, fr_pair_t const *vp) 1(fr_pair_print
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
static void fr_pair_set_immutable(fr_pair_t *vp)
static fr_slen_t quote ssize_t fr_pair_print_name(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_pair_t const **vp_p)
Print an attribute name.
#define fr_pair_dcursor_init(_cursor, _list)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
fr_table_num_ordered_t const fr_type_table[]
Map data types to names representing those types.
#define fr_type_is_structural(_x)
@ FR_TYPE_ATTR
A contains an attribute reference.
#define fr_type_is_string(_x)
#define fr_type_is_numeric(_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.
size_t fr_value_box_network_length(fr_value_box_t const *value)
Get the size of the value held by the fr_value_box_t.
void fr_value_box_mark_unsafe(fr_value_box_t *vb)
Mark a value-box as "unsafe".
ssize_t fr_value_box_list_concat_as_string(fr_value_box_t *safety, fr_sbuff_t *sbuff, fr_value_box_list_t *list, char const *sep, size_t sep_len, fr_sbuff_escape_rules_t const *e_rules, fr_value_box_list_action_t proc_action, fr_value_box_safe_for_t safe_for, bool flatten)
Concatenate a list of value boxes together.
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_mem_alloc(TALLOC_CTX *ctx, uint8_t **out, fr_value_box_t *dst, fr_dict_attr_t const *enumv, size_t len, bool tainted)
Pre-allocate an octets buffer for filling by the caller.
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.
char * fr_value_box_list_aprint(TALLOC_CTX *ctx, fr_value_box_list_t const *list, char const *delim, fr_sbuff_escape_rules_t const *e_rules)
Concatenate the string representations of a list of value boxes together.
int fr_value_box_mem_realloc(TALLOC_CTX *ctx, uint8_t **out, fr_value_box_t *dst, size_t len)
Change the length of a buffer already allocated to a value box.
void fr_value_box_list_untaint(fr_value_box_list_t *head)
Untaint every list member (and their children)
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_clear_value(fr_value_box_t *data)
Clear/free any existing value.
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.
void fr_value_box_safety_copy_changed(fr_value_box_t *out, fr_value_box_t const *in)
Copy the safety values from one box to another.
void fr_value_box_safety_merge(fr_value_box_t *out, fr_value_box_t const *in)
Merge safety results.
void fr_value_box_strdup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Assign a buffer containing a nul terminated string to a box, but don't copy it.
void fr_value_box_safety_copy(fr_value_box_t *out, fr_value_box_t const *in)
Copy the safety values from one box to another.
int fr_value_box_bstr_alloc(TALLOC_CTX *ctx, char **out, fr_value_box_t *dst, fr_dict_attr_t const *enumv, size_t len, bool tainted)
Alloc and assign an empty \0 terminated string to a fr_value_box_t.
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
bool fr_value_box_list_tainted(fr_value_box_list_t const *head)
Check to see if any list members (or their children) are tainted.
int fr_value_box_bstr_realloc(TALLOC_CTX *ctx, char **out, fr_value_box_t *dst, size_t len)
Change the length of a buffer already allocated to a value box.
int fr_value_box_bstrndup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Copy a string to to a fr_value_box_t.
int fr_value_box_bstrdup_buffer_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Assign a talloced buffer containing a nul terminated string to a box, but don't copy it.
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.
int fr_value_box_list_concat_in_place(TALLOC_CTX *ctx, fr_value_box_t *out, fr_value_box_list_t *list, fr_type_t type, fr_value_box_list_action_t proc_action, bool flatten, size_t max_size)
Concatenate a list of value boxes.
@ FR_VALUE_BOX_LIST_FREE_BOX
Free each processed box.
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
#define fr_value_box_mark_safe_for(_box, _safe_for)
static fr_value_box_t * fr_value_box_acopy(TALLOC_CTX *ctx, fr_value_box_t const *src)
Copy an existing box, allocating a new box to hold its contents.
#define fr_value_box_is_safe_for(_box, _safe_for)
#define fr_box_is_variable_size(_x)
#define fr_value_box_get_cursor(_dst)
#define VALUE_BOX_VERIFY(_x)
#define VALUE_BOX_LIST_VERIFY(_x)
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
#define fr_value_box_list_foreach(_list_head, _iter)
static size_t char ** out
#define fr_box_bool(_val)
#define FR_VALUE_BOX_SAFE_FOR_ANY
static xlat_arg_parser_t const xlat_func_bin_arg[]
static int xlat_protocol_register_cbor(void)
static xlat_arg_parser_t const xlat_func_map_arg[]
static xlat_action_t xlat_func_file_tail(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
#define XLAT_REGISTER_VOID(_xlat, _func, _return_type)
static xlat_arg_parser_t const xlat_func_log_dst_args[]
static xlat_arg_parser_t const xlat_func_taint_args[]
static xlat_arg_parser_t const xlat_func_time_args[]
static xlat_arg_parser_t const xlat_func_base64_encode_arg[]
unlang_result_t last_result
static xlat_action_t xlat_change_case(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED request_t *request, fr_value_box_list_t *args, bool upper)
Change case of a string.
static int _log_dst_free(fr_log_t *log)
static xlat_arg_parser_t const xlat_pair_encode_args[]
static xlat_action_t xlat_hmac(TALLOC_CTX *ctx, fr_dcursor_t *out, fr_value_box_list_t *args, uint8_t *digest, int digest_len, hmac_type type)
static xlat_arg_parser_t const xlat_func_signal_raise_args[]
static void xlat_debug_attr_vp(request_t *request, fr_pair_t const *vp, fr_dict_attr_t const *da)
static xlat_arg_parser_t const xlat_func_log_arg[]
static xlat_action_t xlat_func_file_mkdir(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
static xlat_arg_parser_t const xlat_func_sha_arg[]
static xlat_arg_parser_t const xlat_func_cast_args[]
static int xlat_pair_dencode_instantiate(xlat_inst_ctx_t const *mctx)
xlat_action_t xlat_transparent(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *args)
Common function to move boxes from input list to output list.
static xlat_arg_parser_t const xlat_func_hex_arg[]
static xlat_arg_parser_t const xlat_func_substr_args[]
static xlat_action_t xlat_func_file_exists(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *args)
static xlat_action_t xlat_func_file_head(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
static xlat_arg_parser_t const xlat_func_block_args[]
static xlat_arg_parser_t const xlat_func_subnet_args[]
#define XLAT_REGISTER_PURE(_xlat, _func, _return_type, _arg)
static xlat_arg_parser_t const xlat_func_str_printable_arg[]
static xlat_arg_parser_t const xlat_func_randstr_arg[]
static xlat_arg_parser_t const xlat_func_eval_arg[]
static xlat_arg_parser_t const xlat_func_subst_args[]
static xlat_arg_parser_t const xlat_func_explode_args[]
int xlat_protocols_register(void)
Register xlats for any loaded dictionaries.
static xlat_arg_parser_t const xlat_func_str_utf8_arg[]
static const fr_sbuff_escape_rules_t xlat_filename_escape_dots
static dl_loader_t * cbor_loader
static xlat_arg_parser_t const xlat_change_case_arg[]
static xlat_arg_parser_t const xlat_func_strlen_arg[]
static int xlat_protocol_register(fr_dict_t const *dict)
static xlat_arg_parser_t const xlat_func_md5_arg[]
int xlat_global_init(void)
static xlat_arg_parser_t const xlat_func_urlquote_arg[]
static xlat_arg_parser_t const xlat_pair_cursor_args[]
static xlat_action_t xlat_func_file_size(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
static void ungroup(fr_dcursor_t *out, fr_value_box_list_t *in)
static xlat_arg_parser_t const xlat_func_md4_arg[]
static int regex_xlat_escape(UNUSED request_t *request, fr_value_box_t *vb, UNUSED void *uctx)
static xlat_arg_parser_t const xlat_func_join_args[]
static xlat_action_t xlat_eval_resume(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *in)
Just serves to push the result up the stack.
static xlat_action_t xlat_func_taint(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *in)
#define XLAT_REGISTER_HASH(_name, _func)
static xlat_arg_parser_t const xlat_func_debug_args[]
static char const hextab[]
#define FR_FILENAME_SAFE_FOR
static xlat_action_t xlat_func_signal_raise(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
fr_test_point_pair_decode_t * tp_decode
static xlat_arg_parser_t const xlat_func_pad_args[]
static int uuid_print_vb(fr_value_box_t *vb, uint32_t vals[4])
Convert a UUID in an array of uint32_t to the conventional string representation.
static xlat_arg_parser_t const xlat_func_urlunquote_arg[]
static xlat_action_t xlat_func_file_touch(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
fr_dict_t const * dict
Restrict xlat to this namespace.
static xlat_arg_parser_t const xlat_pair_decode_args[]
static xlat_arg_parser_t const xlat_func_rand_arg[]
static void uuid_set_variant(uint32_t vals[4], uint8_t variant)
static int filename_xlat_escape(UNUSED request_t *request, fr_value_box_t *vb, UNUSED void *uctx)
static xlat_arg_parser_t const xlat_func_concat_args[]
static xlat_action_t xlat_func_join(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *in)
Join a series of arguments to form a single list.
static xlat_arg_parser_t const xlat_func_file_name_count_args[]
void xlat_arg_copy_out(TALLOC_CTX *ctx, fr_dcursor_t *out, fr_value_box_list_t *in, fr_value_box_t *vb)
Copy an argument from the input list to the output cursor.
static xlat_arg_parser_t const xlat_func_range_arg[]
static xlat_arg_parser_t const xlat_func_integer_args[]
static int _xlat_global_init(UNUSED void *uctx)
Global initialisation for xlat.
#define XLAT_REGISTER_ARGS(_xlat, _func, _return_type, _args)
static xlat_action_t xlat_func_untaint(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *in)
static xlat_action_t xlat_func_file_cat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
static xlat_action_t xlat_func_file_rm(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
static xlat_arg_parser_t const xlat_func_length_args[]
static xlat_action_t xlat_func_ungroup(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *in)
Ungroups all of its arguments into one flat list.
static int xlat_protocol_register_by_name(dl_t *dl, char const *name, fr_dict_t const *dict)
static xlat_arg_parser_t const xlat_func_file_cat_args[]
static void uuid_set_version(uint32_t vals[4], uint8_t version)
static xlat_action_t xlat_func_file_rmdir(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
#define UUID_CHARS(_v, _num)
static void xlat_debug_attr_list(request_t *request, fr_pair_list_t const *list, fr_dict_attr_t const *parent)
static xlat_arg_parser_t const xlat_func_file_name_args[]
static TALLOC_CTX * xlat_ctx
static xlat_arg_parser_t const xlat_func_next_time_args[]
static int _xlat_global_free(UNUSED void *uctx)
De-register all xlat functions we created.
static const fr_sbuff_escape_rules_t xlat_filename_escape
static xlat_arg_parser_t const xlat_func_base64_decode_arg[]
static xlat_arg_parser_t const xlat_hmac_args[]
static xlat_arg_parser_t const xlat_func_regex_args[]
void * rctx
Resume context.
xlat_exp_t const * ex
Tokenized expression.
xlat_exp_t * ex
Tokenized expression to use in expansion.
void const * inst
xlat instance data.
void * uctx
Passed to the registration function.
void * inst
xlat instance data to populate.
An xlat instantiation ctx.
fr_dict_attr_t const * xlat_time_res_attr(char const *res)
void xlat_eval_free(void)
int xlat_register_expressions(void)
void xlat_func_free(void)
void xlat_func_flags_set(xlat_t *x, xlat_func_flags_t flags)
Specify flags that alter the xlat's behaviour.
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
xlat_t * xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function.
xlat_t * xlat_func_find(char const *in, ssize_t inlen)
#define xlat_func_instantiate_set(_xlat, _instantiate, _inst_struct, _detach, _uctx)
Set a callback for global instantiation of xlat functions.
#define xlat_func_safe_for_set(_xlat, _escaped)
Set the escaped values for output boxes.
@ XLAT_FUNC_FLAG_INTERNAL
int xlat_decode_value_box_list(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, void *decode_ctx, fr_pair_decode_t decode, fr_value_box_list_t *in)
Decode all of the value boxes into the output cursor.
@ XLAT_GROUP
encapsulated string of xlats
bool deprecated
this function was deprecated
xlat_type_t _CONST type
type of this expansion.