Remove vendor specification from fr_dict_attr_by_oid as vendors are structural attributes now and it's not required
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
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.<vid>.<tlv> */
}
/*
* @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.
* - > 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;
*/
*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;
*
* @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;
*/
*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);
}
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);
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.
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);
return talloc_array_length(*out) - 1;
}
+/*
+ * Xlat for %{attr_by_oid:<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
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;
}
+++ /dev/null
-#
-# 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
+update request {
+ FreeRADIUS-Proxied-To := 127.0.0.1
+ Reply-Message := 'foo'
+}
+
if ("%{attr_by_num:1}" == 'User-Name') {
test_pass
}
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
+}
+
+