From: Arran Cudbard-Bell Date: Mon, 23 Jan 2017 17:00:07 +0000 (+0000) Subject: Add type field to value_box_t X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eb5dce0fc86a11ea0294a5467f3cd01c1dd50859;p=thirdparty%2Ffreeradius-server.git Add type field to value_box_t ... 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 --- diff --git a/src/include/libradius.h b/src/include/libradius.h index ebb9e97ad9f..48f5ebc1f63 100644 --- a/src/include/libradius.h +++ b/src/include/libradius.h @@ -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) diff --git a/src/include/pair.h b/src/include/pair.h index 2c16f9e3253..e7edfca343e 100644 --- a/src/include/pair.h +++ b/src/include/pair.h @@ -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); diff --git a/src/include/tmpl.h b/src/include/tmpl.h index b6302146b42..1de3cd5ccea 100644 --- a/src/include/tmpl.h +++ b/src/include/tmpl.h @@ -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, diff --git a/src/lib/pair.c b/src/lib/pair.c index 05cf0d2ce7d..b94e322c611 100644 --- a/src/lib/pair.c +++ b/src/lib/pair.c @@ -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, "")); + fr_int2str(dict_attr_types, vp->vp_type, "")); 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, ""), + fr_int2str(dict_attr_types, vp->data.type, "")); + 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, ""), + fr_int2str(dict_attr_types, vp->da->type, "")); + if (!fr_cond_assert(0)) fr_exit_now(1); + } } /* diff --git a/src/lib/print.c b/src/lib/print.c index b68e200bc32..fd615d1e567 100644 --- a/src/lib/print.c +++ b/src/lib/print.c @@ -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; diff --git a/src/lib/radius_decode.c b/src/lib/radius_decode.c index 330ac00db4c..8d84fa8177e 100644 --- a/src/lib/radius_decode.c +++ b/src/lib/radius_decode.c @@ -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 */ diff --git a/src/lib/radius_encode.c b/src/lib/radius_encode.c index b1ed5588fad..edabcadff3e 100644 --- a/src/lib/radius_encode.c +++ b/src/lib/radius_encode.c @@ -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); diff --git a/src/lib/value.c b/src/lib/value.c index 9c838884083..a668fc6fb36 100644 --- a/src/lib/value.c +++ b/src/lib/value.c @@ -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, ""), + fr_int2str(dict_attr_types, src->type, ""), fr_int2str(dict_attr_types, dst_type, "")); 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, ""), + fr_int2str(dict_attr_types, src->type, ""), fr_int2str(dict_attr_types, dst_type, "")); 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, ""), + fr_int2str(dict_attr_types, src->type, ""), fr_int2str(dict_attr_types, dst_type, "")); 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, ""), + fr_int2str(dict_attr_types, src->type, ""), fr_int2str(dict_attr_types, dst_type, "")); 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, ""), + fr_int2str(dict_attr_types, src->type, ""), fr_int2str(dict_attr_types, dst_type, "")); 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, ""); + type_name = fr_int2str(dict_attr_types, src->type, ""); 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, ""), 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, ""), + fr_int2str(dict_attr_types, src->type, ""), fr_int2str(dict_attr_types, dst_type, ""), 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); diff --git a/src/main/client.c b/src/main/client.c index e39f4b11a3a..d112c6584d3 100644 --- a/src/main/client.c +++ b/src/main/client.c @@ -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); diff --git a/src/main/cond_eval.c b/src/main/cond_eval.c index c65172285fc..e7d8d6e7cc6 100644 --- a/src/main/cond_eval.c +++ b/src/main/cond_eval.c @@ -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, ""),\ + fr_int2str(dict_attr_types, _s->type, ""),\ fr_int2str(dict_attr_types, cast_type, ""));\ - 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, "")); @@ -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; diff --git a/src/main/cond_tokenize.c b/src/main/cond_tokenize.c index a14a6ef0111..44b9566c91f 100644 --- a/src/main/cond_tokenize.c +++ b/src/main/cond_tokenize.c @@ -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; diff --git a/src/main/files.c b/src/main/files.c index 92616b1bbab..26b2720bb12 100644 --- a/src/main/files.c +++ b/src/main/files.c @@ -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", diff --git a/src/main/map.c b/src/main/map.c index b77d0a94c19..6d448efbaf3 100644 --- a/src/main/map.c +++ b/src/main/map.c @@ -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, ""), rhs); break; diff --git a/src/main/pair.c b/src/main/pair.c index 276ef837974..9fde7c00762 100644 --- a/src/main/pair.c +++ b/src/main/pair.c @@ -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 diff --git a/src/main/radclient.c b/src/main/radclient.c index 33b1b421e9f..129190ed9ad 100644 --- a/src/main/radclient.c +++ b/src/main/radclient.c @@ -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); diff --git a/src/main/radsnmp.c b/src/main/radsnmp.c index ac4c6890922..39c27420e8a 100644 --- a/src/main/radsnmp.c +++ b/src/main/radsnmp.c @@ -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; diff --git a/src/main/realms.c b/src/main/realms.c index d5d7efcde92..ccd044ef622 100644 --- a/src/main/realms.c +++ b/src/main/realms.c @@ -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 diff --git a/src/main/snmp.c b/src/main/snmp.c index e9e6e506b72..e495fdc19b2 100644 --- a/src/main/snmp.c +++ b/src/main/snmp.c @@ -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); diff --git a/src/main/stats.c b/src/main/stats.c index 630a403654b..c9c42b08561 100644 --- a/src/main/stats.c +++ b/src/main/stats.c @@ -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, diff --git a/src/main/tmpl.c b/src/main/tmpl.c index 0bf5b62d7d1..a669bd4ba87 100644 --- a/src/main/tmpl.c +++ b/src/main/tmpl.c @@ -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); diff --git a/src/main/unit_test_module.c b/src/main/unit_test_module.c index 0ffb792772d..313af93379c 100644 --- a/src/main/unit_test_module.c +++ b/src/main/unit_test_module.c @@ -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); diff --git a/src/main/unlang_compile.c b/src/main/unlang_compile.c index 051bb91ea7f..97bc03be946 100644 --- a/src/main/unlang_compile.c +++ b/src/main/unlang_compile.c @@ -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); diff --git a/src/main/xlat_func.c b/src/main/xlat_func.c index e43f96b334c..63ffcd63358 100644 --- a/src/main/xlat_func.c +++ b/src/main/xlat_func.c @@ -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, "")); + RIDEBUG2("Type : %s", fr_int2str(dict_attr_types, vp->vp_type, "")); 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; /* diff --git a/src/modules/proto_dhcp/dhcp.c b/src/modules/proto_dhcp/dhcp.c index 88ab16870f4..cf0ddfb79f7 100644 --- a/src/modules/proto_dhcp/dhcp.c +++ b/src/modules/proto_dhcp/dhcp.c @@ -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, "")); + fr_int2str(dict_attr_types, macaddr->vp_type, "")); 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); diff --git a/src/modules/proto_vmps/vqp.c b/src/modules/proto_vmps/vqp.c index ff6c9b558b7..09e04e6382e 100644 --- a/src/modules/proto_vmps/vqp.c +++ b/src/modules/proto_vmps/vqp.c @@ -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; diff --git a/src/modules/rlm_cache/drivers/rlm_cache_redis/rlm_cache_redis.c b/src/modules/rlm_cache/drivers/rlm_cache_redis/rlm_cache_redis.c index ec273bb6cb6..027ba425297 100644 --- a/src/modules/rlm_cache/drivers/rlm_cache_redis/rlm_cache_redis.c +++ b/src/modules/rlm_cache/drivers/rlm_cache_redis/rlm_cache_redis.c @@ -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, "", 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, "", 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); diff --git a/src/modules/rlm_cache/rlm_cache.c b/src/modules/rlm_cache/rlm_cache.c index 56406d4a52d..2a89f9a13bc 100644 --- a/src/modules/rlm_cache/rlm_cache.c +++ b/src/modules/rlm_cache/rlm_cache.c @@ -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; } diff --git a/src/modules/rlm_cache/serialize.c b/src/modules/rlm_cache/serialize.c index c0aa2f88e47..59e5f61f22a 100644 --- a/src/modules/rlm_cache/serialize.c +++ b/src/modules/rlm_cache/serialize.c @@ -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; diff --git a/src/modules/rlm_couchbase/mod.c b/src/modules/rlm_couchbase/mod.c index 9e077eaa34a..8914e6852e8 100644 --- a/src/modules/rlm_couchbase/mod.c +++ b/src/modules/rlm_couchbase/mod.c @@ -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); diff --git a/src/modules/rlm_date/rlm_date.c b/src/modules/rlm_date/rlm_date.c index 0f1a6ecad91..b5f152db1da 100644 --- a/src/modules/rlm_date/rlm_date.c +++ b/src/modules/rlm_date/rlm_date.c @@ -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 diff --git a/src/modules/rlm_eap/lib/sim/sim_proto.c b/src/modules/rlm_eap/lib/sim/sim_proto.c index bff8cd092e0..7d9532d4b07 100644 --- a/src/modules/rlm_eap/lib/sim/sim_proto.c +++ b/src/modules/rlm_eap/lib/sim/sim_proto.c @@ -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); } diff --git a/src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c b/src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c index 46aeebfb67e..f5c819379a6 100644 --- a/src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c +++ b/src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c @@ -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 */ diff --git a/src/modules/rlm_example/rlm_example.c b/src/modules/rlm_example/rlm_example.c index 4c250c3df85..8b1529120fe 100644 --- a/src/modules/rlm_example/rlm_example.c +++ b/src/modules/rlm_example/rlm_example.c @@ -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); diff --git a/src/modules/rlm_expr/paircmp.c b/src/modules/rlm_expr/paircmp.c index 0caae008c26..c07746af85d 100644 --- a/src/modules/rlm_expr/paircmp.c +++ b/src/modules/rlm_expr/paircmp.c @@ -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; diff --git a/src/modules/rlm_expr/rlm_expr.c b/src/modules/rlm_expr/rlm_expr.c index ed4e4fec390..f269a031ef5 100644 --- a/src/modules/rlm_expr/rlm_expr.c +++ b/src/modules/rlm_expr/rlm_expr.c @@ -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; diff --git a/src/modules/rlm_json/json.c b/src/modules/rlm_json/json.c index a3f6b1596c7..00eb79079b3 100644 --- a/src/modules/rlm_json/json.c +++ b/src/modules/rlm_json/json.c @@ -30,32 +30,31 @@ /** 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, ""))); + MEM(type_name = json_object_new_string(fr_int2str(dict_attr_types, vp->vp_type, ""))); 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); /* diff --git a/src/modules/rlm_json/json.h b/src/modules/rlm_json/json.h index 4db2768b710..9e73061205f 100644 --- a/src/modules/rlm_json/json.h +++ b/src/modules/rlm_json/json.h @@ -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); diff --git a/src/modules/rlm_json/rlm_json.c b/src/modules/rlm_json/rlm_json.c index d5e226659d6..6775eb4fd83 100644 --- a/src/modules/rlm_json/rlm_json.c +++ b/src/modules/rlm_json/rlm_json.c @@ -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; diff --git a/src/modules/rlm_linelog/rlm_linelog.c b/src/modules/rlm_linelog/rlm_linelog.c index 0c994c4dae0..beae8357601 100644 --- a/src/modules/rlm_linelog/rlm_linelog.c +++ b/src/modules/rlm_linelog/rlm_linelog.c @@ -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; diff --git a/src/modules/rlm_lua/lua.c b/src/modules/rlm_lua/lua.c index 890adaa7925..66a29956a71 100644 --- a/src/modules/rlm_lua/lua.c +++ b/src/modules/rlm_lua/lua.c @@ -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, "")); + ERROR("Cannot convert %s to Lua type", fr_int2str(dict_attr_types, vp->vp_type, "")); 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; diff --git a/src/modules/rlm_mschap/rlm_mschap.c b/src/modules/rlm_mschap/rlm_mschap.c index 6cd5617259f..38709d03595 100644 --- a/src/modules/rlm_mschap/rlm_mschap.c +++ b/src/modules/rlm_mschap/rlm_mschap.c @@ -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 */ diff --git a/src/modules/rlm_perl/rlm_perl.c b/src/modules/rlm_perl/rlm_perl.c index 06e5d65cd04..109e5c2f0e9 100644 --- a/src/modules/rlm_perl/rlm_perl.c +++ b/src/modules/rlm_perl/rlm_perl.c @@ -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; diff --git a/src/modules/rlm_preprocess/rlm_preprocess.c b/src/modules/rlm_preprocess/rlm_preprocess.c index 6a9ead3c67b..0e9e2f20cfe 100644 --- a/src/modules/rlm_preprocess/rlm_preprocess.c +++ b/src/modules/rlm_preprocess/rlm_preprocess.c @@ -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; diff --git a/src/modules/rlm_python/rlm_python.c b/src/modules/rlm_python/rlm_python.c index f647e288448..350fa6d95ea 100644 --- a/src/modules/rlm_python/rlm_python.c +++ b/src/modules/rlm_python/rlm_python.c @@ -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; diff --git a/src/modules/rlm_realm/rlm_realm.c b/src/modules/rlm_realm/rlm_realm.c index aabd831ae16..400e0df90bf 100644 --- a/src/modules/rlm_realm/rlm_realm.c +++ b/src/modules/rlm_realm/rlm_realm.c @@ -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. diff --git a/src/modules/rlm_redis/redis.c b/src/modules/rlm_redis/redis.c index cb5e674fe31..7e0b81af2b6 100644 --- a/src/modules/rlm_redis/redis.c +++ b/src/modules/rlm_redis/redis.c @@ -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); diff --git a/src/modules/rlm_redis/redis.h b/src/modules/rlm_redis/redis.h index cf9de4cb449..9f5f9cbe298 100644 --- a/src/modules/rlm_redis/redis.h +++ b/src/modules/rlm_redis/redis.h @@ -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); diff --git a/src/modules/rlm_redis_ippool/rlm_redis_ippool.c b/src/modules/rlm_redis_ippool/rlm_redis_ippool.c index fe84e042c6a..88b6cfae311 100644 --- a/src/modules/rlm_redis_ippool/rlm_redis_ippool.c +++ b/src/modules/rlm_redis_ippool/rlm_redis_ippool.c @@ -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; diff --git a/src/modules/rlm_rest/rest.c b/src/modules/rlm_rest/rest.c index b90ddf48c15..b0decedf711 100644 --- a/src/modules/rlm_rest/rest.c +++ b/src/modules/rlm_rest/rest.c @@ -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()); diff --git a/src/modules/rlm_rest/rlm_rest.c b/src/modules/rlm_rest/rlm_rest.c index 638175646f8..f4a90d64628 100644 --- a/src/modules/rlm_rest/rlm_rest.c +++ b/src/modules/rlm_rest/rlm_rest.c @@ -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; } diff --git a/src/modules/rlm_test/rlm_test.c b/src/modules/rlm_test/rlm_test.c index 10f377f5bcd..0eb6a16ab7a 100644 --- a/src/modules/rlm_test/rlm_test.c +++ b/src/modules/rlm_test/rlm_test.c @@ -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); diff --git a/src/modules/rlm_unpack/rlm_unpack.c b/src/modules/rlm_unpack/rlm_unpack.c index 77b9bd8313b..8ccd5cabe71 100644 --- a/src/modules/rlm_unpack/rlm_unpack.c +++ b/src/modules/rlm_unpack/rlm_unpack.c @@ -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; } diff --git a/src/modules/rlm_utf8/rlm_utf8.c b/src/modules/rlm_utf8/rlm_utf8.c index 3caecf22721..d34b073a607 100644 --- a/src/modules/rlm_utf8/rlm_utf8.c +++ b/src/modules/rlm_utf8/rlm_utf8.c @@ -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);