]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
allow relative attributes after DEFINEs
authorAlan T. DeKok <aland@freeradius.org>
Tue, 17 Oct 2023 12:15:18 +0000 (08:15 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 17 Oct 2023 13:00:07 +0000 (09:00 -0400)
src/lib/util/dict_tokenize.c
src/lib/util/dict_util.c

index 619692218088e3d0acf28d16a5dee3224724e141..f197f15d36dd99482f2829b0835e4650f85701d7 100644 (file)
@@ -899,7 +899,7 @@ static int dict_process_ref(dict_tokenize_ctx_t *ctx, fr_dict_attr_t const *pare
 static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, int argc,
                                       fr_dict_attr_flags_t const *base_flags)
 {
-       bool                    set_relative_attr = true;
+       bool                    set_relative_attr;
 
        ssize_t                 slen;
        unsigned int            attr;
@@ -931,11 +931,6 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in
                return -1;
        }
 
-       /*
-        *      Relative OIDs apply ONLY to attributes of type 'tlv'.
-        */
-       if (type != FR_TYPE_TLV) set_relative_attr = false;
-
        /*
         *      A non-relative ATTRIBUTE definition means that it is
         *      in the context of the previous BEGIN-FOO.  So we
@@ -959,6 +954,11 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in
                        if (slen <= 0) return -1;
                }
 
+               /*
+                *      We allow relative attributes only for TLVs.
+                */
+               set_relative_attr = (type == FR_TYPE_TLV);
+
        } else {
                if (!ctx->relative_attr) {
                        fr_strerror_const("Unknown parent for partial OID");
@@ -966,10 +966,11 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in
                }
 
                parent = ctx->relative_attr;
-               set_relative_attr = false;
 
                slen = fr_dict_attr_by_oid_legacy(ctx->dict, &parent, &attr, argv[1]);
                if (slen <= 0) return -1;
+
+               set_relative_attr = false;
        }
 
        if (!fr_cond_assert(parent)) return -1; /* Should have provided us with a parent */
@@ -1029,18 +1030,9 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in
         */
        da = dict_attr_child_by_num(parent, attr);
        if (!da) {
-               fr_strerror_printf("Failed to find attribute '%s' we just added.", argv[0]);
-               return -1;
-       }
-
-#ifndef NDEBUG
-       if (!dict_attr_by_name(NULL, parent, argv[0])) {
-               fr_strerror_printf("Failed to find attribute '%s' we just added.", argv[0]);
+               fr_strerror_printf("Failed to find attribute number %u we just added to parent %s.", attr, parent->name);
                return -1;
        }
-#endif
-
-       if (set_relative_attr) ctx->relative_attr = da;
 
        if (dict_process_ref(ctx, parent, da, ref) < 0) return -1;
 
@@ -1055,6 +1047,8 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in
                memcpy(&ctx->value_attr, &da, sizeof(da));
        }
 
+       if (set_relative_attr) ctx->relative_attr = da;
+
        return 0;
 }
 
@@ -1145,7 +1139,7 @@ static int dict_read_process_define(dict_tokenize_ctx_t *ctx, char **argv, int a
 
        da = dict_attr_by_name(NULL, parent, argv[0]);
        if (!da) {
-               fr_strerror_printf("Failed to find attribute '%s' we just added.", argv[0]);
+               fr_strerror_printf("Failed to find attribute '%s' we just added to parent %s", argv[0], parent->name);
                return -1;
        }
 
@@ -1162,6 +1156,12 @@ static int dict_read_process_define(dict_tokenize_ctx_t *ctx, char **argv, int a
                memcpy(&ctx->value_attr, &da, sizeof(da));
        }
 
+       if (type == FR_TYPE_TLV) {
+               ctx->relative_attr = da;
+       } else {
+               ctx->relative_attr = NULL;
+       }
+
        return 0;
 }
 
@@ -1248,16 +1248,9 @@ static int dict_read_process_enum(dict_tokenize_ctx_t *ctx, char **argv, int arg
         */
        da = dict_attr_child_by_num(parent, attr);
        if (!da) {
-               fr_strerror_printf("Failed to find attribute '%s' we just added.", argv[0]);
-               return -1;
-       }
-
-#ifndef NDEBUG
-       if (!dict_attr_by_name(NULL, parent, argv[0])) {
-               fr_strerror_printf("Failed to find attribute '%s' we just added.", argv[0]);
+               fr_strerror_printf("Failed to find attribute number %u we just added to parent %s", attr, parent->name);
                return -1;
        }
-#endif
 
        memcpy(&ctx->value_attr, &da, sizeof(da));
 
index c775a5bd45ad2dcb7cb64234d5e7e682409cd2d3..e760f9a7af043a2b97476484de8baf5056701574 100644 (file)
@@ -1080,7 +1080,10 @@ int dict_attr_child_add(fr_dict_attr_t *parent, fr_dict_attr_t *child)
         *      The parent has children by name only, not by number.  Don't even bother trying to track
         *      numbers, except for VENDOR in root, and MEMBER of a struct.
         */
-       if (!parent->flags.is_root && parent->flags.name_only && (parent->type != FR_TYPE_STRUCT)) return 0;
+       if (!parent->flags.is_root && parent->flags.name_only &&
+           (parent->type != FR_TYPE_STRUCT) && (parent->type != FR_TYPE_TLV)) {
+               return 0;
+       }
 
        /*
         *      We only allocate the pointer array *if* the parent has children.
@@ -1269,6 +1272,9 @@ int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent,
        fr_dict_attr_t const    *old;
        fr_dict_attr_flags_t    our_flags = *flags;
        bool                    self_allocated = false;
+#ifndef NDEBUG
+       fr_dict_attr_t          const *da;
+#endif
 
        if (unlikely(dict->read_only)) {
                fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root(dict)->name);
@@ -1331,6 +1337,22 @@ int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent,
         */
        if (dict_attr_child_add(UNCONST(fr_dict_attr_t *, parent), n) < 0) goto error;
 
+#ifndef NDEBUG
+       /*
+        *      Check if we added the attribute
+        */
+       da = dict_attr_child_by_num(parent, n->attr);
+       if (!da) {
+               fr_strerror_printf("FATAL - Failed to find attribute number %u we just added to parent %s.", n->attr, parent->name);
+               return -1;
+       }
+
+       if (!dict_attr_by_name(NULL, parent, n->name)) {
+               fr_strerror_printf("FATAL - Failed to find attribute '%s' we just added to parent %s.", n->name, parent->name);
+               return -1;
+       }
+#endif
+
        /*
         *      If it's a group attribute, the default
         *      reference goes to the root of the