From: Arran Cudbard-Bell Date: Thu, 5 Oct 2017 12:35:27 +0000 (+0800) Subject: Move dict xlats into rlm_dict X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5d3e75877f2d2743533f930a87f92a246c78d8e5;p=thirdparty%2Ffreeradius-server.git Move dict xlats into rlm_dict Remove vendor specification from fr_dict_attr_by_oid as vendors are structural attributes now and it's not required --- diff --git a/src/include/dict.h b/src/include/dict.h index 067be899fbd..e7b3cbf7ef8 100644 --- a/src/include/dict.h +++ b/src/include/dict.h @@ -224,7 +224,7 @@ fr_dict_attr_t const *fr_dict_parent_common(fr_dict_attr_t const *a, fr_dict_att int fr_dict_oid_component(unsigned int *out, char const **oid); ssize_t fr_dict_attr_by_oid(fr_dict_t *dict, fr_dict_attr_t const **parent, - unsigned int *vendor, unsigned int *attr, char const *oid); + unsigned int *attr, char const *oid); /* * Lookup diff --git a/src/lib/util/dict.c b/src/lib/util/dict.c index a928f233062..c52f4b5069e 100644 --- a/src/lib/util/dict.c +++ b/src/lib/util/dict.c @@ -1783,16 +1783,13 @@ static int dict_read_process_attribute(fr_dict_t *dict, fr_dict_attr_t const *pa ssize_t slen; oid = true; - vendor = block_vendor; - slen = fr_dict_attr_by_oid(dict, &parent, &vendor, &attr, argv[1]); + slen = fr_dict_attr_by_oid(dict, &parent, &attr, argv[1]); if (slen <= 0) { return -1; } if (!fr_cond_assert(parent)) return -1; /* Should have provided us with a parent */ - - block_vendor = vendor; /* Weird case where we're processing 26.. */ } /* @@ -3699,7 +3696,6 @@ int fr_dict_oid_component(unsigned int *out, char const **oid) * @param[in] dict of protocol context we're operating in. If NULL the internal * dictionary will be used. * @param[out] attr Number we parsed. - * @param[in,out] vendor number of attribute. * @param[in,out] parent attribute (or root of dictionary). Will be updated to the parent * directly beneath the leaf. * @param[in] oid string to parse. @@ -3707,8 +3703,7 @@ int fr_dict_oid_component(unsigned int *out, char const **oid) * - > 0 on success (number of bytes parsed). * - <= 0 on parse error (negative offset of parse error). */ -ssize_t fr_dict_attr_by_oid(fr_dict_t *dict, fr_dict_attr_t const **parent, - unsigned int *vendor, unsigned int *attr, char const *oid) +ssize_t fr_dict_attr_by_oid(fr_dict_t *dict, fr_dict_attr_t const **parent, unsigned int *attr, char const *oid) { char const *p = oid; unsigned int num = 0; @@ -3728,49 +3723,6 @@ ssize_t fr_dict_attr_by_oid(fr_dict_t *dict, fr_dict_attr_t const **parent, */ *attr = num; - /* - * Look for 26.VID.x.y - * - * This allows us to specify a VSA if our parent is the root - * of the dictionary, and we're operating outside of a vendor - * block. - * - * The additional code is because we need at least three components - * the VSA attribute (26), the vendor ID, and actual attribute. - */ - if (((*parent)->flags.is_root) && !*vendor && (num == FR_VENDOR_SPECIFIC)) { - fr_dict_vendor_t const *dv; - - if (p[0] == '\0') { - fr_strerror_printf("Vendor attribute must specify a VID"); - return oid - p; - } - p++; - - if (fr_dict_oid_component(&num, &p) < 0) return oid - p; - if (p[0] == '\0') { - fr_strerror_printf("Vendor attribute must specify a child"); - return oid - p; - } - p++; - - dv = fr_dict_vendor_by_num(dict, num); - if (!dv) { - fr_strerror_printf("Unknown vendor '%u' ", num); - return oid - p; - } - *vendor = dv->vendorpec; /* Record vendor number */ - - /* - * Recurse to get the attribute. - */ - slen = fr_dict_attr_by_oid(dict, parent, vendor, attr, p); - if (slen <= 0) return slen - (p - oid); - - slen += p - oid; - return slen; - } - switch ((*parent)->type) { case FR_TYPE_STRUCTURAL: break; @@ -3786,7 +3738,7 @@ ssize_t fr_dict_attr_by_oid(fr_dict_t *dict, fr_dict_attr_t const **parent, * * @fixme: find the TLV parent, and check it's size */ - if (((*parent)->type != FR_TYPE_VENDOR) && !(*parent)->flags.is_root && + if (((*parent)->type != FR_TYPE_VENDOR) && ((*parent)->type != FR_TYPE_VSA) && !(*parent)->flags.is_root && (num > UINT8_MAX)) { fr_strerror_printf("TLV attributes must be between 0..255 inclusive"); return 0; @@ -3815,7 +3767,7 @@ ssize_t fr_dict_attr_by_oid(fr_dict_t *dict, fr_dict_attr_t const **parent, */ *parent = child; - slen = fr_dict_attr_by_oid(dict, parent, vendor, attr, p); + slen = fr_dict_attr_by_oid(dict, parent, attr, p); if (slen <= 0) return slen - (p - oid); return slen + (p - oid); } diff --git a/src/main/radsnmp.c b/src/main/radsnmp.c index 51487f25eb7..8c0cf07bb48 100644 --- a/src/main/radsnmp.c +++ b/src/main/radsnmp.c @@ -207,7 +207,7 @@ static ssize_t radsnmp_pair_from_oid(TALLOC_CTX *ctx, radsnmp_conf_t *conf, vp_c for (;;) { unsigned int num = 0; - slen = fr_dict_attr_by_oid(conf->dict, &parent, NULL, &attr, p); + slen = fr_dict_attr_by_oid(conf->dict, &parent, &attr, p); if (slen > 0) break; p += -(slen); diff --git a/src/main/xlat_func.c b/src/main/xlat_func.c index ff96b0df393..9c7f06a619f 100644 --- a/src/main/xlat_func.c +++ b/src/main/xlat_func.c @@ -234,76 +234,6 @@ static ssize_t xlat_tag(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, return snprintf(*out, outlen, "%u", vp->tag); } -/** Return the vendor of an attribute reference - * - */ -static ssize_t xlat_vendor(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, - UNUSED void const *mod_inst, UNUSED void const *xlat_inst, - REQUEST *request, char const *fmt) -{ - VALUE_PAIR *vp; - fr_dict_vendor_t const *vendor; - - while (isspace((int) *fmt)) fmt++; - - if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0; - - vendor = fr_dict_vendor_by_num(NULL, vp->da->vendor); - if (!vendor) return 0; - strlcpy(*out, vendor->name, outlen); - - return vendor->length; -} - -/** Return the vendor number of an attribute reference - * - */ -static ssize_t xlat_vendor_num(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, - UNUSED void const *mod_inst, UNUSED void const *xlat_inst, - REQUEST *request, char const *fmt) -{ - VALUE_PAIR *vp; - - while (isspace((int) *fmt)) fmt++; - - if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0; - - return snprintf(*out, outlen, "%i", vp->da->vendor); -} - -/** Return the attribute name of an attribute reference - * - */ -static ssize_t xlat_attr(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, - UNUSED void const *mod_inst, UNUSED void const *xlat_inst, - REQUEST *request, char const *fmt) -{ - VALUE_PAIR *vp; - - while (isspace((int) *fmt)) fmt++; - - if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0; - strlcpy(*out, vp->da->name, outlen); - - return strlen(vp->da->name); -} - -/** Return the attribute number of an attribute reference - * - */ -static ssize_t xlat_attr_num(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, - UNUSED void const *mod_inst, UNUSED void const *xlat_inst, - REQUEST *request, char const *fmt) -{ - VALUE_PAIR *vp; - - while (isspace((int) *fmt)) fmt++; - - if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0; - - return snprintf(*out, outlen, "%i", vp->da->attr); -} - /** Print out attribute info * * Prints out all instances of a current attribute, or all attributes in a list. @@ -738,10 +668,6 @@ int xlat_register(void *mod_inst, char const *name, XLAT_REGISTER(length); XLAT_REGISTER(hex); XLAT_REGISTER(tag); - XLAT_REGISTER(vendor); - XLAT_REGISTER(vendor_num); - XLAT_REGISTER(attr); - XLAT_REGISTER(attr_num); XLAT_REGISTER(string); XLAT_REGISTER(xlat); XLAT_REGISTER(map); diff --git a/src/modules/rlm_dict/rlm_dict.c b/src/modules/rlm_dict/rlm_dict.c index 00b31f13c75..7194f5186d8 100644 --- a/src/modules/rlm_dict/rlm_dict.c +++ b/src/modules/rlm_dict/rlm_dict.c @@ -60,6 +60,104 @@ static ssize_t xlat_dict_attr_by_num(TALLOC_CTX *ctx, char **out, UNUSED size_t return talloc_array_length(*out) - 1; } +/* + * Xlat for %{attr_by_oid:} + */ +static ssize_t xlat_dict_attr_by_oid(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen, + UNUSED void const *mod_inst, UNUSED void const *xlat_inst, + REQUEST *request, char const *fmt) +{ + unsigned int attr = 0; + fr_dict_attr_t const *parent = fr_dict_root(fr_dict_internal); + fr_dict_attr_t const *da; + ssize_t ret; + + ret = fr_dict_attr_by_oid(NULL, &parent, &attr, fmt); + if (ret <= 0) { + REMARKER(fmt, -(ret), fr_strerror()); + return ret; + } + + da = fr_dict_attr_child_by_num(parent, attr); + + *out = talloc_typed_strdup(ctx, da->name); + return talloc_array_length(*out) - 1; +} + + +/** Return the vendor of an attribute reference + * + */ +static ssize_t xlat_vendor(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen, + UNUSED void const *mod_inst, UNUSED void const *xlat_inst, + REQUEST *request, char const *fmt) +{ + VALUE_PAIR *vp; + fr_dict_vendor_t const *vendor; + + while (isspace((int) *fmt)) fmt++; + + if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0; + + vendor = fr_dict_vendor_by_num(NULL, vp->da->vendor); + if (!vendor) return 0; + + *out = talloc_typed_strdup(ctx, vendor->name); + return talloc_array_length(*out) - 1; +} + +/** Return the vendor number of an attribute reference + * + */ +static ssize_t xlat_vendor_num(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen, + UNUSED void const *mod_inst, UNUSED void const *xlat_inst, + REQUEST *request, char const *fmt) +{ + VALUE_PAIR *vp; + + while (isspace((int) *fmt)) fmt++; + + if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0; + + *out = talloc_asprintf(ctx, "%i", vp->da->vendor); + return talloc_array_length(*out) - 1; +} + +/** Return the attribute name of an attribute reference + * + */ +static ssize_t xlat_attr(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen, + UNUSED void const *mod_inst, UNUSED void const *xlat_inst, + REQUEST *request, char const *fmt) +{ + VALUE_PAIR *vp; + + while (isspace((int) *fmt)) fmt++; + + if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0; + strlcpy(*out, vp->da->name, outlen); + + *out = talloc_typed_strdup(ctx, vp->da->name); + return talloc_array_length(*out) - 1; +} + +/** Return the attribute number of an attribute reference + * + */ +static ssize_t xlat_attr_num(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen, + UNUSED void const *mod_inst, UNUSED void const *xlat_inst, + REQUEST *request, char const *fmt) +{ + VALUE_PAIR *vp; + + while (isspace((int) *fmt)) fmt++; + + if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0; + + *out = talloc_asprintf(ctx, "%i", vp->da->attr); + return talloc_array_length(*out) - 1; +} + /* * Do any per-module initialization that is separate to each * configured instance of the module. e.g. set up connections @@ -73,6 +171,11 @@ static ssize_t xlat_dict_attr_by_num(TALLOC_CTX *ctx, char **out, UNUSED size_t static int mod_bootstrap(void *instance, UNUSED CONF_SECTION *conf) { xlat_register(instance, "attr_by_num", xlat_dict_attr_by_num, NULL, NULL, 0, 0, true); + xlat_register(instance, "attr_by_oid", xlat_dict_attr_by_oid, NULL, NULL, 0, 0, true); + xlat_register(instance, "vendor", xlat_vendor, NULL, NULL, 0, 0, true); + xlat_register(instance, "vendor_num", xlat_vendor_num, NULL, NULL, 0, 0, true); + xlat_register(instance, "attr", xlat_attr, NULL, NULL, 0, 0, true); + xlat_register(instance, "attr_num", xlat_attr_num, NULL, NULL, 0, 0, true); return 0; } diff --git a/src/tests/keywords/xlat-attr b/src/tests/keywords/xlat-attr deleted file mode 100644 index 5174dc7a6ee..00000000000 --- a/src/tests/keywords/xlat-attr +++ /dev/null @@ -1,47 +0,0 @@ -# -# PRE: update -# -# Check attribute info xlats work correctly -# -update { - control:Cleartext-Password := 'hello' -} - -update request { - Reply-Message := 'foo' - FreeRADIUS-Proxied-To := 127.0.0.1 -} - -if ("%{attr:&FreeRADIUS-Proxied-To}" != 'FreeRADIUS-Proxied-To') { - test_fail -} - -if ("%{attr_num:&FreeRADIUS-Proxied-To}" != 1) { - test_fail -} - -if ("%{vendor:&FreeRADIUS-Proxied-To}" != 'FreeRADIUS') { - test_fail -} - -if ("%{vendor_num:&FreeRADIUS-Proxied-To}" != 11344) { - test_fail -} - -if ("%{attr:&Reply-Message}" != 'Reply-Message') { - test_fail -} - -if ("%{attr_num:&Reply-Message}" != 18) { - test_fail -} - -if ("%{vendor:&Reply-Message}" != '') { - test_fail -} - -if ("%{vendor_num:&Reply-Message}" != 0) { - test_fail -} - -success diff --git a/src/tests/modules/dict/map.unlang b/src/tests/modules/dict/map.unlang index 288dda01781..76bc2330ec1 100644 --- a/src/tests/modules/dict/map.unlang +++ b/src/tests/modules/dict/map.unlang @@ -1,3 +1,8 @@ +update request { + FreeRADIUS-Proxied-To := 127.0.0.1 + Reply-Message := 'foo' +} + if ("%{attr_by_num:1}" == 'User-Name') { test_pass } @@ -5,3 +10,90 @@ else { test_fail } +if ("%{attr_by_oid:1}" == 'User-Name') { + test_pass +} +else { + test_fail +} + +# Should fail +if ("%{attr_by_oid:26}" == 'Vendor-Specific') { + test_pass +} +else { + test_fail +} + +# Should fail +if ("%{attr_by_oid:26.11344}" == 'FreeRADIUS') { + test_pass +} +else { + test_fail +} + +if ("%{attr_by_oid:26.11344.1}" == 'FreeRADIUS-Proxied-To') { + test_pass +} +else { + test_fail +} + +if ("%{attr:&FreeRADIUS-Proxied-To}" == 'FreeRADIUS-Proxied-To') { + test_pass +} +else { + test_fail +} + +if ("%{attr_num:&FreeRADIUS-Proxied-To}" == 1) { + test_pass +} +else { + test_fail +} + +if ("%{vendor:&FreeRADIUS-Proxied-To}" == 'FreeRADIUS') { + test_pass +} +else { + test_fail +} + +if ("%{vendor_num:&FreeRADIUS-Proxied-To}" == 11344) { + test_pass +} +else { + test_fail +} + +if ("%{attr:&Reply-Message}" == 'Reply-Message') { + test_pass +} +else { + test_fail +} + +if ("%{attr_num:&Reply-Message}" == 18) { + test_pass +} +else { + test_fail +} + +if ("%{vendor:&Reply-Message}" == '') { + test_pass +} +else { + test_fail +} + +if ("%{vendor_num:&Reply-Message}" == 0) { + test_pass +} +else { + test_fail +} + +