24RCSID(
"$Id: b96dfda1d29e50a1c8556b4f11a72dea276f3da8 $")
26#include <freeradius-devel/util/dict.h>
27#include <freeradius-devel/util/file.h>
28#include <freeradius-devel/util/sbuff.h>
29#include <freeradius-devel/util/strerror.h>
30#include <freeradius-devel/util/types.h>
31#include <freeradius-devel/util/talloc.h>
32#include <freeradius-devel/util/value.h>
157 fr_sbuff_terminate(&proto_name_sbuff);
217 da = absolute_root ? dict->root : rel;
247 char const *attr,
size_t attr_len,
248 char const *
name,
size_t name_len,
249 char const *
value,
size_t value_len,
268 fixup->
filename = talloc_strdup(fixup, filename);
301 fixup->
value, talloc_array_length(fixup->
value) - 1,
313 if (ret < 0)
return -1;
341 .ref = talloc_strdup(fixup, ref),
373 fr_strerror_printf(
"References MUST NOT refer to an ATTRIBUTE which also has 'ref=...' at %s[%d]",
433 if (src->dict->proto != dst->dict->proto) {
434 fr_strerror_printf(
"Incompatible protocols. Referenced '%s', referencing '%s'. Defined at %s[%d]",
435 src->dict->proto->name, dst->dict->proto->name, dst->filename, dst->line);
443 if (src->depth < dst->depth) {
456 fr_strerror_printf(
"References MUST NOT refer to an ATTRIBUTE which itself has a 'ref=...' at %s[%d]",
501 if (copied < 0)
return -1;
531 cloned->attr = dst->attr;
532 cloned->parent = dst->parent;
533 cloned->depth = cloned->parent->depth + 1;
540 fr_strerror_printf(
"Failed populating attribute '%s' with children of %s", src->name, dst->name);
550 fr_strerror_printf(
"Failed populating attribute '%s' with children of %s", src->name, dst->name);
646 if (src->dict->proto != fixup->
da->dict->proto) {
647 fr_strerror_printf(
"Incompatible protocols. Referenced '%s', referencing '%s'. Defined at %s[%d]",
648 src->dict->proto->name, fixup->
da->dict->proto->name, fixup->
da->filename, fixup->
da->line);
653 fr_strerror_printf(
"References MUST NOT refer to an ATTRIBUTE which itself has a 'ref=...' at %s[%d]",
663 if (src->type != fixup->
da->type) {
679 if (copied < 0)
return -1;
735 if (!dict->vendors_by_num)
return 0;
779 .alias_parent = alias_parent,
781 .ref_parent = ref_parent
784 fixup->
filename = talloc_strdup(fixup, filename);
800 fr_strerror_printf(
"Attribute '%s' aliased by '%s' doesn't exist in namespace '%s', at %s[%d]",
818 if (fctx->
pool)
return 0;
827 if (!fctx->
pool)
return -1;
838#define APPLY_FIXUP(_fctx, _list, _func, _type) \
841 while ((_fixup = fr_dlist_head(&(_fctx)->_list))) { \
842 if (_func(_fctx, _fixup) < 0) return -1; \
843 fr_dlist_remove(&(_fctx)->_list, _fixup); \
844 talloc_free(_fixup); \
868 TALLOC_FREE(fctx->
pool);
#define L(_str)
Helper for initialising arrays of string literals.
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.
int fr_dict_attr_add_initialised(fr_dict_attr_t *da)
A variant of fr_dict_attr_t that allows a pre-allocated, populated fr_dict_attr_t to be added.
ssize_t fr_dict_valid_oid_str(char const *name, ssize_t len)
int fr_dict_enum_add_name(fr_dict_attr_t *da, char const *name, fr_value_box_t const *value, bool coerce, bool replace)
Add a value name.
char const * name
Vendor name.
fr_dict_t * fr_dict_unconst(fr_dict_t const *dict)
Coerce to non-const.
fr_dict_t const * fr_dict_by_da(fr_dict_attr_t const *da)
Attempt to locate the protocol dictionary containing an attribute.
int fr_dict_walk(fr_dict_attr_t const *da, fr_dict_walk_t callback, void *uctx)
fr_dict_attr_t * fr_dict_attr_unconst(fr_dict_attr_t const *da)
Coerce to non-const.
fr_slen_t fr_dict_attr_by_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_attr_t const *parent, fr_sbuff_t *in, fr_sbuff_term_t const *tt))
Resolve an attribute using an OID string.
int fr_dict_protocol_afrom_file(fr_dict_t **out, char const *proto_name, char const *proto_dir, char const *dependent)
(Re)-initialize a protocol dictionary
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
uint32_t pen
Private enterprise number.
@ FR_DICT_ATTR_EXT_ENUMV
Enumeration values.
int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, unsigned int attr, fr_type_t type, fr_dict_attr_flags_t const *flags))
Add an attribute to the dictionary.
fr_dict_attr_t const * fr_dict_attr_by_oid(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *oid))
Resolve an attribute using an OID string.
#define fr_dict_attr_is_key_field(_da)
#define FR_DICT_ATTR_MAX_NAME_LEN
Maximum length of a attribute name.
fr_hash_table_t * name_by_value
Lookup a name by value.
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
fr_hash_table_t * value_by_name
Lookup an enumeration value by name.
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.
Attribute extension - Holds enumeration values.
static fr_hash_table_t * dict_attr_namespace(fr_dict_attr_t const *da)
Return the namespace hash table associated with the attribute.
static int dict_attr_ref_resolve(fr_dict_attr_t const *da, fr_dict_attr_t const *ref)
static fr_dict_attr_t const ** dict_attr_children(fr_dict_attr_t const *da)
fr_dict_attr_t * da
FR_TYPE_GROUP to fix.
dict_fixup_common_t common
Common fields.
int dict_fixup_apply(dict_fixup_ctx_t *fctx)
Apply all outstanding fixes to a set of dictionaries.
char * ref
the target attribute to clone
char * attribute
we couldn't find (and will need to resolve later).
static int dict_fixup_clone_apply(UNUSED dict_fixup_ctx_t *fctx, dict_fixup_clone_t *fixup)
Clone one are of a tree into another.
char * value
Raw enum value.
char * alias
we need to create.
char * ref
what the alias references.
static int dict_fixup_common(fr_dlist_head_t *fixup_list, dict_fixup_common_t *common)
Initialise common fields in fixup struct, and add it to a fixup list.
char * filename
where the line being fixed up.
int dict_fixup_enumv_enqueue(dict_fixup_ctx_t *fctx, char const *filename, int line, char const *attr, size_t attr_len, char const *name, size_t name_len, char const *value, size_t value_len, fr_dict_attr_t const *parent)
Add an enumeration value to an attribute which has not yet been defined.
int dict_fixup_alias_enqueue(dict_fixup_ctx_t *fctx, char const *filename, int line, fr_dict_attr_t *alias_parent, char const *alias, fr_dict_attr_t *ref_parent, char const *ref)
Resolve a group reference.
int dict_fixup_clone_enqueue(dict_fixup_ctx_t *fctx, fr_dict_attr_t *da, char const *ref)
Clone one area of a tree into another.
dict_fixup_common_t common
Common fields.
dict_fixup_common_t common
Common fields.
static int dict_fixup_clone_enum_apply(UNUSED dict_fixup_ctx_t *fctx, dict_fixup_clone_t *fixup)
Clone one are of a tree into another.
int dict_fixup_init(TALLOC_CTX *ctx, dict_fixup_ctx_t *fctx)
Initialise a fixup ctx.
int dict_fixup_clone_enum_enqueue(dict_fixup_ctx_t *fctx, fr_dict_attr_t *da, char const *ref)
Clone enumeration values from one attribute to another.
static int dict_fixup_vsa_apply(UNUSED dict_fixup_ctx_t *fctx, dict_fixup_vsa_t *fixup)
Run VSA fixups.
fr_dict_attr_t * alias_parent
Where to add the alias.
fr_dict_attr_t const * dict_protocol_reference(fr_dict_attr_t const *rel, char const *ref, bool absolute_root)
Resolve a ref= or copy= value to a dictionary.
fr_dlist_t entry
Entry in linked list of fctx.
fr_dict_attr_t const * parent
Parent attribute to resolve the 'attribute' string in.
static int _dict_attr_fixup_hash_tables(fr_dict_attr_t const *da, UNUSED void *uctx)
Fixup all hash tables in the dictionary so they're suitable for threaded access.
dict_fixup_common_t common
Common fields.
char * filename
where the line being fixed up.
fr_hash_table_t * hash
We need to finalise.
int dict_fixup_vsa_enqueue(dict_fixup_ctx_t *fctx, fr_dict_attr_t *da)
Push a fixup for a VSA.
int dict_fixup_clone(fr_dict_attr_t **dst_p, fr_dict_attr_t const *src)
Clone a dictionary attribute from a ref.
static int dict_fixup_group_apply(UNUSED dict_fixup_ctx_t *fctx, dict_fixup_group_t *fixup)
Resolve a group reference.
dict_fixup_common_t common
Common fields.
int dict_fixup_group_enqueue(dict_fixup_ctx_t *fctx, fr_dict_attr_t *da, char const *ref)
Resolve a group reference.
char * ref
the reference name
static int dict_fixup_enumv_apply(UNUSED dict_fixup_ctx_t *fctx, dict_fixup_enumv_t *fixup)
Add a previously defined enumeration value to an existing attribute.
#define APPLY_FIXUP(_fctx, _list, _func, _type)
fr_dict_attr_t * ref_parent
Parent attribute to resolve the 'attribute' string in.
char * name
Raw enum name.
void dict_hash_tables_finalise(fr_dict_t *dict)
Walk a dictionary finalising the hash tables in all attributes with a distinct namespace.
fr_dict_attr_t * da
FR_TYPE_VSA to fix.
static int dict_fixup_alias_apply(UNUSED dict_fixup_ctx_t *fctx, dict_fixup_alias_t *fixup)
fr_dict_attr_t * da
to populate with cloned information.
dict_fixup_common_t common
Common fields.
Add an enumeration value to an attribute that wasn't defined at the time the value was parsed.
Clone operation from one tree node to another.
Common fields for every fixup structure.
Add an enumeration value to an attribute that wasn't defined at the time the value was parsed.
Resolve a group reference.
Dictionary attribute namespaces need their hash tables finalised.
Run fixup callbacks for a VSA.
Functions to finalise and fixup dictionaries.
fr_dlist_head_t alias
Aliases that can't be resolved immediately.
fr_dlist_head_t group
Group references to resolve.
fr_dlist_head_t clone
Clone operation to apply.
fr_dlist_head_t vsa
VSAs to add vendors for.
fr_dlist_head_t enumv
Raw enumeration values to add.
TALLOC_CTX * pool
Temporary pool for fixups, reduces holes.
fr_slen_t dict_by_protocol_substr(fr_dict_attr_err_t *err, fr_dict_t **out, fr_sbuff_t *name, fr_dict_t const *dict_def)
#define DICT_FIXUP_POOL_SIZE
fr_dict_attr_t * dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr)
Internal version of fr_dict_attr_child_by_num.
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.
int dict_attr_alias_add(fr_dict_attr_t const *parent, char const *alias, fr_dict_attr_t const *ref)
Add an alias to an existing attribute.
int dict_attr_acopy_enumv(fr_dict_attr_t *dst, fr_dict_attr_t const *src)
Copy the VALUEs of an existing attribute, by casting them.
static int fr_dlist_insert_tail(fr_dlist_head_t *list_head, void *ptr)
Insert an item into the tail of a list.
#define fr_dlist_talloc_init(_head, _type, _field)
Initialise the head structure of a doubly linked list.
Head of a doubly linked list.
Entry in a doubly linked list.
char const * fr_cwd_strip(char const *filename)
Intended to be used in logging functions to make output more readable.
void * fr_hash_table_iter_next(fr_hash_table_t *ht, fr_hash_iter_t *iter)
Iterate over entries in a hash table.
void * fr_hash_table_iter_init(fr_hash_table_t *ht, fr_hash_iter_t *iter)
Initialise an iterator.
bool fr_hash_table_insert(fr_hash_table_t *ht, void const *data)
Insert data into a hash table.
void fr_hash_table_fill(fr_hash_table_t *ht)
Ensure all buckets are filled.
Stores the state of the current iteration operation.
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_VENDOR
Attribute that represents a vendor in the attribute tree.
size_t fr_sbuff_out_bstrncpy_until(fr_sbuff_t *out, fr_sbuff_t *in, size_t len, fr_sbuff_term_t const *tt, fr_sbuff_unescape_rules_t const *u_rules)
char * fr_tolower(char *str)
static unsigned int hash(char const *username, unsigned int tablesize)
bool fr_sbuff_next_if_char(fr_sbuff_t *sbuff, char c)
Return true if the current char matches, and if it does, advance.
#define FR_SBUFF_IN(_start, _len_or_end)
#define FR_SBUFF_TERMS(...)
Initialise a terminal structure with a list of sorted strings.
#define FR_SBUFF_OUT(_start, _len_or_end)
fr_aka_sim_id_type_t type
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
#define fr_strerror_const(_msg)
#define fr_type_is_non_leaf(_x)
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
ssize_t fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, char const *in, size_t inlen, fr_sbuff_unescape_rules_t const *erules, bool tainted)
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
#define fr_box_strvalue_buffer(_val)
#define FR_VALUE_BOX_INITIALISER_NULL(_vb)
A static initialiser for stack/globally allocated boxes.