The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
trigger.c
Go to the documentation of this file.
1/*
2 * This program 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
5 * (at 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: d3f13b7d793d06bbe25c6bcac99a677460eeee57 $
19 *
20 * @file trigger.c
21 * @brief Execute scripts when a server event occurs.
22 *
23 * @copyright 2015 The FreeRADIUS server project
24 */
25RCSID("$Id: d3f13b7d793d06bbe25c6bcac99a677460eeee57 $")
26
27#include <freeradius-devel/protocol/freeradius/freeradius.internal.h>
28#include <freeradius-devel/server/cf_file.h>
29#include <freeradius-devel/server/cf_parse.h>
30#include <freeradius-devel/server/exec.h>
31#include <freeradius-devel/server/main_loop.h>
32#include <freeradius-devel/server/map.h>
33#include <freeradius-devel/server/pair.h>
34#include <freeradius-devel/server/request_data.h>
35#include <freeradius-devel/server/trigger.h>
36#include <freeradius-devel/unlang/function.h>
37#include <freeradius-devel/unlang/subrequest.h>
38#include <freeradius-devel/unlang/tmpl.h>
39
40
41#include <sys/wait.h>
42
43/** Whether triggers are enabled globally
44 *
45 */
49
50/** Describes a rate limiting entry for a trigger
51 *
52 */
53typedef struct {
54 fr_rb_node_t node; //!< Entry in the trigger last fired tree.
55 CONF_ITEM *ci; //!< Config item this rate limit counter is associated with.
56 void const *uctx; //!< Combined with ci to distinguish trigger calls. E.g. trunk / connection.
57 fr_time_t last_fired; //!< When this trigger last fired.
59
63 { .out = &dict_freeradius, .proto = "freeradius" },
65};
66
73
75{
77}
78
79/** Compares two last fired structures
80 *
81 * @param one first pointer to compare.
82 * @param two second pointer to compare.
83 * @return CMP(one, two)
84 */
85static fr_cmp_ret_t _trigger_last_fired_cmp(void const *one, void const *two)
86{
87 trigger_last_fired_t const *a = one, *b = two;
88 int8_t ret;
89
90 ret = CMP(a->ci, b->ci);
91 if (ret != 0) return ret;
92 return CMP(a->uctx, b->uctx);
93}
94
95/** Return whether triggers are enabled
96 *
97 */
99{
100 return (trigger_cs != NULL);
101}
102
103typedef struct {
104 fr_value_box_list_t out; //!< result of the xlap (which we ignore)
105 unlang_result_t result; //!< the result of expansion
106 tmpl_t *vpt; //!< the template to execute
107 int exec_status; //!< Result of the program (if the trigger is a tmpl)
109
110/** Execute a trigger - call an executable to process an event
111 *
112 * A trigger ties a state change (e.g. connection up) in a module to an action
113 * (e.g. send an SNMP trap) defined in triggers.conf or in the trigger
114 * section of a module. There's no setup for triggers, the triggering code
115 * just calls this function with the name of the trigger to run, and an optional
116 * interpreter if the trigger should run asynchronously.
117 *
118 * If no interpreter is passed in, the trigger runs synchronously, which is
119 * useful when the server is shutting down and we want to ensure that the
120 * trigger has completed before the server exits.
121 *
122 * If an interpreter is passed in, the trigger runs asynchronously in that
123 * interpreter, allowing the server to continue processing packets while the
124 * trigger runs.
125 *
126 * The name of each trigger is based on the module or portion of the server
127 * which runs the trigger, and is usually taken from the state when the module
128 * has a state change.
129 *
130 * Triggers are separate from logs, because log messages are generally
131 * informational, are not time sensitive, and usually require log files to be
132 * parsed and filtered in order to find relevant information.
133 *
134 * In contrast, triggers are something specific which the administrator needs
135 * to be notified about immediately and can't wait to post-process a log file.
136 *
137 * @note Calls to this function will be ignored if #trigger_init has not been called.
138 *
139 * @param[in] intp Interpreter to run the trigger with. If this is NULL the
140 * trigger will be executed synchronously.
141 * @param[in] cs to search for triggers in.
142 * If cs is not NULL, the portion after the last '.' in name is used for the trigger.
143 * If cs is NULL, the entire name is used to find the trigger in the global trigger
144 * section.
145 * @param[in,out] trigger_cp Optional pointer to a CONF_PAIR pointer. If populated and the pointer is not
146 * NULL, this CONF_PAIR will be used rather than searching.
147 * If populated, and the pointer is NULL, the search will happen and the pointer
148 * will be populated with the found CONF_PAIR.
149 * @param[in] name the path relative to the global trigger section ending in the trigger name
150 * e.g. module.ldap.pool.start.
151 * @param[in] rate_limit whether to rate limit triggers.
152 * @param[in] args to populate the trigger's request list with.
153 * @param[in] uctx to distinguish triggers which use the same CONF_ITEM when rate limiting.
154 * @return
155 * - 0 on success.
156 * - -1 if the trigger is not defined.
157 * - -2 if the trigger was rate limited.
158 * - -3 on failure.
159 */
160int trigger(unlang_interpret_t *intp, CONF_SECTION const *cs, CONF_PAIR **trigger_cp,
161 char const *name, bool rate_limit, fr_pair_list_t *args, void const *uctx)
162{
163 CONF_ITEM *ci;
164 CONF_PAIR *cp;
165
166 char const *attr;
167 char const *value;
168
169 request_t *request;
171 ssize_t slen;
172
174 tmpl_rules_t t_rules;
175 fr_pair_t *vp;
176
177 /*
178 * noop if trigger_init was never called, or if
179 * we're just checking the configuration.
180 */
181 if (!trigger_cs || check_config) return 0;
182
183 /*
184 * Do we have a cached conf pair?
185 */
186 if (trigger_cp && *trigger_cp) {
187 cp = *trigger_cp;
188 ci = cf_pair_to_item(cp);
189 goto cp_found;
190 }
191
192 /*
193 * A module can have a local "trigger" section. In which
194 * case that is used in preference to the global one.
195 *
196 * @todo - we should really allow triggers via @trigger,
197 * so that all of the triggers are in one location. And
198 * then we can have different triggers for different
199 * module instances.
200 */
201 if (cs) {
202 cs = cf_section_find(cs, "trigger", NULL);
203 if (!cs) goto use_global;
204
205 /*
206 * If a local trigger{...} section exists, then
207 * use the local part of the name, rather than
208 * the full path.
209 */
210 attr = strrchr(name, '.');
211 if (attr) {
212 attr++;
213 } else {
214 attr = name;
215 }
216 } else {
217 use_global:
218 cs = trigger_cs;
219 attr = name;
220 }
221
222 /*
223 * Find the trigger. Note that we do NOT allow searching
224 * from the root of the tree. Triggers MUST be in a
225 * trigger{...} section.
226 */
227 ci = cf_reference_item(cs, cs, attr);
228 if (!ci) {
229 if (cs != trigger_cs) goto use_global; /* not found locally, try to find globally */
230
231 DEBUG3("Failed finding trigger '%s'", attr);
232 return -1;
233 }
234
235 if (!cf_item_is_pair(ci)) {
236 ERROR("Trigger is not a configuration variable: %s", attr);
237 return -1;
238 }
239
240 cp = cf_item_to_pair(ci);
241 if (!cp) return -1;
242
243 if (trigger_cp) *trigger_cp = cp;
244
245cp_found:
246 value = cf_pair_value(cp);
247 if (!value) {
248 DEBUG3("Trigger has no value: %s", name);
249 return -1;
250 }
251
252 /*
253 * Perform periodic rate_limiting.
254 */
255 if (rate_limit) {
256 trigger_last_fired_t find, *found;
257 fr_time_t now = fr_time();
258
259 find.ci = ci;
260 find.uctx = uctx;
261
262 pthread_mutex_lock(trigger_mutex);
263
264 fr_rb_find((void **)&found, trigger_last_fired_tree, &find);
265 if (!found) {
266 MEM(found = talloc(NULL, trigger_last_fired_t));
267 found->ci = ci;
268 found->uctx = uctx;
269 /*
270 * Initialise last_fired to 2 seconds ago so
271 * the trigger fires on the first occurrence
272 */
273 found->last_fired = fr_time_wrap(NSEC * -2);
274
276 }
277
278 /*
279 * Send the rate_limited traps at most once per second.
280 *
281 * @todo - make this configurable for longer periods of time.
282 */
283 if (fr_time_to_sec(found->last_fired) == fr_time_to_sec(now)) {
284 pthread_mutex_unlock(trigger_mutex);
285 return -2;
286 }
287
288 found->last_fired = now;
289 pthread_mutex_unlock(trigger_mutex);
290 }
291
292 /*
293 * Allocate a request to run asynchronously in the interpreter.
294 */
295 request = request_local_alloc_internal(NULL, (&(request_init_args_t){ .detachable = true }));
296 request->name = talloc_typed_asprintf(request, "trigger-%s", name);
297
298 if (args) {
299
300 if (fr_pair_list_copy(request->request_ctx, &request->request_pairs, args) < 0) {
301 PERROR("Failed copying trigger arguments");
302
303 fail:
304 talloc_free(request);
305 return -3;
306 }
307 }
308
309 /*
310 * Add the trigger name to the request data
311 */
314
315 MEM(trigger = talloc_zero(request, fr_trigger_t));
316 fr_value_box_list_init(&trigger->out);
317
319 if (!el) el = main_loop_event_list();
320
321 /*
322 * During shutdown there may be no event list, so nothing much can be done.
323 */
324 if (unlikely(!el)) goto fail;
325
326
327 t_rules = (tmpl_rules_t) {
328 .attr = {
329 .dict_def = request->local_dict, /* we can use local attributes */
330 .list_def = request_attr_request,
331 },
332 .xlat = {
333 .runtime_el = el,
334 },
335 .at_runtime = true,
336 };
337
339 cf_pair_value_quote(cp), NULL, &t_rules);
340 if (slen <= 0) {
341 char *spaces, *text;
342
343 fr_canonicalize_error(trigger, &spaces, &text, slen, value);
344
345 cf_log_err(cp, "Failed parsing trigger expression");
346 cf_log_err(cp, "%s", text);
347 cf_log_perr(cp, "%s^", spaces);
348
349 goto fail;
350 }
351
352 if (!tmpl_is_exec(trigger->vpt) && !tmpl_is_xlat(trigger->vpt)) {
353 /*
354 * We only support exec and xlat templates.
355 * Anything else is an error.
356 */
357 cf_log_err(cp, "Trigger must be an \"expr\" or `exec`");
358 goto fail;
359 }
360
361 fr_assert(trigger->vpt != NULL);
362
363 if (unlang_tmpl_push(trigger, &trigger->result, &trigger->out, request, trigger->vpt,
365 .type = UNLANG_TMPL_ARGS_TYPE_EXEC,
366 .exec = {
367 .status_out = &trigger->exec_status,
368 .timeout = fr_time_delta_from_sec(5),
369 },
370 }, UNLANG_TOP_FRAME) < 0) {
371 goto fail;
372 }
373
374 /*
375 * An interpreter was passed in, we can run the expansion
376 * asynchronously in that interpreter. And then the
377 * worker cleans up the detached request.
378 */
379 if (intp) {
380 unlang_interpret_set(request, intp);
381
382 /*
383 * Don't allow the expansion to run for a long time.
384 *
385 * @todo - make the timeout configurable.
386 */
388 DEBUG("Failed setting timeout on trigger %s", value);
389 goto fail;
390 }
391
393 PERROR("Running trigger failed");
394 goto fail;
395 }
396 } else {
397 /*
398 * No interpreter, we MUST be running from the
399 * main loop. We then run the expansion
400 * synchronously. This allows the expansion /
401 * notification to finish before the server shuts
402 * down.
403 *
404 * If the expansion was async, then it may be
405 * possible for the server to exit before the
406 * expansion finishes. Arguably the worker
407 * thread should ensure that the server doesn't
408 * exit until all requests have acknowledged that
409 * they've exited.
410 *
411 * But those exits may be advisory. i.e. "please
412 * finish the request". This one here is
413 * mandatary to finish before the server exits.
414 */
415 unlang_interpret_synchronous(NULL, request);
416 talloc_free(request);
417 }
418
419 return 0;
420}
421
422/** Create trigger arguments to describe the server the pool connects to
423 *
424 * @note #trigger_init must be called before calling this function,
425 * else it will return NULL.
426 *
427 * @param[in] ctx to allocate fr_pair_t s in.
428 * @param[out] list to append Pool-Server and Pool-Port pairs to
429 * @param[in] server we're connecting to.
430 * @param[in] port on that server.
431 */
432void trigger_args_afrom_server(TALLOC_CTX *ctx, fr_pair_list_t *list, char const *server, uint16_t port)
433{
434 fr_dict_attr_t const *server_da;
435 fr_dict_attr_t const *port_da;
436 fr_pair_t *vp;
437
438 server_da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CONNECTION_POOL_SERVER);
439 if (!server_da) {
440 ERROR("Incomplete dictionary: Missing definition for \"Connection-Pool-Server\"");
441 return;
442 }
443
444 port_da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CONNECTION_POOL_PORT);
445 if (!port_da) {
446 ERROR("Incomplete dictionary: Missing definition for \"Connection-Pool-Port\"");
447 return;
448 }
449
450 MEM(vp = fr_pair_afrom_da(ctx, server_da));
451 fr_pair_value_strdup(vp, server, false);
452 fr_pair_append(list, vp);
453
454 MEM(vp = fr_pair_afrom_da(ctx, port_da));
455 vp->vp_uint16 = port;
456 fr_pair_append(list, vp);
457}
458
459/** Callback to verify that trigger_args map is valid
460 */
461static int trigger_args_validate(map_t *map, UNUSED void *uctx)
462{
463 if (map->lhs->type != TMPL_TYPE_ATTR) {
464 cf_log_err(map->ci, "%s is not an internal attribute reference", map->lhs->name);
465 return -1;
466 }
467
468 switch (map->rhs->type) {
470 if (tmpl_resolve(map->rhs, NULL) < 0) {
471 cf_log_err(map->ci, "Invalid data %s", map->rhs->name);
472 return -1;
473 }
474 break;
475 case TMPL_TYPE_DATA:
476 break;
477
478 default:
479 cf_log_err(map->ci, "Right hand side of trigger_args must be literal, not %s", tmpl_type_to_str(map->rhs->type));
480 return -1;
481 }
482
483 return 0;
484}
485
486#define BUILD_ATTR(_name, _value) if (_value) { \
487 da = fr_dict_attr_by_name(NULL, fr_dict_root(fr_dict_internal()), _name); \
488 if (!da) { \
489 ERROR("Incomplete dictionary: Missing definition for \"" _name "\""); \
490 return -1; \
491 } \
492 MEM(vp = fr_pair_afrom_da(ctx, da)); \
493 fr_pair_value_strdup(vp, _value, false); \
494 fr_pair_append(list, vp); \
495}
496
497/** Build trigger args pair list for modules
498 *
499 * @param[in] ctx to allocate pairs in.
500 * @param[in] list to populate.
501 * @param[in] cs CONF_SECTION to search for a "trigger_args" section
502 * @param[in] args Common module data which will populate default pairs
503 */
505{
506 map_list_t *maps;
507 map_t *map = NULL;
508 fr_pair_t *vp;
509 fr_dict_attr_t const *da;
510 tmpl_rules_t t_rules = (tmpl_rules_t){
511 .attr = {
513 .list_def = request_attr_request,
514 },
515 };
516
517 /*
518 * Build the default pairs from the module data
519 */
520 BUILD_ATTR("Module-Name", args->module)
521 BUILD_ATTR("Module-Instance", args->name)
522 BUILD_ATTR("Connection-Pool-Server", args->server)
523 da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CONNECTION_POOL_PORT);
524 if (!da) {
525 ERROR("Incomplete dictionary: Missing definition for \"Connection-Pool-Port\"");
526 return -1;
527 }
528 MEM(vp = fr_pair_afrom_da(ctx, da));
529 vp->vp_uint16 = args->port;
530 fr_pair_append(list, vp);
531
532 /*
533 * If a CONF_SECTION has been passed in, look for a "trigger_args"
534 * sub section and parse that as a map to create additional pairs.
535 */
536 if (!cs) return 0;
537 cs = cf_section_find(cs, "trigger_args", NULL);
538 if (!cs) return 0;
539
540 MEM(maps = talloc(NULL, map_list_t));
541 map_list_init(maps);
542 if (map_afrom_cs(maps, maps, cs, &t_rules, &t_rules, trigger_args_validate, NULL, 256) < 0) {
543 fail:
544 talloc_free(maps);
545 return -1;
546 }
547
548 while ((map = map_list_next(maps, map))) {
550 if (fr_value_box_cast(vp, &vp->data, vp->da->type, vp->da, &map->rhs->data.literal) < 0) goto fail;
551 }
552 talloc_free(maps);
553 return 0;
554}
555
556static int _mutex_free(pthread_mutex_t *mutex)
557{
558 pthread_mutex_destroy(mutex);
559 return 0;
560}
561
562/** Free trigger resources
563 *
564 */
565static int _trigger_free(UNUSED void *uctx)
566{
568 TALLOC_FREE(trigger_last_fired_tree);
569 TALLOC_FREE(trigger_mutex);
570
571 return 0;
572}
573
574/** Set the global trigger section trigger will search in, and register xlats
575 *
576 * This function exists because triggers are used by the connection pool, which
577 * is used in the server library which may not have the mainconfig available.
578 * Additionally, utilities may want to set their own root config sections.
579 *
580 * We don't register the trigger xlat here, as we may inadvertently initialise
581 * the xlat code, which is annoying when this is called from a utility.
582 *
583 * @param[in] cs_arg to use as global trigger section.
584 * @return
585 * - 0 on success.
586 * - -1 on failure.
587 */
588static int _trigger_init(void *cs_arg)
589{
590 CONF_SECTION *cs;
591
593 PERROR("Failed loading trigger dictionaries");
594 return -1;
595 }
597 PERROR("Failed loading trigger attributes");
598 return -1;
599 }
600
601 cs = talloc_get_type_abort(cs_arg, CONF_SECTION);
602 if (!cs) {
603 ERROR("%s - Pointer to main_config was NULL", __FUNCTION__);
604 return -1;
605 }
606
607 trigger_cs = cf_section_find(cs, "trigger", NULL);
608 if (!trigger_cs) {
609 WARN("trigger { ... } subsection not found, triggers will be disabled");
610 return 0;
611 }
612
616
618 if (pthread_mutex_init(trigger_mutex, 0) != 0) {
619 PERROR("Failed to initialize trigger mutex");
621 return -1;
622 }
623
624 talloc_set_destructor(trigger_mutex, _mutex_free);
625
626 return 0;
627}
628
630{
631 int ret;
632
633 fr_atexit_global_once_ret(&ret, _trigger_init, _trigger_free, UNCONST(CONF_SECTION *, cs));
634
635 return ret;
636}
va_list args
Definition acutest.h:770
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition build.h:186
#define RCSID(id)
Definition build.h:560
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
Definition build.h:113
#define unlikely(_x)
Definition build.h:455
#define UNUSED
Definition build.h:384
bool check_config
Definition cf_file.c:61
CONF_ITEM * cf_reference_item(CONF_SECTION const *parent_cs, CONF_SECTION const *outer_cs, char const *ptr)
Definition cf_file.c:4286
Common header for all CONF_* types.
Definition cf_priv.h:54
Configuration AVP similar to a fr_pair_t.
Definition cf_priv.h:77
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:106
bool cf_item_is_pair(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_PAIR.
Definition cf_util.c:643
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
Definition cf_util.c:1204
fr_token_t cf_pair_value_quote(CONF_PAIR const *pair)
Return the value (rhs) quoting of a pair.
Definition cf_util.c:1800
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition cf_util.c:675
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition cf_util.c:1756
CONF_ITEM * cf_pair_to_item(CONF_PAIR const *cp)
Cast a CONF_PAIR to a CONF_ITEM.
Definition cf_util.c:733
char const * cf_pair_attr(CONF_PAIR const *pair)
Return the attr of a CONF_PAIR.
Definition cf_util.c:1740
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:345
#define cf_log_perr(_cf, _fmt,...)
Definition cf_util.h:352
#define MEM(x)
Definition debug.h:38
#define ERROR(fmt,...)
Definition dhcpclient.c:40
#define DEBUG(fmt,...)
Definition dhcpclient.c:38
#define fr_dict_autofree(_to_free)
Definition dict.h:915
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2637
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:292
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:305
int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
Definition dict_util.c:4393
fr_dict_t const * fr_dict_internal(void)
Definition dict_util.c:4926
#define fr_dict_autoload(_to_load)
Definition dict.h:912
#define DICT_AUTOLOAD_TERMINATOR
Definition dict.h:311
fr_dict_attr_t const * fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr)
Check if a child attribute exists in a parent using an attribute number.
Definition dict_util.c:3585
Specifies an attribute which must be present for the module to function.
Definition dict.h:291
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:304
Test enumeration values.
Definition dict_test.h:92
Definition dwarf.c:424
talloc_free(hp)
int unlang_interpret_set_timeout(request_t *request, fr_time_delta_t timeout)
Set a timeout for a request.
Definition interpret.c:1896
void unlang_interpret_set(request_t *request, unlang_interpret_t *intp)
Set a specific interpreter for a request.
Definition interpret.c:2519
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
Definition interpret.c:2538
#define UNLANG_TOP_FRAME
Definition interpret.h:36
rlm_rcode_t unlang_interpret_synchronous(fr_event_list_t *el, request_t *request)
Execute an unlang section synchronously.
#define PERROR(_fmt,...)
Definition log.h:233
#define DEBUG3(_fmt,...)
Definition log.h:271
int map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, CONF_SECTION const *cs, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, map_validate_t validate, void *uctx, unsigned int max)
Convert a config section into an attribute map.
Definition map.c:1136
#define fr_time()
Definition event.c:60
Stores all information relating to an event list.
Definition event.c:377
void fr_canonicalize_error(TALLOC_CTX *ctx, char **sp, char **text, ssize_t slen, char const *fmt)
Canonicalize error strings, removing tabs, and generate spaces for error marker.
Definition log.c:105
fr_event_list_t * main_loop_event_list(void)
Return the main loop event list.
Definition main_loop.c:166
unsigned short uint16_t
@ FR_TYPE_STRING
String of printable characters.
long int ssize_t
fr_cmp_ret_t
Result of an ordering comparison.
Definition misc.h:50
int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from)
Duplicate a list of pairs.
Definition pair.c:2326
int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
Definition pair.c:2663
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
Definition pair.c:1352
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
Definition pair.c:290
fr_pair_t * fr_pair_afrom_da_nested(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_attr_t const *da)
Create a pair (and all intermediate parents), and append it to the list.
Definition pair.c:480
#define fr_assert(_expr)
Definition rad_assert.h:37
#define WARN(fmt,...)
static const char * spaces
Definition radict.c:177
int fr_rb_find(void **found, fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
Definition rb.c:586
int fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
Definition rb.c:637
#define fr_rb_inline_talloc_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black that verifies elements are of a specific talloc type.
Definition rb.h:244
The main red black tree structure.
Definition rb.h:71
fr_dict_attr_t const * request_attr_request
Definition request.c:43
#define request_local_alloc_internal(_ctx, _args)
Allocate a new internal request outside of the request pool.
Definition request.h:344
Optional arguments for initialising requests.
Definition request.h:288
static char const * name
#define FR_SBUFF_IN(_start, _len_or_end)
#define pair_append_request(_attr, _da)
Allocate and append a fr_pair_t to the request list.
Definition pair.h:37
static char const * tmpl_type_to_str(tmpl_type_t type)
Return a static string containing the type name.
Definition tmpl.h:638
#define tmpl_is_xlat(vpt)
Definition tmpl.h:210
int tmpl_resolve(tmpl_t *vpt, tmpl_res_rules_t const *tr_rules))
Attempt to resolve functions and attributes in xlats and attribute references.
#define tmpl_is_exec(vpt)
Definition tmpl.h:211
@ TMPL_TYPE_ATTR
Reference to one or more attributes.
Definition tmpl.h:142
@ TMPL_TYPE_DATA
Value in native boxed format.
Definition tmpl.h:138
@ TMPL_TYPE_DATA_UNRESOLVED
Unparsed literal string.
Definition tmpl.h:179
ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_token_t quote, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Convert an arbitrary string into a tmpl_t.
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
Definition tmpl.h:339
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
Definition tmpl.h:801
struct tmpl_rules_s tmpl_rules_t
Definition tmpl.h:233
Optional arguments passed to vp_tmpl functions.
Definition tmpl.h:336
fr_pair_t * vp
Value pair map.
Definition map.h:77
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
CONF_ITEM * ci
Config item that the map was created from.
Definition map.h:85
fr_dict_t const * dict_def
Default dictionary to use with unqualified attribute references.
Definition tmpl.h:273
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
Definition pair.h:69
int unlang_subrequest_child_push_and_detach(request_t *request)
Add a child request to the runnable queue.
Definition subrequest.c:489
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition talloc.c:546
void * talloc_null_ctx(void)
Retrieve the current talloc NULL ctx.
Definition talloc.c:50
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
Definition talloc.h:143
static int64_t fr_time_to_sec(fr_time_t when)
Convert an fr_time_t (internal time) to number of sec since the unix epoch (wallclock time)
Definition time.h:731
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
Definition time.h:590
#define fr_time_wrap(_time)
Definition time.h:145
#define NSEC
Definition time.h:379
"server local" time.
Definition time.h:69
int unlang_tmpl_push(TALLOC_CTX *ctx, unlang_result_t *p_result, fr_value_box_list_t *out, request_t *request, tmpl_t const *tmpl, unlang_tmpl_args_t *args, bool top_frame)
Push a tmpl onto the stack for evaluation.
Definition tmpl.c:276
tmpl_t * vpt
the template to execute
Definition trigger.c:106
int exec_status
Result of the program (if the trigger is a tmpl)
Definition trigger.c:107
static fr_dict_attr_t const * attr_trigger_name
Definition trigger.c:67
static int _trigger_init(void *cs_arg)
Set the global trigger section trigger will search in, and register xlats.
Definition trigger.c:588
void trigger_args_afrom_server(TALLOC_CTX *ctx, fr_pair_list_t *list, char const *server, uint16_t port)
Create trigger arguments to describe the server the pool connects to.
Definition trigger.c:432
static int _mutex_free(pthread_mutex_t *mutex)
Definition trigger.c:556
int trigger(unlang_interpret_t *intp, CONF_SECTION const *cs, CONF_PAIR **trigger_cp, char const *name, bool rate_limit, fr_pair_list_t *args, void const *uctx)
Execute a trigger - call an executable to process an event.
Definition trigger.c:160
static fr_dict_t const * dict_freeradius
Definition trigger.c:60
int trigger_init(CONF_SECTION const *cs)
Definition trigger.c:629
fr_dict_autoload_t trigger_dict[]
Definition trigger.c:62
static fr_cmp_ret_t _trigger_last_fired_cmp(void const *one, void const *two)
Compares two last fired structures.
Definition trigger.c:85
fr_rb_node_t node
Entry in the trigger last fired tree.
Definition trigger.c:54
fr_value_box_list_t out
result of the xlap (which we ignore)
Definition trigger.c:104
fr_time_t last_fired
When this trigger last fired.
Definition trigger.c:57
static int trigger_args_validate(map_t *map, UNUSED void *uctx)
Callback to verify that trigger_args map is valid.
Definition trigger.c:461
#define BUILD_ATTR(_name, _value)
Definition trigger.c:486
static fr_rb_tree_t * trigger_last_fired_tree
Definition trigger.c:47
unlang_result_t result
the result of expansion
Definition trigger.c:105
CONF_ITEM * ci
Config item this rate limit counter is associated with.
Definition trigger.c:55
static pthread_mutex_t * trigger_mutex
Definition trigger.c:48
void const * uctx
Combined with ci to distinguish trigger calls. E.g. trunk / connection.
Definition trigger.c:56
static CONF_SECTION const * trigger_cs
Whether triggers are enabled globally.
Definition trigger.c:46
static void _trigger_last_fired_free(void *data)
Definition trigger.c:74
bool trigger_enabled(void)
Return whether triggers are enabled.
Definition trigger.c:98
int module_trigger_args_build(TALLOC_CTX *ctx, fr_pair_list_t *list, CONF_SECTION const *cs, module_trigger_args_t *args)
Build trigger args pair list for modules.
Definition trigger.c:504
fr_dict_attr_autoload_t trigger_dict_attr[]
Definition trigger.c:69
static int _trigger_free(UNUSED void *uctx)
Free trigger resources.
Definition trigger.c:565
Describes a rate limiting entry for a trigger.
Definition trigger.c:53
Common values used by modules when building trigger args.
Definition trigger.h:42
static fr_event_list_t * el
Arguments for evaluating different types of tmpls.
Definition tmpl.h:48
int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert one type of fr_value_box_t to another.
Definition value.c:3968
static fr_slen_t data
Definition value.h:1340