The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
xlat_alloc.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: d2c9ccc7454fb1d258a48ddcf10d82e26a433328 $
19 *
20 * @file xlat_alloc.c
21 * @brief Functions to allocate different types of xlat nodes
22 */
23
24RCSID("$Id: d2c9ccc7454fb1d258a48ddcf10d82e26a433328 $")
25
26#include <freeradius-devel/server/base.h>
27#include <freeradius-devel/unlang/xlat.h>
28
29#include <freeradius-devel/util/debug.h>
30#include <freeradius-devel/util/types.h>
31
32#define _XLAT_PRIVATE
33#include <freeradius-devel/unlang/xlat_priv.h>
34
36{
38
39 MEM(head = talloc_zero(ctx, xlat_exp_head_t));
40
41 fr_dlist_init(&head->dlist, xlat_exp_t, entry);
42 head->flags.pure = true;
43#ifndef NDEBUG
44 head->file = file;
45 head->line = line;
46#endif
47
48 return head;
49}
50
51/** Set the type of an xlat node
52 *
53 * Also initialises any xlat_exp_head necessary
54 *
55 * @param[in] node to set type for.
56 * @param[in] type to set.
57 */
59{
60 /*
61 * Do nothing if it's the same type
62 */
63 if (node->type == type) return;
64
65 /*
66 * Free existing lists if present
67 */
68 if (node->type != 0) switch (node->type) {
69 case XLAT_GROUP:
70 TALLOC_FREE(node->group);
71 break;
72
73 case XLAT_FUNC:
75 if (type != XLAT_FUNC) {
76 TALLOC_FREE(node->call.args); /* Just switching from unresolved to resolved */
77 } else goto done;
78 break;
79
80 default:
81 break;
82 }
83
84 /*
85 * Alloc new lists to match the type
86 */
87 switch (type) {
88 case XLAT_GROUP:
90 break;
91
92 case XLAT_FUNC:
94 node->call.args = _xlat_exp_head_alloc(NDEBUG_LOCATION_VALS node);
95 break;
96
97 default:
98 break;
99 }
100
101done:
102 node->type = type;
103}
104
105static xlat_exp_t *xlat_exp_alloc_pool(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, unsigned int extra_hdrs, size_t extra)
106{
107 xlat_exp_t *node;
108
109 MEM(node = talloc_zero_pooled_object(ctx, xlat_exp_t, extra_hdrs, extra));
110 node->flags.pure = true; /* everything starts pure */
111 node->quote = T_BARE_WORD;
112#ifndef NDEBUG
113 node->file = file;
114 node->line = line;
115#endif
116
117 return node;
118}
119
120/** Allocate an xlat node with no name, and no type set
121 *
122 * @param[in] ctx to allocate node in.
123 * @return A new xlat node.
124 */
129
130/** Allocate an xlat node
131 *
132 * @param[in] ctx to allocate node in.
133 * @param[in] type of the node.
134 * @param[in] in original input string.
135 * @param[in] inlen the length of the original input string.
136 * @return A new xlat node.
137 */
139{
140 xlat_exp_t *node;
141 unsigned int extra_hdrs;
142 size_t extra;
143
144 /*
145 * Figure out how much extra memory we
146 * need to allocate for this node type.
147 */
148 switch (type) {
149 case XLAT_GROUP:
150 extra_hdrs = 1;
151 extra = sizeof(xlat_exp_head_t);
152 break;
153
154 case XLAT_FUNC:
155 extra_hdrs = 1;
156 extra = sizeof(xlat_exp_head_t);
157 break;
158
159 default:
160 extra_hdrs = 0;
161 extra = 0;
162 }
163
165 ctx,
166 (in != NULL) + extra_hdrs,
167 inlen + extra);
169
170 if (!in) return node;
171
172 node->fmt = talloc_bstrndup(node, in, inlen);
173 switch (type) {
174 case XLAT_BOX:
175 fr_value_box_strdup_shallow(&node->data, NULL, node->fmt, false);
176 break;
177
178 default:
179 break;
180 }
181
182 return node;
183}
184
185/** Set the format string for an xlat node
186 *
187 * @param[in] node to set fmt for.
188 * @param[in] fmt talloced buffer to set as the fmt string.
189 * @param[in] len of fmt string.
190 */
191void xlat_exp_set_name(xlat_exp_t *node, char const *fmt, size_t len)
192{
193 if (node->fmt) talloc_const_free(node->fmt);
194 node->fmt = talloc_bstrndup(node, fmt, len);
195}
196
197/** Set the format string for an xlat node, copying from a talloc'd buffer
198 *
199 * @param[in] node to set fmt for.
200 * @param[in] fmt talloced buffer to set as the fmt string.
201 */
203{
204 if (node->fmt) talloc_const_free(node->fmt);
205 node->fmt = talloc_typed_strdup_buffer(node, fmt);
206}
207
208/** Set the format string for an xlat node from a pre-existing buffer
209 *
210 * @param[in] node to set fmt for.
211 * @param[in] fmt talloced buffer to set as the fmt string.
212 */
214{
215 if (node->fmt) talloc_const_free(node->fmt);
216 node->fmt = talloc_get_type_abort_const(fmt, char);
217}
218
219/** Copy all nodes in the input list to the output list
220 *
221 * @param[in] ctx to allocate new nodes in.
222 * @param[out] out Where to write new nodes.
223 * @param[in] in Input nodes.
224 * @return
225 * - 0 on success.
226 * - -1 on failure.
227 */
229{
230 xlat_exp_head_t *head = NULL;
231
232 xlat_flags_merge(&out->flags, &in->flags);
233
234 /*
235 * Copy everything in the list of nodes
236 */
237 xlat_exp_foreach(in, p) {
238 xlat_exp_t *node;
239
240 (void)talloc_get_type_abort(p, xlat_exp_t);
241
242 /*
243 * Ensure the format string is valid... At this point
244 * they should all be talloc'd strings.
245 */
246 MEM(node = xlat_exp_alloc(ctx, p->type,
247 talloc_get_type_abort_const(p->fmt, char), talloc_array_length(p->fmt) - 1));
248
249 node->quote = p->quote;
250 node->flags = p->flags;
251
252 switch (p->type) {
253 case XLAT_INVALID:
254 fr_strerror_printf("Cannot copy xlat node of type \"invalid\"");
255 error:
257 return -1;
258
259 case XLAT_BOX:
260 if (unlikely(fr_value_box_copy(node, &node->data, &p->data) < 0)) goto error;
261 break;
262
263 case XLAT_ONE_LETTER: /* Done with format */
266 break;
267
268 case XLAT_VIRTUAL:
269 node->call.func = p->call.func;
270 node->call.dict = p->call.dict;
271 node->call.ephemeral = p->call.ephemeral;
272 break;
273
274 case XLAT_FUNC:
275 /*
276 * Only copy the function pointer, and whether this
277 * is ephemeral.
278 *
279 * All instance data is specific to the xlat node and
280 * cannot be duplicated.
281 *
282 * The node xlat nodes will need to be registered in
283 * the xlat instantiation table later.
284 */
285 node->call.func = p->call.func;
286 node->call.dict = p->call.dict;
287 node->call.ephemeral = p->call.ephemeral;
289 node, node->call.args, p->call.args) < 0)) goto error;
290 break;
291
292 case XLAT_TMPL:
293 node->vpt = tmpl_copy(node, p->vpt);
294 break;
295
296#ifdef HAVE_REGEX
297 case XLAT_REGEX:
298 node->regex_index = p->regex_index;
299 break;
300#endif
301
302 case XLAT_GROUP:
304 node, node->group, p->group) < 0)) goto error;
305 break;
306 }
307
309 }
310
311 return 0;
312}
313
315{
316 int ret;
317
318 if (!in) return 0;
319
323
324 return ret;
325}
326
327#ifdef WITH_VERIFY_PTR
328void xlat_exp_verify(xlat_exp_t const *node)
329{
331
332 switch (node->type) {
333 case XLAT_GROUP:
334 xlat_exp_head_verify(node->group);
335 (void)talloc_get_type_abort_const(node->fmt, char);
336 return;
337
338 case XLAT_FUNC:
339 xlat_exp_head_verify(node->call.args);
340 (void)talloc_get_type_abort_const(node->fmt, char);
341 return;
342
343 default:
344 break;
345 }
346}
347
348/** Performs recursive validation of node lists
349 */
350void xlat_exp_head_verify(xlat_exp_head_t const *head)
351{
353
354 xlat_exp_foreach(head, node) xlat_exp_verify(node);
355}
356#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 RCSID(id)
Definition build.h:483
#define unlikely(_x)
Definition build.h:381
#define NDEBUG_LOCATION_VALS
Definition build.h:264
#define NDEBUG_LOCATION_ARGS
Pass caller information to the function.
Definition build.h:263
#define MEM(x)
Definition debug.h:36
static fr_slen_t in
Definition dict.h:824
#define fr_dlist_init(_head, _type, _field)
Initialise the head structure of a doubly linked list.
Definition dlist.h:260
talloc_free(reap)
static bool done
Definition radclient.c:80
tmpl_t * tmpl_copy(TALLOC_CTX *ctx, tmpl_t const *in)
Copy a tmpl.
fr_aka_sim_id_type_t type
char * talloc_typed_strdup_buffer(TALLOC_CTX *ctx, char const *p)
Call talloc_strndup, setting the type on the new chunk correctly.
Definition talloc.c:469
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
Definition talloc.c:564
#define talloc_get_type_abort_const
Definition talloc.h:282
#define talloc_zero_pooled_object(_ctx, _type, _num_subobjects, _total_subobjects_size)
Definition talloc.h:177
static int talloc_const_free(void const *ptr)
Free const'd memory.
Definition talloc.h:224
@ T_BARE_WORD
Definition token.h:120
#define XLAT_HEAD_VERIFY(_head)
Definition xlat.h:468
static fr_slen_t head
Definition xlat.h:422
bool pure
has no external side effects, true for BOX, LITERAL, and some functions
Definition xlat.h:114
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition strerror.h:64
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
Definition value.c:3740
void fr_value_box_strdup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Assign a buffer containing a nul terminated string to a box, but don't copy it.
Definition value.c:4036
static size_t char fr_sbuff_t size_t inlen
Definition value.h:997
int nonnull(2, 5))
static size_t char ** out
Definition value.h:997
xlat_exp_head_t * _xlat_exp_head_alloc(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx)
Definition xlat_alloc.c:35
xlat_exp_t * _xlat_exp_alloc(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, xlat_type_t type, char const *in, size_t inlen)
Allocate an xlat node.
Definition xlat_alloc.c:138
void xlat_exp_set_name(xlat_exp_t *node, char const *fmt, size_t len)
Set the format string for an xlat node.
Definition xlat_alloc.c:191
void xlat_exp_set_name_buffer(xlat_exp_t *node, char const *fmt)
Set the format string for an xlat node, copying from a talloc'd buffer.
Definition xlat_alloc.c:202
xlat_exp_t * _xlat_exp_alloc_null(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx)
Allocate an xlat node with no name, and no type set.
Definition xlat_alloc.c:125
int _xlat_copy(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, xlat_exp_head_t *out, xlat_exp_head_t const *in)
Definition xlat_alloc.c:314
static xlat_exp_t * xlat_exp_alloc_pool(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, unsigned int extra_hdrs, size_t extra)
Definition xlat_alloc.c:105
void xlat_exp_set_name_buffer_shallow(xlat_exp_t *node, char const *fmt)
Set the format string for an xlat node from a pre-existing buffer.
Definition xlat_alloc.c:213
static int _xlat_copy_internal(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, xlat_exp_head_t *out, xlat_exp_head_t const *in)
Copy all nodes in the input list to the output list.
Definition xlat_alloc.c:228
void _xlat_exp_set_type(NDEBUG_LOCATION_ARGS xlat_exp_t *node, xlat_type_t type)
Set the type of an xlat node.
Definition xlat_alloc.c:58
struct xlat_exp_head_s xlat_exp_head_t
Definition xlat_ctx.h:36
xlat_flags_t flags
Flags that control resolution and evaluation.
Definition xlat_priv.h:157
int line
Line where the xlat was allocated.
Definition xlat_priv.h:162
fr_token_t quote
Type of quoting around XLAT_GROUP types.
Definition xlat_priv.h:155
xlat_type_t
Definition xlat_priv.h:105
@ XLAT_ONE_LETTER
Special "one-letter" expansion.
Definition xlat_priv.h:108
@ XLAT_BOX
fr_value_box_t
Definition xlat_priv.h:107
@ XLAT_TMPL
xlat attribute
Definition xlat_priv.h:113
@ XLAT_VIRTUAL_UNRESOLVED
virtual attribute needs resolution during pass2.
Definition xlat_priv.h:112
@ XLAT_FUNC
xlat module
Definition xlat_priv.h:109
@ XLAT_VIRTUAL
virtual attribute
Definition xlat_priv.h:111
@ XLAT_GROUP
encapsulated string of xlats
Definition xlat_priv.h:117
@ XLAT_FUNC_UNRESOLVED
func needs resolution during pass2.
Definition xlat_priv.h:110
@ XLAT_INVALID
Bad expansion.
Definition xlat_priv.h:106
static void xlat_flags_merge(xlat_flags_t *parent, xlat_flags_t const *child)
Merge flags from child to parent.
Definition xlat_priv.h:227
char const *_CONST fmt
The original format string (a talloced buffer).
Definition xlat_priv.h:154
xlat_type_t _CONST type
type of this expansion.
Definition xlat_priv.h:158
char const *_CONST file
File where the xlat was allocated.
Definition xlat_priv.h:161
#define xlat_exp_alloc(_ctx, _type, _in, _inlen)
Definition xlat_priv.h:280
#define xlat_exp_foreach(_list_head, _iter)
Iterate over the contents of a list, only one level.
Definition xlat_priv.h:220
static int xlat_exp_insert_tail(xlat_exp_head_t *head, xlat_exp_t *node)
Definition xlat_priv.h:236
An xlat expansion node.
Definition xlat_priv.h:151