24 RCSID(
"$Id: 9c28f3d6eabc6e414d9dd4edcfadd16b31be64f2 $")
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>
148 fr_sbuff_terminate(&proto_name_sbuff);
236 char const *attr,
size_t attr_len,
237 char const *
name,
size_t name_len,
238 char const *
value,
size_t value_len,
257 fixup->
filename = talloc_strdup(fixup, filename);
290 fixup->
value, talloc_array_length(fixup->
value) - 1,
302 if (ret < 0)
return -1;
330 .ref = talloc_strdup(fixup, ref),
362 fr_strerror_printf(
"References MUST NOT refer to an ATTRIBUTE which also has 'ref=...' at %s[%d]",
422 if (src->dict->proto != dst->dict->proto) {
423 fr_strerror_printf(
"Incompatible protocols. Referenced '%s', referencing '%s'. Defined at %s[%u]",
424 src->dict->proto->name, dst->dict->proto->name, dst->filename, dst->line);
432 if (src->depth < dst->depth) {
445 fr_strerror_printf(
"References MUST NOT refer to an ATTRIBUTE which itself has a 'ref=...' at %s[%d]",
490 if (copied < 0)
return -1;
520 cloned->attr = dst->attr;
521 cloned->parent = dst->parent;
522 cloned->depth = cloned->parent->depth + 1;
529 fr_strerror_printf(
"Failed populating attribute '%s' with children of %s", src->name, dst->name);
539 fr_strerror_printf(
"Failed populating attribute '%s' with children of %s", src->name, dst->name);
635 if (src->dict->proto != fixup->
da->dict->proto) {
636 fr_strerror_printf(
"Incompatible protocols. Referenced '%s', referencing '%s'. Defined at %s[%u]",
637 src->dict->proto->name, fixup->
da->dict->proto->name, fixup->
da->filename, fixup->
da->line);
642 fr_strerror_printf(
"References MUST NOT refer to an ATTRIBUTE which itself has a 'ref=...' at %s[%d]",
652 if (src->type != fixup->
da->type) {
668 if (copied < 0)
return -1;
724 if (!
dict->vendors_by_num)
return 0;
768 .alias_parent = alias_parent,
770 .ref_parent = ref_parent
773 fixup->
filename = talloc_strdup(fixup, filename);
789 fr_strerror_printf(
"Attribute '%s' aliased by '%s' doesn't exist in namespace '%s', at %s[%u]",
807 if (fctx->
pool)
return 0;
816 if (!fctx->
pool)
return -1;
827 #define APPLY_FIXUP(_fctx, _list, _func, _type) \
830 while ((_fixup = fr_dlist_head(&(_fctx)->_list))) { \
831 if (_func(_fctx, _fixup) < 0) return -1; \
832 fr_dlist_remove(&(_fctx)->_list, _fixup); \
833 talloc_free(_fixup); \
857 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.
fr_dcursor_eval_t void const * uctx
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.
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_attr_t * fr_dict_attr_unconst(fr_dict_attr_t const *da)
Coerce to non-const.
int fr_dict_walk(fr_dict_attr_t const *da, fr_dict_walk_t callback, void *uctx)
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_t const * fr_dict_by_da(fr_dict_attr_t const *da)
Attempt to locate the protocol dictionary containing an attribute.
fr_dict_t * fr_dict_unconst(fr_dict_t const *dict)
Coerce to non-const.
@ 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.
#define fr_dict_attr_is_key_field(_da)
#define FR_DICT_ATTR_MAX_NAME_LEN
Maximum length of a attribute name.
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
fr_hash_table_t * name_by_value
Lookup a name by value.
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.
fr_hash_table_t * value_by_name
Lookup an enumeration value by name.
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.
fr_dict_attr_t const * dict_protocol_reference(fr_dict_attr_t const *root, char const *ref)
Resolve a ref= or copy= value to a dictionary.
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_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)
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.
#define DICT_FIXUP_POOL_SIZE
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.
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.
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_init(fr_hash_table_t *ht, fr_hash_iter_t *iter)
Initialise an iterator.
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_fill(fr_hash_table_t *ht)
Ensure all buckets are filled.
bool fr_hash_table_insert(fr_hash_table_t *ht, void const *data)
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_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
#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.