]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
clean up and clarify namespace issues
authorAlan T. DeKok <aland@freeradius.org>
Thu, 25 Dec 2025 15:35:38 +0000 (10:35 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 25 Dec 2025 15:39:47 +0000 (10:39 -0500)
both for structural attribute to child , and for groups of

protocol/internal -> internal/protocol

in preparation for supporting "flat" attributes in some groups

src/lib/server/tmpl_tokenize.c
src/lib/unlang/compile.c

index 81cccae90796674db5ec472fa13f3ed5c4125898..da44580a6fc21d9a65df454a69809018157f22b9 100644 (file)
@@ -541,18 +541,44 @@ static fr_slen_t tmpl_request_ref_list_from_substr(TALLOC_CTX *ctx, tmpl_attr_er
        at_rules = &t_rules->attr;
 
        /*
-        *      The caller wants to know the default namespace for
-        *      resolving the attribute.
-        *
-        *      @todo - why not use dict_def if it's set?  Tho TBH we
-        *      should probably just remove dict_def, and always use "namespace".
+        *      The caller wants to know the default namespace for resolving the attribute.
         */
        if (namespace) {
                if (at_rules->namespace) {
-                       /*
-                        *      If the namespace is FR_TYPE_GROUP use the correct namespace
-                        */
-                       *namespace = at_rules->namespace->type == FR_TYPE_GROUP ? fr_dict_attr_ref(at_rules->namespace) : at_rules->namespace;
+                       if (request_attr_is_list(at_rules->namespace)) {
+                               /*
+                                *      If the namespace is a list attribute, then reset it to NULL, so that the rest of the
+                                *      code will use the default dictionary.
+                                */
+                               if (!at_rules->dict_def) {
+                                       fr_strerror_const("No dictionary was set - cannot parse attributes");
+                                       FR_SBUFF_ERROR_RETURN(&our_in);
+                               }
+                               *namespace = NULL;
+
+                       } else if (at_rules->namespace->type != FR_TYPE_GROUP) {
+                               /*
+                                *      If the namespace is a structural type, then use the namespace is this
+                                *      attribute.  We can then parse children of the attribute.
+                                */
+                               *namespace = at_rules->namespace;
+
+                       } else if (at_rules->namespace->flags.internal && at_rules->dict_def) {
+                               /*
+                                *      If the group is internal, AND we have a default dictionary, reset the
+                                *      namespace to NULL, so that the rest of the code will use the default
+                                *      dictionary.
+                                */
+                               *namespace = NULL;
+
+                       } else {
+                               /*
+                                *      The namespace is a non-internal group.  Update the namespace to be
+                                *      whereever the group is pointing to.
+                                */
+                               *namespace = fr_dict_attr_ref(at_rules->namespace);
+                       }
+
                } else {
                        *namespace = NULL;
                }
@@ -568,7 +594,7 @@ static fr_slen_t tmpl_request_ref_list_from_substr(TALLOC_CTX *ctx, tmpl_attr_er
        /*
         *      We're in a name space, OR lists are forbidden, don't allow list qualifiers.
         */
-       if (at_rules->namespace || (at_rules->list_presence == TMPL_ATTR_LIST_FORBID)) {
+       if (*namespace || (at_rules->list_presence == TMPL_ATTR_LIST_FORBID)) {
                if (fr_sbuff_is_str_literal(&our_in, "outer.") ||
                    fr_sbuff_is_str_literal(&our_in, "parent.")) {
                        fr_strerror_const("request list qualifiers are not allowed here");
index b606be702788f836680dce0ec6fb64521bc2b93e..1d25388fc4516ed1246523e83ef9ee627379c022 100644 (file)
@@ -682,16 +682,10 @@ static unlang_t *compile_edit_section(unlang_t *parent, unlang_compile_ctx_t *un
                map_t *child;
 
                /*
-                *      Don't update namespace for reply += { ... }
-                *
-                *      Do update namespace for reply.foo += { ... }
-                *
-                *      Don't update if the LHS is an internal group.
+                *      Reset the namespace to be this attribute.  The tmpl tokenizer will take care of
+                *      figuring out if this is a group, TLV, dictionary switch, etc.
                 */
-               if ((tmpl_attr_num_elements(map->lhs) > 1) && (t_rules.attr.list_def != parent_da) &&
-                   !((parent_da->type == FR_TYPE_GROUP) && parent_da->flags.internal)) {
-                       t_rules.attr.namespace = parent_da;
-               }
+               t_rules.attr.namespace = parent_da;
 
                if (map_afrom_cs_edit(map, &map->child, cs, &t_rules, &t_rules, unlang_fixup_edit, map, 256) < 0) {
                        goto fail;