The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_exec.c
Go to the documentation of this file.
1/*
2 * This program is is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 806865d99143c02fc88c74bfa4bf1c55703d4a77 $
19 * @file rlm_exec.c
20 * @brief Execute commands and parse the results.
21 *
22 * @copyright 2002,2006 The FreeRADIUS server project
23 * @copyright 2002 Alan DeKok (aland@freeradius.org)
24 */
25RCSID("$Id: 806865d99143c02fc88c74bfa4bf1c55703d4a77 $")
26
27#define LOG_PREFIX mctx->mi->name
28
29#include <stdint.h>
30
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/server/pairmove.h>
37#include <freeradius-devel/unlang/xlat_func.h>
38
39/*
40 * Define a structure for our module configuration.
41 */
52
53static const conf_parser_t module_config[] = {
54 { FR_CONF_OFFSET("wait", rlm_exec_t, wait), .dflt = "yes" },
55 { FR_CONF_OFFSET_FLAGS("input_pairs", CONF_FLAG_ATTRIBUTE, rlm_exec_t, input_list) },
56 { FR_CONF_OFFSET_FLAGS("output_pairs", CONF_FLAG_ATTRIBUTE, rlm_exec_t, output_list) },
57 { FR_CONF_OFFSET("shell_escape", rlm_exec_t, shell_escape), .dflt = "yes" },
58 { FR_CONF_OFFSET("env_inherit", rlm_exec_t, env_inherit), .dflt = "no" },
59 { FR_CONF_OFFSET_IS_SET("timeout", FR_TYPE_TIME_DELTA, 0, rlm_exec_t, timeout) },
60 { FR_CONF_OFFSET("xlat_read_binary", rlm_exec_t, xlat_read_binary) },
62};
63
64typedef struct {
67
75
77 xlat_ctx_t const *xctx,
78 request_t *request, UNUSED fr_value_box_list_t *in)
79{
81 fr_exec_state_t *exec = talloc_get_type_abort(xctx->rctx, fr_exec_state_t);
83
84 if (exec->failed != FR_EXEC_FAIL_NONE) {
85 RPEDEBUG("Execution of external program failed");
86 return XLAT_ACTION_FAIL;
87 }
88
89 /*
90 * Allow a return code of 3 as success to match the behaviour of
91 * inline module calls.
92 */
93 if ((exec->status != 0) && (exec->status != 3)) {
94 RPEDEBUG("Execution of external program returned %d", exec->status);
95 return XLAT_ACTION_FAIL;
96 }
97
99
100 if (!inst->xlat_read_binary) {
101 /*
102 * Remove any trailing line endings and trim buffer
103 */
105 fr_sbuff_trim_talloc(&exec->stdout_buff, SIZE_MAX);
106 }
107
108 /*
109 * Use the buffer for the output vb
110 */
112
114
115 return XLAT_ACTION_DONE;
116}
117
119 { .required = true, .type = FR_TYPE_STRING },
120 { .variadic = XLAT_ARG_VARIADIC_EMPTY_KEEP, .type = FR_TYPE_VOID},
122};
123
125{
126 fr_exec_oneshot_cleanup(exec, SIGKILL);
127 return 0;
128}
129
130/** Exec programs from an xlat
131 *
132 * Example:
133@verbatim
134%exec('/bin/echo', 'hello') == "hello"
135@endverbatim
136 *
137 * Exactly one request is consumed during the process lifetime,
138 * after which the process exits.
139 *
140 * @ingroup xlat_functions
141 */
143 xlat_ctx_t const *xctx,
144 request_t *request, fr_value_box_list_t *in)
145{
147 fr_pair_list_t *env_pairs = NULL;
148 fr_exec_state_t *exec;
149
150 if (inst->input_list) {
151 env_pairs = tmpl_list_head(request, tmpl_list(inst->input_list));
152 if (!env_pairs) {
153 REDEBUG("Failed to find input pairs for xlat");
154 return XLAT_ACTION_FAIL;
155 }
156 }
157
158 if (!inst->wait) {
159 if (unlikely(fr_exec_oneshot_nowait(request, in, env_pairs, inst->shell_escape, inst->env_inherit) < 0)) {
160 RPEDEBUG("Failed executing program");
161 return XLAT_ACTION_FAIL;
162 }
163
164 return XLAT_ACTION_DONE;
165 }
166
167 MEM(exec = talloc_zero(unlang_interpret_frame_talloc_ctx(request), fr_exec_state_t));
168 if (fr_exec_oneshot(exec, exec, request,
169 in,
170 env_pairs, inst->shell_escape, inst->env_inherit,
171 false,
172 inst->wait, ctx,
173 inst->timeout) < 0) {
174 talloc_free(exec);
175 return XLAT_ACTION_FAIL;
176 }
177 talloc_set_destructor(exec, _exec_free);
178
179 return unlang_xlat_yield(request, exec_xlat_oneshot_wait_resume, NULL, 0, exec);
180}
181
182typedef struct {
183 fr_value_box_list_t box;
186
187static const rlm_rcode_t status2rcode[] = {
188 [0] = RLM_MODULE_OK,
189 [1] = RLM_MODULE_REJECT,
190 [2] = RLM_MODULE_FAIL,
191 [3] = RLM_MODULE_OK,
192 [4] = RLM_MODULE_HANDLED,
193 [5] = RLM_MODULE_INVALID,
196 [8] = RLM_MODULE_NOOP,
197 [9] = RLM_MODULE_UPDATED,
198};
199
200
201/** Process the exit code returned by one of the exec functions
202 *
203 * @param request Current request.
204 * @param box Output string from exec call.
205 * @param status code returned by exec call.
206 * @return One of the RLM_MODULE_* values.
207 */
209{
210 rlm_rcode_t rcode;
211
212 if (status < 0) return RLM_MODULE_FAIL;
213
214 /*
215 * Exec'd programs are meant to return exit statuses that correspond
216 * to the standard RLM_MODULE_* + 1.
217 *
218 * This frees up 0, for success where it'd normally be reject.
219 */
220 if (status == 0) {
221 RDEBUG("Program executed successfully");
222
223 return RLM_MODULE_OK;
224 }
225
226 if (status > 9) {
227 REDEBUG("Program returned invalid code (greater than max rcode) (%i > 9): %pV",
228 status, box);
229 return RLM_MODULE_FAIL;
230 }
231
232 rcode = status2rcode[status];
233
234 if (rcode == RLM_MODULE_FAIL) {
235 if (box) RDEBUG("Program failed with output: %pV", box);
236
237 return RLM_MODULE_FAIL;
238 }
239
240 return rcode;
241}
242
243/** Resume a request after xlat expansion.
244 *
245 */
247 request_t *request)
248{
250 fr_value_box_list_t *args = talloc_get_type_abort(mctx->rctx, fr_value_box_list_t);
251 fr_pair_list_t *env_pairs = NULL;
252
253 /*
254 * Decide what input/output the program takes.
255 */
256 if (inst->input_list) {
257 env_pairs = tmpl_list_head(request, tmpl_list(inst->input_list));
258 if (!env_pairs) {
260 }
261 }
262
263 if (unlikely(fr_exec_oneshot_nowait(request, args, env_pairs, inst->shell_escape, inst->env_inherit) < 0)) {
264 RPEDEBUG("Failed executing program");
266 }
267
269}
270
271static fr_sbuff_parse_rules_t const rhs_term = {
272 .escapes = &(fr_sbuff_unescape_rules_t){
273 .chr = '\\',
274 .do_hex = true,
275 .do_oct = false
276 },
277 .terminals = &FR_SBUFF_TERMS(
278 L(""),
279 L("\t"),
280 L("\n"),
281 L(","),
282 )
283};
284
285/** Process the exit code and output of a short lived process
286 *
287 */
289{
290 int status;
292 rlm_exec_ctx_t *m = talloc_get_type_abort(mctx->rctx, rlm_exec_ctx_t);
293 rlm_rcode_t rcode;
294
295 /*
296 * Also prints stdout as an error if there was any...
297 */
298 rcode = rlm_exec_status2rcode(request, fr_value_box_list_head(&m->box), m->status);
299 switch (rcode) {
300 case RLM_MODULE_OK:
302 if (inst->output_list && !fr_value_box_list_empty(&m->box)) {
303 ssize_t slen;
304 map_t *map;
305 fr_value_box_t *box = fr_value_box_list_head(&m->box);
306 fr_sbuff_t in = FR_SBUFF_IN(box->vb_strvalue, box->vb_length);
307 tmpl_rules_t lhs_rules = (tmpl_rules_t) {
308 .attr = {
309 .dict_def = request->local_dict,
310 .list_def = tmpl_list(inst->output_list),
311 .list_presence = TMPL_ATTR_LIST_ALLOW,
312
313 /*
314 * Otherwise the tmpl code returns 0 when asked
315 * to parse unknown names. So we say "please
316 * parse unknown names as unresolved attributes",
317 * and then do a second pass to complain that the
318 * thing isn't known.
319 */
320 .allow_unresolved = false
321 }
322 };
323 tmpl_rules_t rhs_rules = lhs_rules;
324
326 rhs_rules.at_runtime = true;
327 rhs_rules.xlat.runtime_el = unlang_interpret_event_list(request);
328
329 while (true) {
330 slen = map_afrom_substr(request, &map, NULL, &in,
332 &lhs_rules, &rhs_rules, &rhs_term);
333 if (slen < 0) {
334 RPEDEBUG("Failed parsing exec output string");
335 break;
336 }
337 if (!slen) {
338 RDEBUG("Stopping due to no input at %.*s", (int) fr_sbuff_remaining(&in), fr_sbuff_current(&in));
339 break;
340 }
341
342#ifdef STATIC_ANALYZER
343 if (!map) return -1;
344#endif
345
346 RDEBUG("applying %s %s %s",
347 map->lhs->name, fr_tokens[map->op], map->rhs->name);
348
349 if (radius_legacy_map_apply(request, map, NULL) < 0) {
350 RPEDEBUG("Failed applying assignment");
351
352 TALLOC_FREE(map);
353 return -1;
354 }
355 TALLOC_FREE(map);
356
357 fr_sbuff_adv_past_whitespace(&in, SIZE_MAX, NULL);
358
359 if (!fr_sbuff_remaining(&in)) break;
360
361 /*
362 * Allow commas between attributes
363 */
364 (void) fr_sbuff_next_if_char(&in, ',');
365 }
366 }
367 break;
368
369 default:
370 break;
371 }
372
373 status = m->status;
374 if (status < 0) {
375 REDEBUG("Program exited with signal %d", -status);
377 }
378
379 /*
380 * The status rcodes aren't quite the same as the rcode
381 * enumeration.
382 */
383 RETURN_UNLANG_RCODE(rcode);
384}
385
386/** Dispatch one request using a short lived process
387 *
388 */
390{
392 fr_pair_list_t *env_pairs = NULL;
393 TALLOC_CTX *ctx;
395 exec_call_env_t *env_data = talloc_get_type_abort(mctx->env_data, exec_call_env_t);
396
397 if (!env_data->program) {
398 RDEBUG("This module requires 'program' to be set.");
400 }
401
402 /*
403 * Get frame-local talloc ctx
404 */
406
407 /*
408 * Do the asynchronous xlat expansion.
409 */
410 if (!inst->wait) {
411 fr_value_box_list_t *box = talloc_zero(ctx, fr_value_box_list_t);
412
413 fr_value_box_list_init(box);
414
415 /*
416 * The xlat here only expands the arguments, then calls
417 * the resume function we set to actually dispatch the
418 * exec request.
419 */
420 return unlang_module_yield_to_xlat(request, NULL, box, request, tmpl_xlat(env_data->program),
421 mod_exec_oneshot_nowait_resume, NULL, 0, box);
422 }
423
424 /*
425 * Decide what input/output the program takes.
426 */
427 if (inst->input_list) {
428 env_pairs = tmpl_list_head(request, tmpl_list(inst->input_list));
429 if (!env_pairs) RETURN_UNLANG_INVALID;
430 }
431
432 if (inst->output_list) {
433 if (!tmpl_list_head(request, tmpl_list(inst->output_list))) {
435 }
436 }
437
438 MEM(m = talloc_zero(ctx, rlm_exec_ctx_t));
439 m->status = 2; /* Fail if we couldn't exec */
440
441 fr_value_box_list_init(&m->box);
442 return unlang_module_yield_to_tmpl(m, &m->box,
443 request, env_data->program,
444 TMPL_ARGS_EXEC(env_pairs, inst->timeout, true, &m->status),
446 NULL, 0, &m->box);
447}
448
449static int mob_instantiate(module_inst_ctx_t const *mctx)
450{
451 rlm_exec_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_exec_t);
452 CONF_SECTION *conf = mctx->mi->conf;
453
454 if (inst->input_list && !tmpl_is_list(inst->input_list)) {
455 cf_log_perr(conf, "Invalid input list '%s'", inst->input_list->name);
456 return -1;
457 }
458
459 if (inst->output_list && !tmpl_is_list(inst->output_list)) {
460 cf_log_err(conf, "Invalid output list '%s'", inst->output_list->name);
461 return -1;
462 }
463
464 /*
465 * Sanity check the config. If we're told to NOT wait,
466 * then the output pairs must not be defined.
467 */
468 if (!inst->wait && (inst->output_list != NULL)) {
469 cf_log_err(conf, "Cannot read output pairs if wait = no");
470 return -1;
471 }
472
473 if (!inst->timeout_is_set || !fr_time_delta_ispos(inst->timeout)) {
474 /*
475 * Pick the shorter one
476 */
480 }
481 else {
482 if (fr_time_delta_lt(inst->timeout, fr_time_delta_from_sec(1))) {
483 cf_log_err(conf, "Timeout '%pVs' is too small (minimum: 1s)", fr_box_time_delta(inst->timeout));
484 return -1;
485 }
486
487 /*
488 * Blocking a request longer than max_request_time isn't going to help anyone.
489 */
491 cf_log_err(conf, "Timeout '%pVs' is too large (maximum: %pVs)",
493 return -1;
494 }
495 }
496
497 return 0;
498}
499/*
500 * Do any per-module initialization that is separate to each
501 * configured instance of the module. e.g. set up connections
502 * to external databases, read configuration files, set up
503 * dictionary entries, etc.
504 *
505 * If configuration information is given in the config section
506 * that must be referenced in later calls, store a handle to it
507 * in *instance otherwise put a null pointer there.
508 */
509static int mod_bootstrap(module_inst_ctx_t const *mctx)
510{
511 xlat_t *xlat;
512
515
516 return 0;
517}
518
519/*
520 * The module name should be the only globally exported symbol.
521 * That is, everything else should be 'static'.
522 *
523 * If the module needs to temporarily modify it's instantiation
524 * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
525 * The server will then take care of ensuring that the module
526 * is single-threaded.
527 */
530 .common = {
531 .magic = MODULE_MAGIC_INIT,
532 .name = "exec",
533 .inst_size = sizeof(rlm_exec_t),
535 .bootstrap = mod_bootstrap,
536 .instantiate = mob_instantiate
537 },
538 .method_group = {
539 .bindings = (module_method_binding_t[]){
540 { .section = SECTION_NAME(CF_IDENT_ANY, CF_IDENT_ANY), .method = mod_exec_dispatch_oneshot, .method_env = &exec_method_env },
542 }
543 }
544};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
va_list args
Definition acutest.h:770
#define RCSID(id)
Definition build.h:506
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:228
#define unlikely(_x)
Definition build.h:402
#define UNUSED
Definition build.h:336
#define CALL_ENV_TERMINATOR
Definition call_env.h:236
#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...
Definition call_env.h:240
call_env_parser_t const * env
Parsing rules for call method env.
Definition call_env.h:247
@ CALL_ENV_FLAG_FORCE_QUOTE
Force quote method when parsing tmpl.
Definition call_env.h:81
#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.
Definition call_env.h:389
Per method call config.
Definition call_env.h:180
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:657
#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
Definition cf_parse.h:280
#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,...
Definition cf_parse.h:294
#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
Definition cf_parse.h:268
@ CONF_FLAG_ATTRIBUTE
Value must resolve to attribute in dict (deprecated, use CONF_FLAG_TMPL).
Definition cf_parse.h:431
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:594
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:285
#define cf_log_perr(_cf, _fmt,...)
Definition cf_util.h:292
#define CF_IDENT_ANY
Definition cf_util.h:75
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
Definition dcursor.h:406
#define MEM(x)
Definition debug.h:46
static fr_slen_t in
Definition dict.h:882
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
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.
Definition exec.c:998
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.
Definition exec.c:636
void fr_exec_oneshot_cleanup(fr_exec_state_t *exec, int signal)
Cleans up an exec'd process on error.
Definition exec.c:679
#define EXEC_TIMEOUT
Default wait time for exec calls (in seconds).
Definition exec.h:32
@ FR_EXEC_FAIL_NONE
Definition exec.h:49
fr_sbuff_t stdout_buff
Expandable buffer to store process output.
Definition exec.h:55
int status
return code of the program
Definition exec.h:77
fr_exec_fail_t failed
what kind of failure
Definition exec.h:75
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.
Definition rlm_exec.c:142
talloc_free(hp)
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
Definition interpret.c:1681
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
Definition interpret.c:2053
#define RPEDEBUG(fmt,...)
Definition log.h:388
fr_table_num_sorted_t const map_assignment_op_table[]
Definition map.c:368
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.
Definition map.c:466
size_t map_assignment_op_table_len
Definition map.c:384
main_config_t const * main_config
Main server configuration.
Definition main_config.c:58
fr_worker_config_t worker
Worker thread configuration.
Definition main_config.h:61
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_VOID
User data.
long int ssize_t
void * env_data
Per call environment data.
Definition module_ctx.h:44
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
void * rctx
Resume ctx that a module previously set.
Definition module_ctx.h:45
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for module calls.
Definition module_ctx.h:41
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
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)
Definition module_rlm.c:247
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
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.
Definition pairmove.c:507
static const conf_parser_t config[]
Definition base.c:163
#define REDEBUG(fmt,...)
#define RDEBUG(fmt,...)
static char const * program
Definition radiusd.c:79
static rs_t * conf
Definition radsniff.c:52
#define RETURN_UNLANG_INVALID
Definition rcode.h:66
#define RETURN_UNLANG_RCODE(_rcode)
Definition rcode.h:61
#define RETURN_UNLANG_FAIL
Definition rcode.h:63
#define RETURN_UNLANG_OK
Definition rcode.h:64
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:44
@ RLM_MODULE_INVALID
The module considers the request invalid.
Definition rcode.h:51
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:49
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition rcode.h:48
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
Definition rcode.h:52
@ RLM_MODULE_REJECT
Immediately reject the request.
Definition rcode.h:47
@ RLM_MODULE_NOTFOUND
User not found.
Definition rcode.h:53
@ RLM_MODULE_UPDATED
OK (pairs modified).
Definition rcode.h:55
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition rcode.h:54
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
Definition rcode.h:50
fr_dict_attr_t const * request_attr_request
Definition request.c:43
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)
Definition rlm_exec.c:76
fr_time_delta_t timeout
Definition rlm_exec.c:48
bool shell_escape
Definition rlm_exec.c:46
bool xlat_read_binary
Definition rlm_exec.c:50
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.
Definition rlm_exec.c:208
static int _exec_free(fr_exec_state_t *exec)
Definition rlm_exec.c:124
static unlang_action_t mod_exec_oneshot_nowait_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Resume a request after xlat expansion.
Definition rlm_exec.c:246
static unlang_action_t mod_exec_dispatch_oneshot(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Dispatch one request using a short lived process.
Definition rlm_exec.c:389
module_rlm_t rlm_exec
Definition rlm_exec.c:529
static const rlm_rcode_t status2rcode[]
Definition rlm_exec.c:187
tmpl_t * input_list
Definition rlm_exec.c:44
static int mod_bootstrap(module_inst_ctx_t const *mctx)
Definition rlm_exec.c:509
bool timeout_is_set
Definition rlm_exec.c:49
tmpl_t * output_list
Definition rlm_exec.c:45
fr_value_box_list_t box
Definition rlm_exec.c:183
static const call_env_method_t exec_method_env
Definition rlm_exec.c:68
static xlat_arg_parser_t const exec_xlat_args[]
Definition rlm_exec.c:118
static unlang_action_t mod_exec_oneshot_wait_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Process the exit code and output of a short lived process.
Definition rlm_exec.c:288
bool wait
Definition rlm_exec.c:43
static int mob_instantiate(module_inst_ctx_t const *mctx)
Definition rlm_exec.c:449
static const conf_parser_t module_config[]
Definition rlm_exec.c:53
bool env_inherit
Definition rlm_exec.c:47
static fr_sbuff_parse_rules_t const rhs_term
Definition rlm_exec.c:271
tmpl_t * program
Definition rlm_exec.c:65
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.
Definition sbuff.c:432
size_t fr_sbuff_trim(fr_sbuff_t *sbuff, bool const to_trim[static SBUFF_CHAR_CLASS])
Trim trailing characters from a string we're composing.
Definition sbuff.c:2168
bool const sbuff_char_line_endings[SBUFF_CHAR_CLASS]
Definition sbuff.c:107
bool fr_sbuff_next_if_char(fr_sbuff_t *sbuff, char c)
Return true if the current char matches, and if it does, advance.
Definition sbuff.c:2128
#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.
Definition sbuff.h:190
#define fr_sbuff_buff(_sbuff_or_marker)
#define fr_sbuff_remaining(_sbuff_or_marker)
#define fr_sbuff_used(_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.
Definition section.h:39
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:351
size_t inst_size
Size of the module's instance data.
Definition module.h:212
void * data
Module's instance data.
Definition module.h:293
void * boot
Data allocated during the boostrap phase.
Definition module.h:296
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:152
Named methods exported by a module.
Definition module.h:174
#define tmpl_xlat(_tmpl)
Definition tmpl.h:930
static fr_dict_attr_t const * tmpl_list(tmpl_t const *vpt)
Definition tmpl.h:904
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.
Definition tmpl_eval.c:70
tmpl_xlat_rules_t xlat
Rules/data for parsing xlats.
Definition tmpl.h:340
bool at_runtime
Produce an ephemeral/runtime tmpl.
Definition tmpl.h:348
static bool tmpl_is_list(tmpl_t const *vpt)
Definition tmpl.h:920
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
Definition tmpl.h:339
@ TMPL_ATTR_LIST_ALLOW
Attribute refs are allowed to have a list.
Definition tmpl.h:262
struct tmpl_rules_s tmpl_rules_t
Definition tmpl.h:233
fr_event_list_t * runtime_el
The eventlist to use for runtime instantiation of xlats.
Definition tmpl.h:328
Optional arguments passed to vp_tmpl functions.
Definition tmpl.h:336
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.
Definition module.c:216
unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, unlang_result_t *p_result, 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.
Definition module.c:167
eap_aka_sim_process_conf_t * inst
Value pair map.
Definition map.h:77
fr_token_t op
The operator that controls insertion of the dst attribute.
Definition map.h:82
tmpl_t * lhs
Typically describes the attribute to add, modify or compare.
Definition map.h:78
tmpl_t * rhs
Typically describes a literal value or a src attribute to copy or compare.
Definition map.h:79
fr_dict_attr_t const * list_def
Default list to use with unqualified attribute reference.
Definition tmpl.h:295
fr_dict_t const * dict_def
Default dictionary to use with unqualified attribute references.
Definition tmpl.h:273
#define talloc_get_type_abort_const
Definition talloc.h:110
#define fr_time_delta_lt(_a, _b)
Definition time.h:285
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
Definition time.h:590
#define fr_time_delta_ispos(_a)
Definition time.h:290
#define fr_time_delta_gt(_a, _b)
Definition time.h:283
A time delta, a difference in time measured in nanoseconds.
Definition time.h:80
char const * fr_tokens[T_TOKEN_LAST]
Definition token.c:80
@ T_BACK_QUOTED_STRING
Definition token.h:121
#define TMPL_ARGS_EXEC(_env, _timeout, _stdout_on_error, _status_out)
Create a temporary argument structure for evaluating an exec type tmpl.
Definition tmpl.h:76
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.
Definition xlat.c:543
@ XLAT_ARG_VARIADIC_EMPTY_KEEP
Empty argument groups are left alone, and either passed through as empty groups or null boxes.
Definition xlat.h:137
unsigned int required
Argument must be present, and non-empty.
Definition xlat.h:146
#define XLAT_ARG_PARSER_TERMINATOR
Definition xlat.h:170
xlat_action_t
Definition xlat.h:37
@ XLAT_ACTION_FAIL
An xlat function failed.
Definition xlat.h:44
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition xlat.h:43
Definition for a single argument consumed by an xlat function.
Definition xlat.h:145
void fr_value_box_bstrndup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Assign a string to to a fr_value_box_t.
Definition value.c:4910
#define fr_box_time_delta(_val)
Definition value.h:366
int nonnull(2, 5))
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
Definition value.h:655
static size_t char ** out
Definition value.h:1030
fr_time_delta_t max_request_time
maximum time a request can be processed
Definition worker.h:76
void * rctx
Resume context.
Definition xlat_ctx.h:54
module_ctx_t const * mctx
Synthesised module calling ctx.
Definition xlat_ctx.h:52
An xlat calling ctx.
Definition xlat_ctx.h:49
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
Definition xlat_func.c:363