]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add type field to value_box_t
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 23 Jan 2017 17:00:07 +0000 (17:00 +0000)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 23 Jan 2017 17:18:51 +0000 (17:18 +0000)
... and modify all the hundres of places which get pair type from vp->da->type, to get it from the boxed value instead.

Add additional validation functions to check for places where the box type isn't set correctly.

References #1883
Closes #1012

53 files changed:
src/include/libradius.h
src/include/pair.h
src/include/tmpl.h
src/lib/pair.c
src/lib/print.c
src/lib/radius_decode.c
src/lib/radius_encode.c
src/lib/value.c
src/main/client.c
src/main/cond_eval.c
src/main/cond_tokenize.c
src/main/files.c
src/main/map.c
src/main/pair.c
src/main/radclient.c
src/main/radsnmp.c
src/main/realms.c
src/main/snmp.c
src/main/stats.c
src/main/tmpl.c
src/main/unit_test_module.c
src/main/unlang_compile.c
src/main/xlat_func.c
src/modules/proto_dhcp/dhcp.c
src/modules/proto_vmps/vqp.c
src/modules/rlm_cache/drivers/rlm_cache_redis/rlm_cache_redis.c
src/modules/rlm_cache/rlm_cache.c
src/modules/rlm_cache/serialize.c
src/modules/rlm_couchbase/mod.c
src/modules/rlm_date/rlm_date.c
src/modules/rlm_eap/lib/sim/sim_proto.c
src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c
src/modules/rlm_example/rlm_example.c
src/modules/rlm_expr/paircmp.c
src/modules/rlm_expr/rlm_expr.c
src/modules/rlm_json/json.c
src/modules/rlm_json/json.h
src/modules/rlm_json/rlm_json.c
src/modules/rlm_linelog/rlm_linelog.c
src/modules/rlm_lua/lua.c
src/modules/rlm_mschap/rlm_mschap.c
src/modules/rlm_perl/rlm_perl.c
src/modules/rlm_preprocess/rlm_preprocess.c
src/modules/rlm_python/rlm_python.c
src/modules/rlm_realm/rlm_realm.c
src/modules/rlm_redis/redis.c
src/modules/rlm_redis/redis.h
src/modules/rlm_redis_ippool/rlm_redis_ippool.c
src/modules/rlm_rest/rest.c
src/modules/rlm_rest/rlm_rest.c
src/modules/rlm_test/rlm_test.c
src/modules/rlm_unpack/rlm_unpack.c
src/modules/rlm_utf8/rlm_utf8.c

index ebb9e97ad9f6fffa15cdd31a7903ff453e35b2c5..48f5ebc1f630163666beed44fb4478032efd9fb3 100644 (file)
@@ -316,37 +316,32 @@ void              fr_pair_cursor_free(vp_cursor_t *cursor);
 extern size_t const value_box_field_sizes[];
 extern size_t const value_box_offsets[];
 
-int            value_box_cmp(PW_TYPE a_type, value_box_t const *a,
-                              PW_TYPE b_type, value_box_t const *b);
+int            value_box_cmp(value_box_t const *a, value_box_t const *b);
 
-int            value_box_cmp_op(FR_TOKEN op,
-                                 PW_TYPE a_type, value_box_t const *a,
-                                 PW_TYPE b_type, value_box_t const *b);
+int            value_box_cmp_op(FR_TOKEN op, value_box_t const *a, value_box_t const *b);
 
 size_t         fr_value_str_unescape(uint8_t *out, char const *in, size_t inlen, char quote);
 
+void           value_box_clear(value_box_t *data);
+
 int            value_box_from_str(TALLOC_CTX *ctx, value_box_t *dst,
-                                   PW_TYPE *src_type, fr_dict_attr_t const *src_enumv,
-                                   char const *src, ssize_t src_len, char quote);
+                                  PW_TYPE *type, fr_dict_attr_t const *enumv,
+                                  char const *in, ssize_t inlen, char quote);
 
-void           value_box_hton(value_box_t *dst, PW_TYPE type, value_box_t const *src);
+int            value_box_hton(value_box_t *dst, value_box_t const *src);
 
 int            value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
-                               PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv,
-                               PW_TYPE src_type, fr_dict_attr_t const *src_enumv,
-                               value_box_t const *src);
+                              PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv,
+                              value_box_t const *src);
 
-int            value_box_copy(TALLOC_CTX *ctx, value_box_t *dst, PW_TYPE type, const value_box_t *src);
+int            value_box_copy(TALLOC_CTX *ctx, value_box_t *dst, const value_box_t *src);
 
 size_t         value_box_snprint(char *out, size_t outlen,
-                                 PW_TYPE type, fr_dict_attr_t const *enumv,
                                  value_box_t const *data, char quote);
 
-int            value_box_steal(TALLOC_CTX *ctx, value_box_t *dst, PW_TYPE type, value_box_t const *src);
+int            value_box_steal(TALLOC_CTX *ctx, value_box_t *dst, value_box_t const *src);
 
-char           *value_box_asprint(TALLOC_CTX *ctx,
-                                   PW_TYPE type, fr_dict_attr_t const *enumv, value_box_t const *data,
-                                   char quote);
+char           *value_box_asprint(TALLOC_CTX *ctx, value_box_t const *data, char quote);
 
 extern uint32_t        fr_max_attributes; /* per incoming packet */
 #define        FR_MAX_PACKET_CODE (52)
index 2c16f9e32535d31bfeac1e10255cface0aad19fe..e7edfca343ec06c616c6338964c323bb62752e50 100644 (file)
@@ -90,7 +90,7 @@ struct value_box {
                double                  decimal;                //!< Double precision float.
                uint32_t                date;                   //!< Date (32bit Unix timestamp).
 
-               uint8_t                 filter[32];             //!< Ascend binary format a packed data structure.
+               uint8_t                 filter[32];             //!< Ascend binary format (a packed data structure).
 
        } datum;
 
@@ -197,6 +197,7 @@ typedef struct value_pair_raw {
 #define vp_decimal     data.datum.decimal
 #define vp_ptr         data.datum.ptr                          //!< Either octets or strvalue
 
+#define vp_type                data.type
 #define vp_length      data.length
 #define vp_tainted     data.tainted
 
@@ -246,7 +247,7 @@ void                fr_pair_add(VALUE_PAIR **head, VALUE_PAIR *vp);
 void           fr_pair_replace(VALUE_PAIR **head, VALUE_PAIR *add);
 
 int            fr_pair_update_by_num(TALLOC_CTX *ctx, VALUE_PAIR **list,
-                                     unsigned int vendor, unsigned int attr, int8_t tag, PW_TYPE type,
+                                     unsigned int vendor, unsigned int attr, int8_t tag,
                                      value_box_t *value);
 
 void           fr_pair_delete_by_num(VALUE_PAIR **head, unsigned int vendor, unsigned int attr, int8_t tag);
@@ -261,7 +262,7 @@ typedef             int8_t (*fr_cmp_t)(void const *a, void const *b);
  *     - 0 if not equal.
  *     - -1 on failure.
  */
-#define                fr_pair_cmp_op(_op, _a, _b)     value_box_cmp_op(_op, _a->da->type, &_a->data, _b->da->type, &_b->data)
+#define                fr_pair_cmp_op(_op, _a, _b)     value_box_cmp_op(_op, &_a->data, &_b->data)
 int8_t         fr_pair_cmp_by_da_tag(void const *a, void const *b);
 int8_t         fr_pair_cmp_by_parent_num_tag(void const *a, void const *b);
 int            fr_pair_cmp(VALUE_PAIR *a, VALUE_PAIR *b);
index b6302146b420430ea7bed270a4a1f49c75768ebc..1de3cd5cceabf58a6853e7a8b660dfa4e9542cc9 100644 (file)
@@ -209,10 +209,7 @@ typedef struct vp_tmpl_t {
                /*
                 *  Attribute value. Typically used as the RHS of an update map.
                 */
-               struct {
-                       PW_TYPE                 type;                    //!< Type of data.
-                       value_box_t             data;                    //!< Value data.
-               } literal;
+               value_box_t     literal;                         //!< Value data.
 
                xlat_exp_t      *xlat;   //!< pre-parsed xlat_exp_t
 
@@ -247,9 +244,9 @@ typedef struct vp_tmpl_t {
  * @{
  */
 #define tmpl_value_box         data.literal
-#define tmpl_value_box_type            data.literal.type
-#define tmpl_value_box_length  data.literal.data.length
-#define tmpl_value_box_datum           data.literal.data
+#define tmpl_value_box_datum   data.literal.datum
+#define tmpl_value_box_type    data.literal.type
+#define tmpl_value_box_length  data.literal.length
 /* @} **/
 
 /** @name Field accessors for #TMPL_TYPE_REGEX_STRUCT and #TMPL_TYPE_REGEX
@@ -399,8 +396,7 @@ vp_tmpl_t           *tmpl_alloc(TALLOC_CTX *ctx, tmpl_type_t type, char const *name,
 void                   tmpl_from_da(vp_tmpl_t *vpt, fr_dict_attr_t const *da, int8_t tag, int num,
                                     request_refs_t request, pair_lists_t list);
 
-int                    tmpl_afrom_value_box(TALLOC_CTX *ctx, vp_tmpl_t **out, value_box_t *data,
-                                             PW_TYPE type, fr_dict_attr_t const *enumv, bool steal);
+int                    tmpl_afrom_value_box(TALLOC_CTX *ctx, vp_tmpl_t **out, value_box_t *data, bool steal);
 
 ssize_t                        tmpl_from_attr_substr(vp_tmpl_t *vpt, char const *name,
                                              request_refs_t request_def, pair_lists_t list_def,
@@ -430,8 +426,7 @@ void                        tmpl_cast_in_place_str(vp_tmpl_t *vpt);
 int                    tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request,
                                        vp_tmpl_t const *vpt, fr_dict_attr_t const *cast);
 
-size_t                 tmpl_snprint(char *buffer, size_t bufsize, vp_tmpl_t const *vpt,
-                                   fr_dict_attr_t const *values);
+size_t                 tmpl_snprint(char *buffer, size_t bufsize, vp_tmpl_t const *vpt);
 
 ssize_t                        _tmpl_to_type(void *out,
                                      uint8_t *buff, size_t outlen,
index 05cf0d2ce7d18446a9f78cb4d67cae07001c456d..b94e322c611d33ebe4b3d0a3bf40e79c42b90f16 100644 (file)
@@ -102,6 +102,8 @@ VALUE_PAIR *fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
         */
        vp->da = da;
        vp->vp_length = da->flags.length;
+       vp->vp_type = da->type;
+       if (fr_dict_enum_types[da->type]) vp->data.datum.enumv = da;
 
        return vp;
 }
@@ -244,7 +246,7 @@ VALUE_PAIR *fr_pair_copy(TALLOC_CTX *ctx, VALUE_PAIR const *vp)
                return n;
        }
 
-       switch (vp->da->type) {
+       switch (vp->vp_type) {
        case PW_TYPE_OCTETS:
                n->vp_octets = NULL;    /* else fr_pair_value_memcpy will free vp's value */
                fr_pair_value_memcpy(n, vp->vp_octets, n->vp_length);
@@ -315,10 +317,10 @@ static VALUE_PAIR *fr_pair_make_unknown(TALLOC_CTX *ctx,
                                        char const *attribute, char const *value,
                                        FR_TOKEN op)
 {
-       ssize_t         len;
-       VALUE_PAIR      *vp, *vp2;
-       fr_dict_attr_t const *da;
-       vp_cursor_t cursor;
+       ssize_t                 len;
+       VALUE_PAIR              *vp, *vp2;
+       fr_dict_attr_t const    *da;
+       vp_cursor_t             cursor;
 
        vp = fr_pair_alloc(ctx);
        if (!vp) return NULL;
@@ -560,7 +562,7 @@ VALUE_PAIR *fr_pair_make(TALLOC_CTX *ctx, VALUE_PAIR **vps,
        /*
         *      We allow this for stupidity, but it's really a bad idea.
         */
-       if (vp->da->type == PW_TYPE_TLV) {
+       if (vp->vp_type == PW_TYPE_TLV) {
                ssize_t                 len;
                VALUE_PAIR              *head = NULL;
                PW_TYPE                 type = PW_TYPE_OCTETS;
@@ -849,7 +851,6 @@ void fr_pair_replace(VALUE_PAIR **head, VALUE_PAIR *replace)
  * @param[in] attr Number of attribute to update.
  * @param[in] vendor of attribute to update.
  * @param[in] tag of attribute to update.
- * @param[in] type of value.
  * @param[in] value to set.
  * @return
  *     - 0 on success.
@@ -857,7 +858,7 @@ void fr_pair_replace(VALUE_PAIR **head, VALUE_PAIR *replace)
  */
 int fr_pair_update_by_num(TALLOC_CTX *ctx, VALUE_PAIR **list,
                          unsigned int vendor, unsigned int attr, int8_t tag,
-                         PW_TYPE type, value_box_t *value)
+                         value_box_t *value)
 {
        vp_cursor_t cursor;
        VALUE_PAIR *vp;
@@ -866,14 +867,14 @@ int fr_pair_update_by_num(TALLOC_CTX *ctx, VALUE_PAIR **list,
        vp = fr_pair_cursor_next_by_num(&cursor, vendor, attr, tag);
        if (vp) {
                VERIFY_VP(vp);
-               if (value_box_steal(vp, &vp->data, type, value) < 0) return -1;
+               if (value_box_steal(vp, &vp->data, value) < 0) return -1;
                return 0;
        }
 
        vp = fr_pair_afrom_num(ctx, vendor, attr);
        if (!vp) return -1;
        vp->tag = tag;
-       if (value_box_steal(vp, &vp->data, type, value) < 0) return -1;
+       if (value_box_steal(vp, &vp->data, value) < 0) return -1;
 
        fr_pair_cursor_append(&cursor, vp);
 
@@ -1078,7 +1079,7 @@ int fr_pair_cmp(VALUE_PAIR *a, VALUE_PAIR *b)
                        regex_t *preg;
                        char    *value;
 
-                       if (!fr_cond_assert(a->da->type == PW_TYPE_STRING)) return -1;
+                       if (!fr_cond_assert(a->vp_type == PW_TYPE_STRING)) return -1;
 
                        slen = regex_compile(NULL, &preg, a->xlat, talloc_array_length(a->xlat) - 1, false, false, false, true);
                        if (slen <= 0) {
@@ -1153,8 +1154,7 @@ int fr_pair_list_cmp(VALUE_PAIR *a, VALUE_PAIR *b)
                        return 1;
                }
 
-               ret = value_box_cmp(a_p->da->type, &a_p->data,
-                                    b_p->da->type, &b_p->data);
+               ret = value_box_cmp(&a_p->data, &b_p->data);
                if (ret != 0) {
                        (void)fr_cond_assert(ret >= -1);        /* Comparison error */
                        return ret;
@@ -1793,7 +1793,7 @@ void fr_pair_list_move(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **from)
                         *      so instead we over-write the
                         *      vp that it's pointing to.
                         */
-                       switch (found->da->type) {
+                       switch (found->vp_type) {
                        default:
                                j = found->next;
                                memcpy(found, i, sizeof(*found));
@@ -1906,7 +1906,7 @@ static void fr_pair_list_move_by_num_internal(TALLOC_CTX *ctx, VALUE_PAIR **to,
                return;
        }
 
-       for(i = *from; i; i = next) {
+       for (i = *from; i; i = next) {
                VERIFY_VP(i);
                next = i->next;
 
@@ -2056,7 +2056,6 @@ void fr_pair_list_mcopy_by_num(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **fr
 int fr_pair_value_from_str(VALUE_PAIR *vp, char const *value, size_t inlen)
 {
        PW_TYPE type;
-       VERIFY_VP(vp);
 
        if (!value) return -1;
 
@@ -2087,6 +2086,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->type = VT_DATA;
 
@@ -2095,97 +2095,67 @@ int fr_pair_value_from_str(VALUE_PAIR *vp, char const *value, size_t inlen)
        return 0;
 }
 
-/** Set the type of the VALUE_PAIR value buffer to match it's fr_dict_attr_t
- *
- * @param vp to fixup.
- */
-inline static void fr_pair_value_set_type(VALUE_PAIR *vp)
-{
-       if (!vp->vp_ptr) return;
-
-       switch (vp->da->type) {
-       case PW_TYPE_OCTETS:
-               talloc_set_type(vp->vp_ptr, uint8_t);
-               return;
-
-       case PW_TYPE_STRING:
-               talloc_set_type(vp->vp_ptr, char);
-               return;
-
-       default:
-               return;
-       }
-}
-
 /** Copy data into an "octets" data type.
  *
- * @param[in,out] vp to update
- * @param[in] src data to copy
- * @param[in] size of the data, may be 0 in which case previous value will be freed.
+ * @param[in,out] vp   to update
+ * @param[in] src      data to copy
+ * @param[in] size     of the data.
  */
 void fr_pair_value_memcpy(VALUE_PAIR *vp, uint8_t const *src, size_t size)
 {
-       uint8_t *p = NULL, *q;
-
-       VERIFY_VP(vp);
+       uint8_t *p = NULL;
 
-       if (size > 0) {
-               p = talloc_memdup(vp, src, size);
-               if (!p) return;
-               talloc_set_type(p, uint8_t);
-       }
+       p = talloc_memdup(vp, src, size);
+       if (!p) return;
 
-       memcpy(&q, &vp->vp_octets, sizeof(q));
-       TALLOC_FREE(q);
+       value_box_clear(&vp->data);
 
        vp->vp_octets = p;
        vp->vp_length = size;
+       vp->vp_type = PW_TYPE_OCTETS;
+       talloc_set_type(vp->vp_ptr, uint8_t);
 
-       if (size > 0) fr_pair_value_set_type(vp);
+       vp->type = VT_DATA;
 
        VERIFY_VP(vp);
 }
 
 /** Reparent an allocated octet buffer to a VALUE_PAIR
  *
- * @param[in,out] vp to update
- * @param[in] src buffer to steal.
+ * @param[in,out] vp   to update
+ * @param[in] src      buffer to steal.
  */
 void fr_pair_value_memsteal(VALUE_PAIR *vp, uint8_t const *src)
 {
-       uint8_t *q;
-
-       VERIFY_VP(vp);
-
-       memcpy(&q, &vp->vp_octets, sizeof(q));
-       talloc_free(q);
+       value_box_clear(&vp->data);
 
        vp->vp_octets = talloc_steal(vp, src);
-       vp->type = VT_DATA;
        vp->vp_length = talloc_array_length(vp->vp_octets);
-       fr_pair_value_set_type(vp);
+       vp->vp_type = PW_TYPE_OCTETS;
+       talloc_set_type(vp->vp_ptr, uint8_t);
+
+       vp->type = VT_DATA;
 
        VERIFY_VP(vp);
 }
 
 /** Reparent an allocated char buffer to a VALUE_PAIR
  *
- * @param[in,out] vp to update
- * @param[in] src buffer to steal.
+ * @param[in,out] vp   to update
+ * @param[in] src      buffer to steal.
  */
 void fr_pair_value_strsteal(VALUE_PAIR *vp, char const *src)
 {
-       uint8_t *q;
-
-       VERIFY_VP(vp);
+       if (!fr_cond_assert(vp->da->type == PW_TYPE_STRING)) return;
 
-       memcpy(&q, &vp->vp_octets, sizeof(q));
-       talloc_free(q);
+       value_box_clear(&vp->data);
 
        vp->vp_strvalue = talloc_steal(vp, src);
-       vp->type = VT_DATA;
        vp->vp_length = talloc_array_length(vp->vp_strvalue) - 1;
-       fr_pair_value_set_type(vp);
+       vp->vp_type = PW_TYPE_STRING;
+       talloc_set_type(vp->vp_ptr, char);
+
+       vp->type = VT_DATA;
 
        VERIFY_VP(vp);
 }
@@ -2194,20 +2164,20 @@ void fr_pair_value_strsteal(VALUE_PAIR *vp, char const *src)
  *
  * If len is larger than the current buffer, the additional space will be filled with '\0'
  *
- * @param[in,out] vp to update
- * @param[in] src buffer to steal.
- * @param[in] len of data in buffer.
+ * @note vp->da must be of type PW_TYPE_STRING.
+ *
+ * @param[in,out] vp   to update
+ * @param[in] src      buffer to steal.
+ * @param[in] len      of data in buffer.
  */
 void fr_pair_value_strnsteal(VALUE_PAIR *vp, char *src, size_t len)
 {
-       uint8_t *q;
        char    *p;
        size_t  buf_len;
 
-       VERIFY_VP(vp);
+       if (!fr_cond_assert(vp->da->type == PW_TYPE_STRING)) return;
 
-       memcpy(&q, &vp->vp_octets, sizeof(q));
-       talloc_free(q);
+       value_box_clear(&vp->data);
 
        buf_len = talloc_array_length(src);
        if (buf_len > (len + 1)) {
@@ -2218,36 +2188,38 @@ void fr_pair_value_strnsteal(VALUE_PAIR *vp, char *src, size_t len)
        } else {
                vp->vp_strvalue = talloc_steal(vp, src);
        }
-       vp->vp_strvalue = talloc_steal(vp, src);
-       vp->type = VT_DATA;
        vp->vp_length = len;
-       fr_pair_value_set_type(vp);
+       vp->vp_type = PW_TYPE_STRING;
+       talloc_set_type(vp->vp_ptr, char);
+
+       vp->type = VT_DATA;
 
        VERIFY_VP(vp);
 }
 
 /** Copy data into an "string" data type.
+ *
+ * @note vp->da must be of type PW_TYPE_STRING.
  *
  * @param[in,out] vp to update
  * @param[in] src data to copy
  */
 void fr_pair_value_strcpy(VALUE_PAIR *vp, char const *src)
 {
-       char *p, *q;
+       char *p;
 
-       VERIFY_VP(vp);
+       if (!fr_cond_assert(vp->da->type == PW_TYPE_STRING)) return;
 
        p = talloc_strdup(vp, src);
-
        if (!p) return;
 
-       memcpy(&q, &vp->vp_strvalue, sizeof(q));
-       talloc_free(q);
+       value_box_clear(&vp->data);
 
        vp->vp_strvalue = p;
        vp->type = VT_DATA;
        vp->vp_length = talloc_array_length(vp->vp_strvalue) - 1;
-       fr_pair_value_set_type(vp);
+       vp->vp_type = PW_TYPE_STRING;
+       talloc_set_type(vp->vp_ptr, char);
 
        VERIFY_VP(vp);
 }
@@ -2257,15 +2229,17 @@ void fr_pair_value_strcpy(VALUE_PAIR *vp, char const *src)
  * @note unlike the original strncpy, this function does not stop
  *     if it finds \0 bytes embedded in the string.
  *
+ * @note vp->da must be of type PW_TYPE_STRING.
+ *
  * @param[in,out] vp to update.
  * @param[in] src data to copy.
  * @param[in] len of data to copy.
  */
 void fr_pair_value_bstrncpy(VALUE_PAIR *vp, void const *src, size_t len)
 {
-       char *p, *q;
+       char *p;
 
-       VERIFY_VP(vp);
+       if (!fr_cond_assert(vp->da->type == PW_TYPE_STRING)) return;
 
        p = talloc_array(vp, char, len + 1);
        if (!p) return;
@@ -2273,18 +2247,21 @@ void fr_pair_value_bstrncpy(VALUE_PAIR *vp, void const *src, size_t len)
        memcpy(p, src, len);    /* embdedded \0 safe */
        p[len] = '\0';
 
-       memcpy(&q, &vp->vp_strvalue, sizeof(q));
-       talloc_free(q);
+       value_box_clear(&vp->data);
 
        vp->vp_strvalue = p;
-       vp->type = VT_DATA;
        vp->vp_length = len;
-       fr_pair_value_set_type(vp);
+       vp->vp_type = PW_TYPE_STRING;
+       talloc_set_type(vp->vp_ptr, char);
+
+       vp->type = VT_DATA;
 
        VERIFY_VP(vp);
 }
 
 /** Print data into an "string" data type.
+ *
+ * @note vp->da must be of type PW_TYPE_STRING.
  *
  * @param[in,out] vp to update
  * @param[in] fmt the format string
@@ -2292,24 +2269,23 @@ void fr_pair_value_bstrncpy(VALUE_PAIR *vp, void const *src, size_t len)
 void fr_pair_value_snprintf(VALUE_PAIR *vp, char const *fmt, ...)
 {
        va_list ap;
-       char *p, *q;
+       char *p;
 
-       VERIFY_VP(vp);
+       if (!fr_cond_assert(vp->da->type == PW_TYPE_STRING)) return;
 
        va_start(ap, fmt);
        p = talloc_vasprintf(vp, fmt, ap);
        va_end(ap);
-
        if (!p) return;
 
-       memcpy(&q, &vp->vp_strvalue, sizeof(q));
-       talloc_free(q);
+       value_box_clear(&vp->data);
 
        vp->vp_strvalue = p;
-       vp->type = VT_DATA;
-
        vp->vp_length = talloc_array_length(vp->vp_strvalue) - 1;
-       fr_pair_value_set_type(vp);
+       vp->vp_type = PW_TYPE_STRING;
+       talloc_set_type(vp->vp_ptr, char);
+
+       vp->type = VT_DATA;
 
        VERIFY_VP(vp);
 }
@@ -2331,7 +2307,7 @@ size_t fr_pair_value_snprint(char *out, size_t outlen, VALUE_PAIR const *vp, cha
 
        if (vp->type == VT_XLAT) return snprintf(out, outlen, "%c%s%c", quote, vp->xlat, quote);
 
-       return value_box_snprint(out, outlen, vp->da->type, vp->da, &vp->data, quote);
+       return value_box_snprint(out, outlen, &vp->data, quote);
 }
 
 /** Print one attribute value to a string
@@ -2345,11 +2321,9 @@ char *fr_pair_value_asprint(TALLOC_CTX *ctx, VALUE_PAIR const *vp, char quote)
 {
        VERIFY_VP(vp);
 
-       if (vp->type == VT_XLAT) {
-               return fr_asprint(ctx, vp->xlat, talloc_array_length(vp->xlat) - 1, quote);
-       }
+       if (vp->type == VT_XLAT) return fr_asprint(ctx, vp->xlat, talloc_array_length(vp->xlat) - 1, quote);
 
-       return value_box_asprint(ctx, vp->da->type, vp->da, &vp->data, quote);
+       return value_box_asprint(ctx, &vp->data, quote);
 }
 
 /** Return a const buffer for an enum type attribute
@@ -2367,7 +2341,7 @@ char const *fr_pair_value_enum(VALUE_PAIR const *vp, char buff[20])
        char const              *str;
        fr_dict_enum_t const    *enumv = NULL;
 
-       switch (vp->da->type) {
+       switch (vp->vp_type) {
        case PW_TYPE_NUMERIC:
                break;
 
@@ -2376,7 +2350,7 @@ char const *fr_pair_value_enum(VALUE_PAIR const *vp, char buff[20])
                return NULL;
        }
 
-       if (vp->da->flags.has_value) switch (vp->da->type) {
+       if (vp->da->flags.has_value) switch (vp->vp_type) {
        case PW_TYPE_BOOLEAN:
                return vp->vp_bool ? "yes" : "no";
 
@@ -2595,13 +2569,13 @@ char *fr_pair_asprint(TALLOC_CTX *ctx, VALUE_PAIR const *vp, char quote)
        value = fr_pair_value_asprint(ctx, vp, quote);
 
        if (vp->da->flags.has_tag) {
-               if (quote && (vp->da->type == PW_TYPE_STRING)) {
+               if (quote && (vp->vp_type == PW_TYPE_STRING)) {
                        str = talloc_asprintf(ctx, "%s:%d %s %c%s%c", vp->da->name, vp->tag, token, quote, value, quote);
                } else {
                        str = talloc_asprintf(ctx, "%s:%d %s %s", vp->da->name, vp->tag, token, value);
                }
        } else {
-               if (quote && (vp->da->type == PW_TYPE_STRING)) {
+               if (quote && (vp->vp_type == PW_TYPE_STRING)) {
                        str = talloc_asprintf(ctx, "%s %s %c%s%c", vp->da->name, token, quote, value, quote);
                } else {
                        str = talloc_asprintf(ctx, "%s %s %s", vp->da->name, token, value);
@@ -2807,7 +2781,7 @@ inline void fr_pair_verify(char const *file, int line, VALUE_PAIR const *vp)
 
        fr_dict_verify(file, line, vp->da);
 
-       if (vp->vp_ptr) switch (vp->da->type) {
+       if (vp->vp_ptr) switch (vp->vp_type) {
        case PW_TYPE_OCTETS:
        {
                size_t len;
@@ -2889,7 +2863,7 @@ inline void fr_pair_verify(char const *file, int line, VALUE_PAIR const *vp)
                        FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR attribute %p \"%s\" (%s) "
                                     "not found in global dictionary",
                                     file, line, vp->da, vp->da->name,
-                                    fr_int2str(dict_attr_types, vp->da->type, "<INVALID>"));
+                                    fr_int2str(dict_attr_types, vp->vp_type, "<INVALID>"));
                        if (!fr_cond_assert(0)) fr_exit_now(1);
                }
 
@@ -2915,6 +2889,24 @@ inline void fr_pair_verify(char const *file, int line, VALUE_PAIR const *vp)
                        if (!fr_cond_assert(0)) fr_exit_now(1);
                }
        }
+
+       if (vp->da->flags.is_raw || vp->da->flags.is_unknown) {
+               if (vp->data.type != PW_TYPE_OCTETS) {
+                       FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR (raw/unknown) attribute %p \"%s\" "
+                                    "data type incorrect.  Expected %s, got %s",
+                                    file, line, vp->da, vp->da->name,
+                                    fr_int2str(dict_attr_types, PW_TYPE_OCTETS, "<INVALID>"),
+                                    fr_int2str(dict_attr_types, vp->data.type, "<INVALID>"));
+                       if (!fr_cond_assert(0)) fr_exit_now(1);
+               }
+       } else if (vp->da->type != vp->data.type) {
+               FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR attribute %p \"%s\" "
+                            "data type (%s) does not match da type (%s)",
+                            file, line, vp->da, vp->da->name,
+                            fr_int2str(dict_attr_types, vp->data.type, "<INVALID>"),
+                            fr_int2str(dict_attr_types, vp->da->type, "<INVALID>"));
+               if (!fr_cond_assert(0)) fr_exit_now(1);
+       }
 }
 
 /*
index b68e200bc329bb71a35239794f330a2320310136..fd615d1e567752fdbb01939dbe732d8197ec1ea5 100644 (file)
@@ -612,7 +612,7 @@ char *fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
                                 *      string need to occur in the NULL ctx so we don't fragment
                                 *      any pool associated with it.
                                 */
-                               subst = value_box_asprint(NULL, in->type, in->datum.enumv, in, '"');
+                               subst = value_box_asprint(NULL, in, '"');
                                if (!subst) {
                                        talloc_free(out);
                                        return NULL;
index 330ac00db4c7697fe90cfbd6963707683eabd9b3..8d84fa8177eaf1fb271a615974a4a81343b80bd4 100644 (file)
@@ -1455,7 +1455,7 @@ ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, vp_cursor_t *cursor, fr_dict_attr
                 *      because the talloc API won't let us.  So, we
                 *      just create a fake attribute.
                 */
-               vp = fr_pair_afrom_da(ctx,da);
+               vp = fr_pair_afrom_da(ctx, da);
                if (!vp) return -1;
                fr_pair_cursor_append(cursor, vp);
                vp->vp_tainted = true;          /* not REALLY necessary, but what the heck */
index b1ed5588fad02c3187598471e09cdb965ddaa02c..edabcadff3e399cc6aac4003f229ba58ef7e1c04 100644 (file)
@@ -431,7 +431,7 @@ ssize_t fr_radius_encode_value_hton(uint8_t *out, size_t outlen, VALUE_PAIR cons
         */
        if (outlen > vp->vp_length) outlen = vp->vp_length;
 
-       switch (vp->da->type) {
+       switch (vp->vp_type) {
        case PW_TYPE_STRING:
        case PW_TYPE_OCTETS:
                memcpy(out, vp->vp_ptr, outlen);
@@ -499,7 +499,7 @@ ssize_t fr_radius_encode_value_hton(uint8_t *out, size_t outlen, VALUE_PAIR cons
        case PW_TYPE_TIMEVAL:
        case PW_TYPE_DECIMAL:
        case PW_TYPE_MAX:
-               fr_strerror_printf("Cannot get data for VALUE_PAIR type %i", vp->da->type);
+               fr_strerror_printf("Cannot get data for VALUE_PAIR type %i", vp->vp_type);
                return -1;
 
        /* Don't add default */
@@ -875,11 +875,11 @@ static ssize_t encode_value(uint8_t *out, size_t outlen,
 
        default:
                if (vp->da->flags.has_tag && TAG_VALID(vp->tag)) {
-                       if (vp->da->type == PW_TYPE_STRING) {
+                       if (vp->vp_type == PW_TYPE_STRING) {
                                if (len > ((ssize_t) (outlen - 1))) len = outlen - 1;
                                ptr[0] = vp->tag;
                                ptr++;
-                       } else if (vp->da->type == PW_TYPE_INTEGER) {
+                       } else if (vp->vp_type == PW_TYPE_INTEGER) {
                                buffer[0] = vp->tag;
                        } /* else it can't be any other type */
                }
@@ -1611,7 +1611,7 @@ int fr_radius_encode_pair(uint8_t *out, size_t outlen, vp_cursor_t *cursor, void
        /*
         *      Fast path for the common case.
         */
-       if (vp->da->parent->flags.is_root && !vp->da->flags.concat && (vp->da->type != PW_TYPE_TLV)) {
+       if (vp->da->parent->flags.is_root && !vp->da->flags.concat && (vp->vp_type != PW_TYPE_TLV)) {
                tlv_stack[0] = vp->da;
                tlv_stack[1] = NULL;
                FR_PROTO_STACK_PRINT(tlv_stack, 0);
index 9c838884083f1a69c058972adea9fd828d33b329..a668fc6fb36fc86110aaaac05d7f592106d39163 100644 (file)
@@ -92,11 +92,22 @@ size_t const value_box_offsets[] = {
        [PW_TYPE_MAX]                           = 0     /* Force compiler to allocate memory for all types */
 };
 
+/** Copy flags and type data from one value box to another
+ *
+ * @param[in] dst to copy flags to
+ * @param[in] src of data.
+ */
+static inline void value_box_copy_attrs(value_box_t *dst, value_box_t const *src)
+{
+       dst->type = src->type;
+       dst->length = src->length;
+       dst->tainted = src->tainted;
+       if (fr_dict_enum_types[dst->type]) dst->datum.enumv = src->datum.enumv;
+}
+
 /** Compare two values
  *
- * @param[in] a_type of data to compare.
  * @param[in] a Value to compare.
- * @param[in] b_type of data to compare.
  * @param[in] b Value to compare.
  * @return
  *     - -1 if a is less than b.
@@ -104,12 +115,14 @@ size_t const value_box_offsets[] = {
  *     - 1 if a is more than b.
  *     - < -1 on failure.
  */
-int value_box_cmp(PW_TYPE a_type, value_box_t const *a,
-                  PW_TYPE b_type, value_box_t const *b)
+int value_box_cmp(value_box_t const *a, value_box_t const *b)
 {
        int compare = 0;
 
-       if (a_type != b_type) {
+       if (!fr_cond_assert(a->type != PW_TYPE_INVALID)) return -1;
+       if (!fr_cond_assert(b->type != PW_TYPE_INVALID)) return -1;
+
+       if (a->type != b->type) {
                fr_strerror_printf("Can't compare values of different types");
                return -2;
        }
@@ -118,7 +131,7 @@ int value_box_cmp(PW_TYPE a_type, value_box_t const *a,
         *      After doing the previous check for special comparisons,
         *      do the per-type comparison here.
         */
-       switch (a_type) {
+       switch (a->type) {
        case PW_TYPE_ABINARY:
        case PW_TYPE_OCTETS:
        case PW_TYPE_STRING:    /* We use memcmp to be \0 safe */
@@ -360,32 +373,31 @@ static int value_box_cidr_cmp_op(FR_TOKEN op, int bytes,
 /** Compare two attributes using an operator
  *
  * @param[in] op to use in comparison.
- * @param[in] a_type of data to compare.
  * @param[in] a Value to compare.
- * @param[in] b_type of data to compare.
  * @param[in] b Value to compare.
  * @return
  *     - 1 if true
  *     - 0 if false
  *     - -1 on failure.
  */
-int value_box_cmp_op(FR_TOKEN op,
-                     PW_TYPE a_type, value_box_t const *a,
-                     PW_TYPE b_type, value_box_t const *b)
+int value_box_cmp_op(FR_TOKEN op, value_box_t const *a, value_box_t const *b)
 {
        int compare = 0;
 
        if (!a || !b) return -1;
 
-       switch (a_type) {
+       if (!fr_cond_assert(a->type != PW_TYPE_INVALID)) return -1;
+       if (!fr_cond_assert(b->type != PW_TYPE_INVALID)) return -1;
+
+       switch (a->type) {
        case PW_TYPE_IPV4_ADDR:
-               switch (b_type) {
+               switch (b->type) {
                case PW_TYPE_IPV4_ADDR:         /* IPv4 and IPv4 */
                        goto cmp;
 
                case PW_TYPE_IPV4_PREFIX:       /* IPv4 and IPv4 Prefix */
                        return value_box_cidr_cmp_op(op, 4, 32, (uint8_t const *) &a->datum.ipaddr,
-                                                     b->datum.ipv4prefix[1], (uint8_t const *) &b->datum.ipv4prefix[2]);
+                                                    b->datum.ipv4prefix[1], (uint8_t const *) &b->datum.ipv4prefix[2]);
 
                default:
                        fr_strerror_printf("Cannot compare IPv4 with IPv6 address");
@@ -393,16 +405,16 @@ int value_box_cmp_op(FR_TOKEN op,
                }
 
        case PW_TYPE_IPV4_PREFIX:               /* IPv4 and IPv4 Prefix */
-               switch (b_type) {
+               switch (b->type) {
                case PW_TYPE_IPV4_ADDR:
                        return value_box_cidr_cmp_op(op, 4, a->datum.ipv4prefix[1],
-                                                     (uint8_t const *) &a->datum.ipv4prefix[2],
-                                                     32, (uint8_t const *) &b->datum.ipaddr);
+                                                    (uint8_t const *) &a->datum.ipv4prefix[2],
+                                                    32, (uint8_t const *) &b->datum.ipaddr);
 
                case PW_TYPE_IPV4_PREFIX:       /* IPv4 Prefix and IPv4 Prefix */
                        return value_box_cidr_cmp_op(op, 4, a->datum.ipv4prefix[1],
-                                                     (uint8_t const *) &a->datum.ipv4prefix[2],
-                                                     b->datum.ipv4prefix[1], (uint8_t const *) &b->datum.ipv4prefix[2]);
+                                                    (uint8_t const *) &a->datum.ipv4prefix[2],
+                                                    b->datum.ipv4prefix[1], (uint8_t const *) &b->datum.ipv4prefix[2]);
 
                default:
                        fr_strerror_printf("Cannot compare IPv4 with IPv6 address");
@@ -410,13 +422,13 @@ int value_box_cmp_op(FR_TOKEN op,
                }
 
        case PW_TYPE_IPV6_ADDR:
-               switch (b_type) {
+               switch (b->type) {
                case PW_TYPE_IPV6_ADDR:         /* IPv6 and IPv6 */
                        goto cmp;
 
                case PW_TYPE_IPV6_PREFIX:       /* IPv6 and IPv6 Preifx */
                        return value_box_cidr_cmp_op(op, 16, 128, (uint8_t const *) &a->datum.ipv6addr,
-                                                     b->datum.ipv6prefix[1], (uint8_t const *) &b->datum.ipv6prefix[2]);
+                                                    b->datum.ipv6prefix[1], (uint8_t const *) &b->datum.ipv6prefix[2]);
 
                default:
                        fr_strerror_printf("Cannot compare IPv6 with IPv4 address");
@@ -424,16 +436,16 @@ int value_box_cmp_op(FR_TOKEN op,
                }
 
        case PW_TYPE_IPV6_PREFIX:
-               switch (b_type) {
+               switch (b->type) {
                case PW_TYPE_IPV6_ADDR:         /* IPv6 Prefix and IPv6 */
                        return value_box_cidr_cmp_op(op, 16, a->datum.ipv6prefix[1],
-                                                     (uint8_t const *) &a->datum.ipv6prefix[2],
-                                                     128, (uint8_t const *) &b->datum.ipv6addr);
+                                                    (uint8_t const *) &a->datum.ipv6prefix[2],
+                                                    128, (uint8_t const *) &b->datum.ipv6addr);
 
                case PW_TYPE_IPV6_PREFIX:       /* IPv6 Prefix and IPv6 */
                        return value_box_cidr_cmp_op(op, 16, a->datum.ipv6prefix[1],
-                                                     (uint8_t const *) &a->datum.ipv6prefix[2],
-                                                     b->datum.ipv6prefix[1], (uint8_t const *) &b->datum.ipv6prefix[2]);
+                                                    (uint8_t const *) &a->datum.ipv6prefix[2],
+                                                    b->datum.ipv6prefix[1], (uint8_t const *) &b->datum.ipv6prefix[2]);
 
                default:
                        fr_strerror_printf("Cannot compare IPv6 with IPv4 address");
@@ -442,7 +454,7 @@ int value_box_cmp_op(FR_TOKEN op,
 
        default:
        cmp:
-               compare = value_box_cmp(a_type, a, b_type, b);
+               compare = value_box_cmp(a, b);
                if (compare < -1) {     /* comparison error */
                        return -1;
                }
@@ -691,12 +703,44 @@ size_t fr_value_str_unescape(uint8_t *out, char const *in, size_t inlen, char qu
        return out_p - out;
 }
 
+/** Clear/free any existing value
+ *
+ * @note Do not use on uninitialised memory.
+ *
+ * @param[in] data to clear.
+ */
+void value_box_clear(value_box_t *data)
+{
+       switch (data->type) {
+       case PW_TYPE_OCTETS:
+       case PW_TYPE_STRING:
+               TALLOC_FREE(data->datum.ptr);
+               break;
+
+       case PW_TYPE_STRUCTURAL:
+               if (!fr_cond_assert(0)) return;
+
+       case PW_TYPE_INVALID:
+               return;
+
+       default:
+               memset(&data->datum, 0, dict_attr_sizes[data->type][1]);
+               break;
+       }
+
+       data->tainted = false;
+       data->type = PW_TYPE_INVALID;
+       data->length = 0;
+}
+
 /** Convert string value to a value_box_t type
+ *
+ * @fixme Should take taint param.
  *
  * @param[in] ctx              to alloc strings in.
  * @param[out] dst             where to write parsed value.
- * @param[in,out] src_type     of value data to create/type of value created.
- * @param[in] src_enumv                fr_dict_attr_t with string aliases for integer values.
+ * @param[in,out] dst_type     of value data to create/dst_type of value created.
+ * @param[in] dst_enumv                fr_dict_attr_t with string aliases for integer values.
  * @param[in] in               String to convert. Binary safe for variable length values
  *                             if len is provided.
  * @param[in] inlen            may be < 0 in which case strlen(len) is used to determine
@@ -708,14 +752,16 @@ size_t fr_value_str_unescape(uint8_t *out, char const *in, size_t inlen, char qu
  *     - -1 on parse error.
  */
 int value_box_from_str(TALLOC_CTX *ctx, value_box_t *dst,
-                       PW_TYPE *src_type, fr_dict_attr_t const *src_enumv,
-                       char const *in, ssize_t inlen, char quote)
+                      PW_TYPE *dst_type, fr_dict_attr_t const *dst_enumv,
+                      char const *in, ssize_t inlen, char quote)
 {
        fr_dict_enum_t  *dval;
        size_t          len;
        ssize_t         ret;
        char            buffer[256];
 
+       if (!fr_cond_assert(*dst_type != PW_TYPE_INVALID)) return -1;
+
        if (!in) return -1;
 
        len = (inlen < 0) ? strlen(in) : (size_t)inlen;
@@ -723,13 +769,13 @@ int value_box_from_str(TALLOC_CTX *ctx, value_box_t *dst,
        /*
         *      Set size for all fixed length attributes.
         */
-       ret = dict_attr_sizes[*src_type][1];    /* Max length */
+       ret = dict_attr_sizes[*dst_type][1];    /* Max length */
 
        /*
-        *      It's a variable ret src_type so we just alloc a new buffer
+        *      It's a variable ret src->dst_type so we just alloc a new buffer
         *      of size len and copy.
         */
-       switch (*src_type) {
+       switch (*dst_type) {
        case PW_TYPE_STRING:
        {
                char *buff, *p;
@@ -906,12 +952,12 @@ int value_box_from_str(TALLOC_CTX *ctx, value_box_t *dst,
        case PW_TYPE_STRUCTURAL_EXCEPT_VSA:
        case PW_TYPE_VENDOR:
        case PW_TYPE_BAD:
-               fr_strerror_printf("Invalid type %d", *src_type);
+               fr_strerror_printf("Invalid dst_type %d", *dst_type);
                return -1;
        }
 
        /*
-        *      It's a fixed size src_type, copy to a temporary buffer and
+        *      It's a fixed size src->dst_type, copy to a temporary buffer and
         *      \0 terminate if insize >= 0.
         */
        if (inlen > 0) {
@@ -925,7 +971,7 @@ int value_box_from_str(TALLOC_CTX *ctx, value_box_t *dst,
                in = buffer;
        }
 
-       switch (*src_type) {
+       switch (*dst_type) {
        case PW_TYPE_BYTE:
        {
                char *p;
@@ -940,10 +986,10 @@ int value_box_from_str(TALLOC_CTX *ctx, value_box_t *dst,
                 *      Look for the named in for the given
                 *      attribute.
                 */
-               if (src_enumv && *p && !is_whitespace(p)) {
-                       if ((dval = fr_dict_enum_by_name(NULL, src_enumv, in)) == NULL) {
+               if (dst_enumv && *p && !is_whitespace(p)) {
+                       if ((dval = fr_dict_enum_by_name(NULL, dst_enumv, in)) == NULL) {
                                fr_strerror_printf("Unknown or invalid value \"%s\" for attribute %s",
-                                                  in, src_enumv->name);
+                                                  in, dst_enumv->name);
                                return -1;
                        }
 
@@ -973,10 +1019,10 @@ int value_box_from_str(TALLOC_CTX *ctx, value_box_t *dst,
                 *      Look for the named in for the given
                 *      attribute.
                 */
-               if (src_enumv && *p && !is_whitespace(p)) {
-                       if ((dval = fr_dict_enum_by_name(NULL, src_enumv, in)) == NULL) {
+               if (dst_enumv && *p && !is_whitespace(p)) {
+                       if ((dval = fr_dict_enum_by_name(NULL, dst_enumv, in)) == NULL) {
                                fr_strerror_printf("Unknown or invalid value \"%s\" for attribute %s",
-                                                  in, src_enumv->name);
+                                                  in, dst_enumv->name);
                                return -1;
                        }
 
@@ -1006,10 +1052,10 @@ int value_box_from_str(TALLOC_CTX *ctx, value_box_t *dst,
                 *      Look for the named in for the given
                 *      attribute.
                 */
-               if (src_enumv && *p && !is_whitespace(p)) {
-                       if ((dval = fr_dict_enum_by_name(NULL, src_enumv, in)) == NULL) {
+               if (dst_enumv && *p && !is_whitespace(p)) {
+                       if ((dval = fr_dict_enum_by_name(NULL, dst_enumv, in)) == NULL) {
                                fr_strerror_printf("Unknown or invalid value \"%s\" for attribute %s",
-                                                  in, src_enumv->name);
+                                                  in, dst_enumv->name);
                                return -1;
                        }
 
@@ -1133,10 +1179,10 @@ int value_box_from_str(TALLOC_CTX *ctx, value_box_t *dst,
                break;
 
        /*
-        *      Crazy polymorphic (IPv4/IPv6) attribute src_type for WiMAX.
+        *      Crazy polymorphic (IPv4/IPv6) attribute src->dst_type for WiMAX.
         *
         *      We try and make is saner by replacing the original
-        *      da, with either an IPv4 or IPv6 da src_type.
+        *      da, with either an IPv4 or IPv6 da src->dst_type.
         *
         *      These are not dynamic da, and will have the same vendor
         *      and attribute as the original.
@@ -1144,7 +1190,7 @@ int value_box_from_str(TALLOC_CTX *ctx, value_box_t *dst,
        case PW_TYPE_COMBO_IP_ADDR:
        {
                if (inet_pton(AF_INET6, in, &dst->datum.ipv6addr) > 0) {
-                       *src_type = PW_TYPE_IPV6_ADDR;
+                       *dst_type = PW_TYPE_IPV6_ADDR;
                        ret = dict_attr_sizes[PW_TYPE_COMBO_IP_ADDR][1]; /* size of IPv6 address */
                } else {
                        fr_ipaddr_t ipaddr;
@@ -1154,7 +1200,7 @@ int value_box_from_str(TALLOC_CTX *ctx, value_box_t *dst,
                                return -1;
                        }
 
-                       *src_type = PW_TYPE_IPV4_ADDR;
+                       *dst_type = PW_TYPE_IPV4_ADDR;
                        dst->datum.ipaddr.s_addr = ipaddr.ipaddr.ip4addr.s_addr;
                        ret = dict_attr_sizes[PW_TYPE_COMBO_IP_ADDR][0]; /* size of IPv4 address */
                }
@@ -1173,22 +1219,36 @@ int value_box_from_str(TALLOC_CTX *ctx, value_box_t *dst,
        case PW_TYPE_UNBOUNDED:         /* Should have been dealt with above */
        case PW_TYPE_STRUCTURAL:        /* Listed again to suppress compiler warnings */
        case PW_TYPE_BAD:
-               fr_strerror_printf("Unknown attribute type %d", *src_type);
+               fr_strerror_printf("Unknown attribute dst_type %d", *dst_type);
                return -1;
        }
 
 finish:
        dst->length = ret;
+       dst->type = *dst_type;
+
+       /*
+        *      Fixup enumv
+        */
+       if (fr_dict_enum_types[dst->type]) dst->datum.enumv = dst_enumv;
+
        return 0;
 }
 
 /** Performs byte order reversal for types that need it
  *
+ * @param[in] dst      Where to write the result.  May be the same as src.
+ * @param[in] src      #value_box_t containing an integer value.
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
  */
-void value_box_hton(value_box_t *dst, PW_TYPE type, value_box_t const *src)
+int value_box_hton(value_box_t *dst, value_box_t const *src)
 {
+       if (!fr_cond_assert(src->type != PW_TYPE_INVALID)) return -1;
+
        /* 8 byte integers */
-       switch (type) {
+       switch (src->type) {
        case PW_TYPE_INTEGER64:
                dst->datum.integer64 = htonll(src->datum.integer64);
                break;
@@ -1207,13 +1267,16 @@ void value_box_hton(value_box_t *dst, PW_TYPE type, value_box_t const *src)
 
        case PW_TYPE_OCTETS:
        case PW_TYPE_STRING:
-               (void)fr_cond_assert(0);
-               return;         /* shouldn't happen */
+               if (!fr_cond_assert(0)) return -1; /* shouldn't happen */
 
        default:
-               value_box_copy(NULL, dst, type, src);
+               value_box_copy(NULL, dst, src);
                break;
        }
+
+       value_box_copy_attrs(dst, src);
+
+       return 0;
 }
 
 /** Convert one type of value_box_t to another
@@ -1224,21 +1287,21 @@ void value_box_hton(value_box_t *dst, PW_TYPE type, value_box_t const *src)
  * @param dst Where to write result of casting.
  * @param dst_type to cast to.
  * @param dst_enumv Enumerated values used to converts strings to integers.
- * @param src_type to cast from.
- * @param src_enumv Enumerated values used to convert integers to strings.
  * @param src Input data.
  * @return
  *     - 0 on success.
  *     - -1 on failure.
  */
 int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
-                   PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv,
-                   PW_TYPE src_type, fr_dict_attr_t const *src_enumv,
-                   value_box_t const *src)
+                  PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv,
+                  value_box_t const *src)
 {
+       if (!fr_cond_assert(dst_type != PW_TYPE_INVALID)) return -1;
+       if (!fr_cond_assert(src->type != PW_TYPE_INVALID)) return -1;
+
        if (fr_dict_non_data_types[dst_type]) {
                fr_strerror_printf("Invalid cast from %s to %s.  Can only cast simple data types.",
-                                  fr_int2str(dict_attr_types, src_type, "<INVALID>"),
+                                  fr_int2str(dict_attr_types, src->type, "<INVALID>"),
                                   fr_int2str(dict_attr_types, dst_type, "<INVALID>"));
                return -1;
        }
@@ -1246,12 +1309,12 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
        /*
         *      If it's the same type, copy.
         */
-       if (dst_type == src_type) return value_box_copy(ctx, dst, src_type, src);
+       if (dst_type == src->type) return value_box_copy(ctx, dst, src);
 
        /*
         *      Deserialise a value_box_t
         */
-       if (src_type == PW_TYPE_STRING) {
+       if (src->type == PW_TYPE_STRING) {
                return value_box_from_str(ctx, dst, &dst_type, dst_enumv, src->datum.strvalue, src->length, '\0');
        }
 
@@ -1259,9 +1322,10 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
         *      Converts the src data to octets with no processing.
         */
        if (dst_type == PW_TYPE_OCTETS) {
-               value_box_hton(dst, src_type, src);
+               value_box_hton(dst, src);
                dst->datum.octets = talloc_memdup(ctx, &dst->datum, src->length);
                dst->length = src->length;
+               dst->type = dst_type;
                talloc_set_type(dst->datum.octets, uint8_t);
                return 0;
        }
@@ -1270,21 +1334,26 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
         *      Serialise a value_box_t
         */
        if (dst_type == PW_TYPE_STRING) {
-               dst->datum.strvalue = value_box_asprint(ctx, src_type, src_enumv, src, '\0');
+               dst->datum.strvalue = value_box_asprint(ctx, src, '\0');
                dst->length = talloc_array_length(dst->datum.strvalue) - 1;
+               dst->type = dst_type;
                return 0;
        }
 
-       if ((src_type == PW_TYPE_IFID) &&
+       if ((src->type == PW_TYPE_IFID) &&
            (dst_type == PW_TYPE_INTEGER64)) {
                memcpy(&dst->datum.integer64, src->datum.ifid, sizeof(src->datum.ifid));
                dst->datum.integer64 = htonll(dst->datum.integer64);
+
        fixed_length:
                dst->length = dict_attr_sizes[dst_type][0];
+               dst->type = dst_type;
+               if (fr_dict_enum_types[dst_type]) dst->datum.enumv = dst_enumv;
+
                return 0;
        }
 
-       if ((src_type == PW_TYPE_INTEGER64) &&
+       if ((src->type == PW_TYPE_INTEGER64) &&
            (dst_type == PW_TYPE_ETHERNET)) {
                uint8_t array[8];
                uint64_t i;
@@ -1302,7 +1371,7 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
        }
 
        if (dst_type == PW_TYPE_SHORT) {
-               switch (src_type) {
+               switch (src->type) {
                case PW_TYPE_BYTE:
                        dst->datum.ushort = src->datum.byte;
                        break;
@@ -1321,7 +1390,7 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
         *      as the long one is on the LHS.
         */
        if (dst_type == PW_TYPE_INTEGER) {
-               switch (src_type) {
+               switch (src->type) {
                case PW_TYPE_BYTE:
                        dst->datum.integer = src->datum.byte;
                        break;
@@ -1353,7 +1422,7 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
         *      a larger type, but not vice-versa.
         */
        if (dst_type == PW_TYPE_INTEGER64) {
-               switch (src_type) {
+               switch (src->type) {
                case PW_TYPE_BYTE:
                        dst->datum.integer64 = src->datum.byte;
                        break;
@@ -1376,7 +1445,7 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
                default:
                invalid_cast:
                        fr_strerror_printf("Invalid cast from %s to %s",
-                                          fr_int2str(dict_attr_types, src_type, "<INVALID>"),
+                                          fr_int2str(dict_attr_types, src->type, "<INVALID>"),
                                           fr_int2str(dict_attr_types, dst_type, "<INVALID>"));
                        return -1;
 
@@ -1388,7 +1457,7 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
         *      We can cast integers less that < INT_MAX to signed
         */
        if (dst_type == PW_TYPE_SIGNED) {
-               switch (src_type) {
+               switch (src->type) {
                case PW_TYPE_BYTE:
                        dst->datum.sinteger = src->datum.byte;
                        break;
@@ -1425,7 +1494,7 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
        }
 
        if (dst_type == PW_TYPE_TIMEVAL) {
-               switch (src_type) {
+               switch (src->type) {
                case PW_TYPE_BYTE:
                        dst->datum.timeval.tv_sec = src->datum.byte;
                        dst->datum.timeval.tv_usec = 0;
@@ -1479,12 +1548,12 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
 
                switch (dst_type) {
                case PW_TYPE_IPV4_ADDR:
-                       switch (src_type) {
+                       switch (src->type) {
                        case PW_TYPE_IPV6_ADDR:
                                if (memcmp(src->datum.ipv6addr.s6_addr, v4_v6_map, sizeof(v4_v6_map)) != 0) {
                                bad_v6_prefix_map:
                                        fr_strerror_printf("Invalid cast from %s to %s.  No IPv4-IPv6 mapping prefix",
-                                                          fr_int2str(dict_attr_types, src_type, "<INVALID>"),
+                                                          fr_int2str(dict_attr_types, src->type, "<INVALID>"),
                                                           fr_int2str(dict_attr_types, dst_type, "<INVALID>"));
                                        return -1;
                                }
@@ -1498,7 +1567,7 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
                                bad_v4_prefix_len:
                                        fr_strerror_printf("Invalid cast from %s to %s.  Only /32 prefixes may be "
                                                           "cast to IP address types",
-                                                          fr_int2str(dict_attr_types, src_type, "<INVALID>"),
+                                                          fr_int2str(dict_attr_types, src->type, "<INVALID>"),
                                                           fr_int2str(dict_attr_types, dst_type, "<INVALID>"));
                                        return -1;
                                }
@@ -1511,7 +1580,7 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
                                bad_v6_prefix_len:
                                        fr_strerror_printf("Invalid cast from %s to %s.  Only /128 prefixes may be "
                                                           "cast to IP address types",
-                                                          fr_int2str(dict_attr_types, src_type, "<INVALID>"),
+                                                          fr_int2str(dict_attr_types, src->type, "<INVALID>"),
                                                           fr_int2str(dict_attr_types, dst_type, "<INVALID>"));
                                        return -1;
                                }
@@ -1528,7 +1597,7 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
                        break;
 
                case PW_TYPE_IPV6_ADDR:
-                       switch (src_type) {
+                       switch (src->type) {
                        case PW_TYPE_IPV4_ADDR:
                                /* Add the v4/v6 mapping prefix */
                                memcpy(dst->datum.ipv6addr.s6_addr, v4_v6_map, sizeof(v4_v6_map));
@@ -1558,7 +1627,7 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
                        break;
 
                case PW_TYPE_IPV4_PREFIX:
-                       switch (src_type) {
+                       switch (src->type) {
                        case PW_TYPE_IPV4_ADDR:
                                memcpy(&dst->datum.ipv4prefix[2], &src->datum.ipaddr, sizeof(dst->datum.ipv4prefix) - 2);
                                dst->datum.ipv4prefix[0] = 0;
@@ -1599,7 +1668,7 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
                        break;
 
                case PW_TYPE_IPV6_PREFIX:
-                       switch (src_type) {
+                       switch (src->type) {
                        case PW_TYPE_IPV4_ADDR:
                                /* Add the v4/v6 mapping prefix */
                                memcpy(&dst->datum.ipv6prefix[2], v4_v6_map, sizeof(v4_v6_map));
@@ -1641,34 +1710,41 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
         */
        if ((src->length < dict_attr_sizes[dst_type][0]) ||
            (src->length > dict_attr_sizes[dst_type][1])) {
-               char const *src_type_name;
+               char const *type_name;
 
-               src_type_name = fr_int2str(dict_attr_types, src_type, "<INVALID>");
+               type_name = fr_int2str(dict_attr_types, src->type, "<INVALID>");
                fr_strerror_printf("Invalid cast from %s to %s. Length should be between %zu and %zu but is %zu",
-                                  src_type_name,
+                                  type_name,
                                   fr_int2str(dict_attr_types, dst_type, "<INVALID>"),
                                   dict_attr_sizes[dst_type][0], dict_attr_sizes[dst_type][1],
                                   src->length);
                return -1;
        }
 
-       if (src_type == PW_TYPE_OCTETS) {
+       if (src->type == PW_TYPE_OCTETS) {
                value_box_t tmp;
 
        do_octets:
                if (src->length < value_box_field_sizes[dst_type]) {
                        fr_strerror_printf("Invalid cast from %s to %s.  Source is length %zd is smaller than destination type size %zd",
-                                          fr_int2str(dict_attr_types, src_type, "<INVALID>"),
+                                          fr_int2str(dict_attr_types, src->type, "<INVALID>"),
                                           fr_int2str(dict_attr_types, dst_type, "<INVALID>"),
                                           src->length,
                                           value_box_field_sizes[dst_type]);
                        return -1;
                }
 
+               /*
+                *      Copy the raw octets into the datum of a value_box
+                *      inverting bytesex for integers (if LE).
+                */
                memcpy(&tmp.datum, src->datum.octets, value_box_field_sizes[dst_type]);
+               tmp.type = dst_type;
+               tmp.length = value_box_field_sizes[dst_type];
+               if (fr_dict_enum_types[dst_type]) dst->datum.enumv = dst_enumv;
+
+               value_box_hton(dst, &tmp);
 
-               value_box_hton(dst, dst_type, &tmp);
-               dst->length = value_box_field_sizes[dst_type];
                return 0;
        }
 
@@ -1676,12 +1752,12 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
         *      Convert host order to network byte order.
         */
        if ((dst_type == PW_TYPE_IPV4_ADDR) &&
-           ((src_type == PW_TYPE_INTEGER) ||
-            (src_type == PW_TYPE_DATE) ||
-            (src_type == PW_TYPE_SIGNED))) {
+           ((src->type == PW_TYPE_INTEGER) ||
+            (src->type == PW_TYPE_DATE) ||
+            (src->type == PW_TYPE_SIGNED))) {
                dst->datum.ipaddr.s_addr = htonl(src->datum.integer);
 
-       } else if ((src_type == PW_TYPE_IPV4_ADDR) &&
+       } else if ((src->type == PW_TYPE_IPV4_ADDR) &&
                   ((dst_type == PW_TYPE_INTEGER) ||
                    (dst_type == PW_TYPE_DATE) ||
                    (dst_type == PW_TYPE_SIGNED))) {
@@ -1690,7 +1766,10 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
        } else {                /* they're of the same byte order */
                memcpy(&dst->datum, &src->datum, src->length);
        }
+
        dst->length = src->length;
+       dst->type = dst_type;
+       if (fr_dict_enum_types[dst_type]) dst->datum.enumv = dst_enumv;
 
        return 0;
 }
@@ -1699,19 +1778,20 @@ int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
  *
  * @param ctx To allocate buffers in.
  * @param dst Where to copy value_box to.
- * @param src_type Type of src.
  * @param src Where to copy value_box from.
  * @return
  *     - 0 on success.
  *     - -1 on failure.
  */
-int value_box_copy(TALLOC_CTX *ctx, value_box_t *dst, PW_TYPE src_type, const value_box_t *src)
+int value_box_copy(TALLOC_CTX *ctx, value_box_t *dst, const value_box_t *src)
 {
-       switch (src_type) {
+       if (!fr_cond_assert(src->type != PW_TYPE_INVALID)) return -1;
+
+       switch (src->type) {
        default:
-               memcpy(((uint8_t *)dst) + value_box_offsets[src_type],
-                      ((uint8_t const *)src) + value_box_offsets[src_type],
-                      value_box_field_sizes[src_type]);
+               memcpy(((uint8_t *)dst) + value_box_offsets[src->type],
+                      ((uint8_t const *)src) + value_box_offsets[src->type],
+                      value_box_field_sizes[src->type]);
                break;
 
        case PW_TYPE_STRING:
@@ -1726,9 +1806,7 @@ int value_box_copy(TALLOC_CTX *ctx, value_box_t *dst, PW_TYPE src_type, const va
                break;
        }
 
-       dst->type = src_type;
-       dst->length = src->length;
-       dst->tainted = src->tainted;
+       value_box_copy_attrs(dst, src);
 
        return 0;
 }
@@ -1737,15 +1815,16 @@ int value_box_copy(TALLOC_CTX *ctx, value_box_t *dst, PW_TYPE src_type, const va
  *
  * @param ctx To allocate buffers in.
  * @param dst Where to copy value_box to.
- * @param src_type Type of src.
  * @param src Where to copy value_box from.
  * @return
  *     - 0 on success.
  *     - -1 on failure.
  */
-int value_box_steal(TALLOC_CTX *ctx, value_box_t *dst, PW_TYPE src_type, const value_box_t *src)
+int value_box_steal(TALLOC_CTX *ctx, value_box_t *dst, const value_box_t *src)
 {
-       switch (src_type) {
+       if (!fr_cond_assert(src->type != PW_TYPE_INVALID)) return -1;
+
+       switch (src->type) {
        default:
                memcpy(dst, src, sizeof(*src));
                break;
@@ -1768,7 +1847,8 @@ int value_box_steal(TALLOC_CTX *ctx, value_box_t *dst, PW_TYPE src_type, const v
                }
                break;
        }
-       dst->length = src->length;
+
+       value_box_copy_attrs(dst, src);
 
        return 0;
 }
@@ -1776,13 +1856,23 @@ int value_box_steal(TALLOC_CTX *ctx, value_box_t *dst, PW_TYPE src_type, const v
 /** Print one attribute value to a string
  *
  */
-char *value_box_asprint(TALLOC_CTX *ctx,
-                        PW_TYPE type, fr_dict_attr_t const *enumv, value_box_t const *data, char quote)
+char *value_box_asprint(TALLOC_CTX *ctx, value_box_t const *data, char quote)
 {
        char *p = NULL;
-       unsigned int i;
 
-       switch (type) {
+       if (!fr_cond_assert(data->type != PW_TYPE_INVALID)) return NULL;
+
+       if (fr_dict_enum_types[data->type] && data->datum.enumv) {
+               fr_dict_enum_t const    *dv;
+               value_box_t             tmp;
+
+               value_box_cast(ctx, &tmp, PW_TYPE_INTEGER, NULL, data);
+
+               dv = fr_dict_enum_by_da(NULL, data->datum.enumv, tmp.datum.integer);
+               if (dv) return talloc_typed_strdup(ctx, dv->name);
+       }
+
+       switch (data->type) {
        case PW_TYPE_STRING:
        {
                size_t len, ret;
@@ -1807,29 +1897,17 @@ char *value_box_asprint(TALLOC_CTX *ctx,
                break;
        }
 
-
        case PW_TYPE_BYTE:
-               i = data->datum.byte;
-
-       print_int:
-       {
-               fr_dict_enum_t const *dv;
-
-               if (enumv && (dv = fr_dict_enum_by_da(NULL, enumv, i))) {
-                       p = talloc_typed_strdup(ctx, dv->name);
-               } else {
-                       p = talloc_typed_asprintf(ctx, "%u", i);
-               }
-       }
+               p = talloc_typed_asprintf(ctx, "%u", data->datum.byte);
                break;
 
        case PW_TYPE_SHORT:
-               i = data->datum.ushort;
-               goto print_int;
+               p = talloc_typed_asprintf(ctx, "%u", data->datum.ushort);
+               break;
 
        case PW_TYPE_INTEGER:
-               i = data->datum.integer;
-               goto print_int;
+               p = talloc_typed_asprintf(ctx, "%u", data->datum.integer);
+               break;
 
        case PW_TYPE_INTEGER64:
                p = talloc_typed_asprintf(ctx, "%" PRIu64, data->datum.integer64);
@@ -1901,7 +1979,7 @@ char *value_box_asprint(TALLOC_CTX *ctx,
                char buff[INET_ADDRSTRLEN  + 4]; // + /prefix
 
                buff[0] = '\0';
-               value_box_snprint(buff, sizeof(buff), type, enumv, data, '\0');
+               value_box_snprint(buff, sizeof(buff), data, '\0');
 
                p = talloc_typed_strdup(ctx, buff);
        }
@@ -1913,7 +1991,7 @@ char *value_box_asprint(TALLOC_CTX *ctx,
                char buff[INET6_ADDRSTRLEN + 4]; // + /prefix
 
                buff[0] = '\0';
-               value_box_snprint(buff, sizeof(buff), type, enumv, data, '\0');
+               value_box_snprint(buff, sizeof(buff), data, '\0');
 
                p = talloc_typed_strdup(ctx, buff);
        }
@@ -1956,27 +2034,24 @@ char *value_box_asprint(TALLOC_CTX *ctx,
  *
  * @param out Where to write the printed version of the attribute value.
  * @param outlen Length of the output buffer.
- * @param type of data being printed.
- * @param enumv Enumerated string values for integer types.
  * @param data to print.
  * @param quote char to escape in string output.
  * @return
  *     - The number of bytes written to the out buffer.
  *     - A number >= outlen if truncation has occurred.
  */
-size_t value_box_snprint(char *out, size_t outlen,
-                        PW_TYPE type, fr_dict_attr_t const *enumv, value_box_t const *data, char quote)
+size_t value_box_snprint(char *out, size_t outlen, value_box_t const *data, char quote)
 {
-       fr_dict_enum_t  *v;
        char            buf[1024];      /* Interim buffer to use with poorly behaved printing functions */
        char const      *a = NULL;
        char            *p = out;
        time_t          t;
        struct tm       s_tm;
-       unsigned int    i;
 
        size_t          len = 0, freespace = outlen;
 
+       if (!fr_cond_assert(data->type != PW_TYPE_INVALID)) return -1;
+
        if (!data) return 0;
        if (outlen == 0) return data->length;
 
@@ -1984,7 +2059,17 @@ size_t value_box_snprint(char *out, size_t outlen,
 
        p = out;
 
-       switch (type) {
+       if (fr_dict_enum_types[data->type] && data->datum.enumv) {
+               fr_dict_enum_t const    *dv;
+               value_box_t             tmp;
+
+               value_box_cast(NULL, &tmp, PW_TYPE_INTEGER, NULL, data);
+
+               dv = fr_dict_enum_by_da(NULL, data->datum.enumv, tmp.datum.integer);
+               if (dv) return strlcpy(out, dv->name, outlen);
+       }
+
+       switch (data->type) {
        case PW_TYPE_STRING:
 
                /*
@@ -2017,27 +2102,13 @@ size_t value_box_snprint(char *out, size_t outlen,
                return fr_snprint(out, outlen, data->datum.strvalue, data->length, quote);
 
        case PW_TYPE_BYTE:
-               i = data->datum.byte;
-
-       print_int:
-               /* Normal, non-tagged attribute */
-               if (enumv && (v = fr_dict_enum_by_da(NULL, enumv, i)) != NULL) {
-                       a = v->name;
-                       len = strlen(a);
-               } else {
-                       /* should never be truncated */
-                       len = snprintf(buf, sizeof(buf), "%u", i);
-                       a = buf;
-               }
-               break;
+               return snprintf(out, outlen, "%u", data->datum.byte);
 
        case PW_TYPE_SHORT:
-               i = data->datum.ushort;
-               goto print_int;
+               return snprintf(out, outlen, "%u", data->datum.ushort);
 
        case PW_TYPE_INTEGER:
-               i = data->datum.integer;
-               goto print_int;
+               return snprintf(out, outlen, "%u", data->datum.integer);
 
        case PW_TYPE_INTEGER64:
                return snprintf(out, outlen, "%" PRIu64, data->datum.integer64);
index e39f4b11a3a93427bf4aaa3941aed4a7591dc6fe..d112c6584d3974b3c0c4898269484dd3da4fa07a 100644 (file)
@@ -1415,7 +1415,7 @@ RADCLIENT *client_afrom_request(RADCLIENT_LIST *clients, REQUEST *request)
                                goto error;
                        }
 
-                       if (vp->da->type == PW_TYPE_STRING) {
+                       if (vp->vp_type == PW_TYPE_STRING) {
                                RDEBUG2("%s = '%s'", vp->da->name, value);
                                cp = cf_pair_alloc(c->cs, vp->da->name, value, T_OP_SET,
                                                   T_BARE_WORD, T_SINGLE_QUOTED_STRING);
index c65172285fc8811f789203700183de42a0cf8e5b..e7d8d6e7cc6aefded96e19dc37ad560b613bc2ca 100644 (file)
@@ -158,8 +158,8 @@ int cond_eval_tmpl(REQUEST *request, int modreturn, UNUSED int depth, vp_tmpl_t
  *     - 1 for "match".
  */
 static int cond_do_regex(REQUEST *request, fr_cond_t const *c,
-                        PW_TYPE lhs_type, value_box_t const *lhs,
-                        PW_TYPE rhs_type, value_box_t const *rhs)
+                        value_box_t const *lhs,
+                        value_box_t const *rhs)
 {
        vp_map_t const *map = c->data.map;
 
@@ -171,7 +171,7 @@ static int cond_do_regex(REQUEST *request, fr_cond_t const *c,
        size_t          nmatch = sizeof(rxmatch) / sizeof(regmatch_t);
 
        if (!rad_cond_assert(lhs != NULL)) return -1;
-       if (!rad_cond_assert(lhs_type == PW_TYPE_STRING)) return -1;
+       if (!rad_cond_assert(lhs->type == PW_TYPE_STRING)) return -1;
 
        EVAL_DEBUG("CMP WITH REGEX %s %s",
                   map->rhs->tmpl_iflag ? "CASE INSENSITIVE" : "CASE SENSITIVE",
@@ -183,7 +183,7 @@ static int cond_do_regex(REQUEST *request, fr_cond_t const *c,
                break;
 
        default:
-               if (!rad_cond_assert(rhs_type == PW_TYPE_STRING)) return -1;
+               if (!rad_cond_assert(rhs && rhs->type == PW_TYPE_STRING)) return -1;
                if (!rad_cond_assert(rhs && rhs->datum.strvalue)) return -1;
                slen = regex_compile(request, &rreg, rhs->datum.strvalue, rhs->length,
                                     map->rhs->tmpl_iflag, map->rhs->tmpl_mflag, true, true);
@@ -226,18 +226,18 @@ static int cond_do_regex(REQUEST *request, fr_cond_t const *c,
 
 #ifdef WITH_EVAL_DEBUG
 static void cond_print_operands(REQUEST *request,
-                               PW_TYPE lhs_type, value_box_t const *lhs,
-                               PW_TYPE rhs_type, value_box_t const *rhs)
+                               value_box_t const *lhs,
+                               value_box_t const *rhs)
 {
        if (lhs) {
-               if (lhs_type == PW_TYPE_STRING) {
+               if (lhs->type == PW_TYPE_STRING) {
                        EVAL_DEBUG("LHS: \"%s\" (%zu)" , lhs->datum.strvalue, lhs->length);
                } else {
                        char *lhs_hex;
 
                        lhs_hex = talloc_array(request, char, (lhs->length * 2) + 1);
 
-                       if (lhs_type == PW_TYPE_OCTETS) {
+                       if (lhs->type == PW_TYPE_OCTETS) {
                                fr_bin2hex(lhs_hex, lhs->datum.octets, lhs->length);
                        } else {
                                fr_bin2hex(lhs_hex, (uint8_t const *)&lhs->datum, lhs->length);
@@ -252,14 +252,14 @@ static void cond_print_operands(REQUEST *request,
        }
 
        if (rhs) {
-               if (rhs_type == PW_TYPE_STRING) {
+               if (rhs->type == PW_TYPE_STRING) {
                        EVAL_DEBUG("RHS: \"%s\" (%zu)" , rhs->datum.strvalue, rhs->length);
                } else {
                        char *rhs_hex;
 
                        rhs_hex = talloc_array(request, char, (rhs->length * 2) + 1);
 
-                       if (rhs_type == PW_TYPE_OCTETS) {
+                       if (rhs->type == PW_TYPE_OCTETS) {
                                fr_bin2hex(rhs_hex, rhs->datum.octets, rhs->length);
                        } else {
                                fr_bin2hex(rhs_hex, (uint8_t const *)&rhs->datum, rhs->length);
@@ -285,16 +285,14 @@ static void cond_print_operands(REQUEST *request,
  *     - 0 for "no match".
  *     - 1 for "match".
  */
-static int cond_cmp_values(REQUEST *request, fr_cond_t const *c,
-                          PW_TYPE lhs_type, value_box_t const *lhs,
-                          PW_TYPE rhs_type, value_box_t const *rhs)
+static int cond_cmp_values(REQUEST *request, fr_cond_t const *c, value_box_t const *lhs, value_box_t const *rhs)
 {
        vp_map_t const *map = c->data.map;
        int rcode;
 
 #ifdef WITH_EVAL_DEBUG
-               EVAL_DEBUG("CMP OPERANDS");
-               cond_print_operands(request, lhs_type, lhs, rhs_type, rhs);
+       EVAL_DEBUG("CMP OPERANDS");
+       cond_print_operands(request, lhs, rhs);
 #endif
 
 #ifdef HAVE_REGEX
@@ -302,7 +300,7 @@ static int cond_cmp_values(REQUEST *request, fr_cond_t const *c,
         *      Regex comparison
         */
        if (map->op == T_OP_REG_EQ) {
-               rcode = cond_do_regex(request, c, lhs_type, lhs, rhs_type, rhs);
+               rcode = cond_do_regex(request, c, lhs, rhs);
                goto finish;
        }
 #endif
@@ -318,7 +316,7 @@ static int cond_cmp_values(REQUEST *request, fr_cond_t const *c,
                vp = fr_pair_afrom_da(request, map->lhs->tmpl_da);
                vp->op = c->data.map->op;
 
-               value_box_copy(vp, &vp->data, rhs_type, rhs);
+               value_box_copy(vp, &vp->data, rhs);
 
                rcode = paircompare(request, request->packet->vps, vp, NULL);
                rcode = (rcode == 0) ? 1 : 0;
@@ -326,15 +324,8 @@ static int cond_cmp_values(REQUEST *request, fr_cond_t const *c,
                goto finish;
        }
 
-       /*
-        *      At this point both operands should have been normalised
-        *      to the same type, and there's no special comparisons
-        *      left.
-        */
-       rad_assert(lhs_type == rhs_type);
-
        EVAL_DEBUG("CMP WITH VALUE DATA");
-       rcode = value_box_cmp_op(map->op, lhs_type, lhs, rhs_type, rhs);
+       rcode = value_box_cmp_op(map->op, lhs, rhs);
 finish:
        switch (rcode) {
        case 0:
@@ -399,25 +390,21 @@ done:
  *     - 0 for "no match".
  *     - 1 for "match".
  */
-static int cond_normalise_and_cmp(REQUEST *request, fr_cond_t const *c,
-                                 PW_TYPE lhs_type, fr_dict_attr_t const *lhs_enumv,
-                                 value_box_t const *lhs)
+static int cond_normalise_and_cmp(REQUEST *request, fr_cond_t const *c, value_box_t const *lhs)
 {
-       vp_map_t const *map = c->data.map;
+       vp_map_t const          *map = c->data.map;
 
-       fr_dict_attr_t const *cast = NULL;
-       PW_TYPE cast_type = PW_TYPE_INVALID;
+       int                     rcode;
 
-       int rcode;
+       value_box_t             *rhs = NULL;
 
-       PW_TYPE rhs_type = PW_TYPE_INVALID;
-       fr_dict_attr_t const *rhs_enumv = NULL;
-       value_box_t *rhs = NULL;
+       fr_dict_attr_t const    *cast = NULL;
+       PW_TYPE                 cast_type = PW_TYPE_INVALID;
 
-       value_box_t lhs_cast, rhs_cast;
-       void *lhs_cast_buff = NULL, *rhs_cast_buff = NULL;
+       value_box_t             lhs_cast, rhs_cast;
+       void                    *lhs_cast_buff = NULL, *rhs_cast_buff = NULL;
 
-       xlat_escape_t escape = NULL;
+       xlat_escape_t           escape = NULL;
 
        /*
         *      Cast operand to correct type.
@@ -429,17 +416,16 @@ static int cond_normalise_and_cmp(REQUEST *request, fr_cond_t const *c,
         */
 #define CAST(_s) \
 do {\
-       if ((cast_type != PW_TYPE_INVALID) && (_s ## _type != PW_TYPE_INVALID) && (cast_type != _s ## _type)) {\
+       if ((cast_type != PW_TYPE_INVALID) && _s && (_s ->type != PW_TYPE_INVALID) && (cast_type != _s->type)) {\
                EVAL_DEBUG("CASTING " #_s " FROM %s TO %s",\
-                          fr_int2str(dict_attr_types, _s ## _type, "<INVALID>"),\
+                          fr_int2str(dict_attr_types, _s->type, "<INVALID>"),\
                           fr_int2str(dict_attr_types, cast_type, "<INVALID>"));\
-               if (value_box_cast(request, &_s ## _cast, cast_type, cast, _s ## _type, _s ## _enumv, _s) < 0) {\
+               if (value_box_cast(request, &_s ## _cast, cast_type, cast, _s) < 0) {\
                        REDEBUG("Failed casting " #_s " operand: %s", fr_strerror());\
                        rcode = -1;\
                        goto finish;\
                }\
                if (cast && cast->flags.is_pointer) _s ## _cast_buff = _s ## _cast.datum.ptr;\
-               _s ## _type = cast_type;\
                _s = &_s ## _cast;\
        }\
 } while (0)
@@ -447,8 +433,8 @@ do {\
 #define CHECK_INT_CAST(_l, _r) \
 do {\
        if ((cast_type == PW_TYPE_INVALID) &&\
-           _l && (_l ## _type == PW_TYPE_STRING) &&\
-           _r && (_r ## _type == PW_TYPE_STRING) &&\
+           _l && (_l->type == PW_TYPE_STRING) &&\
+           _r && (_r->type == PW_TYPE_STRING) &&\
            all_digits(lhs->datum.strvalue) && all_digits(rhs->datum.strvalue)) {\
                cast_type = PW_TYPE_INTEGER64;\
                EVAL_DEBUG("OPERANDS ARE NUMBER STRINGS, SETTING CAST TO integer64");\
@@ -475,12 +461,9 @@ do {\
        if (c->pass2_fixup == PASS2_PAIRCOMPARE) {
                rad_assert(!c->cast);
                rad_assert(map->lhs->type == TMPL_TYPE_ATTR);
-#ifndef NDEBUG
-               /* expensive assert */
-               rad_assert((map->rhs->type != TMPL_TYPE_ATTR) || !radius_find_compare(map->rhs->tmpl_da));
-#endif
+               rad_assert((map->rhs->type != TMPL_TYPE_ATTR) || !radius_find_compare(map->rhs->tmpl_da)); /* expensive assert */
+
                cast = map->lhs->tmpl_da;
-               cast_type = cast->type;
 
                EVAL_DEBUG("NORMALISATION TYPE %s (PAIRCMP TYPE)",
                           fr_int2str(dict_attr_types, cast->type, "<INVALID>"));
@@ -523,15 +506,13 @@ do {\
                for (vp = tmpl_cursor_init(&rcode, &cursor, request, map->rhs);
                     vp;
                     vp = tmpl_cursor_next(&cursor, map->rhs)) {
-                       rhs_type = vp->da->type;
-                       rhs_enumv = vp->da;
                        rhs = &vp->data;
 
                        CHECK_INT_CAST(lhs, rhs);
                        CAST(lhs);
                        CAST(rhs);
 
-                       rcode = cond_cmp_values(request, c, lhs_type, lhs, rhs_type, rhs);
+                       rcode = cond_cmp_values(request, c, lhs, rhs);
                        if (rcode != 0) break;
 
                        TALLOC_FREE(rhs_cast_buff);
@@ -540,14 +521,13 @@ do {\
                break;
 
        case TMPL_TYPE_DATA:
-               rhs_type = map->rhs->tmpl_value_box_type;
-               rhs = &map->rhs->tmpl_value_box_datum;
+               rhs = &map->rhs->tmpl_value_box;
 
                CHECK_INT_CAST(lhs, rhs);
                CAST(lhs);
                CAST(rhs);
 
-               rcode = cond_cmp_values(request, c, lhs_type, lhs, rhs_type, rhs);
+               rcode = cond_cmp_values(request, c, lhs, rhs);
                break;
 
        /*
@@ -578,16 +558,17 @@ do {\
                        data.datum.strvalue = map->rhs->name;
                        data.length = map->rhs->len;
                }
+               data.type = PW_TYPE_STRING;
+
                rad_assert(data.datum.strvalue);
 
-               rhs_type = PW_TYPE_STRING;
                rhs = &data;
 
                CHECK_INT_CAST(lhs, rhs);
                CAST(lhs);
                CAST(rhs);
 
-               rcode = cond_cmp_values(request, c, lhs_type, lhs, rhs_type, rhs);
+               rcode = cond_cmp_values(request, c, lhs, rhs);
                if (map->rhs->type != TMPL_TYPE_UNPARSED) talloc_free(data.datum.ptr);
 
                break;
@@ -598,7 +579,7 @@ do {\
         */
        case TMPL_TYPE_REGEX_STRUCT:
                CAST(lhs);
-               rcode = cond_cmp_values(request, c, lhs_type, lhs, PW_TYPE_INVALID, NULL);
+               rcode = cond_cmp_values(request, c, lhs, NULL);
                break;
        /*
         *      Unsupported types (should have been parse errors)
@@ -661,7 +642,7 @@ int cond_eval_map(REQUEST *request, UNUSED int modreturn, UNUSED int depth, fr_c
 #ifndef NDEBUG
                        rad_assert(radius_find_compare(map->lhs->tmpl_da)); /* expensive assert */
 #endif
-                       rcode = cond_normalise_and_cmp(request, c, PW_TYPE_INVALID, NULL, NULL);
+                       rcode = cond_normalise_and_cmp(request, c, NULL);
                        break;
                }
                for (vp = tmpl_cursor_init(&rcode, &cursor, request, map->lhs);
@@ -672,15 +653,14 @@ int cond_eval_map(REQUEST *request, UNUSED int modreturn, UNUSED int depth, fr_c
                         *      if we get at least one set of operands that
                         *      evaluates to true.
                         */
-                       rcode = cond_normalise_and_cmp(request, c, vp->da->type, vp->da, &vp->data);
+                       rcode = cond_normalise_and_cmp(request, c, &vp->data);
                        if (rcode != 0) break;
                }
        }
                break;
 
        case TMPL_TYPE_DATA:
-               rcode = cond_normalise_and_cmp(request, c,
-                                              map->lhs->tmpl_value_box_type, NULL, &map->lhs->tmpl_value_box_datum);
+               rcode = cond_normalise_and_cmp(request, c, &map->lhs->tmpl_value_box);
                break;
 
        case TMPL_TYPE_UNPARSED:
@@ -705,8 +685,9 @@ int cond_eval_map(REQUEST *request, UNUSED int modreturn, UNUSED int depth, fr_c
                        data.length = map->lhs->len;
                }
                rad_assert(data.datum.strvalue);
+               data.type = PW_TYPE_STRING;
 
-               rcode = cond_normalise_and_cmp(request, c, PW_TYPE_STRING, NULL, &data);
+               rcode = cond_normalise_and_cmp(request, c, &data);
                if (p) talloc_free(p);
        }
                break;
index a14a6ef011126ce2431b8b57707117daf2757e88..44b9566c91f2ecfb116078f79dd27761a4fa62f7 100644 (file)
@@ -74,7 +74,7 @@ next:
                        p += len;
                }
 
-               len = tmpl_snprint(p, end - p, c->data.vpt, NULL);
+               len = tmpl_snprint(p, end - p, c->data.vpt);
                RETURN_IF_TRUNCATED(p, len, end - p);
                break;
 
index 92616b1bbabbb6f99d635e79e5d7482b89562882..26b2720bb12e2cf9572f784b3644c5eb109d2408 100644 (file)
@@ -146,7 +146,7 @@ parse_again:
 
                        /*
                         *      Get the name.
-                        */                   
+                        */
                        ptr = buffer;
                        getword(&ptr, entry, sizeof(entry), false);
                        entry_lineno = lineno;
@@ -235,7 +235,7 @@ parse_again:
                             vp = fr_pair_cursor_next(&cursor)) {
                                if (((vp->op == T_OP_REG_EQ) ||
                                     (vp->op == T_OP_REG_NE)) &&
-                                   (vp->da->type != PW_TYPE_STRING)) {
+                                   (vp->vp_type != PW_TYPE_STRING)) {
                                        pairlist_free(&pl);
                                        talloc_free(check_tmp);
                                        ERROR("%s[%d]: Cannot use regular expressions for non-string attributes in entry %s",
index b77d0a94c19a66be7dc79c77c0ffdf979d61f4c8..6d448efbaf311912fdb423809b89baf5da6ffa5d 100644 (file)
@@ -134,15 +134,15 @@ bool map_cast_from_hex(vp_map_t *map, FR_TOKEN rhs_type, char const *rhs)
        map->rhs->tmpl_value_box_type = da->type;
        map->rhs->tmpl_value_box_length = vp->vp_length;
        if (vp->da->flags.is_pointer) {
-               if (vp->da->type == PW_TYPE_STRING) {
-                       map->rhs->tmpl_value_box_datum.datum.ptr = talloc_bstrndup(map->rhs, vp->vp_ptr, vp->vp_length);
+               if (vp->vp_type == PW_TYPE_STRING) {
+                       map->rhs->tmpl_value_box_datum.ptr = talloc_bstrndup(map->rhs, vp->vp_ptr, vp->vp_length);
                        map->rhs->quote = T_SINGLE_QUOTED_STRING;
                } else {
-                       map->rhs->tmpl_value_box_datum.datum.ptr = talloc_memdup(map->rhs, vp->vp_ptr, vp->vp_length);
+                       map->rhs->tmpl_value_box_datum.ptr = talloc_memdup(map->rhs, vp->vp_ptr, vp->vp_length);
                        map->rhs->quote = T_BARE_WORD;
                }
        } else {
-               value_box_copy(map->rhs, &map->rhs->tmpl_value_box_datum, vp->da->type, &vp->data);
+               value_box_copy(map->rhs, &map->rhs->tmpl_value_box, &vp->data);
                map->rhs->quote = T_BARE_WORD;
        }
        map->rhs->name = fr_pair_value_asprint(map->rhs, vp, fr_token_quote[map->rhs->quote]);
@@ -913,8 +913,8 @@ int map_to_vp(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request, vp_map_t cons
                                new = fr_pair_afrom_da(ctx, map->lhs->tmpl_da);
                                if (!new) return -1;
 
-                               if (value_box_cast(new, &new->data, new->da->type, new->da,
-                                                   vp->da->type, vp->da, &vp->data) < 0) {
+                               if (value_box_cast(new, &new->data,
+                                                  map->lhs->tmpl_da->type, map->lhs->tmpl_da, &vp->data) < 0) {
                                        REDEBUG("Attribute conversion failed: %s", fr_strerror());
                                        fr_pair_list_free(&found);
                                        fr_pair_list_free(&new);
@@ -923,9 +923,7 @@ int map_to_vp(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request, vp_map_t cons
                                vp = fr_pair_cursor_remove(&from);
                                talloc_free(vp);
 
-                               if (new->da->type == PW_TYPE_STRING) {
-                                       rad_assert(new->vp_strvalue != NULL);
-                               }
+                               if (new->vp_type == PW_TYPE_STRING) rad_assert(new->vp_strvalue != NULL);
 
                                new->op = map->op;
                                new->tag = map->lhs->tmpl_tag;
@@ -955,13 +953,13 @@ int map_to_vp(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request, vp_map_t cons
                if (!new) return -1;
 
                if (map->lhs->tmpl_da->type == map->rhs->tmpl_value_box_type) {
-                       if (value_box_copy(new, &new->data, new->da->type, &map->rhs->tmpl_value_box_datum) < 0) {
+                       if (value_box_copy(new, &new->data, &map->rhs->tmpl_value_box) < 0) {
                                rcode = -1;
                                goto error;
                        }
                } else {
-                       if (value_box_cast(new, &new->data, new->da->type, new->da, map->rhs->tmpl_value_box_type,
-                                           NULL, &map->rhs->tmpl_value_box_datum) < 0) {
+                       if (value_box_cast(new, &new->data, new->vp_type, new->da,
+                                          &map->rhs->tmpl_value_box) < 0) {
                                REDEBUG("Implicit cast failed: %s", fr_strerror());
                                rcode = -1;
                                goto error;
@@ -1403,7 +1401,7 @@ int map_to_request(REQUEST *request, vp_map_t const *map, radius_map_getvalue_t
                                if (cmp > 0) break;
                                else if (cmp < 0) continue;
 
-                               cmp = (value_box_cmp_op(map->op, a->da->type, &a->data, b->da->type, &b->data) == 0);
+                               cmp = (value_box_cmp_op(map->op, &a->data, &b->data) == 0);
                                if (cmp != 0) {
                                        a = fr_pair_cursor_remove(&dst_list);
                                        talloc_free(a);
@@ -1442,7 +1440,7 @@ finish:
                        if (!vp->da->parent->flags.is_root) continue;
                        if (vp->da->vendor != 0) continue;
                        if (vp->da->flags.has_tag) continue;
-                       if (vp->da->type != PW_TYPE_STRING) continue;
+                       if (vp->vp_type != PW_TYPE_STRING) continue;
 
                        if (!context->username && (vp->da->attr == PW_USER_NAME)) {
                                context->username = vp;
@@ -1495,15 +1493,12 @@ bool map_dst_valid(REQUEST *request, vp_map_t const *map)
 size_t map_snprint(char *out, size_t outlen, vp_map_t const *map)
 {
        size_t          len;
-       fr_dict_attr_t const    *da = NULL;
        char            *p = out;
        char            *end = out + outlen;
 
        VERIFY_MAP(map);
 
-       if (map->lhs->type == TMPL_TYPE_ATTR) da = map->lhs->tmpl_da;
-
-       len = tmpl_snprint(out, (end - p) - 1, map->lhs, da);           /* -1 for proceeding ' ' */
+       len = tmpl_snprint(out, (end - p) - 1, map->lhs);               /* -1 for proceeding ' ' */
        RETURN_IF_TRUNCATED(p, len, (end - p) - 1);
 
        *(p++) = ' ';
@@ -1526,11 +1521,11 @@ size_t map_snprint(char *out, size_t outlen, vp_map_t const *map)
            (map->lhs->tmpl_da->type == PW_TYPE_STRING) &&
            (map->rhs->type == TMPL_TYPE_UNPARSED)) {
                *(p++) = '\'';
-               len = tmpl_snprint(p, (end - p) - 1, map->rhs, da);     /* -1 for proceeding '\'' */
+               len = tmpl_snprint(p, (end - p) - 1, map->rhs); /* -1 for proceeding '\'' */
                RETURN_IF_TRUNCATED(p, len, (end - p) - 1);
                *(p++) = '\'';
        } else {
-               len = tmpl_snprint(p, end - p, map->rhs, da);
+               len = tmpl_snprint(p, end - p, map->rhs);
                RETURN_IF_TRUNCATED(p, len, (end - p) - 1);
        }
 
@@ -1580,7 +1575,7 @@ void map_debug_log(REQUEST *request, vp_map_t const *map, VALUE_PAIR const *vp)
                vp_tmpl_t       vpt;
                char const      *quote;
 
-               quote = (vp->da->type == PW_TYPE_STRING) ? "\"" : "";
+               quote = (vp->vp_type == PW_TYPE_STRING) ? "\"" : "";
 
                /*
                 *      Fudge a temporary tmpl that describes the attribute we're copying
@@ -1598,7 +1593,7 @@ void map_debug_log(REQUEST *request, vp_map_t const *map, VALUE_PAIR const *vp)
                 *      the quoting based on the data type.
                 */
                value = fr_pair_value_asprint(request, vp, quote[0]);
-               tmpl_snprint(buffer, sizeof(buffer), &vpt, vp->da);
+               tmpl_snprint(buffer, sizeof(buffer), &vpt);
                rhs = talloc_typed_asprintf(request, "%s -> %s%s%s", buffer, quote, value, quote);
        }
                break;
@@ -1607,7 +1602,7 @@ void map_debug_log(REQUEST *request, vp_map_t const *map, VALUE_PAIR const *vp)
        {
                char const *quote;
 
-               quote = (vp->da->type == PW_TYPE_STRING) ? "\"" : "";
+               quote = (vp->vp_type == PW_TYPE_STRING) ? "\"" : "";
 
                /*
                 *      Not appropriate to use map->rhs->quote here, as that's the quoting
@@ -1615,7 +1610,7 @@ void map_debug_log(REQUEST *request, vp_map_t const *map, VALUE_PAIR const *vp)
                 *      the quoting based on the data type.
                 */
                value = fr_pair_value_asprint(request, vp, quote[0]);
-               tmpl_snprint(buffer, sizeof(buffer), map->rhs, vp->da);
+               tmpl_snprint(buffer, sizeof(buffer), map->rhs);
                rhs = talloc_typed_asprintf(request, "%s -> %s%s%s", buffer, quote, value, quote);
        }
                break;
@@ -1628,7 +1623,7 @@ void map_debug_log(REQUEST *request, vp_map_t const *map, VALUE_PAIR const *vp)
        switch (map->lhs->type) {
        case TMPL_TYPE_ATTR:
        case TMPL_TYPE_LIST:
-               tmpl_snprint(buffer, sizeof(buffer), map->lhs, NULL);
+               tmpl_snprint(buffer, sizeof(buffer), map->lhs);
                RDEBUG("%s %s %s", buffer, fr_int2str(fr_tokens_table, vp ? vp->op : map->op, "<INVALID>"), rhs);
                break;
 
index 276ef83797418e50c82dfe10da54b9529c99ee15..9fde7c0076208f2493e016d79627da51c2806dcb 100644 (file)
@@ -82,13 +82,13 @@ int radius_compare_vps(UNUSED REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *v
                char *expr = NULL, *value = NULL;
                char const *expr_p, *value_p;
 
-               if (check->da->type == PW_TYPE_STRING) {
+               if (check->vp_type == PW_TYPE_STRING) {
                        expr_p = check->vp_strvalue;
                } else {
                        expr_p = expr = fr_pair_value_asprint(check, check, '\0');
                }
 
-               if (vp->da->type == PW_TYPE_STRING) {
+               if (vp->vp_type == PW_TYPE_STRING) {
                        value_p = vp->vp_strvalue;
                } else {
                        value_p = value = fr_pair_value_asprint(vp, vp, '\0');
@@ -147,7 +147,7 @@ int radius_compare_vps(UNUSED REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *v
         *      a string
         *
         */
-       if (vp->da->type != check->da->type) return -1;
+       if (vp->vp_type != check->vp_type) return -1;
 
        /*
         *      Tagged attributes are equal if and only if both the
@@ -161,7 +161,7 @@ int radius_compare_vps(UNUSED REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *v
        /*
         *      Not a regular expression, compare the types.
         */
-       switch (check->da->type) {
+       switch (check->vp_type) {
 #ifdef WITH_ASCEND_BINARY
                /*
                 *      Ascend binary attributes can be treated
index 33b1b421e9f6a167129589e2f0c7580400528eb4..129190ed9add99bf2037b31cd04464d39c9ed078 100644 (file)
@@ -252,7 +252,7 @@ static bool already_hex(VALUE_PAIR *vp)
 {
        size_t i;
 
-       if (!vp || (vp->da->type != PW_TYPE_OCTETS)) return true;
+       if (!vp || (vp->vp_type != PW_TYPE_OCTETS)) return true;
 
        /*
         *      If it's 17 octets, it *might* be already encoded.
@@ -544,6 +544,7 @@ static int radclient_init(TALLOC_CTX *ctx, rc_file_pair_t *files)
                                talloc_free(q);
 
                                vp->vp_octets = talloc_steal(vp, p);
+                               vp->data.type = PW_TYPE_OCTETS;
                                vp->type = VT_DATA;
 
                                VERIFY_VP(vp);
index ac4c68909227fec5e7bdee072a8a926853280e0c..39c27420e8aef13b84657b9ee71a3f57816f8c8f 100644 (file)
@@ -434,7 +434,7 @@ static int radsnmp_get_response(int fd,
                        slen = dict_print_attr_oid(p, end - p, parent, vp->da->parent);
                        if (slen < 0) return -1;
 
-                       if (vp->da->type != PW_TYPE_INTEGER) {
+                       if (vp->vp_type != PW_TYPE_INTEGER) {
                                fr_strerror_printf("Index attribute \"%s\" is not of type \"integer\"", vp->da->name);
                                return -1;
                        }
@@ -489,7 +489,7 @@ static int radsnmp_get_response(int fd,
                io_vector[3].iov_base = newline;
                io_vector[3].iov_len = 1;
 
-               switch (vp->da->type) {
+               switch (vp->vp_type) {
                case PW_TYPE_OCTETS:
                        memcpy(&io_vector[4].iov_base, &vp->vp_strvalue, sizeof(io_vector[4].iov_base));
                        io_vector[4].iov_len = vp->vp_length;
@@ -506,7 +506,7 @@ static int radsnmp_get_response(int fd,
                         *      because we always need return integer values not
                         *      value aliases.
                         */
-                       len = value_box_snprint(value_buff, sizeof(value_buff), vp->da->type, NULL, &vp->data, '\0');
+                       len = value_box_snprint(value_buff, sizeof(value_buff), &vp->data, '\0');
                        if (is_truncated(len, sizeof(value_buff))) {
                                fr_strerror_printf("Insufficient fixed value buffer");
                                return -1;
index d5d7efcde928b60241cbfea0b8d35ce080e7234a..ccd044ef62258f43db5ae74c7d4352966683184f 100644 (file)
@@ -2360,6 +2360,7 @@ void home_server_update_request(home_server_t *home, REQUEST *request)
 
        if (!request->proxy->packet) {
                VALUE_PAIR *vp;
+               char buff[11];  /* 4294967295 + \0 */
 
                MEM(request->proxy->packet = fr_radius_alloc(request->proxy, true));
 
@@ -2375,7 +2376,8 @@ void home_server_update_request(home_server_t *home, REQUEST *request)
                 *      doesn't need it.
                 */
                vp = radius_pair_create(request->proxy->packet, &request->proxy->packet->vps, PW_PROXY_STATE, 0);
-               fr_pair_value_snprintf(vp, "%u", request->packet->id);
+               snprintf(buff, sizeof(buff), "%u", request->packet->id);
+               fr_pair_value_memcpy(vp, (uint8_t *)buff, strlen(buff));
 
                /*
                 *      If there is no PW_CHAP_CHALLENGE attribute but
index e9e6e506b722e17bd39ac0635b66cb9a7a23d5b5..e495fdc19b279fa603ea4abe91799661effc2ae8 100644 (file)
@@ -780,7 +780,7 @@ static ssize_t snmp_process_leaf(vp_cursor_t *out, REQUEST *request,
                if (map_p->get(request->reply, &data, map_p, snmp_ctx) < 0) goto error;
 
                vp = fr_pair_afrom_da(request->reply, map_p->da);
-               value_box_steal(vp, &vp->data, vp->da->type, &data);
+               value_box_steal(vp, &vp->data, &data);
                fr_pair_cursor_append(out, vp);
 
                vp = fr_pair_afrom_da(request->reply, fr_snmp_type);
@@ -935,7 +935,7 @@ int fr_snmp_process(REQUEST *request)
                 *      Clear out any junk values
                 */
                if (da->type == PW_TYPE_TLV) {
-                       switch (vp->da->type) {
+                       switch (vp->vp_type) {
                        case PW_TYPE_OCTETS:
                        case PW_TYPE_STRING:
                                talloc_free(vp->data.datum.ptr);
index 630a403654bb41f8e35f70bb9eea05de48ac297a..c9c42b0856180efbbca88c213cb1746109c4c97e 100644 (file)
@@ -556,7 +556,7 @@ void request_stats_reply(REQUEST *request)
                         *      When retrieving client by number, also
                         *      echo back it's IP address.
                         */
-                       if ((vp->da->type == PW_TYPE_INTEGER) &&
+                       if ((vp->vp_type == PW_TYPE_INTEGER) &&
                            (client->ipaddr.af == AF_INET)) {
                                vp = radius_pair_create(request->reply,
                                                       &request->reply->vps,
index 0bf5b62d7d193317d5ecd8739ba1eb59ef7aea6e..a669bd4ba87377ad707089d211e0fe029b0da071 100644 (file)
@@ -599,36 +599,31 @@ void tmpl_from_da(vp_tmpl_t *vpt, fr_dict_attr_t const *da, int8_t tag, int num,
  * @param[in,out] ctx to allocate #vp_tmpl_t in.
  * @param[out] out Where to write pointer to new #vp_tmpl_t.
  * @param[in] data to convert.
- * @param[in] type of data.
- * @param[in] enumv Used to convert integers to string types for printing. May be NULL.
  * @param[in] steal If true, any buffers are moved to the new ctx instead of being duplicated.
  * @return
  *     - 0 on success.
  *     - -1 on failure.
  */
-int tmpl_afrom_value_box(TALLOC_CTX *ctx, vp_tmpl_t **out, value_box_t *data,
-                         PW_TYPE type, fr_dict_attr_t const *enumv, bool steal)
+int tmpl_afrom_value_box(TALLOC_CTX *ctx, vp_tmpl_t **out, value_box_t *data, bool steal)
 {
        char const *name;
        vp_tmpl_t *vpt;
 
        vpt = talloc(ctx, vp_tmpl_t);
-       name = value_box_asprint(vpt, type, enumv, data, '\0');
+       name = value_box_asprint(vpt, data, '\0');
        tmpl_init(vpt, TMPL_TYPE_DATA, name, talloc_array_length(name),
-                 (type == PW_TYPE_STRING) ? T_DOUBLE_QUOTED_STRING : T_BARE_WORD);
+                 (data->type == PW_TYPE_STRING) ? T_DOUBLE_QUOTED_STRING : T_BARE_WORD);
 
        if (steal) {
-               if (value_box_steal(vpt, &vpt->tmpl_value_box_datum, type, data) < 0) {
+               if (value_box_steal(vpt, &vpt->tmpl_value_box, data) < 0) {
                        talloc_free(vpt);
                        return -1;
                }
-               vpt->tmpl_value_box_type = type;
        } else {
-               if (value_box_copy(vpt, &vpt->tmpl_value_box_datum, type, data) < 0) {
+               if (value_box_copy(vpt, &vpt->tmpl_value_box, data) < 0) {
                        talloc_free(vpt);
                        return -1;
                }
-               vpt->tmpl_value_box_type = type;
        }
        *out = vpt;
 
@@ -1066,11 +1061,11 @@ ssize_t tmpl_afrom_str(TALLOC_CTX *ctx, vp_tmpl_t **out, char const *in, size_t
                        binlen = (inlen - 2) / 2;
 
                        vpt = tmpl_alloc(ctx, TMPL_TYPE_DATA, in, inlen, type);
-                       vpt->tmpl_value_box_datum.datum.ptr = talloc_array(vpt, uint8_t, binlen);
+                       vpt->tmpl_value_box_datum.ptr = talloc_array(vpt, uint8_t, binlen);
                        vpt->tmpl_value_box_length = binlen;
                        vpt->tmpl_value_box_type = PW_TYPE_OCTETS;
 
-                       len = fr_hex2bin(vpt->tmpl_value_box_datum.datum.ptr, binlen, in + 2, inlen - 2);
+                       len = fr_hex2bin(vpt->tmpl_value_box_datum.ptr, binlen, in + 2, inlen - 2);
                        if (len != binlen) {
                                fr_strerror_printf("Hex string contains none hex char");
                                talloc_free(vpt);
@@ -1236,8 +1231,8 @@ int tmpl_cast_in_place(vp_tmpl_t *vpt, PW_TYPE type, fr_dict_attr_t const *enumv
                /*
                 *      Why do we pass a pointer to the tmpl type? Goddamn WiMAX.
                 */
-               if (value_box_from_str(vpt, &vpt->tmpl_value_box_datum, &vpt->tmpl_value_box_type,
-                                       enumv, vpt->name, vpt->len, '\0') < 0) return -1;
+               if (value_box_from_str(vpt, &vpt->tmpl_value_box, &vpt->tmpl_value_box_type,
+                                      enumv, vpt->name, vpt->len, '\0') < 0) return -1;
                vpt->type = TMPL_TYPE_DATA;
                break;
 
@@ -1247,8 +1242,7 @@ int tmpl_cast_in_place(vp_tmpl_t *vpt, PW_TYPE type, fr_dict_attr_t const *enumv
 
                if (type == vpt->tmpl_value_box_type) return 0; /* noop */
 
-               if (value_box_cast(vpt, &new, type, enumv, vpt->tmpl_value_box_type,
-                                   NULL, &vpt->tmpl_value_box_datum) < 0) return -1;
+               if (value_box_cast(vpt, &new, type, enumv, &vpt->tmpl_value_box) < 0) return -1;
 
                /*
                 *      Free old value buffers
@@ -1256,15 +1250,14 @@ int tmpl_cast_in_place(vp_tmpl_t *vpt, PW_TYPE type, fr_dict_attr_t const *enumv
                switch (vpt->tmpl_value_box_type) {
                case PW_TYPE_STRING:
                case PW_TYPE_OCTETS:
-                       talloc_free(vpt->tmpl_value_box_datum.datum.ptr);
+                       talloc_free(vpt->tmpl_value_box_datum.ptr);
                        break;
 
                default:
                        break;
                }
 
-               value_box_copy(vpt, &vpt->tmpl_value_box_datum, type, &new);
-               vpt->tmpl_value_box_type = type;
+               value_box_copy(vpt, &vpt->tmpl_value_box, &new);
        }
                break;
 
@@ -1288,12 +1281,12 @@ void tmpl_cast_in_place_str(vp_tmpl_t *vpt)
        rad_assert(vpt != NULL);
        rad_assert(vpt->type == TMPL_TYPE_UNPARSED);
 
-       vpt->tmpl_value_box.vp_strvalue = talloc_typed_strdup(vpt, vpt->name);
-       rad_assert(vpt->tmpl_value_box.vp_strvalue != NULL);
+       vpt->tmpl_value_box_datum.strvalue = talloc_typed_strdup(vpt, vpt->name);
+       rad_assert(vpt->tmpl_value_box_datum.strvalue != NULL);
 
        vpt->type = TMPL_TYPE_DATA;
        vpt->tmpl_value_box_type = PW_TYPE_STRING;
-       vpt->tmpl_value_box_length = talloc_array_length(vpt->tmpl_value_box.vp_strvalue) - 1;
+       vpt->tmpl_value_box_length = talloc_array_length(vpt->tmpl_value_box_datum.strvalue) - 1;
 }
 
 /** Expand a #vp_tmpl_t to a string, parse it as an attribute of type cast, create a #VALUE_PAIR from the result
@@ -1317,10 +1310,10 @@ void tmpl_cast_in_place_str(vp_tmpl_t *vpt)
 int tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request,
                    vp_tmpl_t const *vpt, fr_dict_attr_t const *cast)
 {
-       int rcode;
-       VALUE_PAIR *vp;
-       value_box_t data;
-       char *p;
+       int             rcode;
+       VALUE_PAIR      *vp;
+       value_box_t     data;
+       char            *p;
 
        VERIFY_TMPL(vpt);
 
@@ -1331,9 +1324,9 @@ int tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request,
 
        if (vpt->type == TMPL_TYPE_DATA) {
                VERIFY_VP(vp);
-               rad_assert(vp->da->type == vpt->tmpl_value_box_type);
+               rad_assert(vp->vp_type == vpt->tmpl_value_box_type);
 
-               value_box_copy(vp, &vp->data, vpt->tmpl_value_box_type, &vpt->tmpl_value_box_datum);
+               value_box_copy(vp, &vp->data, &vpt->tmpl_value_box);
                *out = vp;
                return 0;
        }
@@ -1348,7 +1341,7 @@ int tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request,
        /*
         *      New escapes: strings are in binary form.
         */
-       if (vp->da->type == PW_TYPE_STRING) {
+       if (vp->vp_type == PW_TYPE_STRING) {
                vp->data.datum.ptr = talloc_steal(vp, data.datum.ptr);
                vp->vp_length = rcode;
        } else if (fr_pair_value_from_str(vp, data.datum.strvalue, rcode) < 0) {
@@ -1606,7 +1599,7 @@ ssize_t _tmpl_to_type(void *out,
                ret = tmpl_find_vp(&vp, request, vpt);
                if (ret < 0) return -2;
 
-               to_cast = &vpt->tmpl_value_box_datum;
+               to_cast = &vpt->tmpl_value_box;
                src_type = vpt->tmpl_value_box_type;
        }
                break;
@@ -1694,7 +1687,7 @@ ssize_t _tmpl_to_type(void *out,
                /*
                 *      Data type conversion...
                 */
-               ret = value_box_cast(ctx, &vd_from_cast, dst_type, NULL, src_type, vp ? vp->da : NULL, to_cast);
+               ret = value_box_cast(ctx, &vd_from_cast, dst_type, NULL, to_cast);
                if (ret < 0) return -1;
 
 
@@ -1797,7 +1790,6 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
 
        VALUE_PAIR              *vp = NULL;
        value_box_t             vd;
-       PW_TYPE                 src_type = PW_TYPE_STRING;
        bool                    needs_dup = false;
 
        ssize_t                 slen = -1;
@@ -1815,6 +1807,7 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
 
                vd.length = vpt->len;
                vd.datum.strvalue = vpt->name;
+               vd.type = PW_TYPE_STRING;
                to_cast = &vd;
                needs_dup = true;
                break;
@@ -1830,6 +1823,7 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
                        return slen;
                }
                vd.length = strlen(vd.datum.strvalue);
+               vd.type = PW_TYPE_STRING;
                MEM(vd.datum.strvalue = talloc_realloc(tmp_ctx, vd.datum.ptr, char, vd.length + 1));    /* Trim */
                rad_assert(vd.datum.strvalue[vd.length] == '\0');
                to_cast = &vd;
@@ -1838,6 +1832,7 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
        case TMPL_TYPE_XLAT:
        {
                value_box_t     tmp;
+               PW_TYPE         src_type = PW_TYPE_STRING;
 
                RDEBUG4("EXPAND TMPL XLAT");
 
@@ -1857,6 +1852,7 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
 
                vd.datum.strvalue = tmp.datum.strvalue;
                vd.length = tmp.length;
+               vd.type = PW_TYPE_STRING;
                to_cast = &vd;
        }
                break;
@@ -1864,6 +1860,7 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
        case TMPL_TYPE_XLAT_STRUCT:
        {
                value_box_t     tmp;
+               PW_TYPE         src_type = PW_TYPE_STRING;
 
                RDEBUG4("EXPAND TMPL XLAT STRUCT");
                RDEBUG2("EXPAND %s", vpt->name); /* xlat_struct doesn't do this */
@@ -1885,6 +1882,7 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
 
                vd.datum.strvalue = tmp.datum.strvalue;
                vd.length = tmp.length;
+               vd.type = PW_TYPE_STRING;
                to_cast = &vd;
 
                RDEBUG2("   --> %s", vd.datum.strvalue);        /* Print post-unescaping */
@@ -1900,9 +1898,7 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
                rad_assert(vp);
 
                to_cast = &vp->data;
-               src_type = vp->da->type;
-
-               switch (src_type) {
+               switch (to_cast->type) {
                case PW_TYPE_STRING:
                case PW_TYPE_OCTETS:
                        rad_assert(to_cast->datum.ptr);
@@ -1918,10 +1914,8 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
        {
                RDEBUG4("EXPAND TMPL DATA");
 
-               to_cast = &vpt->tmpl_value_box_datum;
-               src_type = vpt->tmpl_value_box_type;
-
-               switch (src_type) {
+               to_cast = &vpt->tmpl_value_box;
+               switch (to_cast->type) {
                case PW_TYPE_STRING:
                case PW_TYPE_OCTETS:
                        rad_assert(to_cast->datum.ptr);
@@ -1950,11 +1944,11 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
        /*
         *      Don't dup the buffers unless we need to.
         */
-       if ((src_type != dst_type) || needs_dup) {
-               ret = value_box_cast(ctx, &from_cast, dst_type, NULL, src_type, vp ? vp->da : NULL, to_cast);
+       if ((to_cast->type != dst_type) || needs_dup) {
+               ret = value_box_cast(ctx, &from_cast, dst_type, NULL, to_cast);
                if (ret < 0) goto error;
        } else {
-               switch (src_type) {
+               switch (to_cast->type) {
                case PW_TYPE_OCTETS:
                case PW_TYPE_STRING:
                        /*
@@ -1991,13 +1985,11 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
  * @param[out] out Where to write the presentation format #vp_tmpl_t string.
  * @param[in] outlen Size of output buffer.
  * @param[in] vpt to print.
- * @param[in] values Used for #TMPL_TYPE_DATA only. #fr_dict_attr_t to use when mapping integer
- *     values to strings.
  * @return
  *     - The number of bytes written to the out buffer.
  *     - A number >= outlen if truncation has occurred.
  */
-size_t tmpl_snprint(char *out, size_t outlen, vp_tmpl_t const *vpt, fr_dict_attr_t const *values)
+size_t tmpl_snprint(char *out, size_t outlen, vp_tmpl_t const *vpt)
 {
        size_t          len;
        char const      *p;
@@ -2134,8 +2126,7 @@ do_literal:
                break;
 
        case TMPL_TYPE_DATA:
-               return value_box_snprint(out, outlen, vpt->tmpl_value_box_type, values, &vpt->tmpl_value_box_datum,
-                                        fr_token_quote[vpt->quote]);
+               return value_box_snprint(out, outlen, &vpt->tmpl_value_box, fr_token_quote[vpt->quote]);
 
        default:
                goto empty;
@@ -2678,7 +2669,7 @@ void tmpl_verify(char const *file, int line, vp_tmpl_t const *vpt)
                 */
                switch (vpt->tmpl_value_box_type) {
                case PW_TYPE_STRING:
-                       if (vpt->tmpl_value_box.vp_strvalue[vpt->tmpl_value_box_length] != '\0') {
+                       if (vpt->tmpl_value_box_datum.strvalue[vpt->tmpl_value_box_length] != '\0') {
                                FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_DATA char buffer not \\0 "
                                             "terminated", file, line);
                                if (!fr_cond_assert(0)) fr_exit_now(1);
index 0ffb792772d8f6886d52b5ab842a4ab2c78cae54..313af93379c135987f00453aa874db14eaaadfd7 100644 (file)
@@ -338,6 +338,7 @@ static REQUEST *request_from_file(FILE *fp, RADCLIENT *client)
                        talloc_free(q);
 
                        vp->vp_octets = talloc_steal(vp, p);
+                       vp->data.type = PW_TYPE_OCTETS;
                        vp->type = VT_DATA;
 
                        VERIFY_VP(vp);
index 051bb91ea7f36468f4e6dbcf5f4d19e7047cea11..97bc03be9461f574904e9b9e39ca229e13790428 100644 (file)
@@ -1028,7 +1028,7 @@ static void unlang_dump(unlang_t *mc, int depth)
                case UNLANG_TYPE_SWITCH:
                case UNLANG_TYPE_CASE:
                        g = unlang_group_to_module_call(this);
-                       tmpl_snprint(buffer, sizeof(buffer), g->vpt, NULL);
+                       tmpl_snprint(buffer, sizeof(buffer), g->vpt);
                        DEBUG("%.*s%s %s {", depth, modcall_spaces,
                                unlang_ops[this->type].name, buffer);
                        unlang_dump(g->children, depth + 1);
index e43f96b334c3f43f01c2cb38ed9e117a2fac04c1..63ffcd63358362f454a6395a3e9f4665cb5e0cde 100644 (file)
@@ -96,7 +96,7 @@ static ssize_t xlat_integer(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
 
        if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0;
 
-       switch (vp->da->type) {
+       switch (vp->vp_type) {
        case PW_TYPE_OCTETS:
        case PW_TYPE_STRING:
                if (vp->vp_length > 8) {
@@ -158,7 +158,7 @@ static ssize_t xlat_integer(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
        }
 
        REDEBUG("Type '%s' of length %zu cannot be converted to integer",
-               fr_int2str(dict_attr_types, vp->da->type, "???"), vp->vp_length);
+               fr_int2str(dict_attr_types, vp->vp_type, "???"), vp->vp_length);
 
        return -1;
 }
@@ -187,7 +187,7 @@ static ssize_t xlat_hex(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
        /*
         *      The easy case.
         */
-       if (vp->da->type == PW_TYPE_OCTETS) {
+       if (vp->vp_type == PW_TYPE_OCTETS) {
                p = vp->vp_octets;
                len = vp->vp_length;
        /*
@@ -195,7 +195,7 @@ static ssize_t xlat_hex(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
         *      print that as hex.
         */
        } else {
-               if (value_box_cast(request, &dst, PW_TYPE_OCTETS, NULL, vp->da->type, NULL, &vp->data) < 0) {
+               if (value_box_cast(request, &dst, PW_TYPE_OCTETS, NULL, &vp->data) < 0) {
                        REDEBUG("%s", fr_strerror());
                        goto error;
                }
@@ -371,7 +371,7 @@ static ssize_t xlat_debug_attr(UNUSED TALLOC_CTX *ctx, UNUSED char **out, UNUSED
                        dv = fr_dict_vendor_by_num(NULL, vp->da->vendor);
                        RIDEBUG2("Vendor : %i (%s)", vp->da->vendor, dv ? dv->name : "unknown");
                }
-               RIDEBUG2("Type   : %s", fr_int2str(dict_attr_types, vp->da->type, "<INVALID>"));
+               RIDEBUG2("Type   : %s", fr_int2str(dict_attr_types, vp->vp_type, "<INVALID>"));
                RIDEBUG2("Length : %zu", vp->vp_length);
 
                if (!RDEBUG_ENABLED4) continue;
@@ -382,9 +382,7 @@ static ssize_t xlat_debug_attr(UNUSED TALLOC_CTX *ctx, UNUSED char **out, UNUSED
 
                        value_box_t *dst = NULL;
 
-                       if ((PW_TYPE) type->number == vp->da->type) {
-                               goto next_type;
-                       }
+                       if ((PW_TYPE) type->number == vp->vp_type) goto next_type;
 
                        switch (type->number) {
                        case PW_TYPE_INVALID:           /* Not real type */
@@ -401,11 +399,11 @@ static ssize_t xlat_debug_attr(UNUSED TALLOC_CTX *ctx, UNUSED char **out, UNUSED
 
                        dst = talloc_zero(vp, value_box_t);
                        /* We expect some to fail */
-                       if (value_box_cast(dst, dst, type->number, NULL, vp->da->type, vp->da, &vp->data) < 0) {
+                       if (value_box_cast(dst, dst, type->number, NULL, &vp->data) < 0) {
                                goto next_type;
                        }
 
-                       value = value_box_asprint(dst, type->number, NULL, dst, '\'');
+                       value = value_box_asprint(dst, dst, '\'');
                        if (!value) goto next_type;
 
                        if ((pad = (11 - strlen(type->name))) < 0) {
@@ -542,7 +540,7 @@ static ssize_t xlat_string(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
        /*
         *      These are printed specially.
         */
-       switch (vp->da->type) {
+       switch (vp->vp_type) {
        case PW_TYPE_OCTETS:
                return fr_snprint(*out, outlen, (char const *) vp->vp_octets, vp->vp_length, '"');
 
@@ -590,7 +588,7 @@ static ssize_t xlat_xlat(TALLOC_CTX *ctx, char **out, size_t outlen,
        /*
         *      If it's a string, expand it again
         */
-       if (vp->da->type == PW_TYPE_STRING) {
+       if (vp->vp_type == PW_TYPE_STRING) {
                slen = xlat_eval(*out, outlen, request, vp->vp_strvalue, NULL, NULL);
                if (slen <= 0) return slen;
        /*
index 88ab16870f4906c4883ca809d6a9946e66fda253..cf0ddfb79f7f3c48cd669654e10f953817174247 100644 (file)
@@ -849,7 +849,7 @@ static ssize_t decode_value_internal(TALLOC_CTX *ctx, vp_cursor_t *cursor, fr_di
                break;
 
        default:
-               fr_strerror_printf("Internal sanity check %d %d", vp->da->type, __LINE__);
+               fr_strerror_printf("Internal sanity check %d %d", vp->vp_type, __LINE__);
                talloc_free(vp);
                return -1;
        } /* switch over type */
@@ -1163,7 +1163,7 @@ int fr_dhcp_decode(RADIUS_PACKET *packet)
                        }
                }
 
-               switch (vp->da->type) {
+               switch (vp->vp_type) {
                case PW_TYPE_BYTE:
                        vp->vp_byte = p[0];
                        vp->vp_length = 1;
@@ -1212,7 +1212,7 @@ int fr_dhcp_decode(RADIUS_PACKET *packet)
                        break;
 
                default:
-                       fr_strerror_printf("BAD TYPE %d", vp->da->type);
+                       fr_strerror_printf("BAD TYPE %d", vp->vp_type);
                        fr_pair_list_free(&vp);
                        break;
                }
@@ -1426,7 +1426,7 @@ static ssize_t encode_value(uint8_t *out, size_t outlen,
                break;
 
        default:
-               fr_strerror_printf("Unsupported option type %d", vp->da->type);
+               fr_strerror_printf("Unsupported option type %d", vp->vp_type);
                (void)fr_pair_cursor_next(cursor);
                return -2;
        }
@@ -1903,9 +1903,9 @@ int fr_dhcp_add_arp_entry(int fd, char const *interface,
 #endif
 
        if (!fr_cond_assert(macaddr) ||
-           !fr_cond_assert((macaddr->da->type == PW_TYPE_ETHERNET) || (macaddr->da->type == PW_TYPE_OCTETS))) {
+           !fr_cond_assert((macaddr->vp_type == PW_TYPE_ETHERNET) || (macaddr->vp_type == PW_TYPE_OCTETS))) {
                fr_strerror_printf("Wrong VP type (%s) for chaddr",
-                                  fr_int2str(dict_attr_types, macaddr->da->type, "<invalid>"));
+                                  fr_int2str(dict_attr_types, macaddr->vp_type, "<invalid>"));
                return -1;
        }
 
@@ -1922,7 +1922,7 @@ int fr_dhcp_add_arp_entry(int fd, char const *interface,
 
        strlcpy(req.arp_dev, interface, sizeof(req.arp_dev));
 
-       if (macaddr->da->type == PW_TYPE_ETHERNET) {
+       if (macaddr->vp_type == PW_TYPE_ETHERNET) {
                memcpy(&req.arp_ha.sa_data, macaddr->vp_ether, sizeof(macaddr->vp_ether));
        } else {
                memcpy(&req.arp_ha.sa_data, macaddr->vp_octets, macaddr->vp_length);
index ff6c9b558b734a7abe464ffb6e4699088a0de7c9..09e04e6382e088908113954847c255de00d2b01a 100644 (file)
@@ -307,7 +307,7 @@ int vqp_decode(RADIUS_PACKET *packet)
                        return -1;
                }
 
-               switch (vp->da->type) {
+               switch (vp->vp_type) {
                case PW_TYPE_ETHERNET:
                        if (attr_len != 6) goto unknown;
 
@@ -517,7 +517,7 @@ int vqp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original)
                out += 6;
 
                /* Data */
-               switch (vp->da->type) {
+               switch (vp->vp_type) {
                case PW_TYPE_IPV4_ADDR:
                        memcpy(out, &vp->vp_ipaddr, 4);
                        break;
index ec273bb6cb6af97aaae9b98eba161d47f546ef78..027ba425297f24fd81e92780aea8a837eb642aed 100644 (file)
@@ -209,7 +209,7 @@ static cache_status_t cache_entry_find(rlm_cache_entry_t **out,
        if ((head->lhs->tmpl_da->vendor == 0) && (head->lhs->tmpl_da->attr == PW_CACHE_CREATED)) {
                vp_map_t *map;
 
-               c->created = head->rhs->tmpl_value_box_datum.datum.date;
+               c->created = head->rhs->tmpl_value_box_datum.date;
 
                map = head;
                head = head->next;
@@ -222,7 +222,7 @@ static cache_status_t cache_entry_find(rlm_cache_entry_t **out,
        if ((head->lhs->tmpl_da->vendor == 0) && (head->lhs->tmpl_da->attr == PW_CACHE_EXPIRES)) {
                vp_map_t *map;
 
-               c->expires = head->rhs->tmpl_value_box_datum.datum.date;
+               c->expires = head->rhs->tmpl_value_box_datum.date;
 
                map = head;
                head = head->next;
@@ -289,8 +289,8 @@ static cache_status_t cache_entry_insert(UNUSED rlm_cache_config_t const *config
         */
        tmpl_init(&created_value, TMPL_TYPE_DATA, "<TEMP>", 6, T_BARE_WORD);
        created_value.tmpl_value_box_type = PW_TYPE_DATE;
-       created_value.tmpl_value_box_length = sizeof(created_value.tmpl_value_box_datum.datum.date);
-       created_value.tmpl_value_box_datum.datum.date = c->created;
+       created_value.tmpl_value_box_length = sizeof(created_value.tmpl_value_box_datum.date);
+       created_value.tmpl_value_box_datum.date = c->created;
 
        /*
         *      Encode the entry expiry time
@@ -300,8 +300,8 @@ static cache_status_t cache_entry_insert(UNUSED rlm_cache_config_t const *config
         */
        tmpl_init(&expires_value, TMPL_TYPE_DATA, "<TEMP>", 6, T_BARE_WORD);
        expires_value.tmpl_value_box_type = PW_TYPE_DATE;
-       expires_value.tmpl_value_box_length = sizeof(expires_value.tmpl_value_box_datum.datum.date);
-       expires_value.tmpl_value_box_datum.datum.date = c->expires;
+       expires_value.tmpl_value_box_length = sizeof(expires_value.tmpl_value_box_datum.date);
+       expires_value.tmpl_value_box_datum.date = c->expires;
        expires.next = c->maps; /* Head of the list */
 
        for (cnt = 0, map = &created; map; cnt++, map = map->next);
index 56406d4a52d02298132504e041af4bfca8d64263..2a89f9a13bc02178c622599e8629b5465d06b965 100644 (file)
@@ -373,16 +373,15 @@ static rlm_rcode_t cache_insert(rlm_cache_t const *inst, REQUEST *request, rlm_c
                        do_rhs:
                                MEM(c_map->rhs = tmpl_init(talloc(c_map, vp_tmpl_t),
                                                           TMPL_TYPE_DATA, map->rhs->name, map->rhs->len, T_BARE_WORD));
-                               if (value_box_copy(c_map->rhs, &c_map->rhs->tmpl_value_box_datum,
-                                                   vp->da->type, &vp->data) < 0) {
+                               if (value_box_copy(c_map->rhs, &c_map->rhs->tmpl_value_box, &vp->data) < 0) {
                                        REDEBUG("Failed copying attribute value");
                                error:
                                        talloc_free(pool);
                                        talloc_free(c);
                                        return RLM_MODULE_FAIL;
                                }
-                               c_map->rhs->tmpl_value_box_type = vp->da->type;
-                               if (vp->da->type == PW_TYPE_STRING) {
+                               c_map->rhs->tmpl_value_box_type = vp->vp_type;
+                               if (vp->vp_type == PW_TYPE_STRING) {
                                        c_map->rhs->quote = is_printable(vp->vp_strvalue, vp->vp_length) ?
                                                T_SINGLE_QUOTED_STRING : T_DOUBLE_QUOTED_STRING;
                                }
@@ -408,7 +407,7 @@ static rlm_rcode_t cache_insert(rlm_cache_t const *inst, REQUEST *request, rlm_c
                                 *      We need to rebuild the attribute name, to be the
                                 *      one we copied from the source list.
                                 */
-                               len = tmpl_snprint(attr, sizeof(attr), c_map->lhs, NULL);
+                               len = tmpl_snprint(attr, sizeof(attr), c_map->lhs);
                                if (is_truncated(len, sizeof(attr))) {
                                        REDEBUG("Serialized attribute too long.  Must be < "
                                                STRINGIFY(sizeof(attr)) " bytes, got %zu bytes", len);
@@ -832,8 +831,7 @@ static ssize_t cache_xlat(UNUSED TALLOC_CTX *ctx, char **out, UNUSED size_t free
                    (map->lhs->tmpl_tag != target.tmpl_tag) ||
                    (map->lhs->tmpl_list != target.tmpl_list)) continue;
 
-               *out = value_box_asprint(request, map->rhs->tmpl_value_box_type, map->lhs->tmpl_da,
-                                         &map->rhs->tmpl_value_box_datum, '\0');
+               *out = value_box_asprint(request, &map->rhs->tmpl_value_box, '\0');
                ret = talloc_array_length(*out) - 1;
                break;
        }
index c0aa2f88e47c2f9bc1bfe4ac2e3313be6f4dfc82..59e5f61f22a948ba7ebeb14dd4e225aa6322a4fd 100644 (file)
@@ -67,7 +67,7 @@ int cache_serialize(TALLOC_CTX *ctx, char **out, rlm_cache_entry_t const *c)
                char    *value;
                size_t  len;
 
-               len = tmpl_snprint(attr, sizeof(attr), map->lhs, map->lhs->tmpl_da);
+               len = tmpl_snprint(attr, sizeof(attr), map->lhs);
                if (is_truncated(len, sizeof(attr))) {
                        fr_strerror_printf("Serialized attribute too long.  Must be < " STRINGIFY(sizeof(attr)) " "
                                           "bytes, got %zu bytes", len);
@@ -75,7 +75,7 @@ int cache_serialize(TALLOC_CTX *ctx, char **out, rlm_cache_entry_t const *c)
                }
 
                value = value_box_asprint(value_pool, map->rhs->tmpl_value_box_type,
-                                          map->lhs->tmpl_da, &map->rhs->tmpl_value_box_datum, '\'');
+                                          map->lhs->tmpl_da, &map->rhs->tmpl_value_box, '\'');
                if (!value) goto error;
 
                to_store = talloc_asprintf_append_buffer(to_store, "%s %s %s\n", attr,
@@ -150,12 +150,12 @@ int cache_deserialize(rlm_cache_entry_t *c, char *in, ssize_t inlen)
                 */
                if (map->lhs->tmpl_da->vendor == 0) switch (map->lhs->tmpl_da->attr) {
                case PW_CACHE_CREATED:
-                       c->created = map->rhs->tmpl_value_box_datum.datum.date;
+                       c->created = map->rhs->tmpl_value_box_datum.date;
                        talloc_free(map);
                        goto next;
 
                case PW_CACHE_EXPIRES:
-                       c->expires = map->rhs->tmpl_value_box_datum.datum.date;
+                       c->expires = map->rhs->tmpl_value_box_datum.date;
                        talloc_free(map);
                        goto next;
 
index 9e077eaa34a3ed808adb8b3598033887fc0d97d3..8914e6852e804fc8107b04a3fa2be088743b8644 100644 (file)
@@ -388,7 +388,7 @@ json_object *mod_value_pair_to_json_object(REQUEST *request, VALUE_PAIR *vp)
        if (!vp->da->flags.has_tag) {
                unsigned int i;
 
-               switch (vp->da->type) {
+               switch (vp->vp_type) {
                case PW_TYPE_INTEGER:
                        i = vp->vp_integer;
                        goto print_int;
@@ -446,7 +446,7 @@ json_object *mod_value_pair_to_json_object(REQUEST *request, VALUE_PAIR *vp)
        }
 
        /* keep going if not set above */
-       switch (vp->da->type) {
+       switch (vp->vp_type) {
        case PW_TYPE_STRING:
                /* debug */
                RDEBUG3("assigning string '%s' as string", vp->da->name);
index 0f1a6ecad91eea4556674c1e66b6b2f5f04ae666..b5f152db1da4ce8337e7800d5553e928b805e2b3 100644 (file)
@@ -53,7 +53,7 @@ static ssize_t xlat_date_convert(UNUSED TALLOC_CTX *ctx, char **out, size_t outl
 
        if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0;
 
-       switch (vp->da->type) {
+       switch (vp->vp_type) {
        /*
         *      These are 'to' types, i.e. we'll convert the integers
         *      to a time structure, and then output it in the specified
index bff8cd092e057958069b74e562d734e9b8f2af7b..7d9532d4b078d324d530c7735eadce58b52b6715 100644 (file)
@@ -798,7 +798,7 @@ ssize_t fr_sim_encode(REQUEST *request, fr_dict_attr_t const *parent, uint8_t ty
                /*
                 *      String attributes have a 16bit "Actual Length" field at the start.
                 */
-               } else if (vp->da->type == PW_TYPE_STRING) {
+               } else if (vp->vp_type == PW_TYPE_STRING) {
                        vp_len = vp->vp_length + 2;
                /*
                 *      All other attributes we trust the length.
@@ -855,7 +855,7 @@ ssize_t fr_sim_encode(REQUEST *request, fr_dict_attr_t const *parent, uint8_t ty
                /*
                 *      For strings we have an 'actual' value field.
                 */
-               if (vp->da->type == PW_TYPE_STRING) {
+               if (vp->vp_type == PW_TYPE_STRING) {
                        vp_len = vp->vp_length + 2;
                /*
                 *      All other attributes we trust the length.
@@ -873,7 +873,7 @@ ssize_t fr_sim_encode(REQUEST *request, fr_dict_attr_t const *parent, uint8_t ty
                p[0] = vp->da->attr;
                p[1] = rounded_len >> 2;
 
-               switch (vp->da->type) {
+               switch (vp->vp_type) {
                case PW_TYPE_OCTETS:
                        memcpy(&p[2], vp->vp_octets, vp->vp_length);
                        break;
@@ -938,7 +938,7 @@ ssize_t fr_sim_encode(REQUEST *request, fr_dict_attr_t const *parent, uint8_t ty
                {
                        value_box_t data;
 
-                       value_box_hton(&data, vp->da->type, &vp->data);
+                       value_box_hton(&data, &vp->data);
                        memcpy(&p[2], &data, vp->vp_length);
                }
 
index 46aeebfb67e3ffbea7c93d626830deda885c2667..f5c819379a6344b2a4dee33326dcd05b56e1aeea 100644 (file)
@@ -279,7 +279,7 @@ static VALUE_PAIR *diameter2vp(REQUEST *request, REQUEST *fake, SSL *ssl,
                /*
                 *      Diameter pads strings (i.e. User-Password) with trailing zeros.
                 */
-               if (vp->da->type == PW_TYPE_STRING) {
+               if (vp->vp_type == PW_TYPE_STRING) {
                        fr_pair_value_strcpy(vp, vp->vp_strvalue);
                }
 
@@ -395,7 +395,7 @@ static int vp2diameter(REQUEST *request, tls_session_t *tls_session, VALUE_PAIR
                        total += 4;
                }
 
-               switch (vp->da->type) {
+               switch (vp->vp_type) {
                case PW_TYPE_INTEGER:
                case PW_TYPE_DATE:
                        attr = htonl(vp->vp_integer); /* stored in host order */
index 4c250c3df85e2b1446f39e43acaabab30f243dca..8b1529120fe7148098b9851aa105897f53c35775 100644 (file)
@@ -56,7 +56,7 @@ static const CONF_PARSER module_config[] = {
 static int rlm_example_cmp(UNUSED void *instance, REQUEST *request, UNUSED VALUE_PAIR *thing, VALUE_PAIR *check,
                           UNUSED VALUE_PAIR *check_pairs, UNUSED VALUE_PAIR **reply_pairs)
 {
-       rad_assert(check->da->type == PW_TYPE_STRING);
+       rad_assert(check->vp_type == PW_TYPE_STRING);
 
        RINFO("Example-Paircmp called with \"%s\"", check->vp_strvalue);
 
index 0caae008c26d3c6f6ba28a555a72bb809096b2e9..c07746af85d345706a46a85de10179dfa2758662 100644 (file)
@@ -74,7 +74,7 @@ static int presufcmp(UNUSED void *instance,
 
        VERIFY_VP(req);
        VERIFY_VP(check);
-       rad_assert(req->da->type == PW_TYPE_STRING);
+       rad_assert(req->vp_type == PW_TYPE_STRING);
 
        name = req->vp_strvalue;
 
index ed4e4fec390dfc7ef3c0dd1fe3e41c89aca18d17..f269a031ef5538568fd645152240ed9758e377b5 100644 (file)
@@ -257,10 +257,10 @@ static bool get_number(REQUEST *request, char const **string, int64_t *answer)
                     i++, vp = tmpl_cursor_next(&cursor, &vpt)) {
                        int64_t y;
 
-                       if (vp->da->type != PW_TYPE_INTEGER64) {
+                       if (vp->vp_type != PW_TYPE_INTEGER64) {
                                value_box_t     value;
 
-                               if (value_box_cast(vp, &value, PW_TYPE_INTEGER64, NULL, vp->da->type, vp->da, &vp->data) < 0) {
+                               if (value_box_cast(vp, &value, PW_TYPE_INTEGER64, NULL, &vp->data) < 0) {
                                        REDEBUG("Failed converting &%.*s to an integer value: %s", (int) vpt.len,
                                                vpt.name, fr_strerror());
                                        return false;
@@ -1004,8 +1004,8 @@ static int decode_xlat_ref(uint8_t **out, size_t *outlen, REQUEST *request, char
         *      These are large types.  Return pointers to the
         *      data instead of copying the data.
         */
-       if ((vp->da->type == PW_TYPE_STRING) ||
-           (vp->da->type == PW_TYPE_OCTETS)) {
+       if ((vp->vp_type == PW_TYPE_STRING) ||
+           (vp->vp_type == PW_TYPE_OCTETS)) {
                *out = vp->vp_ptr;
                *outlen = vp->vp_length;
                return 0;
@@ -1424,7 +1424,7 @@ static ssize_t explode_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
                 *      This can theoretically operate on lists too
                 *      so we need to check the type of each attribute.
                 */
-               switch (vp->da->type) {
+               switch (vp->vp_type) {
                case PW_TYPE_OCTETS:
                case PW_TYPE_STRING:
                        break;
@@ -1456,7 +1456,7 @@ static ssize_t explode_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
                        }
                        new->tag = vp->tag;
 
-                       switch (vp->da->type) {
+                       switch (vp->vp_type) {
                        case PW_TYPE_OCTETS:
                        {
                                uint8_t *buff;
index a3f6b1596c7be933f24bf8423ff9664f0cbe3fe4..00eb79079b38fdeb06f3376185da92a325e9f643 100644 (file)
 
 /** Convert json object to value_box_t
  *
- * @param ctx to allocate any value buffers in (should usually be the same as out).
- * @param out Where to write value_box.
- * @param object to convert.
- * @param dst_type FreeRADIUS type to convert to.
- * @param dst_enumv Enumeration values to allow string to integer conversions.
+ * @param[in] ctx      to allocate any value buffers in (should usually be the same as out).
+ * @param[in] out      Where to write value_box.
+ * @param[in] object   to convert.
+ * @param[in] dst_type FreeRADIUS type to convert to.
+ * @param[in] dst_enumv        Enumeration values to allow string to integer conversions.
  * @return
  *     - 0 on success.
  *     - -1 on failure.
  */
 int fr_json_object_to_value_box(TALLOC_CTX *ctx, value_box_t *out, json_object *object,
-                                PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv)
+                               PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv)
 {
-       PW_TYPE src_type = PW_TYPE_INVALID;
        value_box_t in;
 
        memset(&in, 0, sizeof(in));
 
        switch (fr_json_object_get_type(object)) {
        case json_type_string:
-               src_type = PW_TYPE_STRING;
+               in.type = PW_TYPE_STRING;
                in.datum.strvalue = json_object_get_string(object);
                in.length = json_object_get_string_len(object);
                break;
 
        case json_type_double:
-               src_type = PW_TYPE_DECIMAL;
+               in.type = PW_TYPE_DECIMAL;
                in.datum.decimal = json_object_get_double(object);
                in.length = sizeof(in.datum.decimal);
                break;
@@ -84,25 +83,25 @@ int fr_json_object_to_value_box(TALLOC_CTX *ctx, value_box_t *out, json_object *
                        return -1;
                }
                if (num > UINT32_MAX) {         /* 64bit unsigned (supported) */
-                       src_type = PW_TYPE_INTEGER64;
+                       in.type = PW_TYPE_INTEGER64;
                        in.datum.integer64 = (uint64_t) num;
                        in.length = sizeof(in.datum.integer64);
                } else
 #endif
                if (num < 0) {                  /* 32bit signed (supported) */
-                       src_type = PW_TYPE_SIGNED;
+                       in.type = PW_TYPE_SIGNED;
                        in.datum.sinteger = num;
                        in.length = sizeof(in.datum.sinteger);
                } else if (num > UINT16_MAX) {  /* 32bit unsigned (supported) */
-                       src_type = PW_TYPE_INTEGER;
+                       in.type = PW_TYPE_INTEGER;
                        in.datum.integer = (uint32_t) num;
                        in.length = sizeof(in.datum.integer);
                } else if (num > UINT8_MAX) {   /* 16bit unsigned (supported) */
-                       src_type = PW_TYPE_SHORT;
+                       in.type = PW_TYPE_SHORT;
                        in.datum.ushort = (uint16_t) num;
                        in.length = sizeof(in.datum.ushort);
                } else {                /* 8bit unsigned (supported) */
-                       src_type = PW_TYPE_BYTE;
+                       in.type = PW_TYPE_BYTE;
                        in.datum.byte = (uint8_t) num;
                        in.length = sizeof(in.datum.byte);
                }
@@ -110,7 +109,7 @@ int fr_json_object_to_value_box(TALLOC_CTX *ctx, value_box_t *out, json_object *
                break;
 
        case json_type_boolean:
-               src_type = PW_TYPE_BOOLEAN;
+               in.type = PW_TYPE_BOOLEAN;
                in.datum.boolean = json_object_get_boolean(object);
                in.length = sizeof(in.datum.boolean);
                break;
@@ -118,38 +117,32 @@ int fr_json_object_to_value_box(TALLOC_CTX *ctx, value_box_t *out, json_object *
        case json_type_null:
        case json_type_array:
        case json_type_object:
-               src_type = PW_TYPE_STRING;
+               in.type = PW_TYPE_STRING;
                in.datum.strvalue = json_object_to_json_string(object);
                in.length = strlen(in.datum.strvalue);
                break;
        }
 
-       if (src_type == dst_type) {
-               if (value_box_copy(ctx, out, src_type, &in) < 0) return -1;
-       } else {
-               if (value_box_cast(ctx, out, dst_type, dst_enumv, src_type, NULL, &in) < 0) return -1;
-       }
+       if (value_box_cast(ctx, out, dst_type, dst_enumv, &in) < 0) return -1;
+
        return 0;
 }
 
 /** Convert boxed value_box to a JSON object
  *
  * @param[in] ctx      to allocate temporary buffers in
- * @param[in] type     of value data.
- * @param[in] enumv    of value data.
  * @param[in] data     to convert.
  */
-json_object *json_object_from_value_box(TALLOC_CTX *ctx,
-                                        PW_TYPE type, fr_dict_attr_t const *enumv, value_box_t const *data)
+json_object *json_object_from_value_box(TALLOC_CTX *ctx, value_box_t const *data)
 {
-       switch (type) {
+       switch (data->type) {
        default:
        do_string:
        {
                char            *p;
                json_object     *obj;
 
-               p = value_box_asprint(ctx, type, enumv, data, '\0');
+               p = value_box_asprint(ctx, data, '\0');
                if (!p) return NULL;
 
                obj = json_object_new_string(p);
@@ -227,7 +220,7 @@ size_t fr_json_from_pair(char *out, size_t outlen, VALUE_PAIR const *vp)
        size_t len, freespace = outlen;
 
        if (!vp->da->flags.has_tag) {
-               switch (vp->da->type) {
+               switch (vp->vp_type) {
                case PW_TYPE_INTEGER:
                        if (vp->da->flags.has_value) break;
 
@@ -251,7 +244,7 @@ size_t fr_json_from_pair(char *out, size_t outlen, VALUE_PAIR const *vp)
                }
        }
 
-       if (vp->da->type == PW_TYPE_STRING) {
+       if (vp->vp_type == PW_TYPE_STRING) {
                char *tmp = fr_json_from_string(NULL, vp->vp_strvalue, true);
 
                /* Indicate truncation */
@@ -358,7 +351,7 @@ const char *fr_json_afrom_pair_list(TALLOC_CTX *ctx, VALUE_PAIR **vps, const cha
                        MEM(vp_object = json_object_new_object());
                        json_object_object_add(obj, name_with_prefix, vp_object);
 
-                       MEM(type_name = json_object_new_string(fr_int2str(dict_attr_types, vp->da->type, "<INVALID>")));
+                       MEM(type_name = json_object_new_string(fr_int2str(dict_attr_types, vp->vp_type, "<INVALID>")));
                        json_object_object_add(vp_object, "type", type_name);
 
                        MEM(values = json_object_new_array());
@@ -373,7 +366,7 @@ const char *fr_json_afrom_pair_list(TALLOC_CTX *ctx, VALUE_PAIR **vps, const cha
                        return NULL;
                }
 
-               MEM(value = json_object_from_value_box(ctx, vp->da->type, vp->da, &vp->data));
+               MEM(value = json_object_from_value_box(ctx, &vp->data));
                json_object_array_add(values, value);
 
                /*
index 4db2768b710f79d217cea1133ba794a480542eff..9e73061205fcd6cc460822ced024d07029f91a2d 100644 (file)
@@ -59,10 +59,9 @@ ssize_t              fr_jpath_parse(TALLOC_CTX *ctx, fr_jpath_node_t **head, char const *in,
 
 /* json.c */
 int            fr_json_object_to_value_box(TALLOC_CTX *ctx, value_box_t *out, json_object *object,
-                                            PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv);
+                                           PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv);
 
-json_object    *json_object_from_value_box(TALLOC_CTX *ctx,
-                                            PW_TYPE type, fr_dict_attr_t const *enumv, value_box_t const *data);
+json_object    *json_object_from_value_box(TALLOC_CTX *ctx, value_box_t const *data);
 
 char           *fr_json_from_string(TALLOC_CTX *ctx, char const *s, bool include_quotes);
 
index d5e226659d6450e4b9685d80a82763d21228ad6b..6775eb4fd838e381f130ad38dd9643c8b6581f68 100644 (file)
@@ -167,7 +167,7 @@ static int mod_map_proc_instantiate(CONF_SECTION *cs, UNUSED void *mod_inst, voi
                                cf_log_err_cp(cp, "Right side of map must be a string");
                                return -1;
                        }
-                       p = map->rhs->tmpl_value_box_datum.datum.strvalue;
+                       p = map->rhs->tmpl_value_box_datum.strvalue;
                        slen = fr_jpath_parse(cache, &cache->jpath, p, map->rhs->tmpl_value_box_length);
                        if (slen <= 0) goto error;
                        break;
@@ -232,7 +232,7 @@ static int _json_map_proc_get_value(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *
                }
                vp->op = map->op;
 
-               if (value_box_steal(vp, &vp->data, vp->da->type, value) < 0) {
+               if (value_box_steal(vp, &vp->data, value) < 0) {
                        REDEBUG("Copying data to attribute failed: %s", fr_strerror());
                        talloc_free(vp);
                        goto error;
index 0c994c4dae0103fef4f565db9d375606e24c1d5a..beae83576015f5cdc13a8d2df3f4dc38e7f29cd7 100644 (file)
@@ -584,7 +584,7 @@ build_vector:
                                MEM(vector = talloc_realloc(request, vector, struct iovec, alloced));
                        }
 
-                       switch (vp->da->type) {
+                       switch (vp->vp_type) {
                        case PW_TYPE_OCTETS:
                        case PW_TYPE_STRING:
                                vector[i].iov_base = vp->vp_ptr;
index 890adaa79254c5ef7e12e826ced88ac0d3f0d970..66a29956a710871684ce8444f1ea08d551e0c5bd 100644 (file)
@@ -53,7 +53,7 @@ static int rlm_lua_marshall(lua_State *L, VALUE_PAIR const *vp)
 
        if (!vp) return -1;
 
-       switch (vp->da->type) {
+       switch (vp->vp_type) {
        case PW_TYPE_DATE:
        case PW_TYPE_ETHERNET:
        case PW_TYPE_IPV4_ADDR:
@@ -83,7 +83,7 @@ static int rlm_lua_marshall(lua_State *L, VALUE_PAIR const *vp)
                break;
 
        default:
-               ERROR("Cannot convert %s to Lua type", fr_int2str(dict_attr_types, vp->da->type, "<INVALID>"));
+               ERROR("Cannot convert %s to Lua type", fr_int2str(dict_attr_types, vp->vp_type, "<INVALID>"));
                return -1;
        }
        return 0;
@@ -107,7 +107,7 @@ static int rlm_lua_unmarshall(VALUE_PAIR **out, REQUEST *request, lua_State *L,
        MEM(vp = fr_pair_afrom_da(request, da));
        switch (lua_type(L, -1)) {
        case LUA_TNUMBER:
-               switch (vp->da->type) {
+               switch (vp->vp_type) {
                case PW_TYPE_STRING:
                {
                        char *p;
index 6cd5617259f779b466e05709be999f2818599d51..38709d03595528f7afce6ee48c2dbc3abb0fb097 100644 (file)
@@ -694,7 +694,7 @@ void mschap_add_reply(REQUEST *request, uint8_t ident,
                return;
        }
 
-       if (vp->da->type == PW_TYPE_STRING) {
+       if (vp->vp_type == PW_TYPE_STRING) {
                char *p;
 
                p = talloc_array(vp, char, len + 1 + 1);        /* Account for the ident byte */
index 06e5d65cd0490e4082b607f5c5647cb8c50a6a0d..109e5c2f0e99ee406e7949f23048a26baccf0e6a 100644 (file)
@@ -624,7 +624,7 @@ static void perl_vp_to_svpvn_element(REQUEST *request, AV *av, VALUE_PAIR const
 
        char buffer[1024];
 
-       switch (vp->da->type) {
+       switch (vp->vp_type) {
        case PW_TYPE_STRING:
                RDEBUG("$%s{'%s'}[%i] = &%s:%s -> '%s'", hash_name, vp->da->name, *i,
                       list_name, vp->da->name, vp->vp_strvalue);
@@ -715,7 +715,7 @@ static void perl_store_vps(UNUSED TALLOC_CTX *ctx, REQUEST *request, VALUE_PAIR
                /*
                 *      It's a normal single valued attribute
                 */
-               switch (vp->da->type) {
+               switch (vp->vp_type) {
                case PW_TYPE_STRING:
                        RDEBUG("$%s{'%s'} = &%s:%s -> '%s'", hash_name, vp->da->name, list_name,
                               vp->da->name, vp->vp_strvalue);
@@ -771,7 +771,7 @@ static int pairadd_sv(TALLOC_CTX *ctx, REQUEST *request, VALUE_PAIR **vps, char
                return -1;
        }
 
-       switch (vp->da->type) {
+       switch (vp->vp_type) {
        case PW_TYPE_STRING:
                fr_pair_value_bstrncpy(vp, val, len);
                break;
index 6a9ead3c67b90b2a6092e2ff6a4e579db9437f54..0e9e2f20cfe9f89cc98be58ecf38f9650469a70d 100644 (file)
@@ -116,9 +116,7 @@ static void cisco_vsa_hack(REQUEST *request)
                        continue; /* not a Cisco or Quintum VSA, continue */
                }
 
-               if (vp->da->type != PW_TYPE_STRING) {
-                       continue;
-               }
+               if (vp->vp_type != PW_TYPE_STRING) continue;
 
                /*
                 *  No weird packing.  Ignore it.
@@ -173,18 +171,12 @@ static void alvarion_vsa_hack(VALUE_PAIR *vp)
             vp = fr_pair_cursor_next(&cursor)) {
                fr_dict_attr_t const *da;
 
-               if (vp->da->vendor != 12394) {
-                       continue;
-               }
+               if (vp->da->vendor != 12394) continue;
 
-               if (vp->da->type != PW_TYPE_STRING) {
-                       continue;
-               }
+               if (vp->vp_type != PW_TYPE_STRING) continue;
 
                da = fr_dict_attr_by_num(NULL, 12394, number);
-               if (!da) {
-                       continue;
-               }
+               if (!da) continue;
 
                vp->da = da;
 
index f647e288448d1c58caf8b24b5f4e3d168be465ee..350fa6d95ea4503a10c8153cb77c29cf520c7eb9 100644 (file)
@@ -354,7 +354,7 @@ static int mod_populate_vptuple(PyObject *pp, VALUE_PAIR *vp)
 
        PyTuple_SET_ITEM(pp, 0, attribute);
 
-       switch (vp->da->type) {
+       switch (vp->vp_type) {
        case PW_TYPE_STRING:
                value = PyUnicode_FromStringAndSize(vp->vp_strvalue, vp->vp_length);
                break;
index aabd831ae16ce686af130b2d3a9e81aa14982c8b..400e0df90bf4ddde58ef932d3e2738f589192b99 100644 (file)
@@ -481,7 +481,7 @@ static rlm_rcode_t mod_realm_recv_coa(UNUSED void *instance, UNUSED void *thread
        /*
         *      Catch the case of broken dictionaries.
         */
-       if (vp->da->type != PW_TYPE_STRING) return RLM_MODULE_NOOP;
+       if (vp->vp_type != PW_TYPE_STRING) return RLM_MODULE_NOOP;
 
        /*
         *      The string is too short.
index cb5e674fe310eca812b985739901f156470d3db4..7e0b81af2b65bfbaa879c005e2135720a30bdf2e 100644 (file)
@@ -192,7 +192,6 @@ int fr_redis_reply_to_value_box(TALLOC_CTX *ctx, value_box_t *out, redisReply *r
                                 PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv)
 {
        value_box_t     in;
-       PW_TYPE         src_type = 0;
 
        memset(&in, 0, sizeof(in));
 
@@ -211,34 +210,34 @@ int fr_redis_reply_to_value_box(TALLOC_CTX *ctx, value_box_t *out, redisReply *r
                        return -1;
                }
                if (reply->integer < 0) {               /* 32bit signed (supported) */
-                       src_type = PW_TYPE_SIGNED;
+                       in.type = PW_TYPE_SIGNED;
                        in.datum.sinteger = (int32_t) reply->integer;
                        in.length = sizeof(in.datum.sinteger);
                }
                else if (reply->integer > UINT32_MAX) { /* 64bit unsigned (supported) */
-                       src_type = PW_TYPE_INTEGER64;
+                       in.type = PW_TYPE_INTEGER64;
                        in.datum.integer64 = (uint64_t) reply->integer;
                        in.length = sizeof(in.datum.integer64);
                }
                else if (reply->integer > UINT16_MAX) { /* 32bit unsigned (supported) */
-                       src_type = PW_TYPE_INTEGER;
+                       in.type = PW_TYPE_INTEGER;
                        in.datum.integer = (uint32_t) reply->integer;
                        in.length = sizeof(in.datum.integer);
                }
                else if (reply->integer > UINT8_MAX) {  /* 16bit unsigned (supported) */
-                       src_type = PW_TYPE_SHORT;
+                       in.type = PW_TYPE_SHORT;
                        in.datum.ushort = (uint16_t) reply->integer;
                        in.length = sizeof(in.datum.ushort);
                }
                else {          /* 8bit unsigned (supported) */
-                       src_type = PW_TYPE_BYTE;
+                       in.type = PW_TYPE_BYTE;
                        in.datum.byte = (uint8_t) reply->integer;
                        in.length = sizeof(in.datum.byte);
                }
                break;
 
        case REDIS_REPLY_STRING:
-               src_type = PW_TYPE_STRING;
+               in.type = PW_TYPE_STRING;
                in.datum.ptr = reply->str;
                in.length = reply->len;
                break;
@@ -249,11 +248,8 @@ int fr_redis_reply_to_value_box(TALLOC_CTX *ctx, value_box_t *out, redisReply *r
                rad_assert(0);
        }
 
-       if (src_type == dst_type) {
-               if (value_box_copy(ctx, out, src_type, &in) < 0) return -1;
-       } else {
-               if (value_box_cast(ctx, out, dst_type, dst_enumv, src_type, NULL, &in) < 0) return -1;
-       }
+       if (value_box_cast(ctx, out, dst_type, dst_enumv, &in) < 0) return -1;
+
        return 0;
 }
 
@@ -331,10 +327,7 @@ int fr_redis_reply_to_map(TALLOC_CTX *ctx, vp_map_t **out, REQUEST *request,
                }
 
                /* This will only fail only memory allocation errors */
-               if (tmpl_afrom_value_box(map, &map->rhs, &vpt,
-                                         map->lhs->tmpl_da->type, map->lhs->tmpl_da, true) < 0) {
-                       goto error;
-               }
+               if (tmpl_afrom_value_box(map, &map->rhs, &vpt, true) < 0) goto error;
        }
                break;
 
@@ -381,7 +374,7 @@ int fr_redis_tuple_from_map(TALLOC_CTX *pool, char const *out[], size_t out_len[
        rad_assert(map->lhs->type == TMPL_TYPE_ATTR);
        rad_assert(map->rhs->type == TMPL_TYPE_DATA);
 
-       key_len = tmpl_snprint(key_buf, sizeof(key_buf), map->lhs, map->lhs->tmpl_da);
+       key_len = tmpl_snprint(key_buf, sizeof(key_buf), map->lhs);
        if (is_truncated(key_len, sizeof(key_buf))) {
                fr_strerror_printf("Key too long.  Must be < " STRINGIFY(sizeof(key_buf)) " "
                                   "bytes, got %zu bytes", key_len);
@@ -393,7 +386,7 @@ int fr_redis_tuple_from_map(TALLOC_CTX *pool, char const *out[], size_t out_len[
        switch (map->rhs->tmpl_value_box_type) {
        case PW_TYPE_STRING:
        case PW_TYPE_OCTETS:
-               out[2] = map->rhs->tmpl_value_box_datum.datum.ptr;
+               out[2] = map->rhs->tmpl_value_box_datum.ptr;
                out_len[2] = map->rhs->tmpl_value_box_length;
                break;
 
@@ -405,8 +398,7 @@ int fr_redis_tuple_from_map(TALLOC_CTX *pool, char const *out[], size_t out_len[
                char    value[256];
                size_t  len;
 
-               len = value_box_snprint(value, sizeof(value), map->rhs->tmpl_value_box_type, map->lhs->tmpl_da,
-                                       &map->rhs->tmpl_value_box_datum, '\0');
+               len = value_box_snprint(value, sizeof(value), &map->rhs->tmpl_value_box, '\0');
                new = talloc_bstrndup(pool, value, len);
                if (!new) {
                        talloc_free(key);
index cf9de4cb44925608a0ae81a7de9090d6fbd71826..9f5f9cbe2988961eb5b4624b39ee8f77d9446133 100644 (file)
@@ -120,7 +120,7 @@ fr_redis_rcode_t    fr_redis_command_status(fr_redis_conn_t *conn, redisReply *repl
 void                   fr_redis_reply_print(log_lvl_t lvl, redisReply *reply, REQUEST *request, int idx);
 
 int                    fr_redis_reply_to_value_box(TALLOC_CTX *ctx, value_box_t *out, redisReply *reply,
-                                                    PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv);
+                                                   PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv);
 
 int                    fr_redis_reply_to_map(TALLOC_CTX *ctx, vp_map_t **out,
                                              REQUEST *request, redisReply *key, redisReply *op, redisReply *value);
index fe84e042c6aefa0ce584d118b733c1896d466d2b..88b6cfae3118be2f57ca6872dffae50f350de0e9 100644 (file)
@@ -642,24 +642,25 @@ static ippool_rcode_t redis_ippool_allocate(rlm_redis_ippool_t const *inst, REQU
                                memset(&tmp, 0, sizeof(tmp));
 
                                tmp.datum.integer = ntohl((uint32_t)reply->element[1]->integer);
-                               tmp.length = sizeof(ip_map.rhs->tmpl_value_box_datum.datum.integer);
+                               tmp.length = sizeof(ip_map.rhs->tmpl_value_box_datum.integer);
+                               tmp.type = PW_TYPE_INTEGER;
 
-                               if (value_box_cast(NULL, &ip_map.rhs->tmpl_value_box_datum, PW_TYPE_IPV4_ADDR,
-                                                   NULL, PW_TYPE_INTEGER, NULL, &tmp)) {
+                               if (value_box_cast(NULL, &ip_map.rhs->tmpl_value_box, PW_TYPE_IPV4_ADDR,
+                                                   NULL, &tmp)) {
                                        REDEBUG("Failed converting integer to IPv4 address: %s", fr_strerror());
                                        ret = IPPOOL_RCODE_FAIL;
                                        goto finish;
                                }
                        } else {
-                               ip_map.rhs->tmpl_value_box_datum.datum.integer = ntohl((uint32_t)reply->element[1]->integer);
-                               ip_map.rhs->tmpl_value_box_length = sizeof(ip_map.rhs->tmpl_value_box_datum.datum.integer);
+                               ip_map.rhs->tmpl_value_box_datum.integer = ntohl((uint32_t)reply->element[1]->integer);
+                               ip_map.rhs->tmpl_value_box_length = sizeof(ip_map.rhs->tmpl_value_box_datum.integer);
                                ip_map.rhs->tmpl_value_box_type = PW_TYPE_INTEGER;
                        }
                }
                        goto do_ip_map;
 
                case REDIS_REPLY_STRING:
-                       ip_map.rhs->tmpl_value_box_datum.datum.strvalue = reply->element[1]->str;
+                       ip_map.rhs->tmpl_value_box_datum.strvalue = reply->element[1]->str;
                        ip_map.rhs->tmpl_value_box_length = reply->element[1]->len;
                        ip_map.rhs->tmpl_value_box_type = PW_TYPE_STRING;
 
@@ -700,7 +701,7 @@ static ippool_rcode_t redis_ippool_allocate(rlm_redis_ippool_t const *inst, REQU
                                .rhs = &range_rhs
                        };
 
-                       range_map.rhs->tmpl_value_box_datum.datum.strvalue = reply->element[2]->str;
+                       range_map.rhs->tmpl_value_box_datum.strvalue = reply->element[2]->str;
                        range_map.rhs->tmpl_value_box_length = reply->element[2]->len;
                        range_map.rhs->tmpl_value_box_type = PW_TYPE_STRING;
                        if (map_to_request(request, &range_map, map_to_vp, NULL) < 0) {
@@ -744,8 +745,8 @@ static ippool_rcode_t redis_ippool_allocate(rlm_redis_ippool_t const *inst, REQU
                        goto finish;
                }
 
-               expiry_map.rhs->tmpl_value_box_datum.datum.integer = reply->element[3]->integer;
-               expiry_map.rhs->tmpl_value_box_length = sizeof(expiry_map.rhs->tmpl_value_box_datum.datum.integer);
+               expiry_map.rhs->tmpl_value_box_datum.integer = reply->element[3]->integer;
+               expiry_map.rhs->tmpl_value_box_length = sizeof(expiry_map.rhs->tmpl_value_box_datum.integer);
                expiry_map.rhs->tmpl_value_box_type = PW_TYPE_INTEGER;
                if (map_to_request(request, &expiry_map, map_to_vp, NULL) < 0) {
                        ret = IPPOOL_RCODE_FAIL;
@@ -851,7 +852,7 @@ static ippool_rcode_t redis_ippool_update(rlm_redis_ippool_t const *inst, REQUES
                 *      Add range ID to request
                 */
                case REDIS_REPLY_STRING:
-                       range_map.rhs->tmpl_value_box_datum.datum.strvalue = reply->element[1]->str;
+                       range_map.rhs->tmpl_value_box_datum.strvalue = reply->element[1]->str;
                        range_map.rhs->tmpl_value_box_length = reply->element[1]->len;
                        range_map.rhs->tmpl_value_box_type = PW_TYPE_STRING;
                        if (map_to_request(request, &range_map, map_to_vp, NULL) < 0) {
@@ -887,8 +888,8 @@ static ippool_rcode_t redis_ippool_update(rlm_redis_ippool_t const *inst, REQUES
                        .rhs = &expiry_rhs
                };
 
-               expiry_map.rhs->tmpl_value_box_datum.datum.integer = expires;
-               expiry_map.rhs->tmpl_value_box_length = sizeof(expiry_map.rhs->tmpl_value_box_datum.datum.integer);
+               expiry_map.rhs->tmpl_value_box_datum.integer = expires;
+               expiry_map.rhs->tmpl_value_box_length = sizeof(expiry_map.rhs->tmpl_value_box_datum.integer);
                expiry_map.rhs->tmpl_value_box_type = PW_TYPE_INTEGER;
                if (map_to_request(request, &expiry_map, map_to_vp, NULL) < 0) {
                        ret = IPPOOL_RCODE_FAIL;
@@ -1146,7 +1147,7 @@ static rlm_rcode_t mod_action(rlm_redis_ippool_t const *inst, REQUEST *request,
                                };
 
                                ip_rhs.tmpl_value_box_length = strlen(ip_str);
-                               ip_rhs.tmpl_value_box_datum.datum.strvalue = ip_str;
+                               ip_rhs.tmpl_value_box_datum.strvalue = ip_str;
                                ip_rhs.tmpl_value_box_type = PW_TYPE_STRING;
 
                                if (map_to_request(request, &ip_map, map_to_vp, NULL) < 0) return RLM_MODULE_FAIL;
index b90ddf48c159e7c5b4808d77356954f2e703f49f..b0decedf71144886b153c98825323836b19d64a2 100644 (file)
@@ -899,7 +899,6 @@ static VALUE_PAIR *json_pair_make_leaf(UNUSED rlm_rest_t const *instance, UNUSED
 
        VALUE_PAIR      *vp;
 
-       PW_TYPE         type;
        value_box_t     src;
 
        if (fr_json_object_is_type(leaf, json_type_null)) {
@@ -920,18 +919,17 @@ static VALUE_PAIR *json_pair_make_leaf(UNUSED rlm_rest_t const *instance, UNUSED
        switch (json_object_get_type(leaf)) {
        case json_type_int:
                if (flags->do_xlat) RWDEBUG("Ignoring do_xlat on 'int', attribute \"%s\"", da->name);
-               type = PW_TYPE_SIGNED;
                src.datum.sinteger = json_object_get_int(leaf);
+               src.type = PW_TYPE_SIGNED;
                break;
 
        case json_type_double:
                if (flags->do_xlat) RWDEBUG("Ignoring do_xlat on 'double', attribute \"%s\"", da->name);
-               type = PW_TYPE_DECIMAL;
                src.datum.decimal = json_object_get_double(leaf);
+               src.type = PW_TYPE_DECIMAL;
                break;
 
        case json_type_string:
-               type = PW_TYPE_STRING;
                value = json_object_get_string(leaf);
                if (flags->do_xlat) {
                        if (xlat_aeval(request, &expanded, request, value, NULL, NULL) < 0) return NULL;
@@ -941,6 +939,7 @@ static VALUE_PAIR *json_pair_make_leaf(UNUSED rlm_rest_t const *instance, UNUSED
                        src.datum.strvalue = value;
                        src.length = json_object_get_string_len(leaf);
                }
+               src.type = PW_TYPE_STRING;
 
                break;
 
@@ -952,17 +951,17 @@ static VALUE_PAIR *json_pair_make_leaf(UNUSED rlm_rest_t const *instance, UNUSED
                 *
                 *      "I knew you liked JSON so I put JSON in your JSON!"
                 */
-               type = PW_TYPE_STRING;
                src.datum.strvalue = json_object_get_string(leaf);
                if (!src.datum.strvalue) {
                        RWDEBUG("Failed getting string value for attribute \"%s\", skipping...", da->name);
 
                        return NULL;
                }
+               src.type = PW_TYPE_STRING;
                src.length = strlen(src.datum.strvalue);
        }
 
-       ret = value_box_cast(vp, &vp->data, vp->da->type, vp->da, type, NULL, &src);
+       ret = value_box_cast(vp, &vp->data, da->type, da, &src);
        talloc_free(expanded);
        if (ret < 0) {
                RWDEBUG("Failed parsing value for attribute \"%s\" (skipping): %s", da->name, fr_strerror());
index 638175646f8d5769dbe24e07eb63e57ad1e44414..f4a90d646286ebae358f64491ddc299240f27519 100644 (file)
@@ -123,8 +123,7 @@ static int rlm_rest_status_update(REQUEST *request,  void *handle)
         *      current request.
         */
        RADIUS_LIST_AND_CTX(ctx, list, request, REQUEST_CURRENT, PAIR_LIST_REQUEST);
-       if (!list || (fr_pair_update_by_num(ctx, list, 0, PW_REST_HTTP_STATUS_CODE,
-                                           TAG_ANY, PW_TYPE_INTEGER, &value) < 0)) {
+       if (!list || (fr_pair_update_by_num(ctx, list, 0, PW_REST_HTTP_STATUS_CODE, TAG_ANY, &value) < 0)) {
                REDEBUG("Failed updating &REST-HTTP-Status-Code");
                return -1;
        }
index 10f377f5bcd5108bcff23c0cdac1e3dc9bbbde03..0eb6a16ab7a34721e07b35a1981503025bfeac39 100644 (file)
@@ -169,7 +169,7 @@ static const CONF_PARSER module_config[] = {
 static int rlm_test_cmp(UNUSED void *instance, REQUEST *request, UNUSED VALUE_PAIR *thing, VALUE_PAIR *check,
                        UNUSED VALUE_PAIR *check_pairs, UNUSED VALUE_PAIR **reply_pairs)
 {
-       rad_assert(check->da->type == PW_TYPE_STRING);
+       rad_assert(check->vp_type == PW_TYPE_STRING);
 
        RINFO("test-Paircmp called with \"%s\"", check->vp_strvalue);
 
index 77b9bd8313b2797ab0d8c37fd8014cd81815ea34..8ccd5cabe7162a229b0dceacc775a2509d2728f7 100644 (file)
@@ -92,8 +92,8 @@ static ssize_t unpack_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
        if (*data_name == '&') {
                if (radius_get_vp(&vp, request, data_name) < 0) goto nothing;
 
-               if ((vp->da->type != PW_TYPE_OCTETS) &&
-                   (vp->da->type != PW_TYPE_STRING)) {
+               if ((vp->vp_type != PW_TYPE_OCTETS) &&
+                   (vp->vp_type != PW_TYPE_STRING)) {
                        REDEBUG("unpack requires the input attribute to be 'string' or 'octets'");
                        goto nothing;
                }
index 3caecf22721e355b1fb0fc6e635669efdb93959f..d34b073a60794758f4986072f3e9e117bc610a4f 100644 (file)
@@ -38,7 +38,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_utf8_clean(UNUSED void *instance, UNUSED
        for (vp = fr_pair_cursor_init(&cursor, &request->packet->vps);
             vp;
             vp = fr_pair_cursor_next(&cursor)) {
-               if (vp->da->type != PW_TYPE_STRING) continue;
+               if (vp->vp_type != PW_TYPE_STRING) continue;
 
                for (i = 0; i < vp->vp_length; i += len) {
                        len = fr_utf8_char(&vp->vp_octets[i], -1);