Add pairdatacpy to fix value parenting issues
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 17 Jun 2014 22:40:37 +0000 (23:40 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 17 Jun 2014 23:08:13 +0000 (00:08 +0100)
src/include/libradius.h
src/lib/filters.c
src/lib/print.c
src/lib/valuepair.c
src/main/evaluate.c
src/main/map.c
src/main/valuepair.c

index b5976ac..827a339 100644 (file)
@@ -424,6 +424,8 @@ size_t              fr_print_string_len(char const *in, size_t inlen);
 
 #define                is_truncated(_ret, _max) ((_ret) >= (_max))
 #define                truncate_len(_ret, _max) (((_ret) >= (_max)) ? ((_max) - 1) : _ret)
+size_t         vp_data_prints_value(char *out, size_t outlen,
+                                    DICT_ATTR const *da, value_data_t const *data, size_t data_len, int8_t quote);
 size_t         vp_prints_value(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t quote);
 size_t         vp_prints_value_json(char *out, size_t outlen, VALUE_PAIR const *vp);
 size_t         vp_prints(char *out, size_t outlen, VALUE_PAIR const *vp);
@@ -591,7 +593,6 @@ void                pairvalidate_debug(TALLOC_CTX *ctx, VALUE_PAIR const *failed[2]);
 bool           pairvalidate(VALUE_PAIR const *failed[2], VALUE_PAIR *filter, VALUE_PAIR *list);
 bool           pairvalidate_relaxed(VALUE_PAIR const *failed[2], VALUE_PAIR *filter, VALUE_PAIR *list);
 VALUE_PAIR     *paircopyvp(TALLOC_CTX *ctx, VALUE_PAIR const *vp);
-VALUE_PAIR     *paircopyvpdata(TALLOC_CTX *ctx, DICT_ATTR const *da, VALUE_PAIR const *vp);
 VALUE_PAIR     *paircopy(TALLOC_CTX *ctx, VALUE_PAIR *from);
 VALUE_PAIR     *paircopy2(TALLOC_CTX *ctx, VALUE_PAIR *from, unsigned int attr, unsigned int vendor, int8_t tag);
 VALUE_PAIR     *pairsteal(TALLOC_CTX *ctx, VALUE_PAIR *from);
@@ -600,6 +601,7 @@ void                pairmemsteal(VALUE_PAIR *vp, uint8_t const *src);
 void           pairstrsteal(VALUE_PAIR *vp, char const *src);
 void           pairstrcpy(VALUE_PAIR *vp, char const * src);
 void           pairstrncpy(VALUE_PAIR *vp, char const * src, size_t len);
+int            pairdatacpy(VALUE_PAIR *vp, DICT_ATTR const *da, value_data_t const *data, size_t len);
 void           pairsprintf(VALUE_PAIR *vp, char const * fmt, ...) CC_HINT(format (printf, 2, 3));
 void           pairmove(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **from);
 void           pairfilter(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **from,
@@ -699,7 +701,7 @@ void                fr_talloc_verify_cb(const void *ptr, int depth,
 #ifdef WITH_ASCEND_BINARY
 /* filters.c */
 int            ascend_parse_filter(VALUE_PAIR *vp, char const *value, size_t len);
-void           print_abinary(char *out, size_t outlen, VALUE_PAIR const *vp,  int8_t quote);
+void           print_abinary(char *out, size_t outlen, uint8_t const *data, size_t len, int8_t quote);
 #endif /*WITH_ASCEND_BINARY*/
 
 /* random numbers in isaac.c */
index 07a0757..3203907 100644 (file)
@@ -1115,11 +1115,11 @@ int ascend_parse_filter(VALUE_PAIR *vp, char const *value, size_t len)
  *     Note we don't bother checking 'len' after the snprintf's.
  *     This function should ONLY be called with a large (~1k) buffer.
  */
-void print_abinary(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t quote)
+void print_abinary(char *out, size_t outlen, uint8_t const *data, size_t len, int8_t quote)
 {
        size_t  i;
        char    *p;
-       ascend_filter_t *filter;
+       ascend_filter_t const *filter;
 
        static char const *action[] = {"drop", "forward"};
        static char const *direction[] = {"out", "in"};
@@ -1129,14 +1129,12 @@ void print_abinary(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t quote)
        /*
         *  Just for paranoia: wrong size filters get printed as octets
         */
-       if (vp->length != sizeof(*filter)) {
-               uint8_t *f = (uint8_t *) &vp->vp_filter;
-
+       if (len != sizeof(*filter)) {
                strcpy(p, "0x");
                p += 2;
                outlen -= 2;
-               for (i = 0; i < vp->length; i++) {
-                       snprintf(p, outlen, "%02x", f[i]);
+               for (i = 0; i < len; i++) {
+                       snprintf(p, outlen, "%02x", data[i]);
                        p += 2;
                        outlen -= 2;
                }
@@ -1148,7 +1146,7 @@ void print_abinary(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t quote)
                outlen -= 3;                    /* account for leading & trailing quotes */
        }
 
-       filter = (ascend_filter_t *) &(vp->vp_filter);
+       filter = (ascend_filter_t const *) data;
        i = snprintf(p, outlen, "%s %s %s", fr_int2str(filterType, filter->type, "??"),
                     direction[filter->direction & 0x01], action[filter->forward & 0x01]);
 
@@ -1162,10 +1160,10 @@ void print_abinary(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t quote)
 
                if (filter->u.ip.srcip) {
                        i = snprintf(p, outlen, " srcip %d.%d.%d.%d/%d",
-                                    ((uint8_t *) &filter->u.ip.srcip)[0],
-                                    ((uint8_t *) &filter->u.ip.srcip)[1],
-                                    ((uint8_t *) &filter->u.ip.srcip)[2],
-                                    ((uint8_t *) &filter->u.ip.srcip)[3],
+                                    ((uint8_t const *) &filter->u.ip.srcip)[0],
+                                    ((uint8_t const *) &filter->u.ip.srcip)[1],
+                                    ((uint8_t const *) &filter->u.ip.srcip)[2],
+                                    ((uint8_t const *) &filter->u.ip.srcip)[3],
                                     filter->u.ip.srcmask);
                        p += i;
                        outlen -= i;
@@ -1173,10 +1171,10 @@ void print_abinary(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t quote)
 
                if (filter->u.ip.dstip) {
                        i = snprintf(p, outlen, " dstip %d.%d.%d.%d/%d",
-                                    ((uint8_t *) &filter->u.ip.dstip)[0],
-                                    ((uint8_t *) &filter->u.ip.dstip)[1],
-                                    ((uint8_t *) &filter->u.ip.dstip)[2],
-                                    ((uint8_t *) &filter->u.ip.dstip)[3],
+                                    ((uint8_t const *) &filter->u.ip.dstip)[0],
+                                    ((uint8_t const *) &filter->u.ip.dstip)[1],
+                                    ((uint8_t const *) &filter->u.ip.dstip)[2],
+                                    ((uint8_t const *) &filter->u.ip.dstip)[3],
                                     filter->u.ip.dstmask);
                        p += i;
                        outlen -= i;
index e4e85af..cd84c78 100644 (file)
@@ -298,17 +298,11 @@ size_t fr_print_string_len(char const *in, size_t inlen)
        return outlen;
 }
 
-
 /** Print the value of an attribute to a string
  *
- * @param[out] out Where to write the string.
- * @param[in] outlen Size of outlen (must be at least 3 bytes).
- * @param[in] vp to print.
- * @param[in] quote Char to add before and after printed value, if 0 no char will be added, if < 0 raw string will be
- *     added.
- * @return the length of data written to out, or a value >= outlen on truncation.
  */
-size_t vp_prints_value(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t quote)
+size_t vp_data_prints_value(char *out, size_t outlen,
+                           DICT_ATTR const *da, value_data_t const *data, size_t data_len, int8_t quote)
 {
        DICT_VALUE      *v;
        char            buf[1024];      /* Interim buffer to use with poorly behaved printing functions */
@@ -318,26 +312,23 @@ size_t vp_prints_value(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t qu
 
        size_t          len = 0, freespace = outlen;
 
-       if (!vp) return 0;
-
-       VERIFY_VP(vp);
-
-       if (outlen == 0) return vp->length;
+       if (!data) return 0;
+       if (outlen == 0) return data_len;
 
        *out = '\0';
 
-       switch (vp->da->type) {
+       switch (da->type) {
        case PW_TYPE_STRING:
                /* need to copy the escaped value, but quoted */
                if (quote > 0) {
                        if (freespace < 3) {
-                               return vp->length + 2;
+                               return data_len + 2;
                        }
 
                        *out++ = (char) quote;
                        freespace--;
 
-                       len = fr_print_string(vp->vp_strvalue, vp->length, out, freespace);
+                       len = fr_print_string(data->strvalue, data_len, out, freespace);
                        /* always terminate the quoted string with another quote */
                        if (len >= (freespace - 1)) {
                                out[outlen - 2] = (char) quote;
@@ -356,49 +347,37 @@ size_t vp_prints_value(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t qu
 
                /* xlat.c - need to copy raw value verbatim */
                else if (quote < 0) {
-                       if (outlen > vp->length) {
-                               memcpy(out, vp->vp_strvalue, vp->length + 1);
-                               return vp->length;
+                       if (outlen > data_len) {
+                               memcpy(out, data->strvalue, data_len + 1);
+                               return data_len;
                        }
 
-                       memcpy(out, vp->vp_strvalue, outlen);
+                       memcpy(out, data->strvalue, outlen);
                        out[outlen - 1] = '\0';
-                       return vp->length;      /* not a typo */
+                       return data_len;        /* not a typo */
                }
 
-               return fr_print_string(vp->vp_strvalue, vp->length, out, outlen);
+               return fr_print_string(data->strvalue, data_len, out, outlen);
 
        case PW_TYPE_INTEGER:
-               if (vp->da->flags.has_tag) {
-                       /* Attribute value has a tag, need to ignore it */
-                       if ((v = dict_valbyattr(vp->da->attr, vp->da->vendor, (vp->vp_integer & 0xffffff))) != NULL) {
-                               a = v->name;
-                               len = strlen(a);
-                       } else {
-                               /* should never be truncated */
-                               len = snprintf(buf, sizeof(buf), "%u", (vp->vp_integer & 0xffffff));
-                               a = buf;
-                       }
-               } else {
        case PW_TYPE_BYTE:
        case PW_TYPE_SHORT:
-                       /* Normal, non-tagged attribute */
-                       if ((v = dict_valbyattr(vp->da->attr, vp->da->vendor, vp->vp_integer)) != NULL) {
-                               a = v->name;
-                               len = strlen(a);
-                       } else {
-                               /* should never be truncated */
-                               len = snprintf(buf, sizeof(buf), "%u", vp->vp_integer);
-                               a = buf;
-                       }
+               /* Normal, non-tagged attribute */
+               if ((v = dict_valbyattr(da->attr, da->vendor, data->integer)) != NULL) {
+                       a = v->name;
+                       len = strlen(a);
+               } else {
+                       /* should never be truncated */
+                       len = snprintf(buf, sizeof(buf), "%u", data->integer);
+                       a = buf;
                }
                break;
 
        case PW_TYPE_INTEGER64:
-               return snprintf(out, outlen, "%" PRIu64, vp->vp_integer64);
+               return snprintf(out, outlen, "%" PRIu64, data->integer64);
 
        case PW_TYPE_DATE:
-               t = vp->vp_date;
+               t = data->date;
                if (quote > 0) {
                        len = strftime(buf, sizeof(buf) - 1, "%%%b %e %Y %H:%M:%S %Z%%", localtime_r(&t, &s_tm));
                        buf[0] = (char) quote;
@@ -411,19 +390,18 @@ size_t vp_prints_value(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t qu
                break;
 
        case PW_TYPE_SIGNED: /* Damned code for 1 WiMAX attribute */
-               len = snprintf(buf, sizeof(buf), "%d", vp->vp_signed);
+               len = snprintf(buf, sizeof(buf), "%d", data->sinteger);
                a = buf;
                break;
 
        case PW_TYPE_IPV4_ADDR:
-               a = inet_ntop(AF_INET, &(vp->vp_ipaddr), buf, sizeof(buf));
+               a = inet_ntop(AF_INET, &(data->ipaddr), buf, sizeof(buf));
                len = strlen(buf);
                break;
 
        case PW_TYPE_ABINARY:
 #ifdef WITH_ASCEND_BINARY
-
-               print_abinary(buf, sizeof(buf), vp, quote);
+               print_abinary(buf, sizeof(buf), (uint8_t const *) data->filter, len, quote);
                a = buf;
                len = strlen(buf);
                break;
@@ -436,7 +414,7 @@ size_t vp_prints_value(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t qu
                size_t max;
 
                /* Return the number of bytes we would have written */
-               len = (vp->length * 2) + 2;
+               len = (data_len * 2) + 2;
                if (freespace <= 1) {
                        return len;
                }
@@ -458,19 +436,17 @@ size_t vp_prints_value(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t qu
 
                /* Get maximum number of bytes we can encode given freespace */
                max = ((freespace % 2) ? freespace - 1 : freespace - 2) / 2;
-               fr_bin2hex(out, vp->vp_octets, (vp->length > max) ? max : vp->length);
-
-               return len;
+               fr_bin2hex(out, data->octets, (data_len > max) ? max : data_len);
        }
-               break;
+               return len;
 
        case PW_TYPE_IFID:
-               a = ifid_ntoa(buf, sizeof(buf), vp->vp_ifid);
+               a = ifid_ntoa(buf, sizeof(buf), data->ifid);
                len = strlen(buf);
                break;
 
        case PW_TYPE_IPV6_ADDR:
-               a = inet_ntop(AF_INET6, &vp->vp_ipv6addr, buf, sizeof(buf));
+               a = inet_ntop(AF_INET6, &data->ipv6addr, buf, sizeof(buf));
                len = strlen(buf);
                break;
 
@@ -481,7 +457,7 @@ size_t vp_prints_value(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t qu
                /*
                 *      Alignment issues.
                 */
-               memcpy(&addr, &(vp->vp_ipv6prefix[2]), sizeof(addr));
+               memcpy(&addr, &(data->ipv6prefix[2]), sizeof(addr));
 
                a = inet_ntop(AF_INET6, &addr, buf, sizeof(buf));
                if (a) {
@@ -489,7 +465,7 @@ size_t vp_prints_value(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t qu
 
                        len = strlen(buf);
                        p += len;
-                       len += snprintf(p, sizeof(buf) - len, "/%u", (unsigned int) vp->vp_ipv6prefix[1]);
+                       len += snprintf(p, sizeof(buf) - len, "/%u", (unsigned int) data->ipv6prefix[1]);
                }
        }
                break;
@@ -501,7 +477,7 @@ size_t vp_prints_value(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t qu
                /*
                 *      Alignment issues.
                 */
-               memcpy(&addr, &(vp->vp_ipv4prefix[2]), sizeof(addr));
+               memcpy(&addr, &(data->ipv4prefix[2]), sizeof(addr));
 
                a = inet_ntop(AF_INET, &addr, buf, sizeof(buf));
                if (a) {
@@ -509,16 +485,16 @@ size_t vp_prints_value(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t qu
 
                        len = strlen(buf);
                        p += len;
-                       len += snprintf(p, sizeof(buf) - len, "/%u", (unsigned int) (vp->vp_ipv4prefix[1] & 0x3f));
+                       len += snprintf(p, sizeof(buf) - len, "/%u", (unsigned int) (data->ipv4prefix[1] & 0x3f));
                }
        }
                break;
 
        case PW_TYPE_ETHERNET:
                return snprintf(out, outlen, "%02x:%02x:%02x:%02x:%02x:%02x",
-                               vp->vp_ether[0], vp->vp_ether[1],
-                               vp->vp_ether[2], vp->vp_ether[3],
-                               vp->vp_ether[4], vp->vp_ether[5]);
+                               data->ether[0], data->ether[1],
+                               data->ether[2], data->ether[3],
+                               data->ether[4], data->ether[5]);
 
        default:
                a = "UNKNOWN-TYPE";
@@ -531,6 +507,20 @@ size_t vp_prints_value(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t qu
        return len;     /* Return the number of bytes we would of written (for truncation detection) */
 }
 
+/** Print the value of an attribute to a string
+ *
+ * @param[out] out Where to write the string.
+ * @param[in] outlen Size of outlen (must be at least 3 bytes).
+ * @param[in] vp to print.
+ * @param[in] quote Char to add before and after printed value, if 0 no char will be added, if < 0 raw string will be
+ *     added.
+ * @return the length of data written to out, or a value >= outlen on truncation.
+ */
+size_t vp_prints_value(char *out, size_t outlen, VALUE_PAIR const *vp, int8_t quote)
+{
+       return vp_data_prints_value(out, outlen, vp->da, &vp->data, vp->length, quote);
+}
+
 char *vp_aprint_type(TALLOC_CTX *ctx, PW_TYPE type)
 {
        switch (type) {
@@ -887,7 +877,7 @@ char *vp_aprint_value(TALLOC_CTX *ctx, VALUE_PAIR const *vp)
 #ifdef WITH_ASCEND_BINARY
                p = talloc_array(ctx, char, 128);
                if (!p) return NULL;
-               print_abinary(p, 128, vp, 0);
+               print_abinary(p, 128, (uint8_t *) *vp->vp_filter, vp->length, 0);
                break;
 #else
                  /* FALL THROUGH */
index 322c392..99732cc 100644 (file)
@@ -712,118 +712,6 @@ VALUE_PAIR *paircopyvp(TALLOC_CTX *ctx, VALUE_PAIR const *vp)
        return n;
 }
 
-/** Copy data from one VP to another
- *
- * Allocate a new pair using da, and copy over the value from the specified
- * vp.
- *
- * @todo Should be able to do type conversions.
- *
- * @param[in] ctx for talloc
- * @param[in] da of new attribute to alloc.
- * @param[in] vp to copy data from.
- * @return the new valuepair.
- */
-VALUE_PAIR *paircopyvpdata(TALLOC_CTX *ctx, DICT_ATTR const *da, VALUE_PAIR const *vp)
-{
-       VALUE_PAIR *n;
-
-       if (!vp) return NULL;
-
-       VERIFY_VP(vp);
-
-       /*
-        *      The types have to be identical, OR the "from" VP has
-        *      to be octets.
-        */
-       if (da->type != vp->da->type) {
-               int length;
-               uint8_t *p;
-               VALUE_PAIR const **pvp;
-
-               if (vp->da->type == PW_TYPE_OCTETS) {
-                       /*
-                        *      Decode the octets buffer using the RADIUS decoder.
-                        */
-                       if (data2vp(ctx, NULL, NULL, NULL, da, vp->vp_octets, vp->length, vp->length, &n) < 0) {
-                               return NULL;
-                       }
-
-                       n->type = VT_DATA;
-                       return n;
-               }
-
-               /*
-                *      Else the destination type is octets
-                */
-               switch (vp->da->type) {
-               default:
-                       return NULL; /* can't do it */
-
-               case PW_TYPE_INTEGER:
-               case PW_TYPE_IPV4_ADDR:
-               case PW_TYPE_DATE:
-               case PW_TYPE_IFID:
-               case PW_TYPE_IPV6_ADDR:
-               case PW_TYPE_IPV6_PREFIX:
-               case PW_TYPE_BYTE:
-               case PW_TYPE_SHORT:
-               case PW_TYPE_ETHERNET:
-               case PW_TYPE_SIGNED:
-               case PW_TYPE_INTEGER64:
-               case PW_TYPE_IPV4_PREFIX:
-                       break;
-               }
-
-               n = pairalloc(ctx, da);
-               if (!n) return NULL;
-
-               p = talloc_array(n, uint8_t, dict_attr_sizes[vp->da->type][1] + 2);
-
-               pvp = &vp;
-               length = rad_vp2attr(NULL, NULL, NULL, pvp, p, dict_attr_sizes[vp->da->type][1]);
-               if (length < 0) {
-                       pairfree(&n);
-                       return NULL;
-               }
-
-               pairmemcpy(n, p + 2, length - 2);
-               talloc_free(p);
-               return n;
-       }
-
-       n = pairalloc(ctx, da);
-       if (!n) return NULL;
-
-       memcpy(n, vp, sizeof(*n));
-       n->da = da;
-
-       if (n->type == VT_XLAT) {
-               n->value.xlat = talloc_typed_strdup(n, n->value.xlat);
-       }
-
-       if (n->data.ptr) switch (n->da->type) {
-       case PW_TYPE_TLV:
-       case PW_TYPE_OCTETS:
-               n->vp_octets = talloc_memdup(n, vp->vp_octets, n->length);
-               talloc_set_type(n->vp_octets, uint8_t);
-               break;
-
-       case PW_TYPE_STRING:
-               n->vp_strvalue = talloc_memdup(n, vp->vp_strvalue, n->length + 1);      /* NULL byte */
-               talloc_set_type(n->vp_strvalue, char);
-               break;
-
-       default:
-               break;
-       }
-
-       n->next = NULL;
-
-       return n;
-}
-
-
 /** Copy a pairlist.
  *
  * Copy all pairs from 'from' regardless of tag, attribute or vendor.
@@ -2970,6 +2858,87 @@ void pairstrncpy(VALUE_PAIR *vp, char const *src, size_t len)
        pairtypeset(vp);
 }
 
+/** Copy data from one VP to another
+ *
+ * Allocate a new pair using da, and copy over the value from the specified vp.
+ *
+ * @todo Should be able to do type conversions.
+ *
+ * @param[in,out] vp to update.
+ * @param[in] da Type of data represented by data.
+ * @param[in] data to copy.
+ * @param[in] len of data to copy.
+ */
+int pairdatacpy(VALUE_PAIR *vp, DICT_ATTR const *da, value_data_t const *data, size_t len)
+{
+       void *old;
+       VERIFY_VP(vp);
+
+       /*
+        *      The da->types have to be identical, OR the "from" da->type has
+        *      to be octets.
+        */
+       if (vp->da->type != da->type) {
+               /*
+                *      Decode the octets buffer using the RADIUS decoder.
+                */
+               if (da->type == PW_TYPE_OCTETS) {
+                       if (data2vp(vp, NULL, NULL, NULL, vp->da, data->octets, len, len, &vp) < 0) return -1;
+                       vp->type = VT_DATA;
+                       return 0;
+               }
+
+               /*
+                *      Else if the destination da->type is octets
+                */
+               if (vp->da->type == PW_TYPE_OCTETS) {
+                       int ret;
+                       uint8_t *buff;
+                       VALUE_PAIR const *pvp = vp;
+
+                       buff = talloc_array(vp, uint8_t, dict_attr_sizes[da->type][1] + 2);
+
+                       ret = rad_vp2rfc(NULL, NULL, NULL, &pvp, buff, dict_attr_sizes[da->type][1]);
+                       if (ret < 0) return -1;
+
+                       pairmemcpy(vp, buff + 2, ret - 2);
+                       talloc_free(buff);
+
+                       return 0;
+               }
+
+               /*
+                *      Fixme...
+                */
+               fr_strerror_printf("Data conversion not supported");
+               return -1;
+       }
+
+       /*
+        *      Clear existing value if there is one
+        */
+       memcpy(&old, &vp->data.ptr, sizeof(old));
+       talloc_free(old);
+
+       switch (vp->da->type) {
+       case PW_TYPE_TLV:
+       case PW_TYPE_OCTETS:
+               pairmemcpy(vp, data->octets, len);
+               break;
+
+       case PW_TYPE_STRING:
+               pairstrncpy(vp, data->strvalue, len);
+               break;
+
+       default:
+               memcpy(&vp->data, data, sizeof(vp->data));
+               break;
+       }
+       vp->length = len;
+
+       return 0;
+}
+
 /** Print data into an "string" data type.
  *
  * @param[in,out] vp to update
index b8334a7..bcecfd9 100644 (file)
@@ -326,8 +326,7 @@ static VALUE_PAIR *get_cast_vp(REQUEST *request, value_pair_tmpl_t const *vpt, D
 
        if (vpt->type == VPT_TYPE_DATA) {
                rad_assert(vp->da->type == vpt->vpt_da->type);
-               memcpy(&vp->data, vpt->vpt_value, sizeof(vp->data));
-               vp->length = vpt->vpt_length;
+               pairdatacpy(vp, vpt->vpt_da, vpt->vpt_value, vpt->vpt_length);
                return vp;
        }
 
@@ -337,7 +336,7 @@ static VALUE_PAIR *get_cast_vp(REQUEST *request, value_pair_tmpl_t const *vpt, D
                return NULL;
        }
 
-       if ((pairparsevalue(vp, str, 0) < 0)) {
+       if (pairparsevalue(vp, str, 0) < 0) {
                talloc_free(str);
                pairfree(&vp);
                return NULL;
index d198bfb..ee6d431 100644 (file)
@@ -726,31 +726,8 @@ size_t radius_tmpl2str(char *buffer, size_t bufsize, value_pair_tmpl_t const *vp
 
        case VPT_TYPE_DATA:
                if (vpt->vpt_value) {
-                       VALUE_PAIR *vp;
-                       TALLOC_CTX *ctx;
-
-                       memcpy(&ctx, &vpt, sizeof(ctx)); /* hack */
-
-                       MEM(vp = pairalloc(ctx, vpt->vpt_da));
-                       memcpy(&vp->data, vpt->vpt_value, sizeof(vp->data));
-                       vp->length = vpt->vpt_length;
-
-                       q = vp_aprint_value(vp, vp);
-
-                       if ((vpt->vpt_da->type != PW_TYPE_STRING) &&
-                           (vpt->vpt_da->type != PW_TYPE_DATE)) {
-                               strlcpy(buffer, q, bufsize);
-                       } else {
-                               /*
-                                *      FIXME: properly escape the string...
-                                */
-                               snprintf(buffer, bufsize, "\"%s\"", q);
-                       }
-
-                       talloc_free(q);
-                       pairfree(&vp);
-                       return strlen(buffer);
-
+                       return vp_data_prints_value(buffer, bufsize, vpt->vpt_da,
+                                                   vpt->vpt_value, vpt->vpt_length, '"');
                } else {
                        *buffer = '\0';
                        return 0;
@@ -815,7 +792,6 @@ size_t radius_tmpl2str(char *buffer, size_t bufsize, value_pair_tmpl_t const *vp
        return q - buffer;
 }
 
-
 /**  Print a map to a string
  *
  * @param[out] buffer for the output string
index c89cf91..1ae0cf7 100644 (file)
@@ -1432,6 +1432,7 @@ int radius_map2vp(VALUE_PAIR **out, REQUEST *request, value_pair_map_t const *ma
        case VPT_TYPE_XLAT_STRUCT:
        case VPT_TYPE_LITERAL:
        case VPT_TYPE_DATA:
+       case VPT_TYPE_ATTR:
                vp = pairalloc(request, da);
                if (!vp) return -1;
                vp->op = map->op;
@@ -1549,13 +1550,9 @@ int radius_map2vp(VALUE_PAIR **out, REQUEST *request, value_pair_map_t const *ma
                }
 
                /*
-                *      Copy the data over verbatim, assuming it's
-                *      actually data.
+                *      Copy the data over verbatim
                 */
-               vp = paircopyvpdata(request, da, found);
-               if (!vp) {
-                       return -1;
-               }
+               if (pairdatacpy(vp, found->da, &found->data, found->length) < 0) return -1;
                vp->op = map->op;
 
                break;
@@ -1564,8 +1561,9 @@ int radius_map2vp(VALUE_PAIR **out, REQUEST *request, value_pair_map_t const *ma
                rad_assert(map->src && map->src->vpt_da);
                rad_assert(map->dst && map->dst->vpt_da);
                rad_assert(map->src->vpt_da->type == map->dst->vpt_da->type);
-               memcpy(&vp->data, map->src->vpt_value, sizeof(vp->data));
-               vp->length = map->src->vpt_length;
+
+               if (pairdatacpy(vp, map->src->vpt_da, map->src->vpt_value, map->src->vpt_length) < 0) goto error;
+               vp->op = map->op;
                break;
 
        /*