]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Allow value aliases (enumerations) to work with any attribute type, not just integers
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 15 May 2017 17:25:52 +0000 (13:25 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 15 May 2017 17:25:52 +0000 (13:25 -0400)
41 files changed:
src/include/dict.h
src/include/token.h
src/include/value.h
src/lib/util/dict.c
src/lib/util/pair.c
src/lib/util/value.c
src/main/acct.c
src/main/auth.c
src/main/cond_tokenize.c
src/main/listen.c
src/main/map.c
src/main/process.c
src/main/radclient.c
src/main/radsnmp.c
src/main/tmpl.c
src/main/unit_test_module.c
src/main/unlang_compile.c
src/main/virtual_servers.c
src/main/xlat_eval.c
src/modules/proto_dhcp/proto_dhcp.c
src/modules/proto_dhcp/rlm_dhcp.c
src/modules/proto_ldap_sync/proto_ldap_sync.c
src/modules/proto_radius/proto_radius_acct.c
src/modules/proto_radius/proto_radius_auth.c
src/modules/proto_radius/proto_radius_coa.c
src/modules/proto_radius/proto_radius_status.c
src/modules/proto_tacacs/proto_tacacs.c
src/modules/proto_tacacs/tacacs.c
src/modules/proto_vmps/proto_vmps.c
src/modules/rlm_eap/lib/base/eapcommon.c
src/modules/rlm_eap/types/rlm_eap_gtc/rlm_eap_gtc.c
src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c
src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c
src/modules/rlm_eap/types/rlm_eap_sim/rlm_eap_sim.c
src/modules/rlm_exec/rlm_exec.c
src/modules/rlm_json/json.c
src/modules/rlm_mschap/rlm_mschap.c
src/modules/rlm_pap/rlm_pap.c
src/modules/rlm_rediswho/rlm_rediswho.c
src/modules/rlm_yubikey/rlm_yubikey.c
src/tests/unit/dict.txt

index d0e5b37a0189865230fb881a87b7edc55491e897..fb9c0d2c14200609ce0c00afb9143f67c1f87dfa 100644 (file)
 #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
@@ -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
index 3352d6764506bf1b2e2b9a3df2f64b656ed69f00..c2faccc63b3ed948cd768d902f2d0119750b3638 100644 (file)
@@ -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[];
index aaaeb55121d0f61080a54773c1d777d1a94d1a6d..c461a955d0db075e56f7da6c3624ed47ff3fce6a 100644 (file)
 #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[];
@@ -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
index 35ea5e2cf4bec81327e3c7b6221d36f16384a7f5..f3dd1af33670133c791229a153c35bb5cc457b16 100644 (file)
@@ -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, "<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;
                }
        }
@@ -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);
 }
 
 /*
index 0bcc54560abed8f1efce851eab253f0048a4e3a1..784d9a5f36ecccd62fa047c4714ed674e553839d 100644 (file)
@@ -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;
index 04d201a1ac69f733b413e7e8bda4ba2efb5088ab..10b35320cdb080e3fbe009136ac703d036e06234 100644 (file)
@@ -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, "<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;
                        }
 
@@ -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) {
index 64e82c175bf07d5665a040657dcb4377e81f3ecf..e1befb140f2fbbf4420ab3882762c6a526ec822c 100644 (file)
@@ -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) {
                /*
index 4effa966f9e48c08f3a6a83630d7861673343525..34a23e4a073ac76bd725736de0a7d8298f47e36c 100644 (file)
@@ -115,7 +115,7 @@ static int rad_authlog(char const *msg, REQUEST *request, int goodpass)
                        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>");
                        }
@@ -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)));
                }
 
                /*
index b864144d9e43dce3030b131c00b4adb130cc794f..801bb770a8d9f6707a458837c0f547da5dbfcc59 100644 (file)
@@ -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) &&
index 626c7e1dd930d9f9a183661e25ec4a59bd15fd67..d20e6e2ace0f658e72e2fb196de3983c9fa14f7f 100644 (file)
@@ -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,
index 518f2529581d34fe4a34edcb73fd38cf82d5baaa..cc8867d25cb49cebb65a5b65aba81f0772558751 100644 (file)
@@ -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.
         *
index aba35c8faf793db6a0092af5255faf54d7887a32..c088e944c0efc695f596c2e2a4310c44313ec5d8 100644 (file)
@@ -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;
        }
 
index 328ccc53c4b0959b6496dd64af4c011e709c9466..8d6b021708c9d47733e909518016983587abd291 100644 (file)
@@ -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);
index 003b8801858557c0ddc70cfc6bb37a9855245f44..7847ca872f32d16eddbd4514da8573c1badca599 100644 (file)
@@ -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;
 
index b25f75cd46decaeaf2ad81070de2841b8d609ac9..f250f143d0949981fee469c392f97fc8fe246c92 100644 (file)
@@ -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.
index cd455119162fa3cc1dd8de996cd6227c82b6e8ee..a7ea2d3afa7e9db8dc91eb59d423b422b6bd7b42 100644 (file)
@@ -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);
index d83c26186b21e928702977fac03ab0dd9a33f8bd..ca721300966349dd0c99258975b3af86458a6bd0 100644 (file)
@@ -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);
index 1f464a27696fc9ca0560d4f5b5cdd40a43d7d2bc..18ebfa4899ec9e912dfbff3693c61ea2677830d3 100644 (file)
@@ -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",
index 833092859bf265999f6cbd4dbc50fc6c6f3906e1..4aed41ad51b40a271537ec6ad1b9bac5dde25dd4 100644 (file)
@@ -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);
                }
 
index a60f97680cf6edab9ef8fa1e63dbcdf0f78e4daa..5f6910b399132664f6ef95a09eaeadf3a44c62ae 100644 (file)
@@ -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);
index a9b91a2192b085b11e442308dd771630d37fa39e..d636336bdffbfdb2ceeda11420827de0a8339354 100644 (file)
@@ -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());
                        }
                }
index 1c45fa4b388e9183e94179787be2267318f1f712..a8bc68b9bf7b62228eee485747ecb04a425b665e 100644 (file)
@@ -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;
index fd580539d70717efdb29fd6055026d878041fa38..043adfff604ed926ad5b00d1bd2ce2b5215bbd02 100644 (file)
@@ -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;
index 4ab68366ef432f109853515a55cbf0719c16880f..589aa73a168cb0385fedd87376ace5d1e7a6693d 100644 (file)
@@ -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),
-                                        "<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>");
                        }
@@ -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;
                }
index 6abeeb54524cf03f6a7c4f1343f9c743d47677fc..e9d7adbee2ae1d1eff8b12911fee99e78d9d8aac 100644 (file)
@@ -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.
index 654fc52f33ece81fbea123f82e4d9d4ac6587d24..44843f9660586db61c2b1f184db3236a59ce1cc4 100644 (file)
@@ -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;
                }
index 018fb71a93779c858876dd37640086b962104a4c..05bed02284932f47507cc8c0bc22949b7f86ed54 100644 (file)
@@ -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;
                }
index ba64e978c9607c1b9ffa7bc7dcd061e0612ee823..66c14a6f61a91dc729cec97fc1c5914e3a9924d3 100644 (file)
@@ -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);
 
index 441114c7e1a8b82703be45828b1fc52296881d0a..fd0638d997a500d3970eaf6ffbc3105977b5c6ef 100644 (file)
@@ -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", "*");
 
index d4557f84da961c3ded02a26066bf1d36918deb62..4e70ddc047fa460ec3c59982f8adab2de853b650 100644 (file)
@@ -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";
 }
index f9be5c5e4fa232ef4eb122376399c08248f74646..0832747ea6f84376833bc315fe147df12e0ae677 100644 (file)
@@ -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;
 }
index 5a8cca056eaee4af49810eadf7d0bf72c4cf4c13..7a18082611b0bd01f08b422a80bb728089ad28fa 100644 (file)
@@ -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;
 }
index fa7a1161a47335a7136442e5f8380e1cf3e1baab..a61d7d9c78e5788eacfdac01d723f3781980b25d 100644 (file)
@@ -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;
index 0034276b31cd188399a6370bc5b8d55d3b0bc133..582a9f4bdd5fb8f6d2b367ef0a799853972ab6e7 100644 (file)
@@ -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;
index 3e7e7bcb949b86d734ac72207790bbfd0333e84a..457341ba7f7a1b7256b31d6645d5bcefcb8a8110 100644 (file)
@@ -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);
        }
 
        /*
index 39af53b6de26da95082ecf7bb26c8651ad6044d1..18e73365de4da7bebb43b588378e78eb40891220 100644 (file)
@@ -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
index 47efa8daa190908db4b3a90d5b216e43a9592339..3630c8e44bdbd95eef53cf4dbf2c0241e815544c 100644 (file)
@@ -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;
index 5f20c3f439a6036fb75c3367530a56866e86f9a7..a378e2352d44b5eda62eb6115e10f7429b681059 100644 (file)
@@ -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;
        }
index f8c93584ed7c1055d5ef00f77991f45a56cc8622..c7b5ff855b871b71f7b45d8ef5fe72a0d62fb841 100644 (file)
@@ -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;
        }
 
index 32c7927c192faeb49cc5ef74af9483f48810517a..ed8dafe5ee9595140ca65326240fa0827587f50f 100644 (file)
@@ -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;
index f5ca683f19614469d4593a74994b03555d897823..9a8e90aad78def9ebbfe9d3ed759beb60770ca73 100644 (file)
@@ -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"
 
 
 #