25 RCSID(
"$Id: 3c1ac23a4d58ee9062aece1f3ee762b0f1fd16f4 $")
27 #define LOG_PREFIX mctx->mi->name
31 #include <freeradius-devel/server/log.h>
32 #include <freeradius-devel/server/module_rlm.h>
33 #include <freeradius-devel/server/tmpl.h>
34 #include <freeradius-devel/server/exec.h>
35 #include <freeradius-devel/server/main_config.h>
36 #include <freeradius-devel/unlang/interpret.h>
37 #include <freeradius-devel/unlang/call_env.h>
38 #include <freeradius-devel/util/debug.h>
39 #include <freeradius-devel/util/token.h>
40 #include <freeradius-devel/server/pairmove.h>
41 #include <freeradius-devel/unlang/xlat_func.h>
42 #include <freeradius-devel/unlang/xlat.h>
43 #include <freeradius-devel/unlang/module.h>
88 RPEDEBUG(
"Execution of external program failed");
97 RPEDEBUG(
"Execution of external program returned %d", exec->
status);
145 if (
inst->input_list) {
148 REDEBUG(
"Failed to find input pairs for xlat");
155 RPEDEBUG(
"Failed executing program");
165 env_pairs,
inst->shell_escape,
inst->env_inherit,
168 inst->timeout) < 0) {
215 RDEBUG(
"Program executed successfully");
221 REDEBUG(
"Program returned invalid code (greater than max rcode) (%i > 9): %pV",
229 if (box)
RDEBUG(
"Program failed with output: %pV", box);
244 fr_value_box_list_t *
args = talloc_get_type_abort(mctx->
rctx, fr_value_box_list_t);
250 if (
inst->input_list) {
258 RPEDEBUG(
"Failed executing program");
296 if (
inst->output_list && !fr_value_box_list_empty(&m->
box)) {
315 .allow_unresolved =
false
330 RPEDEBUG(
"Failed parsing exec output string");
338 #ifdef STATIC_ANALYZER
342 RDEBUG(
"applying %s %s %s",
346 RPEDEBUG(
"Failed applying assignment");
371 REDEBUG(
"Program exited with signal %d", -status);
394 RDEBUG(
"This module requires 'program' to be set.");
407 fr_value_box_list_t *box = talloc_zero(ctx, fr_value_box_list_t);
409 fr_value_box_list_init(box);
423 if (
inst->input_list) {
428 if (
inst->output_list) {
437 fr_value_box_list_init(&m->
box);
464 if (!
inst->wait && (
inst->output_list != NULL)) {
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
#define L(_str)
Helper for initialising arrays of string literals.
#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_FORCE_QUOTE
Force quote method when parsing tmpl.
#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.
#define CONF_PARSER_TERMINATOR
#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_OFFSET_IS_SET(_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.
A section grouping multiple CONF_PAIR.
#define cf_log_err(_cf, _fmt,...)
#define cf_log_perr(_cf, _fmt,...)
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
static fr_time_delta_t timeout
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
int fr_exec_oneshot(TALLOC_CTX *ctx, fr_exec_state_t *exec, request_t *request, fr_value_box_list_t *args, fr_pair_list_t *env_pairs, bool env_escape, bool env_inherit, bool need_stdin, bool store_stdout, TALLOC_CTX *stdout_ctx, fr_time_delta_t timeout)
Call an child program, optionally reading it's output.
int fr_exec_oneshot_nowait(request_t *request, fr_value_box_list_t *args, fr_pair_list_t *env_pairs, bool env_escape, bool env_inherit)
Similar to fr_exec_oneshot, but does not attempt to parse output.
#define EXEC_TIMEOUT
Default wait time for exec calls (in seconds).
fr_sbuff_t stdout_buff
Expandable buffer to store process output.
int status
return code of the program
fr_exec_fail_t failed
what kind of failure
static xlat_action_t exec_xlat_oneshot(TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Exec programs from an xlat.
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.
#define RPEDEBUG(fmt,...)
fr_table_num_sorted_t const map_assignment_op_table[]
ssize_t map_afrom_substr(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, fr_sbuff_t *in, fr_table_num_sorted_t const *op_table, size_t op_table_len, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, fr_sbuff_parse_rules_t const *p_rules)
Parse sbuff into (which may contain refs) to map_t.
size_t map_assignment_op_table_len
main_config_t const * main_config
Main server configuration.
fr_time_delta_t max_request_time
How long a request can be processed for before timing out.
@ TMPL_ATTR_REF_PREFIX_AUTO
Attribute refs may have a '&' prefix.
@ TMPL_ATTR_REF_PREFIX_YES
Attribute refs must have '&' prefix.
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
@ FR_TYPE_STRING
String of printable characters.
void * env_data
Per call environment data.
module_instance_t const * mi
Instance of the module being instantiated.
void * rctx
Resume ctx that a module previously set.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for instantiation calls.
xlat_t * module_rlm_xlat_register(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
module_t common
Common fields presented by all modules.
int radius_legacy_map_apply(request_t *request, map_t const *map, fr_edit_list_t *el)
Move a map using the operators from the old pairmove functionality.
static const conf_parser_t config[]
#define RETURN_MODULE_RCODE(_rcode)
#define RETURN_MODULE_INVALID
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_INVALID
The module considers the request invalid.
@ RLM_MODULE_OK
The module is OK, continue.
@ RLM_MODULE_FAIL
Module failed, don't reply.
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
@ RLM_MODULE_REJECT
Immediately reject the request.
@ RLM_MODULE_NOTFOUND
User not found.
@ RLM_MODULE_UPDATED
OK (pairs modified).
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
fr_dict_attr_t const * request_attr_request
static xlat_action_t exec_xlat_oneshot_wait_resume(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, UNUSED fr_value_box_list_t *in)
static unlang_action_t mod_exec_oneshot_nowait_resume(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Resume a request after xlat expansion.
static rlm_rcode_t rlm_exec_status2rcode(request_t *request, fr_value_box_t *box, int status)
Process the exit code returned by one of the exec functions.
static const rlm_rcode_t status2rcode[]
static int mod_bootstrap(module_inst_ctx_t const *mctx)
static unlang_action_t mod_exec_dispatch_oneshot(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Dispatch one request using a short lived process.
static const call_env_method_t exec_method_env
static unlang_action_t mod_exec_oneshot_wait_resume(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Process the exit code and output of a short lived process.
static xlat_arg_parser_t const exec_xlat_args[]
static int mob_instantiate(module_inst_ctx_t const *mctx)
static const conf_parser_t module_config[]
static fr_sbuff_parse_rules_t const rhs_term
static int instantiate(module_inst_ctx_t const *mctx)
int fr_sbuff_trim_talloc(fr_sbuff_t *sbuff, size_t len)
Trim a talloced sbuff to the minimum length required to represent the contained string.
bool const sbuff_char_line_endings[UINT8_MAX+1]
size_t fr_sbuff_trim(fr_sbuff_t *sbuff, bool const to_trim[static UINT8_MAX+1])
Trim trailing characters from a string we're composing.
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_IN(_start, _len_or_end)
#define fr_sbuff_adv_past_whitespace(_sbuff, _len, _tt)
#define fr_sbuff_current(_sbuff_or_marker)
#define FR_SBUFF_TERMS(...)
Initialise a terminal structure with a list of sorted strings.
#define fr_sbuff_buff(_sbuff_or_marker)
#define fr_sbuff_remaining(_sbuff_or_marker)
Set of parsing rules for *unescape_until functions.
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
CONF_SECTION * conf
Module's instance configuration.
void * data
Module's instance data.
void * boot
Data allocated during the boostrap phase.
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Named methods exported by a module.
fr_pair_list_t * tmpl_list_head(request_t *request, fr_dict_attr_t const *list)
Resolve attribute fr_pair_list_t value to an attribute list.
tmpl_xlat_rules_t xlat
Rules/data for parsing xlats.
bool at_runtime
Produce an ephemeral/runtime tmpl.
static bool tmpl_is_list(tmpl_t const *vpt)
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
@ TMPL_ATTR_LIST_ALLOW
Attribute refs are allowed to have a list.
struct tmpl_rules_s tmpl_rules_t
static fr_dict_attr_t const * tmpl_list(tmpl_t const *vpt)
fr_event_list_t * runtime_el
The eventlist to use for runtime instantiation of xlats.
Optional arguments passed to vp_tmpl functions.
unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out, request_t *request, xlat_exp_head_t const *exp, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
Push a pre-compiled xlat and resumption state onto the stack for evaluation.
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
fr_token_t op
The operator that controls insertion of the dst attribute.
tmpl_t * lhs
Typically describes the attribute to add, modify or compare.
tmpl_t * rhs
Typically describes a literal value or a src attribute to copy or compare.
fr_dict_attr_t const * list_def
Default list to use with unqualified attribute reference.
fr_dict_t const * dict_def
Default dictionary to use with unqualified attribute references.
tmpl_attr_prefix_t prefix
Whether the attribute reference requires a prefix.
#define talloc_get_type_abort_const
#define fr_time_delta_lt(_a, _b)
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
#define fr_time_delta_ispos(_a)
#define fr_time_delta_gt(_a, _b)
A time delta, a difference in time measured in nanoseconds.
char const * fr_tokens[T_TOKEN_LAST]
#define TMPL_ARGS_EXEC(_env, _timeout, _stdout_on_error, _status_out)
Create a temporary argument structure for evaluating an exec type tmpl.
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.
bool required
Argument must be present, and non-empty.
@ XLAT_ARG_VARIADIC_EMPTY_KEEP
Empty argument groups are left alone, and either passed through as empty groups or null boxes.
#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.
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_box_time_delta(_val)
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
static size_t char ** out
void * rctx
Resume context.
module_ctx_t const * mctx
Synthesised module calling ctx.
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.