]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add "local" flag to attributes and glue into tmpl parser
authorAlan T. DeKok <aland@freeradius.org>
Mon, 28 Nov 2022 00:23:10 +0000 (19:23 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 23 Sep 2023 11:57:13 +0000 (07:57 -0400)
they current are put into the request list, due to the tmpl
code not supporting PAIR_LIST_ROOT.  As the PAIR_LIST will be
going away soon

src/lib/server/tmpl_tokenize.c
src/lib/unlang/compile.c
src/lib/util/dict.h
src/tests/keywords/local-array-error [new file with mode: 0644]
src/tests/keywords/local-list-error [new file with mode: 0644]
src/tests/keywords/local-variable [new file with mode: 0644]

index 27e274fe5f13821210431ecb163e26945b41754c..4fe8b40cfd42941b22da901841b2334989a9426f 100644 (file)
@@ -1862,6 +1862,18 @@ do_suffix:
         */
        if (tmpl_attr_parse_filter(err, ar, name, at_rules) < 0) goto error;
 
+       /*
+        *      Local variables are always unitary.
+        *
+        *      [0] is allowed, as is [n], [*], and [#].  But [1], etc. aren't allowed.
+        */
+       if (da->flags.local && (ar->ar_num > 0)) {
+               fr_strerror_printf("Invalid array reference for local variable");
+               if (err) *err = TMPL_ATTR_ERROR_INVALID_ARRAY_INDEX;
+               fr_sbuff_set(name, &m_s);
+               goto error;
+       }
+
        /*
         *      At the end of the attribute reference. If there's a
         *      trailing '.' then there's another attribute reference
@@ -2115,10 +2127,16 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err,
        if (tmpl_is_attr(vpt) && is_raw) tmpl_attr_to_raw(vpt);
 
        /*
-        *      Check to see what the first attribute reference
-        *      was.  If it wasn't a known list group attribute,
-        *      then we need to add in a default list.
+        *      Local variables cannot be given an explicit parent or list modifier.
+        *
+        *      @todo - maybe allow parent references for local variables?  But that's just weird.
         */
+       if (tmpl_is_attr(vpt) && tmpl_attr_tail_da(vpt) && tmpl_attr_tail_da(vpt)->flags.local && (tmpl_attr_list_num_elements(tmpl_attr(vpt)) > 1)) {
+               fr_strerror_printf("Local attributes cannot be used in any list");
+               if (err) *err = TMPL_ATTR_ERROR_FOREIGN_NOT_ALLOWED;
+               fr_sbuff_set(&our_name, &m_l);
+               goto error;
+       }
 
        /*
         *      Check whether the tmpl has a list qualifier.
index d7e723280f162cdd4aa85021037e87113be0bdb1..38796852b99b8a1c9211942eeac80c2d7d02e44e 100644 (file)
@@ -1712,6 +1712,7 @@ static unlang_t *compile_variable(unlang_t *parent, unlang_compile_t *unlang_ctx
 
        fr_dict_attr_flags_t flags = {
                .internal = true,
+               .local = true,
        };
 
        c = *prev;
index 30c52345e428dab9a76d10d8bbcde5ca73bd0881..9a1359109571967fd4904b345e69b1b2b2cab006 100644 (file)
@@ -106,6 +106,8 @@ typedef struct {
         */
        unsigned int            extra : 1;                      //!< really "subtype is used by dict, not by protocol"
 
+       unsigned int            local : 1;                      //!< is a local variable
+
        /*
         *      main: extra is set, then this field is is key, bit, or a uint16 length field.
         *      radius: is one of 9 options for flags
diff --git a/src/tests/keywords/local-array-error b/src/tests/keywords/local-array-error
new file mode 100644 (file)
index 0000000..d0174a6
--- /dev/null
@@ -0,0 +1,6 @@
+group {
+       uint32 foo
+
+       #  There's only one local variable
+       &foo[1] := 1    # ERROR
+}
diff --git a/src/tests/keywords/local-list-error b/src/tests/keywords/local-list-error
new file mode 100644 (file)
index 0000000..d551de7
--- /dev/null
@@ -0,0 +1,5 @@
+group {
+       uint32 foo
+
+       &request.foo := 1       # ERROR
+}
diff --git a/src/tests/keywords/local-variable b/src/tests/keywords/local-variable
new file mode 100644 (file)
index 0000000..c04324a
--- /dev/null
@@ -0,0 +1,13 @@
+group {
+       uint32 foo
+
+       &foo := 1
+
+       &Filter-Id := &foo
+
+       if !(&Filter-Id == "1") {
+               test_fail
+       }
+}
+
+success