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: e5ee3bc1e812ef11c064c24eaee93f8e983e8514 $
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: e5ee3bc1e812ef11c064c24eaee93f8e983e8514 $")
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/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>
44
45/*
46 * Define a structure for our module configuration.
47 */
58
59static const conf_parser_t module_config[] = {
60 { FR_CONF_OFFSET("wait", rlm_exec_t, wait), .dflt = "yes" },
61 { FR_CONF_OFFSET_FLAGS("input_pairs", CONF_FLAG_ATTRIBUTE, rlm_exec_t, input_list) },
62 { FR_CONF_OFFSET_FLAGS("output_pairs", CONF_FLAG_ATTRIBUTE, rlm_exec_t, output_list) },
63 { FR_CONF_OFFSET("shell_escape", rlm_exec_t, shell_escape), .dflt = "yes" },
64 { FR_CONF_OFFSET("env_inherit", rlm_exec_t, env_inherit), .dflt = "no" },
65 { FR_CONF_OFFSET_IS_SET("timeout", FR_TYPE_TIME_DELTA, 0, rlm_exec_t, timeout) },
66 { FR_CONF_OFFSET("xlat_read_binary", rlm_exec_t, xlat_read_binary) },
68};
69
70typedef struct {
73
81
83 xlat_ctx_t const *xctx,
84 request_t *request, UNUSED fr_value_box_list_t *in)
85{
87 fr_exec_state_t *exec = talloc_get_type_abort(xctx->rctx, fr_exec_state_t);
89
90 if (exec->failed == FR_EXEC_FAIL_TIMEOUT) {
91 RPEDEBUG("Execution of external program failed");
92 return XLAT_ACTION_FAIL;
93 }
94
95 /*
96 * Allow a return code of 3 as success to match the behaviour of
97 * inline module calls.
98 */
99 if ((exec->status != 0) && (exec->status != 3)) {
100 RPEDEBUG("Execution of external program returned %d", exec->status);
101 return XLAT_ACTION_FAIL;
102 }
103
104 MEM(vb = fr_value_box_alloc_null(ctx));
105
106 if (!inst->xlat_read_binary) {
107 /*
108 * Remove any trailing line endings and trim buffer
109 */
111 fr_sbuff_trim_talloc(&exec->stdout_buff, SIZE_MAX);
112 }
113
114 /*
115 * Use the buffer for the output vb
116 */
118
120
121 return XLAT_ACTION_DONE;
122}
123
125 { .required = true, .type = FR_TYPE_STRING },
126 { .variadic = XLAT_ARG_VARIADIC_EMPTY_KEEP, .type = FR_TYPE_VOID},
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
178 return unlang_xlat_yield(request, exec_xlat_oneshot_wait_resume, NULL, 0, exec);
179}
180
181typedef struct {
182 fr_value_box_list_t box;
185
186static const rlm_rcode_t status2rcode[] = {
187 [0] = RLM_MODULE_OK,
188 [1] = RLM_MODULE_REJECT,
189 [2] = RLM_MODULE_FAIL,
190 [3] = RLM_MODULE_OK,
191 [4] = RLM_MODULE_HANDLED,
192 [5] = RLM_MODULE_INVALID,
195 [8] = RLM_MODULE_NOOP,
196 [9] = RLM_MODULE_UPDATED,
197};
198
199
200/** Process the exit code returned by one of the exec functions
201 *
202 * @param request Current request.
203 * @param box Output string from exec call.
204 * @param status code returned by exec call.
205 * @return One of the RLM_MODULE_* values.
206 */
208{
209 rlm_rcode_t rcode;
210
211 if (status < 0) return RLM_MODULE_FAIL;
212
213 /*
214 * Exec'd programs are meant to return exit statuses that correspond
215 * to the standard RLM_MODULE_* + 1.
216 *
217 * This frees up 0, for success where it'd normally be reject.
218 */
219 if (status == 0) {
220 RDEBUG("Program executed successfully");
221
222 return RLM_MODULE_OK;
223 }
224
225 if (status > 9) {
226 REDEBUG("Program returned invalid code (greater than max rcode) (%i > 9): %pV",
227 status, box);
228 return RLM_MODULE_FAIL;
229 }
230
231 rcode = status2rcode[status];
232
233 if (rcode == RLM_MODULE_FAIL) {
234 if (box) RDEBUG("Program failed with output: %pV", box);
235
236 return RLM_MODULE_FAIL;
237 }
238
239 return rcode;
240}
241
242/** Resume a request after xlat expansion.
243 *
244 */
246 request_t *request)
247{
249 fr_value_box_list_t *args = talloc_get_type_abort(mctx->rctx, fr_value_box_list_t);
250 fr_pair_list_t *env_pairs = NULL;
251
252 /*
253 * Decide what input/output the program takes.
254 */
255 if (inst->input_list) {
256 env_pairs = tmpl_list_head(request, tmpl_list(inst->input_list));
257 if (!env_pairs) {
259 }
260 }
261
262 if (unlikely(fr_exec_oneshot_nowait(request, args, env_pairs, inst->shell_escape, inst->env_inherit) < 0)) {
263 RPEDEBUG("Failed executing program");
265 }
266
268}
269
270static fr_sbuff_parse_rules_t const rhs_term = {
271 .escapes = &(fr_sbuff_unescape_rules_t){
272 .chr = '\\',
273 .do_hex = true,
274 .do_oct = false
275 },
276 .terminals = &FR_SBUFF_TERMS(
277 L(""),
278 L("\t"),
279 L("\n"),
280 L(","),
281 )
282};
283
284/** Process the exit code and output of a short lived process
285 *
286 */
288{
289 int status;
291 rlm_exec_ctx_t *m = talloc_get_type_abort(mctx->rctx, rlm_exec_ctx_t);
292 rlm_rcode_t rcode;
293
294 /*
295 * Also prints stdout as an error if there was any...
296 */
297 rcode = rlm_exec_status2rcode(request, fr_value_box_list_head(&m->box), m->status);
298 switch (rcode) {
299 case RLM_MODULE_OK:
301 if (inst->output_list && !fr_value_box_list_empty(&m->box)) {
302 ssize_t slen;
303 map_t *map;
304 fr_value_box_t *box = fr_value_box_list_head(&m->box);
305 fr_sbuff_t in = FR_SBUFF_IN(box->vb_strvalue, box->vb_length);
306 tmpl_rules_t lhs_rules = (tmpl_rules_t) {
307 .attr = {
308 .dict_def = request->local_dict,
309 .list_def = tmpl_list(inst->output_list),
310 .list_presence = TMPL_ATTR_LIST_ALLOW,
311
312 /*
313 * Otherwise the tmpl code returns 0 when asked
314 * to parse unknown names. So we say "please
315 * parse unknown names as unresolved attributes",
316 * and then do a second pass to complain that the
317 * thing isn't known.
318 */
319 .allow_unresolved = false
320 }
321 };
322 tmpl_rules_t rhs_rules = lhs_rules;
323
325 rhs_rules.at_runtime = true;
326 rhs_rules.xlat.runtime_el = unlang_interpret_event_list(request);
327
328 while (true) {
329 slen = map_afrom_substr(request, &map, NULL, &in,
331 &lhs_rules, &rhs_rules, &rhs_term);
332 if (slen < 0) {
333 RPEDEBUG("Failed parsing exec output string");
334 break;
335 }
336 if (!slen) {
337 RDEBUG("Stopping due to no input at %.*s", (int) fr_sbuff_remaining(&in), fr_sbuff_current(&in));
338 break;
339 }
340
341#ifdef STATIC_ANALYZER
342 if (!map) return -1;
343#endif
344
345 RDEBUG("applying %s %s %s",
346 map->lhs->name, fr_tokens[map->op], map->rhs->name);
347
348 if (radius_legacy_map_apply(request, map, NULL) < 0) {
349 RPEDEBUG("Failed applying assignment");
350
351 TALLOC_FREE(map);
352 return -1;
353 }
354 TALLOC_FREE(map);
355
356 fr_sbuff_adv_past_whitespace(&in, SIZE_MAX, NULL);
357
358 if (!fr_sbuff_remaining(&in)) break;
359
360 /*
361 * Allow commas between attributes
362 */
363 (void) fr_sbuff_next_if_char(&in, ',');
364 }
365 }
366 break;
367
368 default:
369 break;
370 }
371
372 status = m->status;
373 if (status < 0) {
374 REDEBUG("Program exited with signal %d", -status);
376 }
377
378 /*
379 * The status rcodes aren't quite the same as the rcode
380 * enumeration.
381 */
382 RETURN_UNLANG_RCODE(rcode);
383}
384
385/** Dispatch one request using a short lived process
386 *
387 */
389{
391 fr_pair_list_t *env_pairs = NULL;
392 TALLOC_CTX *ctx;
394 exec_call_env_t *env_data = talloc_get_type_abort(mctx->env_data, exec_call_env_t);
395
396 if (!env_data->program) {
397 RDEBUG("This module requires 'program' to be set.");
399 }
400
401 /*
402 * Get frame-local talloc ctx
403 */
405
406 /*
407 * Do the asynchronous xlat expansion.
408 */
409 if (!inst->wait) {
410 fr_value_box_list_t *box = talloc_zero(ctx, fr_value_box_list_t);
411
412 fr_value_box_list_init(box);
413
414 /*
415 * The xlat here only expands the arguments, then calls
416 * the resume function we set to actually dispatch the
417 * exec request.
418 */
419 return unlang_module_yield_to_xlat(request, NULL, box, request, tmpl_xlat(env_data->program),
420 mod_exec_oneshot_nowait_resume, NULL, 0, box);
421 }
422
423 /*
424 * Decide what input/output the program takes.
425 */
426 if (inst->input_list) {
427 env_pairs = tmpl_list_head(request, tmpl_list(inst->input_list));
428 if (!env_pairs) RETURN_UNLANG_INVALID;
429 }
430
431 if (inst->output_list) {
432 if (!tmpl_list_head(request, tmpl_list(inst->output_list))) {
434 }
435 }
436
437 MEM(m = talloc_zero(ctx, rlm_exec_ctx_t));
438 m->status = 2; /* Fail if we couldn't exec */
439
440 fr_value_box_list_init(&m->box);
441 return unlang_module_yield_to_tmpl(m, &m->box,
442 request, env_data->program,
443 TMPL_ARGS_EXEC(env_pairs, inst->timeout, true, &m->status),
445 NULL, 0, &m->box);
446}
447
448static int mob_instantiate(module_inst_ctx_t const *mctx)
449{
450 rlm_exec_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_exec_t);
451 CONF_SECTION *conf = mctx->mi->conf;
452
453 if (inst->input_list && !tmpl_is_list(inst->input_list)) {
454 cf_log_perr(conf, "Invalid input list '%s'", inst->input_list->name);
455 return -1;
456 }
457
458 if (inst->output_list && !tmpl_is_list(inst->output_list)) {
459 cf_log_err(conf, "Invalid output list '%s'", inst->output_list->name);
460 return -1;
461 }
462
463 /*
464 * Sanity check the config. If we're told to NOT wait,
465 * then the output pairs must not be defined.
466 */
467 if (!inst->wait && (inst->output_list != NULL)) {
468 cf_log_err(conf, "Cannot read output pairs if wait = no");
469 return -1;
470 }
471
472 if (!inst->timeout_is_set || !fr_time_delta_ispos(inst->timeout)) {
473 /*
474 * Pick the shorter one
475 */
479 }
480 else {
481 if (fr_time_delta_lt(inst->timeout, fr_time_delta_from_sec(1))) {
482 cf_log_err(conf, "Timeout '%pVs' is too small (minimum: 1s)", fr_box_time_delta(inst->timeout));
483 return -1;
484 }
485
486 /*
487 * Blocking a request longer than max_request_time isn't going to help anyone.
488 */
490 cf_log_err(conf, "Timeout '%pVs' is too large (maximum: %pVs)",
492 return -1;
493 }
494 }
495
496 return 0;
497}
498/*
499 * Do any per-module initialization that is separate to each
500 * configured instance of the module. e.g. set up connections
501 * to external databases, read configuration files, set up
502 * dictionary entries, etc.
503 *
504 * If configuration information is given in the config section
505 * that must be referenced in later calls, store a handle to it
506 * in *instance otherwise put a null pointer there.
507 */
508static int mod_bootstrap(module_inst_ctx_t const *mctx)
509{
510 xlat_t *xlat;
511
514
515 return 0;
516}
517
518/*
519 * The module name should be the only globally exported symbol.
520 * That is, everything else should be 'static'.
521 *
522 * If the module needs to temporarily modify it's instantiation
523 * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
524 * The server will then take care of ensuring that the module
525 * is single-threaded.
526 */
529 .common = {
530 .magic = MODULE_MAGIC_INIT,
531 .name = "exec",
532 .inst_size = sizeof(rlm_exec_t),
534 .bootstrap = mod_bootstrap,
536 },
537 .method_group = {
538 .bindings = (module_method_binding_t[]){
539 { .section = SECTION_NAME(CF_IDENT_ANY, CF_IDENT_ANY), .method = mod_exec_dispatch_oneshot, .method_env = &exec_method_env },
541 }
542 }
543};
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:485
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:209
#define unlikely(_x)
Definition build.h:383
#define UNUSED
Definition build.h:317
#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:658
#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:284
#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:298
#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:272
@ CONF_FLAG_ATTRIBUTE
Value must resolve to attribute in dict (deprecated, use CONF_FLAG_TMPL).
Definition cf_parse.h:436
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:595
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:289
#define cf_log_perr(_cf, _fmt,...)
Definition cf_util.h:296
#define CF_IDENT_ANY
Definition cf_util.h:78
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
Definition dcursor.h:408
#define MEM(x)
Definition debug.h:36
static fr_slen_t in
Definition dict.h:841
#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:982
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:621
#define EXEC_TIMEOUT
Default wait time for exec calls (in seconds).
Definition exec.h:32
@ FR_EXEC_FAIL_TIMEOUT
Definition exec.h:51
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_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
Definition interpret.c:1661
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
Definition interpret.c:2013
#define RPEDEBUG(fmt,...)
Definition log.h:376
fr_table_num_sorted_t const map_assignment_op_table[]
Definition map.c:363
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:461
size_t map_assignment_op_table_len
Definition map.c:379
talloc_free(reap)
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:243
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:505
static const conf_parser_t config[]
Definition base.c:186
#define REDEBUG(fmt,...)
Definition radclient.h:52
#define RDEBUG(fmt,...)
Definition radclient.h:53
char const * program
Definition radiusd.c:85
static rs_t * conf
Definition radsniff.c:53
#define RETURN_UNLANG_INVALID
Definition rcode.h:60
#define RETURN_UNLANG_RCODE(_rcode)
Definition rcode.h:66
#define RETURN_UNLANG_FAIL
Definition rcode.h:57
#define RETURN_UNLANG_OK
Definition rcode.h:58
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
@ RLM_MODULE_INVALID
The module considers the request invalid.
Definition rcode.h:45
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:43
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition rcode.h:42
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
Definition rcode.h:46
@ RLM_MODULE_REJECT
Immediately reject the request.
Definition rcode.h:41
@ RLM_MODULE_NOTFOUND
User not found.
Definition rcode.h:47
@ RLM_MODULE_UPDATED
OK (pairs modified).
Definition rcode.h:49
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition rcode.h:48
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
Definition rcode.h:44
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:82
fr_time_delta_t timeout
Definition rlm_exec.c:54
bool shell_escape
Definition rlm_exec.c:52
bool xlat_read_binary
Definition rlm_exec.c:56
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:207
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:245
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:388
module_rlm_t rlm_exec
Definition rlm_exec.c:528
static const rlm_rcode_t status2rcode[]
Definition rlm_exec.c:186
tmpl_t * input_list
Definition rlm_exec.c:50
static int mod_bootstrap(module_inst_ctx_t const *mctx)
Definition rlm_exec.c:508
bool timeout_is_set
Definition rlm_exec.c:55
tmpl_t * output_list
Definition rlm_exec.c:51
fr_value_box_list_t box
Definition rlm_exec.c:182
static const call_env_method_t exec_method_env
Definition rlm_exec.c:74
static xlat_arg_parser_t const exec_xlat_args[]
Definition rlm_exec.c:124
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:287
bool wait
Definition rlm_exec.c:49
static int mob_instantiate(module_inst_ctx_t const *mctx)
Definition rlm_exec.c:448
static const conf_parser_t module_config[]
Definition rlm_exec.c:59
bool env_inherit
Definition rlm_exec.c:53
static fr_sbuff_parse_rules_t const rhs_term
Definition rlm_exec.c:270
tmpl_t * program
Definition rlm_exec.c:71
static int instantiate(module_inst_ctx_t const *mctx)
Definition rlm_rest.c:1297
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:421
bool const sbuff_char_line_endings[UINT8_MAX+1]
Definition sbuff.c:104
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.
Definition sbuff.c:2161
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:2121
#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:192
#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:40
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:349
size_t inst_size
Size of the module's instance data.
Definition module.h:212
void * data
Module's instance data.
Definition module.h:291
void * boot
Data allocated during the boostrap phase.
Definition module.h:294
#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:336
bool at_runtime
Produce an ephemeral/runtime tmpl.
Definition tmpl.h:344
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:335
@ 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:324
Optional arguments passed to vp_tmpl functions.
Definition tmpl.h:332
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:229
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:180
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:287
#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:79
@ T_BACK_QUOTED_STRING
Definition token.h:123
#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:560
@ 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
uint8_t 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 consumend 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:4463
#define fr_box_time_delta(_val)
Definition value.h:362
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:651
static size_t char ** out
Definition value.h:1020
fr_time_delta_t max_request_time
maximum time a request can be processed
Definition worker.h:67
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