The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
dict_ext_priv.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/** Extensions for dictionary definitions
19 *
20 * @file src/lib/util/dict_ext_priv.h
21 *
22 * @copyright 2020 The FreeRADIUS server project
23 * @copyright 2020 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
24 */
25RCSIDH(dict_ext_priv_h, "$Id: ca0859ac1b092c4bc9ec1e20b295dab1359c4b2a $")
26
27#include <freeradius-devel/util/dict.h>
28#include <freeradius-devel/util/dict_ext.h>
29#include <limits.h>
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35/** @name Add extension structures to attributes
36 *
37 * @{
38 */
39
40static inline bool dict_attr_ext_mutable(fr_dict_attr_t **da_p)
41{
42 if ((*da_p)->flags.is_ref_target) {
43 fr_strerror_printf("%s is already the target of a reference, and cannot be changed", (*da_p)->name);
44 return false;
45 }
46
47 if (!(*da_p)->flags.is_unknown && unlikely((*da_p)->dict && fr_dict_is_read_only((*da_p)->dict))) {
48 fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root((*da_p)->dict)->name);
49 return false;
50 }
51
52 return true;
53}
54
55/** Allocate an attribute extension of a particular size
56 *
57 */
58static inline void *dict_attr_ext_alloc_size(fr_dict_attr_t **da_p, fr_dict_attr_ext_t ext, size_t ext_len)
59{
60 if (!dict_attr_ext_mutable(da_p)) return NULL;
61
62 return fr_ext_alloc_size(&fr_dict_attr_ext_def, (void **)da_p, ext, ext_len);
63}
64
65/** Allocate an attribute extension
66 *
67 */
69{
70 if (!dict_attr_ext_mutable(da_p)) return NULL;
71
72 return fr_ext_alloc_size(&fr_dict_attr_ext_def, (void **)da_p, ext, fr_dict_attr_ext_def.info[ext].min);
73}
74
75/** Return the length of an attribute extension
76 *
77 */
78static inline size_t dict_attr_ext_len(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
79{
80 return fr_ext_len(&fr_dict_attr_ext_def, (void const *)da, ext);
81}
82
83/** Copy a single attribute extension from one attribute to another
84 *
85 */
86static inline void *dict_attr_ext_copy(fr_dict_attr_t **da_out_p, fr_dict_attr_t const *da_in, fr_dict_attr_ext_t ext)
87{
88 if (!dict_attr_ext_mutable(da_out_p)) return NULL;
89
90 /*
91 * We might be able to copy things for unknown
92 * attributes. But if the unknown is of type 'octets',
93 * then we can only copy the protocol-specific things.
94 */
95#ifndef NDEBUG
96 if ((*da_out_p)->flags.is_unknown && ((*da_out_p)->type == FR_TYPE_OCTETS)) {
98 }
99#endif
100
101 return fr_ext_copy(&fr_dict_attr_ext_def, (void **)da_out_p, (void const *)da_in, ext);
102}
103
104/** Copy all attribute extensions from one attribute to another
105 *
106 */
107static inline int dict_attr_ext_copy_all(fr_dict_attr_t **da_out_p, fr_dict_attr_t const *da_in)
108{
109 if (!dict_attr_ext_mutable(da_out_p)) return -1;
110
111 return fr_ext_copy_all(&fr_dict_attr_ext_def, (void **)da_out_p, (void const *)da_in);
112}
113
114/** Print extension debug information for attributes
115 *
116 */
117static inline void dict_attr_ext_debug(char const *name, fr_dict_attr_t const *da)
118{
120}
121/** @} */
122
123/** @name Convenience functions for populating attribute extensions
124 *
125 * @{
126 */
127
128static inline int dict_attr_ref_null(fr_dict_attr_t const *da)
129{
131
133 if (unlikely(!ext)) {
134 fr_strerror_printf("Contains no 'ref' extension");
135 return -1;
136 }
137
138 if (unlikely((ext->type & FR_DICT_ATTR_REF_UNRESOLVED) != 0)) {
139 fr_strerror_printf("Contains an resolved 'ref' extension");
140 return -1;
141 }
142
143 ext->type = 0;
144 ext->ref = NULL;
145
146 return 0;
147}
148
150{
152
154 if (unlikely(!ext)) {
156 }
157
158 /*
159 * Check that the attribute ref is unresolved.
160 */
162 fr_strerror_printf("Reference type cannot be unresolved");
163 return -1;
164 }
165
166 ext->type = type;
167 ext->ref = ref;
168
169 return 0;
170}
171
173{
175
177 if (unlikely(!ext)) {
178 fr_strerror_printf("Attribute contains no 'ref' extension");
179 return -1;
180 }
181
182 /*
183 * Check that the attribute ref is unresolved.
184 */
186 fr_strerror_printf("Reference type cannot be unresolved");
187 return -1;
188 }
189
190 ext->type = type;
191 ext->ref = ref;
192
193 UNCONST(fr_dict_attr_t *, ref)->flags.is_ref_target = true;
194
195 return 0;
196}
197
198static inline int dict_attr_ref_resolve(fr_dict_attr_t const *da, fr_dict_attr_t const *ref)
199{
201
203 if (unlikely(!ext)) {
204 fr_strerror_printf("Contains no 'ref' extension");
205 return -1;
206 }
207
208 /*
209 * Check that the attribute ref is unresolved.
210 */
211 if (unlikely(fr_dict_attr_ref_is_unresolved(ext->type) == false)) {
212 fr_strerror_printf("Contains an resolved 'ref' extension");
213 return -1;
214 }
215
217 talloc_free(ext->unresolved);
218 ext->ref = ref;
219
220 return 0;
221}
222
223static inline int dict_attr_ref_aunresolved(fr_dict_attr_t **da_p, char const *ref, fr_dict_attr_ref_type_t type)
224{
226 fr_dict_attr_t *da;
227
229 if (unlikely(!ext)) {
231 if (unlikely(!ext)) return -1;
232 }
233 da = *da_p;
234 if (unlikely(ext->type != 0)) {
235 fr_strerror_printf("Attribute already has a 'ref=...' defined");
236 return -1;
237 }
238 ext->type = type | FR_DICT_ATTR_REF_UNRESOLVED; /* Always unresolved */
239 ext->unresolved = talloc_typed_strdup(da, ref);
240
241 return 0;
242}
243
244static inline int dict_attr_children_set(fr_dict_attr_t const *da, fr_dict_attr_t const **children)
245{
247
249 if (unlikely(!ext)) {
250 fr_strerror_printf("Attribute contains no 'children' extension");
251 return -1;
252 }
253 ext->children = children;
254
255 return 0;
256}
257
258static inline fr_dict_attr_t const **dict_attr_children(fr_dict_attr_t const *da)
259{
261
263 if (unlikely(!ext)) {
264 fr_strerror_printf("Attribute contains no 'children' extension");
265 return NULL;
266 }
267 return ext->children;
268}
269
270/** Return the namespace hash table associated with the attribute
271 *
272 * @param[in] da to return the reference for.
273 * @return
274 * - NULL if no namespace available.
275 * - A pointer to the namespace hash table
276 */
278{
279 fr_dict_attr_t const *ref;
281
282 ref = fr_dict_attr_ref(da);
283 if (unlikely(ref != NULL)) return NULL;
284
286 if (!ext) return NULL;
287
288 return ext->namespace;
289}
290/** @} */
291
292#ifdef __cplusplus
293}
294#endif
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition build.h:167
#define RCSIDH(h, id)
Definition build.h:486
#define unlikely(_x)
Definition build.h:383
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2514
bool fr_dict_is_read_only(fr_dict_t const *dict)
Definition dict_util.c:2519
fr_dict_attr_ext_t
Extension identifier.
Definition dict.h:182
@ FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC
Protocol specific extensions.
Definition dict.h:192
@ FR_DICT_ATTR_EXT_NAMESPACE
Attribute has its own namespace.
Definition dict.h:191
@ FR_DICT_ATTR_EXT_REF
Attribute references another attribute and/or dictionary.
Definition dict.h:185
@ FR_DICT_ATTR_EXT_VENDOR
Cached vendor pointer.
Definition dict.h:188
@ FR_DICT_ATTR_EXT_CHILDREN
Attribute has children.
Definition dict.h:184
fr_ext_t const fr_dict_attr_ext_def
Holds additional information about extension structures.
Definition dict_ext.c:217
fr_dict_attr_ref_type_t type
The state of the reference.
Definition dict_ext.h:78
fr_dict_attr_t const ** children
Children of this attribute.
Definition dict_ext.h:54
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
Definition dict_ext.h:141
#define fr_dict_attr_ref_is_unresolved(_type)
Definition dict_ext.h:71
static fr_dict_attr_t const * fr_dict_attr_ref(fr_dict_attr_t const *da)
Return the reference associated with a group type attribute.
Definition dict_ext.h:185
fr_dict_attr_ref_type_t
Definition dict_ext.h:58
@ FR_DICT_ATTR_REF_UNRESOLVED
This flag is combined with the other states to indicate that the reference is unresolved.
Definition dict_ext.h:66
Attribute extension - Holds children for an attribute.
Definition dict_ext.h:52
Attribute extension - Holds a hash table with the names of all children of this attribute.
Definition dict_ext.h:117
Attribute extension - Holds a reference to an attribute in another dictionary.
Definition dict_ext.h:77
static int dict_attr_ref_set(fr_dict_attr_t const *da, fr_dict_attr_t const *ref, fr_dict_attr_ref_type_t type)
static int dict_attr_children_set(fr_dict_attr_t const *da, fr_dict_attr_t const **children)
static fr_hash_table_t * dict_attr_namespace(fr_dict_attr_t const *da)
Return the namespace hash table associated with the attribute.
static size_t dict_attr_ext_len(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
Return the length of an attribute extension.
static int dict_attr_ref_null(fr_dict_attr_t const *da)
static int dict_attr_ref_resolve(fr_dict_attr_t const *da, fr_dict_attr_t const *ref)
static bool dict_attr_ext_mutable(fr_dict_attr_t **da_p)
static int dict_attr_ref_aunresolved(fr_dict_attr_t **da_p, char const *ref, fr_dict_attr_ref_type_t type)
static int dict_attr_ext_copy_all(fr_dict_attr_t **da_out_p, fr_dict_attr_t const *da_in)
Copy all attribute extensions from one attribute to another.
static void * dict_attr_ext_copy(fr_dict_attr_t **da_out_p, fr_dict_attr_t const *da_in, fr_dict_attr_ext_t ext)
Copy a single attribute extension from one attribute to another.
static fr_dict_attr_t const ** dict_attr_children(fr_dict_attr_t const *da)
static void * dict_attr_ext_alloc_size(fr_dict_attr_t **da_p, fr_dict_attr_ext_t ext, size_t ext_len)
Allocate an attribute extension of a particular size.
static int dict_attr_ref_aset(fr_dict_attr_t **da_p, fr_dict_attr_t const *ref, fr_dict_attr_ref_type_t type)
static void * dict_attr_ext_alloc(fr_dict_attr_t **da_p, fr_dict_attr_ext_t ext)
Allocate an attribute extension.
static void dict_attr_ext_debug(char const *name, fr_dict_attr_t const *da)
Print extension debug information for attributes.
void * fr_ext_copy(fr_ext_t const *def, TALLOC_CTX **chunk_dst, TALLOC_CTX const *chunk_src, int ext)
Copy extension data from one attribute to another.
Definition ext.c:163
size_t fr_ext_len(fr_ext_t const *def, TALLOC_CTX const *chunk, int ext)
Return the length of an extension.
Definition ext.c:131
void fr_ext_debug(fr_ext_t const *def, char const *name, void const *chunk)
Print out all extensions and hexdump their contents.
Definition ext.c:339
int fr_ext_copy_all(fr_ext_t const *def, TALLOC_CTX **chunk_dst, TALLOC_CTX const *chunk_src)
Copy all the extensions from one attribute to another.
Definition ext.c:248
void * fr_ext_alloc_size(fr_ext_t const *def, void **chunk_p, int ext, size_t ext_len)
Add a variable length extension to a talloc chunk.
Definition ext.c:55
size_t min
Minimum size of extension.
Definition ext.h:112
fr_ext_info_t const * info
Additional information about each extension.
Definition ext.h:131
talloc_free(reap)
@ FR_TYPE_OCTETS
Raw octets.
#define fr_assert(_expr)
Definition rad_assert.h:38
static char const * name
fr_aka_sim_id_type_t type
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition talloc.c:467
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition strerror.h:64