From: Alan T. DeKok Date: Sun, 28 Aug 2022 14:01:47 +0000 (-0400) Subject: add ungroup and use it X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=edc13036dd656454509569ee23c7766e9f37d5cc;p=thirdparty%2Ffreeradius-server.git add ungroup and use it because %{request[*]} returns a group, as it really means "all request attributes". We really want to have %{request.[*]}, but that is not yet supported --- diff --git a/src/lib/unlang/xlat_builtin.c b/src/lib/unlang/xlat_builtin.c index ff638464ee4..d452a5f8254 100644 --- a/src/lib/unlang/xlat_builtin.c +++ b/src/lib/unlang/xlat_builtin.c @@ -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); diff --git a/src/tests/keywords/concat b/src/tests/keywords/concat index 629d271cea0..56a82c1e0b4 100644 --- a/src/tests/keywords/concat +++ b/src/tests/keywords/concat @@ -14,16 +14,16 @@ 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 } diff --git a/src/tests/keywords/join b/src/tests/keywords/join index 84396319011..a123d116dbf 100644 --- a/src/tests/keywords/join +++ b/src/tests/keywords/join @@ -12,13 +12,20 @@ &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 }