]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
only groups can use "ref=".
authorAlan T. DeKok <aland@freeradius.org>
Thu, 11 Aug 2022 15:31:11 +0000 (11:31 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 12 Aug 2022 14:40:22 +0000 (10:40 -0400)
Perhaps when other things get fixed, we can have TLVs use
"ref=" instead of "clone="

src/lib/util/dict_tokenize.c
src/lib/util/dict_util.c

index c9223402fb599bbae961e0bf7e7f814bfa275369..7fb0fdb6d6d1539182f9ce2b929a24dd4c4ad0fe 100644 (file)
@@ -888,6 +888,9 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in
                        goto check;
                }
 
+               /*
+                *      Else we find the reference.
+                */
                da = fr_dict_attr_by_oid(NULL, parent, ref);
                if (da) {
                        dict = ctx->dict;
@@ -900,7 +903,7 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in
                 *      dictionary.
                 */
                p = strchr(ref, '.');
-               if (!p) goto save;
+               if (!p) goto fixup;
 
                /*
                 *      Get / skip protocol name.
@@ -915,10 +918,13 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in
                 *      No known dictionary, so we're asked to just
                 *      use the whole string.  Which we did above.  So
                 *      either it's a bad ref, OR it's a ref to a
-                *      dictionary which doesn't exist.
+                *      dictionary which hasn't yet been loaded.
+                *
+                *      Save the fixup for later, when we've hopefully
+                *      loaded the dictionary.
                 */
                if (slen == 0) {
-               save:
+               fixup:
                        if (dict_fixup_group(&ctx->fixup, CURRENT_FRAME(ctx)->filename, CURRENT_FRAME(ctx)->line,
                                             self, ref, talloc_array_length(ref) - 1) < 0) {
                        oom:
index 701036b9e625edeb8c761ef232b7f2b7d0061ade..fd3c5f553a8c41090ad577fb689dffce60efd378 100644 (file)
@@ -563,13 +563,23 @@ int dict_attr_init(fr_dict_attr_t **da_p,
        switch (type) {
        case FR_TYPE_STRUCTURAL:
        structural:
-               if (dict_attr_ref_init(da_p, NULL) < 0) return -1;      /* Just allocate space */
-
                /*
-                *      Groups don't have children or
-                *      namespaces.
+                *      Groups don't have children or namespaces.  But
+                *      they always have refs.  Either to the root of
+                *      the current dictionary, or to another dictionary,
+                *      via its top-level TLV.
+                *
+                *      Note that when multiple TLVs have the same
+                *      children, the dictionary has to use "clone="
+                *      instead of "ref=".  That's because the
+                *      children of the TLVs all require the correct
+                *      parentage.  Perhaps that can be changed when
+                *      the encoders / decoders are updated.  It would be good to just reference the DAs instead of cloning an entire subtree.
                 */
-               if (type == FR_TYPE_GROUP) break;
+               if (type == FR_TYPE_GROUP) {
+                       if (dict_attr_ref_init(da_p, NULL) < 0) return -1;
+                       break;
+               }
 
                if (dict_attr_children_init(da_p) < 0) return -1;
                if (dict_attr_namespace_init(da_p) < 0) return -1;      /* Needed for all TLV style attributes */