]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add ungroup and use it
authorAlan T. DeKok <aland@freeradius.org>
Sun, 28 Aug 2022 14:01:47 +0000 (10:01 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 28 Aug 2022 14:56:12 +0000 (10:56 -0400)
because %{request[*]} returns a group, as it really means
"all request attributes".  We really want to have %{request.[*]},
but that is not yet supported

src/lib/unlang/xlat_builtin.c
src/tests/keywords/concat
src/tests/keywords/join

index ff638464ee4811a05aed419683df05cc6a409c00..d452a5f825441026cb44220d0e3c19d4c84e6e11 100644 (file)
@@ -2451,6 +2451,36 @@ static xlat_action_t xlat_func_join(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out,
        return XLAT_ACTION_DONE;
 }
 
+static void ungroup(fr_dcursor_t *out, fr_value_box_list_t *in)
+{
+       fr_value_box_t *vb;
+
+       while ((vb = fr_dlist_pop_head(in)) != NULL) {
+               if (vb->type != FR_TYPE_GROUP) {
+                       fr_dcursor_append(out, vb);
+                       continue;
+               }
+               talloc_free(vb);
+       }
+}
+
+/** Ungroups all of its arguments into one flat list.
+ *
+ */
+static xlat_action_t xlat_func_ungroup(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out,
+                                      UNUSED xlat_ctx_t const *xctx,
+                                      UNUSED request_t *request, fr_value_box_list_t *in)
+{
+       fr_value_box_t  *arg = NULL;
+
+       while ((arg = fr_dlist_next(in, arg)) != NULL) {
+               fr_assert(arg->type == FR_TYPE_GROUP);
+
+               ungroup(out, &arg->vb_group);
+       }
+       return XLAT_ACTION_DONE;
+}
+
 static xlat_arg_parser_t const xlat_func_length_args[] = {
        { .single = true, .variadic = true, .type = FR_TYPE_VOID },
        XLAT_ARG_PARSER_TERMINATOR
@@ -3919,6 +3949,7 @@ do { \
        XLAT_REGISTER_ARGS("hmacsha1", xlat_func_hmac_sha1, xlat_hmac_args);
        XLAT_REGISTER_ARGS("integer", xlat_func_integer, xlat_func_integer_args);
        XLAT_REGISTER_ARGS("join", xlat_func_join, xlat_func_join_args);
+       XLAT_REGISTER_ARGS("ungroup", xlat_func_ungroup, xlat_func_join_args);
        XLAT_REGISTER_ARGS("length", xlat_func_length, xlat_func_length_args);
        XLAT_REGISTER_ARGS("lpad", xlat_func_lpad, xlat_func_pad_args);
        XLAT_REGISTER_ARGS("rpad", xlat_func_rpad, xlat_func_pad_args);
index 629d271cea013e4e8b0996579ed0704b92326c4d..56a82c1e0b4a096cee5ff97a7c27ac8fdff1f491 100644 (file)
 ok     # separate updates
 
 #
-#  Tmp-String-1 ends up as a group ????
+#  We need "ungroup" here, because request[*] is "all attributes with
+#  da of request", not "all attributes contained by the request VP."
 #
-#  @todo - track down and fix this!.  This is different behavior
-#  than `update`.
+#  We don't (yet) have syntax like "request.[*]", so we need this hack.
 #
 &request += {
-       &Tmp-String-1 = "%(concat:%{request[*]} ', ')"
+       &Tmp-String-1 = "%(concat:%(ungroup:%{request[*]}) ', ')"
 }
 
-if (&request.Tmp-String-1 != "{bob, hello, ab c, de fg, 123}") {
+if (&request.Tmp-String-1 != "bob, hello, ab c, de fg, 123") {
        test_fail
 }
 
index 843963190113eb22ca4f433c4824169d97871cda..a123d116dbf6901a318dc8f7698bc00f9118ca0d 100644 (file)
 &control.Tmp-IP-Address-0 := 192.168.1.254
 
 #
-#  The new code produces a group of groups?
+#  Don't insert this string into the request list, because we're getting its value
+#  from all of the request attributes.  And the insertion of the new attribute happens before the
+#  RHS value is created?  That seems wrong...
 #
-#update request {
-        &Tmp-String-1 := "%(concat:%(join:%{request[*]} %{control.Tmp-IP-Address-0}) '. ')"
-#}
+#  This is because edit_list_pair_build() is called before the value is created, when we're trying to
+#  see if the attribute already exists.  In order to fix this, we have to create the value first, and
+#  then modify the list.  Changing that involves fixing the logic in edit.c to check for ":=", and if
+#  it is there, do a simple "find" first.
+#
+#  @todo - fix this...
+#
+&control.Tmp-String-1 := "%(concat:%(join:%(ungroup:%{request[*]}) %{control.Tmp-IP-Address-0}) '. ')"
 
-if (&request.Tmp-String-1 != "bob. hello. ab c. de fg. 123. 192.168.1.254") {
+if (&control.Tmp-String-1 != "bob. hello. ab c. de fg. 123. 192.168.1.254") {
         test_fail
 }