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: 3c1ac23a4d58ee9062aece1f3ee762b0f1fd16f4 $
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: 3c1ac23a4d58ee9062aece1f3ee762b0f1fd16f4 $")
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 */
57
58static const conf_parser_t module_config[] = {
59 { FR_CONF_OFFSET("wait", rlm_exec_t, wait), .dflt = "yes" },
60 { FR_CONF_OFFSET("input_pairs", rlm_exec_t, input_list) },
61 { FR_CONF_OFFSET("output_pairs", rlm_exec_t, output_list) },
62 { FR_CONF_OFFSET("shell_escape", rlm_exec_t, shell_escape), .dflt = "yes" },
63 { FR_CONF_OFFSET("env_inherit", rlm_exec_t, env_inherit), .dflt = "no" },
64 { FR_CONF_OFFSET_IS_SET("timeout", FR_TYPE_TIME_DELTA, 0, rlm_exec_t, timeout) },
66};
67
68typedef struct {
71
79
81 xlat_ctx_t const *xctx,
82 request_t *request, UNUSED fr_value_box_list_t *in)
83{
84 fr_exec_state_t *exec = talloc_get_type_abort(xctx->rctx, fr_exec_state_t);
86
87 if (exec->failed == FR_EXEC_FAIL_TIMEOUT) {
88 RPEDEBUG("Execution of external program failed");
89 return XLAT_ACTION_FAIL;
90 }
91
92 /*
93 * Allow a return code of 3 as success to match the behaviour of
94 * inline module calls.
95 */
96 if ((exec->status != 0) && (exec->status != 3)) {
97 RPEDEBUG("Execution of external program returned %d", exec->status);
98 return XLAT_ACTION_FAIL;
99 }
100
101 MEM(vb = fr_value_box_alloc_null(ctx));
102
103 /*
104 * Remove any trailing line endings and trim buffer
105 */
107 fr_sbuff_trim_talloc(&exec->stdout_buff, SIZE_MAX);
108
109 /*
110 * Use the buffer for the output vb
111 */
113
115
116 return XLAT_ACTION_DONE;
117}
118
120 { .required = true, .type = FR_TYPE_STRING },
121 { .variadic = XLAT_ARG_VARIADIC_EMPTY_KEEP, .type = FR_TYPE_VOID},
123};
124
125/** Exec programs from an xlat
126 *
127 * Example:
128@verbatim
129%exec('/bin/echo', 'hello') == "hello"
130@endverbatim
131 *
132 * Exactly one request is consumed during the process lifetime,
133 * after which the process exits.
134 *
135 * @ingroup xlat_functions
136 */
138 xlat_ctx_t const *xctx,
139 request_t *request, fr_value_box_list_t *in)
140{
142 fr_pair_list_t *env_pairs = NULL;
143 fr_exec_state_t *exec;
144
145 if (inst->input_list) {
146 env_pairs = tmpl_list_head(request, tmpl_list(inst->input_list));
147 if (!env_pairs) {
148 REDEBUG("Failed to find input pairs for xlat");
149 return XLAT_ACTION_FAIL;
150 }
151 }
152
153 if (!inst->wait) {
154 if (unlikely(fr_exec_oneshot_nowait(request, in, env_pairs, inst->shell_escape, inst->env_inherit) < 0)) {
155 RPEDEBUG("Failed executing program");
156 return XLAT_ACTION_FAIL;
157 }
158
159 return XLAT_ACTION_DONE;
160 }
161
162 MEM(exec = talloc_zero(unlang_interpret_frame_talloc_ctx(request), fr_exec_state_t));
163 if (fr_exec_oneshot(exec, exec, request,
164 in,
165 env_pairs, inst->shell_escape, inst->env_inherit,
166 false,
167 inst->wait, ctx,
168 inst->timeout) < 0) {
169 talloc_free(exec);
170 return XLAT_ACTION_FAIL;
171 }
172
173 return unlang_xlat_yield(request, exec_xlat_oneshot_wait_resume, NULL, 0, exec);
174}
175
176typedef struct {
177 fr_value_box_list_t box;
180
181static const rlm_rcode_t status2rcode[] = {
182 [0] = RLM_MODULE_OK,
183 [1] = RLM_MODULE_REJECT,
184 [2] = RLM_MODULE_FAIL,
185 [3] = RLM_MODULE_OK,
186 [4] = RLM_MODULE_HANDLED,
187 [5] = RLM_MODULE_INVALID,
190 [8] = RLM_MODULE_NOOP,
191 [9] = RLM_MODULE_UPDATED,
192};
193
194
195/** Process the exit code returned by one of the exec functions
196 *
197 * @param request Current request.
198 * @param box Output string from exec call.
199 * @param status code returned by exec call.
200 * @return One of the RLM_MODULE_* values.
201 */
203{
204 rlm_rcode_t rcode;
205
206 if (status < 0) return RLM_MODULE_FAIL;
207
208 /*
209 * Exec'd programs are meant to return exit statuses that correspond
210 * to the standard RLM_MODULE_* + 1.
211 *
212 * This frees up 0, for success where it'd normally be reject.
213 */
214 if (status == 0) {
215 RDEBUG("Program executed successfully");
216
217 return RLM_MODULE_OK;
218 }
219
220 if (status > 9) {
221 REDEBUG("Program returned invalid code (greater than max rcode) (%i > 9): %pV",
222 status, box);
223 return RLM_MODULE_FAIL;
224 }
225
226 rcode = status2rcode[status];
227
228 if (rcode == RLM_MODULE_FAIL) {
229 if (box) RDEBUG("Program failed with output: %pV", box);
230
231 return RLM_MODULE_FAIL;
232 }
233
234 return rcode;
235}
236
237/** Resume a request after xlat expansion.
238 *
239 */
241 request_t *request)
242{
244 fr_value_box_list_t *args = talloc_get_type_abort(mctx->rctx, fr_value_box_list_t);
245 fr_pair_list_t *env_pairs = NULL;
246
247 /*
248 * Decide what input/output the program takes.
249 */
250 if (inst->input_list) {
251 env_pairs = tmpl_list_head(request, tmpl_list(inst->input_list));
252 if (!env_pairs) {
254 }
255 }
256
257 if (unlikely(fr_exec_oneshot_nowait(request, args, env_pairs, inst->shell_escape, inst->env_inherit) < 0)) {
258 RPEDEBUG("Failed executing program");
260 }
261
263}
264
265static fr_sbuff_parse_rules_t const rhs_term = {
266 .escapes = &(fr_sbuff_unescape_rules_t){
267 .chr = '\\',
268 .do_hex = true,
269 .do_oct = false
270 },
271 .terminals = &FR_SBUFF_TERMS(
272 L(""),
273 L("\t"),
274 L("\n"),
275 L(","),
276 )
277};
278
279/** Process the exit code and output of a short lived process
280 *
281 */
283{
284 int status;
286 rlm_exec_ctx_t *m = talloc_get_type_abort(mctx->rctx, rlm_exec_ctx_t);
287 rlm_rcode_t rcode;
288
289 /*
290 * Also prints stdout as an error if there was any...
291 */
292 rcode = rlm_exec_status2rcode(request, fr_value_box_list_head(&m->box), m->status);
293 switch (rcode) {
294 case RLM_MODULE_OK:
296 if (inst->output_list && !fr_value_box_list_empty(&m->box)) {
297 ssize_t slen;
298 map_t *map;
299 fr_value_box_t *box = fr_value_box_list_head(&m->box);
300 fr_sbuff_t in = FR_SBUFF_IN(box->vb_strvalue, box->vb_length);
301 tmpl_rules_t lhs_rules = (tmpl_rules_t) {
302 .attr = {
303 .dict_def = request->dict,
305 .list_def = tmpl_list(inst->output_list),
306 .list_presence = TMPL_ATTR_LIST_ALLOW,
307
308 /*
309 * Otherwise the tmpl code returns 0 when asked
310 * to parse unknown names. So we say "please
311 * parse unknown names as unresolved attributes",
312 * and then do a second pass to complain that the
313 * thing isn't known.
314 */
315 .allow_unresolved = false
316 }
317 };
318 tmpl_rules_t rhs_rules = lhs_rules;
319
322 rhs_rules.at_runtime = true;
323 rhs_rules.xlat.runtime_el = unlang_interpret_event_list(request);
324
325 while (true) {
326 slen = map_afrom_substr(request, &map, NULL, &in,
328 &lhs_rules, &rhs_rules, &rhs_term);
329 if (slen < 0) {
330 RPEDEBUG("Failed parsing exec output string");
331 break;
332 }
333 if (!slen) {
334 RDEBUG("Stopping due to no input at %.*s", (int) fr_sbuff_remaining(&in), fr_sbuff_current(&in));
335 break;
336 }
337
338#ifdef STATIC_ANALYZER
339 if (!map) return -1;
340#endif
341
342 RDEBUG("applying %s %s %s",
343 map->lhs->name, fr_tokens[map->op], map->rhs->name);
344
345 if (radius_legacy_map_apply(request, map, NULL) < 0) {
346 RPEDEBUG("Failed applying assignment");
347
348 TALLOC_FREE(map);
349 return -1;
350 }
351 TALLOC_FREE(map);
352
353 fr_sbuff_adv_past_whitespace(&in, SIZE_MAX, NULL);
354
355 if (!fr_sbuff_remaining(&in)) break;
356
357 /*
358 * Allow commas between attributes
359 */
360 (void) fr_sbuff_next_if_char(&in, ',');
361 }
362 }
363 break;
364
365 default:
366 break;
367 }
368
369 status = m->status;
370 if (status < 0) {
371 REDEBUG("Program exited with signal %d", -status);
373 }
374
375 /*
376 * The status rcodes aren't quite the same as the rcode
377 * enumeration.
378 */
379 RETURN_MODULE_RCODE(rcode);
380}
381
382/** Dispatch one request using a short lived process
383 *
384 */
386{
388 fr_pair_list_t *env_pairs = NULL;
389 TALLOC_CTX *ctx;
391 exec_call_env_t *env_data = talloc_get_type_abort(mctx->env_data, exec_call_env_t);
392
393 if (!env_data->program) {
394 RDEBUG("This module requires 'program' to be set.");
396 }
397
398 /*
399 * Get frame-local talloc ctx
400 */
402
403 /*
404 * Do the asynchronous xlat expansion.
405 */
406 if (!inst->wait) {
407 fr_value_box_list_t *box = talloc_zero(ctx, fr_value_box_list_t);
408
409 fr_value_box_list_init(box);
410
411 /*
412 * The xlat here only expands the arguments, then calls
413 * the resume function we set to actually dispatch the
414 * exec request.
415 */
416 return unlang_module_yield_to_xlat(request, NULL, box, request, tmpl_xlat(env_data->program),
417 mod_exec_oneshot_nowait_resume, NULL, 0, box);
418 }
419
420 /*
421 * Decide what input/output the program takes.
422 */
423 if (inst->input_list) {
424 env_pairs = tmpl_list_head(request, tmpl_list(inst->input_list));
425 if (!env_pairs) RETURN_MODULE_INVALID;
426 }
427
428 if (inst->output_list) {
429 if (!tmpl_list_head(request, tmpl_list(inst->output_list))) {
431 }
432 }
433
434 MEM(m = talloc_zero(ctx, rlm_exec_ctx_t));
435 m->status = 2; /* Fail if we couldn't exec */
436
437 fr_value_box_list_init(&m->box);
438 return unlang_module_yield_to_tmpl(m, &m->box,
439 request, env_data->program,
440 TMPL_ARGS_EXEC(env_pairs, inst->timeout, true, &m->status),
442 NULL, 0, &m->box);
443}
444
445static int mob_instantiate(module_inst_ctx_t const *mctx)
446{
447 rlm_exec_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_exec_t);
448 CONF_SECTION *conf = mctx->mi->conf;
449
450 if (inst->input_list && !tmpl_is_list(inst->input_list)) {
451 cf_log_perr(conf, "Invalid input list '%s'", inst->input_list->name);
452 return -1;
453 }
454
455 if (inst->output_list && !tmpl_is_list(inst->output_list)) {
456 cf_log_err(conf, "Invalid output list '%s'", inst->output_list->name);
457 return -1;
458 }
459
460 /*
461 * Sanity check the config. If we're told to NOT wait,
462 * then the output pairs must not be defined.
463 */
464 if (!inst->wait && (inst->output_list != NULL)) {
465 cf_log_err(conf, "Cannot read output pairs if wait = no");
466 return -1;
467 }
468
469 if (!inst->timeout_is_set || !fr_time_delta_ispos(inst->timeout)) {
470 /*
471 * Pick the shorter one
472 */
476 }
477 else {
478 if (fr_time_delta_lt(inst->timeout, fr_time_delta_from_sec(1))) {
479 cf_log_err(conf, "Timeout '%pVs' is too small (minimum: 1s)", fr_box_time_delta(inst->timeout));
480 return -1;
481 }
482
483 /*
484 * Blocking a request longer than max_request_time isn't going to help anyone.
485 */
487 cf_log_err(conf, "Timeout '%pVs' is too large (maximum: %pVs)",
489 return -1;
490 }
491 }
492
493 return 0;
494}
495/*
496 * Do any per-module initialization that is separate to each
497 * configured instance of the module. e.g. set up connections
498 * to external databases, read configuration files, set up
499 * dictionary entries, etc.
500 *
501 * If configuration information is given in the config section
502 * that must be referenced in later calls, store a handle to it
503 * in *instance otherwise put a null pointer there.
504 */
505static int mod_bootstrap(module_inst_ctx_t const *mctx)
506{
507 xlat_t *xlat;
508
511
512 return 0;
513}
514
515/*
516 * The module name should be the only globally exported symbol.
517 * That is, everything else should be 'static'.
518 *
519 * If the module needs to temporarily modify it's instantiation
520 * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
521 * The server will then take care of ensuring that the module
522 * is single-threaded.
523 */
526 .common = {
527 .magic = MODULE_MAGIC_INIT,
528 .name = "exec",
529 .inst_size = sizeof(rlm_exec_t),
531 .bootstrap = mod_bootstrap,
533 },
534 .method_group = {
535 .bindings = (module_method_binding_t[]){
536 { .section = SECTION_NAME(CF_IDENT_ANY, CF_IDENT_ANY), .method = mod_exec_dispatch_oneshot, .method_env = &exec_method_env },
538 }
539 }
540};
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:483
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:209
#define unlikely(_x)
Definition build.h:381
#define UNUSED
Definition build.h:315
#define CALL_ENV_TERMINATOR
Definition call_env.h:231
#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:235
call_env_parser_t const * env
Parsing rules for call method env.
Definition call_env.h:242
@ 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:384
Per method call config.
Definition call_env.h:175
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:642
#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:268
#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:282
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:579
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:406
#define MEM(x)
Definition debug.h:36
static fr_slen_t in
Definition dict.h:824
#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:984
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:623
#define EXEC_TIMEOUT
Default wait time for exec calls (in seconds).
Definition exec.h:32
@ FR_EXEC_FAIL_TIMEOUT
Definition exec.h:50
fr_sbuff_t stdout_buff
Expandable buffer to store process output.
Definition exec.h:54
int status
return code of the program
Definition exec.h:76
fr_exec_fail_t failed
what kind of failure
Definition exec.h:74
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:137
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
Definition interpret.c:1403
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
Definition interpret.c:1764
#define RPEDEBUG(fmt,...)
Definition log.h:376
fr_table_num_sorted_t const map_assignment_op_table[]
Definition map.c:329
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:427
size_t map_assignment_op_table_len
Definition map.c:345
talloc_free(reap)
main_config_t const * main_config
Main server configuration.
Definition main_config.c:69
fr_time_delta_t max_request_time
How long a request can be processed for before timing out.
Definition main_config.h:61
@ 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.
@ 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:257
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:506
static const conf_parser_t config[]
Definition base.c:183
#define REDEBUG(fmt,...)
Definition radclient.h:52
#define RDEBUG(fmt,...)
Definition radclient.h:53
static rs_t * conf
Definition radsniff.c:53
#define RETURN_MODULE_RCODE(_rcode)
Definition rcode.h:64
#define RETURN_MODULE_INVALID
Definition rcode.h:59
#define RETURN_MODULE_OK
Definition rcode.h:57
#define RETURN_MODULE_FAIL
Definition rcode.h:56
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:45
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:80
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.
Definition rlm_exec.c:240
fr_time_delta_t timeout
Definition rlm_exec.c:54
bool shell_escape
Definition rlm_exec.c:52
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:202
module_rlm_t rlm_exec
Definition rlm_exec.c:525
static const rlm_rcode_t status2rcode[]
Definition rlm_exec.c:181
tmpl_t * input_list
Definition rlm_exec.c:50
static int mod_bootstrap(module_inst_ctx_t const *mctx)
Definition rlm_exec.c:505
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:177
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.
Definition rlm_exec.c:385
static const call_env_method_t exec_method_env
Definition rlm_exec.c:72
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.
Definition rlm_exec.c:282
static xlat_arg_parser_t const exec_xlat_args[]
Definition rlm_exec.c:119
bool wait
Definition rlm_exec.c:49
static int mob_instantiate(module_inst_ctx_t const *mctx)
Definition rlm_exec.c:445
static const conf_parser_t module_config[]
Definition rlm_exec.c:58
bool env_inherit
Definition rlm_exec.c:53
static fr_sbuff_parse_rules_t const rhs_term
Definition rlm_exec.c:265
tmpl_t * program
Definition rlm_exec.c:69
static int instantiate(module_inst_ctx_t const *mctx)
Definition rlm_rest.c:1310
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:419
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:2128
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:2088
#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)
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:329
size_t inst_size
Size of the module's instance data.
Definition module.h:203
void * data
Module's instance data.
Definition module.h:271
void * boot
Data allocated during the boostrap phase.
Definition module.h:274
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:151
Named methods exported by a module.
Definition module.h:173
#define tmpl_xlat(_tmpl)
Definition tmpl.h:941
static fr_dict_attr_t const * tmpl_list(tmpl_t const *vpt)
Definition tmpl.h:915
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:76
tmpl_xlat_rules_t xlat
Rules/data for parsing xlats.
Definition tmpl.h:345
bool at_runtime
Produce an ephemeral/runtime tmpl.
Definition tmpl.h:353
static bool tmpl_is_list(tmpl_t const *vpt)
Definition tmpl.h:931
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
Definition tmpl.h:344
@ TMPL_ATTR_LIST_ALLOW
Attribute refs are allowed to have a list.
Definition tmpl.h:274
struct tmpl_rules_s tmpl_rules_t
Definition tmpl.h:236
fr_event_list_t * runtime_el
The eventlist to use for runtime instantiation of xlats.
Definition tmpl.h:333
Optional arguments passed to vp_tmpl functions.
Definition tmpl.h:341
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.
Definition module.c:181
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:228
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:307
fr_dict_t const * dict_def
Default dictionary to use with unqualified attribute references.
Definition tmpl.h:285
tmpl_attr_prefix_t prefix
Whether the attribute reference requires a prefix.
Definition tmpl.h:310
#define talloc_get_type_abort_const
Definition talloc.h:282
#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:78
@ 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:75
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:573
bool required
Argument must be present, and non-empty.
Definition xlat.h:148
@ XLAT_ARG_VARIADIC_EMPTY_KEEP
Empty argument groups are left alone, and either passed through as empty groups or null boxes.
Definition xlat.h:139
#define XLAT_ARG_PARSER_TERMINATOR
Definition xlat.h:168
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:147
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.
Definition value.c:4036
#define fr_box_time_delta(_val)
Definition value.h:343
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:632
static size_t char ** out
Definition value.h:997
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:365