27 RCSID(
"$Id: e4d9329085e75c7006d7c4311a6e5b82913c4fac $")
29 #include <freeradius-devel/radiusd.h>
30 #include <freeradius-devel/parser.h>
31 #include <freeradius-devel/rad_assert.h>
32 #include <freeradius-devel/base64.h>
102 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
105 snprintf(*out, outlen,
"%u", (
unsigned int) strlen(fmt));
113 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
114 REQUEST *request,
char const *fmt)
118 while (isspace((
int) *fmt)) fmt++;
122 snprintf(*out, outlen,
"%zu", vp->vp_length);
130 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
131 REQUEST *request,
char const *fmt)
138 while (isspace((
int) *fmt)) fmt++;
145 if (vp->vp_length > 8) {
149 if (vp->vp_length > 4) {
150 memcpy(&int64, vp->vp_octets, vp->vp_length);
151 return snprintf(*out, outlen,
"%" PRIu64, htonll(int64));
154 memcpy(&int32, vp->vp_octets, vp->vp_length);
155 return snprintf(*out, outlen,
"%i", htonl(int32));
158 return snprintf(*out, outlen,
"%" PRIu64, vp->vp_integer64);
165 return snprintf(*out, outlen,
"%u", htonl(vp->vp_ipaddr));
168 return snprintf(*out, outlen,
"%u", htonl((*(uint32_t *)(vp->vp_ipv4prefix + 2))));
171 return snprintf(*out, outlen,
"%u", vp->vp_integer);
174 return snprintf(*out, outlen,
"%u", vp->vp_date);
177 return snprintf(*out, outlen,
"%u", (
unsigned int) vp->vp_byte);
180 return snprintf(*out, outlen,
"%u", (
unsigned int) vp->vp_short);
187 memcpy(&int64, vp->vp_ether, vp->vp_length);
188 return snprintf(*out, outlen,
"%" PRIu64, htonll(int64));
191 return snprintf(*out, outlen,
"%i", vp->vp_signed);
203 REDEBUG(
"Type '%s' of length %zu cannot be converted to integer",
213 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
214 REQUEST *request,
char const *fmt)
221 uint8_t
const *buff = NULL;
223 while (isspace((
int) *fmt)) fmt++;
246 p = buff = dst.octets;
254 if (outlen < (len * 2)) {
259 for (i = 0; i < len; i++) {
260 snprintf((*out) + (2 * i), 3,
"%02x", p[i]);
271 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
272 REQUEST *request,
char const *fmt)
276 while (isspace((
int) *fmt)) fmt++;
289 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
290 REQUEST *request,
char const *fmt)
295 while (isspace((
int) *fmt)) fmt++;
310 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
311 REQUEST *request,
char const *fmt)
315 while (isspace((
int) *fmt)) fmt++;
326 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
327 REQUEST *request,
char const *fmt)
331 while (isspace((
int) *fmt)) fmt++;
336 return strlen(vp->
da->
name);
343 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
344 REQUEST *request,
char const *fmt)
348 while (isspace((
int) *fmt)) fmt++;
366 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
367 REQUEST *request,
char const *fmt)
376 while (isspace((
int) *fmt)) fmt++;
383 RIDEBUG(
"Attributes matching \"%s\"", fmt);
418 RIDEBUG2(
"Length : %zu", vp->vp_length);
456 if (!value)
goto next_type;
458 if ((pad = (11 - strlen(type->
name))) < 0) {
463 RDEBUG2(
"as %s%*s: %s", type->
name, pad,
" ", value);
482 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
483 REQUEST *request,
char const *fmt)
499 if (ret < 0)
return strlcpy(*out,
"0", outlen);
501 return strlcpy(*out,
"1", outlen);
508 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
516 #if defined(HAVE_REGEX) && defined(HAVE_PCRE)
517 static ssize_t xlat_regex(
char **out,
size_t outlen,
518 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
519 REQUEST *request,
char const *fmt)
524 if (regex_request_to_sub_named(request, &p, request, fmt) < 0)
return 0;
526 len = talloc_array_length(p);
528 RDEBUG(
"Insufficient buffer space to write subcapture value, needed %zu bytes, have %zu bytes",
544 void const *mod_inst,
UNUSED void const *xlat_inst,
554 if (!pvp || !*pvp)
return 0;
558 RDEBUG(
"Insufficient buffer space to write foreach value");
573 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
574 REQUEST *request,
char const *fmt)
581 while (isspace((
int) *fmt)) fmt++;
588 if ((
radius_get_vp(&vp, request, fmt) < 0) || !vp)
goto nothing;
597 len =
fr_snprint(*out, outlen, (
char const *) p, vp->vp_length,
'"');
605 len =
strlcpy(*out, vp->vp_strvalue, outlen);
609 len =
fr_snprint(*out, outlen, (
char const *) p, ret,
'\0');
620 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
621 REQUEST *request,
char const *fmt)
625 while (isspace((
int) *fmt)) fmt++;
632 if ((
radius_get_vp(&vp, request, fmt) < 0) || !vp)
goto nothing;
634 return radius_xlat(*out, outlen, request, vp->vp_strvalue, NULL, NULL);
642 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
643 REQUEST *request,
char const *fmt)
661 request->
log.func = NULL;
663 if (level > 4) level = 4;
665 request->
log.lvl = level;
676 static int xlat_cmp(
void const *one,
void const *two)
726 if (!name || !*name) {
727 DEBUG(
"xlat_register: Invalid xlat name");
744 DEBUG(
"xlat_register: Failed to create tree");
749 for (i = 0; xlat_foreach_names[i] != NULL; i++) {
757 #define XLAT_REGISTER(_x) xlat_register(NULL, STRINGIFY(_x), xlat_ ## _x, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN); \
758 c = xlat_find(STRINGIFY(_x)); \
759 rad_assert(c != NULL); \
776 #if defined(HAVE_REGEX) && defined(HAVE_PCRE)
794 DEBUG(
"xlat_register: Cannot re-define internal xlat");
810 c = talloc_zero(xlat_root,
xlat_t);
837 (void) talloc_steal(node, c);
855 if (!name || !xlat_root)
return;
863 if (c->
mod_inst != mod_inst)
return;
872 if (c->
mod_inst != mod_inst)
return 0;
900 void const *mod_inst,
UNUSED void const *xlat_inst,
901 REQUEST *request,
char const *fmt)
928 *out = talloc_array(request,
char, xlat->
buf_len);
951 void const *mod_inst,
UNUSED void const *xlat_inst,
952 REQUEST *request,
char const *fmt)
976 if ((count * (
fr_rand() & 0xffff)) < (uint32_t) 0x10000) {
990 if (!xlat)
return -1;
993 *out = talloc_array(request,
char, xlat->
buf_len);
999 if (slen <= 0) TALLOC_FREE(*out);
1020 *out = talloc_array(request,
char, xlat->
buf_len);
1026 if (rcode > 0)
return rcode;
1035 }
while (ci != found);
1043 char const *name1, *name2;
1050 cf_log_err_cs(cs,
"An expansion is already registered for this name");
1055 if (!xr)
return false;
1057 if (strcmp(name1,
"redundant") == 0) {
1060 }
else if (strcmp(name1,
"redundant-load-balance") == 0) {
1063 }
else if (strcmp(name1,
"load-balance") == 0) {
1129 while (isspace((
int) *fmt)) fmt++;
1131 if (fmt[0] ==
'&') {
1140 *out = (uint8_t
const *)fmt;
1153 # define XLAT_DEBUG DEBUG3
1155 # define XLAT_DEBUG(...)
1159 char const **error);
1161 bool brace,
char const **error);
1186 return slen - (p - fmt);
1192 *error =
"Expected ':' after first expansion";
1199 *error =
"Expected '-' after ':'";
1220 return slen - (p - fmt);
1225 *error =
"Empty expansion is invalid";
1253 node->
fmt = fmt + 2;
1261 num = strtol(p, &q, 10);
1262 if (p != q && (*q ==
'}')) {
1266 if ((num > REQUEST_MAX_REGEX) || (num < 0)) {
1268 *error =
"Invalid regex reference. Must be in range 0-" STRINGIFY(REQUEST_MAX_REGEX);
1271 node->
attr.tmpl_num = num;
1273 node->
type = XLAT_REGEX;
1276 return (q - fmt) + 1;
1296 for (q = p; *q !=
'\0'; q++) {
1297 if (*q ==
':')
break;
1299 if (isspace((
int) *q))
break;
1301 if (*q ==
'[')
continue;
1303 if (*q ==
'}')
break;
1309 if ((*q ==
'}') && (q == p)) {
1311 *error =
"Empty expression is invalid";
1335 return slen - (p - fmt);
1360 if ((*q ==
':') && ((p + (slen * -1)) < q)) {
1361 *error =
"Unknown module";
1367 return slen - (p - fmt);
1377 *error =
"Missing content in expansion";
1378 return -(p - fmt) - slen;
1383 node->
fmt = node->
attr.tmpl_unknown_name;
1393 *error =
"Unknown attribute";
1402 *error =
"No matching closing brace";
1414 bool brace,
char const **error)
1419 if (!*fmt)
return 0;
1434 *error =
"Invalid escape at end of string";
1446 if ((p[0] ==
'%') && (p[1] ==
'{')) {
1454 return slen - (p - fmt);
1478 return slen - (p - fmt);
1493 if (!p[1] || !strchr(
"%}dlmntDGHISTYv", p[1])) {
1495 *error =
"Invalid variable expansion";
1506 next->
fmt = talloc_strndup(next, p + 1, 1);
1533 return slen - (p - fmt);
1544 if (brace && (*p ==
'}')) {
1560 *error =
"Missing closing brace at end of string";
1567 if (node->
len > 0) {
1571 (void) talloc_steal(ctx, node->
next);
1586 if (lvl >= (
int)
sizeof(xlat_tabs)) lvl =
sizeof(
xlat_tabs);
1589 switch (node->
type) {
1591 DEBUG(
"%.*sliteral --> %s", lvl, xlat_tabs, node->
fmt);
1595 DEBUG(
"%.*spercent --> %c", lvl, xlat_tabs, node->
fmt[0]);
1600 DEBUG(
"%.*sattribute --> %s", lvl, xlat_tabs, node->
attr.tmpl_da->
name);
1603 DEBUG(
"%.*s{", lvl, xlat_tabs);
1605 DEBUG(
"%.*sref %d", lvl + 1, xlat_tabs, node->
attr.tmpl_request);
1606 DEBUG(
"%.*slist %d", lvl + 1, xlat_tabs, node->
attr.tmpl_list);
1609 DEBUG(
"%.*stag %d", lvl + 1, xlat_tabs, node->
attr.tmpl_tag);
1613 DEBUG(
"%.*s[#]", lvl + 1, xlat_tabs);
1615 DEBUG(
"%.*s[*]", lvl + 1, xlat_tabs);
1617 DEBUG(
"%.*s[%d]", lvl + 1, xlat_tabs, node->
attr.tmpl_num);
1621 DEBUG(
"%.*s}", lvl, xlat_tabs);
1627 DEBUG(
"%.*svirtual --> %s", lvl, xlat_tabs, node->
fmt);
1634 DEBUG(
"%.*s{", lvl, xlat_tabs);
1636 DEBUG(
"%.*s}", lvl, xlat_tabs);
1642 DEBUG(
"%.*sregex-var --> %d", lvl, xlat_tabs, node->
attr.tmpl_num);
1647 DEBUG(
"%.*sif {", lvl, xlat_tabs);
1649 DEBUG(
"%.*s}", lvl, xlat_tabs);
1650 DEBUG(
"%.*selse {", lvl, xlat_tabs);
1652 DEBUG(
"%.*s}", lvl, xlat_tabs);
1670 end = buffer + bufsize;
1673 switch (node->
type) {
1681 p[1] = node->
fmt[0];
1713 switch (node->
attr.tmpl_num) {
1774 if (p == end)
break;
1801 char const *error = NULL;
1811 if (!tokens)
return -1;
1829 talloc_free(tokens);
1838 DEBUG(
"Parsed xlat tree:");
1847 (void) talloc_steal(*head, tokens);
1854 bool escape,
bool return_null)
1862 char quote = escape ?
'"' :
'\0';
1881 if (vp)
goto do_print;
1888 if (!vpt->tmpl_da->flags.virtual) {
1889 if (vpt->tmpl_num ==
NUM_COUNT)
goto do_print;
1896 if (
radius_request(&request, vpt->tmpl_request) < 0)
return NULL;
1901 switch (vpt->tmpl_da->attr) {
1905 case PW_CLIENT_SHORTNAME:
1906 if (vpt->tmpl_num ==
NUM_COUNT)
goto count_virtual;
1912 case PW_REQUEST_PROCESSING_STAGE:
1913 if (vpt->tmpl_num ==
NUM_COUNT)
goto count_virtual;
1919 case PW_VIRTUAL_SERVER:
1920 if (vpt->tmpl_num ==
NUM_COUNT)
goto count_virtual;
1921 if (!request->
server)
return NULL;
1924 case PW_MODULE_RETURN_CODE:
1925 if (vpt->tmpl_num ==
NUM_COUNT)
goto count_virtual;
1926 if (!request->
rcode)
return NULL;
1937 if (return_null)
return NULL;
1942 switch (vpt->tmpl_da->attr) {
1946 case PW_PACKET_TYPE:
1947 if (packet->
code > 0) {
1956 return talloc_strdup(ctx,
"");
1958 case PW_RESPONSE_PACKET_TYPE:
1967 if (request->
reply) {
1976 return talloc_strdup(ctx,
"");
1985 case PW_PACKET_AUTHENTICATION_VECTOR:
1991 case PW_CLIENT_IP_ADDRESS:
1992 case PW_PACKET_SRC_IP_ADDRESS:
2000 case PW_PACKET_DST_IP_ADDRESS:
2008 case PW_PACKET_SRC_IPV6_ADDRESS:
2011 memcpy(&virtual->vp_ipv6addr,
2018 case PW_PACKET_DST_IPV6_ADDRESS:
2021 memcpy(&virtual->vp_ipv6addr,
2028 case PW_PACKET_SRC_PORT:
2030 virtual->vp_integer = packet->
src_port;
2034 case PW_PACKET_DST_PORT:
2036 virtual->vp_integer = packet->
dst_port;
2045 if (vpt->tmpl_num !=
NUM_ANY)
switch (vpt->tmpl_num) {
2062 ret = talloc_strdup(ctx,
"1");
2075 switch (vpt->tmpl_num) {
2101 if (!p)
return NULL;
2105 if (!q)
return NULL;
2106 p = talloc_strdup_append(p,
",");
2107 p = talloc_strdup_append(p, q);
2123 if (return_null)
return NULL;
2131 talloc_free(
virtual);
2136 static const char xlat_spaces[] =
" ";
2143 char *str = NULL, *child;
2148 switch (node->
type) {
2162 size_t freespace = 256;
2168 str = talloc_array(ctx,
char, freespace);
2184 strftime(str, freespace,
"%d", &ts);
2189 (
unsigned long) when);
2194 strftime(str, freespace,
"%m", &ts);
2202 CTIME_R(&when, str, freespace);
2203 nl = strchr(str,
'\n');
2209 strftime(str, freespace,
"%Y%m%d", &ts);
2214 strftime(str, freespace,
"%M", &ts);
2219 strftime(str, freespace,
"%H", &ts);
2230 strftime(str, freespace,
"%Y-%m-%d %H:%M:%S", &ts);
2235 strftime(str, freespace,
"%Y-%m-%d-%H.%M.%S.000000", &ts);
2245 strftime(str, freespace,
"%Y", &ts);
2249 RWDEBUG(
"%%v is deprecated and will be removed. Use ${version.freeradius-server}");
2266 str =
xlat_getvp(ctx, request, &node->
attr, escape ?
false :
true,
true);
2277 str = talloc_array(request,
char, node->
xlat->
buf_len);
2299 XLAT_DEBUG(
"%.*sEXPAND mod %s", lvl, xlat_spaces, node->
fmt);
2303 XLAT_DEBUG(
"%.*s ---> %s", lvl, xlat_spaces, child);
2317 if (
value_data_from_str(request, &data, &type, NULL, child, talloc_array_length(child) - 1,
'"') < 0) {
2330 if (*p ==
'\\')
switch (p[1]) {
2353 str = talloc_array(request,
char, node->
xlat->
buf_len);
2367 if (regex_request_to_sub(ctx, &str, request, node->
attr.tmpl_num) < 0)
return NULL;
2392 if (str && !str[0]) {
2400 if (str && escape) {
2403 escaped = talloc_array(ctx,
char, 2048);
2404 escape(request, escaped, 2038, str, escape_ctx);
2418 char **array, *answer;
2428 *out = talloc_zero_array(request,
char, 1);
2443 answer =
xlat_aprint(request, request, head, escape, escape_ctx, 0);
2445 *out = talloc_zero_array(request,
char, 1);
2449 return strlen(answer);
2453 for (node = head; node != NULL; node = node->
next) {
2457 array = talloc_array(request,
char *, list);
2458 if (!array)
return -1;
2460 for (node = head, i = 0; node != NULL; node = node->
next, i++) {
2461 array[i] =
xlat_aprint(array, request, node, escape, escape_ctx, 0);
2465 for (i = 0; i < list; i++) {
2466 if (array[i]) total += strlen(array[i]);
2471 *out = talloc_zero_array(request,
char, 1);
2475 answer = talloc_array(request,
char, total + 1);
2478 for (i = 0; i < list; i++) {
2482 len = strlen(array[i]);
2483 memcpy(answer + total, array[i], len);
2487 answer[total] =
'\0';
2515 len =
xlat_process(&buff, request, node, escape, escape_ctx);
2516 if ((len < 0) || !buff) {
2518 if (*out) **out =
'\0';
2541 static ssize_t
xlat_expand(
char **out,
size_t outlen,
REQUEST *request,
char const *fmt,
2570 *out = talloc_zero_array(request,
char, 1);
2576 if (*out) **out =
'\0';
2610 if (!vpt)
return NULL;
2643 return xlat_expand(&out, outlen, request, fmt, escape, ctx);
2653 return xlat_expand(out, 0, request, fmt, escape, ctx);
static ssize_t xlat_integer(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Print data as integer, not as VALUE.
size_t len
Length of the output string.
static ssize_t xlat_tokenize_request(REQUEST *request, char const *fmt, xlat_exp_t **head)
Tokenize an xlat expansion.
static ssize_t xlat_attr(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Return the attribute name of an attribute reference.
void * mod_inst
Module instance passed to xlat and escape functions.
int id
Packet ID (used to link requests/responses).
#define RINDENT()
Indent R* messages by one level.
static char const xlat_tabs[]
struct timeval timestamp
When we received the packet.
int int map_to_request(REQUEST *request, vp_map_t const *map, radius_map_getvalue_t func, void *ctx)
Convert vp_map_t to VALUE_PAIR (s) and add them to a REQUEST.
vp_tmpl_t * xlat_to_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_t *node)
Try to convert an xlat to a tmpl for efficiency.
void rbtree_free(rbtree_t *tree)
vp_tmpl_t attr
An attribute template.
static ssize_t xlat_foreach(char **out, size_t outlen, void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, UNUSED char const *fmt)
Implements the Foreach-Variable-X.
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
Time value (struct timeval), only for config items.
ssize_t radius_xlat(char *out, size_t outlen, REQUEST *request, char const *fmt, xlat_escape_t escape, void *ctx)
static ssize_t xlat_module(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, UNUSED char const *fmt)
Prints the current module processing the request.
RADIUS_PACKET * proxy_reply
Incoming response from proxy server.
struct rad_request::@7 log
uint128_t ntohlll(uint128_t const num)
Swap byte order of 128 bit integer.
bool rbtree_deletebydata(rbtree_t *tree, void const *data)
Delete a node from the tree, based on given data, which MUST have come from rbtree_finddata().
static ssize_t xlat_tag(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Return the tag of an attribute reference.
RADIUS_PACKET * radius_packet(REQUEST *request, pair_lists_t list_name)
Resolve a list to the RADIUS_PACKET holding the HEAD pointer for a VALUE_PAIR list.
void xlat_free(void)
De-register all xlat functions, used mainly for debugging.
#define RDEBUG_ENABLED2
True if request debug level 1-2 messages are enabled.
char const * fr_packet_codes[FR_MAX_PACKET_CODE]
char const * name
Raw string used to create the template.
uint32_t fr_rand(void)
Return a 32-bit random number.
rbnode_t * rbtree_insert_node(rbtree_t *tree, void *data)
Insert an element into the tree.
xlat conditional syntax :-
rlm_rcode_t rcode
Last rcode returned by a module.
fr_ipaddr_t src_ipaddr
Src IP address of packet.
WiMAX IPv4 or IPv6 address depending on length.
xlat_exp_t * alternate
Alternative expansion if this one expanded to a zero length string.
size_t length
Length of length data.
static int xlat_foreach_inst[]
ssize_t(* xlat_func_t)(char **out, size_t outlen, void const *mod_inst, void const *xlat_inst, REQUEST *request, char const *fmt)
xlat callback function
#define REMARKER(_m, _i, _e)
Output string with error marker, showing where format error occurred.
ssize_t tmpl_from_attr_substr(vp_tmpl_t *vpt, char const *name, request_refs_t request_def, pair_lists_t list_def, bool allow_unknown, bool allow_undefined)
Parse a string into a TMPL_TYPE_ATTR_* or TMPL_TYPE_LIST type vp_tmpl_t.
void xlat_unregister(void *mod_inst, char const *name, UNUSED xlat_func_t func)
Unregister an xlat function.
int8_t tag
Tag value used to group valuepairs.
void size_t fr_pair_value_snprint(char *out, size_t outlen, VALUE_PAIR const *vp, char quote)
Print the value of an attribute to a string.
const FR_NAME_NUMBER fr_tokens_table[]
char name[MAX_STRING_LEN]
Name of the xlat expansion.
void * request_data_reference(REQUEST *request, void *unique_ptr, int unique_int)
Get opaque data from a request without removing it.
static ssize_t xlat_map(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Processes fmt as a map string and applies it to the current request.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Number of defined data types.
#define RBTREE_FLAG_REPLACE
Long extended attribute space attribute.
void * rbtree_finddata(rbtree_t *tree, void const *data)
Find the user data.
size_t len
Length of the format string.
unsigned int number
Monotonically increasing request number. Reset on server restart.
size_t(* xlat_escape_t)(REQUEST *request, char *out, size_t outlen, char const *in, void *arg)
#define XLAT_DEFAULT_BUF_LEN
uint16_t dst_port
DST Port of packet.
uint16_t src_port
Src port of packet.
fr_ipaddr_t dst_ipaddr
Dst IP address of packet.
static char const *const xlat_foreach_names[]
ssize_t fr_radius_encode_value_hton(uint8_t const **out, VALUE_PAIR const *vp)
Converts vp_data to network byte order.
Abstraction to allow iterating over different configurations of VALUE_PAIRs.
fr_dict_attr_flags_t flags
Flags.
fr_dict_vendor_t const * fr_dict_vendor_by_num(fr_dict_t *dict, int vendor)
Look up a vendor by its PEN.
const FR_NAME_NUMBER modreturn_table[]
size_t fr_snprint(char *out, size_t outlen, char const *in, ssize_t inlen, char quote)
Escape any non printable or non-UTF8 characters in the input string.
void vradlog_request(log_type_t type, log_lvl_t lvl, REQUEST *request, char const *msg, va_list ap) CC_HINT(format(printf
WiMAX IPv4 or IPv6 address prefix depending on length.
char * fr_pair_value_asprint(TALLOC_CTX *ctx, VALUE_PAIR const *vp, char quote)
Print one attribute value to a string.
static ssize_t xlat_expand(char **out, size_t outlen, REQUEST *request, char const *fmt, xlat_escape_t escape, void *escape_ctx) CC_HINT(nonnull(1
Replace whatever in a string.
int(* xlat_instantiate_t)(void *xlat_inst, void *mod_inst, char const *fmt)
Allocate new instance data for an xlat instance.
#define is_truncated(_ret, _max)
Attribute not found in the global dictionary.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
const FR_NAME_NUMBER request_refs[]
Map keywords to request_refs_t values.
VALUE_PAIR * tmpl_cursor_init(int *err, vp_cursor_t *cursor, REQUEST *request, vp_tmpl_t const *vpt)
Initialise a vp_cursor_t to the VALUE_PAIR specified by a vp_tmpl_t.
static ssize_t xlat_string(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Print data as string, if possible.
int value_data_cast(TALLOC_CTX *ctx, value_data_t *dst, PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv, PW_TYPE src_type, fr_dict_attr_t const *src_enumv, value_data_t const *src)
Convert one type of value_data_t to another.
char const * cf_pair_attr(CONF_PAIR const *pair)
rbtree_t * rbtree_create(TALLOC_CTX *ctx, rb_comparator_t compare, rb_free_t node_free, int flags)
Create a new RED-BLACK tree.
static ssize_t xlat_debug(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Dynamically change the debugging level for the current request.
char const * component
Section the request is in.
ssize_t tmpl_from_attr_str(vp_tmpl_t *vpt, char const *name, request_refs_t request_def, pair_lists_t list_def, bool allow_unknown, bool allow_undefined)
Parse a string into a TMPL_TYPE_ATTR_* or TMPL_TYPE_LIST type vp_tmpl_t.
static size_t xlat_process(char **out, REQUEST *request, xlat_exp_t const *const head, xlat_escape_t escape, void *escape_ctx)
const FR_NAME_NUMBER dict_attr_types[]
Map data types to names representing those types.
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *item)
Cast a CONF_ITEM to a CONF_PAIR.
unsigned int attr
Attribute number.
union fr_ipaddr_t::@1 ipaddr
Attributes in incoming or internally proxied request.
xlat_func_t func
xlat function.
int radius_request(REQUEST **request, request_refs_t name)
Resolve a request_refs_t to a REQUEST.
#define RDEBUG_ENABLED4
True if request debug level 1-4 messages are enabled.
unsigned int code
Packet code (type).
int rbtree_walk(rbtree_t *tree, rb_order_t order, rb_walker_t compare, void *context)
char * fr_pair_type_snprint(TALLOC_CTX *ctx, PW_TYPE type)
unsigned int vendor
Vendor that defines this attribute.
void void int radius_get_vp(VALUE_PAIR **out, REQUEST *request, char const *name)
Return a VP from the specified request.
static ssize_t xlat_hex(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Print data as hex, not as VALUE.
static rbtree_t * xlat_root
static xlat_t * xlat_find(char const *name)
Stores an attribute, a value and various bits of other data.
void rad_const_free(void const *ptr)
VALUE_PAIR * fr_cursor_current(vp_cursor_t *cursor)
Return the VALUE_PAIR the cursor current points to.
RADIUS_PACKET * reply
Outgoing response.
char * talloc_typed_asprintf(void const *t, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
ssize_t xlat_tokenize(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head, char const **error)
bool internal
If true, cannot be redefined.
void void cf_log_err_cs(CONF_SECTION const *cs, char const *fmt,...) CC_HINT(format(printf
xlat_exp_t * child
Nested expansion.
ssize_t xlat_fmt_to_ref(uint8_t const **out, REQUEST *request, char const *fmt)
Crappy temporary function to add attribute ref support to xlats.
bool cf_item_is_pair(CONF_ITEM const *item)
static ssize_t xlat_vendor_num(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Return the vendor number of an attribute reference.
Invalid (uninitialised) attribute type.
#define REXDENT()
Exdent (unindent) R* messages by one level.
ssize_t radius_axlat(char **out, REQUEST *request, char const *fmt, xlat_escape_t escape, void *ctx)
FR_TOKEN op
Operator to use when moving or inserting valuepair into a list.
tmpl_type_t type
What type of value tmpl refers to.
uint8_t vector[AUTH_VECTOR_LEN]
RADIUS authentication vector.
int length
Length of name.
char const * fr_strerror(void)
Get the last library error.
size_t len
Length of the raw string used to create the template.
xlat_exp_t * xlat_from_tmpl_attr(TALLOC_CTX *ctx, vp_tmpl_t *vpt)
Try to convert attr tmpl to an xlat for &attr[*] and artificially constructing expansions.
char const * cf_section_name1(CONF_SECTION const *cs)
vp_tmpl_t * tmpl_init(vp_tmpl_t *vpt, tmpl_type_t type, char const *name, ssize_t len, FR_TOKEN quote)
Initialise stack allocated vp_tmpl_t.
Vendor-Specific, for RADIUS attribute 26.
char name[1]
Attribute name.
static ssize_t xlat_tokenize_expansion(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head, char const **error)
size_t length
Length of value data.
char * talloc_bstrndup(void const *t, char const *in, size_t inlen)
Binary safe strndup function.
size_t buf_len
Length of output buffer to pre-allocate.
static ssize_t xlat_expand_struct(char **out, size_t outlen, REQUEST *request, xlat_exp_t const *node, xlat_escape_t escape, void *escape_ctx)
Replace whatever in a string.
#define RIDEBUG2(fmt,...)
int int map_afrom_attr_str(TALLOC_CTX *ctx, vp_map_t **out, char const *raw, request_refs_t dst_request_def, pair_lists_t dst_list_def, request_refs_t src_request_def, pair_lists_t src_list_def)
Convert a value pair string to valuepair map.
size_t xlat_snprint(char *buffer, size_t bufsize, xlat_exp_t const *node)
Extended attribute space attribute.
struct timeval timestamp
When we started processing the request.
log_lvl_t rad_debug_lvl
Global debugging level.
static ssize_t xlat_attr_num(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Return the attribute number of an attribute reference.
static ssize_t xlat_load_balance(char **out, size_t outlen, void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
struct xlat_redundant_t xlat_redundant_t
char const * out
Output data.
xlat_state_t type
type of this expansion.
static char * xlat_getvp(TALLOC_CTX *ctx, REQUEST *request, vp_tmpl_t const *vpt, bool escape, bool return_null)
int value_data_from_str(TALLOC_CTX *ctx, value_data_t *dst, PW_TYPE *src_type, fr_dict_attr_t const *src_enumv, char const *src, ssize_t src_len, char quote)
Convert string value to a value_data_t type.
RADIUS_PACKET * packet
Incoming request.
static ssize_t xlat_vendor(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Return the vendor of an attribute reference.
static char * xlat_aprint(TALLOC_CTX *ctx, REQUEST *request, xlat_exp_t const *const node, xlat_escape_t escape, void *escape_ctx, int lvl)
fr_dict_enum_t * fr_dict_enum_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, int value)
Lookup the structure representing an enum value in a fr_dict_attr_t.
static ssize_t xlat_tokenize_alternation(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head, char const **error)
static ssize_t xlat_tokenize_literal(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head, bool brace, char const **error)
bool xlat_register_redundant(CONF_SECTION *cs)
unsigned int has_tag
Tagged attribute.
static void xlat_tokenize_debug(xlat_exp_t const *node, int lvl)
CONF_ITEM * cf_item_find_next(CONF_SECTION const *section, CONF_ITEM const *item)
Return the next item after a CONF_ITEM.
int map_to_vp(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request, vp_map_t const *map, void *uctx) CC_HINT(nonnull(2
xlat_instantiate_t instantiate
Instantiation function.
static ssize_t xlat_strlen(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, UNUSED REQUEST *request, char const *fmt)
Print length of its RHS.
struct xlat_out xlat_out_t
static ssize_t xlat_redundant(char **out, size_t outlen, void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
#define XLAT_REGISTER(_x)
#define RAD_REQUEST_LVL_NONE
No debug messages should be printed.
static ssize_t xlat_debug_attr(UNUSED char **out, UNUSED size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Print out attribute info.
ssize_t radius_xlat_struct(char *out, size_t outlen, REQUEST *request, xlat_exp_t const *xlat, xlat_escape_t escape, void *ctx)
char const * fmt
The format string.
size_t strlcpy(char *dst, char const *src, size_t siz)
VALUE_PAIR * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute.
char const * fr_int2str(FR_NAME_NUMBER const *table, int number, char const *def)
fr_dict_attr_t const * da
Dictionary attribute defines the attribute.
void xlat_unregister_module(void *instance)
size_t inst_size
Length of instance data to pre-allocate.
static ssize_t xlat_length(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
Print the size of the attribute in bytes.
String of printable characters.
Contains nested attributes.
size_t fr_snprint_uint128(char *out, size_t outlen, uint128_t const num)
Write 128bit unsigned integer to buffer.
RADCLIENT * client
The client that originally sent us the request.
char const * radiusd_version_short
VALUE_PAIR * tmpl_cursor_next(vp_cursor_t *cursor, vp_tmpl_t const *vpt)
Returns the next VALUE_PAIR specified by vpt.
struct tm * localtime_r(time_t const *l_clock, struct tm *result)
xlat_redundant_type_t type
xlat_t const * xlat
The xlat expansion to expand format with.
static int xlat_unregister_callback(void *mod_inst, void *data)
static ssize_t xlat_xlat(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
xlat expand string attribute value
char * talloc_typed_strdup(void const *t, char const *p)
Call talloc strdup, setting the type on the new chunk correctly.
ssize_t radius_axlat_struct(char **out, REQUEST *request, xlat_exp_t const *xlat, xlat_escape_t escape, void *ctx)
char const * module
Module the request is currently being processed by.
union vp_tmpl_t::@11 data
int xlat_register(void *mod_inst, char const *name, xlat_func_t func, xlat_escape_t escape, xlat_instantiate_t instantiate, size_t inst_size, size_t buf_len)
Register an xlat function.
xlat_exp_t * next
Next in the list.
static int xlat_cmp(void const *one, void const *two)
A source or sink of value data.
char * value_data_asprint(TALLOC_CTX *ctx, PW_TYPE type, fr_dict_attr_t const *enumv, value_data_t const *data, char quote)
Print one attribute value to a string.
Value of an enumerated attribute.
void fr_pair_value_memcpy(VALUE_PAIR *vp, uint8_t const *src, size_t len)
Copy data into an "octets" data type.
vp_tmpl_t * tmpl_alloc(TALLOC_CTX *ctx, tmpl_type_t type, char const *name, ssize_t len, FR_TOKEN quote)
Create a new heap allocated vp_tmpl_t.
char const * cf_section_name2(CONF_SECTION const *cs)
xlat_escape_t escape
Escape function to apply to dynamic input to func.
char const * shortname
Client nickname.
PW_TYPE
Internal data types used within libfreeradius.
Extended attribute, vendor specific.