The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 5104a0071413c011e1d4bda01d057536b1e69dc7 $
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  */
70 RCSIDH(tmpl_h, "$Id: 5104a0071413c011e1d4bda01d057536b1e69dc7 $")
71 
72 #ifdef __cplusplus
73 extern "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 
88 extern size_t pair_list_table_len;
89 
90 typedef 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 
101 extern 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  */
131 typedef 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  */
138  TMPL_TYPE_NULL = 0x0001,
139 
140  /** Value in native boxed format
141  */
142  TMPL_TYPE_DATA = 0x0002,
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 
234 extern size_t tmpl_type_table_len;
235 
236 typedef struct tmpl_rules_s tmpl_rules_t;
237 typedef struct tmpl_attr_rules_s tmpl_attr_rules_t;
238 typedef struct tmpl_xlat_rules_s tmpl_xlat_rules_t;
239 typedef struct tmpl_literal_rules_s tmpl_literal_rules_t;
240 typedef struct tmpl_res_rules_s tmpl_res_rules_t;
241 typedef 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  */
264 typedef 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  */
273 typedef 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  */
282 FR_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  */
341 struct tmpl_rules_s {
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 
385 typedef 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  */
407 FR_DLIST_TYPES(tmpl_attr_list)
408 
409 /** Different types of filter that can be applied to an attribute reference
410  *
411  */
412 typedef 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
417 
418 typedef struct {
419  tmpl_attr_filter_type_t _CONST type; //!< Type of filter this is.
420  int16_t _CONST num; //!< For array references.
421  xlat_exp_head_t _CONST *cond; //!< xlat condition
423 
424 /** An element in a list of nested attribute references
425  *
426  */
427 typedef struct {
428  FR_DLIST_ENTRY(tmpl_attr_list) _CONST entry; //!< Entry in the doubly linked list
429  ///< of attribute references.
430 
431  fr_dict_attr_t const * _CONST da; //!< Resolved dictionary attribute.
432 
433  union {
434  struct {
435  fr_dict_attr_t * _CONST da; //!< Unknown dictionary attribute.
436  } unknown;
437 
438  struct {
439  char * _CONST name; //!< Undefined reference type.
440  fr_dict_attr_t const * _CONST namespace; //!< Namespace we should be trying
441  ///< to resolve this attribute in.
442  } unresolved;
443  };
444 
445  fr_dict_attr_t const * _CONST parent; //!< The parent we used when trying to
446  ///< resolve the attribute originally.
447  ///< Should point to the referenced
448  ///< attribute.
449 
450  unsigned int _CONST resolve_only : 1; //!< This reference and those before it
451  ///< in the list can only be used for
452  ///< resolution, not building out trees.
453  unsigned int _CONST is_raw : 1; /// is a raw reference
454 
455  tmpl_attr_type_t _CONST type; //!< Type of attribute reference.
456 
457  tmpl_attr_filter_t _CONST filter; //!< Filter associated with the attribute reference.
458 } tmpl_attr_t;
459 
460 /** Define manipulation functions for the attribute reference list
461  *
462  */
463 FR_DLIST_FUNCS(tmpl_attr_list, tmpl_attr_t, entry)
464 
465 /** An element in a list of request references
466  *
467  */
468 typedef struct {
469  FR_DLIST_ENTRY(tmpl_request_list) _CONST entry; //!< Entry in the doubly linked list
470  ///< of request references.
471 
474 
475 /** Define manipulation functions for the attribute reference list
476  *
477  */
478 FR_DLIST_FUNCS(tmpl_request_list, tmpl_request_t, entry)
479 
480 /** How many additional headers to allocate in a pool for a tmpl_t
481  *
482  */
483 #define TMPL_POOL_DEF_HEADERS 4
484 
485 /** How many additional bytes to allocate in a pool for a tmpl_t
486  *
487  */
488 #define TMPL_POOL_DEF_LEN (sizeof(tmpl_t) + 64 + sizeof(tmpl_attr_t) + sizeof(tmpl_request_t))
489 
490 /** @name Field accessors for attribute references
491  *
492  * @{
493  */
494 #define ar_type type
495 #define ar_depth depth
496 #define ar_da da
497 #define ar_parent parent
498 #define ar_unknown unknown.da
499 #define ar_unresolved unresolved.name
500 #define ar_unresolved_namespace unresolved.namespace
501 
502 #define ar_is_normal(_ar) ((_ar)->ar_type == TMPL_ATTR_TYPE_NORMAL)
503 #define ar_is_unspecified(_ar) ((_ar)->ar_type == TMPL_ATTR_TYPE_UNSPEC)
504 #define ar_is_unknown(_ar) ((_ar)->ar_type == TMPL_ATTR_TYPE_UNKNOWN)
505 #define ar_is_unresolved(_ar) ((_ar)->ar_type == TMPL_ATTR_TYPE_UNRESOLVED)
506 #define ar_is_raw(_ar) ((_ar)->is_raw)
507 
508 #define ar_num filter.num
509 #define ar_cond filter.cond
510 #define ar_filter_type filter.type
511 
512 #define ar_filter_is_none(_ar) ((_ar)->ar_filter_type == TMPL_ATTR_FILTER_TYPE_NONE)
513 #define ar_filter_is_num(_ar) ((_ar)->ar_filter_type == TMPL_ATTR_FILTER_TYPE_INDEX)
514 #define ar_filter_is_cond(_ar) ((_ar)->ar_filter_type == TMPL_ATTR_FILTER_TYPE_CONDITION)
515 /** @} */
516 
517 /** A source or sink of value data.
518  *
519  * Is used as both the RHS and LHS of a map (both update, and conditional types)
520  *
521  * @section update_maps Use in update map_t
522  * When used on the LHS it describes an attribute to create and should be one of these types:
523  * - #TMPL_TYPE_ATTR
524  *
525  * When used on the RHS it describes the value to assign to the attribute being created and
526  * should be one of these types:
527  * - #TMPL_TYPE_DATA_UNRESOLVED
528  * - #TMPL_TYPE_XLAT_UNRESOLVED
529  * - #TMPL_TYPE_ATTR
530  * - #TMPL_TYPE_EXEC
531  * - #TMPL_TYPE_DATA
532  * - #TMPL_TYPE_XLAT (pre-parsed xlat)
533  *
534  * @section conditional_maps Use in conditional map_t
535  * When used as part of a condition it may be any of the RHS side types, as well as:
536  * - #TMPL_TYPE_REGEX (pre-parsed regex)
537  *
538  * @see map_t
539  */
540 struct tmpl_s {
541  tmpl_type_t _CONST type; //!< What type of value tmpl refers to.
542 
543  char const * _CONST name; //!< Raw string used to create the template.
544  ///< this string will have any escape sequences left intact.
545  size_t _CONST len; //!< Length of the raw string used to create the template.
546  fr_token_t _CONST quote; //!< What type of quoting was around the raw string.
547 
548  union {
549  char *unescaped; //!< Unescaped form of the name, used for TMPL_TYPE_DATA_UNRESOLVED
550  ///< and TMPL_TYPE_REGEX_UNCOMPILED.
551 
552  _CONST struct {
553  bool ref_prefix; //!< true if the reference was prefixed
554  ///< with a '&'.
555  FR_DLIST_HEAD(tmpl_request_list) rr; //!< Request to search or insert in.
556  FR_DLIST_HEAD(tmpl_attr_list) ar; //!< Head of the attribute reference list.
557  } attribute;
558 
559  /*
560  * Attribute value. Typically used as the RHS of an update map.
561  */
562  fr_value_box_t literal; //!< Value data.
563 
564  struct {
565  union {
566  _CONST struct {
567  xlat_exp_head_t *ex; //!< pre-parsed xlat expansion
568  ///< and expansion.
569  } xlat;
570 #ifdef HAVE_REGEX
571  _CONST struct {
572  char *src; //!< Original unescaped source string.
573  regex_t *ex; //!< pre-parsed regex_t
574  bool subcaptures; //!< Whether the regex was compiled with
575  ///< subcaptures.
576  } reg;
577 #endif
578  };
579  fr_regex_flags_t reg_flags; //!< Flags for regular expressions.
580  ///< Used by:
581  ///< - TMPL_TYPE_REGEX_XLAT
582  ///< - TMPL_TYPE_REGEX_UNCOMPILED
583  ///< - TMPL_TYPE_REGEX
584  ///< - TMPL_TYPE_REGEX_XLAT_UNRESOLVED
585  };
586  } data;
587 
588  tmpl_rules_t _CONST rules; //!< The rules that were used when creating the tmpl.
589  ///< These are useful for multiple resolution passes as
590  ///< they ensure the correct parsing rules are applied.
591 };
592 
593 /** Describes the current extents of a pair tree in relation to the tree described by a tmpl_t
594  *
595  */
596 typedef struct {
597  fr_dlist_t entry; //!< Entry in the dlist of extents
598 
599  tmpl_attr_t const *ar; //!< Attribute representing the ar
600  ///< after the deepest node that was found
601  ///< in the existing pair tree when evaluating
602  ///< this path. If this is NULL, then all ars
603  ///< were evaluated.
604 
605  TALLOC_CTX *list_ctx; //!< Where to allocate new attributes if building
606  ///< out from the current extents of the tree.
607  fr_pair_list_t *list; //!< List that we tried to evaluate ar in and failed.
608  ///< Or if ar is NULL, the list that represents the
609  ///< deepest grouping or TLV attribute the chain of
610  ///< ars referenced.
612 
613 /** Convenience macro for printing a meaningful assert message when we get a bad tmpl type
614  */
615 #define tmpl_assert_type(_cond) \
616  fr_assert_msg(_cond, "Unexpected tmpl type '%s'", \
617  tmpl_type_to_str(vpt->type))
618 
619 
620 /** @name Functions for printing and parsing tmpl type names
621  *
622  * @{
623  */
624 /** Return a static string containing the type name
625  *
626  * @param[in] type to return name for.
627  * @return name of the type
628  */
629 static inline char const *tmpl_type_to_str(tmpl_type_t type)
630 {
631  return fr_table_str_by_value(tmpl_type_table, type, "<INVALID>");
632 }
633 
634 /** Return the constant value representing a type
635  *
636  * @param[in] type to return the constant value for.
637  * @return The constant type value or TMPL_TYPE_UNINITIALISED if no type matches.
638  */
639 static inline tmpl_type_t tmpl_type_from_str(char const *type)
640 {
642 }
643 /** @} */
644 
645 /** @name Field accessors for #TMPL_TYPE_ATTR, #TMPL_TYPE_ATTR_UNRESOLVED
646  *
647  * @{
648  */
649  #define tmpl_attr(_tmpl) &(_tmpl)->data.attribute.ar
650 
651 static inline FR_DLIST_HEAD(tmpl_request_list) const *tmpl_request(tmpl_t const *vpt)
652 {
655 
656  return &vpt->data.attribute.rr;
657 }
658 
659 /** The number of request references contained within a tmpl
660  *
661  */
662 static inline size_t tmpl_request_ref_count(tmpl_t const *vpt)
663 {
666 
667  return tmpl_request_list_num_elements(&vpt->data.attribute.rr);
668 }
669 
670 /** Return true if the tmpl_attr is one of the list types
671  *
672  * @hidecallergraph
673 */
674 static inline bool tmpl_attr_is_list_attr(tmpl_attr_t const *ar)
675 {
676  if (!ar || !ar_is_normal(ar)) return false;
677 
678  return (ar->ar_da == request_attr_request) ||
679  (ar->ar_da == request_attr_reply) ||
680  (ar->ar_da == request_attr_control) ||
681  (ar->ar_da == request_attr_state) ||
682  (ar->ar_da == request_attr_local);
683 }
684 
685 /** Return true if the head attribute reference is a list reference
686  *
687  * @hidecallergraph
688  */
689 static inline bool tmpl_attr_head_is_list(tmpl_t const *vpt)
690 {
691  tmpl_attr_t *ar;
692 
694 
695  ar = tmpl_attr_list_head(tmpl_attr(vpt));
696  if (unlikely(!ar)) return false;
697 
698  return tmpl_attr_is_list_attr(ar);
699 }
700 
701 /** Return true if the last attribute reference is "normal"
702  *
703  * @hidecallergraph
704  */
705 static inline bool tmpl_attr_tail_is_normal(tmpl_t const *vpt)
706 {
707  tmpl_attr_t *ar;
708 
710 
711  ar = tmpl_attr_list_tail(tmpl_attr(vpt));
712  if (unlikely(!ar)) return false;
713 
714  return ar_is_normal(ar);
715 }
716 
717 /** Return true if the last attribute reference is "unspecified"
718  *
719  * @hidecallergraph
720  */
721 static inline bool tmpl_attr_tail_is_unspecified(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_unspecified(ar);
731 }
732 
733 /** Return true if the last attribute reference is "unknown"
734  *
735  * @hidecallergraph
736  */
737 static inline bool tmpl_attr_tail_is_unknown(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_unknown(ar);
747 }
748 
749 /** Return true if the last attribute reference is "unresolved"
750  *
751  * @hidecallergraph
752  */
753 static inline bool tmpl_attr_tail_is_unresolved(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_unresolved(ar);
763 }
764 
765 /** Return true if the last attribute reference is "raw"
766  *
767  * @hidecallergraph
768  */
769 static inline bool tmpl_attr_tail_is_raw(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_raw(ar);
779 }
780 
781 /** Return the last attribute reference
782  *
783  * @hidecallergraph
784  */
785 static inline tmpl_attr_t const *tmpl_attr_tail(tmpl_t const *vpt)
786 {
788 
789  return tmpl_attr_list_tail(tmpl_attr(vpt));
790 }
791 
792 /** Return the last attribute reference da
793  *
794  * @hidecallergraph
795  */
796 static inline fr_dict_attr_t const *tmpl_attr_tail_da(tmpl_t const *vpt)
797 {
798  tmpl_attr_t *ar;
799 
801 
802  ar = tmpl_attr_list_tail(tmpl_attr(vpt));
803  if (!ar) return NULL;
804 
805  return ar->ar_da;
806 }
807 
808 /** Return true if the the last attribute reference is a leaf attribute
809  *
810  * @hidecallergraph
811  */
812 static inline bool tmpl_attr_tail_da_is_leaf(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 false;
820 
822 
823  return fr_type_is_leaf(ar->ar_da->type);
824 }
825 
826 /** Return true if the the last attribute reference is a structural attribute
827  *
828  * @hidecallergraph
829  */
830 static inline bool tmpl_attr_tail_da_is_structural(tmpl_t const *vpt)
831 {
832  tmpl_attr_t *ar;
833 
835 
836  ar = tmpl_attr_list_tail(tmpl_attr(vpt));
837  if (!ar) return false;
838 
840 
841  return fr_type_is_structural(ar->ar_da->type);
842 }
843 
844 /** Return the last attribute reference unknown da
845  *
846  * @hidecallergraph
847  */
848 static inline fr_dict_attr_t const *tmpl_attr_tail_unknown(tmpl_t const *vpt)
849 {
850  tmpl_attr_t *ar;
851 
853 
854  ar = tmpl_attr_list_tail(tmpl_attr(vpt));
855  if (!ar) return NULL;
856 
857  return ar->ar_unknown;
858 }
859 
860 /** Return the last attribute reference unresolved da
861  *
862  * @hidecallergraph
863  */
864 static inline char const *tmpl_attr_tail_unresolved(tmpl_t const *vpt)
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_unresolved;
874 }
875 
876 /** Return the last attribute reference's attribute number
877  *
878  * @hidecallergraph
879  */
880 static inline int16_t tmpl_attr_tail_num(tmpl_t const *vpt)
881 {
884 
885  return tmpl_attr_list_tail(tmpl_attr(vpt))->ar_num;
886 }
887 
888 /** The number of attribute references contained within a tmpl
889  *
890  */
891 static inline size_t tmpl_attr_num_elements(tmpl_t const *vpt)
892 {
895 
896  return tmpl_attr_list_num_elements(tmpl_attr(vpt));
897 }
898 
899 static inline fr_dict_attr_t const *tmpl_list(tmpl_t const *vpt)
900 {
901  if (!tmpl_attr_head_is_list(vpt)) return NULL;
902 
903  return tmpl_attr_list_head(tmpl_attr(vpt))->ar_da;
904 }
905 /** @} */
906 
907 /** Return the name of a tmpl list or def if list not provided
908  *
909 */
910 static inline char const *tmpl_list_name(fr_dict_attr_t const *list, char const *def)
911 {
912  return (list ? list->name : def);
913 }
914 
915 static inline bool tmpl_is_list(tmpl_t const *vpt)
916 {
917  if (!tmpl_is_attr(vpt)) return false;
919 }
920 
921 /** @name Field accessors for #TMPL_TYPE_XLAT
922  *
923  * @{
924  */
925 #define tmpl_xlat(_tmpl) (_tmpl)->data.xlat.ex
926 /** @} */
927 
928 /** @name Field accessors for #TMPL_TYPE_DATA
929  *
930  * @{
931  */
932 #define tmpl_value(_tmpl) (&(_tmpl)->data.literal)
933 #define tmpl_value_length(_tmpl) (_tmpl)->data.literal.vb_length
934 #define tmpl_value_type(_tmpl) (_tmpl)->data.literal.type
935 #define tmpl_value_enumv(_tmpl) (_tmpl)->data.literal.enumv
936 
937 #define tmpl_rules_cast(_tmpl) (_tmpl)->rules.cast
938 #define tmpl_rules_enumv(_tmpl) (_tmpl)->rules.enumv
939 /** @} */
940 
941 /** @name Field accessors for #TMPL_TYPE_REGEX and #TMPL_TYPE_REGEX_XLAT_UNRESOLVED
942  *
943  * @{
944  */
945 #ifdef HAVE_REGEX
946 # define tmpl_regex(_tmpl) (_tmpl)->data.reg.ex //!< #TMPL_TYPE_REGEX only.
947 # define tmpl_regex_flags(_tmpl) (&(_tmpl)->data.reg_flags)
948 #endif
949 /** @} */
950 
951 #ifndef WITH_VERIFY_PTR
952 # define TMPL_ATTR_VERIFY(_vpt)
953 # define TMPL_VERIFY(_vpt)
954 #else
955 # define TMPL_ATTR_VERIFY(_vpt) tmpl_attr_verify(__FILE__, __LINE__, _vpt)
956 # define TMPL_VERIFY(_vpt) tmpl_verify(__FILE__, __LINE__, _vpt)
957 void tmpl_attr_verify(char const *file, int line, tmpl_t const *vpt);
958 void tmpl_verify(char const *file, int line, tmpl_t const *vpt);
959 #endif
960 
961 /** Determine the correct context and list head
962  *
963  * Used in conjunction with the fr_dcursor functions to determine the correct list
964  * and TALLOC_CTX for inserting fr_pair_ts.
965  *
966  * Example:
967  @code{.c}
968  TALLOC_CTX *ctx;
969  fr_pair_list_t *head;
970  fr_value_box_t value;
971 
972  tmpl_pair_list_and_ctx(ctx, head, request, CURRENT_REQUEST, request_attr_request);
973  if (!list) return -1; // error
974 
975  value.strvalue = talloc_typed_strdup(NULL, "my new username");
976  value.length = talloc_array_length(value.strvalue) - 1;
977  @endcode
978  *
979  * @param _ctx new #fr_pair_t s should be allocated in for the specified list.
980  * @param _head of the #fr_pair_t list.
981  * @param _request The current request.
982  * @param _ref to resolve.
983  * @param _list to resolve.
984  */
985 #define tmpl_pair_list_and_ctx(_ctx, _head, _request, _ref, _list) \
986 do {\
987  request_t *_rctx = _request; \
988  if ((tmpl_request_ptr(&_rctx, _ref) < 0) || \
989  !(_head = tmpl_list_head(_rctx, _list)) || \
990  !(_ctx = tmpl_list_ctx(_rctx, _list))) {\
991  _ctx = NULL; \
992  _head = NULL; \
993  }\
994 } while (0)
995 
996 typedef enum {
997  TMPL_ATTR_ERROR_NONE = 0, //!< No error.
998  TMPL_ATTR_ERROR_EMPTY, //!< Attribute ref contains no data.
999  TMPL_ATTR_ERROR_BAD_PREFIX, //!< Missing '&' or has '&' when it shouldn't.
1000  TMPL_ATTR_ERROR_LIST_NOT_ALLOWED, //!< List qualifier is not allowed here.
1001  TMPL_ATTR_ERROR_LIST_MISSING, //!< List qualifier is required, but missing.
1002  TMPL_ATTR_ERROR_UNKNOWN_NOT_ALLOWED, //!< Attribute specified as OID, could not be
1003  ///< found in the dictionaries, and is disallowed
1004  ///< because 'disallow_internal' in tmpl_rules_t
1005  ///< is trie.
1006  TMPL_ATTR_ERROR_UNRESOLVED_NOT_ALLOWED, //!< Attribute couldn't be found in the dictionaries.
1007  TMPL_ATTR_ERROR_UNQUALIFIED_NOT_ALLOWED, //!< Attribute must be qualified to be used here.
1008  TMPL_ATTR_ERROR_INVALID_NAME, //!< Attribute ref length is zero, or longer than
1009  ///< the maximum.
1010  TMPL_ATTR_ERROR_INTERNAL_NOT_ALLOWED, //!< Attribute resolved to an internal attribute
1011  ///< which is disallowed.
1012  TMPL_ATTR_ERROR_FOREIGN_NOT_ALLOWED, //!< Attribute resolved in a dictionary different
1013  ///< to the one specified.
1014  TMPL_ATTR_ERROR_FILTER_NOT_ALLOWED, //!< Filters disallowed by rules.
1015  TMPL_ATTR_ERROR_INVALID_ARRAY_INDEX, //!< Invalid array index.
1016  TMPL_ATTR_ERROR_INVALID_FILTER, //!< Invalid filter
1017  TMPL_ATTR_ERROR_NESTING_TOO_DEEP, //!< Too many levels of nesting.
1018  TMPL_ATTR_ERROR_MISSING_TERMINATOR, //!< Unexpected text found after attribute reference
1019  TMPL_ATTR_ERROR_BAD_CAST //!< Specified cast was invalid.
1021 
1022 /** Map ptr type to a boxed type
1023  *
1024  */
1025 #define FR_TYPE_FROM_PTR(_ptr) \
1026  _Generic((_ptr), \
1027  char **: FR_TYPE_STRING, \
1028  char const **: FR_TYPE_STRING, \
1029  uint8_t **: FR_TYPE_OCTETS, \
1030  uint8_t const **: FR_TYPE_OCTETS, \
1031  uint8_t *: FR_TYPE_UINT8, \
1032  uint16_t *: FR_TYPE_UINT16, \
1033  uint32_t *: FR_TYPE_UINT32, \
1034  uint64_t *: FR_TYPE_UINT64, \
1035  fr_value_box_t **: FR_TYPE_VALUE_BOX, \
1036  fr_value_box_t const **: FR_TYPE_VALUE_BOX)
1037 
1038 /** Expand a tmpl to a C type, using existing storage to hold variably sized types
1039  *
1040  * Expands a template using the _out ptr to determinate the cast type.
1041  *
1042  * @see _tmpl_to_type
1043  */
1044 #define tmpl_expand(_out, _buff, _buff_len, _request, _vpt, _escape, _escape_ctx) \
1045  _tmpl_to_type((void *)(_out), (uint8_t *)_buff, _buff_len, \
1046  _request, _vpt, _escape, _escape_ctx, FR_TYPE_FROM_PTR(_out))
1047 
1048 /** Expand a tmpl to a C type, allocing a new buffer to hold the string
1049  *
1050  * Expands a template using the _out ptr to determinate the cast type.
1051  *
1052  * @see _tmpl_to_atype
1053  */
1054 #define tmpl_aexpand(_ctx, _out, _request, _vpt, _escape, _escape_ctx) \
1055  _tmpl_to_atype(_ctx, (void *)(_out), _request, _vpt, _escape, _escape_ctx, FR_TYPE_FROM_PTR(_out))
1056 
1057 /** Expand a tmpl to a C type, allocing a new buffer to hold the string
1058  *
1059  * Takes an explicit type which must match the ctype pointed to by out.
1060  *
1061  * @see _tmpl_to_atype
1062  */
1063 #define tmpl_aexpand_type(_ctx, _out, _type, _request, _vpt, _escape, _escape_ctx) \
1064  _tmpl_to_atype(_ctx, (void *)(_out), _request, _vpt, _escape, _escape_ctx, _type)
1065 
1066 void tmpl_debug(tmpl_t const *vpt) CC_HINT(nonnull);
1067 
1068 fr_pair_list_t *tmpl_list_head(request_t *request, fr_dict_attr_t const *list);
1069 
1070 fr_packet_t *tmpl_packet_ptr(request_t *request, fr_dict_attr_t const *list) CC_HINT(nonnull);
1071 
1072 TALLOC_CTX *tmpl_list_ctx(request_t *request, fr_dict_attr_t const *list);
1073 
1075 
1076 tmpl_t *tmpl_init_printf(tmpl_t *vpt, tmpl_type_t type, fr_token_t quote, char const *fmt, ...) CC_HINT(nonnull(1,4));
1077 
1079  char const *name, ssize_t len,
1080  tmpl_rules_t const *t_rules) CC_HINT(nonnull(1,4));
1081 
1083  char const *name, ssize_t len,
1084  tmpl_rules_t const *t_rules) CC_HINT(nonnull(1,4));
1085 
1086 tmpl_t *tmpl_alloc(TALLOC_CTX *ctx, tmpl_type_t type, fr_token_t quote, char const *name, ssize_t len);
1087 
1088 /** @name Parse request qualifiers
1089  *
1090  * @{
1091  */
1092 /** Static default request ref list for the current request
1093  *
1094  * Passed as request_def in tmpl_attr_rules_t.
1095  */
1096 extern FR_DLIST_HEAD(tmpl_request_list) tmpl_request_def_current;
1097 
1098 /** Static default request ref list for the outer request
1099  *
1100  * Passed as request_def in tmpl_attr_rules_t.
1101  */
1102 extern FR_DLIST_HEAD(tmpl_request_list) tmpl_request_def_outer;
1103 
1104 /** Static default request ref list for the parent request
1105  *
1106  * Passed as request_def in tmpl_attr_rules_t.
1107  */
1108 extern FR_DLIST_HEAD(tmpl_request_list) tmpl_request_def_parent;
1109 
1110 int tmpl_request_ptr(request_t **request, FR_DLIST_HEAD(tmpl_request_list) const *rql) CC_HINT(nonnull);
1111 
1112 void tmpl_request_ref_list_debug(FR_DLIST_HEAD(tmpl_request_list) const *rql);
1113 
1114 int8_t tmpl_request_ref_list_cmp(FR_DLIST_HEAD(tmpl_request_list) const *a,
1115  FR_DLIST_HEAD(tmpl_request_list) const *b);
1116 
1117 /** Returns true if the specified qualifier list points to the current request
1118  *
1119  * @param[in] _list to check.
1120  * @return
1121  * - true if the list only contains a current request qualifier.
1122  * - false otherwise.
1123  */
1124 #define tmpl_request_ref_is_current(_list) (tmpl_request_ref_list_cmp(_list, &tmpl_request_def_current) == 0)
1125 
1126 /** Returns true if the specified qualifier list points to the parent request
1127  *
1128  * @param[in] _list to check.
1129  * @return
1130  * - true if the list only contains a parent request qualifier.
1131  * - false otherwise.
1132  */
1133 #define tmpl_request_ref_is_parent(_list) (tmpl_request_ref_list_cmp(_list, &tmpl_request_def_parent) == 0)
1134 
1135 /** Returns true if the specified qualifier list points to the outer request
1136  *
1137  * @param[in] _list to check.
1138  * @return
1139  * - true if the list only contains a outer request qualifier.
1140  * - false otherwise.
1141  */
1142 #define tmpl_request_ref_is_outer(_list) (tmpl_request_ref_list_cmp(_list, &tmpl_request_def_outer) == 0)
1143 
1144 
1146  FR_DLIST_HEAD(tmpl_request_list) _CONST **out,
1147  fr_sbuff_t *in);
1148 /** @} */
1149 
1150 void tmpl_set_name_printf(tmpl_t *vpt, fr_token_t quote, char const *fmt, ...) CC_HINT(nonnull(1,3));
1151 
1152 void tmpl_set_name_shallow(tmpl_t *vpt, fr_token_t quote, char const *name, ssize_t len) CC_HINT(nonnull);
1153 
1154 void tmpl_set_name(tmpl_t *vpt, fr_token_t quote, char const *name, ssize_t len) CC_HINT(nonnull);
1155 
1156 void tmpl_set_dict_def(tmpl_t *vpt, fr_dict_t const *dict) CC_HINT(nonnull);
1157 
1158 void tmpl_set_escape(tmpl_t *vpt, tmpl_escape_t const *escape) CC_HINT(nonnull);
1159 
1160 void tmpl_set_xlat(tmpl_t *vpt, xlat_exp_head_t *xlat) CC_HINT(nonnull);
1161 
1162 int tmpl_afrom_value_box(TALLOC_CTX *ctx, tmpl_t **out, fr_value_box_t *data, bool steal) CC_HINT(nonnull);
1163 
1164 void tmpl_attr_ref_debug(const tmpl_attr_t *ar, int idx) CC_HINT(nonnull);
1165 
1166 void tmpl_attr_ref_list_debug(FR_DLIST_HEAD(tmpl_attr_list) const *ar_head) CC_HINT(nonnull);
1167 
1168 void tmpl_attr_debug(tmpl_t const *vpt) CC_HINT(nonnull);
1169 
1170 int tmpl_attr_copy(tmpl_t *dst, tmpl_t const *src) CC_HINT(nonnull);
1171 
1172 int tmpl_attr_set_da(tmpl_t *vpt, fr_dict_attr_t const *da) CC_HINT(nonnull);
1173 
1174 int tmpl_attr_set_leaf_da(tmpl_t *vpt, fr_dict_attr_t const *da) CC_HINT(nonnull);
1175 
1176 void tmpl_attr_set_leaf_num(tmpl_t *vpt, int16_t num) CC_HINT(nonnull);
1177 
1178 void tmpl_attr_rewrite_leaf_num(tmpl_t *vpt, int16_t from, int16_t to) CC_HINT(nonnull);
1179 
1180 void tmpl_attr_rewrite_num(tmpl_t *vpt, int16_t from, int16_t to) CC_HINT(nonnull);
1181 
1182 void tmpl_attr_set_request_ref(tmpl_t *vpt, FR_DLIST_HEAD(tmpl_request_list) const *request_def) CC_HINT(nonnull);
1183 
1184 void tmpl_attr_set_list(tmpl_t *vpt, fr_dict_attr_t const *list) CC_HINT(nonnull);
1185 
1186 int tmpl_attr_afrom_list(TALLOC_CTX *ctx, tmpl_t **out, tmpl_t const *list,
1187  fr_dict_attr_t const *da) CC_HINT(nonnull);
1188 
1189 /** @name Produce a #tmpl_t from a string or substring
1190  *
1191  * @{
1192  */
1194  tmpl_t **out, fr_sbuff_t *name,
1195  fr_sbuff_parse_rules_t const *p_rules,
1196  tmpl_rules_t const *t_rules) CC_HINT(nonnull(3,4));
1197 
1199  tmpl_t **out, char const *name,
1200  tmpl_rules_t const *rules) CC_HINT(nonnull (3, 4));
1201 
1202 ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out,
1203  fr_sbuff_t *in,
1204  fr_token_t quote,
1205  fr_sbuff_parse_rules_t const *p_rules,
1206  tmpl_rules_t const *t_rules) CC_HINT(nonnull(2,3));
1207 
1208 tmpl_t *tmpl_copy(TALLOC_CTX *ctx, tmpl_t const *in) CC_HINT(nonnull);
1209 
1210 ssize_t tmpl_cast_from_substr(tmpl_rules_t *t_rules, fr_sbuff_t *in) CC_HINT(nonnull(2)); /* Parses cast string */
1211 
1212 int tmpl_cast_set(tmpl_t *vpt, fr_type_t type) CC_HINT(nonnull); /* Sets cast type */
1213 
1215 {
1216  return vpt->rules.cast;
1217 }
1218 
1219 #ifdef HAVE_REGEX
1220 ssize_t tmpl_regex_flags_substr(tmpl_t *vpt, fr_sbuff_t *in,
1221  fr_sbuff_term_t const *terminals) CC_HINT(nonnull(1,2));
1222 #endif
1223 /** @} */
1224 
1225 /** @name Change a #tmpl_t type, usually by casting or resolving a reference
1226  * @{
1227  */
1228 int tmpl_cast_in_place(tmpl_t *vpt, fr_type_t type, fr_dict_attr_t const *enumv) CC_HINT(nonnull(1));
1229 
1230 int tmpl_resolve(tmpl_t *vpt, tmpl_res_rules_t const *tr_rules) CC_HINT(nonnull(1));
1231 
1232 void tmpl_unresolve(tmpl_t *vpt) CC_HINT(nonnull);
1233 
1234 int tmpl_attr_to_xlat(TALLOC_CTX *ctx, tmpl_t **vpt_p) CC_HINT(nonnull);
1235 
1236 void tmpl_attr_to_raw(tmpl_t *vpt) CC_HINT(nonnull);
1237 
1239 
1241  fr_type_t type, fr_dict_attr_flags_t const *flags) CC_HINT(nonnull(1));
1242 
1243 #ifdef HAVE_REGEX
1244 ssize_t tmpl_regex_compile(tmpl_t *vpt, bool subcaptures) CC_HINT(nonnull);
1245 #endif
1246 /** @} */
1247 
1248 /** @name Print the contents of a #tmpl_t
1249  * @{
1250  */
1251 fr_slen_t tmpl_request_ref_list_print(fr_sbuff_t *out, FR_DLIST_HEAD(tmpl_request_list) const *rql)
1252  CC_HINT(nonnull(1,2));
1253 
1254 static inline fr_slen_t tmpl_request_ref_list_aprint(TALLOC_CTX *ctx, char **out, FR_DLIST_HEAD(tmpl_request_list) const *rql)
1256 
1258 
1259 static inline fr_slen_t tmpl_attr_aprint(TALLOC_CTX *ctx, char **out, tmpl_t const *vpt, tmpl_attr_prefix_t ar_prefix)
1261 
1263  tmpl_attr_prefix_t ar_prefix, fr_sbuff_escape_rules_t const *e_rules) CC_HINT(nonnull(1,2));
1264 
1265 static inline fr_slen_t tmpl_aprint(TALLOC_CTX *ctx, char **out, tmpl_t const *vpt,
1268 
1270 
1271 static inline fr_slen_t tmpl_aprint_quoted(TALLOC_CTX *ctx, char **out, tmpl_t const *vpt, tmpl_attr_prefix_t ar_prefix)
1273 /** @} */
1274 
1275 /** @name Expand the tmpl, returning one or more values
1276  * @{
1277  */
1278 fr_type_t tmpl_expanded_type(tmpl_t const *vpt) CC_HINT(nonnull);
1279 
1280 ssize_t _tmpl_to_type(void *out,
1281  uint8_t *buff, size_t outlen,
1282  request_t *request,
1283  tmpl_t const *vpt,
1284  xlat_escape_legacy_t escape, void const *escape_ctx,
1285  fr_type_t dst_type)
1286  CC_HINT(nonnull (1, 4, 5));
1287 
1288 ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
1289  request_t *request,
1290  tmpl_t const *vpt,
1291  xlat_escape_legacy_t escape, void const *escape_ctx,
1292  fr_type_t dst_type)
1293  CC_HINT(nonnull (2, 3, 4));
1294 
1295 int tmpl_copy_pairs(TALLOC_CTX *ctx, fr_pair_list_t *out,
1296  request_t *request, tmpl_t const *vpt) CC_HINT(nonnull(2,3,4));
1297 
1298 int tmpl_copy_pair_children(TALLOC_CTX *ctx, fr_pair_list_t *out,
1299  request_t *request, tmpl_t const *vpt) CC_HINT(nonnull(2,3,4));
1300 
1301 int tmpl_find_vp(fr_pair_t **out, request_t *request, tmpl_t const *vpt) CC_HINT(nonnull(2,3));
1302 
1303 int tmpl_find_or_add_vp(fr_pair_t **out, request_t *request, tmpl_t const *vpt) CC_HINT(nonnull);
1304 
1305 int pair_append_by_tmpl_parent(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list,
1306  tmpl_t const *vpt, bool skip_list) CC_HINT(nonnull(1,3,4));
1307 
1308 int tmpl_extents_find(TALLOC_CTX *ctx,
1309  fr_dlist_head_t *leaf, fr_dlist_head_t *interior,
1310  request_t *request, tmpl_t const *vpt) CC_HINT(nonnull(5));
1311 
1313  tmpl_t const *vpt) CC_HINT(nonnull);
1314 
1316 
1317 int tmpl_eval_pair(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt);
1318 
1319 int tmpl_eval(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt);
1320 
1321 int tmpl_eval_cast_in_place(fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt);
1322 /** @} */
1323 
1324 ssize_t tmpl_preparse(char const **out, size_t *outlen, char const *in, size_t inlen,
1325  fr_token_t *type,
1326  fr_dict_attr_t const **castda, bool require_regex,
1327  bool allow_xlat) CC_HINT(nonnull(1,2,3,5));
1328 
1329 bool tmpl_async_required(tmpl_t const *vpt) CC_HINT(nonnull);
1330 
1331 int tmpl_value_list_insert_tail(fr_value_box_list_t *list, fr_value_box_t *vb, tmpl_t const *vpt) CC_HINT(nonnull);
1332 
1333 void tmpl_rules_child_init(TALLOC_CTX *ctx, tmpl_rules_t *out, tmpl_rules_t const *parent, tmpl_t *vpt) CC_HINT(nonnull);
1334 
1335 void tmpl_rules_debug(tmpl_rules_t const *rules) CC_HINT(nonnull);
1336 
1337 int tmpl_global_init(void);
1338 void tmpl_global_free(void);
1339 
1340 #undef _CONST
1341 
1342 #ifdef __cplusplus
1343 }
1344 #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
static fr_dict_t * dict
Definition: fuzzer.c:46
#define RCSIDH(h, id)
Definition: build.h:445
#define unlikely(_x)
Definition: build.h:378
static fr_slen_t err
Definition: dict.h:645
static fr_slen_t in
Definition: dict.h:645
Values of the encryption flags.
Definition: merged_model.c:139
#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
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
Definition: merged_model.c:228
size_t(* xlat_escape_legacy_t)(request_t *request, char *out, size_t outlen, char const *in, void *arg)
Definition: merged_model.c:213
fr_type_t
Definition: merged_model.c:80
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
ssize_t fr_slen_t
Definition: merged_model.c:35
fr_dict_attr_t const * request_attr_request
Definition: request.c:41
fr_dict_attr_t const * request_attr_control
Definition: request.c:43
fr_dict_attr_t const * request_attr_local
Definition: request.c:45
fr_dict_attr_t const * request_attr_state
Definition: request.c:44
fr_dict_attr_t const * request_attr_reply
Definition: request.c:42
static char const * name
#define SBUFF_OUT_TALLOC_FUNC_NO_LEN_DEF(_func,...)
Set of terminal elements.
Definition: merged_model.c:161
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:887
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:1267
static int16_t tmpl_attr_tail_num(tmpl_t const *vpt)
Return the last attribute reference's attribute number.
Definition: tmpl.h:880
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:503
void tmpl_unresolve(tmpl_t *vpt)
Reset the tmpl, leaving only the name in place.
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.
#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:721
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_rewrite_num(tmpl_t *vpt, int16_t from, int16_t to)
Rewrite all instances of an array number.
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:144
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
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:114
static fr_slen_t vpt
Definition: tmpl.h:1260
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:705
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:605
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:910
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:504
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:737
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
Definition: tmpl.h:796
int tmpl_extents_build_to_leaf_parent(fr_dlist_head_t *leaf, fr_dlist_head_t *interior, tmpl_t const *vpt)
Allocate interior pairs.
Definition: tmpl_dcursor.c:619
static tmpl_type_t tmpl_type_from_str(char const *type)
Return the constant value representing a type.
Definition: tmpl.h:639
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:506
size_t pair_list_table_len
union tmpl_s::@82 data
#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.
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.
int16_t _CONST num
For array references.
Definition: tmpl.h:420
static fr_dict_attr_t const * tmpl_attr_tail_unknown(tmpl_t const *vpt)
Return the last attribute reference unknown da.
Definition: tmpl.h:848
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:674
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.
Definition: tmpl_dcursor.c:493
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:1344
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:812
#define tmpl_assert_type(_cond)
Convenience macro for printing a meaningful assert message when we get a bad tmpl type.
Definition: tmpl.h:615
#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:1216
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:830
void tmpl_global_free(void)
Definition: tmpl_eval.c:1471
tmpl_t * tmpl_copy(TALLOC_CTX *ctx, tmpl_t const *in)
Copy a tmpl.
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:796
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:561
#define TMPL_FLAG_REGEX
Is a type of regular expression.
Definition: tmpl.h:116
static size_t tmpl_request_ref_count(tmpl_t const *vpt)
The number of request references contained within a tmpl.
Definition: tmpl.h:662
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:588
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_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:74
fr_dlist_t entry
Entry in the dlist of extents.
Definition: tmpl.h:597
int tmpl_global_init(void)
Definition: tmpl_eval.c:1453
tmpl_xlat_rules_t xlat
Rules/data for parsing xlats.
Definition: tmpl.h:345
bool at_runtime
Produce an ephemeral/runtime tmpl.
Definition: tmpl.h:353
static bool tmpl_is_list(tmpl_t const *vpt)
Definition: tmpl.h:915
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:1075
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.
Definition: merged_model.c:237
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:282
static FR_DLIST_HEAD(tmpl_request_list) const *tmpl_request(tmpl_t const *vpt)
Static default request ref list for the current request.
Definition: tmpl.h:651
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:753
tmpl_type_t _CONST type
What type of value tmpl refers to.
Definition: tmpl.h:541
#define _CONST
Definition: tmpl.h:256
static size_t tmpl_attr_num_elements(tmpl_t const *vpt)
The number of attribute references contained within a tmpl.
Definition: tmpl.h:891
ssize_t tmpl_preparse(char const **out, size_t *outlen, char const *in, size_t inlen, fr_token_t *type, fr_dict_attr_t const **castda, bool require_regex, bool allow_xlat))
Preparse a string in preparation for passing it to tmpl_afrom_substr()
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_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:649
xlat_exp_head_t _CONST * cond
xlat condition
Definition: tmpl.h:421
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:1214
void tmpl_attr_rewrite_leaf_num(tmpl_t *vpt, int16_t from, int16_t to)
Rewrite the leaf's instance number.
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:167
char const *_CONST name
Raw string used to create the template.
Definition: tmpl.h:543
tmpl_attr_error_t
Definition: tmpl.h:996
@ TMPL_ATTR_ERROR_INVALID_ARRAY_INDEX
Invalid array index.
Definition: tmpl.h:1015
@ TMPL_ATTR_ERROR_LIST_NOT_ALLOWED
List qualifier is not allowed here.
Definition: tmpl.h:1000
@ TMPL_ATTR_ERROR_INTERNAL_NOT_ALLOWED
Attribute resolved to an internal attribute which is disallowed.
Definition: tmpl.h:1010
@ TMPL_ATTR_ERROR_UNRESOLVED_NOT_ALLOWED
Attribute couldn't be found in the dictionaries.
Definition: tmpl.h:1006
@ TMPL_ATTR_ERROR_INVALID_FILTER
Invalid filter.
Definition: tmpl.h:1016
@ TMPL_ATTR_ERROR_BAD_CAST
Specified cast was invalid.
Definition: tmpl.h:1019
@ TMPL_ATTR_ERROR_INVALID_NAME
Attribute ref length is zero, or longer than the maximum.
Definition: tmpl.h:1008
@ TMPL_ATTR_ERROR_UNQUALIFIED_NOT_ALLOWED
Attribute must be qualified to be used here.
Definition: tmpl.h:1007
@ TMPL_ATTR_ERROR_MISSING_TERMINATOR
Unexpected text found after attribute reference.
Definition: tmpl.h:1018
@ TMPL_ATTR_ERROR_LIST_MISSING
List qualifier is required, but missing.
Definition: tmpl.h:1001
@ TMPL_ATTR_ERROR_NONE
No error.
Definition: tmpl.h:997
@ TMPL_ATTR_ERROR_FOREIGN_NOT_ALLOWED
Attribute resolved in a dictionary different to the one specified.
Definition: tmpl.h:1012
@ 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:1002
@ TMPL_ATTR_ERROR_FILTER_NOT_ALLOWED
Filters disallowed by rules.
Definition: tmpl.h:1014
@ TMPL_ATTR_ERROR_EMPTY
Attribute ref contains no data.
Definition: tmpl.h:998
@ TMPL_ATTR_ERROR_NESTING_TOO_DEEP
Too many levels of nesting.
Definition: tmpl.h:1017
@ TMPL_ATTR_ERROR_BAD_PREFIX
Missing '&' or has '&' when it shouldn't.
Definition: tmpl.h:999
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
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:607
static char const * tmpl_attr_tail_unresolved(tmpl_t const *vpt)
Return the last attribute reference unresolved da.
Definition: tmpl.h:864
static tmpl_attr_t const * tmpl_attr_tail(tmpl_t const *vpt)
Return the last attribute reference.
Definition: tmpl.h:785
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)
Definition: tmpl_dcursor.c:669
#define ar_is_unresolved(_ar)
Definition: tmpl.h:505
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:689
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:502
int tmpl_attr_set_leaf_da(tmpl_t *vpt, fr_dict_attr_t const *da)
Replace the leaf attribute only.
static bool tmpl_attr_tail_is_raw(tmpl_t const *vpt)
Return true if the last attribute reference is "raw".
Definition: tmpl.h:769
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:916
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:1050
static fr_dict_attr_t const * tmpl_list(tmpl_t const *vpt)
Definition: tmpl.h:899
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:839
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:545
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.
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:972
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:599
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_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
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:546
void tmpl_attr_debug(tmpl_t const *vpt)
void tmpl_attr_set_leaf_num(tmpl_t *vpt, int16_t num)
fr_type_t tmpl_expanded_type(tmpl_t const *vpt)
Return the native data type of the expression.
Definition: tmpl_eval.c:207
tmpl_attr_filter_type_t _CONST type
Type of filter this is.
Definition: tmpl.h:419
size_t tmpl_request_ref_table_len
static char const * tmpl_type_to_str(tmpl_type_t type)
Return a static string containing the type name.
Definition: tmpl.h:629
Describes the current extents of a pair tree in relation to the tree described by a tmpl_t.
Definition: tmpl.h:596
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:540
static char buff[sizeof("18446744073709551615")+3]
Definition: size_tests.c:41
fr_assert(0)
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:427
unsigned int _CONST resolve_only
This reference and those before it.
Definition: tmpl.h:450
unsigned int _CONST is_raw
Definition: tmpl.h:453
fr_dict_attr_t const *_CONST da
Resolved dictionary attribute.
Definition: tmpl.h:431
fr_dict_attr_t const *_CONST parent
The parent we used when trying to resolve the attribute originally.
Definition: tmpl.h:445
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:457
tmpl_attr_type_t _CONST type
is a raw reference
Definition: tmpl.h:455
Define manipulation functions for the attribute reference list.
Definition: tmpl.h:468
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:472
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:134
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition: table.h:253
An element in an arbitrarily ordered array of name to num mappings.
Definition: table.h:53
An element in a lexicographically sorted array of name to num mappings.
Definition: table.h:45
Escaping rules for tmpls.
Definition: tmpl_escape.h:80
enum fr_token fr_token_t
static fr_slen_t head
Definition: xlat.h:408
static fr_slen_t parent
Definition: pair.h:844
#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:1259
static size_t char fr_sbuff_t size_t inlen
Definition: value.h:984
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:984