26 RCSID(
"$Id: fe96e217544536ddee8dae8895e2475d132c559d $")
28 #include <freeradius-devel/unlang/tmpl.h>
29 #include <freeradius-devel/server/exec.h>
30 #include <freeradius-devel/util/syserror.h>
31 #include <freeradius-devel/util/value.h>
35 #if defined(__linux__) || defined(__FreeBSD__)
60 if (!state->
signal)
return;
68 if (action == FR_SIGNAL_CANCEL) state->
signal = NULL;
83 RPEDEBUG(
"Failed casting expansion");
88 if (state->
out) fr_value_box_list_move(state->
out, &state->
list);
110 if (state->exec.failed) {
111 fr_value_box_list_talloc_free(&state->
list);
117 if (!state->
args.
exec.stdout_on_error && (state->exec.status != 0)) {
141 fr_value_box_list_init(&state->
list);
151 fr_value_box_list_insert_head(&state->
list, box);
158 if (state->
args.
exec.status_out) *state->
args.
exec.status_out = state->exec.status;
180 (state->
out != NULL), state,
182 RPEDEBUG(
"Failed executing program");
187 fr_value_box_list_talloc_free(&state->
list);
206 fr_value_box_list_init(&state->
list);
217 RPEDEBUG(
"Failed evaluating expansion");
268 static unlang_t tmpl_instruction = {
271 .debug_name =
"tmpl",
297 .
self = tmpl_instruction,
322 fr_value_box_list_init(&state->
list);
335 .frame_state_type =
"unlang_frame_state_tmpl_t",
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_PUSHED_CHILD
unlang_t pushed a new child onto the stack, execute it instead of continuing.
@ UNLANG_ACTION_STOP_PROCESSING
Break out of processing the current request (unwind).
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
@ UNLANG_ACTION_YIELD
Temporarily pause execution until an event occurs.
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.
void fr_exec_oneshot_cleanup(fr_exec_state_t *exec, int signal)
Cleans up an exec'd process on error.
#define EXEC_TIMEOUT
Default wait time for exec calls (in seconds).
int unlang_interpret_push(request_t *request, unlang_t const *instruction, rlm_rcode_t default_rcode, bool do_next_sibling, bool top_frame)
Push a new frame onto the stack.
#define RPEDEBUG(fmt,...)
void unlang_register(int type, unlang_op_t *op)
Register an operation with the interpreter.
static char * stack[MAX_STACK]
@ FR_TYPE_STRING
String of printable characters.
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_NOT_SET
Error resolving rcode (should not be returned by modules).
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
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.
#define fr_sbuff_start(_sbuff_or_marker)
#define fr_sbuff_used(_sbuff_or_marker)
#define tmpl_contains_xlat(vpt)
#define tmpl_is_xlat(vpt)
#define tmpl_contains_regex(vpt)
#define tmpl_is_exec(vpt)
bool tmpl_async_required(tmpl_t const *vpt)
Return whether or not async is required for this tmpl.
int tmpl_eval_cast_in_place(fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt)
Casts a value or list of values according to the tmpl.
int tmpl_eval(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt)
Gets the value of a tmpl.
#define tmpl_needs_resolving(vpt)
Signals that can be sent to a request.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
fr_aka_sim_id_type_t type
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
#define fr_time_delta_ispos(_a)
static unlang_action_t unlang_tmpl_exec_wait_final(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
Wrapper to call exec after the program has finished executing.
void unlang_tmpl_init(void)
static void unlang_tmpl_signal(request_t *request, unlang_stack_frame_t *frame, fr_signal_t action)
Send a signal (usually stop) to a request.
static unlang_action_t unlang_tmpl_resume(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
Wrapper to call a resumption function after a tmpl has been expanded.
int unlang_tmpl_push(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *tmpl, unlang_tmpl_args_t *args)
Push a tmpl onto the stack for evaluation.
static unlang_action_t unlang_tmpl(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
static unlang_action_t unlang_tmpl_exec_wait_resume(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
Wrapper to call exec after a tmpl has been expanded.
Declarations for the unlang tmpl interface.
fr_value_box_list_t * out
output list if the exec succeeds
unlang_tmpl_args_t args
Arguments that control how the tmpl is evaluated.
TALLOC_CTX * ctx
for allocating value boxes
fr_unlang_tmpl_resume_t resume
resumption handler
fr_value_box_list_t list
our intermediate working list
fr_unlang_tmpl_signal_t signal
signal handler
struct unlang_tmpl_args_t::@99 exec
Exec specific arguments.
Arguments for evaluating different types of tmpls.
int unlang_xlat_push(TALLOC_CTX *ctx, bool *p_success, 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 * state
Stack frame specialisations.
@ UNLANG_TYPE_TMPL
asynchronously expand a tmpl_t
static void frame_repeat(unlang_stack_frame_t *frame, unlang_process_t process)
Mark the current stack frame up for repeat, and set a new process function.
unlang_t const * instruction
The unlang node we're evaluating.
static unlang_t * unlang_tmpl_to_generic(unlang_tmpl_t const *p)
unlang_process_t process
function to call for interpreting this stack frame
unlang_type_t type
The specialisation of this node.
static unlang_tmpl_t * unlang_generic_to_tmpl(unlang_t const *p)
A node in a graph of unlang_op_t (s) that we execute.
Our interpreter stack, as distinct from the C stack.
An unlang stack associated with a request.
ssize_t fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, char const *in, size_t inlen, fr_sbuff_unescape_rules_t const *erules, bool tainted)
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
#define fr_box_strvalue_len(_val, _len)
static size_t char ** out