The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
dict_ext.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 /** Extensions to dictionary structures
18  *
19  * @file src/lib/util/dict_ext.c
20  *
21  * @copyright 2020 The FreeRADIUS server project
22  * @copyright 2020 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
23  */
24 RCSID("$Id: f3c2444b30af84446076a2d11a49f23d3b549653 $")
25 
26 #include <freeradius-devel/util/dict_priv.h>
27 
29  { L("name"), FR_DICT_ATTR_EXT_NAME },
30  { L("children"), FR_DICT_ATTR_EXT_CHILDREN },
31  { L("ref"), FR_DICT_ATTR_EXT_REF },
32  { L("vendor"), FR_DICT_ATTR_EXT_VENDOR },
33  { L("da_stack"), FR_DICT_ATTR_EXT_DA_STACK },
34  { L("enumv"), FR_DICT_ATTR_EXT_ENUMV },
35  { L("namespace"), FR_DICT_ATTR_EXT_NAMESPACE },
36  { L("protocol-specific"), FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC }
37 };
39 
40 /** Fixup name pointer on realloc
41  *
42  */
44  TALLOC_CTX *chunk,
45  void *ext_ptr, UNUSED size_t ext_ptr_len)
46 {
47  fr_dict_attr_t *da = talloc_get_type_abort(chunk, fr_dict_attr_t);
48 
49  da->name = ext_ptr;
50 
51  return 0;
52 }
53 
54 /** Copy all enumeration values from one attribute to another
55  *
56  */
58  TALLOC_CTX *chunk_dst,
59  UNUSED void *dst_ext_ptr, UNUSED size_t dst_ext_len,
60  TALLOC_CTX const *chunk_src,
61  void *src_ext_ptr, UNUSED size_t src_ext_len)
62 {
63  fr_dict_attr_t const *da_src = talloc_get_type_abort_const(chunk_src, fr_dict_attr_t);
64  fr_dict_attr_t *da_dst = talloc_get_type_abort(chunk_dst, fr_dict_attr_t);
65  fr_dict_attr_ext_enumv_t *src_ext = src_ext_ptr;
66  fr_hash_iter_t iter;
67  fr_dict_enum_value_t *enumv;
68  bool has_child = fr_dict_attr_is_key_field(da_src);
69 
70  if (!src_ext->value_by_name) return 0;
71 
72  /*
73  * Add all the enumeration values from
74  * the old attribute to the new attribute.
75  */
76  for (enumv = fr_hash_table_iter_init(src_ext->value_by_name, &iter);
77  enumv;
78  enumv = fr_hash_table_iter_next(src_ext->value_by_name, &iter)) {
79  fr_dict_attr_t *child_struct;
80 
81  if (!has_child) {
82  child_struct = NULL;
83  } else {
84  fr_dict_t *dict = dict_by_da(enumv->child_struct[0]);
85 
86  /*
87  * Copy the child_struct, and all if it's children recursively.
88  */
89  child_struct = dict_attr_acopy(dict->pool, enumv->child_struct[0], NULL);
90  if (!child_struct) return -1;
91 
92  child_struct->parent = da_dst; /* we need to re-parent this attribute */
93 
94  if (dict_attr_children(enumv->child_struct[0])) {
95  if (dict_attr_acopy_children(dict, child_struct, enumv->child_struct[0]) < 0) return -1;
96  }
97  }
98 
99  if (dict_attr_enum_add_name(da_dst, enumv->name, enumv->value,
100  true, true, child_struct) < 0) return -1;
101  }
102 
103  return 0;
104 }
105 
106 /** Rediscover the parent of this attribute, and cache it
107  *
108  */
110  TALLOC_CTX *chunk_dst,
111  void *dst_ext_ptr, UNUSED size_t dst_ext_len,
112  UNUSED TALLOC_CTX const *chunk_src,
113  void *src_ext_ptr, UNUSED size_t src_ext_len)
114 {
115  fr_dict_attr_t *da_dst = talloc_get_type_abort(chunk_dst, fr_dict_attr_t);
116  fr_dict_attr_ext_vendor_t *dst_ext = dst_ext_ptr, *src_ext = src_ext_ptr;
117  fr_dict_attr_t const **da_stack;
118  fr_dict_attr_t const *old_vendor = src_ext->vendor;
119  fr_dict_attr_t const *new_vendor, *da;
120 
121  if (!old_vendor) {
122  dst_ext->vendor = NULL;
123  return 0;
124  }
125 
126  /*
127  * If we have a da stack, see if we can
128  * find a vendor at the same depth as
129  * the old depth.
130  */
131  da_stack = fr_dict_attr_da_stack(da_dst);
132  if (da_stack) {
133  new_vendor = da_stack[old_vendor->depth];
134  if ((new_vendor->type == old_vendor->type) && (new_vendor->attr == old_vendor->attr)) {
135  dst_ext->vendor = new_vendor;
136  return 0;
137  }
138  }
139 
140  /*
141  * Otherwise traverse the parent list
142  * looking for the vendor.
143  *
144  * Theoretically the attribute could
145  * have been moved to a different depth.
146  */
147  for (da = da_dst->parent; da; da = da->parent) {
148  if ((da->type == old_vendor->type) && (da->attr == old_vendor->attr)) {
149  dst_ext->vendor = da;
150  return 0;
151  }
152  }
153 
154  return -1;
155 }
156 
157 /** Holds additional information about extension structures
158  *
159  */
161  .offset_of_exts = offsetof(fr_dict_attr_t, ext),
162  .name_table = dict_attr_ext_table,
163  .name_table_len = &dict_attr_ext_table_len,
164  .max = FR_DICT_ATTR_EXT_MAX,
165  .info = (fr_ext_info_t[]){ /* -Wgnu-flexible-array-initializer */
167  .min = sizeof(char),
168  .has_hdr = true,
170  .can_copy = false, /* Name may change, and we can only set it once */
171  },
173  .min = sizeof(fr_dict_attr_ext_children_t),
174  .can_copy = false, /* Limitation in hashing scheme we use */
175  },
177  .min = sizeof(fr_dict_attr_ext_ref_t),
178  .can_copy = true,
179  },
181  .min = sizeof(fr_dict_attr_ext_vendor_t),
182  .can_copy = true,
184  },
186  .min = sizeof(fr_dict_attr_ext_da_stack_t),
187  .has_hdr = true,
188  .can_copy = false /* Reinitialised for each new attribute */
189  },
191  .min = sizeof(fr_dict_attr_ext_enumv_t),
192  .can_copy = true,
194  },
196  .min = sizeof(fr_dict_attr_ext_namespace_t),
197  .can_copy = false, /* Same limitation as ext_children */
198  },
200  .min = FR_EXT_ALIGNMENT, /* allow for one byte of protocol stuff */
201  .has_hdr = true, /* variable sized */
202  .can_copy = false /* only the protocol can copy it */
203  },
204  [FR_DICT_ATTR_EXT_MAX] = {}
205  }
206 };
207 
209  { L("union_ref"), FR_DICT_ENUM_EXT_UNION_REF }
210 };
212 
214 {
215  fr_ext_debug(&fr_dict_attr_ext_def, da->name, da);
216 }
217 
218 /** Holds additional information about extension structures
219  *
220  */
222  .offset_of_exts = offsetof(fr_dict_enum_value_t, ext),
223  .name_table = dict_enum_ext_table,
224  .name_table_len = &dict_enum_ext_table_len,
225  .max = FR_DICT_ENUM_EXT_MAX,
226  .info = (fr_ext_info_t[]){ /* -Wgnu-flexible-array-initializer */
228  .min = sizeof(fr_dict_enum_ext_union_ref_t),
229  .can_copy = true
230  },
231  [FR_DICT_ENUM_EXT_MAX] = {}
232  }
233 };
234 
static fr_dict_t * dict
Definition: fuzzer.c:46
#define RCSID(id)
Definition: build.h:444
#define L(_str)
Helper for initialising arrays of string literals.
Definition: build.h:207
#define UNUSED
Definition: build.h:313
#define NUM_ELEMENTS(_t)
Definition: build.h:335
@ FR_DICT_ENUM_EXT_MAX
Definition: dict.h:202
@ FR_DICT_ENUM_EXT_UNION_REF
Reference to a union/subs-struct.
Definition: dict.h:201
fr_value_box_t const * value
Enum value (what name maps to).
Definition: dict.h:213
@ FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC
Protocol specific extensions.
Definition: dict.h:168
@ FR_DICT_ATTR_EXT_MAX
Definition: dict.h:169
@ FR_DICT_ATTR_EXT_ENUMV
Enumeration values.
Definition: dict.h:166
@ FR_DICT_ATTR_EXT_NAMESPACE
Attribute has its own namespace.
Definition: dict.h:167
@ FR_DICT_ATTR_EXT_DA_STACK
Cached da stack.
Definition: dict.h:165
@ FR_DICT_ATTR_EXT_REF
Attribute references another attribute and/or dictionary.
Definition: dict.h:162
@ FR_DICT_ATTR_EXT_VENDOR
Cached vendor pointer.
Definition: dict.h:164
@ FR_DICT_ATTR_EXT_NAME
Name of the attribute.
Definition: dict.h:160
@ FR_DICT_ATTR_EXT_CHILDREN
Attribute has children.
Definition: dict.h:161
#define fr_dict_attr_is_key_field(_da)
Definition: dict.h:149
char const * name
Enum name.
Definition: dict.h:210
fr_dict_attr_t const * child_struct[]
for key fields
Definition: dict.h:217
Value of an enumerated attribute.
Definition: dict.h:209
fr_ext_t const fr_dict_attr_ext_def
Holds additional information about extension structures.
Definition: dict_ext.c:160
fr_ext_t const fr_dict_enum_ext_def
Holds additional information about extension structures.
Definition: dict_ext.c:221
static int fr_dict_attr_ext_vendor_copy(UNUSED int ext, TALLOC_CTX *chunk_dst, void *dst_ext_ptr, UNUSED size_t dst_ext_len, UNUSED TALLOC_CTX const *chunk_src, void *src_ext_ptr, UNUSED size_t src_ext_len)
Rediscover the parent of this attribute, and cache it.
Definition: dict_ext.c:109
static size_t dict_attr_ext_table_len
Definition: dict_ext.c:38
static size_t dict_enum_ext_table_len
Definition: dict_ext.c:211
static int fr_dict_attr_ext_enumv_copy(UNUSED int ext, TALLOC_CTX *chunk_dst, UNUSED void *dst_ext_ptr, UNUSED size_t dst_ext_len, TALLOC_CTX const *chunk_src, void *src_ext_ptr, UNUSED size_t src_ext_len)
Copy all enumeration values from one attribute to another.
Definition: dict_ext.c:57
void fr_dict_attr_ext_debug(fr_dict_attr_t const *da)
Definition: dict_ext.c:213
static fr_table_num_ordered_t const dict_enum_ext_table[]
Definition: dict_ext.c:208
static fr_table_num_ordered_t const dict_attr_ext_table[]
Definition: dict_ext.c:28
static int fr_dict_attr_ext_name_fixup(UNUSED int ext, TALLOC_CTX *chunk, void *ext_ptr, UNUSED size_t ext_ptr_len)
Fixup name pointer on realloc.
Definition: dict_ext.c:43
fr_dict_attr_t const * vendor
ancestor which has type FR_TYPE_VENDOR
Definition: dict_ext.h:68
static fr_dict_attr_t const ** fr_dict_attr_da_stack(fr_dict_attr_t const *da)
Return the cached da stack (if any) associated with an attribute.
Definition: dict_ext.h:147
fr_hash_table_t * value_by_name
Lookup an enumeration value by name.
Definition: dict_ext.h:89
Attribute extension - Holds children for an attribute.
Definition: dict_ext.h:52
Attribute extension - Stack of dictionary attributes that describe the path back to the root of the d...
Definition: dict_ext.h:74
Attribute extension - Holds enumeration values.
Definition: dict_ext.h:87
Attribute extension - Holds a hash table with the names of all children of this attribute.
Definition: dict_ext.h:96
Attribute extension - Holds a reference to an attribute in another dictionary.
Definition: dict_ext.h:60
Attribute extension - Cached vendor pointer.
Definition: dict_ext.h:67
Enum extension - Sub-struct or union pointer.
Definition: dict_ext.h:103
static fr_dict_attr_t const ** dict_attr_children(fr_dict_attr_t const *da)
fr_dict_t * dict_by_da(fr_dict_attr_t const *da)
Internal version of fr_dict_by_da.
Definition: dict_util.c:2133
int dict_attr_enum_add_name(fr_dict_attr_t *da, char const *name, fr_value_box_t const *value, bool coerce, bool replace, fr_dict_attr_t const *child_struct)
Definition: dict_util.c:1346
fr_dict_attr_t * dict_attr_acopy(TALLOC_CTX *ctx, fr_dict_attr_t const *in, char const *new_name)
Copy a an existing attribute.
Definition: dict_util.c:725
int dict_attr_acopy_children(fr_dict_t *dict, fr_dict_attr_t *dst, fr_dict_attr_t const *src)
Copy the children of an existing attribute.
Definition: dict_util.c:751
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
size_t offset_of_exts
Where in the extended struct the extensions array starts.
Definition: ext.h:127
#define FR_EXT_ALIGNMENT
The alignment of object extension structures.
Definition: ext.h:54
Additional information for a given extension.
Definition: ext.h:111
Structure to define a set of extensions.
Definition: ext.h:126
void * fr_hash_table_iter_init(fr_hash_table_t *ht, fr_hash_iter_t *iter)
Initialise an iterator.
Definition: hash.c:672
void * fr_hash_table_iter_next(fr_hash_table_t *ht, fr_hash_iter_t *iter)
Iterate over entries in a hash table.
Definition: hash.c:620
Stores the state of the current iteration operation.
Definition: hash.h:41
An element in an arbitrarily ordered array of name to num mappings.
Definition: table.h:53
#define talloc_get_type_abort_const
Definition: talloc.h:270