Coverage Report

Created: 2026-08-08 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeradius-server/src/freeradius-devel/server/cf_priv.h
Line
Count
Source
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: cee63aa6fb33295498356bfe67ace3e8c1b66455 $
20
 *
21
 * @file cf_priv.h
22
 * @brief Private data structures and types for cf_*.c
23
 *
24
 * @copyright 2017 The FreeRADIUS server project
25
 */
26
RCSIDH(cf_priv_h, "$Id: cee63aa6fb33295498356bfe67ace3e8c1b66455 $")
27
28
#ifdef __cplusplus
29
extern "C" {
30
#endif
31
32
#include <stdint.h>
33
#include <sys/stat.h>
34
35
#include <freeradius-devel/server/cf_parse.h>
36
#include <freeradius-devel/util/rb.h>
37
#include <freeradius-devel/util/dlist.h>
38
39
typedef enum conf_type {
40
  CONF_ITEM_INVALID = 0,
41
  CONF_ITEM_PAIR,
42
  CONF_ITEM_SECTION,
43
  CONF_ITEM_DATA,
44
  CONF_ITEM_COMMENT,    //!< A `# ...` line preserved verbatim
45
          ///< from the input - only created when
46
          ///< the parser is asked to keep comments
47
          ///< (off by default; the runtime parser
48
          ///< doesn't keep them, tooling can opt in).
49
} CONF_ITEM_TYPE;
50
51
/** Common header for all CONF_* types
52
 *
53
 */
54
struct cf_item {
55
  fr_rb_node_t    ident1_node;  //!< Entry in the ident1 tree.
56
  fr_rb_node_t    ident2_node;  //!< Entry in the ident2 tree.
57
58
  fr_dlist_t    entry;    //!< Entry in dlist
59
  fr_dlist_head_t   children; //!< The head of the ordered list of children.
60
61
  CONF_ITEM   *parent;  //!< Parent
62
63
  fr_rb_tree_t    *ident1;  //!< Tree to store the first identifier (name1 || type || attr).
64
  fr_rb_tree_t    *ident2;  //!< Tree to store the second identifier (name2 || name).
65
66
  CONF_ITEM_TYPE    type;   //!< Whether the config item is a config_pair, conf_section or cf_data.
67
68
  bool      parsed;   //!< Was this item used during parsing?
69
  bool      referenced; //!< Was this item referenced in the config?
70
  int     lineno;   //!< The line number the config item began on.
71
  char const    *filename;  //!< The file the config item was parsed from.
72
};
73
74
/** Configuration AVP similar to a fr_pair_t
75
 *
76
 */
77
struct cf_pair {
78
  CONF_ITEM   item;   //!< Common set of fields.
79
80
  char const    *attr;    //!< Attribute name
81
  char const    *value;   //!< Attribute value
82
83
  fr_token_t    op;   //!< Operator e.g. =, :=
84
  fr_token_t    lhs_quote;  //!< Name quoting style T_(DOUBLE|SINGLE|BACK)_QUOTE_STRING or T_BARE_WORD.
85
  fr_token_t    rhs_quote;  //!< Value Quoting style T_(DOUBLE|SINGLE|BACK)_QUOTE_STRING or T_BARE_WORD.
86
87
  bool      pass2;    //!< do expansion in pass2.
88
  bool      printed;  //!< Was this item printed already in debug mode?
89
};
90
91
typedef enum {
92
  CF_UNLANG_NONE = 0,     //!< no unlang
93
  CF_UNLANG_ALLOW,      //!< allow unlang in this section
94
  CF_UNLANG_SERVER,     //!< this section is a virtual server, allow unlang 2 down
95
  CF_UNLANG_POLICY,     //!< this section is a policy, allow unlang 2 down
96
  CF_UNLANG_MODULES,      //!< this section is in "modules", allow unlang 2 down
97
  CF_UNLANG_EDIT,       //!< only edit commands
98
  CF_UNLANG_ASSIGNMENT,       //!< only assignments inside of map / update
99
  CF_UNLANG_DICTIONARY,       //!< only local variable definitions
100
  CF_UNLANG_CAN_HAVE_UPDATE,    //!< can have "update"
101
} cf_unlang_t;
102
103
/** A section grouping multiple #CONF_PAIR
104
 *
105
 */
106
struct cf_section {
107
  CONF_ITEM   item;   //!< Common set of fields.
108
109
  char const    *name1;   //!< First name token.  Given ``foo bar {}`` would be ``foo``.
110
  char const    *name2;   //!< Second name token. Given ``foo bar {}`` would be ``bar``.
111
112
  fr_token_t    name2_quote;  //!< The type of quoting around name2.
113
114
  int     argc;   //!< number of additional arguments
115
  char const    **argv;   //!< additional arguments
116
  fr_token_t    *argv_quote;
117
118
  void      *base;
119
  int     depth;
120
  cf_unlang_t       unlang;
121
  bool      allow_locals; //!< allow local variables
122
  bool      at_reference; //!< this thing was created from an @...
123
124
  CONF_SECTION    *template;
125
};
126
453
#define CONF_SECTION_MAX_DEPTH 256
127
128
/*
129
 *  Private getter for cf_file.c's parser hook - the public API is the
130
 *  `cf_preserve_comments_set()` setter in cf_util.h; the flag itself
131
 *  lives static in cf_util.c.
132
 */
133
bool _cf_preserve_comments(void);
134
135
/*
136
 *  Private getter for cf_file.c's cf_expand_variables() short-circuit.
137
 *  Public API is `cf_expand_variables_set()` in cf_util.h.
138
 */
139
bool _cf_expand_variables(void);
140
141
/** A `# ...` comment line preserved verbatim from the input.
142
 *
143
 * Only constructed when `cf_preserve_comments` is set before parsing;
144
 * the runtime config parser drops comments as it always has.
145
 */
146
struct cf_comment {
147
  CONF_ITEM   item;   //!< Common set of fields.
148
149
  char const    *text;    //!< Comment text, with the leading `#`
150
            //!< and any surrounding whitespace stripped.
151
};
152
153
/** Internal data that is associated with a configuration section
154
 *
155
 */
156
struct cf_data {
157
  CONF_ITEM     item;   //!< Common set of fields.
158
159
  char const    *type;    //!< C type of data being stored.
160
  char const    *name;    //!< Additional qualification of type.
161
162
  void const      *data;    //!< User data.
163
  bool      is_talloced;  //!< If true we can do extra checks.
164
};
165
166
typedef struct {
167
  fr_rb_node_t    node;
168
  char const    *filename;  //!< name of the file
169
  CONF_SECTION    *cs;    //!< CONF_SECTION associated with the file
170
  struct stat   buf;    //!< stat about the file
171
  bool      from_dir; //!< was read from a directory
172
} cf_file_t;
173
174
/** Iterate over the contents of a list
175
 *
176
 * @param[in] _ci   to iterate over.
177
 * @param[in] _iter   Name of iteration variable.
178
 *        Will be declared in the scope of the loop.
179
 * @param[in] _prev   previous pointer
180
 */
181
#define cf_item_foreach_next(_ci, _iter, _prev) \
182
0
  for (CONF_ITEM *_iter = fr_dlist_next(&(_ci)->children, _prev); _iter; _iter = fr_dlist_next(&(_ci)->children, _iter))
183
184
/** Iterate over the contents of a list in reverse order
185
 *
186
 * @param[in] _ci   to iterate over.
187
 * @param[in] _iter   Name of iteration variable.
188
 *        Will be declared in the scope of the loop.
189
 * @param[in] _prev   previous pointer
190
 */
191
#define cf_item_foreach_prev(_ci, _iter, _prev) \
192
0
  for (CONF_ITEM *_iter = fr_dlist_prev(&(_ci)->children, _prev); _iter; _iter = fr_dlist_prev(&(_ci)->children, _iter))
193
194
/** Check if the CONF_ITEM has no children.
195
 *
196
 *  Which is the common use-case
197
 *
198
 * @param[in] ci    to check
199
 * @return      true/false
200
 */
201
static inline CC_HINT(nonnull) bool cf_item_has_no_children(CONF_ITEM const *ci)
202
3.88k
{
203
3.88k
  return fr_dlist_empty(&ci->children);
204
3.88k
}
Unexecuted instantiation: cf_file.c:cf_item_has_no_children
Unexecuted instantiation: cf_parse.c:cf_item_has_no_children
cf_util.c:cf_item_has_no_children
Line
Count
Source
202
3.88k
{
203
3.88k
  return fr_dlist_empty(&ci->children);
204
3.88k
}
205
206
#ifdef __cplusplus
207
}
208
#endif