The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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  */
25 RCSIDH(dict_ext_priv_h, "$Id: 7d41351cca3454ced3ab0aab558bfdcc42698d8b $")
26 
27 #include <freeradius-devel/util/dict.h>
28 #include <freeradius-devel/util/dict_ext.h>
29 #include <limits.h>
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 /** @name Add extension structures to attributes
36  *
37  * @{
38  */
39 
40 /** Allocate an attribute extension of a particular size
41  *
42  */
43 static inline void *dict_attr_ext_alloc_size(fr_dict_attr_t **da_p, fr_dict_attr_ext_t ext, size_t ext_len)
44 {
45  if (!(*da_p)->flags.is_unknown && unlikely((*da_p)->dict && fr_dict_is_read_only((*da_p)->dict))) {
46  fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root((*da_p)->dict)->name);
47  return NULL;
48  }
49 
50  return fr_ext_alloc_size(&fr_dict_attr_ext_def, (void **)da_p, ext, ext_len);
51 }
52 
53 /** Allocate an attribute extension
54  *
55  */
56 static inline void *dict_attr_ext_alloc(fr_dict_attr_t **da_p, fr_dict_attr_ext_t ext)
57 {
58  if (!(*da_p)->flags.is_unknown && unlikely((*da_p)->dict && fr_dict_is_read_only((*da_p)->dict))) {
59  fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root((*da_p)->dict)->name);
60  return NULL;
61  }
62 
63  return fr_ext_alloc_size(&fr_dict_attr_ext_def, (void **)da_p, ext, fr_dict_attr_ext_def.info[ext].min);
64 }
65 
66 /** Return the length of an attribute extension
67  *
68  */
69 static inline size_t dict_attr_ext_len(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
70 {
71  return fr_ext_len(&fr_dict_attr_ext_def, (void const *)da, ext);
72 }
73 
74 /** Copy a single attribute extension from one attribute to another
75  *
76  */
77 static 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)
78 {
79  if (unlikely((*da_out_p)->dict && fr_dict_is_read_only((*da_out_p)->dict))) {
80  fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root((*da_out_p)->dict)->name);
81  return NULL;
82  }
83 
84  return fr_ext_copy(&fr_dict_attr_ext_def, (void **)da_out_p, (void const *)da_in, ext);
85 }
86 
87 /** Copy all attribute extensions from one attribute to another
88  *
89  */
90 static inline int dict_attr_ext_copy_all(fr_dict_attr_t **da_out_p, fr_dict_attr_t const *da_in)
91 {
92  if (unlikely((*da_out_p)->dict && fr_dict_is_read_only((*da_out_p)->dict))) {
93  fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root((*da_out_p)->dict)->name);
94  return -1;
95  }
96 
97  return fr_ext_copy_all(&fr_dict_attr_ext_def, (void **)da_out_p, (void const *)da_in);
98 }
99 
100 /** Print extension debug information for attributes
101  *
102  */
103 static inline void dict_attr_ext_debug(char const *name, fr_dict_attr_t const *da)
104 {
106 }
107 /** @} */
108 
109 /** @name Convenience functions for populating attribute extensions
110  *
111  * @{
112  */
113 
114 static inline int dict_attr_ref_null(fr_dict_attr_t const *da)
115 {
117 
119  if (unlikely(!ext)) {
120  fr_strerror_printf("Contains no 'ref' extension");
121  return -1;
122  }
123 
124  if (unlikely((ext->type & FR_DICT_ATTR_REF_UNRESOLVED) != 0)) {
125  fr_strerror_printf("Contains an resolved 'ref' extension");
126  return -1;
127  }
128 
129  ext->type = 0;
130  ext->ref = NULL;
131 
132  return 0;
133 }
134 
136 {
138 
140  if (unlikely(!ext)) {
142  }
143 
144  /*
145  * Check that the attribute ref is unresolved.
146  */
147  if (unlikely((type & FR_DICT_ATTR_REF_UNRESOLVED) != 0)) {
148  fr_strerror_printf("Reference type cannot be unresolved");
149  return -1;
150  }
151 
152  ext->type = type;
153  ext->ref = ref;
154 
155  return 0;
156 }
157 
159 {
161 
163  if (unlikely(!ext)) {
164  fr_strerror_printf("Attribute contains no 'ref' extension");
165  return -1;
166  }
167 
168  /*
169  * Check that the attribute ref is unresolved.
170  */
171  if (unlikely((type & FR_DICT_ATTR_REF_UNRESOLVED) != 0)) {
172  fr_strerror_printf("Reference type cannot be unresolved");
173  return -1;
174  }
175 
176  ext->type = type;
177  ext->ref = ref;
178 
179  return 0;
180 }
181 
182 static inline int dict_attr_ref_resolve(fr_dict_attr_t const *da, fr_dict_attr_t const *ref)
183 {
185 
187  if (unlikely(!ext)) {
188  fr_strerror_printf("Contains no 'ref' extension");
189  return -1;
190  }
191 
192  /*
193  * Check that the attribute ref is unresolved.
194  */
195  if (unlikely(fr_dict_attr_ref_is_unresolved(ext->type) == false)) {
196  fr_strerror_printf("Contains an resolved 'ref' extension");
197  return -1;
198  }
199 
201  talloc_free(ext->unresolved);
202  ext->ref = ref;
203 
204  return 0;
205 }
206 
207 static inline int dict_attr_ref_aunresolved(fr_dict_attr_t **da_p, char const *ref, fr_dict_attr_ref_type_t type)
208 {
210  fr_dict_attr_t *da;
211 
212  ext = fr_dict_attr_ext((*da_p), FR_DICT_ATTR_EXT_REF);
213  if (unlikely(!ext)) {
215  if (unlikely(!ext)) return -1;
216  }
217  da = *da_p;
218  if (unlikely(ext->type != 0)) {
219  fr_strerror_printf("Attribute already contains a populatd 'ref' extension");
220  return -1;
221  }
222  ext->type = type | FR_DICT_ATTR_REF_UNRESOLVED; /* Always unresolved */
223  ext->unresolved = talloc_typed_strdup(da, ref);
224 
225  return 0;
226 }
227 
228 static inline int dict_attr_children_set(fr_dict_attr_t const *da, fr_dict_attr_t const **children)
229 {
231 
233  if (unlikely(!ext)) {
234  fr_strerror_printf("Attribute contains no 'children' extension");
235  return -1;
236  }
237  ext->children = children;
238 
239  return 0;
240 }
241 
242 static inline fr_dict_attr_t const **dict_attr_children(fr_dict_attr_t const *da)
243 {
245 
247  if (unlikely(!ext)) {
248  fr_strerror_printf("Attribute contains no 'children' extension");
249  return NULL;
250  }
251  return ext->children;
252 }
253 
254 /** Return the namespace hash table associated with the attribute
255  *
256  * @param[in] da to return the reference for.
257  * @return
258  * - NULL if no namespace available.
259  * - A pointer to the namespace hash table
260  */
262 {
263  fr_dict_attr_t const *ref;
265 
266  ref = fr_dict_attr_ref(da);
267  if (unlikely(ref != NULL)) return NULL;
268 
270  if (!ext) return NULL;
271 
272  return ext->namespace;
273 }
274 /** @} */
275 
276 #ifdef __cplusplus
277 }
278 #endif
#define RCSIDH(h, id)
Definition: build.h:482
#define unlikely(_x)
Definition: build.h:379
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition: dict_util.c:2400
bool fr_dict_is_read_only(fr_dict_t const *dict)
Definition: dict_util.c:2405
fr_dict_attr_ext_t
Extension identifier.
Definition: dict.h:161
@ FR_DICT_ATTR_EXT_NAMESPACE
Attribute has its own namespace.
Definition: dict.h:169
@ FR_DICT_ATTR_EXT_REF
Attribute references another attribute and/or dictionary.
Definition: dict.h:164
@ FR_DICT_ATTR_EXT_CHILDREN
Attribute has children.
Definition: dict.h:163
fr_ext_t const fr_dict_attr_ext_def
Holds additional information about extension structures.
Definition: dict_ext.c:213
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
Definition: dict_ext.h:140
fr_dict_attr_ref_type_t type
The state of the reference.
Definition: dict_ext.h:77
fr_dict_attr_t const ** children
Children of this attribute.
Definition: dict_ext.h:54
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:184
#define fr_dict_attr_ref_is_unresolved(_type)
Definition: dict_ext.h:70
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:65
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:116
Attribute extension - Holds a reference to an attribute in another dictionary.
Definition: dict_ext.h:76
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 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.
Definition: dict_ext_priv.h:43
static void * dict_attr_ext_alloc(fr_dict_attr_t **da_p, fr_dict_attr_ext_t ext)
Allocate an attribute extension.
Definition: dict_ext_priv.h:56
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.
Definition: dict_ext_priv.h:69
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 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.
Definition: dict_ext_priv.h:90
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.
Definition: dict_ext_priv.h:77
static fr_dict_attr_t const ** dict_attr_children(fr_dict_attr_t const *da)
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_debug(char const *name, fr_dict_attr_t const *da)
Print extension debug information for attributes.
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 fr_ext_len(fr_ext_t const *def, TALLOC_CTX const *chunk, int ext)
Return the length of an extension.
Definition: ext.c:128
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:336
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:160
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:245
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)
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:445
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64