#include <freeradius-devel/token.h>
#include <freeradius-devel/types.h>
+/*
+ * Avoid circular type references.
+ */
+typedef struct dict_attr fr_dict_attr_t;
+typedef struct fr_dict fr_dict_t;
+
+#include <freeradius-devel/value.h>
+
#ifdef __cplusplus
extern "C" {
#endif
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
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.
*/
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
*/
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
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);
/*
* 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);
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
typedef struct FR_NAME_NUMBER {
char const *name;
- int number;
+ int32_t number;
} FR_NAME_NUMBER;
extern const FR_NAME_NUMBER fr_tokens_table[];
#define _FR_VALUE_H
#include <freeradius-devel/inet.h>
#include <freeradius-devel/types.h>
+
+/*
+ * Avoid circular type references.
+ */
+typedef struct value_box fr_value_box_t;
+
#include <freeradius-devel/dict.h>
extern size_t const fr_value_box_field_sizes[];
*
* 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 {
/*
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?).
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
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
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.
[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.
*
/** 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;
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
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
*/
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.
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, "<INVALID>"),
+ fr_int2str(dict_attr_types, value->type, "<INVALID>"));
+ 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, "<INVALID>"),
+ fr_int2str(dict_attr_types, da->type, "<INVALID>"));
- 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;
}
}
* 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);
}
/*
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;
/*
* 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;
}
*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;
}
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");
}
/*
- * 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;
}
/*
* 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;
}
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;
}
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;
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.
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;
/** 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;
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);
}
/*
*/
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;
}
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;
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:
fr_pair_value_snprint(buff, 20, vp, '\0');
str = buff;
} else {
- str = enumv->name;
+ str = enumv->alias;
}
return str;
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;
}
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;
}
* @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;
* @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;
* @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;
* @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;
* @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;
* @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:
* 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;
* 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)) {
fixed_length:
dst->type = dst_type;
- if (fr_dict_enum_types[dst_type]) dst->datum.enumv = dst_enumv;
+ dst->enumv = dst_enumv;
return 0;
}
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);
}
dst->type = dst_type;
- if (fr_dict_enum_types[dst_type]) dst->datum.enumv = dst_enumv;
+ dst->enumv = dst_enumv;
return 0;
}
* 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);
* 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);
*/
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.
*/
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, "<INVALID>"));
+ 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;
}
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;
/*
* Fixup enumv
*/
- if (fr_dict_enum_types[dst->type]) dst->datum.enumv = dst_enumv;
+ dst->enumv = dst_enumv;
return 0;
}
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) {
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) {
* 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) {
/*
if (auth_type) {
snprintf(clean_password, sizeof(clean_password),
"<via Auth-Type = %s>",
- 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, "<no User-Password attribute>");
}
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");
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) {
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;
}
#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)));
}
/*
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) &&
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;
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;
}
* 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;
}
}
*
* 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;
}
* 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;
}
/*
* 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
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;
}
}
*/
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;
}
*/
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
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);
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;
}
#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;
}
* 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;
}
.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,
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);
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;
}
* 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.
*
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;
}
}
- 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
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);
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;
}
*/
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;
}
*/
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;
}
vp->vp_octets = talloc_steal(vp, p);
vp->data.type = FR_TYPE_OCTETS;
+ vp->data.enumv = NULL;
vp->type = VT_DATA;
VERIFY_VP(vp);
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;
* @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.
vp->vp_octets = talloc_steal(vp, p);
vp->data.type = FR_TYPE_OCTETS;
+ vp->data.enumv = NULL;
vp->type = VT_DATA;
VERIFY_VP(vp);
* 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);
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;
}
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",
* 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;
}
* 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);
* 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",
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);
}
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);
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);
*/
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());
}
}
*/
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;
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");
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;
auth_type = fr_pair_find_by_num(request->control, 0, PW_AUTH_TYPE, TAG_ANY);
if (auth_type) {
- snprintf(clean_password, sizeof(clean_password),
- "<via Auth-Type = %s>",
- fr_dict_enum_name_by_da(NULL, auth_type->da, auth_type->vp_uint32));
+ snprintf(clean_password, sizeof(clean_password), "<via Auth-Type = %s>",
+ fr_dict_enum_alias_by_da(NULL, auth_type->da, &auth_type->data));
} else {
strcpy(clean_password, "<no User-Password attribute>");
}
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");
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));
}
/*
* 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;
}
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 (!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);
}
/*
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;
}
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) {
* 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;
/*
* 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;
}
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");
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 (!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.
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;
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;
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;
}
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));
}
/*
* 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;
}
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)
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);
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");
}
}
- 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", "*");
{
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
{
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";
}
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;
}
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;
}
*/
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;
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;
} 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);
}
/*
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
/*
* 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;
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;
}
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;
}
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;
# 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"
#