From: Arran Cudbard-Bell Date: Mon, 15 May 2017 17:25:52 +0000 (-0400) Subject: Allow value aliases (enumerations) to work with any attribute type, not just integers X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=619ffaaa88da791c4d020a1c82280a7e901aaba4;p=thirdparty%2Ffreeradius-server.git Allow value aliases (enumerations) to work with any attribute type, not just integers --- diff --git a/src/include/dict.h b/src/include/dict.h index d0e5b37a018..fb9c0d2c142 100644 --- a/src/include/dict.h +++ b/src/include/dict.h @@ -26,6 +26,14 @@ #include #include +/* + * Avoid circular type references. + */ +typedef struct dict_attr fr_dict_attr_t; +typedef struct fr_dict fr_dict_t; + +#include + #ifdef __cplusplus extern "C" { #endif @@ -72,9 +80,6 @@ typedef struct attr_flags { extern const FR_NAME_NUMBER dict_attr_types[]; extern const size_t dict_attr_sizes[FR_TYPE_MAX + 1][2]; - -typedef struct dict_attr fr_dict_attr_t; -typedef struct fr_dict fr_dict_t; extern fr_dict_t *fr_dict_internal; /** Dictionary attribute @@ -82,7 +87,7 @@ extern fr_dict_t *fr_dict_internal; struct dict_attr { unsigned int vendor; //!< Vendor that defines this attribute. unsigned int attr; //!< Attribute number. - fr_type_t type; //!< Value type. + fr_type_t type; //!< Value type. fr_dict_attr_t const *parent; //!< Immediate parent of this attribute. fr_dict_attr_t const **children; //!< Children of this attribute. @@ -100,8 +105,8 @@ struct dict_attr { */ typedef struct dict_enum { fr_dict_attr_t const *da; //!< Dictionary attribute enum is associated with. - int64_t value; //!< Enum value - char name[1]; //!< Enum name. + char const *alias; //!< Enum name. + fr_value_box_t const *value; //!< Enum value (what name maps to). } fr_dict_enum_t; /** Private enterprise @@ -151,7 +156,6 @@ typedef struct dict_vendor { */ extern bool const fr_dict_attr_allowed_chars[UINT8_MAX]; extern bool const fr_dict_non_data_types[FR_TYPE_MAX + 1]; -extern bool const fr_dict_enum_types[FR_TYPE_MAX + 1]; /* * Dictionary debug @@ -166,12 +170,13 @@ int fr_dict_vendor_add(fr_dict_t *dict, char const *name, unsigned int value); int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, int attr, fr_type_t type, fr_dict_attr_flags_t flags); -int fr_dict_enum_add(fr_dict_t *dict, char const *attr, char const *alias, int value); +int fr_dict_enum_add_alias(fr_dict_attr_t const *da, char const *alias, + fr_value_box_t const *value, bool coerce, bool replace); int fr_dict_str_to_argv(char *str, char **argv, int max_argc); int fr_dict_from_file(TALLOC_CTX *ctx, fr_dict_t **out, - char const *dir, char const *fn, char const *name); + char const *dir, char const *fn, char const *name); int fr_dict_read(fr_dict_t *dict, char const *dir, char const *filename); @@ -183,7 +188,6 @@ fr_dict_attr_t const *fr_dict_root(fr_dict_t const *dict); /* * Unknown ephemeral attributes */ - fr_dict_attr_t *fr_dict_unknown_acopy(TALLOC_CTX *ctx, fr_dict_attr_t const *da); fr_dict_attr_t const *fr_dict_unknown_add(fr_dict_t *dict, fr_dict_attr_t const *old); @@ -245,11 +249,13 @@ fr_dict_attr_t const *fr_dict_attr_child_by_da(fr_dict_attr_t const *parent, fr_ fr_dict_attr_t const *fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr); -fr_dict_enum_t *fr_dict_enum_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, int64_t value); +fr_dict_enum_t *fr_dict_enum_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, + fr_value_box_t const *value); -char const *fr_dict_enum_name_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, int64_t value); +char const *fr_dict_enum_alias_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, + fr_value_box_t const *value); -fr_dict_enum_t *fr_dict_enum_by_name(fr_dict_t *dict, fr_dict_attr_t const *da, char const *val); +fr_dict_enum_t *fr_dict_enum_by_alias(fr_dict_t *dict, fr_dict_attr_t const *da, char const *val); /* * Validation diff --git a/src/include/token.h b/src/include/token.h index 3352d676450..c2faccc63b3 100644 --- a/src/include/token.h +++ b/src/include/token.h @@ -67,7 +67,7 @@ typedef enum fr_token { typedef struct FR_NAME_NUMBER { char const *name; - int number; + int32_t number; } FR_NAME_NUMBER; extern const FR_NAME_NUMBER fr_tokens_table[]; diff --git a/src/include/value.h b/src/include/value.h index aaaeb55121d..c461a955d0d 100644 --- a/src/include/value.h +++ b/src/include/value.h @@ -17,6 +17,12 @@ #define _FR_VALUE_H #include #include + +/* + * Avoid circular type references. + */ +typedef struct value_box fr_value_box_t; + #include extern size_t const fr_value_box_field_sizes[]; @@ -31,7 +37,6 @@ extern size_t const fr_value_box_offsets[]; * * fr_type_t should be an enumeration of the values in this union. */ -typedef struct value_box fr_value_box_t; struct value_box { union { /* @@ -45,9 +50,12 @@ struct value_box { uint8_t filter[32]; //!< Ascend binary format (a packed data structure). }; - size_t length; + size_t length; }; + /* + * Fixed length values + */ fr_ipaddr_t ip; //!< IPv4/6 address/prefix. uint8_t ifid[8]; //!< IPv6 interface ID (should be struct?). @@ -55,39 +63,34 @@ struct value_box { bool boolean; //!< A truth value. - struct { - union { - uint8_t uint8; //!< 8bit unsigned integer. - uint16_t uint16; //!< 16bit unsigned integer. - uint32_t uint32; //!< 32bit unsigned integer. - uint64_t uint64; //!< 64bit unsigned integer. - uint128_t uint128; //!< 128bit unsigned integer. - - int8_t int8; //!< 8bit signed integer. - int16_t int16; //!< 16bit signed integer. - int32_t int32; //!< 32bit signed integer. - int64_t int64; //!< 64bit signed integer; - }; - fr_dict_attr_t const *enumv; //!< Enumeration values for integer type. - }; + uint8_t uint8; //!< 8bit unsigned integer. + uint16_t uint16; //!< 16bit unsigned integer. + uint32_t uint32; //!< 32bit unsigned integer. + uint64_t uint64; //!< 64bit unsigned integer. + uint128_t uint128; //!< 128bit unsigned integer. + + int8_t int8; //!< 8bit signed integer. + int16_t int16; //!< 16bit signed integer. + int32_t int32; //!< 32bit signed integer. + int64_t int64; //!< 64bit signed integer; float float32; //!< Single precision float. double float64; //!< Double precision float. uint32_t date; //!< Date (32bit Unix timestamp). - uint64_t date_miliseconds; //!< milliseconds since the epoch. - uint64_t date_microseconds; //!< microseconds since the epoch. - uint64_t date_nanoseconds; //!< nanoseconds since the epoch. + uint64_t date_miliseconds; //!< Milliseconds since the epoch. + uint64_t date_microseconds; //!< Microseconds since the epoch. + uint64_t date_nanoseconds; //!< Nanoseconds since the epoch. /* - * System specific - Used for runtime - * configuration only. + * System specific - Used for runtime configuration only. */ size_t size; //!< System specific file/memory size. struct timeval timeval; //!< A time value with usec precision. - } datum; + fr_dict_attr_t const *enumv; //!< Enumeration values. + fr_type_t type; //!< Type of this value-box. bool tainted; //!< i.e. did it come from an untrusted source diff --git a/src/lib/util/dict.c b/src/lib/util/dict.c index 35ea5e2cf4b..f3dd1af3367 100644 --- a/src/lib/util/dict.c +++ b/src/lib/util/dict.c @@ -55,10 +55,16 @@ typedef struct dict_stat_t { struct stat stat_buf; } dict_stat_t; +/** A temporary enum value, which we'll resolve later + * + */ typedef struct dict_enum_fixup_t { - char attrstr[FR_DICT_ATTR_MAX_NAME_LEN]; - fr_dict_enum_t *dval; - struct dict_enum_fixup_t *next; + char *attribute; //!< we couldn't find (and will need to resolve later). + char *alias; //!< Raw enum name. + char *value; //!< Raw enum value. We can't do anything with this until + //!< we know the attribute type, which we only find out later. + + struct dict_enum_fixup_t *next; //!< Next in the linked list of fixups. } dict_enum_fixup_t; /** Vendors and attribute names @@ -82,8 +88,8 @@ struct fr_dict { fr_hash_table_t *attributes_combo; //!< Lookup variants of polymorphic attributes. - fr_hash_table_t *values_by_da; //!< Lookup an attribute enum value by integer value. - fr_hash_table_t *values_by_name; //!< Lookup an attribute enum value by name. + fr_hash_table_t *values_by_da; //!< Lookup an attribute enum by its value. + fr_hash_table_t *values_by_alias; //!< Lookup an attribute enum by its alias name. fr_dict_attr_t *root; //!< Root attribute of this dictionary. TALLOC_CTX *pool; //!< Talloc memory pool to reduce allocs. @@ -216,19 +222,6 @@ bool const fr_dict_non_data_types[FR_TYPE_MAX + 1] = { [FR_TYPE_VENDOR] = true }; -/** Numeric dictionary types - * - * @note Must be updated to match the anonymous enum types union in fr_value_box_t - */ -bool const fr_dict_enum_types[FR_TYPE_MAX + 1] = { - [FR_TYPE_UINT8] = true, - [FR_TYPE_UINT16] = true, - [FR_TYPE_UINT32] = true, - [FR_TYPE_UINT64] = true, - [FR_TYPE_SIZE] = true, - [FR_TYPE_INT32] = true -}; - /* * Create the hash of the name. * @@ -375,19 +368,19 @@ static int dict_vendor_vendorpec_cmp(void const *one, void const *two) /** Hash a dictionary name * */ -static uint32_t dict_enum_name_hash(void const *data) +static uint32_t dict_enum_alias_hash(void const *data) { uint32_t hash; - fr_dict_enum_t const *dval = data; + fr_dict_enum_t const *enumv = data; - hash = dict_hash_name(dval->name); - return fr_hash_update(&dval->da, sizeof(dval->da), hash); + hash = dict_hash_name(enumv->alias); + return fr_hash_update(&enumv->da, sizeof(enumv->da), hash); } /** Compare two dictionary attribute enum values * */ -static int dict_enum_name_cmp(void const *one, void const *two) +static int dict_enum_alias_cmp(void const *one, void const *two) { int rcode; fr_dict_enum_t const *a = one; @@ -396,7 +389,7 @@ static int dict_enum_name_cmp(void const *one, void const *two) rcode = a->da - b->da; if (rcode != 0) return rcode; - return strcasecmp(a->name, b->name); + return strcasecmp(a->alias, b->alias); } /** Hash a dictionary enum value @@ -405,10 +398,10 @@ static int dict_enum_name_cmp(void const *one, void const *two) static uint32_t dict_enum_value_hash(void const *data) { uint32_t hash = 0; - fr_dict_enum_t const *dval = data; + fr_dict_enum_t const *enumv = data; - hash = fr_hash_update(&dval->da, sizeof(dval->da), hash); - return fr_hash_update(&dval->value, sizeof(dval->value), hash); + hash = fr_hash_update(&enumv->da, sizeof(enumv->da), hash); + return fr_hash_update(enumv->value, sizeof(enumv->value), hash); } /** Compare two dictionary enum values @@ -416,14 +409,10 @@ static uint32_t dict_enum_value_hash(void const *data) */ static int dict_enum_value_cmp(void const *one, void const *two) { - int rcode; fr_dict_enum_t const *a = one; fr_dict_enum_t const *b = two; - rcode = a->da - b->da; - if (rcode != 0) return rcode; - - return a->value - b->value; + return fr_value_box_cmp(a->value, b->value); } /** Add an entry to the list of stat buffers. @@ -1524,138 +1513,115 @@ int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, return 0; } -/* - * Add a value for an attribute to the dictionary. +/** Add a value alias + * + * Aliases are textual (string) aliases for a given value. + * + * Value aliases are not limited to integers, and may be added for any non-structural + * attribute type. + * + * @param[in] da to add enumeration value to. + * @param[in] alias Name of value alias. + * @param[in] value to associate with alias. + * @param[in] coerce if the type of the value does not match the type of the da, + * attempt to cast it to match the type of the da. If this is + * false and there's a type mismatch, we fail. + * We also fail if the value cannot be coerced to the attribute type. + * @param[in] takes_precedence This alias should take precedence over previous aliases for the + * same value, when resolving value to alias. + * @return + * - 0 on success. + * - -1 on failure. */ -int fr_dict_enum_add(fr_dict_t *dict, char const *attr, char const *alias, int value) +int fr_dict_enum_add_alias(fr_dict_attr_t const *da, char const *alias, + fr_value_box_t const *value, + bool coerce, bool takes_precedence) { - size_t length; - fr_dict_attr_t const *da; - fr_dict_enum_t *dval; - - static fr_dict_attr_t const *last_attr = NULL; - - INTERNAL_IF_NULL(dict); + size_t len; + fr_dict_t *dict; + fr_dict_enum_t *enumv = NULL; + fr_value_box_t *enum_value = NULL; - if (!*alias) { - fr_strerror_printf("%s: empty names are not permitted", __FUNCTION__); + if (!da) { + fr_strerror_printf("%s: Dictionary attribute not specified", __FUNCTION__); return -1; } - if ((length = strlen(alias)) >= FR_DICT_ENUM_MAX_NAME_LEN) { - fr_strerror_printf("%s: value name too long", __FUNCTION__); + if (!*alias) { + fr_strerror_printf("%s: Empty names are not permitted", __FUNCTION__); return -1; } - dval = (fr_dict_enum_t *)talloc_zero_array(dict->pool, uint8_t, sizeof(*dval) + length); - if (dval == NULL) { - fr_strerror_printf("%s: out of memory", __FUNCTION__); + len = strlen(alias); + if (len >= FR_DICT_ENUM_MAX_NAME_LEN) { + fr_strerror_printf("%s: Value name too long", __FUNCTION__); return -1; } - talloc_set_type(dval, fr_dict_enum_t); - strcpy(dval->name, alias); - dval->value = value; + dict = fr_dict_by_da(da); - /* - * Most VALUEs are bunched together by ATTRIBUTE. We can - * save a lot of lookups on dictionary initialization by - * caching the last attribute. - */ - if (last_attr && (strcasecmp(attr, last_attr->name) == 0)) { - da = last_attr; - } else { - da = fr_dict_attr_by_name(dict, attr); - last_attr = da; + enumv = talloc_zero(dict->pool, fr_dict_enum_t); + if (!enumv) { + fr_strerror_printf("%s: Out of memory", __FUNCTION__); + return -1; } + enumv->alias = talloc_typed_strdup(enumv, alias); + enum_value = fr_value_box_alloc(enumv, da->type); - /* - * Remember which attribute is associated with this - * value, if possible. - */ - if (da) { - dval->da = da; - - /* - * Enforce valid values - * - * Don't worry about fixups... - */ - switch (da->type) { - case FR_TYPE_UINT8: - if (value > UINT8_MAX) { - talloc_free(dval); - fr_strerror_printf("%s: ATTRIBUTEs of type 'byte' cannot have " - "VALUEs larger than %i", __FUNCTION__, UINT8_MAX); - return -1; - } - break; - case FR_TYPE_UINT16: - if (value > UINT16_MAX) { - talloc_free(dval); - fr_strerror_printf("%s: ATTRIBUTEs of type 'short' cannot have " - "VALUEs larger than %i", __FUNCTION__, UINT16_MAX); - return -1; - } - break; + if (da->type != value->type) { + if (!coerce) { + fr_strerror_printf("%s: Type mismatch between attribute (%s) and enum (%s)", + __FUNCTION__, + fr_int2str(dict_attr_types, da->type, ""), + fr_int2str(dict_attr_types, value->type, "")); + return -1; + } - case FR_TYPE_UINT32: - break; + if (fr_value_box_cast(enumv, enum_value, da->type, NULL, value) < 0) { + fr_strerror_printf_push("%s: Failed coercing enum type (%s) to attribute type (%s)", + __FUNCTION__, + fr_int2str(dict_attr_types, value->type, ""), + fr_int2str(dict_attr_types, da->type, "")); - default: - talloc_free(dval); - fr_strerror_printf("%s: VALUEs cannot be defined for attributes of type '%s'", - __FUNCTION__, fr_int2str(dict_attr_types, da->type, "?Unknown?")); return -1; } } else { - dict_enum_fixup_t *fixup; - - fixup = talloc_zero(dict->pool, dict_enum_fixup_t); - if (!fixup) { - talloc_free(dval); - fr_strerror_printf("Out of memory"); + if (fr_value_box_copy(enum_value, enum_value, value) < 0) { + fr_strerror_printf_push("%s: Failed copying value into enum", __FUNCTION__); return -1; } - - strlcpy(fixup->attrstr, attr, sizeof(fixup->attrstr)); - fixup->dval = dval; - - /* - * Insert to the head of the list. - */ - fixup->next = dict->enum_fixup; - dict->enum_fixup = fixup; - - return 0; } + enumv->value = enum_value; + enumv->da = da; + /* * Add the value into the dictionary. */ { fr_dict_attr_t *tmp; - memcpy(&tmp, &dval, sizeof(tmp)); + memcpy(&tmp, &enumv, sizeof(tmp)); - if (!fr_hash_table_insert(dict->values_by_name, tmp)) { - if (da) { - fr_dict_enum_t *old; + if (!fr_hash_table_insert(dict->values_by_alias, tmp)) { + fr_dict_enum_t *old; - /* - * Suppress duplicates with the same - * name and value. There are lots in - * dictionary.ascend. - */ - old = fr_dict_enum_by_name(dict, da, alias); - if (old && (old->value == dval->value)) { - talloc_free(dval); - return 0; - } + /* + * Suppress duplicates with the same + * name and value. There are lots in + * dictionary.ascend. + */ + old = fr_dict_enum_by_alias(dict, da, alias); + if (!fr_cond_assert(old)) return -1; + + if (fr_value_box_cmp(old->value, enumv->value) == 0) { + talloc_free(enumv); + return 0; } - talloc_free(dval); - fr_strerror_printf("Duplicate VALUE name '%s' for attribute '%s'", alias, - attr); + fr_strerror_printf("Duplicate VALUE alias \"%s\" for attribute \"%s\". " + "Old value was \"%pV\", new value was \"%pV\"", alias, da->name, + old->value, enumv->value); + talloc_free(enumv); return -1; } } @@ -1664,9 +1630,13 @@ int fr_dict_enum_add(fr_dict_t *dict, char const *attr, char const *alias, int v * There are multiple VALUE's, keyed by attribute, so we * take care of that here. */ - if (!fr_hash_table_replace(dict->values_by_da, dval)) { - fr_strerror_printf("%s: Failed inserting value %s", __FUNCTION__, alias); - return -1; + if (takes_precedence) { + if (!fr_hash_table_replace(dict->values_by_da, enumv)) { + fr_strerror_printf("%s: Failed inserting value %s", __FUNCTION__, alias); + return -1; + } + } else { + (void) fr_hash_table_insert(dict->values_by_da, enumv); } /* @@ -1724,7 +1694,7 @@ int fr_dict_str_to_argv(char *str, char **argv, int max_argc) return argc; } -static int dict_read_sscanf_i(char const *str, unsigned int *pvalue) +static int dict_read_sscanf_i(unsigned int *pvalue, char const *str) { int rcode = 0; int base = 10; @@ -1794,7 +1764,7 @@ static int dict_read_process_attribute(fr_dict_t *dict, fr_dict_attr_t const *pa /* * Parse out the attribute number */ - if (!dict_read_sscanf_i(argv[1], &attr)) { + if (!dict_read_sscanf_i(&attr, argv[1])) { fr_strerror_printf("Invalid ATTRIBUTE number"); return -1; } @@ -1845,7 +1815,7 @@ static int dict_read_process_attribute(fr_dict_t *dict, fr_dict_attr_t const *pa *q = 0; - if (!dict_read_sscanf_i(p + 1, &length)) { + if (!dict_read_sscanf_i(&length, p + 1)) { fr_strerror_printf("Invalid length for '%s[...]'", argv[2]); return -1; } @@ -2005,12 +1975,14 @@ static int dict_read_process_named_attribute(fr_dict_t *dict, fr_dict_attr_t con return 0; } -/* - * Process the VALUE command +/** Process a value alias + * */ static int dict_read_process_value(fr_dict_t *dict, char **argv, int argc) { - unsigned int value; + static fr_dict_attr_t const *last_attr = NULL; + fr_dict_attr_t const *da; + fr_value_box_t value; if (argc != 3) { fr_strerror_printf("Invalid VALUE syntax"); @@ -2018,14 +1990,64 @@ static int dict_read_process_value(fr_dict_t *dict, char **argv, int argc) } /* - * Validate all entries + * Most VALUEs are bunched together by ATTRIBUTE. We can + * save a lot of lookups on dictionary initialization by + * caching the last attribute. + */ + if (last_attr && (strcasecmp(argv[0], last_attr->name) == 0)) { + da = last_attr; + } else { + da = fr_dict_attr_by_name(dict, argv[0]); + last_attr = da; + } + + /* + * Remember which attribute is associated with this + * value. This allows us to define enum + * values before the attribute exists, and fix them + * up later. */ - if (!dict_read_sscanf_i(argv[2], &value)) { - fr_strerror_printf("Invalid number in VALUE"); + if (!da) { + dict_enum_fixup_t *fixup; + + fixup = talloc_zero(dict->pool, dict_enum_fixup_t); + if (!fixup) { + oom: + talloc_free(fixup); + fr_strerror_printf("Out of memory"); + return -1; + } + fixup->attribute = talloc_strdup(fixup, argv[0]); + if (!fixup->attribute) goto oom; + fixup->alias = talloc_strdup(fixup, argv[1]); + if (!fixup->alias) goto oom; + fixup->value = talloc_strdup(fixup, argv[2]); + if (!fixup->value) goto oom; + + /* + * Insert to the head of the list. + */ + fixup->next = dict->enum_fixup; + dict->enum_fixup = fixup; + + return 0; + } + + { + fr_type_t type = da->type; /* Might change - Stupid combo IP */ + + if (fr_value_box_from_str(NULL, &value, &type, NULL, argv[2], -1, '\0') < 0) { + fr_strerror_printf_push("Invalid VALUE for ATTRIBUTE \"%s\"", da->name); + return -1; + } + } + + if (fr_dict_enum_add_alias(da, argv[1], &value, false, true) < 0) { + fr_value_box_clear(&value); return -1; } + fr_value_box_clear(&value); - if (fr_dict_enum_add(dict, argv[0], argv[1], value) < 0) return -1; return 0; } @@ -2142,7 +2164,7 @@ static int dict_read_process_vendor(fr_dict_t *dict, char **argv, int argc) /* * Validate all entries */ - if (!dict_read_sscanf_i(argv[1], &value)) { + if (!dict_read_sscanf_i(&value, argv[1])) { fr_strerror_printf("Invalid number in VENDOR"); return -1; } @@ -2355,7 +2377,7 @@ static int _dict_from_file(dict_from_file_ctx_t *ctx, fr_strerror_printf("Invalid entry"); error: - fr_strerror_printf("%s: %s[%d]: %s", __FUNCTION__, fn, line, fr_strerror()); + fr_strerror_printf_push("%s: %s[%d]", __FUNCTION__, fn, line); fclose(fp); return -1; } @@ -2716,8 +2738,8 @@ int fr_dict_from_file(TALLOC_CTX *ctx, fr_dict_t **out, char const *dir, char co dict->attributes_combo = fr_hash_table_create(dict, dict_attr_combo_hash, dict_attr_combo_cmp, hash_pool_free); if (!dict->attributes_combo) goto error; - dict->values_by_name = fr_hash_table_create(dict, dict_enum_name_hash, dict_enum_name_cmp, hash_pool_free); - if (!dict->values_by_name) goto error; + dict->values_by_alias = fr_hash_table_create(dict, dict_enum_alias_hash, dict_enum_alias_cmp, hash_pool_free); + if (!dict->values_by_alias) goto error; dict->values_by_da = fr_hash_table_create(dict, dict_enum_value_hash, dict_enum_value_cmp, hash_pool_free); if (!dict->values_by_da) goto error; @@ -2775,43 +2797,34 @@ int fr_dict_from_file(TALLOC_CTX *ctx, fr_dict_t **out, char const *dir, char co if (dict_from_file(dict, dir, fn, NULL, 0) < 0) goto error; + /* + * Resolve any VALUE aliases (enums) that were defined + * before the attributes they reference. + */ if (dict->enum_fixup) { - fr_dict_attr_t const *a; + fr_dict_attr_t const *da; dict_enum_fixup_t *this, *next; for (this = dict->enum_fixup; this != NULL; this = next) { - next = this->next; + fr_value_box_t value; + fr_type_t type; - a = fr_dict_attr_by_name(dict, this->attrstr); - if (!a) { + next = this->next; + da = fr_dict_attr_by_name(dict, this->attribute); + if (!da) { fr_strerror_printf("No ATTRIBUTE '%s' defined for VALUE '%s'", - this->attrstr, this->dval->name); - goto error; /* leak, but they should die... */ + this->attribute, this->alias); + goto error; } + type = da->type; - this->dval->da = a; - - /* - * Add the value into the dictionary. - */ - if (!fr_hash_table_replace(dict->values_by_name, this->dval)) { - fr_strerror_printf("Duplicate VALUE name '%s' for attribute '%s'", - this->dval->name, a->name); + if (fr_value_box_from_str(this, &value, &type, NULL, + this->value, talloc_array_length(this->value) - 1, '\0') < 0) { + fr_strerror_printf_push("Invalid VALUE for ATTRIBUTE \"%s\"", da->name); goto error; } - /* - * Allow them to use the old name, but - * prefer the new name when printing - * values. - */ - if (a->parent->flags.is_root || ((a->parent->type == FR_TYPE_VENDOR) && - (a->parent->parent->type == FR_TYPE_VSA))) { - if (!fr_hash_table_finddata(dict->values_by_da, this->dval)) { - fr_hash_table_replace(dict->values_by_da, this->dval); - } - } - talloc_free(this); + if (fr_dict_enum_add_alias(da, this->alias, &value, false, false) < 0) goto error; /* * Just so we don't lose track of things. @@ -2830,7 +2843,7 @@ int fr_dict_from_file(TALLOC_CTX *ctx, fr_dict_t **out, char const *dir, char co fr_hash_table_walk(dict->vendors_by_num, hash_null_callback, NULL); fr_hash_table_walk(dict->values_by_da, hash_null_callback, NULL); - fr_hash_table_walk(dict->values_by_name, hash_null_callback, NULL); + fr_hash_table_walk(dict->values_by_alias, hash_null_callback, NULL); if (out) *out = dict; @@ -4182,51 +4195,53 @@ inline fr_dict_attr_t const *fr_dict_attr_child_by_num(fr_dict_attr_t const *par /** Lookup the structure representing an enum value in a #fr_dict_attr_t * - * @param[in] dict of protocol context we're operating in. If NULL the internal - * dictionary will be used. - * @param[in] da to search in. - * @param[in] value number to search for. + * @param[in] dict of protocol context we're operating in. + * If NULL the internal dictionary will be used. + * @param[in] da to search in. + * @param[in] value to search for. * @return * - Matching #fr_dict_enum_t. * - NULL if no matching #fr_dict_enum_t could be found. */ -fr_dict_enum_t *fr_dict_enum_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, int64_t value) +fr_dict_enum_t *fr_dict_enum_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, fr_value_box_t const *value) { - fr_dict_enum_t dval, *dv; + fr_dict_enum_t enumv, *dv; if (!da) return NULL; INTERNAL_IF_NULL(dict); + if (!fr_cond_assert(value->type == da->type)) return NULL; + /* * First, look up aliases. */ - dval.da = da; - dval.name[0] = '\0'; + enumv.da = da; + enumv.alias = ""; /* * Look up the attribute alias target, and use * the correct attribute number if found. */ - dv = fr_hash_table_finddata(dict->values_by_name, &dval); - if (dv) dval.da = dv->da; + dv = fr_hash_table_finddata(dict->values_by_alias, &enumv); + if (dv) enumv.da = dv->da; - dval.value = value; + enumv.value = value; - return fr_hash_table_finddata(dict->values_by_da, &dval); + return fr_hash_table_finddata(dict->values_by_da, &enumv); } /** Lookup the name of an enum value in a #fr_dict_attr_t * - * @param[in] dict of protocol context we're operating in. If NULL the internal - * dictionary will be used. - * @param[in] da to search in. - * @param[in] value number to search for. + * @param[in] dict of protocol context we're operating in. If NULL the internal + * dictionary will be used. + * @param[in] da to search in. + * @param[in] value number to search for. * @return * - Name of value. * - NULL if no matching value could be found. */ -char const *fr_dict_enum_name_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, int64_t value) +char const *fr_dict_enum_alias_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, fr_value_box_t const *value) { fr_dict_enum_t *dv; @@ -4237,34 +4252,33 @@ char const *fr_dict_enum_name_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, i dv = fr_dict_enum_by_da(dict, da, value); if (!dv) return ""; - return dv->name; + return dv->alias; } /* * Get a value by its name, keyed off of an attribute. */ -fr_dict_enum_t *fr_dict_enum_by_name(fr_dict_t *dict, fr_dict_attr_t const *da, char const *name) +fr_dict_enum_t *fr_dict_enum_by_alias(fr_dict_t *dict, fr_dict_attr_t const *da, char const *alias) { - fr_dict_enum_t *my_dv, *dv; - uint32_t buffer[(sizeof(*my_dv) + FR_DICT_ENUM_MAX_NAME_LEN + 3) / 4]; + fr_dict_enum_t find, *found; + + memset(&find, 0, sizeof(find)); + + if (!alias) return NULL; - if (!name) return NULL; INTERNAL_IF_NULL(dict); - my_dv = (fr_dict_enum_t *)buffer; - my_dv->da = da; - my_dv->name[0] = '\0'; + find.da = da; + find.alias = alias; /* * Look up the attribute alias target, and use * the correct attribute number if found. */ - dv = fr_hash_table_finddata(dict->values_by_name, my_dv); - if (dv) my_dv->da = dv->da; - - strlcpy(my_dv->name, name, FR_DICT_ENUM_MAX_NAME_LEN + 1); + found = fr_hash_table_finddata(dict->values_by_alias, &find); + if (found) find.da = found->da; - return fr_hash_table_finddata(dict->values_by_name, my_dv); + return fr_hash_table_finddata(dict->values_by_alias, &find); } /* diff --git a/src/lib/util/pair.c b/src/lib/util/pair.c index 0bcc54560ab..784d9a5f36e 100644 --- a/src/lib/util/pair.c +++ b/src/lib/util/pair.c @@ -102,7 +102,7 @@ VALUE_PAIR *fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da) */ vp->da = da; vp->vp_type = da->type; - if (fr_dict_enum_types[da->type]) vp->data.datum.enumv = da; + vp->data.enumv = da; return vp; } @@ -1998,7 +1998,7 @@ int fr_pair_value_from_str(VALUE_PAIR *vp, char const *value, size_t inlen) return -1; } vp->da = da; - if (fr_dict_enum_types[da->type]) vp->data.datum.enumv = da; + vp->data.enumv = da; } vp->type = VT_DATA; @@ -2267,23 +2267,11 @@ char const *fr_pair_value_enum(VALUE_PAIR const *vp, char buff[20]) return vp->vp_bool ? "yes" : "no"; case FR_TYPE_UINT8: - enumv = fr_dict_enum_by_da(NULL, vp->da, vp->vp_uint8); - break; - case FR_TYPE_UINT16: - enumv = fr_dict_enum_by_da(NULL, vp->da, vp->vp_short); - break; - case FR_TYPE_UINT32: - enumv = fr_dict_enum_by_da(NULL, vp->da, vp->vp_uint32); - break; - case FR_TYPE_UINT64: - enumv = fr_dict_enum_by_da(NULL, vp->da, vp->vp_uint64); - break; - case FR_TYPE_INT32: - enumv = fr_dict_enum_by_da(NULL, vp->da, vp->vp_signed); + enumv = fr_dict_enum_by_da(NULL, vp->da, &vp->data); break; default: @@ -2294,7 +2282,7 @@ char const *fr_pair_value_enum(VALUE_PAIR const *vp, char buff[20]) fr_pair_value_snprint(buff, 20, vp, '\0'); str = buff; } else { - str = enumv->name; + str = enumv->alias; } return str; diff --git a/src/lib/util/value.c b/src/lib/util/value.c index 04d201a1ac6..10b35320cdb 100644 --- a/src/lib/util/value.c +++ b/src/lib/util/value.c @@ -241,7 +241,7 @@ static inline void fr_value_box_copy_meta(fr_value_box_t *dst, fr_value_box_t co break; } - if (fr_dict_enum_types[src->type]) dst->datum.enumv = src->datum.enumv; + dst->enumv = src->enumv; dst->type = src->type; dst->tainted = src->tainted; } @@ -264,7 +264,7 @@ int fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b) if (!fr_cond_assert(b->type != FR_TYPE_INVALID)) return -1; if (a->type != b->type) { - fr_strerror_printf("Can't compare values of different types"); + fr_strerror_printf("%s: Can't compare values of different types", __FUNCTION__); return -2; } @@ -851,8 +851,8 @@ static uint8_t const v4_v6_map[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, * @param src Input data. */ static inline int fr_value_box_cast_to_strvalue(TALLOC_CTX *ctx, fr_value_box_t *dst, - fr_type_t dst_type, UNUSED fr_dict_attr_t const *dst_enumv, - fr_value_box_t const *src) + fr_type_t dst_type, UNUSED fr_dict_attr_t const *dst_enumv, + fr_value_box_t const *src) { if (!fr_cond_assert(dst_type == FR_TYPE_STRING)) return -1; @@ -892,8 +892,8 @@ static inline int fr_value_box_cast_to_strvalue(TALLOC_CTX *ctx, fr_value_box_t * @param src Input data. */ static inline int fr_value_box_cast_to_octets(TALLOC_CTX *ctx, fr_value_box_t *dst, - fr_type_t dst_type, UNUSED fr_dict_attr_t const *dst_enumv, - fr_value_box_t const *src) + fr_type_t dst_type, UNUSED fr_dict_attr_t const *dst_enumv, + fr_value_box_t const *src) { uint8_t *bin; @@ -978,8 +978,8 @@ static inline int fr_value_box_cast_to_octets(TALLOC_CTX *ctx, fr_value_box_t *d * @param src Input data. */ static inline int fr_value_box_cast_to_ipv4addr(TALLOC_CTX *ctx, fr_value_box_t *dst, - fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, - fr_value_box_t const *src) + fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, + fr_value_box_t const *src) { if (!fr_cond_assert(dst_type == FR_TYPE_IPV4_ADDR)) return -1; @@ -1080,8 +1080,8 @@ static inline int fr_value_box_cast_to_ipv4addr(TALLOC_CTX *ctx, fr_value_box_t * @param src Input data. */ static inline int fr_value_box_cast_to_ipv4prefix(TALLOC_CTX *ctx, fr_value_box_t *dst, - fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, - fr_value_box_t const *src) + fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, + fr_value_box_t const *src) { if (!fr_cond_assert(dst_type == FR_TYPE_IPV4_PREFIX)) return -1; @@ -1179,8 +1179,8 @@ static inline int fr_value_box_cast_to_ipv4prefix(TALLOC_CTX *ctx, fr_value_box_ * @param src Input data. */ static inline int fr_value_box_cast_to_ipv6addr(TALLOC_CTX *ctx, fr_value_box_t *dst, - fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, - fr_value_box_t const *src) + fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, + fr_value_box_t const *src) { if (!fr_cond_assert(dst_type == FR_TYPE_IPV6_ADDR)) return -1; @@ -1281,8 +1281,8 @@ static inline int fr_value_box_cast_to_ipv6addr(TALLOC_CTX *ctx, fr_value_box_t * @param src Input data. */ static inline int fr_value_box_cast_to_ipv6prefix(TALLOC_CTX *ctx, fr_value_box_t *dst, - fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, - fr_value_box_t const *src) + fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, + fr_value_box_t const *src) { switch (src->type) { case FR_TYPE_IPV4_ADDR: @@ -1352,20 +1352,22 @@ static inline int fr_value_box_cast_to_ipv6prefix(TALLOC_CTX *ctx, fr_value_box_ * This should be the canonical function used to convert between INTERNAL data formats. * * - If you want to convert from PRESENTATION format, use #fr_value_box_from_str. - + * * * @param ctx to allocate buffers in (usually the same as dst) * @param dst Where to write result of casting. * @param dst_type to cast to. - * @param dst_enumv Enumerated values used to converts strings to uint32s. + * @param dst_enumv Aliases for values contained within this fr_value_box_t. + * If #fr_value_box_t is passed to #fr_value_box_asprint + * aliases will be printed instead of actual value. * @param src Input data. * @return * - 0 on success. * - -1 on failure. */ int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, - fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, - fr_value_box_t const *src) + fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, + fr_value_box_t const *src) { if (!fr_cond_assert(dst_type != FR_TYPE_INVALID)) return -1; if (!fr_cond_assert(src->type != FR_TYPE_INVALID)) return -1; @@ -1442,7 +1444,7 @@ int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, * Deserialise a fr_value_box_t */ if (src->type == FR_TYPE_STRING) return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv, - src->datum.strvalue, src->datum.length, '\0'); + src->datum.strvalue, src->datum.length, '\0'); if ((src->type == FR_TYPE_IFID) && (dst_type == FR_TYPE_UINT64)) { @@ -1451,7 +1453,7 @@ int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, fixed_length: dst->type = dst_type; - if (fr_dict_enum_types[dst_type]) dst->datum.enumv = dst_enumv; + dst->enumv = dst_enumv; return 0; } @@ -1655,13 +1657,15 @@ int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, return -1; } + memset(&tmp, 0, sizeof(tmp)); + /* * Copy the raw octets into the datum of a value_box - * inverting uint8sex for uint32s (if LE). + * inverting bytesex for uint32s (if LE). */ memcpy(&tmp.datum, src->datum.octets, fr_value_box_field_sizes[dst_type]); tmp.type = dst_type; - if (fr_dict_enum_types[dst_type]) dst->datum.enumv = dst_enumv; + dst->enumv = dst_enumv; fr_value_box_hton(dst, &tmp); @@ -1711,7 +1715,7 @@ int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, } dst->type = dst_type; - if (fr_dict_enum_types[dst_type]) dst->datum.enumv = dst_enumv; + dst->enumv = dst_enumv; return 0; } @@ -2444,13 +2448,12 @@ int fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, * attribute. */ if (dst_enumv && *p && !is_whitespace(p)) { - if ((dval = fr_dict_enum_by_name(NULL, dst_enumv, in)) == NULL) { + if ((dval = fr_dict_enum_by_alias(NULL, dst_enumv, in)) == NULL) { fr_strerror_printf("Unknown or invalid value \"%s\" for attribute %s", in, dst_enumv->name); return -1; } - - dst->datum.uint8 = dval->value; + fr_value_box_copy_shallow(NULL, dst, dval->value); } else { if (i > 255) { fr_strerror_printf("Byte value \"%s\" is larger than 255", in); @@ -2477,13 +2480,13 @@ int fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, * attribute. */ if (dst_enumv && *p && !is_whitespace(p)) { - if ((dval = fr_dict_enum_by_name(NULL, dst_enumv, in)) == NULL) { + if ((dval = fr_dict_enum_by_alias(NULL, dst_enumv, in)) == NULL) { fr_strerror_printf("Unknown or invalid value \"%s\" for attribute %s", in, dst_enumv->name); return -1; } - dst->datum.uint16 = dval->value; + fr_value_box_copy_shallow(NULL, dst, dval->value); } else { if (i > 65535) { fr_strerror_printf("Short value \"%s\" is larger than 65535", in); @@ -2508,28 +2511,18 @@ int fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, */ if (dst_enumv && (!is_integer(in) || (!(in[0] == '0') && (in[1] == 'x')))) { - if ((dval = fr_dict_enum_by_name(NULL, dst_enumv, in)) == NULL) { + if ((dval = fr_dict_enum_by_alias(NULL, dst_enumv, in)) == NULL) { fr_strerror_printf("Unknown or invalid value \"%s\" for attribute %s", in, dst_enumv->name); return -1; } - dst->datum.uint32 = dval->value; + fr_value_box_copy_shallow(NULL, dst, dval->value); } else { unsigned long i; int base = 10; - /* - * Empty strings or invalid strings get - * parsed as zero for backwards - * compatability. - */ - if (!*in || !isdigit((int) *in)) { - dst->datum.uint32 = 0; - break; - } - /* * Hex strings are base 16. */ @@ -2537,11 +2530,17 @@ int fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, i = strtoul(in, &p, base); + if ((size_t)(p - in) != len) { + fr_strerror_printf("Invalid value \"%s\" for %s type", in, + fr_int2str(dict_attr_types, *dst_type, "")); + return -1; + } + /* * Catch and complain on overflows. */ if ((i == ULONG_MAX) || (i >= ((unsigned long) 1) << 32)) { - fr_strerror_printf("Integer Value \"%s\" is larger than 1<<32", in); + fr_strerror_printf("Integer value \"%s\" is larger than 1<<32", in); return -1; } @@ -2599,7 +2598,7 @@ int fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, case FR_TYPE_DATE: { /* - * time_t may be 64 bits, whule vp_date MUST be 32-bits. We need an + * time_t may be 64 bits, while vp_date MUST be 32-bits. We need an * intermediary variable to handle the conversions. */ time_t date; @@ -2726,7 +2725,7 @@ finish: /* * Fixup enumv */ - if (fr_dict_enum_types[dst->type]) dst->datum.enumv = dst_enumv; + dst->enumv = dst_enumv; return 0; } @@ -2755,14 +2754,11 @@ char *fr_value_box_asprint(TALLOC_CTX *ctx, fr_value_box_t const *data, char quo if (!fr_cond_assert(data->type != FR_TYPE_INVALID)) return NULL; - if (fr_dict_enum_types[data->type] && data->datum.enumv) { + if (data->enumv) { fr_dict_enum_t const *dv; - fr_value_box_t tmp; - - fr_value_box_cast(ctx, &tmp, FR_TYPE_UINT32, NULL, data); - dv = fr_dict_enum_by_da(NULL, data->datum.enumv, tmp.datum.uint32); - if (dv) return talloc_typed_strdup(ctx, dv->name); + dv = fr_dict_enum_by_da(NULL, data->enumv, data); + if (dv) return talloc_typed_strdup(ctx, dv->alias); } switch (data->type) { @@ -2952,14 +2948,11 @@ size_t fr_value_box_snprint(char *out, size_t outlen, fr_value_box_t const *data p = out; - if (fr_dict_enum_types[data->type] && data->datum.enumv) { + if (data->enumv) { fr_dict_enum_t const *dv; - fr_value_box_t tmp; - - fr_value_box_cast(NULL, &tmp, FR_TYPE_UINT32, NULL, data); - dv = fr_dict_enum_by_da(NULL, data->datum.enumv, tmp.datum.uint32); - if (dv) return strlcpy(out, dv->name, outlen); + dv = fr_dict_enum_by_da(NULL, data->enumv, data); + if (dv) return strlcpy(out, dv->alias, outlen); } switch (data->type) { diff --git a/src/main/acct.c b/src/main/acct.c index 64e82c175bf..e1befb140f2 100644 --- a/src/main/acct.c +++ b/src/main/acct.c @@ -85,11 +85,8 @@ rlm_rcode_t rad_accounting(REQUEST *request) * that we log the packet, even if the proxy never does. */ vp = fr_pair_find_by_num(request->control, 0, PW_ACCT_TYPE, TAG_ANY); - if (vp) { - acct_type = vp->vp_uint32; - DEBUG2(" Found Acct-Type %s", - fr_dict_enum_name_by_da(NULL, vp->da, acct_type)); - } + if (vp) DEBUG2(" Found Acct-Type %s", fr_dict_enum_alias_by_da(NULL, vp->da, &vp->data)); + rcode = process_accounting(acct_type, request); switch (rcode) { /* diff --git a/src/main/auth.c b/src/main/auth.c index 4effa966f9e..34a23e4a073 100644 --- a/src/main/auth.c +++ b/src/main/auth.c @@ -115,7 +115,7 @@ static int rad_authlog(char const *msg, REQUEST *request, int goodpass) if (auth_type) { snprintf(clean_password, sizeof(clean_password), "", - fr_dict_enum_name_by_da(NULL, auth_type->da, auth_type->vp_uint32)); + fr_dict_enum_alias_by_da(NULL, auth_type->da, &auth_type->data)); } else { strcpy(clean_password, ""); } @@ -184,7 +184,8 @@ static int CC_HINT(nonnull) rad_check_password(REQUEST *request) auth_type = auth_type_pair->vp_uint32; auth_type_count++; - RDEBUG2("Using 'Auth-Type = %s' for authenticate {...}", fr_dict_enum_name_by_da(NULL, auth_type_pair->da, auth_type)); + RDEBUG2("Using 'Auth-Type = %s' for authenticate {...}", + fr_dict_enum_alias_by_da(NULL, auth_type_pair->da, fr_box_uint32(auth_type))); if (auth_type == PW_AUTH_TYPE_REJECT) { RDEBUG2("Auth-Type = Reject, rejecting user"); @@ -297,7 +298,7 @@ rlm_rcode_t rad_postauth(REQUEST *request) if (vp) { postauth_type = vp->vp_uint32; RDEBUG2("Using Post-Auth-Type %s", - fr_dict_enum_name_by_da(NULL, vp->da, postauth_type)); + fr_dict_enum_alias_by_da(NULL, vp->da, fr_box_uint32(postauth_type))); } rcode = process_post_auth(postauth_type, request); switch (rcode) { @@ -464,7 +465,7 @@ autz_redo: if (tmp) { autz_type = tmp->vp_uint32; RDEBUG2("Using Autz-Type %s", - fr_dict_enum_name_by_da(NULL, tmp->da, autz_type)); + fr_dict_enum_alias_by_da(NULL, tmp->da, fr_box_uint32(autz_type))); autz_retry = 1; goto autz_redo; } @@ -568,15 +569,15 @@ authenticate: #ifdef WITH_SESSION_MGMT if (result >= 0 && (check_item = fr_pair_find_by_num(request->control, 0, PW_SIMULTANEOUS_USE, TAG_ANY)) != NULL) { - int r, session_type = 0; - char logstr[1024]; - char umsg[FR_MAX_STRING_LEN + 1]; + int r, session_type = 0; + char logstr[1024]; + char umsg[FR_MAX_STRING_LEN + 1]; tmp = fr_pair_find_by_num(request->control, 0, PW_SESSION_TYPE, TAG_ANY); if (tmp) { session_type = tmp->vp_uint32; RDEBUG2("Using Session-Type %s", - fr_dict_enum_name_by_da(NULL, tmp->da, session_type)); + fr_dict_enum_alias_by_da(NULL, tmp->da, fr_box_uint32(session_type))); } /* diff --git a/src/main/cond_tokenize.c b/src/main/cond_tokenize.c index b864144d9e4..801bb770a8d 100644 --- a/src/main/cond_tokenize.c +++ b/src/main/cond_tokenize.c @@ -1079,7 +1079,14 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, CONF_ITEM *ci, char const *start, break; } - if (tmpl_cast_in_place(c->data.map->rhs, type, c->data.map->lhs->tmpl_da) < 0) { + /* + * Do not pass LHS as enumv if we're casting + * as that means there's now a type mismatch between + * lhs and rhs, which means the enumerations + * can never match. + */ + if (tmpl_cast_in_place(c->data.map->rhs, type, + c->cast ? NULL : c->data.map->lhs->tmpl_da) < 0) { fr_dict_attr_t const *da = c->data.map->lhs->tmpl_da; if ((da->vendor == 0) && diff --git a/src/main/listen.c b/src/main/listen.c index 626c7e1dd93..d20e6e2ace0 100644 --- a/src/main/listen.c +++ b/src/main/listen.c @@ -126,7 +126,7 @@ int listen_bootstrap(CONF_SECTION *server, CONF_SECTION *cs, char const *server_ CONF_PAIR *cp; CONF_SECTION *tls; int transports; - char const *value; + char const *type; fr_dict_enum_t const *dv; rad_protocol_t const *proto = NULL; dl_t const *module = NULL; @@ -141,8 +141,8 @@ int listen_bootstrap(CONF_SECTION *server, CONF_SECTION *cs, char const *server_ return -1; } - value = cf_pair_value(cp); - if (!value) { + type = cf_pair_value(cp); + if (!type) { cf_log_err_cs(cs, "Invalid 'type' specified in listen section"); return -1; } @@ -152,16 +152,16 @@ int listen_bootstrap(CONF_SECTION *server, CONF_SECTION *cs, char const *server_ * Only control sockets and proxy sockets are global for now. */ if (!server_name) { - if ((strcmp(value, "control") != 0) && - (strcmp(value, "proxy") != 0)) { - cf_log_err_cs(cs, "Listeners of type '%s' MUST be defined in a server.", value); + if ((strcmp(type, "control") != 0) && + (strcmp(type, "proxy") != 0)) { + cf_log_err_cs(cs, "Listeners of type '%s' MUST be defined in a server", type); return -1; } } else { - if ((strcmp(value, "control") == 0) || - (strcmp(value, "proxy") == 0)) { - cf_log_err_cs(cs, "Listeners of type '%s' MUST NOT be defined in a server.", value); + if ((strcmp(type, "control") == 0) || + (strcmp(type, "proxy") == 0)) { + cf_log_err_cs(cs, "Listeners of type '%s' MUST NOT be defined in a server", type); return -1; } } @@ -177,33 +177,42 @@ int listen_bootstrap(CONF_SECTION *server, CONF_SECTION *cs, char const *server_ * * At some point, we'll move all of these to plugins. */ - if (cp || !((strcmp(value, "control") == 0) || - (strcmp(value, "status") == 0) || - (strcmp(value, "coa") == 0) || - (strcmp(value, "auth") == 0) || - (strcmp(value, "acct") == 0) || - (strcmp(value, "auth+acct") == 0))) { - static int max_listener = 256; + if (cp || !((strcmp(type, "control") == 0) || + (strcmp(type, "status") == 0) || + (strcmp(type, "coa") == 0) || + (strcmp(type, "auth") == 0) || + (strcmp(type, "acct") == 0) || + (strcmp(type, "auth+acct") == 0))) { + static uint32_t max_listener = 256; char buffer[256]; if (cp) { - snprintf(buffer, sizeof(buffer), "%s_%s", cf_pair_value(cp), value); - value = buffer; + snprintf(buffer, sizeof(buffer), "%s_%s", cf_pair_value(cp), type); + type = buffer; } - module = dl_module(cs, NULL, value, DL_TYPE_PROTO); + module = dl_module(cs, NULL, type, DL_TYPE_PROTO); if (!module) return -1; proto = (rad_protocol_t const *)module->common; /* * We need numbers for internal use. */ - dv = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_LISTEN_SOCKET_TYPE), value); + dv = fr_dict_enum_by_alias(NULL, fr_dict_attr_by_num(NULL, 0, PW_LISTEN_SOCKET_TYPE), type); if (!dv) { - if (fr_dict_enum_add(NULL, "Listen-Socket-Type", value, max_listener++) < 0) { + fr_dict_attr_t const *da; + + da = fr_dict_attr_by_name(NULL, "Listen-Socket-Type"); + if (!da) { + ERROR("Listen-Socket-Type attribute not defined"); + talloc_const_free(module); + return -1; + } + + if (fr_dict_enum_add_alias(da, type, fr_box_uint32(max_listener), true, false) < 0) { cf_log_err_cs(cs, "Failed adding dictionary entry for protocol %s: %s", - value, fr_strerror()); + type, fr_strerror()); talloc_const_free(module); return -1; } @@ -215,7 +224,7 @@ int listen_bootstrap(CONF_SECTION *server, CONF_SECTION *cs, char const *server_ * the protocol-specific processing sections. */ if (proto->bootstrap && (proto->bootstrap(server, cs) < 0)) { - cf_log_err_cs(cs, "Failed loading protocol %s", value); + cf_log_err_cs(cs, "Failed loading protocol %s", type); talloc_const_free(module); return -1; } @@ -232,14 +241,14 @@ int listen_bootstrap(CONF_SECTION *server, CONF_SECTION *cs, char const *server_ /* * The type MUST now be defined in the dictionaries. */ - dv = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_LISTEN_SOCKET_TYPE), value); + dv = fr_dict_enum_by_alias(NULL, fr_dict_attr_by_num(NULL, 0, PW_LISTEN_SOCKET_TYPE), type); if (!dv) { - cf_log_err_cs(cs, "Failed finding dictionary entry for protocol %s", value); + cf_log_err_cs(cs, "Failed finding dictionary entry for protocol %s", type); talloc_const_free(module); return -1; } - if (!proto) proto = &master_listen[dv->value]; + if (!proto) proto = &master_listen[fr_unbox_uint32(dv->value)]; /* * Check the allowed transport protocols. For most @@ -251,23 +260,23 @@ int listen_bootstrap(CONF_SECTION *server, CONF_SECTION *cs, char const *server_ cp = cf_pair_find(cs, "proto"); if (!cp) { transports = TRANSPORT_UDP; - value = "udp"; + type = "udp"; } else { - value = cf_pair_value(cp); - if (!value) { + type = cf_pair_value(cp); + if (!type) { cf_log_err_cs(cs, "No value for 'proto'"); return -1; } - if (strcmp(value, "udp") == 0) { + if (strcmp(type, "udp") == 0) { transports = TRANSPORT_UDP; - } else if (strcmp(value, "tcp") == 0) { + } else if (strcmp(type, "tcp") == 0) { transports = TRANSPORT_TCP; } else { - cf_log_err_cs(cs, "Unknown transport protocol 'proto = %s'", value); + cf_log_err_cs(cs, "Unknown transport protocol 'proto = %s'", type); return -1; } } @@ -277,7 +286,7 @@ int listen_bootstrap(CONF_SECTION *server, CONF_SECTION *cs, char const *server_ */ if ((transports & proto->transports) == 0) { cf_log_err_cs(cs, "Invalid transport 'proto = %s' for listeners of 'type = %s'", - value, proto->name); + type, proto->name); return -1; } @@ -290,7 +299,7 @@ int listen_bootstrap(CONF_SECTION *server, CONF_SECTION *cs, char const *server_ */ if ((strcmp(proto->name, "proxy") == 0) && (transports == TRANSPORT_TCP)) { cf_log_err_cs(cs, "Invalid transport 'proto = %s' for listeners of 'type = %s'", - value, proto->name); + type, proto->name); return -1; } #endif @@ -337,7 +346,7 @@ int listen_bootstrap(CONF_SECTION *server, CONF_SECTION *cs, char const *server_ lc->cs = cs; lc->server_name = server_name; lc->handle = module; - lc->type = dv->value; + lc->type = fr_unbox_uint32(dv->value); lc->proto = proto; lc->listener = listen_parse(lc); @@ -618,9 +627,9 @@ rlm_rcode_t rad_status_server(REQUEST *request) case RAD_LISTEN_NONE: #endif case RAD_LISTEN_AUTH: - dval = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTZ_TYPE), "Status-Server"); + dval = fr_dict_enum_by_alias(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTZ_TYPE), "Status-Server"); if (dval) { - rcode = process_authorize(dval->value, request); + rcode = process_authorize(fr_unbox_uint32(dval->value), request); } else { rcode = RLM_MODULE_OK; } @@ -645,9 +654,9 @@ rlm_rcode_t rad_status_server(REQUEST *request) #ifdef WITH_ACCOUNTING case RAD_LISTEN_ACCT: - dval = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_ACCT_TYPE), "Status-Server"); + dval = fr_dict_enum_by_alias(NULL, fr_dict_attr_by_num(NULL, 0, PW_ACCT_TYPE), "Status-Server"); if (dval) { - rcode = process_accounting(dval->value, request); + rcode = process_accounting(fr_unbox_uint32(dval->value), request); } else { rcode = RLM_MODULE_OK; } @@ -672,9 +681,9 @@ rlm_rcode_t rad_status_server(REQUEST *request) * the WG. We like it, so it goes in here. */ case RAD_LISTEN_COA: - dval = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_RECV_COA_TYPE), "Status-Server"); + dval = fr_dict_enum_by_alias(NULL, fr_dict_attr_by_num(NULL, 0, PW_RECV_COA_TYPE), "Status-Server"); if (dval) { - rcode = process_recv_coa(dval->value, request); + rcode = process_recv_coa(fr_unbox_uint32(dval->value), request); } else { rcode = RLM_MODULE_OK; } @@ -2556,7 +2565,7 @@ static rad_protocol_t master_listen[] = { .name = "proxy", .inst_size = sizeof(listen_socket_t), .transports = TRANSPORT_DUAL, - .tls = true, + .tls = true, .parse = common_socket_parse, .open = common_socket_open, .recv = proxy_socket_recv, diff --git a/src/main/map.c b/src/main/map.c index 518f2529581..cc8867d25cb 100644 --- a/src/main/map.c +++ b/src/main/map.c @@ -64,7 +64,7 @@ bool map_cast_from_hex(vp_map_t *map, FR_TOKEN rhs_type, char const *rhs) fr_dict_attr_t const *da; VALUE_PAIR *vp = NULL; vp_tmpl_t *vpt; - fr_value_box_t bin = { .type = FR_TYPE_STRING }, cast; + fr_value_box_t cast; rad_assert(map != NULL); @@ -101,16 +101,11 @@ bool map_cast_from_hex(vp_map_t *map, FR_TOKEN rhs_type, char const *rhs) fr_hex2bin(ptr, len >> 1, rhs + 2, len); - /* - * Assign but don't dup. - */ - fr_value_box_memdup_buffer_shallow(NULL, &bin, ptr, false); - /* * Convert to da->type (if possible); */ - if (fr_value_box_cast(map, &cast, da->type, da, &bin) < 0) { - talloc_free(bin.datum.ptr); + if (fr_value_box_cast(map, &cast, da->type, da, fr_box_octets_buffer(ptr)) < 0) { + talloc_free(ptr); return false; } @@ -118,10 +113,12 @@ bool map_cast_from_hex(vp_map_t *map, FR_TOKEN rhs_type, char const *rhs) * Package the #fr_value_box_t as a #vp_tmpl_t */ if (tmpl_afrom_value_box(map, &map->rhs, &cast, true) < 0) { - talloc_free(bin.datum.ptr); + talloc_free(ptr); return false; } + talloc_free(ptr); + /* * Set the LHS to the REAL attribute name. * diff --git a/src/main/process.c b/src/main/process.c index aba35c8faf7..c088e944c0e 100644 --- a/src/main/process.c +++ b/src/main/process.c @@ -2272,11 +2272,11 @@ static int process_proxy_reply(REQUEST *request, RADIUS_PACKET *reply) case PW_CODE_ACCESS_REJECT: case PW_CODE_DISCONNECT_NAK: case PW_CODE_COA_NAK: - dval = fr_dict_enum_by_name(NULL, da, fr_packet_codes[reply->code]); + dval = fr_dict_enum_by_alias(NULL, da, fr_packet_codes[reply->code]); if (dval) { vp = radius_pair_create(request, &request->control, PW_POST_PROXY_TYPE, 0); - vp->vp_uint32 = dval->value; + fr_value_box_copy(NULL, &vp->data, dval->value); } break; @@ -2285,7 +2285,7 @@ static int process_proxy_reply(REQUEST *request, RADIUS_PACKET *reply) } } - if (vp) RDEBUG2("Found Post-Proxy-Type %s", fr_dict_enum_name_by_da(NULL, vp->da, vp->vp_uint32)); + if (vp) RDEBUG2("Found Post-Proxy-Type %s", fr_dict_enum_alias_by_da(NULL, vp->da, &vp->data)); /* * Remove it from the proxy hash, if there's no reply, or @@ -2534,9 +2534,9 @@ static int setup_post_proxy_fail(REQUEST *request) VERIFY_REQUEST(request); snprintf(buffer, sizeof(buffer), "Fail-%s", fr_packet_codes[request->proxy->packet->code]); - dval = fr_dict_enum_by_name(NULL, da, buffer); + dval = fr_dict_enum_by_alias(NULL, da, buffer); - if (!dval) dval = fr_dict_enum_by_name(NULL, da, "Fail"); + if (!dval) dval = fr_dict_enum_by_alias(NULL, da, "Fail"); if (!dval) { fr_pair_delete_by_num(&request->control, 0, PW_POST_PROXY_TYPE, TAG_ANY); @@ -2546,7 +2546,7 @@ static int setup_post_proxy_fail(REQUEST *request) vp = fr_pair_find_by_num(request->control, 0, PW_POST_PROXY_TYPE, TAG_ANY); if (!vp) vp = radius_pair_create(request, &request->control, PW_POST_PROXY_TYPE, 0); - vp->vp_uint32 = dval->value; + fr_value_box_copy(NULL, &vp->data, dval->value); return 1; } @@ -3109,10 +3109,10 @@ do_home: */ vp = fr_pair_find_by_num(request->control, 0, PW_PRE_PROXY_TYPE, TAG_ANY); if (vp) { - fr_dict_enum_t const *dval = fr_dict_enum_by_da(NULL, vp->da, vp->vp_uint32); + fr_dict_enum_t const *dval = fr_dict_enum_by_da(NULL, vp->da, &vp->data); /* Must be a validation issue */ rad_assert(dval); - RDEBUG2("Found Pre-Proxy-Type %s", dval->name); + RDEBUG2("Found Pre-Proxy-Type %s", dval->alias); pre_proxy_type = vp->vp_uint32; } @@ -4245,10 +4245,10 @@ static void request_coa_originate(REQUEST *request) */ vp = fr_pair_find_by_num(request->control, 0, PW_PRE_PROXY_TYPE, TAG_ANY); if (vp) { - fr_dict_enum_t const *dval = fr_dict_enum_by_da(NULL, vp->da, vp->vp_uint32); + fr_dict_enum_t const *dval = fr_dict_enum_by_da(NULL, vp->da, &vp->data); /* Must be a validation issue */ rad_assert(dval); - RDEBUG2("Found Pre-Proxy-Type %s", dval->name); + RDEBUG2("Found Pre-Proxy-Type %s", dval->alias); pre_proxy_type = vp->vp_uint32; } diff --git a/src/main/radclient.c b/src/main/radclient.c index 328ccc53c4b..8d6b021708c 100644 --- a/src/main/radclient.c +++ b/src/main/radclient.c @@ -528,6 +528,7 @@ static int radclient_init(TALLOC_CTX *ctx, rc_file_pair_t *files) vp->vp_octets = talloc_steal(vp, p); vp->data.type = FR_TYPE_OCTETS; + vp->data.enumv = NULL; vp->type = VT_DATA; VERIFY_VP(vp); diff --git a/src/main/radsnmp.c b/src/main/radsnmp.c index 003b8801858..7847ca872f3 100644 --- a/src/main/radsnmp.c +++ b/src/main/radsnmp.c @@ -675,14 +675,14 @@ static int radsnmp_send_recv(radsnmp_conf_t *conf, int fd) strlcpy(type_str, value, (p - value) + 1); - type = fr_dict_enum_by_name(NULL, conf->snmp_type, type_str); + type = fr_dict_enum_by_alias(NULL, conf->snmp_type, type_str); if (!type) { ERROR("Unknown type \"%s\"", type_str); RESPOND_STATIC("NONE"); continue; } - slen = radsnmp_pair_from_oid(conf, conf, &cursor, line, type->value, p + 1); + slen = radsnmp_pair_from_oid(conf, conf, &cursor, line, fr_unbox_int32(type->value), p + 1); } break; diff --git a/src/main/tmpl.c b/src/main/tmpl.c index b25f75cd46d..f250f143d09 100644 --- a/src/main/tmpl.c +++ b/src/main/tmpl.c @@ -1131,10 +1131,10 @@ ssize_t tmpl_afrom_str(TALLOC_CTX *ctx, vp_tmpl_t **out, char const *in, size_t * @note Irrespective of whether the #vp_tmpl_t was #TMPL_TYPE_UNPARSED or #TMPL_TYPE_DATA, * on successful cast it will be #TMPL_TYPE_DATA. * - * @param[in,out] vpt The template to modify. Must be of type #TMPL_TYPE_UNPARSED - * or #TMPL_TYPE_DATA. - * @param[in] type to cast to. - * @param[in] enumv Enumerated dictionary values associated with a #fr_dict_attr_t. + * @param[in,out] vpt The template to modify. Must be of type #TMPL_TYPE_UNPARSED + * or #TMPL_TYPE_DATA. + * @param[in] type to cast to. + * @param[in] enumv Enumerated dictionary values associated with a #fr_dict_attr_t. * @return * - 0 on success. * - -1 on failure. diff --git a/src/main/unit_test_module.c b/src/main/unit_test_module.c index cd455119162..a7ea2d3afa7 100644 --- a/src/main/unit_test_module.c +++ b/src/main/unit_test_module.c @@ -327,6 +327,7 @@ static REQUEST *request_from_file(FILE *fp, RADCLIENT *client) vp->vp_octets = talloc_steal(vp, p); vp->data.type = FR_TYPE_OCTETS; + vp->data.enumv = NULL; vp->type = VT_DATA; VERIFY_VP(vp); diff --git a/src/main/unlang_compile.c b/src/main/unlang_compile.c index d83c26186b2..ca721300966 100644 --- a/src/main/unlang_compile.c +++ b/src/main/unlang_compile.c @@ -657,7 +657,7 @@ static bool pass2_cond_callback(void *ctx, fr_cond_t *c) * Where "foo" is dynamically defined. */ if (c->pass2_fixup == PASS2_FIXUP_TYPE) { - if (!fr_dict_enum_by_name(NULL, map->lhs->tmpl_da, map->rhs->name)) { + if (!fr_dict_enum_by_alias(NULL, map->lhs->tmpl_da, map->rhs->name)) { cf_log_err(map->ci, "Invalid reference to non-existent %s %s { ... }", map->lhs->tmpl_da->name, map->rhs->name); diff --git a/src/main/virtual_servers.c b/src/main/virtual_servers.c index 1f464a27696..18ebfa4899e 100644 --- a/src/main/virtual_servers.c +++ b/src/main/virtual_servers.c @@ -96,18 +96,18 @@ static rlm_rcode_t module_method_call(rlm_components_t comp, int idx, REQUEST *r da = fr_dict_attr_by_num(NULL, 0, section_type_value[comp].attr); if (!da) return RLM_MODULE_FAIL; - dv = fr_dict_enum_by_da(NULL, da, idx); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32((uint32_t)idx)); if (!dv) return RLM_MODULE_FAIL; - subcs = cf_subsection_find_name2(cs, da->name, dv->name); + subcs = cf_subsection_find_name2(cs, da->name, dv->alias); if (!subcs) { RDEBUG2("%s %s sub-section not found. Using default return values.", - da->name, dv->name); + da->name, dv->alias); return default_component_results[comp]; } RDEBUG("Running %s %s from file %s", - da->name, dv->name, cf_section_filename(subcs)); + da->name, dv->alias, cf_section_filename(subcs)); cs = subcs; } @@ -237,14 +237,14 @@ rlm_rcode_t process_send_coa(int send_coa_type, REQUEST *request) static bool define_type(CONF_SECTION *cs, fr_dict_attr_t const *da, char const *name) { - uint32_t value; - fr_dict_enum_t *dval; + fr_value_box_t value = { .type = FR_TYPE_UINT32 }; + fr_dict_enum_t *dval; /* * If the value already exists, don't * create it again. */ - dval = fr_dict_enum_by_name(NULL, da, name); + dval = fr_dict_enum_by_alias(NULL, da, name); if (dval) { if (dval->value == 0) { ERROR("The dictionaries must not define VALUE %s %s 0", @@ -262,11 +262,11 @@ static bool define_type(CONF_SECTION *cs, fr_dict_attr_t const *da, char const * * is that it's unique. */ do { - value = (fr_rand() & 0x00ffffff) + 1; - } while (fr_dict_enum_by_da(NULL, da, value)); + value.datum.uint32 = (fr_rand() & 0x00ffffff) + 1; + } while (fr_dict_enum_by_da(NULL, da, &value)); cf_log_module(cs, "Creating %s = %s", da->name, name); - if (fr_dict_enum_add(NULL, da->name, name, value) < 0) { + if (fr_dict_enum_add_alias(da, name, &value, true, false) < 0) { ERROR("%s", fr_strerror()); return false; } @@ -279,7 +279,7 @@ static bool define_type(CONF_SECTION *cs, fr_dict_attr_t const *da, char const * * block */ static bool load_subcomponent_section(CONF_SECTION *cs, - fr_dict_attr_t const *da, rlm_components_t comp) + fr_dict_attr_t const *da, rlm_components_t comp) { fr_dict_enum_t *dval; char const *name2 = cf_section_name2(cs); @@ -295,7 +295,7 @@ static bool load_subcomponent_section(CONF_SECTION *cs, * automatically. If it isn't found, it's a serious * error. */ - dval = fr_dict_enum_by_name(NULL, da, name2); + dval = fr_dict_enum_by_alias(NULL, da, name2); if (!dval) { cf_log_err_cs(cs, "The %s attribute has no VALUE defined for %s", diff --git a/src/main/xlat_eval.c b/src/main/xlat_eval.c index 833092859bf..4aed41ad51b 100644 --- a/src/main/xlat_eval.c +++ b/src/main/xlat_eval.c @@ -130,8 +130,8 @@ static char *xlat_getvp(TALLOC_CTX *ctx, REQUEST *request, vp_tmpl_t const *vpt, case PW_PACKET_TYPE: if (packet->code > 0) { - dv = fr_dict_enum_by_da(NULL, vpt->tmpl_da, packet->code); - if (dv) return talloc_typed_strdup(ctx, dv->name); + dv = fr_dict_enum_by_da(NULL, vpt->tmpl_da, fr_box_uint32(packet->code)); + if (dv) return talloc_typed_strdup(ctx, dv->alias); return talloc_typed_asprintf(ctx, "%d", packet->code); } diff --git a/src/modules/proto_dhcp/proto_dhcp.c b/src/modules/proto_dhcp/proto_dhcp.c index a60f97680cf..5f6910b3991 100644 --- a/src/modules/proto_dhcp/proto_dhcp.c +++ b/src/modules/proto_dhcp/proto_dhcp.c @@ -315,16 +315,16 @@ static rlm_rcode_t dhcp_process(REQUEST *request) vp = fr_pair_find_by_num(request->packet->vps, DHCP_MAGIC_VENDOR, 53, TAG_ANY); /* DHCP-Message-Type */ if (vp) { - fr_dict_enum_t *dv = fr_dict_enum_by_da(NULL, vp->da, vp->vp_uint8); + fr_dict_enum_t *dv = fr_dict_enum_by_da(NULL, vp->da, &vp->data); if (dv) { CONF_SECTION *server, *unlang; - RDEBUG("Trying sub-section dhcp %s {...}", dv->name); + RDEBUG("Trying sub-section dhcp %s {...}", dv->alias); server = cf_item_parent(cf_section_to_item(request->listener->cs)); - unlang = cf_subsection_find_name2(server, "dhcp", dv->name); + unlang = cf_subsection_find_name2(server, "dhcp", dv->alias); rcode = unlang_interpret(request, unlang, RLM_MODULE_NOOP); } else { REDEBUG("Unknown DHCP-Message-Type %d", vp->vp_uint8); @@ -1026,7 +1026,7 @@ static int dhcp_listen_compile(CONF_SECTION *server_cs, CONF_SECTION *listen_cs) cf_log_module(cs, "Loading dhcp {...}"); } - dv = fr_dict_enum_by_name(NULL, da, name2); + dv = fr_dict_enum_by_alias(NULL, da, name2); if (!dv) { cf_log_err_cs(cs, "Server contains 'dhcp %s {...}, but there is no such value for DHCP-Message-Type", name2); diff --git a/src/modules/proto_dhcp/rlm_dhcp.c b/src/modules/proto_dhcp/rlm_dhcp.c index a9b91a2192b..d636336bdff 100644 --- a/src/modules/proto_dhcp/rlm_dhcp.c +++ b/src/modules/proto_dhcp/rlm_dhcp.c @@ -174,20 +174,23 @@ static int mod_bootstrap(UNUSED CONF_SECTION *conf, void *instance) */ da = fr_dict_attr_by_num(NULL, DHCP_MAGIC_VENDOR, PW_DHCP_PARAMETER_REQUEST_LIST); if (da) { - fr_dict_attr_t const *value; - int i; + fr_value_box_t value = { .type = FR_TYPE_UINT8 }; + uint8_t i; /* No padding or termination options */ DEBUG3("Adding values for %s", da->name); for (i = 1; i < 255; i++) { - value = fr_dict_attr_by_num(NULL, DHCP_MAGIC_VENDOR, i); - if (!value) { + fr_dict_attr_t const *attr; + + attr = fr_dict_attr_by_num(NULL, DHCP_MAGIC_VENDOR, i); + if (!attr) { DEBUG3("No DHCP RFC space attribute at %i", i); continue; } + value.datum.uint8 = i; - DEBUG3("Adding %s value %i %s", da->name, i, value->name); - if (fr_dict_enum_add(NULL, da->name, value->name, i) < 0) { + DEBUG3("Adding %s value %i %s", da->name, i, attr->name); + if (fr_dict_enum_add_alias(da, attr->name, &value, true, false) < 0) { DEBUG3("Failed adding value: %s", fr_strerror()); } } diff --git a/src/modules/proto_ldap_sync/proto_ldap_sync.c b/src/modules/proto_ldap_sync/proto_ldap_sync.c index 1c45fa4b388..a8bc68b9bf7 100644 --- a/src/modules/proto_ldap_sync/proto_ldap_sync.c +++ b/src/modules/proto_ldap_sync/proto_ldap_sync.c @@ -203,10 +203,12 @@ static const CONF_PARSER module_config[] = { */ static int fr_dict_enum_from_name_number(fr_dict_attr_t const *da, FR_NAME_NUMBER const *table) { - FR_NAME_NUMBER const *p; + FR_NAME_NUMBER const *p; + fr_value_box_t value = { .type = FR_TYPE_INT32 }; for (p = table; p->name; p++) { - if (fr_dict_enum_add(NULL, da->name, p->name, p->number) < 0) return -1; + value.datum.int32 = p->number; + if (fr_dict_enum_add_alias(da, p->name, &value, true, false) < 0) return -1; } return 0; diff --git a/src/modules/proto_radius/proto_radius_acct.c b/src/modules/proto_radius/proto_radius_acct.c index fd580539d70..043adfff604 100644 --- a/src/modules/proto_radius/proto_radius_acct.c +++ b/src/modules/proto_radius/proto_radius_acct.c @@ -71,13 +71,13 @@ static void acct_running(REQUEST *request, fr_state_action_t action) da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); rad_assert(da != NULL); - dv = fr_dict_enum_by_da(NULL, da, request->packet->code); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->packet->code)); if (!dv) { REDEBUG("Failed to find value for &request:Packet-Type"); goto done; } - unlang = cf_subsection_find_name2(request->server_cs, "recv", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "recv", dv->alias); if (!unlang) unlang = cf_subsection_find_name2(request->server_cs, "recv", "*"); if (!unlang) { REDEBUG("Failed to find 'recv' section"); @@ -140,10 +140,10 @@ static void acct_running(REQUEST *request, fr_state_action_t action) if (!da) da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); rad_assert(da != NULL); - dv = fr_dict_enum_by_da(NULL, da, request->reply->code); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->reply->code)); unlang = NULL; if (dv) { - unlang = cf_subsection_find_name2(request->server_cs, "send", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "send", dv->alias); } if (!unlang) unlang = cf_subsection_find_name2(request->server_cs, "send", "*"); if (!unlang) goto send_reply; diff --git a/src/modules/proto_radius/proto_radius_auth.c b/src/modules/proto_radius/proto_radius_auth.c index 4ab68366ef4..589aa73a168 100644 --- a/src/modules/proto_radius/proto_radius_auth.c +++ b/src/modules/proto_radius/proto_radius_auth.c @@ -77,9 +77,8 @@ static void auth_message(char const *msg, REQUEST *request, int goodpass) auth_type = fr_pair_find_by_num(request->control, 0, PW_AUTH_TYPE, TAG_ANY); if (auth_type) { - snprintf(clean_password, sizeof(clean_password), - "", - fr_dict_enum_name_by_da(NULL, auth_type->da, auth_type->vp_uint32)); + snprintf(clean_password, sizeof(clean_password), "", + fr_dict_enum_alias_by_da(NULL, auth_type->da, &auth_type->data)); } else { strcpy(clean_password, ""); } @@ -342,14 +341,14 @@ static void auth_running(REQUEST *request, fr_state_action_t action) da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); rad_assert(da != NULL); - dv = fr_dict_enum_by_da(NULL, da, request->packet->code); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->packet->code)); if (!dv) { REDEBUG("Failed to find value for &request:Packet-Type"); request->reply->code = PW_CODE_ACCESS_REJECT; goto setup_send; } - unlang = cf_subsection_find_name2(request->server_cs, "recv", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "recv", dv->alias); if (!unlang) unlang = cf_subsection_find_name2(request->server_cs, "recv", "*"); if (!unlang) { REDEBUG("Failed to find 'recv' section"); @@ -426,7 +425,8 @@ static void auth_running(REQUEST *request, fr_state_action_t action) continue; } - RWDEBUG("Ignoring extra Auth-Type = %s", fr_dict_enum_name_by_da(NULL, auth_type->da, vp->vp_uint32)); + RWDEBUG("Ignoring extra Auth-Type = %s", + fr_dict_enum_alias_by_da(NULL, auth_type->da, &vp->data)); } /* @@ -457,16 +457,16 @@ static void auth_running(REQUEST *request, fr_state_action_t action) * Find the appropriate Auth-Type by name. */ vp = auth_type; - dv = fr_dict_enum_by_da(NULL, vp->da, vp->vp_uint32); + dv = fr_dict_enum_by_da(NULL, vp->da, &vp->data); if (!dv) { - REDEBUG2("Unknown Auth-Type %d found: rejecting the user.", vp->vp_uint32); + REDEBUG2("Unknown Auth-Type %d found: rejecting the user", vp->vp_uint32); request->reply->code = PW_CODE_ACCESS_REJECT; goto setup_send; } - unlang = cf_subsection_find_name2(request->server_cs, "process", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "process", dv->alias); if (!unlang) { - REDEBUG2("No 'process %s' section found: rejecting the user.", dv->name); + REDEBUG2("No 'process %s' section found: rejecting the user", dv->alias); request->reply->code = PW_CODE_ACCESS_REJECT; goto setup_send; } @@ -628,10 +628,10 @@ static void auth_running(REQUEST *request, fr_state_action_t action) if (!da) da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); rad_assert(da != NULL); - dv = fr_dict_enum_by_da(NULL, da, request->reply->code); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->reply->code)); unlang = NULL; if (dv) { - unlang = cf_subsection_find_name2(request->server_cs, "send", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "send", dv->alias); } if (!unlang) unlang = cf_subsection_find_name2(request->server_cs, "send", "*"); @@ -673,19 +673,19 @@ static void auth_running(REQUEST *request, fr_state_action_t action) if (!da) da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); rad_assert(da != NULL); - dv = fr_dict_enum_by_da(NULL, da, request->reply->code); - RWDEBUG("Failed running 'send %s', trying 'send Access-Reject'.", dv->name); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->reply->code)); + RWDEBUG("Failed running 'send %s', trying 'send Access-Reject'.", dv->alias); request->reply->code = PW_CODE_ACCESS_REJECT; - dv = fr_dict_enum_by_da(NULL, da, request->reply->code); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->reply->code)); unlang = NULL; if (!dv) goto send_reply; - unlang = cf_subsection_find_name2(request->server_cs, "send", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "send", dv->alias); if (unlang) goto rerun_nak; - RWDEBUG("Not running 'send %s' section as it does not exist", dv->name); + RWDEBUG("Not running 'send %s' section as it does not exist", dv->alias); } /* @@ -835,7 +835,7 @@ static void auth_running(REQUEST *request, fr_state_action_t action) RDEBUG2("Delaying Access-Reject for %d.%06d seconds", (int) delay.tv_sec, (int) delay.tv_usec); - + if (unlang_delay(request, &delay, auth_reject_delay) == 0) { return; } @@ -1086,9 +1086,9 @@ static int auth_listen_bootstrap(CONF_SECTION *server_cs, UNUSED CONF_SECTION *l for (subcs = cf_subsection_find_next(server_cs, NULL, "process"); subcs != NULL; subcs = cf_subsection_find_next(server_cs, subcs, "process")) { - char const *name2; - uint32_t value; - fr_dict_enum_t *dv; + char const *name2; + fr_value_box_t value = { .type = FR_TYPE_UINT32 }; + fr_dict_enum_t *dv; name2 = cf_section_name2(subcs); if (!name2) { @@ -1105,7 +1105,7 @@ static int auth_listen_bootstrap(CONF_SECTION *server_cs, UNUSED CONF_SECTION *l * If the value already exists, don't * create it again. */ - dv = fr_dict_enum_by_name(NULL, da, name2); + dv = fr_dict_enum_by_alias(NULL, da, name2); if (dv) continue; /* @@ -1115,11 +1115,11 @@ static int auth_listen_bootstrap(CONF_SECTION *server_cs, UNUSED CONF_SECTION *l * requirement is that it's unique. */ do { - value = (fr_rand() & 0x00ffffff) + 1; - } while (fr_dict_enum_by_da(NULL, da, value)); + value.datum.uint32 = (fr_rand() & 0x00ffffff) + 1; + } while (fr_dict_enum_by_da(NULL, da, &value)); cf_log_module(subcs, "Creating %s = %s", da->name, name2); - if (fr_dict_enum_add(NULL, da->name, name2, value) < 0) { + if (fr_dict_enum_add_alias(da, name2, &value, true, false) < 0) { ERROR("%s", fr_strerror()); return -1; } diff --git a/src/modules/proto_radius/proto_radius_coa.c b/src/modules/proto_radius/proto_radius_coa.c index 6abeeb54524..e9d7adbee2a 100644 --- a/src/modules/proto_radius/proto_radius_coa.c +++ b/src/modules/proto_radius/proto_radius_coa.c @@ -71,13 +71,13 @@ static void coa_running(REQUEST *request, fr_state_action_t action) da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); rad_assert(da != NULL); - dv = fr_dict_enum_by_da(NULL, da, request->packet->code); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->packet->code)); if (!dv) { REDEBUG("Failed to find value for &request:Packet-Type"); goto done; } - unlang = cf_subsection_find_name2(request->server_cs, "recv", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "recv", dv->alias); if (!unlang) unlang = cf_subsection_find_name2(request->server_cs, "recv", "*"); if (!unlang) { REDEBUG("Failed to find 'recv' section"); @@ -135,10 +135,10 @@ static void coa_running(REQUEST *request, fr_state_action_t action) if (!da) da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); rad_assert(da != NULL); - dv = fr_dict_enum_by_da(NULL, da, request->reply->code); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->reply->code)); unlang = NULL; if (dv) { - unlang = cf_subsection_find_name2(request->server_cs, "send", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "send", dv->alias); } if (!unlang) unlang = cf_subsection_find_name2(request->server_cs, "send", "*"); @@ -187,19 +187,19 @@ static void coa_running(REQUEST *request, fr_state_action_t action) if (!da) da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); rad_assert(da != NULL); - dv = fr_dict_enum_by_da(NULL, da, request->reply->code); - RWDEBUG("Failed running 'send %s', trying corresponding NAK section.", dv->name); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->reply->code)); + RWDEBUG("Failed running 'send %s', trying corresponding NAK section.", dv->alias); request->reply->code = request->packet->code + 2; - dv = fr_dict_enum_by_da(NULL, da, request->reply->code); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->reply->code)); unlang = NULL; if (!dv) goto send_reply; - unlang = cf_subsection_find_name2(request->server_cs, "send", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "send", dv->alias); if (unlang) goto rerun_nak; - RWDEBUG("Not running 'send %s' section as it does not exist", dv->name); + RWDEBUG("Not running 'send %s' section as it does not exist", dv->alias); } /* * Else it was already a NAK or something else. diff --git a/src/modules/proto_radius/proto_radius_status.c b/src/modules/proto_radius/proto_radius_status.c index 654fc52f33e..44843f96605 100644 --- a/src/modules/proto_radius/proto_radius_status.c +++ b/src/modules/proto_radius/proto_radius_status.c @@ -70,13 +70,13 @@ static void status_running(REQUEST *request, fr_state_action_t action) da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); rad_assert(da != NULL); - dv = fr_dict_enum_by_da(NULL, da, request->packet->code); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->packet->code)); if (!dv) { REDEBUG("Failed to find value for &request:Packet-Type"); goto done; } - unlang = cf_subsection_find_name2(request->server_cs, "recv", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "recv", dv->alias); if (!unlang) { RWDEBUG("Failed to find 'recv' section"); request->reply->code = PW_CODE_ACCESS_REJECT; @@ -118,10 +118,10 @@ static void status_running(REQUEST *request, fr_state_action_t action) if (!da) da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); rad_assert(da != NULL); - dv = fr_dict_enum_by_da(NULL, da, request->reply->code); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->reply->code)); unlang = NULL; if (dv) { - unlang = cf_subsection_find_name2(request->server_cs, "send", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "send", dv->alias); } if (!unlang) unlang = cf_subsection_find_name2(request->server_cs, "send", "*"); if (!unlang) goto send_reply; @@ -159,19 +159,19 @@ static void status_running(REQUEST *request, fr_state_action_t action) if (!da) da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); rad_assert(da != NULL); - dv = fr_dict_enum_by_da(NULL, da, request->reply->code); - RWDEBUG("Failed running 'send %s', trying 'send Access-Reject'.", dv->name); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->reply->code)); + RWDEBUG("Failed running 'send %s', trying 'send Access-Reject'.", dv->alias); request->reply->code = PW_CODE_ACCESS_REJECT; - dv = fr_dict_enum_by_da(NULL, da, request->reply->code); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->reply->code)); unlang = NULL; if (!dv) goto send_reply; - unlang = cf_subsection_find_name2(request->server_cs, "send", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "send", dv->alias); if (unlang) goto rerun_nak; - RWDEBUG("Not running 'send %s' section as it does not exist", dv->name); + RWDEBUG("Not running 'send %s' section as it does not exist", dv->alias); } break; } diff --git a/src/modules/proto_tacacs/proto_tacacs.c b/src/modules/proto_tacacs/proto_tacacs.c index 018fb71a937..05bed022849 100644 --- a/src/modules/proto_tacacs/proto_tacacs.c +++ b/src/modules/proto_tacacs/proto_tacacs.c @@ -246,7 +246,8 @@ stop_processing: continue; } - RWDEBUG("Ignoring extra Auth-Type = %s", fr_dict_enum_name_by_da(NULL, auth_type->da, vp->vp_uint32)); + RWDEBUG("Ignoring extra Auth-Type = %s", + fr_dict_enum_alias_by_da(NULL, auth_type->da, &vp->data)); } /* @@ -277,16 +278,16 @@ stop_processing: * Find the appropriate Auth-Type by name. */ vp = auth_type; - dv = fr_dict_enum_by_da(NULL, vp->da, vp->vp_uint32); + dv = fr_dict_enum_by_da(NULL, vp->da, &vp->data); if (!dv) { - REDEBUG2("Unknown Auth-Type %d found: rejecting the user.", vp->vp_uint32); + REDEBUG2("Unknown Auth-Type %d found: rejecting the user", vp->vp_uint32); tacacs_status(request, RLM_MODULE_FAIL); goto setup_send; } - unlang = cf_subsection_find_name2(request->server_cs, "process", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "process", dv->alias); if (!unlang) { - REDEBUG2("No 'process %s' section found: rejecting the user.", dv->name); + REDEBUG2("No 'process %s' section found: rejecting the user.", dv->alias); tacacs_status(request, RLM_MODULE_FAIL); goto setup_send; } diff --git a/src/modules/proto_tacacs/tacacs.c b/src/modules/proto_tacacs/tacacs.c index ba64e978c96..66c14a6f61a 100644 --- a/src/modules/proto_tacacs/tacacs.c +++ b/src/modules/proto_tacacs/tacacs.c @@ -53,10 +53,10 @@ char const * tacacs_lookup_packet_code(RADIUS_PACKET const * const packet) da = fr_dict_attr_child_by_num(dict_tacacs_root, PW_TACACS_PACKET_TYPE); rad_assert(da != NULL); - dv = fr_dict_enum_by_da(NULL, da, type); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(type)); rad_assert(dv != NULL); - return dv->name; + return dv->alias; } uint32_t tacacs_session_id(RADIUS_PACKET const * const packet) @@ -818,7 +818,7 @@ int tacacs_send(RADIUS_PACKET * const packet, RADIUS_PACKET const * const origin seq_no = vp->vp_uint8 + 1; /* we catch client 255 on ingress */ vp = fr_pair_afrom_da(packet, vp->da); - if (!vp) return -1; + if (!vp) return -1; vp->vp_uint8 = seq_no; fr_pair_add(&packet->vps, vp); diff --git a/src/modules/proto_vmps/proto_vmps.c b/src/modules/proto_vmps/proto_vmps.c index 441114c7e1a..fd0638d997a 100644 --- a/src/modules/proto_vmps/proto_vmps.c +++ b/src/modules/proto_vmps/proto_vmps.c @@ -61,13 +61,13 @@ static void vmps_running(REQUEST *request, fr_state_action_t action) goto done; } - dv = fr_dict_enum_by_da(NULL, vp->da, vp->vp_uint32); + dv = fr_dict_enum_by_da(NULL, vp->da, &vp->data); if (!dv) { REDEBUG("Failed to find value for &request:VMPS-Packet-Type"); goto done; } - unlang = cf_subsection_find_name2(request->server_cs, "recv", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "recv", dv->alias); if (!unlang) unlang = cf_subsection_find_name2(request->server_cs, "recv", "*"); if (!unlang) { RPEDEBUG("Failed to find 'recv' section"); @@ -101,10 +101,10 @@ static void vmps_running(REQUEST *request, fr_state_action_t action) } } - dv = fr_dict_enum_by_da(NULL, da, request->reply->code); + dv = fr_dict_enum_by_da(NULL, da, fr_box_uint32(request->reply->code)); unlang = NULL; if (dv) { - unlang = cf_subsection_find_name2(request->server_cs, "send", dv->name); + unlang = cf_subsection_find_name2(request->server_cs, "send", dv->alias); } if (!unlang) unlang = cf_subsection_find_name2(request->server_cs, "send", "*"); diff --git a/src/modules/rlm_eap/lib/base/eapcommon.c b/src/modules/rlm_eap/lib/base/eapcommon.c index d4557f84da9..4e70ddc047f 100644 --- a/src/modules/rlm_eap/lib/base/eapcommon.c +++ b/src/modules/rlm_eap/lib/base/eapcommon.c @@ -79,12 +79,12 @@ eap_type_t eap_name2type(char const *name) { fr_dict_enum_t *dv; - dv = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_EAP_TYPE), name); + dv = fr_dict_enum_by_alias(NULL, fr_dict_attr_by_num(NULL, 0, PW_EAP_TYPE), name); if (!dv) return PW_EAP_INVALID; - if (dv->value >= PW_EAP_MAX_TYPES) return PW_EAP_INVALID; + if (fr_unbox_uint32(dv->value) >= PW_EAP_MAX_TYPES) return PW_EAP_INVALID; - return dv->value; + return fr_unbox_uint32(dv->value); } /** Return an EAP-name for a particular type @@ -95,8 +95,8 @@ char const *eap_type2name(eap_type_t method) { fr_dict_enum_t *dv; - dv = fr_dict_enum_by_da(NULL, fr_dict_attr_by_num(NULL, 0, PW_EAP_TYPE), method); - if (dv) return dv->name; + dv = fr_dict_enum_by_da(NULL, fr_dict_attr_by_num(NULL, 0, PW_EAP_TYPE), fr_box_uint32(method)); + if (dv) return dv->alias; return "unknown"; } diff --git a/src/modules/rlm_eap/types/rlm_eap_gtc/rlm_eap_gtc.c b/src/modules/rlm_eap/types/rlm_eap_gtc/rlm_eap_gtc.c index f9be5c5e4fa..0832747ea6f 100644 --- a/src/modules/rlm_eap/types/rlm_eap_gtc/rlm_eap_gtc.c +++ b/src/modules/rlm_eap/types/rlm_eap_gtc/rlm_eap_gtc.c @@ -201,13 +201,13 @@ static int mod_instantiate(UNUSED rlm_eap_config_t const *config, void *instance return -1; } - dval = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTH_TYPE), inst->auth_type_name); + dval = fr_dict_enum_by_alias(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTH_TYPE), inst->auth_type_name); if (!dval) { cf_log_err_by_name(cs, "auth_type", "Unknown Auth-Type %s", inst->auth_type_name); return -1; } - inst->auth_type = dval->value; + inst->auth_type = fr_unbox_uint32(dval->value); return 0; } diff --git a/src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c b/src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c index 5a8cca056ea..7a18082611b 100644 --- a/src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c +++ b/src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c @@ -754,13 +754,13 @@ static int mod_instantiate(UNUSED rlm_eap_config_t const *config, void *instance if (!inst->identity) inst->identity = talloc_asprintf(inst, "freeradius-%s", RADIUSD_VERSION_STRING); - dv = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTH_TYPE), "MS-CHAP"); - if (!dv) dv = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTH_TYPE), "MSCHAP"); + dv = fr_dict_enum_by_alias(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTH_TYPE), "MS-CHAP"); + if (!dv) dv = fr_dict_enum_by_alias(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTH_TYPE), "MSCHAP"); if (!dv) { cf_log_err_cs(cs, "Failed to find 'Auth-Type MS-CHAP' section. Cannot authenticate users."); return -1; } - inst->auth_type_mschap = dv->value; + inst->auth_type_mschap = fr_unbox_uint32(dv->value); return 0; } diff --git a/src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c b/src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c index fa7a1161a47..a61d7d9c78e 100644 --- a/src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c +++ b/src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c @@ -313,13 +313,13 @@ static int mod_instantiate(UNUSED rlm_eap_config_t const *config, void *instance */ if (!inst->inner_eap_module) inst->inner_eap_module = "eap"; - dv = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTH_TYPE), inst->inner_eap_module); + dv = fr_dict_enum_by_alias(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTH_TYPE), inst->inner_eap_module); if (!dv) { WARN("Failed to find 'Auth-Type %s' section in virtual server %s. " "The server cannot proxy inner-tunnel EAP packets", inst->inner_eap_module, inst->virtual_server); } else { - inst->auth_type_eap = dv->value; + inst->auth_type_eap = fr_unbox_uint32(dv->value); } return 0; diff --git a/src/modules/rlm_eap/types/rlm_eap_sim/rlm_eap_sim.c b/src/modules/rlm_eap/types/rlm_eap_sim/rlm_eap_sim.c index 0034276b31c..582a9f4bdd5 100644 --- a/src/modules/rlm_eap/types/rlm_eap_sim/rlm_eap_sim.c +++ b/src/modules/rlm_eap/types/rlm_eap_sim/rlm_eap_sim.c @@ -568,7 +568,7 @@ static int mod_instantiate(UNUSED rlm_eap_config_t const *config, UNUSED void *i return -1; } - dv = fr_dict_enum_by_name(NULL, da, name2); + dv = fr_dict_enum_by_alias(NULL, da, name2); if (!dv) { cf_log_err_cs(subcs, "Unknown EAP-SIM-Subtype %s", name2); return -1; diff --git a/src/modules/rlm_exec/rlm_exec.c b/src/modules/rlm_exec/rlm_exec.c index 3e7e7bcb949..457341ba7f7 100644 --- a/src/modules/rlm_exec/rlm_exec.c +++ b/src/modules/rlm_exec/rlm_exec.c @@ -242,13 +242,13 @@ static int mod_bootstrap(CONF_SECTION *conf, void *instance) } else { fr_dict_enum_t *dval; - dval = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE), inst->packet_type); + dval = fr_dict_enum_by_alias(NULL, fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE), inst->packet_type); if (!dval) { cf_log_err_cs(conf, "Unknown packet type %s: See list of VALUEs for Packet-Type in " "share/dictionary", inst->packet_type); return -1; } - inst->packet_code = dval->value; + inst->packet_code = fr_unbox_uint32(dval->value); } /* diff --git a/src/modules/rlm_json/json.c b/src/modules/rlm_json/json.c index 39af53b6de2..18e73365de4 100644 --- a/src/modules/rlm_json/json.c +++ b/src/modules/rlm_json/json.c @@ -373,12 +373,12 @@ const char *fr_json_afrom_pair_list(TALLOC_CTX *ctx, VALUE_PAIR **vps, const cha json_object_object_add(vp_object, "mapping", mapping); } - dv = fr_dict_enum_by_da(NULL, vp->da, vp->vp_uint32); + dv = fr_dict_enum_by_da(NULL, vp->da, &vp->data); if (dv) { struct json_object *mapped_value; /* Add to mapping array */ - MEM(mapped_value = json_object_new_string(dv->name)); + MEM(mapped_value = json_object_new_string(dv->alias)); json_object_array_add(mapping, mapped_value); /* * Add NULL value to mapping array diff --git a/src/modules/rlm_mschap/rlm_mschap.c b/src/modules/rlm_mschap/rlm_mschap.c index 47efa8daa19..3630c8e44bd 100644 --- a/src/modules/rlm_mschap/rlm_mschap.c +++ b/src/modules/rlm_mschap/rlm_mschap.c @@ -600,7 +600,7 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance) /* * For backwards compatibility */ - if (!fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTH_TYPE), inst->xlat_name)) { + if (!fr_dict_enum_by_alias(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTH_TYPE), inst->xlat_name)) { inst->auth_type = "MS-CHAP"; } else { inst->auth_type = inst->xlat_name; diff --git a/src/modules/rlm_pap/rlm_pap.c b/src/modules/rlm_pap/rlm_pap.c index 5f20c3f439a..a378e2352d4 100644 --- a/src/modules/rlm_pap/rlm_pap.c +++ b/src/modules/rlm_pap/rlm_pap.c @@ -108,9 +108,9 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance) inst->name = cf_section_name1(conf); } - dval = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTH_TYPE), inst->name); + dval = fr_dict_enum_by_alias(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTH_TYPE), inst->name); if (dval) { - inst->auth_type = dval->value; + inst->auth_type = fr_unbox_uint32(dval->value); } else { inst->auth_type = 0; } diff --git a/src/modules/rlm_rediswho/rlm_rediswho.c b/src/modules/rlm_rediswho/rlm_rediswho.c index f8c93584ed7..c7b5ff855b8 100644 --- a/src/modules/rlm_rediswho/rlm_rediswho.c +++ b/src/modules/rlm_rediswho/rlm_rediswho.c @@ -180,15 +180,15 @@ static rlm_rcode_t CC_HINT(nonnull) mod_accounting(void *instance, UNUSED void * return RLM_MODULE_NOOP; } - dv = fr_dict_enum_by_da(NULL, vp->da, vp->vp_uint32); + dv = fr_dict_enum_by_da(NULL, vp->da, &vp->data); if (!dv) { RDEBUG("Unknown Acct-Status-Type %u", vp->vp_uint32); return RLM_MODULE_NOOP; } - cs = cf_subsection_find(inst->cs, dv->name); + cs = cf_subsection_find(inst->cs, dv->alias); if (!cs) { - RDEBUG("No subsection %s", dv->name); + RDEBUG("No subsection %s", dv->alias); return RLM_MODULE_NOOP; } diff --git a/src/modules/rlm_yubikey/rlm_yubikey.c b/src/modules/rlm_yubikey/rlm_yubikey.c index 32c7927c192..ed8dafe5ee9 100644 --- a/src/modules/rlm_yubikey/rlm_yubikey.c +++ b/src/modules/rlm_yubikey/rlm_yubikey.c @@ -311,10 +311,10 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void *instance, UNUSED void *t fr_pair_value_bstrncpy(vp, passcode, inst->id_len); } - dval = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTH_TYPE), inst->name); + dval = fr_dict_enum_by_alias(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTH_TYPE), inst->name); if (dval) { vp = radius_pair_create(request, &request->control, PW_AUTH_TYPE, 0); - vp->vp_uint32 = dval->value; + fr_value_box_copy(NULL, &vp->data, dval->value); } return RLM_MODULE_OK; diff --git a/src/tests/unit/dict.txt b/src/tests/unit/dict.txt index f5ca683f196..9a8e90aad78 100644 --- a/src/tests/unit/dict.txt +++ b/src/tests/unit/dict.txt @@ -6,29 +6,30 @@ # VALUEs # dictionary VALUE Service-Type Foo bar -data Invalid number in VALUE +data Invalid VALUE for ATTRIBUTE "Service-Type" dictionary VALUE Unit-Byte TooBig 256 -data fr_dict_enum_add: ATTRIBUTEs of type 'byte' cannot have VALUEs larger than 255 +data Invalid VALUE for ATTRIBUTE "Unit-Byte" dictionary VALUE Unit-Byte Too-Small -1 -data Invalid number in VALUE +data Invalid VALUE for ATTRIBUTE "Unit-Byte" dictionary VALUE Unit-Short Too-Big 65537 -data fr_dict_enum_add: ATTRIBUTEs of type 'short' cannot have VALUEs larger than 65535 +data Invalid VALUE for ATTRIBUTE "Unit-Short" -dictionary VALUE Unit-Integer64 Not-OK 1 -data fr_dict_enum_add: VALUEs cannot be defined for attributes of type 'uint64' +# Check non-uint32 types +dictionary VALUE Unit-Integer64 OK 1 +data ok dictionary VALUE Unit-Octets Porridge 1 -data fr_dict_enum_add: VALUEs cannot be defined for attributes of type 'octets' +data ok dictionary VALUE Unit-Byte Life 42 data ok # re-defining it is not OK dictionary VALUE Unit-Byte Life 43 -data Duplicate VALUE name 'Life' for attribute 'Unit-Byte' +data Duplicate VALUE alias "Life" for attribute "Unit-Byte". Old value was "42", new value was "43" #