24 RCSID(
"$Id: d3b8ce762cfd1e4d8bfb428b6f9a6cbe7a235458 $")
26 #include <freeradius-devel/server/base.h>
27 #include <freeradius-devel/server/exfile.h>
28 #include <freeradius-devel/server/module_rlm.h>
29 #include <freeradius-devel/server/tmpl_dcursor.h>
30 #include <freeradius-devel/server/rcode.h>
31 #include <freeradius-devel/server/tmpl.h>
32 #include <freeradius-devel/unlang/call_env.h>
33 #include <freeradius-devel/unlang/tmpl.h>
34 #include <freeradius-devel/unlang/module.h>
36 #include <freeradius-devel/util/debug.h>
37 #include <freeradius-devel/util/iovec.h>
38 #include <freeradius-devel/util/perm.h>
39 #include <freeradius-devel/util/print.h>
40 #include <freeradius-devel/util/value.h>
41 #include <freeradius-devel/util/types.h>
43 #include <freeradius-devel/unlang/xlat_func.h>
68 UNUSED char const *section_name1,
UNUSED char const *section_name2,
114 char const *facility;
115 char const *severity;
121 char const *group_str;
255 switch (
inst->log_dst) {
257 DEBUG2(
"Opening UNIX socket at \"%s\"",
inst->unix_sock.path);
260 PERROR(
"Failed opening UNIX socket");
270 PERROR(
"Failed opening TCP socket");
280 PERROR(
"Failed opening UDP socket");
298 if (errno == EINPROGRESS) {
300 DEBUG2(
"Waiting for connection to complete...");
302 DEBUG2(
"Blocking until connection complete...");
305 PERROR(
"Failed connecting to log destination");
310 DEBUG2(
"Connection successful");
316 ERROR(
"Failed setting nonblock flag on fd");
344 if (vb->vb_length == 0)
return 0;
346 MEM(escaped =
fr_asprint(vb, vb->vb_strvalue, vb->vb_length, 0));
371 switch (
inst->log_dst) {
380 RERROR(
"Missing filename");
384 path = call_env->
filename->vb_strvalue;
387 p = strrchr(path,
'/');
390 if (
fr_mkdir(NULL, path, -1, 0700, NULL, NULL) < 0) {
403 if (
inst->file.group_str && (chown(path, -1,
inst->file.group) == -1)) {
412 if (call_env->
log_head && (offset == 0)) {
413 struct iovec head_vector_s[2];
414 size_t head_vector_len;
416 memcpy(&head_vector_s[0].iov_base, &call_env->
log_head->vb_strvalue,
sizeof(head_vector_s[0].iov_base));
417 head_vector_s[0].iov_len = call_env->
log_head->vb_length;
422 memcpy(&head_vector_s[1].iov_base, &(
inst->delimiter),
423 sizeof(head_vector_s[1].iov_base));
424 head_vector_s[1].iov_len =
inst->delimiter_len;
430 if (writev(fd, &head_vector_s[0], head_vector_len) < 0) {
436 fr_assert((errno != EINVAL) && (errno != EFAULT));
444 ret = writev(fd, vector_p, vector_len);
445 if (ret < 0)
goto write_fail;
456 for (i = 0; i < vector_len; i++) {
457 RINFO(
"%.*s", (
int)vector_p[i].iov_len, (
char *)vector_p[i].iov_base);
458 ret += vector_p[i].iov_len;
485 if (!conn)
return -1;
487 for (i = num; i >= 0; i--) {
493 if (wrote < 0)
switch (errno) {
502 RWARN(
"Failed writing to socket: %s. Will reconnect and try again...",
523 RDEBUG2(
"Wrote %zi bytes", wrote);
527 while (read(conn->
sockfd, discard,
sizeof(discard)) > 0);
541 for (i = 0; i < vector_len; i++) {
542 syslog(
inst->syslog.priority,
"%.*s", (
int)vector_p[i].iov_len, (
char *)vector_p[i].iov_base);
543 ret += vector_p[i].iov_len;
553 if ((ret = writev(fd, vector_p, vector_len)) < 0) {
554 RERROR(
"Failed writing to \"%s\": %s",
572 fr_value_box_list_t *
args)
577 struct iovec vector[2];
585 vector[i].iov_base =
UNCONST(
char *,
msg->vb_strvalue);
586 vector[i].iov_len =
msg->vb_length;
591 memcpy(&vector[i].iov_base, &(
inst->delimiter),
sizeof(vector[i].iov_base));
592 vector[i].iov_len =
inst->delimiter_len;
599 wrote->vb_size = (
size_t)slen;
616 struct iovec *vector;
617 struct iovec *vector_p;
620 vector_len = fr_value_box_list_num_elements(&rctx->
expanded);
621 if (vector_len == 0) {
631 MEM(vector = vector_p = talloc_array(rctx,
struct iovec, vector_len));
636 REDEBUG(
"Failed casting value to string");
642 vector_p->iov_base =
UNCONST(
char *, vb->vb_strvalue);
643 vector_p->iov_len = vb->vb_length;
648 vector_p->iov_base =
UNCONST(
char *, vb->vb_octets);
649 vector_p->iov_len = vb->vb_length;
658 memcpy(&vector_p->iov_base, &(
inst->delimiter),
sizeof(vector_p->iov_base));
659 vector_p->iov_len =
inst->delimiter_len;
686 tmpl_t *empty, *
vpt = NULL, *vpt_p = NULL;
693 cf_log_err(
conf,
"A 'format', or 'reference' configuration item must be set to call this module");
708 char const *tmpl_str;
713 if (
buff[1] ==
'.') p++;
718 if (
buff[2] ==
'.') {
719 REDEBUG(
"Invalid path \"%s\"", p);
725 RDEBUG2(
"Path \"%s\" doesn't exist", p);
730 REDEBUG(
"Path \"%s\" resolves to a section (should be a pair)", p);
736 if (!tmpl_str || (tmpl_str[0] ==
'\0')) {
737 RDEBUG2(
"Path \"%s\" resolves to an empty config pair", p);
738 empty = talloc(frame_ctx,
tmpl_t);
750 &
FR_SBUFF_IN(tmpl_str, talloc_array_length(tmpl_str) - 1),
756 .dict_def = request->dict,
757 .allow_unknown =
true,
758 .allow_unresolved =
false,
770 RPERROR(
"Runtime resolution of tmpl failed");
781 RDEBUG2(
"No default message configured");
787 RDEBUG2(
"Using default message");
797 switch (vpt_p->type) {
800 #define VECTOR_INCREMENT 20
805 struct iovec *vector = NULL, *vector_p;
809 MEM(vector = talloc_array(frame_ctx,
struct iovec, alloced));
814 if ((with_delim && ((i + 1) >= alloced)) ||
817 MEM(vector = talloc_realloc(frame_ctx, vector,
struct iovec, alloced));
820 switch (
vp->vp_type) {
823 vector[i].iov_len =
vp->vp_length;
824 vector[i].iov_base =
vp->vp_ptr;
829 vector[i].iov_base = p;
838 memcpy(&vector[i].iov_base, &(
inst->delimiter),
sizeof(vector[i].iov_base));
839 vector[i].iov_len =
inst->delimiter_len;
846 if (vector_len == 0) {
867 fr_value_box_list_init(&rctx->
expanded);
879 UNUSED char const *section_name1,
UNUSED char const *section_name2,
892 our_rules = *t_rules;
903 *(
void **)
out = parsed;
936 switch (
inst->log_dst) {
948 if (!
inst->file.ef) {
953 if (
inst->file.group_str) {
956 inst->file.group = strtol(
inst->file.group_str, &endptr, 10);
957 if (*endptr !=
'\0') {
960 inst->file.group_str);
972 #ifndef HAVE_SYSLOG_H
973 cf_log_err(
conf,
"Syslog output is not supported on this system");
976 if (
inst->syslog.facility) {
982 inst->syslog.priority |= num;
990 inst->syslog.priority |= num;
996 #ifndef HAVE_SYS_UN_H
997 cf_log_err(
conf,
"Unix sockets are not supported on this system");
1002 if (!
inst->pool)
return -1;
1009 if (!
inst->pool)
return -1;
1015 if (!
inst->pool)
return -1;
1028 inst->delimiter_len = talloc_array_length(
inst->delimiter) - 1;
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define L(_str)
Helper for initialising arrays of string literals.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
#define CALL_ENV_TERMINATOR
#define FR_CALL_ENV_METHOD_OUT(_inst)
Helper macro for populating the size/type fields of a call_env_method_t from the output structure typ...
@ CALL_ENV_FLAG_CONCAT
If the tmpl produced multiple boxes they should be concatenated.
@ CALL_ENV_FLAG_PARSE_ONLY
The result of parsing will not be evaluated at runtime.
#define FR_CALL_ENV_SUBSECTION(_name, _ident2, _flags, _subcs)
Specify a call_env_parser_t which defines a nested subsection.
#define FR_CALL_ENV_OFFSET(_name, _cast_type, _flags, _struct, _field)
Specify a call_env_parser_t which writes out runtime results to the specified field.
#define FR_CALL_ENV_PARSE_ONLY_OFFSET(_name, _cast_type, _flags, _struct, _parse_field)
Specify a call_env_parser_t which writes out the result of the parsing phase to the field specified.
CONF_ITEM * cf_reference_item(CONF_SECTION const *parent_cs, CONF_SECTION const *outer_cs, char const *ptr)
#define CONF_PARSER_TERMINATOR
#define FR_CONF_DEPRECATED(_name, _struct, _field)
conf_parser_t entry which raises an error if a matching CONF_PAIR is found
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Defines a CONF_PAIR to C data type mapping.
Common header for all CONF_* types.
Configuration AVP similar to a fr_pair_t.
A section grouping multiple CONF_PAIR.
bool cf_item_is_pair(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_PAIR.
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
CONF_PAIR * cf_pair_find(CONF_SECTION const *cs, char const *attr)
Search for a CONF_PAIR with a specific name.
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
fr_token_t cf_pair_value_quote(CONF_PAIR const *pair)
Return the value (rhs) quoting of a pair.
#define cf_log_err(_cf, _fmt,...)
#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.
static int fr_dcursor_insert(fr_dcursor_t *cursor, void *v)
Insert directly after the current item.
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
static fr_time_delta_t timeout
char const *_CONST name
Instance name.
void *_CONST data
Module instance's parsed configuration.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
CONF_SECTION *_CONST conf
Module's instance configuration.
dl_module_inst_t const * inst
int exfile_open(exfile_t *ef, char const *filename, mode_t permissions, off_t *offset)
Open a new log file, or maybe an existing one.
int exfile_close(exfile_t *ef, int fd)
Close the log file.
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.
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
ssize_t fr_writev(int fd, struct iovec vector[], int iovcnt, fr_time_delta_t timeout)
Write out a vector to a file descriptor.
fr_slen_t fr_concatv(fr_dbuff_t *out, struct iovec vector[], int iovcnt)
Concatenate an iovec into a dbuff.
fr_table_num_sorted_t const syslog_severity_table[]
Syslog severity table.
fr_table_num_sorted_t const syslog_facility_table[]
Syslog facility table.
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
#define REMARKER(_str, _marker_idx, _marker,...)
Output string with error marker, showing where format error occurred.
#define RHEXDUMP3(_data, _len, _fmt,...)
int rad_filename_box_escape(fr_value_box_t *vb, UNUSED void *uxtc)
int rad_filename_box_make_safe(fr_value_box_t *vb, UNUSED void *uxtc)
@ FR_TYPE_STRING
String of printable characters.
@ 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_OCTETS
Raw octets.
int fr_blocking(UNUSED int fd)
void * env_data
Per call environment data.
void * rctx
Resume ctx that a module previously set.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for instantiation calls.
Specifies a module method identifier.
exfile_t * module_rlm_exfile_init(TALLOC_CTX *ctx, CONF_SECTION *module, uint32_t max_entries, fr_time_delta_t max_idle, bool locking, char const *trigger_prefix, fr_pair_list_t *trigger_args)
Initialise a module specific exfile handle.
fr_pool_t * module_rlm_connection_pool_init(CONF_SECTION *module, void *opaque, fr_pool_connection_create_t c, fr_pool_connection_alive_t a, char const *log_prefix, char const *trigger_prefix, fr_pair_list_t *trigger_args)
Initialise a module specific connection pool.
module_t common
Common fields presented by all modules.
int fr_perm_gid_from_str(TALLOC_CTX *ctx, gid_t *out, char const *name)
Resolve a group name to a GID.
void fr_pool_connection_release(fr_pool_t *pool, request_t *request, void *conn)
Release a connection.
void fr_pool_free(fr_pool_t *pool)
Delete a connection pool.
fr_pool_state_t const * fr_pool_state(fr_pool_t *pool)
Get the number of connections currently in the pool.
void * fr_pool_connection_get(fr_pool_t *pool, request_t *request)
Reserve a connection in the connection pool.
void * fr_pool_connection_reconnect(fr_pool_t *pool, request_t *request, void *conn)
Reconnect a suspected inviable connection.
uint32_t num
Number of connections in the pool.
char * fr_asprint(TALLOC_CTX *ctx, char const *in, ssize_t inlen, char quote)
Escape string that may contain binary data, and write it to a new buffer.
static const conf_parser_t config[]
#define RETURN_MODULE_NOOP
#define RETURN_MODULE_RCODE(_rcode)
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_OK
The module is OK, continue.
@ RLM_MODULE_FAIL
Module failed, don't reply.
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
fr_dict_attr_t const * request_attr_request
static int mod_detach(module_detach_ctx_t const *mctx)
static int call_env_filename_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, UNUSED char const *section_name1, UNUSED char const *section_name2, void const *data, UNUSED call_env_parser_t const *rule)
tmpl_t * log_src
Source of log messages.
static const conf_parser_t file_config[]
static const call_env_method_t linelog_xlat_method_env
linelog_net_t tcp
TCP server.
linelog_net_t udp
UDP server.
static const conf_parser_t syslog_config[]
fr_ipaddr_t src_ipaddr
Send requests from a given src_ipaddr.
size_t delimiter_len
Length of line termination string.
static xlat_action_t linelog_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
static int _mod_conn_free(linelog_conn_t *conn)
static unlang_action_t mod_do_linelog(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Write a linelog message.
static int mod_bootstrap(module_inst_ctx_t const *mctx)
fr_value_box_list_t expanded
The result of expanding the fmt tmpl.
fr_ipaddr_t dst_ipaddr
Network server.
static const conf_parser_t udp_config[]
static void linelog_hexdump(request_t *request, struct iovec *vector_p, size_t vector_len, char const *msg)
fr_pool_t * pool
Connection pool instance.
static int linelog_write(rlm_linelog_t const *inst, linelog_call_env_t const *call_env, request_t *request, struct iovec *vector_p, size_t vector_len, bool with_delim)
fr_time_delta_t timeout
How long to wait for read/write operations.
int sockfd
File descriptor associated with socket.
@ LINELOG_DST_FILE
Log to a file.
@ LINELOG_DST_STDERR
Log to stderr.
@ LINELOG_DST_UNIX
Log via Unix socket.
@ LINELOG_DST_STDOUT
Log to stdout.
@ LINELOG_DST_TCP
Log via TCP.
@ LINELOG_DST_REQUEST
Log to the request->log.
@ LINELOG_DST_UDP
Log via UDP.
@ LINELOG_DST_SYSLOG
Log to syslog.
fr_value_box_t * log_head
Header to add to each new log file.
static void * mod_conn_create(TALLOC_CTX *ctx, void *instance, fr_time_delta_t timeout)
static unlang_action_t mod_do_linelog_resume(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
uint16_t port
Network port.
static fr_table_num_sorted_t const linefr_log_dst_table[]
static const call_env_method_t linelog_method_env
CONF_SECTION * cs
CONF_SECTION to use as the root for #log_ref lookups.
static const conf_parser_t module_config[]
static int linelog_escape_func(fr_value_box_t *vb, UNUSED void *uctx)
Escape unprintable characters.
fr_value_box_t * log_ref
Path to a CONF_PAIR (to use as the source of log messages).
static const conf_parser_t unix_config[]
fr_value_box_t * filename
File name, if output is to a file.
static size_t linefr_log_dst_table_len
static int mod_instantiate(module_inst_ctx_t const *mctx)
char const * delimiter
Line termination string (usually ).
bool with_delim
Whether to add a delimiter.
static const conf_parser_t tcp_config[]
linefr_log_dst_t log_dst
Logging destination.
char const * log_dst_str
Logging destination string.
static int instantiate(module_inst_ctx_t const *mctx)
#define FR_SBUFF_IN(_start, _len_or_end)
#define MODULE_NAME_TERMINATOR
tmpl_escape_t escape
How escaping should be handled during evaluation.
int tmpl_resolve(tmpl_t *vpt, tmpl_res_rules_t const *tr_rules))
Attempt to resolve functions and attributes in xlats and attribute references.
fr_value_box_safe_for_t literals_safe_for
safe_for value assigned to literal values in xlats, execs, and data.
@ TMPL_TYPE_ATTR
Reference to one or more attributes.
@ TMPL_TYPE_DATA
Value in native boxed format.
ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_token_t quote, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Convert an arbitrary string into a tmpl_t.
tmpl_t * tmpl_init_shallow(tmpl_t *vpt, tmpl_type_t type, fr_token_t quote, char const *name, ssize_t len, tmpl_rules_t const *t_rules))
Initialise a tmpl without copying the input name string.
Optional arguments passed to vp_tmpl functions.
static char buff[sizeof("18446744073709551615")+3]
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
int fr_socket_client_udp(char const *ifname, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async)
Establish a connected UDP socket.
int fr_socket_client_tcp(char const *ifname, fr_ipaddr_t *src_ipaddr, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async)
Establish a connected TCP socket.
int fr_socket_wait_for_connect(int sockfd, fr_time_delta_t timeout)
Wait for a socket to be connected, with an optional timeout.
int fr_socket_client_unix(UNUSED char const *path, UNUSED bool async)
unlang_action_t unlang_module_yield_to_tmpl(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt, unlang_tmpl_args_t *args, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
Push a pre-compiled tmpl and resumption state onto the stack for evaluation.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
Stores an attribute, a value and various bits of other data.
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_str_by_value(_table, _number, _def)
Convert an integer to a string.
An element in a lexicographically sorted array of name to num mappings.
#define talloc_get_type_abort_const
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
#define fr_time_delta_wrap(_time)
#define fr_time_delta_ispos(_a)
A time delta, a difference in time measured in nanoseconds.
void tmpl_dcursor_clear(tmpl_dcursor_ctx_t *cc)
Clear any temporary state allocations.
#define tmpl_dcursor_init(_err, _ctx, _cc, _cursor, _request, _vpt)
Maintains state between cursor calls.
fr_value_box_escape_t func
How to escape when returned from evaluation.
@ TMPL_ESCAPE_PRE_CONCAT
Pre-concatenation escaping is useful for DSLs where elements of the expansion are static,...
fr_value_box_safe_for_t safe_for
Value to set on boxes which have been escaped by the fr_value_box_escape_t function.
tmpl_escape_mode_t mode
Whether to apply escape function after concatenation, i.e.
bool required
Argument must be present, and non-empty.
#define XLAT_ARGS(_list,...)
Populate local variables with value boxes from the input list.
#define XLAT_ARG_PARSER_TERMINATOR
@ XLAT_ACTION_FAIL
An xlat function failed.
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition for a single argument consumend by an xlat function.
char const * fr_strerror(void)
Get the last library error.
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_strdup_shallow_replace(fr_value_box_t *vb, char const *src, ssize_t len)
Free the existing buffer (if talloced) associated with the valuebox, and replace it with a new one.
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.
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
static fr_slen_t fr_value_box_aprint(TALLOC_CTX *ctx, char **out, fr_value_box_t const *data, fr_sbuff_escape_rules_t const *e_rules) 1(fr_value_box_print
#define fr_box_ipaddr(_val)
#define fr_value_box_init_null(_vb)
Initialise an empty/null box that will be filled later.
uintptr_t fr_value_box_safe_for_t
Escaping that's been applied to a value box.
#define fr_value_box_list_foreach(_list_head, _iter)
static size_t char ** out
module_ctx_t const * mctx
Synthesised module calling ctx.
void * env_data
Expanded call env data.
void xlat_func_call_env_set(xlat_t *x, call_env_method_t const *env_method)
Register call environment of an xlat.
int xlat_func_mono_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the argument of an xlat.
xlat_t * xlat_func_register_module(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function for a module.