From: Alan T. DeKok Date: Sat, 6 Apr 2024 15:10:38 +0000 (-0400) Subject: allow relative references in "clone=" X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c9a796fda338af3775577177a13b85e29b46cbd0;p=thirdparty%2Ffreeradius-server.git allow relative references in "clone=" remove code which allowed clone to reference other protocols. The "reference protocol" code was changed during the refactoring to support ATTRIBUTE ... group ref=..DHCPv4 which now makes this code invalid. So we fix up this code to work, and (at least temporarily) remove the ability to reference other protocols. Now that the framework supports relative references, it should be fairly simply to re-add protocol references as a separate commit. --- diff --git a/share/dictionary/radius/dictionary.wimax b/share/dictionary/radius/dictionary.wimax index 1b70ae810de..9f87656478e 100644 --- a/share/dictionary/radius/dictionary.wimax +++ b/share/dictionary/radius/dictionary.wimax @@ -217,7 +217,7 @@ VALUE Assigned Src-Assigned 1 VALUE Assigned Dst-Assigned 2 VALUE Assigned Src-Dst-Assigned 3 -ATTRIBUTE Dst-Spec 28.11.6 tlv clone=Vendor-Specific.WiMAX.Packet-Flow-Descriptor.Classifier.Src-Spec +ATTRIBUTE Dst-Spec 28.11.6 tlv clone=.Src-Spec ATTRIBUTE IP-TOS/DSCP-Range-and-Mask 28.11.7 octets ATTRIBUTE VLAN-ID 28.11.8 integer @@ -475,12 +475,12 @@ ATTRIBUTE Priority .2 byte ATTRIBUTE Protocol .3 byte ATTRIBUTE Direction .4 byte -ATTRIBUTE Src-Spec 84.9.5 tlv clone=Vendor-Specific.WiMAX.Packet-Flow-Descriptor.Classifier.Src-Spec +ATTRIBUTE Src-Spec 84.9.5 tlv clone=...Packet-Flow-Descriptor.Classifier.Src-Spec # Add these two, also ATTRIBUTE MAC-Address .8 ether ATTRIBUTE MAC-Mask .9 ether -ATTRIBUTE Dest-Spec 84.9.6 tlv clone=Vendor-Specific.WiMAX.Packet-Flow-Descriptor-v2.Classifier.Src-Spec +ATTRIBUTE Dest-Spec 84.9.6 tlv clone=.Src-Spec ATTRIBUTE Classifier-IP-ToS-DSCP 84.9.7 byte diff --git a/src/lib/util/dict_fixup.c b/src/lib/util/dict_fixup.c index c88e559812a..32532812ba6 100644 --- a/src/lib/util/dict_fixup.c +++ b/src/lib/util/dict_fixup.c @@ -416,36 +416,59 @@ int dict_fixup_clone(dict_fixup_ctx_t *fctx, char const *filename, int line, */ static inline CC_HINT(always_inline) int dict_fixup_clone_apply(UNUSED dict_fixup_ctx_t *fctx, dict_fixup_clone_t *fixup) { - fr_dict_attr_t const *da; + fr_dict_attr_t const *da, *root; fr_dict_attr_t *cloned; fr_dict_t *dict = fr_dict_unconst(fr_dict_by_da(fixup->da)); + char const *ref = fixup->ref; /* - * Find the reference + * Allow relative attribute references. */ - da = fr_dict_attr_by_oid(NULL, fr_dict_root(dict), fixup->ref); - if (da) { - /* - * The referenced DA is higher than the one we're - * creating. Ensure it's not a parent. - */ - if (da->depth < fixup->da->depth) { - fr_dict_attr_t const *parent; - - for (parent = fixup->da->parent; !parent->flags.is_root; parent = parent->parent) { - if (parent == da) { - fr_strerror_printf("References MUST NOT refer to a parent attribute %s at %s[%d]", - parent->name, fr_cwd_strip(fixup->common.filename), fixup->common.line); - return -1; - } + if (ref[0] == '.') { + root = fixup->da->parent; + ref++; + + while (ref[0] == '.') { + /* + * @todo - allow references to other protocols. + */ + if (root->flags.is_root) { + fr_strerror_printf("Too many '.' in clone=%s at %s[%d]", + fixup->ref, fr_cwd_strip(fixup->common.filename), fixup->common.line); + return -1; } + + root = root->parent; + ref++; } } else { - /* - * @todo - cloning foreign attributes is not a well-tested path. - */ - da = dict_protocol_reference(&dict, fixup->ref, fixup->common.filename, fixup->common.line); - if (!da) return -1; + root = fr_dict_root(dict); + } + + /* + * Find the reference + */ + da = fr_dict_attr_by_oid(NULL, root, ref); + if (!da) { + fr_strerror_printf("Unknown attribute reference in clone=%s at parent %s %s[%d]", + fixup->ref, root->name, fr_cwd_strip(fixup->common.filename), fixup->common.line); + return -1; + } + + /* + * The referenced DA is higher than the one we're + * creating. Ensure it's not a parent. + */ + if (da->depth < fixup->da->depth) { + fr_dict_attr_t const *parent; + + for (parent = fixup->da->parent; !parent->flags.is_root; parent = parent->parent) { + if (parent == da) { + fr_strerror_printf("References MUST NOT refer to a parent attribute %s at %s[%d]", + parent->name, fr_cwd_strip(fixup->common.filename), fixup->common.line); + return -1; + } + } } if (fr_dict_attr_ref(da)) {