From: Alan T. DeKok Date: Fri, 15 Apr 2016 14:54:02 +0000 (-0400) Subject: Ensure da is parented from VP, not ctx X-Git-Tag: release_3_0_12~160 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=76bd462f8dac7abdf203ba6549e0dc2bb0d4bc18;p=thirdparty%2Ffreeradius-server.git Ensure da is parented from VP, not ctx --- diff --git a/src/lib/pair.c b/src/lib/pair.c index f8631ef8b0f..7deccdbb804 100644 --- a/src/lib/pair.c +++ b/src/lib/pair.c @@ -1288,37 +1288,6 @@ finish: } -static VALUE_PAIR *fr_pair_from_octets(TALLOC_CTX *ctx, VALUE_PAIR *vp, DICT_ATTR const *da) -{ - ssize_t len; - VALUE_PAIR *vp2; - - len = data2vp(ctx, NULL, NULL, NULL, da, - vp->vp_octets, vp->vp_length, vp->vp_length, - &vp2); - if (len <= 0) return vp; /* it's really unknown */ - - if (vp2->da->flags.is_unknown) { - fr_pair_list_free(&vp2); - return vp; - } - - /* - * Didn't parse all of it. Return the "unknown" one. - * - * FIXME: it COULD have parsed 2 attributes and - * then not the third, so returning 2 "knowns" - * and 1 "unknown" is likely preferable. - */ - if ((size_t) len < vp->vp_length) { - fr_pair_list_free(&vp2); - return vp; - } - - fr_pair_list_free(&vp); - return vp2; -} - /** Create a valuepair from an ASCII attribute and value * * Where the attribute name is in the form: @@ -1337,44 +1306,47 @@ static VALUE_PAIR *fr_pair_make_unknown(TALLOC_CTX *ctx, char const *attribute, char const *value, FR_TOKEN op) { - VALUE_PAIR *vp; + VALUE_PAIR *vp, *vp2; DICT_ATTR const *da; uint8_t *data; size_t size; + ssize_t len; + + vp = fr_pair_alloc(ctx); + if (!vp) return NULL; - da = dict_unknown_afrom_str(ctx, attribute); - if (!da) return NULL; + da = dict_unknown_afrom_str(vp, attribute); + if (!da) { + talloc_free(vp); + return NULL; + } + + /* + * No value. Nothing more to do. + */ + if (!value) return vp; /* * Unknown attributes MUST be of type 'octets' */ - if (value && (strncasecmp(value, "0x", 2) != 0)) { + if (strncasecmp(value, "0x", 2) != 0) { fr_strerror_printf("Unknown attribute \"%s\" requires a hex " "string, not \"%s\"", attribute, value); - - dict_attr_free(&da); + talloc_free(vp); return NULL; } /* - * We've now parsed the attribute properly, Let's create - * it. This next stop also looks the attribute up in the - * dictionary, and creates the appropriate type for it. + * Convert the hex data to binary. */ - vp = fr_pair_afrom_da(ctx, da); - if (!vp) { - dict_attr_free(&da); - return NULL; - } - - vp->op = (op == 0) ? T_OP_EQ : op; - - if (!value) return vp; - size = strlen(value + 2); + vp->vp_length = size >> 1; - data = talloc_array(vp, uint8_t, vp->vp_length); + vp->vp_octets = data = talloc_array(vp, uint8_t, vp->vp_length); + vp->type = VT_DATA; + vp->op = (op == 0) ? T_OP_EQ : op; + vp->da = da; if (fr_hex2bin(data, vp->vp_length, value + 2, size) != vp->vp_length) { fr_strerror_printf("Invalid hex string"); @@ -1382,21 +1354,43 @@ static VALUE_PAIR *fr_pair_make_unknown(TALLOC_CTX *ctx, return NULL; } - vp->vp_octets = data; - vp->type = VT_DATA; + /* + * It's still unknown, return it as-is. + */ + da = dict_attrbyvalue(vp->da->attr, vp->da->vendor); + if (!da) return vp; /* - * We were asked to parse "Attr-26 = 0xabcdef" + * It MIGHT be known. See if we can decode the raw data + * into a valid attribute. + */ + len = data2vp(ctx, NULL, NULL, NULL, da, + vp->vp_octets, vp->vp_length, vp->vp_length, + &vp2); + if (len <= 0) return vp; + + /* + * It's still unknown. Return the original VP. + */ + if (vp2->da->flags.is_unknown) { + fr_pair_list_free(&vp2); + return vp; + } + + /* + * Didn't parse all of it. Return the "unknown" one. * - * If we have a dictionary entry for it, try to - * parse it as raw data. + * FIXME: it COULD have parsed 2 attributes and + * then not the third, so returning 2 "knowns" + * and 1 "unknown" is likely preferable. */ - da = dict_attrbyvalue(vp->da->attr, vp->da->vendor); - if (da) { - return fr_pair_from_octets(ctx, vp, da); + if ((size_t) len < vp->vp_length) { + fr_pair_list_free(&vp2); + return vp; } - return vp; + fr_pair_list_free(&vp); + return vp2; }