The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
tmpl.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16 */
17
18/**
19 * $Id: 356109420969b970e97049ee2b134f5ac6f410b4 $
20 *
21 * @file lib/server/tmpl.h
22 * @brief Structures and prototypes for templates
23 *
24 * These functions are used to work with #tmpl_t structs.
25 *
26 * #tmpl_t (VPTs) specify either a data source, or a data sink.
27 *
28 * Examples of sources are #TMPL_TYPE_XLAT_UNRESOLVED, #TMPL_TYPE_EXEC and #TMPL_TYPE_ATTR.
29 * Examples of sinks are #TMPL_TYPE_ATTR.
30 *
31 * VPTs are used to gather values or attributes for evaluation, or copying, and to specify
32 * where values or #fr_pair_t should be copied to.
33 *
34 * To create new #tmpl_t use one of the tmpl_*from_* functions. These parse
35 * strings into VPTs. The main parsing function is #tmpl_afrom_substr, which can produce
36 * most types of VPTs. It uses the type of quoting (passed as an #fr_token_t) to determine
37 * what type of VPT to parse the string as. For example a #T_DOUBLE_QUOTED_STRING will
38 * produce either a #TMPL_TYPE_XLAT_UNRESOLVED or a #TMPL_TYPE_DATA_UNRESOLVED (depending if the string
39 * contained a non-literal expansion).
40 *
41 * @see tmpl_afrom_substr
42 * @see tmpl_afrom_attr_str
43 *
44 * In the case of #TMPL_TYPE_ATTR, there are special cursor overlay
45 * functions which can be used to iterate over only the #fr_pair_t that match a
46 * tmpl_t in a given list.
47 *
48 * @see tmpl_dcursor_init
49 * @see tmpl_cursor_next
50 *
51 * Or for simplicity, there are functions which wrap the cursor functions, to copy or
52 * return the #fr_pair_t that match the VPT.
53 *
54 * @see tmpl_copy_pairs
55 * @see tmpl_find_vp
56 *
57 * If you just need the string value of whatever the VPT refers to, the tmpl_*expand
58 * functions may be used. These functions evaluate the VPT, execing, and xlat expanding
59 * as necessary. In the case of #TMPL_TYPE_ATTR, and #FR_TYPE_STRING or #FR_TYPE_OCTETS
60 * #tmpl_expand will return a pointer to the raw #fr_pair_t buffer. This can be very
61 * useful when using the #CONF_FLAG_TMPL type in #conf_parser_t structs, as it allows the
62 * user to determine whether they want the module to sanitise the value using presentation
63 * format specific #xlat_escape_legacy_t function, or to operate on the raw value.
64 *
65 * @see tmpl_expand
66 * @see tmpl_aexpand
67 *
68 * @copyright 2014-2015 The FreeRADIUS server project
69 */
70RCSIDH(tmpl_h, "$Id: 356109420969b970e97049ee2b134f5ac6f410b4 $")
71
72#ifdef __cplusplus
73extern "C" {
74#endif
75
76#include <freeradius-devel/util/table.h>
77#include <freeradius-devel/util/dlist.h>
78#include <freeradius-devel/util/value.h>
79
80#include <freeradius-devel/server/tmpl_escape.h>
81
82/** The maximum number of request references allowed
83 *
84 */
85#define TMPL_MAX_REQUEST_REF_NESTING 10
86
88extern size_t pair_list_table_len;
89
90typedef enum requests_ref_e {
91 REQUEST_CURRENT = 0, //!< The current request (default).
92 REQUEST_OUTER, //!< #request_t containing the outer layer of the EAP
93 //!< conversation. Usually the RADIUS request sent
94 //!< by the NAS.
95
96 REQUEST_PARENT, //!< Parent (whatever it is).
97 REQUEST_UNKNOWN //!< Unknown request.
99
101extern size_t tmpl_request_ref_table_len;
102
103/** Base data type is an attribute reference
104 *
105 */
106#define TMPL_FLAG_ATTR 0x01000000
107
108/** Base data type is an xlat expansion
109 *
110 */
111#define TMPL_FLAG_XLAT 0x02000000
112
113/** Is a type of regular expression
114 *
115 */
116#define TMPL_FLAG_REGEX 0x04000000
117
118/** Needs resolution
119 *
120 */
121#define TMPL_FLAG_UNRESOLVED 0x08000000
122
123/** Types of #tmpl_t
124 *
125 * Types may be compound types made up of multiple other types.
126 *
127 * Types which are used as part of compound types are:
128 * - XLAT_TYPE_XLAT - #tmpl_t contains xlat expansion.
129 * - XLAT_TYPE_UNRESOLVED - #tmpl_t contains unresolved elements such as xlat functions or other expansions.
130 */
131typedef enum tmpl_type_e {
132 /** Uninitialised
133 */
135
136 /** Has no value. Usually a placeholder in a binary expression that's really a unary expression
137 */
139
140 /** Value in native boxed format
141 */
143
144 /** Reference to one or more attributes
145 */
147
148 /** Pre-parsed xlat expansion
149 */
151
152 /** Callout to an external script or program
153 */
155
156 /** Compiled (and possibly JIT'd) regular expression
157 */
159
160 /** Regex where compilation is possible but hasn't been performed yet
161 */
163
164 /** A regex containing xlat expansions. Cannot be pre-compiled
165 */
167
168 /** @name unresolved types
169 *
170 * These are tmpls which could not immediately be transformed into
171 * their "resolved" form due to missing references or because
172 * additional parsing is required.
173 *
174 * @{
175 */
176
177 /** Unparsed literal string
178 *
179 * May be an intermediary phase where the tmpl is created as a
180 * temporary structure during parsing. The value here MUST be raw
181 * data, and cannot be anything else.
182 */
184
185 /** An attribute reference that we couldn't resolve but looked valid
186 *
187 * May be resolvable later once more attributes are defined.
188 */
190
191 /** An exec with unresolved xlat function or attribute references
192 */
194
195 /** A xlat expansion with unresolved xlat functions or attribute references
196 */
198
199 /** A regular expression with unresolved xlat functions or attribute references
200 */
202
203 TMPL_TYPE_MAX //!< Marker for the last tmpl type.
205
206/** Helpers to verify the type of #tmpl_t
207 */
208#define tmpl_is_uninitialised(vpt) (vpt->type == TMPL_TYPE_UNINITIALISED)
209
210#define tmpl_is_null(vpt) (vpt->type == TMPL_TYPE_NULL)
211#define tmpl_is_data(vpt) (vpt->type == TMPL_TYPE_DATA)
212
213#define tmpl_is_attr(vpt) (vpt->type == TMPL_TYPE_ATTR)
214
215#define tmpl_is_xlat(vpt) (vpt->type == TMPL_TYPE_XLAT)
216#define tmpl_is_exec(vpt) (vpt->type == TMPL_TYPE_EXEC)
217
218#define tmpl_is_regex(vpt) (vpt->type == TMPL_TYPE_REGEX)
219#define tmpl_is_regex_uncompiled(vpt) (vpt->type == TMPL_TYPE_REGEX_UNCOMPILED)
220#define tmpl_is_regex_xlat(vpt) (vpt->type == TMPL_TYPE_REGEX_XLAT)
221
222#define tmpl_is_data_unresolved(vpt) (vpt->type == TMPL_TYPE_DATA_UNRESOLVED)
223#define tmpl_is_exec_unresolved(vpt) (vpt->type == TMPL_TYPE_EXEC_UNRESOLVED)
224#define tmpl_is_attr_unresolved(vpt) (vpt->type == TMPL_TYPE_ATTR_UNRESOLVED)
225#define tmpl_is_xlat_unresolved(vpt) (vpt->type == TMPL_TYPE_XLAT_UNRESOLVED)
226#define tmpl_is_regex_xlat_unresolved(vpt) (vpt->type == TMPL_TYPE_REGEX_XLAT_UNRESOLVED)
227
228#define tmpl_needs_resolving(vpt) (vpt->type & TMPL_FLAG_UNRESOLVED)
229#define tmpl_contains_attr(vpt) (vpt->type & TMPL_FLAG_ATTR)
230#define tmpl_contains_regex(vpt) (vpt->type & TMPL_FLAG_REGEX)
231#define tmpl_contains_xlat(vpt) (vpt->type & TMPL_FLAG_XLAT)
232
234extern size_t tmpl_type_table_len;
235
239typedef struct tmpl_literal_rules_s tmpl_literal_rules_t;
241typedef struct tmpl_s tmpl_t;
242
243#include <freeradius-devel/unlang/xlat.h>
244#include <freeradius-devel/unlang/xlat_ctx.h>
245#include <freeradius-devel/util/packet.h>
246#include <freeradius-devel/util/proto.h>
247#include <freeradius-devel/util/regex.h>
248
249/*
250 * Allow public and private versions of the same structures
251 */
252#ifdef _CONST
253# error _CONST can only be defined in the local header
254#endif
255#ifndef _TMPL_PRIVATE
256# define _CONST const
257#else
258# define _CONST
259#endif
260
261/** Specify whether attribute references require a prefix
262 *
263 */
264typedef enum {
265 TMPL_ATTR_REF_PREFIX_YES = 0, //!< Attribute refs must have '&' prefix.
266 TMPL_ATTR_REF_PREFIX_NO, //!< Attribute refs have no '&' prefix.
267 TMPL_ATTR_REF_PREFIX_AUTO //!< Attribute refs may have a '&' prefix.
269
270/** Specify whether attribute references can have a list (or parent) reference
271 *
272 */
273typedef enum {
274 TMPL_ATTR_LIST_ALLOW = 0, //!< Attribute refs are allowed to have a list
275 TMPL_ATTR_LIST_FORBID, //!< Attribute refs are forbidden from having a list
276 TMPL_ATTR_LIST_REQUIRE //!< Attribute refs are required to have a list.
278
279/** Define entry and head types for tmpl request references
280 *
281 */
282FR_DLIST_TYPES(tmpl_request_list)
283
285 fr_dict_t const *dict_def; //!< Default dictionary to use
286 ///< with unqualified attribute references.
287
288 fr_dict_attr_t const *namespace; //!< Point in dictionary tree to resume parsing
289 ///< from. If this is provided then dict_def
290 ///< request_def and list_def will be ignored
291 ///< and the presence of any of those qualifiers
292 ///< will be treated as an error.
293
294 FR_DLIST_HEAD(tmpl_request_list) _CONST *request_def; //!< Default request to use with
295 ///< unqualified attribute references.
296 ///< If NULL the request is assumed to
297 ///< but the current request.
298 ///< Usually this will be one of
299 ///< - tmpl_request_def_current
300 ///< - tmpl_request_def_outer
301 ///< - tmpl_request_def_parent
302 ///< If a custom list needs to be
303 ///< used it should be allocated on
304 ///< the stack and a pointer to it
305 ///< placed here.
306
307 fr_dict_attr_t const *list_def; //!< Default list to use with unqualified
308 ///< attribute reference.
309
310 tmpl_attr_prefix_t prefix; //!< Whether the attribute reference requires
311 ///< a prefix.
312
313 tmpl_attr_list_presence_t list_presence; //!< Whether the attribute reference can
314 ///< have a list, forbid it, or require it.
315
316 uint8_t allow_unknown:1; //!< Allow unknown attributes i.e. attributes
317 ///< defined by OID string.
318
319 uint8_t allow_unresolved:1; //!< Allow attributes that look valid but were
320 ///< not found in the dictionaries.
321 ///< This should be used as part of a multi-pass
322 ///< approach to parsing.
323
324 uint8_t allow_wildcard:1; //!< Allow the special case of .[*] representing
325 ///< all children of a structural attribute.
326
327 uint8_t allow_foreign:1; //!< Allow arguments not found in dict_def.
328
329 uint8_t disallow_filters:1; //!< disallow filters.
330};
331
333 fr_event_list_t *runtime_el; //!< The eventlist to use for runtime instantiation
334 ///< of xlats.
335 bool new_functions; //!< new function syntax
336};
337
338/** Optional arguments passed to vp_tmpl functions
339 *
340 */
342 tmpl_rules_t const *parent; //!< for parent / child relationships
343
344 tmpl_attr_rules_t attr; //!< Rules/data for parsing attribute references.
345 tmpl_xlat_rules_t xlat; //!< Rules/data for parsing xlats.
346
347 fr_dict_attr_t const *enumv; //!< Enumeration attribute used to resolve enum values.
348
349 fr_type_t cast; //!< Whether there was an explicit cast.
350 ///< Used to determine if barewords or other values
351 ///< should be converted to an internal data type.
352
353 bool at_runtime; //!< Produce an ephemeral/runtime tmpl.
354 ///< Instantiated xlats are not added to the global
355 ///< trees, regexes are not JIT'd.
356 fr_value_box_safe_for_t literals_safe_for; //!< safe_for value assigned to literal values in
357 ///< xlats, execs, and data.
358 tmpl_escape_t escape; //!< How escaping should be handled during evaluation.
359};
360
361/** Similar to tmpl_rules_t, but used to specify parameters that may change during subsequent resolution passes
362 *
363 * When a tmpl is parsed initially the rules are stored in the #tmpl_t.
364 *
365 * During subsequent resolution phases where unresolved attributes are resolved to dictionary
366 * attributes the initial #tmpl_rules_t is used to control resolution.
367 *
368 * In some instances however (primarily policies), some rules may need change between initial
369 * parsing and subsequent resolution phases.
370 *
371 * This structure holds rules which may override the tmpl_rules_s during subsequent resolution passes.
372 */
374 fr_dict_t const *dict_def; //!< Alternative default dictionary to use if
375 ///< vpt->rules->dict_def is NULL.
376 //!< Will be written to vpt->rules->dict_def
377 ///< if used.
378
379 bool force_dict_def; //!< Use supplied dict_def even if original
380 ///< vpt->rules->dict_def was not NULL.
381
382 fr_dict_attr_t const *enumv; //!< for resolving T_BARE_WORD
383};
384
385typedef enum {
386 TMPL_ATTR_TYPE_NORMAL = 0, //!< Normal, resolved, attribute ref.
387 TMPL_ATTR_TYPE_UNSPEC, //!< No attribute was specified as this level
388 ///< only a filter.
389 TMPL_ATTR_TYPE_UNKNOWN, //!< We have an attribute number but
390 ///< it doesn't match anything in the
391 ///< dictionary, or isn't a child of
392 ///< the previous ref. May be resolved
393 ///< later.
394 TMPL_ATTR_TYPE_UNRESOLVED //!< We have a name, but nothing else
395 ///< to identify the attribute.
396 ///< may be resolved later.
398
399#define NUM_UNSPEC INT16_MIN
400#define NUM_ALL (INT16_MIN + 1)
401#define NUM_COUNT (INT16_MIN + 2)
402#define NUM_LAST (INT16_MIN + 3)
403
404/** Define entry and head types for attribute reference lists
405 *
406 */
407FR_DLIST_TYPES(tmpl_attr_list)
408
409/** Different types of filter that can be applied to an attribute reference
410 *
411 */
412typedef enum {
413 TMPL_ATTR_FILTER_TYPE_NONE = 0, //!< No filter present.
414 TMPL_ATTR_FILTER_TYPE_INDEX, //!< Filter is an index type.
415 TMPL_ATTR_FILTER_TYPE_CONDITION, //!< Filter is a condition
416 TMPL_ATTR_FILTER_TYPE_TMPL, //!< Filter is a tmpl
417 TMPL_ATTR_FILTER_TYPE_EXPR, //!< Filter is an expression
419
420typedef struct {
421 tmpl_attr_filter_type_t _CONST type; //!< Type of filter this is.
422 int16_t _CONST num; //!< For array references.
423
424 /*
425 * These are "union" because they are disjoint. The "num" field is arguably disjoint, too, but
426 * there is currently a lot of code in tmpl_tokenize.c which directly references ar->ar_num
427 * without checking the type.
428 */
429 union {
430 xlat_exp_head_t _CONST *cond; //!< xlat condition
431 tmpl_t _CONST *tmpl; //!< tmpl
432 xlat_exp_head_t _CONST *expr; //!< xlat expression
433 };
435
436/** An element in a list of nested attribute references
437 *
438 */
439typedef struct {
440 FR_DLIST_ENTRY(tmpl_attr_list) _CONST entry; //!< Entry in the doubly linked list
441 ///< of attribute references.
442
443 fr_dict_attr_t const * _CONST da; //!< Resolved dictionary attribute.
444
445 union {
446 struct {
447 fr_dict_attr_t * _CONST da; //!< Unknown dictionary attribute.
448 } unknown;
449
450 struct {
451 char * _CONST name; //!< Undefined reference type.
452 fr_dict_attr_t const * _CONST namespace; //!< Namespace we should be trying
453 ///< to resolve this attribute in.
454 } unresolved;
455 };
456
457 fr_dict_attr_t const * _CONST parent; //!< The parent we used when trying to
458 ///< resolve the attribute originally.
459 ///< Should point to the referenced
460 ///< attribute.
461
462 unsigned int _CONST resolve_only : 1; //!< This reference and those before it
463 ///< in the list can only be used for
464 ///< resolution, not building out trees.
465 unsigned int _CONST is_raw : 1; /// is a raw reference
466
467 tmpl_attr_type_t _CONST type; //!< Type of attribute reference.
468
469 tmpl_attr_filter_t _CONST filter; //!< Filter associated with the attribute reference.
471
472/** Define manipulation functions for the attribute reference list
473 *
474 */
475FR_DLIST_FUNCS(tmpl_attr_list, tmpl_attr_t, entry)
476
477/** An element in a list of request references
478 *
479 */
480typedef struct {
481 FR_DLIST_ENTRY(tmpl_request_list) _CONST entry; //!< Entry in the doubly linked list
482 ///< of request references.
483
486
487/** Define manipulation functions for the attribute reference list
488 *
489 */
490FR_DLIST_FUNCS(tmpl_request_list, tmpl_request_t, entry)
491
492/** How many additional headers to allocate in a pool for a tmpl_t
493 *
494 */
495#define TMPL_POOL_DEF_HEADERS 4
496
497/** How many additional bytes to allocate in a pool for a tmpl_t
498 *
499 */
500#define TMPL_POOL_DEF_LEN (sizeof(tmpl_t) + 64 + sizeof(tmpl_attr_t) + sizeof(tmpl_request_t))
501
502/** @name Field accessors for attribute references
503 *
504 * @{
505 */
506#define ar_type type
507#define ar_depth depth
508#define ar_da da
509#define ar_parent parent
510#define ar_unknown unknown.da
511#define ar_unresolved unresolved.name
512#define ar_unresolved_namespace unresolved.namespace
513
514#define ar_is_normal(_ar) ((_ar)->ar_type == TMPL_ATTR_TYPE_NORMAL)
515#define ar_is_unspecified(_ar) ((_ar)->ar_type == TMPL_ATTR_TYPE_UNSPEC)
516#define ar_is_unknown(_ar) ((_ar)->ar_type == TMPL_ATTR_TYPE_UNKNOWN)
517#define ar_is_unresolved(_ar) ((_ar)->ar_type == TMPL_ATTR_TYPE_UNRESOLVED)
518#define ar_is_raw(_ar) ((_ar)->is_raw)
519
520#define ar_num filter.num
521#define ar_cond filter.cond
522#define ar_tmpl filter.tmpl
523#define ar_expr filter.expr
524#define ar_filter_type filter.type
525
526#define ar_filter_is_none(_ar) ((_ar)->ar_filter_type == TMPL_ATTR_FILTER_TYPE_NONE)
527#define ar_filter_is_num(_ar) ((_ar)->ar_filter_type == TMPL_ATTR_FILTER_TYPE_INDEX)
528#define ar_filter_is_cond(_ar) ((_ar)->ar_filter_type == TMPL_ATTR_FILTER_TYPE_CONDITION)
529#define ar_filter_is_tmpl(_ar) ((_ar)->ar_filter_type == TMPL_ATTR_FILTER_TYPE_TMPL)
530#define ar_filter_is_expr(_ar) ((_ar)->ar_filter_type == TMPL_ATTR_FILTER_TYPE_EXPR)
531/** @} */
532
533/** A source or sink of value data.
534 *
535 * Is used as both the RHS and LHS of a map (both update, and conditional types)
536 *
537 * @section update_maps Use in update map_t
538 * When used on the LHS it describes an attribute to create and should be one of these types:
539 * - #TMPL_TYPE_ATTR
540 *
541 * When used on the RHS it describes the value to assign to the attribute being created and
542 * should be one of these types:
543 * - #TMPL_TYPE_DATA_UNRESOLVED
544 * - #TMPL_TYPE_XLAT_UNRESOLVED
545 * - #TMPL_TYPE_ATTR
546 * - #TMPL_TYPE_EXEC
547 * - #TMPL_TYPE_DATA
548 * - #TMPL_TYPE_XLAT (pre-parsed xlat)
549 *
550 * @section conditional_maps Use in conditional map_t
551 * When used as part of a condition it may be any of the RHS side types, as well as:
552 * - #TMPL_TYPE_REGEX (pre-parsed regex)
553 *
554 * @see map_t
555 */
556struct tmpl_s {
557 tmpl_type_t _CONST type; //!< What type of value tmpl refers to.
558
559 char const * _CONST name; //!< Raw string used to create the template.
560 ///< this string will have any escape sequences left intact.
561 size_t _CONST len; //!< Length of the raw string used to create the template.
562 fr_token_t _CONST quote; //!< What type of quoting was around the raw string.
563
564 union {
565 char *unescaped; //!< Unescaped form of the name, used for TMPL_TYPE_DATA_UNRESOLVED
566 ///< and TMPL_TYPE_REGEX_UNCOMPILED.
567
568 _CONST struct {
569 bool ref_prefix; //!< true if the reference was prefixed
570 ///< with a '&'.
571 FR_DLIST_HEAD(tmpl_request_list) rr; //!< Request to search or insert in.
572 FR_DLIST_HEAD(tmpl_attr_list) ar; //!< Head of the attribute reference list.
573 } attribute;
574
575 /*
576 * Attribute value. Typically used as the RHS of an update map.
577 */
578 fr_value_box_t literal; //!< Value data.
579
580 struct {
581 union {
582 _CONST struct {
583 xlat_exp_head_t *ex; //!< pre-parsed xlat expansion
584 ///< and expansion.
585 } xlat;
586#ifdef HAVE_REGEX
587 _CONST struct {
588 char *src; //!< Original unescaped source string.
589 regex_t *ex; //!< pre-parsed regex_t
590 bool subcaptures; //!< Whether the regex was compiled with
591 ///< subcaptures.
592 } reg;
593#endif
594 };
595 fr_regex_flags_t reg_flags; //!< Flags for regular expressions.
596 ///< Used by:
597 ///< - TMPL_TYPE_REGEX_XLAT
598 ///< - TMPL_TYPE_REGEX_UNCOMPILED
599 ///< - TMPL_TYPE_REGEX
600 ///< - TMPL_TYPE_REGEX_XLAT_UNRESOLVED
601 };
603
604 tmpl_rules_t _CONST rules; //!< The rules that were used when creating the tmpl.
605 ///< These are useful for multiple resolution passes as
606 ///< they ensure the correct parsing rules are applied.
607};
608
609/** Describes the current extents of a pair tree in relation to the tree described by a tmpl_t
610 *
611 */
612typedef struct {
613 fr_dlist_t entry; //!< Entry in the dlist of extents
614
615 tmpl_attr_t const *ar; //!< Attribute representing the ar
616 ///< after the deepest node that was found
617 ///< in the existing pair tree when evaluating
618 ///< this path. If this is NULL, then all ars
619 ///< were evaluated.
620
621 TALLOC_CTX *list_ctx; //!< Where to allocate new attributes if building
622 ///< out from the current extents of the tree.
623 fr_pair_list_t *list; //!< List that we tried to evaluate ar in and failed.
624 ///< Or if ar is NULL, the list that represents the
625 ///< deepest grouping or TLV attribute the chain of
626 ///< ars referenced.
628
629/** Convenience macro for printing a meaningful assert message when we get a bad tmpl type
630 */
631#define tmpl_assert_type(_cond) \
632 fr_assert_msg(_cond, "Unexpected tmpl type '%s'", \
633 tmpl_type_to_str(vpt->type))
634
635
636/** @name Functions for printing and parsing tmpl type names
637 *
638 * @{
639 */
640/** Return a static string containing the type name
641 *
642 * @param[in] type to return name for.
643 * @return name of the type
644 */
645static inline char const *tmpl_type_to_str(tmpl_type_t type)
646{
647 return fr_table_str_by_value(tmpl_type_table, type, "<INVALID>");
648}
649
650/** Return the constant value representing a type
651 *
652 * @param[in] type to return the constant value for.
653 * @return The constant type value or TMPL_TYPE_UNINITIALISED if no type matches.
654 */
659/** @} */
660
661/** @name Field accessors for #TMPL_TYPE_ATTR, #TMPL_TYPE_ATTR_UNRESOLVED
662 *
663 * @{
664 */
665 #define tmpl_attr(_tmpl) &(_tmpl)->data.attribute.ar
666
667static inline FR_DLIST_HEAD(tmpl_request_list) const *tmpl_request(tmpl_t const *vpt)
668{
671
672 return &vpt->data.attribute.rr;
673}
674
675/** The number of request references contained within a tmpl
676 *
677 */
678static inline size_t tmpl_request_ref_count(tmpl_t const *vpt)
679{
682
683 return tmpl_request_list_num_elements(&vpt->data.attribute.rr);
684}
685
686/** Return true if the tmpl_attr is one of the list types
687 *
688 * @hidecallergraph
689*/
690static inline bool tmpl_attr_is_list_attr(tmpl_attr_t const *ar)
691{
692 if (!ar || !ar_is_normal(ar)) return false;
693
694 return (ar->ar_da == request_attr_request) ||
695 (ar->ar_da == request_attr_reply) ||
696 (ar->ar_da == request_attr_control) ||
697 (ar->ar_da == request_attr_state) ||
698 (ar->ar_da == request_attr_local);
699}
700
701/** Return true if the head attribute reference is a list reference
702 *
703 * @hidecallergraph
704 */
705static inline bool tmpl_attr_head_is_list(tmpl_t const *vpt)
706{
707 tmpl_attr_t *ar;
708
710
711 ar = tmpl_attr_list_head(tmpl_attr(vpt));
712 if (unlikely(!ar)) return false;
713
714 return tmpl_attr_is_list_attr(ar);
715}
716
717/** Return true if the last attribute reference is "normal"
718 *
719 * @hidecallergraph
720 */
721static inline bool tmpl_attr_tail_is_normal(tmpl_t const *vpt)
722{
723 tmpl_attr_t *ar;
724
726
727 ar = tmpl_attr_list_tail(tmpl_attr(vpt));
728 if (unlikely(!ar)) return false;
729
730 return ar_is_normal(ar);
731}
732
733/** Return true if the last attribute reference is "unspecified"
734 *
735 * @hidecallergraph
736 */
737static inline bool tmpl_attr_tail_is_unspecified(tmpl_t const *vpt)
738{
739 tmpl_attr_t *ar;
740
742
743 ar = tmpl_attr_list_tail(tmpl_attr(vpt));
744 if (unlikely(!ar)) return false;
745
746 return ar_is_unspecified(ar);
747}
748
749/** Return true if the last attribute reference is "unknown"
750 *
751 * @hidecallergraph
752 */
753static inline bool tmpl_attr_tail_is_unknown(tmpl_t const *vpt)
754{
755 tmpl_attr_t *ar;
756
758
759 ar = tmpl_attr_list_tail(tmpl_attr(vpt));
760 if (unlikely(!ar)) return false;
761
762 return ar_is_unknown(ar);
763}
764
765/** Return true if the last attribute reference is "unresolved"
766 *
767 * @hidecallergraph
768 */
769static inline bool tmpl_attr_tail_is_unresolved(tmpl_t const *vpt)
770{
771 tmpl_attr_t *ar;
772
774
775 ar = tmpl_attr_list_tail(tmpl_attr(vpt));
776 if (unlikely(!ar)) return false;
777
778 return ar_is_unresolved(ar);
779}
780
781/** Return true if the last attribute reference is "raw"
782 *
783 * @hidecallergraph
784 */
785static inline bool tmpl_attr_tail_is_raw(tmpl_t const *vpt)
786{
787 tmpl_attr_t *ar;
788
790
791 ar = tmpl_attr_list_tail(tmpl_attr(vpt));
792 if (unlikely(!ar)) return false;
793
794 return ar_is_raw(ar);
795}
796
797/** Return the last attribute reference
798 *
799 * @hidecallergraph
800 */
801static inline tmpl_attr_t const *tmpl_attr_tail(tmpl_t const *vpt)
802{
804
805 return tmpl_attr_list_tail(tmpl_attr(vpt));
806}
807
808/** Return the last attribute reference da
809 *
810 * @hidecallergraph
811 */
812static inline fr_dict_attr_t const *tmpl_attr_tail_da(tmpl_t const *vpt)
813{
814 tmpl_attr_t *ar;
815
817
818 ar = tmpl_attr_list_tail(tmpl_attr(vpt));
819 if (!ar) return NULL;
820
821 return ar->ar_da;
822}
823
824/** Return true if the the last attribute reference is a leaf attribute
825 *
826 * @hidecallergraph
827 */
828static inline bool tmpl_attr_tail_da_is_leaf(tmpl_t const *vpt)
829{
830 tmpl_attr_t *ar;
831
833
834 ar = tmpl_attr_list_tail(tmpl_attr(vpt));
835 if (!ar) return false;
836
838
839 return fr_type_is_leaf(ar->ar_da->type);
840}
841
842/** Return true if the the last attribute reference is a structural attribute
843 *
844 * @hidecallergraph
845 */
847{
848 tmpl_attr_t *ar;
849
851
852 ar = tmpl_attr_list_tail(tmpl_attr(vpt));
853 if (!ar) return false;
854
856
857 return fr_type_is_structural(ar->ar_da->type);
858}
859
860/** Return the last attribute reference unknown da
861 *
862 * @hidecallergraph
863 */
865{
866 tmpl_attr_t *ar;
867
869
870 ar = tmpl_attr_list_tail(tmpl_attr(vpt));
871 if (!ar) return NULL;
872
873 return ar->ar_unknown;
874}
875
876/** Return the last attribute reference unresolved da
877 *
878 * @hidecallergraph
879 */
880static inline char const *tmpl_attr_tail_unresolved(tmpl_t const *vpt)
881{
882 tmpl_attr_t *ar;
883
885
886 ar = tmpl_attr_list_tail(tmpl_attr(vpt));
887 if (!ar) return NULL;
888
889 return ar->ar_unresolved;
890}
891
892/** Return the last attribute reference's attribute number
893 *
894 * @hidecallergraph
895 */
896static inline int16_t tmpl_attr_tail_num(tmpl_t const *vpt)
897{
900
901 return tmpl_attr_list_tail(tmpl_attr(vpt))->ar_num;
902}
903
904/** The number of attribute references contained within a tmpl
905 *
906 */
907static inline size_t tmpl_attr_num_elements(tmpl_t const *vpt)
908{
911
912 return tmpl_attr_list_num_elements(tmpl_attr(vpt));
913}
914
915static inline fr_dict_attr_t const *tmpl_list(tmpl_t const *vpt)
916{
917 if (!tmpl_attr_head_is_list(vpt)) return NULL;
918
919 return tmpl_attr_list_head(tmpl_attr(vpt))->ar_da;
920}
921/** @} */
922
923/** Return the name of a tmpl list or def if list not provided
924 *
925*/
926static inline char const *tmpl_list_name(fr_dict_attr_t const *list, char const *def)
927{
928 return (list ? list->name : def);
929}
930
931static inline bool tmpl_is_list(tmpl_t const *vpt)
932{
933 if (!tmpl_is_attr(vpt)) return false;
935}
936
937/** @name Field accessors for #TMPL_TYPE_XLAT
938 *
939 * @{
940 */
941#define tmpl_xlat(_tmpl) (_tmpl)->data.xlat.ex
942/** @} */
943
944/** @name Field accessors for #TMPL_TYPE_DATA
945 *
946 * @{
947 */
948#define tmpl_value(_tmpl) (&(_tmpl)->data.literal)
949#define tmpl_value_length(_tmpl) (_tmpl)->data.literal.vb_length
950#define tmpl_value_type(_tmpl) (_tmpl)->data.literal.type
951#define tmpl_value_enumv(_tmpl) (_tmpl)->data.literal.enumv
952
953#define tmpl_rules_cast(_tmpl) (_tmpl)->rules.cast
954#define tmpl_rules_enumv(_tmpl) (_tmpl)->rules.enumv
955/** @} */
956
957/** @name Field accessors for #TMPL_TYPE_REGEX and #TMPL_TYPE_REGEX_XLAT_UNRESOLVED
958 *
959 * @{
960 */
961#ifdef HAVE_REGEX
962# define tmpl_regex(_tmpl) (_tmpl)->data.reg.ex //!< #TMPL_TYPE_REGEX only.
963# define tmpl_regex_flags(_tmpl) (&(_tmpl)->data.reg_flags)
964#endif
965/** @} */
966
967#ifndef WITH_VERIFY_PTR
968# define TMPL_ATTR_VERIFY(_vpt)
969# define TMPL_VERIFY(_vpt)
970#else
971# define TMPL_ATTR_VERIFY(_vpt) tmpl_attr_verify(__FILE__, __LINE__, _vpt)
972# define TMPL_VERIFY(_vpt) tmpl_verify(__FILE__, __LINE__, _vpt)
973void tmpl_attr_verify(char const *file, int line, tmpl_t const *vpt);
974void tmpl_verify(char const *file, int line, tmpl_t const *vpt);
975#endif
976
977/** Determine the correct context and list head
978 *
979 * Used in conjunction with the fr_dcursor functions to determine the correct list
980 * and TALLOC_CTX for inserting fr_pair_ts.
981 *
982 * Example:
983 @code{.c}
984 TALLOC_CTX *ctx;
985 fr_pair_list_t *head;
986 fr_value_box_t value;
987
988 tmpl_pair_list_and_ctx(ctx, head, request, CURRENT_REQUEST, request_attr_request);
989 if (!list) return -1; // error
990
991 value.strvalue = talloc_typed_strdup(NULL, "my new username");
992 value.length = talloc_array_length(value.strvalue) - 1;
993 @endcode
994 *
995 * @param _ctx new #fr_pair_t s should be allocated in for the specified list.
996 * @param _head of the #fr_pair_t list.
997 * @param _request The current request.
998 * @param _ref to resolve.
999 * @param _list to resolve.
1000 */
1001#define tmpl_pair_list_and_ctx(_ctx, _head, _request, _ref, _list) \
1002do {\
1003 request_t *_rctx = _request; \
1004 if ((tmpl_request_ptr(&_rctx, _ref) < 0) || \
1005 !(_head = tmpl_list_head(_rctx, _list)) || \
1006 !(_ctx = tmpl_list_ctx(_rctx, _list))) {\
1007 _ctx = NULL; \
1008 _head = NULL; \
1009 }\
1010} while (0)
1011
1012typedef enum {
1013 TMPL_ATTR_ERROR_NONE = 0, //!< No error.
1014 TMPL_ATTR_ERROR_EMPTY, //!< Attribute ref contains no data.
1015 TMPL_ATTR_ERROR_BAD_PREFIX, //!< Missing '&' or has '&' when it shouldn't.
1016 TMPL_ATTR_ERROR_LIST_NOT_ALLOWED, //!< List qualifier is not allowed here.
1017 TMPL_ATTR_ERROR_LIST_MISSING, //!< List qualifier is required, but missing.
1018 TMPL_ATTR_ERROR_UNKNOWN_NOT_ALLOWED, //!< Attribute specified as OID, could not be
1019 ///< found in the dictionaries, and is disallowed
1020 ///< because 'disallow_internal' in tmpl_rules_t
1021 ///< is trie.
1022 TMPL_ATTR_ERROR_UNRESOLVED_NOT_ALLOWED, //!< Attribute couldn't be found in the dictionaries.
1023 TMPL_ATTR_ERROR_UNQUALIFIED_NOT_ALLOWED, //!< Attribute must be qualified to be used here.
1024 TMPL_ATTR_ERROR_INVALID_NAME, //!< Attribute ref length is zero, or longer than
1025 ///< the maximum.
1026 TMPL_ATTR_ERROR_INTERNAL_NOT_ALLOWED, //!< Attribute resolved to an internal attribute
1027 ///< which is disallowed.
1028 TMPL_ATTR_ERROR_FOREIGN_NOT_ALLOWED, //!< Attribute resolved in a dictionary different
1029 ///< to the one specified.
1030 TMPL_ATTR_ERROR_FILTER_NOT_ALLOWED, //!< Filters disallowed by rules.
1031 TMPL_ATTR_ERROR_INVALID_ARRAY_INDEX, //!< Invalid array index.
1033 TMPL_ATTR_ERROR_NESTING_TOO_DEEP, //!< Too many levels of nesting.
1034 TMPL_ATTR_ERROR_MISSING_TERMINATOR, //!< Unexpected text found after attribute reference
1035 TMPL_ATTR_ERROR_BAD_CAST //!< Specified cast was invalid.
1037
1038/** Map ptr type to a boxed type
1039 *
1040 */
1041#define FR_TYPE_FROM_PTR(_ptr) \
1042 _Generic((_ptr), \
1043 char **: FR_TYPE_STRING, \
1044 char const **: FR_TYPE_STRING, \
1045 uint8_t **: FR_TYPE_OCTETS, \
1046 uint8_t const **: FR_TYPE_OCTETS, \
1047 uint8_t *: FR_TYPE_UINT8, \
1048 uint16_t *: FR_TYPE_UINT16, \
1049 uint32_t *: FR_TYPE_UINT32, \
1050 uint64_t *: FR_TYPE_UINT64, \
1051 fr_value_box_t **: FR_TYPE_VALUE_BOX, \
1052 fr_value_box_t const **: FR_TYPE_VALUE_BOX)
1053
1054/** Expand a tmpl to a C type, using existing storage to hold variably sized types
1055 *
1056 * Expands a template using the _out ptr to determinate the cast type.
1057 *
1058 * @see _tmpl_to_type
1059 */
1060#define tmpl_expand(_out, _buff, _buff_len, _request, _vpt, _escape, _escape_ctx) \
1061 _tmpl_to_type((void *)(_out), (uint8_t *)_buff, _buff_len, \
1062 _request, _vpt, _escape, _escape_ctx, FR_TYPE_FROM_PTR(_out))
1063
1064/** Expand a tmpl to a C type, allocing a new buffer to hold the string
1065 *
1066 * Expands a template using the _out ptr to determinate the cast type.
1067 *
1068 * @see _tmpl_to_atype
1069 */
1070#define tmpl_aexpand(_ctx, _out, _request, _vpt, _escape, _escape_ctx) \
1071 _tmpl_to_atype(_ctx, (void *)(_out), _request, _vpt, _escape, _escape_ctx, FR_TYPE_FROM_PTR(_out))
1072
1073/** Expand a tmpl to a C type, allocing a new buffer to hold the string
1074 *
1075 * Takes an explicit type which must match the ctype pointed to by out.
1076 *
1077 * @see _tmpl_to_atype
1078 */
1079#define tmpl_aexpand_type(_ctx, _out, _type, _request, _vpt, _escape, _escape_ctx) \
1080 _tmpl_to_atype(_ctx, (void *)(_out), _request, _vpt, _escape, _escape_ctx, _type)
1081
1082void tmpl_debug(tmpl_t const *vpt) CC_HINT(nonnull);
1083
1085
1086fr_packet_t *tmpl_packet_ptr(request_t *request, fr_dict_attr_t const *list) CC_HINT(nonnull);
1087
1088TALLOC_CTX *tmpl_list_ctx(request_t *request, fr_dict_attr_t const *list);
1089
1091
1092tmpl_t *tmpl_init_printf(tmpl_t *vpt, tmpl_type_t type, fr_token_t quote, char const *fmt, ...) CC_HINT(nonnull(1,4));
1093
1095 char const *name, ssize_t len,
1096 tmpl_rules_t const *t_rules) CC_HINT(nonnull(1,4));
1097
1099 char const *name, ssize_t len,
1100 tmpl_rules_t const *t_rules) CC_HINT(nonnull(1,4));
1101
1102tmpl_t *tmpl_alloc(TALLOC_CTX *ctx, tmpl_type_t type, fr_token_t quote, char const *name, ssize_t len);
1103
1104/** @name Parse request qualifiers
1105 *
1106 * @{
1107 */
1108/** Static default request ref list for the current request
1109 *
1110 * Passed as request_def in tmpl_attr_rules_t.
1111 */
1112extern FR_DLIST_HEAD(tmpl_request_list) tmpl_request_def_current;
1113
1114/** Static default request ref list for the outer request
1115 *
1116 * Passed as request_def in tmpl_attr_rules_t.
1117 */
1118extern FR_DLIST_HEAD(tmpl_request_list) tmpl_request_def_outer;
1119
1120/** Static default request ref list for the parent request
1121 *
1122 * Passed as request_def in tmpl_attr_rules_t.
1123 */
1124extern FR_DLIST_HEAD(tmpl_request_list) tmpl_request_def_parent;
1125
1126int tmpl_request_ptr(request_t **request, FR_DLIST_HEAD(tmpl_request_list) const *rql) CC_HINT(nonnull);
1127
1128void tmpl_request_ref_list_debug(FR_DLIST_HEAD(tmpl_request_list) const *rql);
1129
1130int8_t tmpl_request_ref_list_cmp(FR_DLIST_HEAD(tmpl_request_list) const *a,
1131 FR_DLIST_HEAD(tmpl_request_list) const *b);
1132
1133/** Returns true if the specified qualifier list points to the current request
1134 *
1135 * @param[in] _list to check.
1136 * @return
1137 * - true if the list only contains a current request qualifier.
1138 * - false otherwise.
1139 */
1140#define tmpl_request_ref_is_current(_list) (tmpl_request_ref_list_cmp(_list, &tmpl_request_def_current) == 0)
1141
1142/** Returns true if the specified qualifier list points to the parent request
1143 *
1144 * @param[in] _list to check.
1145 * @return
1146 * - true if the list only contains a parent request qualifier.
1147 * - false otherwise.
1148 */
1149#define tmpl_request_ref_is_parent(_list) (tmpl_request_ref_list_cmp(_list, &tmpl_request_def_parent) == 0)
1150
1151/** Returns true if the specified qualifier list points to the outer request
1152 *
1153 * @param[in] _list to check.
1154 * @return
1155 * - true if the list only contains a outer request qualifier.
1156 * - false otherwise.
1157 */
1158#define tmpl_request_ref_is_outer(_list) (tmpl_request_ref_list_cmp(_list, &tmpl_request_def_outer) == 0)
1159
1160
1162 FR_DLIST_HEAD(tmpl_request_list) _CONST **out,
1163 fr_sbuff_t *in);
1164/** @} */
1165
1166void tmpl_set_name_printf(tmpl_t *vpt, fr_token_t quote, char const *fmt, ...) CC_HINT(nonnull(1,3));
1167
1168void tmpl_set_name_shallow(tmpl_t *vpt, fr_token_t quote, char const *name, ssize_t len) CC_HINT(nonnull);
1169
1170void tmpl_set_name(tmpl_t *vpt, fr_token_t quote, char const *name, ssize_t len) CC_HINT(nonnull);
1171
1172void tmpl_set_dict_def(tmpl_t *vpt, fr_dict_t const *dict) CC_HINT(nonnull);
1173
1174void tmpl_set_escape(tmpl_t *vpt, tmpl_escape_t const *escape) CC_HINT(nonnull);
1175
1176void tmpl_set_xlat(tmpl_t *vpt, xlat_exp_head_t *xlat) CC_HINT(nonnull);
1177
1178int tmpl_afrom_value_box(TALLOC_CTX *ctx, tmpl_t **out, fr_value_box_t *data, bool steal) CC_HINT(nonnull);
1179
1180void tmpl_attr_ref_debug(const tmpl_attr_t *ar, int idx) CC_HINT(nonnull);
1181
1182void tmpl_attr_ref_list_debug(FR_DLIST_HEAD(tmpl_attr_list) const *ar_head) CC_HINT(nonnull);
1183
1184void tmpl_attr_debug(tmpl_t const *vpt) CC_HINT(nonnull);
1185
1186int tmpl_attr_copy(tmpl_t *dst, tmpl_t const *src) CC_HINT(nonnull);
1187
1188int tmpl_attr_set_da(tmpl_t *vpt, fr_dict_attr_t const *da) CC_HINT(nonnull);
1189
1190int tmpl_attr_set_leaf_da(tmpl_t *vpt, fr_dict_attr_t const *da) CC_HINT(nonnull);
1191
1192void tmpl_attr_rewrite_leaf_num(tmpl_t *vpt, int16_t num) CC_HINT(nonnull);
1193
1194void tmpl_attr_set_request_ref(tmpl_t *vpt, FR_DLIST_HEAD(tmpl_request_list) const *request_def) CC_HINT(nonnull);
1195
1196void tmpl_attr_set_list(tmpl_t *vpt, fr_dict_attr_t const *list) CC_HINT(nonnull);
1197
1198int tmpl_attr_afrom_list(TALLOC_CTX *ctx, tmpl_t **out, tmpl_t const *list,
1199 fr_dict_attr_t const *da) CC_HINT(nonnull);
1200
1201/** @name Produce a #tmpl_t from a string or substring
1202 *
1203 * @{
1204 */
1207 fr_sbuff_parse_rules_t const *p_rules,
1208 tmpl_rules_t const *t_rules) CC_HINT(nonnull(3,4));
1209
1211 tmpl_t **out, char const *name,
1212 tmpl_rules_t const *rules) CC_HINT(nonnull (3, 4));
1213
1214ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out,
1215 fr_sbuff_t *in,
1216 fr_token_t quote,
1217 fr_sbuff_parse_rules_t const *p_rules,
1218 tmpl_rules_t const *t_rules) CC_HINT(nonnull(2,3));
1219
1220tmpl_t *tmpl_copy(TALLOC_CTX *ctx, tmpl_t const *in) CC_HINT(nonnull);
1221
1222ssize_t tmpl_cast_from_substr(tmpl_rules_t *t_rules, fr_sbuff_t *in) CC_HINT(nonnull(2)); /* Parses cast string */
1223
1224int tmpl_cast_set(tmpl_t *vpt, fr_type_t type) CC_HINT(nonnull); /* Sets cast type */
1225
1227{
1228 return vpt->rules.cast;
1229}
1230
1231#ifdef HAVE_REGEX
1232ssize_t tmpl_regex_flags_substr(tmpl_t *vpt, fr_sbuff_t *in,
1233 fr_sbuff_term_t const *terminals) CC_HINT(nonnull(1,2));
1234#endif
1235/** @} */
1236
1237/** @name Change a #tmpl_t type, usually by casting or resolving a reference
1238 * @{
1239 */
1240int tmpl_cast_in_place(tmpl_t *vpt, fr_type_t type, fr_dict_attr_t const *enumv) CC_HINT(nonnull(1));
1241
1242int tmpl_resolve(tmpl_t *vpt, tmpl_res_rules_t const *tr_rules) CC_HINT(nonnull(1));
1243
1244void tmpl_unresolve(tmpl_t *vpt) CC_HINT(nonnull);
1245
1246int tmpl_attr_to_xlat(TALLOC_CTX *ctx, tmpl_t **vpt_p) CC_HINT(nonnull);
1247
1248void tmpl_attr_to_raw(tmpl_t *vpt) CC_HINT(nonnull);
1249
1251
1253 fr_type_t type, fr_dict_attr_flags_t const *flags) CC_HINT(nonnull(1));
1254
1255#ifdef HAVE_REGEX
1256ssize_t tmpl_regex_compile(tmpl_t *vpt, bool subcaptures) CC_HINT(nonnull);
1257#endif
1258/** @} */
1259
1260/** @name Print the contents of a #tmpl_t
1261 * @{
1262 */
1263fr_slen_t tmpl_request_ref_list_print(fr_sbuff_t *out, FR_DLIST_HEAD(tmpl_request_list) const *rql)
1264 CC_HINT(nonnull(1,2));
1265
1266static inline fr_slen_t tmpl_request_ref_list_aprint(TALLOC_CTX *ctx, char **out, FR_DLIST_HEAD(tmpl_request_list) const *rql)
1268
1270
1271static inline fr_slen_t tmpl_attr_aprint(TALLOC_CTX *ctx, char **out, tmpl_t const *vpt, tmpl_attr_prefix_t ar_prefix)
1273
1275 tmpl_attr_prefix_t ar_prefix, fr_sbuff_escape_rules_t const *e_rules) CC_HINT(nonnull(1,2));
1276
1277static inline fr_slen_t tmpl_aprint(TALLOC_CTX *ctx, char **out, tmpl_t const *vpt,
1280
1282
1283static inline fr_slen_t tmpl_aprint_quoted(TALLOC_CTX *ctx, char **out, tmpl_t const *vpt, tmpl_attr_prefix_t ar_prefix)
1285/** @} */
1286
1287/** @name Expand the tmpl, returning one or more values
1288 * @{
1289 */
1291
1293 uint8_t *buff, size_t outlen,
1294 request_t *request,
1295 tmpl_t const *vpt,
1296 xlat_escape_legacy_t escape, void const *escape_ctx,
1297 fr_type_t dst_type)
1298 CC_HINT(nonnull (1, 4, 5));
1299
1300ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
1301 request_t *request,
1302 tmpl_t const *vpt,
1303 xlat_escape_legacy_t escape, void const *escape_ctx,
1304 fr_type_t dst_type)
1305 CC_HINT(nonnull (2, 3, 4));
1306
1307int tmpl_copy_pairs(TALLOC_CTX *ctx, fr_pair_list_t *out,
1308 request_t *request, tmpl_t const *vpt) CC_HINT(nonnull(2,3,4));
1309
1310int tmpl_copy_pair_children(TALLOC_CTX *ctx, fr_pair_list_t *out,
1311 request_t *request, tmpl_t const *vpt) CC_HINT(nonnull(2,3,4));
1312
1313int tmpl_find_vp(fr_pair_t **out, request_t *request, tmpl_t const *vpt) CC_HINT(nonnull(2,3));
1314
1315int tmpl_find_or_add_vp(fr_pair_t **out, request_t *request, tmpl_t const *vpt) CC_HINT(nonnull);
1316
1317int pair_append_by_tmpl_parent(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list,
1318 tmpl_t const *vpt, bool skip_list) CC_HINT(nonnull(1,3,4));
1319
1320int tmpl_extents_find(TALLOC_CTX *ctx,
1321 fr_dlist_head_t *leaf, fr_dlist_head_t *interior,
1322 request_t *request, tmpl_t const *vpt) CC_HINT(nonnull(5));
1323
1325 tmpl_t const *vpt) CC_HINT(nonnull);
1326
1328
1329int tmpl_eval_pair(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt);
1330
1331int tmpl_eval(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt);
1332
1333int tmpl_eval_cast_in_place(fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt);
1334/** @} */
1335
1336ssize_t tmpl_preparse(char const **out, size_t *outlen, char const *in, size_t inlen,
1337 fr_token_t *type) CC_HINT(nonnull(1,2,3,5));
1338
1339bool tmpl_async_required(tmpl_t const *vpt) CC_HINT(nonnull);
1340
1341int tmpl_value_list_insert_tail(fr_value_box_list_t *list, fr_value_box_t *vb, tmpl_t const *vpt) CC_HINT(nonnull);
1342
1343void tmpl_rules_child_init(TALLOC_CTX *ctx, tmpl_rules_t *out, tmpl_rules_t const *parent, tmpl_t *vpt) CC_HINT(nonnull);
1344
1345void tmpl_rules_debug(tmpl_rules_t const *rules) CC_HINT(nonnull);
1346
1347int tmpl_global_init(void);
1348
1349#undef _CONST
1350
1351#ifdef __cplusplus
1352}
1353#endif
int const char * file
Definition acutest.h:702
static int const char * fmt
Definition acutest.h:573
int const char int line
Definition acutest.h:702
#define RCSIDH(h, id)
Definition build.h:484
#define unlikely(_x)
Definition build.h:381
static fr_slen_t err
Definition dict.h:824
static fr_slen_t in
Definition dict.h:824
Values of the encryption flags.
#define FR_DLIST_TYPES(_name)
Define type specific wrapper structs for dlists.
Definition dlist.h:1129
#define FR_DLIST_FUNCS(_name, _element_type, _element_entry)
Define type specific wrapper functions for dlists.
Definition dlist.h:1152
#define FR_DLIST_HEAD(_name)
Expands to the type name used for the head wrapper structure.
Definition dlist.h:1122
Head of a doubly linked list.
Definition dlist.h:51
Entry in a doubly linked list.
Definition dlist.h:41
Stores all information relating to an event list.
Definition event.c:411
tmpl_attr_prefix_t
size_t(* xlat_escape_legacy_t)(request_t *request, char *out, size_t outlen, char const *in, void *arg)
fr_type_t
long int ssize_t
unsigned char uint8_t
ssize_t fr_slen_t
#define fr_assert(_expr)
Definition rad_assert.h:38
fr_dict_attr_t const * request_attr_request
Definition request.c:45
fr_dict_attr_t const * request_attr_control
Definition request.c:47
fr_dict_attr_t const * request_attr_local
Definition request.c:49
fr_dict_attr_t const * request_attr_state
Definition request.c:48
fr_dict_attr_t const * request_attr_reply
Definition request.c:46
static char const * name
#define SBUFF_OUT_TALLOC_FUNC_NO_LEN_DEF(_func,...)
Set of terminal elements.
int8_t tmpl_request_ref_list_cmp(FR_DLIST_HEAD(tmpl_request_list) const *a, FR_DLIST_HEAD(tmpl_request_list) const *b)
Compare a list of request qualifiers.
int tmpl_find_vp(fr_pair_t **out, request_t *request, tmpl_t const *vpt))
Returns the first VP matching a tmpl_t.
Definition tmpl_eval.c:889
static fr_slen_t tmpl_attr_aprint(TALLOC_CTX *ctx, char **out, tmpl_t const *vpt, tmpl_attr_prefix_t ar_prefix) 1(tmpl_attr_print
void tmpl_request_ref_list_debug(FR_DLIST_HEAD(tmpl_request_list) const *rql)
Dump a request list to stderr.
static fr_slen_t ar_prefix
Definition tmpl.h:1279
static tmpl_attr_t const * tmpl_attr_tail(tmpl_t const *vpt)
Return the last attribute reference.
Definition tmpl.h:801
static int16_t tmpl_attr_tail_num(tmpl_t const *vpt)
Return the last attribute reference's attribute number.
Definition tmpl.h:896
void tmpl_attr_set_list(tmpl_t *vpt, fr_dict_attr_t const *list)
tmpl_attr_prefix_t
Specify whether attribute references require a prefix.
Definition tmpl.h:264
@ TMPL_ATTR_REF_PREFIX_NO
Attribute refs have no '&' prefix.
Definition tmpl.h:266
@ TMPL_ATTR_REF_PREFIX_AUTO
Attribute refs may have a '&' prefix.
Definition tmpl.h:267
@ TMPL_ATTR_REF_PREFIX_YES
Attribute refs must have '&' prefix.
Definition tmpl.h:265
#define ar_is_unspecified(_ar)
Definition tmpl.h:515
static char const * tmpl_type_to_str(tmpl_type_t type)
Return a static string containing the type name.
Definition tmpl.h:645
void tmpl_unresolve(tmpl_t *vpt)
Reset the tmpl, leaving only the name in place.
#define tmpl_is_attr_unresolved(vpt)
Definition tmpl.h:224
enum requests_ref_e tmpl_request_ref_t
void tmpl_set_name_printf(tmpl_t *vpt, fr_token_t quote, char const *fmt,...))
Set the name on a pre-initialised tmpl.
static bool tmpl_attr_tail_is_unspecified(tmpl_t const *vpt)
Return true if the last attribute reference is "unspecified".
Definition tmpl.h:737
void tmpl_set_xlat(tmpl_t *vpt, xlat_exp_head_t *xlat)
Change the default dictionary in the tmpl's resolution rules.
void tmpl_attr_set_request_ref(tmpl_t *vpt, FR_DLIST_HEAD(tmpl_request_list) const *request_def)
Set the request for an attribute ref.
int tmpl_attr_set_da(tmpl_t *vpt, fr_dict_attr_t const *da)
Replace the current attribute reference.
fr_packet_t * tmpl_packet_ptr(request_t *request, fr_dict_attr_t const *list)
Resolve a list to the fr_packet_t holding the HEAD pointer for a fr_pair_t list.
Definition tmpl_eval.c:146
static fr_slen_t tmpl_aprint(TALLOC_CTX *ctx, char **out, tmpl_t const *vpt, tmpl_attr_prefix_t ar_prefix, fr_sbuff_escape_rules_t const *e_rules) 1(tmpl_print
static fr_slen_t vpt
Definition tmpl.h:1272
tmpl_escape_t escape
How escaping should be handled during evaluation.
Definition tmpl.h:358
static bool tmpl_attr_tail_is_normal(tmpl_t const *vpt)
Return true if the last attribute reference is "normal".
Definition tmpl.h:721
tmpl_t * tmpl_init(tmpl_t *vpt, tmpl_type_t type, fr_token_t quote, char const *name, ssize_t len, tmpl_rules_t const *t_rules))
Initialise a tmpl using a literal string to create the name.
int tmpl_resolve(tmpl_t *vpt, tmpl_res_rules_t const *tr_rules))
Attempt to resolve functions and attributes in xlats and attribute references.
TALLOC_CTX * list_ctx
Where to allocate new attributes if building out from the current extents of the tree.
Definition tmpl.h:621
fr_table_num_sorted_t const tmpl_request_ref_table[]
Map keywords to tmpl_request_ref_t values.
#define TMPL_FLAG_ATTR
Base data type is an attribute reference.
Definition tmpl.h:106
int tmpl_afrom_value_box(TALLOC_CTX *ctx, tmpl_t **out, fr_value_box_t *data, bool steal)
Create a tmpl_t from a fr_value_box_t.
#define ar_is_unknown(_ar)
Definition tmpl.h:516
tmpl_t * tmpl_alloc(TALLOC_CTX *ctx, tmpl_type_t type, fr_token_t quote, char const *name, ssize_t len)
Create a new heap allocated tmpl_t.
int tmpl_attr_unknown_add(tmpl_t *vpt)
Add an unknown fr_dict_attr_t specified by a tmpl_t to the main dictionary.
static bool tmpl_attr_tail_is_unknown(tmpl_t const *vpt)
Return true if the last attribute reference is "unknown".
Definition tmpl.h:753
int tmpl_extents_build_to_leaf_parent(fr_dlist_head_t *leaf, fr_dlist_head_t *interior, tmpl_t const *vpt)
Allocate interior pairs.
static tmpl_type_t tmpl_type_from_str(char const *type)
Return the constant value representing a type.
Definition tmpl.h:655
void tmpl_attr_ref_debug(const tmpl_attr_t *ar, int idx)
fr_value_box_safe_for_t literals_safe_for
safe_for value assigned to literal values in xlats, execs, and data.
Definition tmpl.h:356
void tmpl_set_escape(tmpl_t *vpt, tmpl_escape_t const *escape)
Set escape parameters for the tmpl output.
#define TMPL_FLAG_UNRESOLVED
Needs resolution.
Definition tmpl.h:121
#define ar_is_raw(_ar)
Definition tmpl.h:518
size_t pair_list_table_len
#define tmpl_is_attr(vpt)
Definition tmpl.h:213
bool tmpl_async_required(tmpl_t const *vpt)
Return whether or not async is required for this tmpl.
fr_dict_attr_t const * enumv
Enumeration attribute used to resolve enum values.
Definition tmpl.h:347
tmpl_rules_t const * parent
for parent / child relationships
Definition tmpl.h:342
void tmpl_rules_child_init(TALLOC_CTX *ctx, tmpl_rules_t *out, tmpl_rules_t const *parent, tmpl_t *vpt)
Initialize a set of rules from a parent set of rules, and a parsed tmpl_t.
static fr_dict_attr_t const * tmpl_list(tmpl_t const *vpt)
Definition tmpl.h:915
int16_t _CONST num
For array references.
Definition tmpl.h:422
static bool tmpl_attr_is_list_attr(tmpl_attr_t const *ar)
Return true if the tmpl_attr is one of the list types.
Definition tmpl.h:690
int tmpl_extents_find(TALLOC_CTX *ctx, fr_dlist_head_t *leaf, fr_dlist_head_t *interior, request_t *request, tmpl_t const *vpt))
Determines points where the reference list extends beyond the current pair tree.
ssize_t tmpl_afrom_attr_str(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t **out, char const *name, tmpl_rules_t const *rules))
Parse a string into a TMPL_TYPE_ATTR_* type tmpl_t.
static fr_slen_t tmpl_request_ref_list_aprint(TALLOC_CTX *ctx, char **out, FR_DLIST_HEAD(tmpl_request_list) const *rql) 1(tmpl_request_ref_list_print
int tmpl_eval_cast_in_place(fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt)
Casts a value or list of values according to the tmpl.
Definition tmpl_eval.c:1349
void tmpl_set_name(tmpl_t *vpt, fr_token_t quote, char const *name, ssize_t len)
Set the name on a pre-initialised tmpl.
tmpl_type_e
Types of tmpl_t.
Definition tmpl.h:131
@ TMPL_TYPE_REGEX_UNCOMPILED
Regex where compilation is possible but hasn't been performed yet.
Definition tmpl.h:162
@ TMPL_TYPE_MAX
Marker for the last tmpl type.
Definition tmpl.h:203
@ TMPL_TYPE_ATTR_UNRESOLVED
An attribute reference that we couldn't resolve but looked valid.
Definition tmpl.h:189
@ TMPL_TYPE_ATTR
Reference to one or more attributes.
Definition tmpl.h:146
@ TMPL_TYPE_XLAT
Pre-parsed xlat expansion.
Definition tmpl.h:150
@ TMPL_TYPE_NULL
Has no value.
Definition tmpl.h:138
@ TMPL_TYPE_EXEC
Callout to an external script or program.
Definition tmpl.h:154
@ TMPL_TYPE_REGEX_XLAT_UNRESOLVED
A regular expression with unresolved xlat functions or attribute references.
Definition tmpl.h:201
@ TMPL_TYPE_DATA
Value in native boxed format.
Definition tmpl.h:142
@ TMPL_TYPE_REGEX
Compiled (and possibly JIT'd) regular expression.
Definition tmpl.h:158
@ TMPL_TYPE_DATA_UNRESOLVED
Unparsed literal string.
Definition tmpl.h:183
@ TMPL_TYPE_XLAT_UNRESOLVED
A xlat expansion with unresolved xlat functions or attribute references.
Definition tmpl.h:197
@ TMPL_TYPE_REGEX_XLAT
A regex containing xlat expansions.
Definition tmpl.h:166
@ TMPL_TYPE_EXEC_UNRESOLVED
An exec with unresolved xlat function or attribute references.
Definition tmpl.h:193
@ TMPL_TYPE_UNINITIALISED
Uninitialised.
Definition tmpl.h:134
int tmpl_attr_afrom_list(TALLOC_CTX *ctx, tmpl_t **out, tmpl_t const *list, fr_dict_attr_t const *da)
Create a new tmpl from a list tmpl and a da.
void tmpl_attr_to_raw(tmpl_t *vpt)
Convert the leaf attribute of a tmpl to a unknown/raw type.
static bool tmpl_attr_tail_da_is_leaf(tmpl_t const *vpt)
Return true if the the last attribute reference is a leaf attribute.
Definition tmpl.h:828
#define tmpl_assert_type(_cond)
Convenience macro for printing a meaningful assert message when we get a bad tmpl type.
Definition tmpl.h:631
#define tmpl_contains_attr(vpt)
Definition tmpl.h:229
int tmpl_eval(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt)
Gets the value of a tmpl.
Definition tmpl_eval.c:1221
tmpl_t * tmpl_copy(TALLOC_CTX *ctx, tmpl_t const *in)
Copy a tmpl.
static bool tmpl_attr_tail_da_is_structural(tmpl_t const *vpt)
Return true if the the last attribute reference is a structural attribute.
Definition tmpl.h:846
int tmpl_copy_pairs(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, tmpl_t const *vpt))
Copy pairs matching a tmpl_t in the current request_t.
Definition tmpl_eval.c:798
ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out, request_t *request, tmpl_t const *vpt, xlat_escape_legacy_t escape, void const *escape_ctx, fr_type_t dst_type))
Expand a template to a string, allocing a new buffer to hold the string.
Definition tmpl_eval.c:563
#define TMPL_FLAG_REGEX
Is a type of regular expression.
Definition tmpl.h:116
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
static size_t tmpl_request_ref_count(tmpl_t const *vpt)
The number of request references contained within a tmpl.
Definition tmpl.h:678
TALLOC_CTX * tmpl_list_ctx(request_t *request, fr_dict_attr_t const *list)
Return the correct TALLOC_CTX to alloc fr_pair_t in, for a list.
Definition tmpl_eval.c:116
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_rules_t _CONST rules
The rules that were used when creating the tmpl.
Definition tmpl.h:604
static fr_slen_t e_rules fr_slen_t tmpl_print_quoted(fr_sbuff_t *out, tmpl_t const *vpt, tmpl_attr_prefix_t ar_prefix)
Print a tmpl_t to a string with quotes.
fr_dlist_t entry
Entry in the dlist of extents.
Definition tmpl.h:613
int tmpl_global_init(void)
Definition tmpl_eval.c:1485
tmpl_xlat_rules_t xlat
Rules/data for parsing xlats.
Definition tmpl.h:345
static char const * tmpl_attr_tail_unresolved(tmpl_t const *vpt)
Return the last attribute reference unresolved da.
Definition tmpl.h:880
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
static fr_slen_t rql fr_slen_t tmpl_attr_print(fr_sbuff_t *out, tmpl_t const *vpt, tmpl_attr_prefix_t ar_prefix))
Print an attribute or list tmpl_t to a string.
static fr_slen_t tmpl_aprint_quoted(TALLOC_CTX *ctx, char **out, tmpl_t const *vpt, tmpl_attr_prefix_t ar_prefix) 1(tmpl_print_quoted
ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t **out, fr_sbuff_t *name, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Parse a string into a TMPL_TYPE_ATTR_* type tmpl_t.
bool new_functions
new function syntax
Definition tmpl.h:335
int tmpl_eval_pair(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt)
Gets the value of a real or virtual attribute.
Definition tmpl_eval.c:1077
static fr_slen_t ar_prefix fr_slen_t tmpl_print(fr_sbuff_t *out, tmpl_t const *vpt, tmpl_attr_prefix_t ar_prefix, fr_sbuff_escape_rules_t const *e_rules))
Print a tmpl_t to a string.
ssize_t _tmpl_to_type(void *out, uint8_t *buff, size_t outlen, request_t *request, tmpl_t const *vpt, xlat_escape_legacy_t escape, void const *escape_ctx, fr_type_t dst_type))
Expand a tmpl_t to a string writing the result to a buffer.
Definition tmpl_eval.c:284
int tmpl_cast_in_place(tmpl_t *vpt, fr_type_t type, fr_dict_attr_t const *enumv))
Convert tmpl_t of type TMPL_TYPE_DATA_UNRESOLVED or TMPL_TYPE_DATA to TMPL_TYPE_DATA of type specifie...
bool force_dict_def
Use supplied dict_def even if original vpt->rules->dict_def was not NULL.
Definition tmpl.h:379
void tmpl_debug(tmpl_t const *vpt)
void tmpl_set_name_shallow(tmpl_t *vpt, fr_token_t quote, char const *name, ssize_t len)
Set the name on a pre-initialised tmpl.
fr_dict_t const * dict_def
Alternative default dictionary to use if vpt->rules->dict_def is NULL.
Definition tmpl.h:374
static bool tmpl_attr_tail_is_unresolved(tmpl_t const *vpt)
Return true if the last attribute reference is "unresolved".
Definition tmpl.h:769
tmpl_type_t _CONST type
What type of value tmpl refers to.
Definition tmpl.h:557
#define _CONST
Definition tmpl.h:256
ssize_t tmpl_preparse(char const **out, size_t *outlen, char const *in, size_t inlen, fr_token_t *type))
Preparse a string in preparation for passing it to tmpl_afrom_substr()
static size_t tmpl_attr_num_elements(tmpl_t const *vpt)
The number of attribute references contained within a tmpl.
Definition tmpl.h:907
fr_slen_t tmpl_request_ref_list_afrom_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, FR_DLIST_HEAD(tmpl_request_list) _CONST **out, fr_sbuff_t *in)
fr_table_num_ordered_t const pair_list_table[]
#define tmpl_attr(_tmpl)
Definition tmpl.h:665
void tmpl_attr_rewrite_leaf_num(tmpl_t *vpt, int16_t num)
Rewrite the leaf's instance number.
void tmpl_attr_ref_list_debug(FR_DLIST_HEAD(tmpl_attr_list) const *ar_head)
static fr_type_t tmpl_cast_get(tmpl_t *vpt)
Definition tmpl.h:1226
int tmpl_request_ptr(request_t **request, FR_DLIST_HEAD(tmpl_request_list) const *rql)
Resolve a tmpl_request_ref_t to a request_t.
Definition tmpl_eval.c:169
char const *_CONST name
Raw string used to create the template.
Definition tmpl.h:559
tmpl_attr_error_t
Definition tmpl.h:1012
@ TMPL_ATTR_ERROR_INVALID_ARRAY_INDEX
Invalid array index.
Definition tmpl.h:1031
@ TMPL_ATTR_ERROR_LIST_NOT_ALLOWED
List qualifier is not allowed here.
Definition tmpl.h:1016
@ TMPL_ATTR_ERROR_INTERNAL_NOT_ALLOWED
Attribute resolved to an internal attribute which is disallowed.
Definition tmpl.h:1026
@ TMPL_ATTR_ERROR_UNRESOLVED_NOT_ALLOWED
Attribute couldn't be found in the dictionaries.
Definition tmpl.h:1022
@ TMPL_ATTR_ERROR_INVALID_FILTER
Invalid filter.
Definition tmpl.h:1032
@ TMPL_ATTR_ERROR_BAD_CAST
Specified cast was invalid.
Definition tmpl.h:1035
@ TMPL_ATTR_ERROR_INVALID_NAME
Attribute ref length is zero, or longer than the maximum.
Definition tmpl.h:1024
@ TMPL_ATTR_ERROR_UNQUALIFIED_NOT_ALLOWED
Attribute must be qualified to be used here.
Definition tmpl.h:1023
@ TMPL_ATTR_ERROR_MISSING_TERMINATOR
Unexpected text found after attribute reference.
Definition tmpl.h:1034
@ TMPL_ATTR_ERROR_LIST_MISSING
List qualifier is required, but missing.
Definition tmpl.h:1017
@ TMPL_ATTR_ERROR_NONE
No error.
Definition tmpl.h:1013
@ TMPL_ATTR_ERROR_FOREIGN_NOT_ALLOWED
Attribute resolved in a dictionary different to the one specified.
Definition tmpl.h:1028
@ TMPL_ATTR_ERROR_UNKNOWN_NOT_ALLOWED
Attribute specified as OID, could not be found in the dictionaries, and is disallowed because 'disall...
Definition tmpl.h:1018
@ TMPL_ATTR_ERROR_FILTER_NOT_ALLOWED
Filters disallowed by rules.
Definition tmpl.h:1030
@ TMPL_ATTR_ERROR_EMPTY
Attribute ref contains no data.
Definition tmpl.h:1014
@ TMPL_ATTR_ERROR_NESTING_TOO_DEEP
Too many levels of nesting.
Definition tmpl.h:1033
@ TMPL_ATTR_ERROR_BAD_PREFIX
Missing '&' or has '&' when it shouldn't.
Definition tmpl.h:1015
fr_type_t cast
Whether there was an explicit cast.
Definition tmpl.h:349
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
Definition tmpl.h:344
union tmpl_s::@86 data
void tmpl_rules_debug(tmpl_rules_t const *rules)
int tmpl_attr_copy(tmpl_t *dst, tmpl_t const *src)
Copy a list of attribute and request references from one tmpl to another.
fr_pair_list_t * list
List that we tried to evaluate ar in and failed.
Definition tmpl.h:623
tmpl_t * tmpl_init_printf(tmpl_t *vpt, tmpl_type_t type, fr_token_t quote, char const *fmt,...))
Initialise a tmpl using a format string to create the name.
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
Definition tmpl.h:812
tmpl_attr_list_presence_t
Specify whether attribute references can have a list (or parent) reference.
Definition tmpl.h:273
@ TMPL_ATTR_LIST_REQUIRE
Attribute refs are required to have a list.
Definition tmpl.h:276
@ TMPL_ATTR_LIST_ALLOW
Attribute refs are allowed to have a list.
Definition tmpl.h:274
@ TMPL_ATTR_LIST_FORBID
Attribute refs are forbidden from having a list.
Definition tmpl.h:275
void tmpl_extents_debug(fr_dlist_head_t *head)
#define ar_is_unresolved(_ar)
Definition tmpl.h:517
static bool tmpl_attr_head_is_list(tmpl_t const *vpt)
Return true if the head attribute reference is a list reference.
Definition tmpl.h:705
enum tmpl_type_e tmpl_type_t
Types of tmpl_t.
size_t tmpl_type_table_len
struct tmpl_literal_rules_s tmpl_literal_rules_t
Definition tmpl.h:239
#define ar_is_normal(_ar)
Definition tmpl.h:514
int tmpl_attr_set_leaf_da(tmpl_t *vpt, fr_dict_attr_t const *da)
Replace the leaf attribute only.
static fr_dict_attr_t const * tmpl_attr_tail_unknown(tmpl_t const *vpt)
Return the last attribute reference unknown da.
Definition tmpl.h:864
static char const * tmpl_list_name(fr_dict_attr_t const *list, char const *def)
Return the name of a tmpl list or def if list not provided.
Definition tmpl.h:926
static bool tmpl_attr_tail_is_raw(tmpl_t const *vpt)
Return true if the last attribute reference is "raw".
Definition tmpl.h:785
requests_ref_e
Definition tmpl.h:90
@ REQUEST_OUTER
request_t containing the outer layer of the EAP conversation.
Definition tmpl.h:92
@ REQUEST_PARENT
Parent (whatever it is).
Definition tmpl.h:96
@ REQUEST_UNKNOWN
Unknown request.
Definition tmpl.h:97
@ REQUEST_CURRENT
The current request (default).
Definition tmpl.h:91
fr_slen_t tmpl_request_ref_list_print(fr_sbuff_t *out, FR_DLIST_HEAD(tmpl_request_list) const *rql))
int tmpl_find_or_add_vp(fr_pair_t **out, request_t *request, tmpl_t const *vpt)
Returns the first VP matching a tmpl_t, or if no VPs match, creates a new one.
Definition tmpl_eval.c:918
int tmpl_value_list_insert_tail(fr_value_box_list_t *list, fr_value_box_t *vb, tmpl_t const *vpt)
Insert a value-box to a list, with casting.
Definition tmpl_eval.c:1052
void tmpl_set_dict_def(tmpl_t *vpt, fr_dict_t const *dict)
Change the default dictionary in the tmpl's resolution rules.
int tmpl_attr_tail_unresolved_add(fr_dict_t *dict, tmpl_t *vpt, fr_type_t type, fr_dict_attr_flags_t const *flags))
Add an unresolved fr_dict_attr_t specified by a tmpl_t to the main dictionary.
int tmpl_copy_pair_children(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, tmpl_t const *vpt))
Copy children of pairs matching a tmpl_t in the current request_t.
Definition tmpl_eval.c:841
fr_dict_attr_t const * enumv
for resolving T_BARE_WORD
Definition tmpl.h:382
size_t _CONST len
Length of the raw string used to create the template.
Definition tmpl.h:561
ssize_t tmpl_cast_from_substr(tmpl_rules_t *t_rules, fr_sbuff_t *in))
Parse a cast specifier.
int pair_append_by_tmpl_parent(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, tmpl_t const *vpt, bool skip_list))
Allocate and insert a leaf vp from a tmpl_t, building the parent vps if needed.
Definition tmpl_eval.c:974
tmpl_attr_type_t
Definition tmpl.h:385
@ TMPL_ATTR_TYPE_UNSPEC
No attribute was specified as this level only a filter.
Definition tmpl.h:387
@ TMPL_ATTR_TYPE_NORMAL
Normal, resolved, attribute ref.
Definition tmpl.h:386
@ TMPL_ATTR_TYPE_UNKNOWN
We have an attribute number but it doesn't match anything in the dictionary, or isn't a child of the ...
Definition tmpl.h:389
@ TMPL_ATTR_TYPE_UNRESOLVED
We have a name, but nothing else to identify the attribute.
Definition tmpl.h:394
#define TMPL_FLAG_XLAT
Base data type is an xlat expansion.
Definition tmpl.h:111
tmpl_attr_t const * ar
Attribute representing the ar after the deepest node that was found in the existing pair tree when ev...
Definition tmpl.h:615
int tmpl_attr_to_xlat(TALLOC_CTX *ctx, tmpl_t **vpt_p)
Convert an attribute reference to an xlat expansion.
fr_slen_t tmpl_attr_list_from_substr(fr_dict_attr_t const **da_p, fr_sbuff_t *in)
Parse one a single list reference.
tmpl_attr_filter_type_t
Define entry and head types for attribute reference lists.
Definition tmpl.h:412
@ TMPL_ATTR_FILTER_TYPE_TMPL
Filter is a tmpl.
Definition tmpl.h:416
@ TMPL_ATTR_FILTER_TYPE_INDEX
Filter is an index type.
Definition tmpl.h:414
@ TMPL_ATTR_FILTER_TYPE_CONDITION
Filter is a condition.
Definition tmpl.h:415
@ TMPL_ATTR_FILTER_TYPE_NONE
No filter present.
Definition tmpl.h:413
@ TMPL_ATTR_FILTER_TYPE_EXPR
Filter is an expression.
Definition tmpl.h:417
fr_event_list_t * runtime_el
The eventlist to use for runtime instantiation of xlats.
Definition tmpl.h:333
fr_table_num_ordered_t const tmpl_type_table[]
Map tmpl_type_t values to descriptive strings.
int tmpl_cast_set(tmpl_t *vpt, fr_type_t type)
Set a cast for a tmpl.
fr_token_t _CONST quote
What type of quoting was around the raw string.
Definition tmpl.h:562
void tmpl_attr_debug(tmpl_t const *vpt)
tmpl_t * tmpl_init_shallow(tmpl_t *vpt, tmpl_type_t type, fr_token_t quote, char const *name, ssize_t len, tmpl_rules_t const *t_rules))
Initialise a tmpl without copying the input name string.
fr_type_t tmpl_expanded_type(tmpl_t const *vpt)
Return the native data type of the expression.
Definition tmpl_eval.c:209
tmpl_attr_filter_type_t _CONST type
Type of filter this is.
Definition tmpl.h:421
size_t tmpl_request_ref_table_len
Describes the current extents of a pair tree in relation to the tree described by a tmpl_t.
Definition tmpl.h:612
Similar to tmpl_rules_t, but used to specify parameters that may change during subsequent resolution ...
Definition tmpl.h:373
Optional arguments passed to vp_tmpl functions.
Definition tmpl.h:341
A source or sink of value data.
Definition tmpl.h:556
static char buff[sizeof("18446744073709551615")+3]
Definition size_tests.c:41
fr_aka_sim_id_type_t type
Define entry and head types for tmpl request references.
Definition tmpl.h:284
tmpl_attr_list_presence_t list_presence
Whether the attribute reference can have a list, forbid it, or require it.
Definition tmpl.h:313
fr_dict_attr_t const * list_def
Default list to use with unqualified attribute reference.
Definition tmpl.h:307
uint8_t disallow_filters
disallow filters.
Definition tmpl.h:329
uint8_t allow_unresolved
Allow attributes that look valid but were not found in the dictionaries.
Definition tmpl.h:319
uint8_t allow_foreign
Allow arguments not found in dict_def.
Definition tmpl.h:327
fr_dict_t const * dict_def
Default dictionary to use with unqualified attribute references.
Definition tmpl.h:285
FR_DLIST_HEAD(tmpl_request_list) _CONST *request_def
< Point in dictionary tree to resume parsing from.
uint8_t allow_wildcard
Allow the special case of .
Definition tmpl.h:324
uint8_t allow_unknown
Allow unknown attributes i.e.
Definition tmpl.h:316
tmpl_attr_prefix_t prefix
Whether the attribute reference requires a prefix.
Definition tmpl.h:310
An element in a list of nested attribute references.
Definition tmpl.h:439
unsigned int _CONST resolve_only
This reference and those before it.
Definition tmpl.h:462
unsigned int _CONST is_raw
Definition tmpl.h:465
fr_dict_attr_t const *_CONST da
Resolved dictionary attribute.
Definition tmpl.h:443
fr_dict_attr_t const *_CONST parent
The parent we used when trying to resolve the attribute originally.
Definition tmpl.h:457
FR_DLIST_ENTRY(tmpl_attr_list) _CONST entry
Entry in the doubly linked list of attribute references.
tmpl_attr_filter_t _CONST filter
Filter associated with the attribute reference.
Definition tmpl.h:469
tmpl_attr_type_t _CONST type
is a raw reference
Definition tmpl.h:467
Define manipulation functions for the attribute reference list.
Definition tmpl.h:480
FR_DLIST_ENTRY(tmpl_request_list) _CONST entry
Entry in the doubly linked list of request references.
tmpl_request_ref_t _CONST request
Definition tmpl.h:484
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
Definition table.h:653
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition table.h:772
An element in an arbitrarily ordered array of name to num mappings.
Definition table.h:57
An element in a lexicographically sorted array of name to num mappings.
Definition table.h:49
Escaping rules for tmpls.
Definition tmpl_escape.h:80
enum fr_token fr_token_t
static fr_slen_t head
Definition xlat.h:422
static fr_slen_t parent
Definition pair.h:851
#define fr_type_is_structural(_x)
Definition types.h:371
#define fr_type_is_leaf(_x)
Definition types.h:372
static fr_slen_t data
Definition value.h:1265
static size_t char fr_sbuff_t size_t inlen
Definition value.h:997
uintptr_t fr_value_box_safe_for_t
Escaping that's been applied to a value box.
Definition value.h:155
int nonnull(2, 5))
static size_t char ** out
Definition value.h:997