From: Nick Porter Date: Mon, 1 Mar 2021 17:13:41 +0000 (+0000) Subject: v4: Convert lists of fr_value_box_t to doubly linked lists (#3964) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a1d42c314de97c5be8d60129ea1e3e39129da6cd;p=thirdparty%2Ffreeradius-server.git v4: Convert lists of fr_value_box_t to doubly linked lists (#3964) * Typo in dlist.h * Make fr_value_box_list_t a dlist header * Add initialisation function for list of fr_value_box_t * Amend other structs containing lists of value boxes to use fr_value_box_list_t * Replace fr_cursor use with fr_dcursors * Amend exiting fr_value_box_list helper functions to use dlist properties * Initialise lists of fr_value_box_t * Use fr_dlist_empty() to test for empty lists of fr_value_box_t * Alter fr_value_box_clear_value() to correctly clear child lists. * Amend fr_vasprintf() to correctly take fr_value_box_list_t for %pM parameter and differentiate between logging a single fr_value_box_t and a fr_value_box_list_t. * Use fr_dlist_talloc_free() to free fr_value_box_list_t * Use dlist functions to walk fr_value_box_list_t * Amend unlang_xlat_push() to take fr_value_box_list_t * Amend definition of xlat_func_t and xlat_funct_resume_t ... ... to take fr_value_box_list_t * Amend xlat_func_base64_encode() to take fr_value_box_list_t * Amend xlat_func_base64_decode() to take fr_value_box_list_t * Amend xlat_func_bin() to take fr_value_box_list_t * Amend xlat_func_concat() to take fr_value_box_list_t * Amend xlat_func_hex() to take fr_value_box_list_t * Amend xlat_hmac() to take fr_value_box_list_t * Amend xlat_func_hmac_* to use fr_value_box_list_t * Amend xlat_func_length() to take fr_value_box_list_t * Amend xlat_func_md4() to take fr_value_box_list_t * Amend xlat_func_md5() to take fr_value_box_list_t * Amend xlat_func_pairs() to take fr_value_box_list_t * Amend xlat_func_rand() to take fr_value_box_list_t * Amend xlat_func_randstr() to take fr_value_box_list_t * Amend xlat_func_regex() to take fr_value_box_list_t * Amend xlat_func_sha1() to take fr_value_box_list_t * Amend xlat_func_##_md to take fr_value_pair_list_t * Amend xlat_func_string() to take fr_value_box_list_t * Amend xlat_func_strlen() to take fr_value_box_list_t * Amend xlat_func_sub_regex() to take fr_value_box_list_t * Amend xlat_func_sub() to take fr_value_box_list_t * Amend case change xlat_funcs to take fr_value_box_list_t * Amend xlat_func_urlquote() to take fr_value_box_list_t * Amend xlat_func_urlunquote() to take fr_value_box_list_t * Amend remaining builtin xlat funcs to take fr_value_box_list_t * Amend always_xlat() to take fr_value_box_list_t * Amend xlat_func_chap_password() to take fr_value_box_list_t * Amend cipher_rsa_encrypt_xlat() to take fr_value_box_list_t * Amend cipher_rsa_sign_xlat() to take fr_value_box_list_t * Amend cipher_rsa_decrypt_xlat() to take fr_value_box_list_t * Amend cipher_rsa_verify_xlat() to take fr_value_box_list_t * Amend xlat_delay() and xlat_delay_resume() to take fr_value_box_list_t * Amend dhcp4_decode_xlat and dhcpv4_encode_xlat to take fr_value_box_list_t * Amend xlat_icmp_resume() and xlat_icmp() to take fr_value_box_list_t * Amend rest_xlat() and rest_xlat_resume() to take fr_value_box_list_t * Amend redis_remap_xlat() to take fr_value_box_list_t * Amend redis_node_xlat() to take fr_value_box_list_t * Amend json_quote_xlat() to take fr_value_box_list_t * Amend json_encode_xlat() to take fr_value_box_list_t * Correctly initialise dlist entry in fr_value_box_copy_meta() * Amend fr_value_box_list_concat() to take fr_value_box_list_t * Amend fr_value_box_list_aprint() to take fr_value_box_list_t * Amend fr_value_box_list_acopy() to take fr_value_box_list_t * Amend fr_value_box_list_tainted() to take fr_value_box_list_t * Remove unused function fr_value_box_list_get() * Amend fr_value_box_list_flatten_argv() to take fr_value_box_list_t * Amend map_proc() to take fr_value_box_list_t * Amend definition of map_proc_func_t to take fr_value_box_list_t * Amend rlm_client map_proc_client() to take fr_value_box_list_t * Amend rlm_csv mod_map_proc() to take fr_value_box_list_t * Amend rlm_json mod_map_proc() to take fr_value_box_list_t * Amend rlm_ldap mod_map_proc() to take fr_value_box_list_t * Amend map_to_list_mod() to take fr_value_box_list_t * Maintain list pointers when performing cast in place on fr_value_box_t * Amend unlang_module_yield_to_*() to take fr_value_box_list_t * Amend rlm_sql mod_map_proc() to take fr_value_box_list_t * Initialise list entry pointers correctly * Amend fr_jpath_evaluate_leaf to take fr_value_box_list_t * Amend unlang_tmpl_push() to take fr_value_box_list_t * Amend unlang_tmpl_resume() to add fr_value_box_t to new list header * Amend unlang_tmpl_exec_wait_final() to populate box and add to list header * Alter fr_exec_nowait() to take fr_value_box_list_t * Amend fr_exec_wait_start() to take fr_value_box_list_t * Amend unit_test_module mod_map_proc() to take fr_value_box_list_t * Handle fr_value_box_list_t in list_mod_create(), map_proc_apply() ... ... and unlang_map_state_init() * Amend xlat_frame_eval_resume() to take fr_value_box_list_t * Amend xlat_frame_eval_repeat() to handle fr_value_box_list_t * Amend xlat_sync_eval() to hand fr_value_box_list_t * Amend _json_map_proc_get_value() to take handle fr_value_box_list_t * Pass parent to fr_value_box_cast_to_strvalue() to extract children as string * Amend mod_exec_nowait_resume(), mod_exec_wait_resume() and mod_exec_dispatch() ... to handle fr_value_box_list_t * Comment out code which allows for a fr_value_box_t in a fr_tmpl_t ... ... to be the head of a singly linked list. Now that lists of fr_value_box_t are doubly linked lists, this will no-longer work. Code left in place commented out as a reminder as to where this behaviour was used. --- diff --git a/src/bin/unit_test_module.c b/src/bin/unit_test_module.c index a3d9149afd8..9b5c27982de 100644 --- a/src/bin/unit_test_module.c +++ b/src/bin/unit_test_module.c @@ -451,7 +451,7 @@ static int map_proc_verify(CONF_SECTION *cs, UNUSED void *mod_inst, UNUSED void } static rlm_rcode_t mod_map_proc(UNUSED void *mod_inst, UNUSED void *proc_inst, UNUSED request_t *request, - UNUSED fr_value_box_t **src, UNUSED fr_map_list_t const *maps) + UNUSED fr_value_box_list_t *src, UNUSED fr_map_list_t const *maps) { return RLM_MODULE_FAIL; } diff --git a/src/lib/json/base.h b/src/lib/json/base.h index 729fae87fe1..195c211c0e2 100644 --- a/src/lib/json/base.h +++ b/src/lib/json/base.h @@ -241,7 +241,7 @@ typedef struct fr_jpath_node fr_jpath_node_t; size_t fr_jpath_escape_func(UNUSED request_t *request, char *out, size_t outlen, char const *in, UNUSED void *arg); -int fr_jpath_evaluate_leaf(TALLOC_CTX *ctx, fr_value_box_t **out, +int fr_jpath_evaluate_leaf(TALLOC_CTX *ctx, fr_value_box_list_t *out, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, json_object *root, fr_jpath_node_t const *jpath); diff --git a/src/lib/json/jpath.c b/src/lib/json/jpath.c index 5e72a91c290..ef385cb0692 100644 --- a/src/lib/json/jpath.c +++ b/src/lib/json/jpath.c @@ -128,7 +128,7 @@ size_t fr_jpath_escape_func(UNUSED request_t *request, char *out, size_t outlen, /** Recursive function for jpath_expr_evaluate * * @param[in,out] ctx to allocate fr_value_box_t in. - * @param[out] tail Where to write fr_value_box_t (**). + * @param[out] tail Where to write fr_value_box_t. * @param[in] dst_type FreeRADIUS type to convert to. * @param[in] dst_enumv Enumeration values to allow string to integer conversions. * @param[in] object current node in the json tree. @@ -138,7 +138,7 @@ size_t fr_jpath_escape_func(UNUSED request_t *request, char *out, size_t outlen, * - 0 on no match. * - -1 on error. */ -static int jpath_evaluate(TALLOC_CTX *ctx, fr_value_box_t ***tail, +static int jpath_evaluate(TALLOC_CTX *ctx, fr_value_box_list_t *tail, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, json_object *object, fr_jpath_node_t const *jpath) { @@ -360,8 +360,7 @@ static int jpath_evaluate(TALLOC_CTX *ctx, fr_value_box_t ***tail, return -1; } - **tail = value; - *tail = &(**tail)->next; + fr_dlist_insert_tail(tail, value); return 1; } @@ -381,14 +380,10 @@ static int jpath_evaluate(TALLOC_CTX *ctx, fr_value_box_t ***tail, * - 0 on no match. * - -1 on error. */ -int fr_jpath_evaluate_leaf(TALLOC_CTX *ctx, fr_value_box_t **out, +int fr_jpath_evaluate_leaf(TALLOC_CTX *ctx, fr_value_box_list_t *out, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, json_object *root, fr_jpath_node_t const *jpath) { - fr_value_box_t **tail = out; - - *tail = NULL; - if (!root) return -1; switch (jpath->selector->type) { @@ -401,7 +396,7 @@ int fr_jpath_evaluate_leaf(TALLOC_CTX *ctx, fr_value_box_t **out, return -1; } - return jpath_evaluate(ctx, &tail, dst_type, dst_enumv, root, jpath->next); + return jpath_evaluate(ctx, out, dst_type, dst_enumv, root, jpath->next); } /** Print a node list to a string for debugging diff --git a/src/lib/server/exec.c b/src/lib/server/exec.c index 18a73815834..f50db3ff229 100644 --- a/src/lib/server/exec.c +++ b/src/lib/server/exec.c @@ -598,7 +598,7 @@ wait: /** Execute a program without waiting for the program to finish. * * @param request the request - * @param vb as returned by xlat_frame_eval() + * @param vb_list as returned by xlat_frame_eval() * @param env_pairs VPs to put into into the environment. May be NULL. * @return * - <0 on error @@ -608,7 +608,7 @@ wait: * would allow finer-grained control over the attributes to put into * the environment. */ -int fr_exec_nowait(request_t *request, fr_value_box_t *vb, fr_pair_list_t *env_pairs) +int fr_exec_nowait(request_t *request, fr_value_box_list_t *vb_list, fr_pair_list_t *env_pairs) { int argc; char **envp; @@ -619,8 +619,8 @@ int fr_exec_nowait(request_t *request, fr_value_box_t *vb, fr_pair_list_t *env_p /* * Ensure that we don't do anything stupid. */ - first = fr_value_box_list_get(vb, 0); - if (first->type == FR_TYPE_GROUP) first = first->vb_group; + first = fr_dlist_head(vb_list); + if (first->type == FR_TYPE_GROUP) first = fr_dlist_head(&first->vb_group); if (first->tainted) { fr_strerror_printf("Program to run comes from tainted source - %pV", first); return -1; @@ -637,7 +637,7 @@ int fr_exec_nowait(request_t *request, fr_value_box_t *vb, fr_pair_list_t *env_p envp[0] = NULL; } - argc = fr_value_box_list_flatten_argv(request, &argv, vb); + argc = fr_value_box_list_flatten_argv(request, &argv, vb_list); if (argc < 0) { talloc_free(envp); return -1; @@ -688,7 +688,7 @@ int fr_exec_nowait(request_t *request, fr_value_box_t *vb, fr_pair_list_t *env_p * and closing it. * * @param request the request - * @param vb as returned by xlat_frame_eval() + * @param vb_list as returned by xlat_frame_eval() * @param env_pairs VPs to put into into the environment. May be NULL. * @param[out] pid_p The PID of the child * @param[out] input_fd The stdin FD of the child @@ -701,7 +701,7 @@ int fr_exec_nowait(request_t *request, fr_value_box_t *vb, fr_pair_list_t *env_p * would allow finer-grained control over the attributes to put into * the environment. */ -int fr_exec_wait_start(request_t *request, fr_value_box_t *vb, fr_pair_list_t *env_pairs, pid_t *pid_p, int *input_fd, int *output_fd) +int fr_exec_wait_start(request_t *request, fr_value_box_list_t *vb_list, fr_pair_list_t *env_pairs, pid_t *pid_p, int *input_fd, int *output_fd) { int argc; char **envp; @@ -714,8 +714,8 @@ int fr_exec_wait_start(request_t *request, fr_value_box_t *vb, fr_pair_list_t *e /* * Ensure that we don't do anything stupid. */ - first = fr_value_box_list_get(vb, 0); - if (first->type == FR_TYPE_GROUP) first = first->vb_group; + first = fr_dlist_head(vb_list); + if (first->type == FR_TYPE_GROUP) first = fr_dlist_head(&first->vb_group); if (first->tainted) { fr_strerror_printf("Program to run comes from tainted source - %pV", first); return -1; @@ -732,7 +732,7 @@ int fr_exec_wait_start(request_t *request, fr_value_box_t *vb, fr_pair_list_t *e envp[0] = NULL; } - argc = fr_value_box_list_flatten_argv(request, &argv, vb); + argc = fr_value_box_list_flatten_argv(request, &argv, vb_list); if (argc < 0) { error: talloc_free(envp); diff --git a/src/lib/server/exec.h b/src/lib/server/exec.h index a3aeae1b130..7baae851dad 100644 --- a/src/lib/server/exec.h +++ b/src/lib/server/exec.h @@ -56,9 +56,9 @@ int radius_exec_program(TALLOC_CTX *ctx, char *out, size_t outlen, fr_pair_list_ request_t *request, char const *cmd, fr_pair_list_t *input_pairs, bool exec_wait, bool shell_escape, fr_time_delta_t timeout) CC_HINT(nonnull (5, 6)); -int fr_exec_nowait(request_t *request, fr_value_box_t *vb, fr_pair_list_t *env_pairs); +int fr_exec_nowait(request_t *request, fr_value_box_list_t *vb_list, fr_pair_list_t *env_pairs); -int fr_exec_wait_start(request_t *request, fr_value_box_t *vb, fr_pair_list_t *env_pairs, pid_t *pid_p, int *input_fd, int *output_fd); +int fr_exec_wait_start(request_t *request, fr_value_box_list_t *vb_list, fr_pair_list_t *env_pairs, pid_t *pid_p, int *input_fd, int *output_fd); void fr_exec_waitpid(pid_t pid); diff --git a/src/lib/server/map.h b/src/lib/server/map.h index 5af0cfb695b..b8790b6e448 100644 --- a/src/lib/server/map.h +++ b/src/lib/server/map.h @@ -143,7 +143,7 @@ int map_list_mod_apply(request_t *request, vp_list_mod_t const *vlm); int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, request_t *request, map_t const *map, - fr_value_box_t **lhs_result, fr_value_box_t **rhs_result); + fr_value_box_list_t *lhs_result, fr_value_box_list_t *rhs_result); int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t func, void *ctx); diff --git a/src/lib/server/map_async.c b/src/lib/server/map_async.c index 7c3ff8060de..252fe79edee 100644 --- a/src/lib/server/map_async.c +++ b/src/lib/server/map_async.c @@ -258,15 +258,14 @@ static inline fr_pair_list_t *map_check_src_or_dst(request_t *request, map_t con */ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, request_t *request, map_t const *original, - fr_value_box_t **lhs_result, fr_value_box_t **rhs_result) + fr_value_box_list_t *lhs_result, fr_value_box_list_t *rhs_result) { vp_list_mod_t *n = NULL; - map_t map_tmp; + map_t map_tmp; map_t const *mutated = original; - fr_cursor_t values; - fr_value_box_t *head = NULL; - + fr_dcursor_t values; + fr_value_box_list_t head; TALLOC_CTX *tmp_ctx = NULL; MAP_VERIFY(original); @@ -279,6 +278,7 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, tmpl_is_xlat(original->lhs)); *out = NULL; + fr_value_box_list_init(&head); /* * Preprocessing of the LHS of the map. @@ -301,6 +301,7 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, case TMPL_TYPE_XLAT: { ssize_t slen; + fr_value_box_t *lhs_result_head = fr_dlist_head(lhs_result); /* * Get our own mutable copy of the original so we can @@ -311,27 +312,27 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, tmp_ctx = talloc_new(NULL); - fr_assert(lhs_result && *lhs_result); + fr_assert(!fr_dlist_empty(lhs_result)); /* * This should always be a noop, but included * here for robustness. */ - if (fr_value_box_list_concat(*lhs_result, *lhs_result, lhs_result, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(lhs_result_head, lhs_result_head, lhs_result, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Left side expansion failed"); - TALLOC_FREE(*lhs_result); + fr_dlist_talloc_free(lhs_result); goto error; } - slen = tmpl_afrom_attr_str(tmp_ctx, NULL, &map_tmp.lhs, (*lhs_result)->vb_strvalue, + slen = tmpl_afrom_attr_str(tmp_ctx, NULL, &map_tmp.lhs, lhs_result_head->vb_strvalue, &(tmpl_rules_t){ .dict_def = request->dict, .prefix = TMPL_ATTR_REF_PREFIX_NO }); if (slen <= 0) { RPEDEBUG("Left side expansion result \"%s\" is not an attribute reference", - (*lhs_result)->vb_strvalue); - TALLOC_FREE(*lhs_result); + lhs_result_head->vb_strvalue); + fr_dlist_talloc_free(lhs_result); goto error; } fr_assert(tmpl_is_attr(mutated->lhs) || tmpl_is_list(mutated->lhs)); @@ -448,7 +449,7 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, n = list_mod_generic_afrom_map(ctx, original, mutated); if (!n) goto error; - fr_cursor_init(&values, &head); + fr_dcursor_init(&values, &head); if (fr_value_box_from_str(fr_dlist_head(&n->mod), tmpl_value(fr_map_list_head(&n->mod)->rhs), &type, @@ -465,13 +466,13 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, */ if (!map_check_src_or_dst(request, mutated, mutated->lhs)) goto error; - (void)fr_cursor_init(&values, &head); + (void)fr_dcursor_init(&values, &head); switch (mutated->rhs->type) { case TMPL_TYPE_XLAT: { fr_assert(tmpl_xlat(mutated->rhs) != NULL); - fr_cursor_t from; + fr_dcursor_t from; fr_value_box_t *vb, *n_vb; assign_values: @@ -484,13 +485,13 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, * happens. This is only for XLATs and in future * EXECs. */ - if (!rhs_result || !*rhs_result) { + if (fr_dlist_empty(rhs_result)) { n = list_mod_empty_string_afrom_map(ctx, original, mutated); if (!n) { RPEDEBUG("Assigning value to \"%s\" failed", tmpl_da(mutated->lhs)->name); xlat_error: - fr_cursor_head(&values); - fr_cursor_free_list(&values); + fr_dcursor_head(&values); + fr_dcursor_free_list(&values); goto error; } goto finish; @@ -502,13 +503,13 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, n = list_mod_generic_afrom_map(ctx, original, mutated); if (!n) goto error; - (void)fr_cursor_init(&from, rhs_result); - while ((vb = fr_cursor_remove(&from))) { + (void)fr_dcursor_init(&from, rhs_result); + while ((vb = fr_dcursor_remove(&from))) { if (vb->type != tmpl_da(mutated->lhs)->type) { n_vb = fr_value_box_alloc_null(fr_map_list_head(&n->mod)->rhs); if (!n_vb) { - fr_cursor_head(&from); - fr_cursor_free_list(&from); + fr_dcursor_head(&from); + fr_dcursor_free_list(&from); goto xlat_error; } @@ -517,15 +518,15 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, tmpl_da(mutated->lhs), vb) < 0) { RPEDEBUG("Assigning value to \"%s\" failed", tmpl_da(mutated->lhs)->name); - fr_cursor_head(&from); - fr_cursor_free_list(&from); + fr_dcursor_head(&from); + fr_dcursor_free_list(&from); goto xlat_error; } talloc_free(vb); } else { n_vb = talloc_steal(n, vb); /* Should already be in ctx of n's parent */ } - fr_cursor_append(&values, n_vb); + fr_dcursor_append(&values, n_vb); } } break; @@ -538,7 +539,7 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, fr_value_box_t *n_vb; int err; - fr_assert(!rhs_result || !*rhs_result); + fr_assert(fr_dlist_empty(rhs_result)); fr_assert((tmpl_is_attr(mutated->lhs) && tmpl_da(mutated->lhs)) || (tmpl_is_list(mutated->lhs) && !tmpl_da(mutated->lhs))); @@ -586,8 +587,8 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, n_vb = fr_value_box_alloc_null(fr_map_list_head(&n->mod)->rhs); if (!n_vb) { attr_error: - fr_cursor_head(&values); - fr_cursor_free_list(&values); + fr_dcursor_head(&values); + fr_dcursor_free_list(&values); tmpl_cursor_clear(&cc_attr); goto error; } @@ -603,7 +604,7 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, } else { fr_value_box_copy(n_vb, n_vb, &vp->data); } - fr_cursor_append(&values, n_vb); + fr_dcursor_append(&values, n_vb); } while ((vp = fr_dcursor_next(&from))); tmpl_cursor_clear(&cc_attr); @@ -612,26 +613,29 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, case TMPL_TYPE_DATA: { - fr_cursor_t from; - fr_value_box_t *vb, *vb_head, *n_vb; + /* + * Commented out lines below are due to fr_value_box_t + * now being in a dlist - so value box entries in a fr_tmpl_t + * can no-longer be treated as the head of a list + */ + fr_value_box_t *vb, *n_vb; +// fr_value_box_t *vb_head; - fr_assert(!rhs_result || !*rhs_result); + fr_assert(fr_dlist_empty(rhs_result)); fr_assert(tmpl_da(mutated->lhs)); fr_assert(tmpl_is_attr(mutated->lhs)); n = list_mod_generic_afrom_map(ctx, original, mutated); if (!n) goto error; - vb_head = tmpl_value(mutated->rhs); + vb = tmpl_value(mutated->rhs); - for (vb = fr_cursor_init(&from, &vb_head); - vb; - vb = fr_cursor_next(&from)) { +// while ((vb = fr_dlist_next(vb_head, vb))) { n_vb = fr_value_box_alloc_null(fr_map_list_head(&n->mod)->rhs); if (!n_vb) { data_error: - fr_cursor_head(&values); - fr_cursor_free_list(&values); + fr_dcursor_head(&values); + fr_dcursor_free_list(&values); goto error; } /* @@ -656,8 +660,8 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, */ if (fr_value_box_copy(n_vb, n_vb, vb) < 0) goto data_error; } - fr_cursor_append(&values, n_vb); - } + fr_dcursor_append(&values, n_vb); +// } } break; @@ -673,6 +677,7 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, fr_dcursor_t from; fr_pair_list_t vp_head; fr_pair_t *vp; + fr_value_box_t *rhs_result_head = fr_dlist_head(rhs_result); fr_pair_list_init(&vp_head); /* @@ -689,7 +694,7 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, * happens. This is only for XLATs and in future * EXECs. */ - if (!rhs_result || !*rhs_result) { + if (fr_dlist_empty(rhs_result)) { RPEDEBUG("Cannot assign empty value to \"%s\"", mutated->lhs->name); goto error; } @@ -698,9 +703,9 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, * This should always be a noop, but included * here for robustness. */ - if (fr_value_box_list_concat(*rhs_result, *rhs_result, rhs_result, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(rhs_result_head, rhs_result_head, rhs_result, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Right side expansion failed"); - TALLOC_FREE(*rhs_result); + fr_dlist_talloc_free(rhs_result); goto error; } @@ -712,7 +717,7 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, /* * Parse the VPs from the RHS. */ - fr_pair_list_afrom_box(ctx, &vp_head, request->dict, *rhs_result); + fr_pair_list_afrom_box(ctx, &vp_head, request->dict, rhs_result_head); if (fr_pair_list_empty(&vp_head)) { talloc_free(n); RDEBUG2("No pairs returned by exec"); @@ -762,7 +767,7 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, goto error; } - fr_assert(head || !n); + fr_assert(!fr_dlist_empty(&head) || !n); /* * FIXME: This is only required because @@ -771,9 +776,13 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, * If tmpl_value were a pointer we could * assign values directly. */ - fr_value_box_copy(fr_map_list_head(&n->mod)->rhs, tmpl_value(fr_map_list_head(&n->mod)->rhs), head); - tmpl_value(fr_map_list_head(&n->mod)->rhs)->next = head->next; - talloc_free(head); + fr_value_box_copy(fr_map_list_head(&n->mod)->rhs, tmpl_value(fr_map_list_head(&n->mod)->rhs), fr_dlist_head(&head)); + /* + * value boxes in tmpls cannot now be the head of a list + * + *tmpl_value(fr_map_list_head(&n->mod)->rhs)->next = head->next; + */ + fr_dlist_talloc_free(&head); finish: if (n) { @@ -823,7 +832,7 @@ static void map_list_mod_to_vps(TALLOC_CTX *ctx, fr_pair_list_t *list, vp_list_m * Fast path... */ mod = fr_dlist_head(&vlm->mod); - if ((vlm->mod.num_elements == 1) && !tmpl_value(mod->rhs)->next) { + if (vlm->mod.num_elements == 1) { fr_pair_t *vp; vp = map_list_mod_to_vp(ctx, mod->lhs, tmpl_value(mod->rhs)); fr_pair_add(list, vp); @@ -836,18 +845,22 @@ static void map_list_mod_to_vps(TALLOC_CTX *ctx, fr_pair_list_t *list, vp_list_m for (; mod; mod = fr_dlist_next(&vlm->mod, mod)) { - fr_value_box_t *vb; + /* + * Commented out lines due to fr_value_box_t lists now + * being dlists + */ +// fr_value_box_t *vb; fr_pair_t *vp; - for (vb = tmpl_value(mod->rhs); - vb; - vb = vb->next) { - vp = map_list_mod_to_vp(ctx, mod->lhs, vb); +// for (vb = tmpl_value(mod->rhs); +// vb; +// vb = vb->next) { + vp = map_list_mod_to_vp(ctx, mod->lhs, tmpl_value(mod->rhs)); if (!vp) { fr_pair_list_free(list); } fr_pair_add(list, vp); - } +// } } } @@ -972,11 +985,16 @@ int map_list_mod_apply(request_t *request, vp_list_mod_t const *vlm) * map_list_mod_debug() */ if (RDEBUG_ENABLED2) { - for (vb = tmpl_value(mod->rhs); - vb; - vb = vb->next) { + vb = tmpl_value(mod->rhs); + /* + * Commented out lines due to fr_value_box_t lists now + * being dlists + */ +// for (vb = tmpl_value(mod->rhs); +// vb; +// vb = vb->next) { map_list_mod_debug(request, map, mod, vb->type != FR_TYPE_INVALID ? vb : NULL); - } +// } } } mod = fr_dlist_head(&vlm->mod); /* Reset */ @@ -1132,13 +1150,16 @@ int map_list_mod_apply(request_t *request, vp_list_mod_t const *vlm) */ if (tmpl_num(map->lhs) != NUM_ALL) { fr_value_box_t *vb = tmpl_value(fr_map_list_head(&vlm->mod)->rhs); - - do { + /* + * Commented out loop due to fr_value_box_t now being + * in dlists + */ +// do { if (fr_value_box_cmp(vb, &found->data) == 0) { fr_dcursor_free_item(&list); goto finish; } - } while ((vb = vb->next)); +// } while ((vb = vb->next)); goto finish; /* Wasn't found */ } @@ -1150,13 +1171,16 @@ int map_list_mod_apply(request_t *request, vp_list_mod_t const *vlm) */ do { fr_value_box_t *vb = tmpl_value(fr_map_list_head(&vlm->mod)->rhs); - - do { + /* + * Commented out loop due to fr_value_box_t now being + * in dlists + */ +// do { if (fr_value_box_cmp(vb, &found->data) == 0) { fr_dcursor_free_item(&list); break; } - } while ((vb = vb->next)); +// } while ((vb = vb->next)); } while ((found = fr_dcursor_next(&list))); } goto finish; @@ -1236,9 +1260,13 @@ int map_list_mod_apply(request_t *request, vp_list_mod_t const *vlm) fr_value_box_t *vb = tmpl_value(mod->rhs); bool remove = true; - do { + /* + * Commented out loop due to fr_value_box_t now being + * in dlists + */ +// do { if (fr_value_box_cmp_op(mod->op, &found->data, vb) == 1) remove = false; - } while ((vb = vb->next)); +// } while ((vb = vb->next)); if (remove) fr_dcursor_free_item(&list); goto finish; @@ -1251,9 +1279,13 @@ int map_list_mod_apply(request_t *request, vp_list_mod_t const *vlm) fr_value_box_t *vb = tmpl_value(mod->rhs); bool remove = true; - do { + /* + * Commented out loop due to fr_value_box_t now being + * in dlists + */ +// do { if (fr_value_box_cmp_op(mod->op, &found->data, vb) == 1) remove = false; - } while ((vb = vb->next)); +// } while ((vb = vb->next)); if (remove) { fr_dcursor_free_item(&list); diff --git a/src/lib/server/map_proc.c b/src/lib/server/map_proc.c index f1cdf5733ad..91164107d4d 100644 --- a/src/lib/server/map_proc.c +++ b/src/lib/server/map_proc.c @@ -201,7 +201,7 @@ map_proc_inst_t *map_proc_instantiate(TALLOC_CTX *ctx, map_proc_t const *proc, * @param[in,out] result Result of expanding the map input. May be consumed * by the map processor. */ -rlm_rcode_t map_proc(request_t *request, map_proc_inst_t const *inst, fr_value_box_t **result) +rlm_rcode_t map_proc(request_t *request, map_proc_inst_t const *inst, fr_value_box_list_t *result) { return inst->proc->evaluate(inst->proc->mod_inst, inst->data, request, result, inst->maps); } diff --git a/src/lib/server/map_proc.h b/src/lib/server/map_proc.h index 1ee679390c3..e0b0929c63d 100644 --- a/src/lib/server/map_proc.h +++ b/src/lib/server/map_proc.h @@ -59,7 +59,7 @@ extern "C" { * - #RLM_MODULE_FAIL - If an error occurred performing the mapping. */ typedef rlm_rcode_t (*map_proc_func_t)(void *mod_inst, void *proc_inst, request_t *request, - fr_value_box_t **result, fr_map_list_t const *maps); + fr_value_box_list_t *result, fr_map_list_t const *maps); /** Allocate new instance data for a map processor * @@ -85,7 +85,7 @@ int map_proc_register(void *mod_inst, char const *name, map_proc_inst_t *map_proc_instantiate(TALLOC_CTX *ctx, map_proc_t const *proc, CONF_SECTION *cs, tmpl_t const *src, fr_map_list_t const *maps); -rlm_rcode_t map_proc(request_t *request, map_proc_inst_t const *inst, fr_value_box_t **src); +rlm_rcode_t map_proc(request_t *request, map_proc_inst_t const *inst, fr_value_box_list_t *src); #ifdef __cplusplus } diff --git a/src/lib/server/trigger.c b/src/lib/server/trigger.c index 76aec7004c3..7076bd2fe88 100644 --- a/src/lib/server/trigger.c +++ b/src/lib/server/trigger.c @@ -188,11 +188,11 @@ bool trigger_enabled(void) } typedef struct { - char *name; - xlat_exp_t *xlat; - fr_pair_list_t vps; - fr_value_box_t *box; - bool expanded; + char *name; + xlat_exp_t *xlat; + fr_pair_list_t vps; + fr_value_box_list_t box; + bool expanded; } fr_trigger_t; static unlang_action_t trigger_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request) @@ -236,7 +236,7 @@ static unlang_action_t trigger_process(rlm_rcode_t *p_result, module_ctx_t const */ } - if (!ctx->box) { + if (fr_dlist_empty(&ctx->box)) { RERROR("Failed trigger %s - did not expand to anything", ctx->name); RETURN_MODULE_FAIL; } @@ -244,7 +244,7 @@ static unlang_action_t trigger_process(rlm_rcode_t *p_result, module_ctx_t const /* * Execute the program without waiting for results. */ - if (fr_exec_nowait(request, ctx->box, NULL) < 0) { + if (fr_exec_nowait(request, &ctx->box, NULL) < 0) { RPERROR("Failed trigger %s", ctx->name); RETURN_MODULE_FAIL; } @@ -404,6 +404,7 @@ int trigger_exec(request_t *request, CONF_SECTION const *cs, char const *name, b MEM(ctx = talloc_zero(fake, fr_trigger_t)); fr_pair_list_init(&ctx->vps); + fr_value_box_list_init(&ctx->box); ctx->name = talloc_strdup(ctx, value); if (request && !fr_pair_list_empty(&request->request_pairs)) { diff --git a/src/lib/unlang/map.c b/src/lib/unlang/map.c index 76cab106e22..1b4c08dbd47 100644 --- a/src/lib/unlang/map.c +++ b/src/lib/unlang/map.c @@ -53,8 +53,8 @@ typedef struct { vp_list_mod_t **vlm_next; vp_list_mod_t *vlm_head; //!< First VP List Mod. - fr_value_box_t *lhs_result; //!< Result of expanding the LHS - fr_value_box_t *rhs_result; //!< Result of expanding the RHS. + fr_value_box_list_t lhs_result; //!< Result of expanding the LHS + fr_value_box_list_t rhs_result; //!< Result of expanding the RHS. unlang_update_state_t state; //!< What we're currently doing. } unlang_frame_state_update_t; @@ -63,7 +63,7 @@ typedef struct { * */ typedef struct { - fr_value_box_t *src_result; //!< Result of expanding the map source. + fr_value_box_list_t src_result; //!< Result of expanding the map source. } unlang_frame_state_map_proc_t; /** Apply a list of modifications on one or more fr_pair_t lists. @@ -139,8 +139,8 @@ static unlang_action_t list_mod_create(rlm_rcode_t *p_result, request_t *request case UNLANG_UPDATE_MAP_INIT: update_state->state = UNLANG_UPDATE_MAP_EXPANDED_LHS; - fr_assert(!update_state->lhs_result); /* Should have been consumed */ - fr_assert(!update_state->rhs_result); /* Should have been consumed */ + fr_assert(fr_dlist_empty(&update_state->lhs_result)); /* Should have been consumed */ + fr_assert(fr_dlist_empty(&update_state->rhs_result)); /* Should have been consumed */ switch (map->lhs->type) { default: @@ -219,8 +219,8 @@ static unlang_action_t list_mod_create(rlm_rcode_t *p_result, request_t *request /* * Concat the top level results together */ - if (update_state->rhs_result && - (fr_value_box_list_concat(update_state, update_state->rhs_result, &update_state->rhs_result, + if (!fr_dlist_empty(&update_state->rhs_result) && + (fr_value_box_list_concat(update_state, fr_dlist_head(&update_state->rhs_result), &update_state->rhs_result, FR_TYPE_STRING, true) < 0)) { RPEDEBUG("Failed concatenating RHS expansion results"); goto error; @@ -230,11 +230,11 @@ static unlang_action_t list_mod_create(rlm_rcode_t *p_result, request_t *request request, map, &update_state->lhs_result, &update_state->rhs_result) < 0) goto error; - talloc_list_free(&update_state->rhs_result); + fr_dlist_talloc_free(&update_state->rhs_result); next: update_state->state = UNLANG_UPDATE_MAP_INIT; - talloc_list_free(&update_state->lhs_result); + fr_dlist_talloc_free(&update_state->lhs_result); /* * Wind to the end... @@ -279,6 +279,8 @@ static unlang_action_t unlang_update_state_init(rlm_rcode_t *p_result, request_t g->num_children)); /* 128 is for string buffers */ fr_dcursor_init(&update_state->maps, &gext->map); + fr_value_box_list_init(&update_state->lhs_result); + fr_value_box_list_init(&update_state->rhs_result); update_state->vlm_next = &update_state->vlm_head; repeatable_set(frame); @@ -302,17 +304,17 @@ static unlang_action_t map_proc_apply(rlm_rcode_t *p_result, request_t *request) map_proc_inst_t *inst = gext->proc_inst; unlang_frame_state_map_proc_t *map_proc_state = talloc_get_type_abort(frame->state, unlang_frame_state_map_proc_t); - RDEBUG2("MAP %s \"%pM\"", inst->proc->name, map_proc_state->src_result); + RDEBUG2("MAP %s \"%pM\"", inst->proc->name, &map_proc_state->src_result); /* * FIXME - We don't yet support async LHS/RHS expansions for map procs */ #ifndef NDEBUG - if (map_proc_state->src_result) talloc_list_get_type_abort(map_proc_state->src_result, fr_value_box_t); + if (!fr_dlist_empty(&map_proc_state->src_result)) fr_dlist_verify(&map_proc_state->src_result); #endif *p_result = map_proc(request, gext->proc_inst, &map_proc_state->src_result); #ifndef NDEBUG - if (map_proc_state->src_result) talloc_list_get_type_abort(map_proc_state->src_result, fr_value_box_t); + if (!fr_dlist_empty(&map_proc_state->src_result)) fr_dlist_verify(&map_proc_state->src_result); #endif return *p_result == RLM_MODULE_YIELD ? UNLANG_ACTION_YIELD : UNLANG_ACTION_CALCULATE_RESULT; @@ -333,6 +335,7 @@ static unlang_action_t unlang_map_state_init(rlm_rcode_t *p_result, request_t *r */ repeatable_set(frame); + fr_value_box_list_init(&map_proc_state->src_result); /* * Set this BEFORE doing anything else, as we will be * called again after unlang_xlat_push() returns. @@ -344,15 +347,18 @@ static unlang_action_t unlang_map_state_init(rlm_rcode_t *p_result, request_t *r */ if (inst->src) switch (inst->src->type) { default: - if (tmpl_aexpand(frame->state, &map_proc_state->src_result, + { + fr_value_box_t *src_result = NULL; + if (tmpl_aexpand(frame->state, &src_result, request, inst->src, NULL, NULL) < 0) { REDEBUG("Failed expanding map src"); error: *p_result = RLM_MODULE_FAIL; return UNLANG_ACTION_CALCULATE_RESULT; } + fr_dlist_insert_head(&map_proc_state->src_result, src_result); break; - + } case TMPL_TYPE_EXEC: if (unlang_tmpl_push(map_proc_state, &map_proc_state->src_result, request, inst->src, NULL, NULL) < 0) { diff --git a/src/lib/unlang/module.c b/src/lib/unlang/module.c index b5d2daf74d9..f1692050271 100644 --- a/src/lib/unlang/module.c +++ b/src/lib/unlang/module.c @@ -475,7 +475,7 @@ unlang_action_t unlang_module_yield_to_subrequest(rlm_rcode_t *p_result, request * @return * - UNLANG_ACTION_YIELD */ -unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, fr_value_box_t **out, +unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, xlat_exp_t const *exp, unlang_module_resume_t resume, unlang_module_signal_t signal, void *rctx) @@ -521,7 +521,7 @@ unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, fr_value_box_t **ou * @return * - UNLANG_ACTION_YIELD */ -unlang_action_t unlang_module_yield_to_tmpl(TALLOC_CTX *ctx, fr_value_box_t **out, int *status, +unlang_action_t unlang_module_yield_to_tmpl(TALLOC_CTX *ctx, fr_value_box_list_t *out, int *status, request_t *request, tmpl_t const *vpt, fr_pair_list_t *vps, unlang_module_resume_t resume, diff --git a/src/lib/unlang/module.h b/src/lib/unlang/module.h index 0d14a7878d8..e03989bb25d 100644 --- a/src/lib/unlang/module.h +++ b/src/lib/unlang/module.h @@ -126,12 +126,12 @@ unlang_action_t unlang_module_yield_to_section(rlm_rcode_t *p_result, unlang_module_resume_t resume, unlang_module_signal_t signal, void *rctx); -unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, fr_value_box_t **out, +unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, xlat_exp_t const *xlat, unlang_module_resume_t resume, unlang_module_signal_t signal, void *rctx); -unlang_action_t unlang_module_yield_to_tmpl(TALLOC_CTX *ctx, fr_value_box_t **out, int *status, +unlang_action_t unlang_module_yield_to_tmpl(TALLOC_CTX *ctx, fr_value_box_list_t *out, int *status, request_t *request, tmpl_t const *exp, fr_pair_list_t *vps, unlang_module_resume_t resume, diff --git a/src/lib/unlang/tmpl.c b/src/lib/unlang/tmpl.c index cde3de777da..12b48f91fa9 100644 --- a/src/lib/unlang/tmpl.c +++ b/src/lib/unlang/tmpl.c @@ -112,7 +112,7 @@ static void unlang_tmpl_signal(request_t *request, fr_state_signal_t action) * @param[in] vps the input VPs. May be NULL. Used only for #TMPL_TYPE_EXEC * @param[out] status where the status of exited programs will be stored. */ -int unlang_tmpl_push(TALLOC_CTX *ctx, fr_value_box_t **out, request_t *request, tmpl_t const *tmpl, fr_pair_list_t *vps, int *status) +int unlang_tmpl_push(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *tmpl, fr_pair_list_t *vps, int *status) { unlang_stack_t *stack = request->stack; unlang_stack_frame_t *frame; @@ -159,6 +159,8 @@ int unlang_tmpl_push(TALLOC_CTX *ctx, fr_value_box_t **out, request_t *request, .status_p = status }; + fr_value_box_list_init(&state->box); + return 0; } @@ -303,7 +305,7 @@ static unlang_action_t unlang_tmpl_resume(rlm_rcode_t *p_result, request_t *requ unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_tmpl_t); - if (state->out) *state->out = state->box; + if (state->out) fr_dlist_move(state->out, &state->box); if (state->resume) { rlm_rcode_t rcode; @@ -337,7 +339,7 @@ static unlang_action_t unlang_tmpl_exec_wait_final(rlm_rcode_t *p_result, reques * care about output, and we don't care about the programs exit status. */ if (state->failed) { - TALLOC_FREE(state->box); + fr_dlist_talloc_free(&state->box); goto resume; } @@ -357,7 +359,7 @@ static unlang_action_t unlang_tmpl_exec_wait_final(rlm_rcode_t *p_result, reques state->status = -state->status; } - fr_assert(state->box == NULL); + fr_assert(fr_dlist_empty(&state->box)); goto resume; } @@ -374,6 +376,7 @@ static unlang_action_t unlang_tmpl_exec_wait_final(rlm_rcode_t *p_result, reques */ if (state->out) { fr_type_t type = FR_TYPE_STRING; + fr_value_box_t *box; /* * Remove any trailing LF / CR @@ -392,13 +395,15 @@ static unlang_action_t unlang_tmpl_exec_wait_final(rlm_rcode_t *p_result, reques state->ptr = p; } - MEM(state->box = fr_value_box_alloc(state->ctx, FR_TYPE_STRING, NULL, true)); - if (fr_value_box_from_str(state->box, state->box, &type, NULL, + fr_value_box_list_init(&state->box); + MEM(box = fr_value_box_alloc(state->ctx, FR_TYPE_STRING, NULL, true)); + if (fr_value_box_from_str(state->ctx, box, &type, NULL, state->buffer, state->ptr - state->buffer, 0, true) < 0) { - talloc_free(state->box); + talloc_free(box); *p_result = RLM_MODULE_FAIL; return UNLANG_ACTION_CALCULATE_RESULT; } + fr_dlist_insert_head(&state->box, box); } /* @@ -429,14 +434,14 @@ static unlang_action_t unlang_tmpl_exec_wait_resume(rlm_rcode_t *p_result, reque state->fd = -1; if (state->out) fd_p = &state->fd; - if (fr_exec_wait_start(request, state->box, state->vps, &pid, NULL, fd_p) < 0) { + if (fr_exec_wait_start(request, &state->box, state->vps, &pid, NULL, fd_p) < 0) { RPEDEBUG("Failed executing program"); fail: *p_result = RLM_MODULE_FAIL; return UNLANG_ACTION_CALCULATE_RESULT; } - TALLOC_FREE(state->box); /* this is the xlat expansion, and not the output string we want */ + fr_dlist_talloc_free(&state->box); /* this is the xlat expansion, and not the output string we want */ state->pid = pid; state->status = -1; /* default to program didn't work */ @@ -492,7 +497,7 @@ static unlang_action_t unlang_tmpl_exec_nowait_resume(rlm_rcode_t *p_result, req unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_tmpl_t); - if (fr_exec_nowait(request, state->box, state->vps) < 0) { + if (fr_exec_nowait(request, &state->box, state->vps) < 0) { RPEDEBUG("Failed executing program"); *p_result = RLM_MODULE_FAIL; @@ -520,9 +525,13 @@ static unlang_action_t unlang_tmpl(rlm_rcode_t *p_result, request_t *request) /* * If we're not called from unlang_tmpl_push(), then - * ensure that we clean up the resulting value boxes. + * ensure that we clean up the resulting value boxes + * and that the list to write the boxes in is initialised. */ - if (!state->ctx) state->ctx = state; + if (!state->ctx) { + state->ctx = state; + fr_value_box_list_init(&state->box); + } if (!tmpl_async_required(ut->tmpl)) { if (!ut->inline_exec) { diff --git a/src/lib/unlang/tmpl.h b/src/lib/unlang/tmpl.h index 966db00caa3..e3a5030c8c3 100644 --- a/src/lib/unlang/tmpl.h +++ b/src/lib/unlang/tmpl.h @@ -57,7 +57,7 @@ typedef void (*fr_unlang_tmpl_signal_t)(request_t *request, void *rctx, fr_state */ typedef rlm_rcode_t (*fr_unlang_tmpl_resume_t)(request_t *request, void *rctx); -int unlang_tmpl_push(TALLOC_CTX *ctx, fr_value_box_t **out, +int unlang_tmpl_push(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *tmpl, fr_pair_list_t *vps, int *status) CC_HINT(warn_unused_result); diff --git a/src/lib/unlang/tmpl_priv.h b/src/lib/unlang/tmpl_priv.h index 62300e77f26..ec578f1b1e0 100644 --- a/src/lib/unlang/tmpl_priv.h +++ b/src/lib/unlang/tmpl_priv.h @@ -35,8 +35,8 @@ extern "C" { */ typedef struct { TALLOC_CTX *ctx; //!< for allocating value boxes - fr_value_box_t **out; //!< where the expansion is stored - fr_value_box_t *box; //!< where the expansion is stored + fr_value_box_list_t *out; //!< where the expansion is stored + fr_value_box_list_t box; //!< where the expansion is stored void *rctx; //!< for resume fr_unlang_tmpl_resume_t resume; //!< resumption handler diff --git a/src/lib/unlang/xlat.c b/src/lib/unlang/xlat.c index 1861055b5a7..94be17fa4c3 100644 --- a/src/lib/unlang/xlat.c +++ b/src/lib/unlang/xlat.c @@ -40,12 +40,12 @@ typedef struct { TALLOC_CTX *ctx; //!< to allocate boxes and values in. TALLOC_CTX *event_ctx; //!< for temporary events xlat_exp_t const *exp; - fr_cursor_t values; //!< Values aggregated so far. + fr_dcursor_t values; //!< Values aggregated so far. /* * For func and alternate */ - fr_value_box_t *rhead; //!< Head of the result of a nested + fr_value_box_list_t rhead; //!< Head of the result of a nested ///< expansion. bool alternate; //!< record which alternate branch we ///< previously took. @@ -192,7 +192,7 @@ int unlang_xlat_event_timeout_add(request_t *request, fr_unlang_xlat_timeout_t c * - 0 on success. * - -1 on failure. */ -int unlang_xlat_push(TALLOC_CTX *ctx, fr_value_box_t **out, +int unlang_xlat_push(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, xlat_exp_t const *exp, bool top_frame) { @@ -214,7 +214,8 @@ int unlang_xlat_push(TALLOC_CTX *ctx, fr_value_box_t **out, MEM(frame->state = state = talloc_zero(stack, unlang_frame_state_xlat_t)); state->exp = talloc_get_type_abort_const(exp, xlat_exp_t); /* Ensure the node is valid */ - fr_cursor_talloc_init(&state->values, out, fr_value_box_t); + fr_dcursor_talloc_init(&state->values, out, fr_value_box_t); + fr_value_box_list_init(&state->rhead); state->ctx = ctx; @@ -252,7 +253,7 @@ static unlang_action_t unlang_xlat(rlm_rcode_t *p_result, request_t *request) * at this level. A frame may be used to evaluate * multiple sibling nodes. */ - talloc_list_free(&state->rhead); + fr_dlist_talloc_free(&state->rhead); if (unlang_xlat_push(state->ctx, &state->rhead, request, child, false) < 0) { *p_result = RLM_MODULE_FAIL; return UNLANG_ACTION_STOP_PROCESSING; diff --git a/src/lib/unlang/xlat.h b/src/lib/unlang/xlat.h index a4d8ab81b3f..0b4210f587b 100644 --- a/src/lib/unlang/xlat.h +++ b/src/lib/unlang/xlat.h @@ -141,9 +141,9 @@ typedef void (*fr_unlang_xlat_fd_event_t)(request_t *request, void *xlat_inst, * mean it turned a result. * - XLAT_ACTION_FAIL the xlat function failed. */ -typedef xlat_action_t (*xlat_func_t)(TALLOC_CTX *ctx, fr_cursor_t *out, +typedef xlat_action_t (*xlat_func_t)(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, void const *xlat_inst, void *xlat_thread_inst, - fr_value_box_t **in); + fr_value_box_list_t *in); /** xlat callback resumption function * @@ -164,9 +164,9 @@ typedef xlat_action_t (*xlat_func_t)(TALLOC_CTX *ctx, fr_cursor_t *out, * mean it turned a result. * - XLAT_ACTION_FAIL the xlat function failed. */ -typedef xlat_action_t (*xlat_func_resume_t)(TALLOC_CTX *ctx, fr_cursor_t *out, +typedef xlat_action_t (*xlat_func_resume_t)(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, void const *xlat_inst, void *xlat_thread_inst, - fr_value_box_t **in, void *rctx); + fr_value_box_list_t *in, void *rctx); /** A callback when the request gets a fr_state_signal_t. * @@ -404,7 +404,7 @@ void xlat_instances_free(void); int unlang_xlat_event_timeout_add(request_t *request, fr_unlang_xlat_timeout_t callback, void const *ctx, fr_time_t when); -int unlang_xlat_push(TALLOC_CTX *ctx, fr_value_box_t **out, +int unlang_xlat_push(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, xlat_exp_t const *exp, bool top_frame) CC_HINT(warn_unused_result); diff --git a/src/lib/unlang/xlat_builtin.c b/src/lib/unlang/xlat_builtin.c index 1952293501d..585a2d80028 100644 --- a/src/lib/unlang/xlat_builtin.c +++ b/src/lib/unlang/xlat_builtin.c @@ -1600,27 +1600,29 @@ static ssize_t xlat_func_xlat(TALLOC_CTX *ctx, char **out, size_t outlen, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_base64_encode(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_base64_encode(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { size_t alen; ssize_t elen; char *buff; fr_value_box_t *vb; + fr_value_box_t *in_head; /* * If there's no input, there's no output */ - if (!in) return XLAT_ACTION_DONE; + if (fr_dlist_empty(in)) return XLAT_ACTION_DONE; - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) { + in_head = fr_dlist_head(in); + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - alen = FR_BASE64_ENC_LENGTH((*in)->vb_length); + alen = FR_BASE64_ENC_LENGTH(in_head->vb_length); MEM(vb = fr_value_box_alloc_null(ctx)); if (fr_value_box_bstr_alloc(vb, &buff, vb, NULL, alen, false) < 0) { @@ -1628,7 +1630,7 @@ static xlat_action_t xlat_func_base64_encode(TALLOC_CTX *ctx, fr_cursor_t *out, return XLAT_ACTION_FAIL; } - elen = fr_base64_encode(buff, alen + 1, (*in)->vb_octets, (*in)->vb_length); + elen = fr_base64_encode(buff, alen + 1, in_head->vb_octets, in_head->vb_length); if (elen < 0) { RPEDEBUG("Base64 encoding failed"); talloc_free(buff); @@ -1636,7 +1638,7 @@ static xlat_action_t xlat_func_base64_encode(TALLOC_CTX *ctx, fr_cursor_t *out, } fr_assert((size_t)elen <= alen); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -1651,38 +1653,40 @@ static xlat_action_t xlat_func_base64_encode(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_base64_decode(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_base64_decode(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { size_t alen; ssize_t declen; uint8_t *decbuf; fr_value_box_t *vb; + fr_value_box_t *in_head; /* * If there's no input, there's no output */ - if (!in) return XLAT_ACTION_DONE; + if (fr_dlist_empty(in)) return XLAT_ACTION_DONE; - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) { + in_head = fr_dlist_head(in); + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - alen = FR_BASE64_DEC_LENGTH((*in)->vb_length); + alen = FR_BASE64_DEC_LENGTH(in_head->vb_length); MEM(vb = fr_value_box_alloc_null(ctx)); - MEM(fr_value_box_mem_alloc(vb, &decbuf, vb, NULL, alen, (*in)->tainted) == 0); - declen = fr_base64_decode(decbuf, alen, (*in)->vb_strvalue, (*in)->vb_length); + MEM(fr_value_box_mem_alloc(vb, &decbuf, vb, NULL, alen, in_head->tainted) == 0); + declen = fr_base64_decode(decbuf, alen, in_head->vb_strvalue, in_head->vb_length); if (declen < 0) { talloc_free(vb); REDEBUG("Base64 string invalid"); return XLAT_ACTION_FAIL; } MEM(fr_value_box_mem_realloc(vb, NULL, vb, declen) == 0); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -1699,9 +1703,9 @@ static xlat_action_t xlat_func_base64_decode(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_bin(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_bin(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { fr_value_box_t *result; char *buff = NULL, *p, *end; @@ -1712,9 +1716,9 @@ static xlat_action_t xlat_func_bin(TALLOC_CTX *ctx, fr_cursor_t *out, /* * If there's no input, there's no output */ - if (!*in) return XLAT_ACTION_DONE; + if (fr_dlist_empty(in)) return XLAT_ACTION_DONE; - buff = fr_value_box_list_aprint(NULL, *in, NULL, NULL); + buff = fr_value_box_list_aprint(NULL, in, NULL, NULL); if (!buff) return XLAT_ACTION_FAIL; len = talloc_array_length(buff) - 1; @@ -1736,7 +1740,7 @@ static xlat_action_t xlat_func_bin(TALLOC_CTX *ctx, fr_cursor_t *out, outlen = len / 2; MEM(result = fr_value_box_alloc_null(ctx)); - MEM(fr_value_box_mem_alloc(result, &bin, result, NULL, outlen, fr_value_box_list_tainted(*in)) == 0); + MEM(fr_value_box_mem_alloc(result, &bin, result, NULL, outlen, fr_value_box_list_tainted(in)) == 0); fr_hex2bin(&err, &FR_DBUFF_TMP(bin, outlen), &FR_SBUFF_IN(p, end - p), true); if (err) { REDEBUG2("Invalid hex string"); @@ -1744,7 +1748,7 @@ static xlat_action_t xlat_func_bin(TALLOC_CTX *ctx, fr_cursor_t *out, return XLAT_ACTION_FAIL; } - fr_cursor_append(out, result); + fr_dcursor_append(out, result); finish: talloc_free(buff); @@ -1764,9 +1768,9 @@ finish: * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_concat(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_concat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { fr_value_box_t *result; fr_value_box_t *separator; @@ -1776,12 +1780,12 @@ static xlat_action_t xlat_func_concat(TALLOC_CTX *ctx, fr_cursor_t *out, /* * If there's no input, there's no output */ - if (!in) return XLAT_ACTION_DONE; + if (fr_dlist_empty(in)) return XLAT_ACTION_DONE; /* * Separator is first value box */ - separator = *in; + separator = fr_dlist_pop_head(in); if (!separator) { REDEBUG("Missing separator for concat xlat"); @@ -1797,12 +1801,17 @@ static xlat_action_t xlat_func_concat(TALLOC_CTX *ctx, fr_cursor_t *out, return XLAT_ACTION_FAIL; } - buff = fr_value_box_list_aprint(result, (*in)->next, sep, NULL); + buff = fr_value_box_list_aprint(result, in, sep, NULL); if (!buff) goto error; - fr_value_box_bstrdup_buffer_shallow(NULL, result, NULL, buff, fr_value_box_list_tainted((*in)->next)); + fr_value_box_bstrdup_buffer_shallow(NULL, result, NULL, buff, fr_value_box_list_tainted(in)); - fr_cursor_append(out, result); + /* + * Return separator to the start of the vb list + */ + fr_dlist_insert_head(in, separator); + + fr_dcursor_append(out, result); return XLAT_ACTION_DONE; } @@ -1819,34 +1828,36 @@ static xlat_action_t xlat_func_concat(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_hex(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_hex(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { char *p; fr_value_box_t* vb; + fr_value_box_t* in_head; /* * If there's no input, there's no output */ - if (!*in) return XLAT_ACTION_DONE; + if (fr_dlist_empty(in)) return XLAT_ACTION_DONE; + in_head = fr_dlist_head(in); /* * Concatenate all input */ - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL, false)); - vb->vb_length = ((*in)->vb_length * 2); + vb->vb_length = (in_head->vb_length * 2); vb->vb_strvalue = p = talloc_zero_array(vb, char, vb->vb_length + 1); - if ((*in)->vb_length) { - fr_bin2hex(&FR_SBUFF_OUT(p, talloc_array_length(p)), &FR_DBUFF_TMP((*in)->vb_octets, (*in)->vb_length), SIZE_MAX); + if (in_head->vb_length) { + fr_bin2hex(&FR_SBUFF_OUT(p, talloc_array_length(p)), &FR_DBUFF_TMP(in_head->vb_octets, in_head->vb_length), SIZE_MAX); } - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -1857,19 +1868,19 @@ typedef enum { HMAC_SHA1 } hmac_type; -static xlat_action_t xlat_hmac(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_hmac(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in, uint8_t *digest, int digest_len, hmac_type type) + fr_value_box_list_t *in, uint8_t *digest, int digest_len, hmac_type type) { uint8_t const *data_p, *key_p; size_t data_len, key_len; fr_value_box_t *vb, *vb_data, *vb_sep, *vb_key; - if (!in) return XLAT_ACTION_FAIL; + if (fr_dlist_empty(in)) return XLAT_ACTION_FAIL; - vb_data = fr_value_box_list_get(*in, 0); - vb_sep = fr_value_box_list_get(*in, 1); - vb_key = fr_value_box_list_get(*in, 2); + vb_data = fr_dlist_head(in); + vb_sep = fr_dlist_next(in, vb_data); + vb_key = fr_dlist_next(in, vb_sep); if (!vb_data || !vb_sep || !vb_key || vb_sep->vb_length != 1 || @@ -1893,7 +1904,7 @@ static xlat_action_t xlat_hmac(TALLOC_CTX *ctx, fr_cursor_t *out, MEM(vb = fr_value_box_alloc_null(ctx)); fr_value_box_memdup(vb, vb, NULL, digest, digest_len, false); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -1908,9 +1919,9 @@ static xlat_action_t xlat_hmac(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_hmac_md5(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_hmac_md5(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, void const *xlat_inst, void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { uint8_t digest[MD5_DIGEST_LENGTH]; return xlat_hmac(ctx, out, request, xlat_inst, xlat_thread_inst, in, digest, MD5_DIGEST_LENGTH, HMAC_MD5); @@ -1926,9 +1937,9 @@ static xlat_action_t xlat_func_hmac_md5(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_hmac_sha1(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_hmac_sha1(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, void const *xlat_inst, void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { uint8_t digest[SHA1_DIGEST_LENGTH]; return xlat_hmac(ctx, out, request, xlat_inst, xlat_thread_inst, in, digest, SHA1_DIGEST_LENGTH, HMAC_SHA1); @@ -1947,22 +1958,22 @@ static xlat_action_t xlat_func_hmac_sha1(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_length(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_length(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED request_t *request, UNUSED void const *xlat_inst, - UNUSED void *xlat_thread_inst, fr_value_box_t **in) + UNUSED void *xlat_thread_inst, fr_value_box_list_t *in) { fr_value_box_t *vb; - fr_cursor_t cursor; + fr_dcursor_t cursor; - for (vb = fr_cursor_talloc_init(&cursor, in, fr_value_box_t); + for (vb = fr_dcursor_talloc_init(&cursor, in, fr_value_box_t); vb; - vb = fr_cursor_next(&cursor)) { + vb = fr_dcursor_next(&cursor)) { fr_value_box_t *my; MEM(my = fr_value_box_alloc(ctx, FR_TYPE_SIZE, NULL, false)); my->vb_size = fr_value_box_network_length(vb); - fr_cursor_append(out, my); + fr_dcursor_append(out, my); } return XLAT_ACTION_DONE; @@ -1978,23 +1989,24 @@ static xlat_action_t xlat_func_length(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_md4(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_md4(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { uint8_t digest[MD5_DIGEST_LENGTH]; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); /* * Concatenate all input if there is some */ - if (*in && fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) { + if (in_head && fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - if (*in) { - fr_md4_calc(digest, (*in)->vb_octets, (*in)->vb_length); + if (in_head) { + fr_md4_calc(digest, in_head->vb_octets, in_head->vb_length); } else { /* Digest of empty string */ fr_md4_calc(digest, NULL, 0); @@ -2003,7 +2015,7 @@ static xlat_action_t xlat_func_md4(TALLOC_CTX *ctx, fr_cursor_t *out, MEM(vb = fr_value_box_alloc_null(ctx)); fr_value_box_memdup(vb, vb, NULL, digest, sizeof(digest), false); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -2018,23 +2030,24 @@ static xlat_action_t xlat_func_md4(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_md5(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_md5(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { uint8_t digest[MD5_DIGEST_LENGTH]; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); /* * Concatenate all input if there is some */ - if (*in && fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) { + if (in_head && fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - if (*in) { - fr_md5_calc(digest, (*in)->vb_octets, (*in)->vb_length); + if (in_head) { + fr_md5_calc(digest, in_head->vb_octets, in_head->vb_length); } else { /* Digest of empty string */ fr_md5_calc(digest, NULL, 0); @@ -2043,7 +2056,7 @@ static xlat_action_t xlat_func_md5(TALLOC_CTX *ctx, fr_cursor_t *out, MEM(vb = fr_value_box_alloc_null(ctx)); fr_value_box_memdup(vb, vb, NULL, digest, sizeof(digest), false); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -2068,9 +2081,9 @@ exec echo { * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_module(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_module(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - UNUSED fr_value_box_t **in) + UNUSED fr_value_box_list_t *in) { fr_value_box_t *vb = NULL; @@ -2085,7 +2098,7 @@ static xlat_action_t xlat_func_module(TALLOC_CTX *ctx, fr_cursor_t *out, return XLAT_ACTION_FAIL; } - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -2100,14 +2113,13 @@ static xlat_action_t xlat_func_module(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_pack(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_pack(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { fr_value_box_t *vb, *in_vb; - fr_cursor_t cursor; - if (!*in) { + if (fr_dlist_empty(in)) { REDEBUG("Missing input boxes"); return XLAT_ACTION_FAIL; } @@ -2117,9 +2129,9 @@ static xlat_action_t xlat_func_pack(TALLOC_CTX *ctx, fr_cursor_t *out, /* * Loop over the input boxes, packing them together. */ - for (in_vb = fr_cursor_init(&cursor, in); + for (in_vb = fr_dlist_head(in); in_vb; - in_vb = fr_cursor_next(&cursor)) { + in_vb = fr_dlist_next(in, in_vb)) { fr_value_box_t *cast, box; if (in_vb->type != FR_TYPE_OCTETS) { @@ -2144,7 +2156,7 @@ static xlat_action_t xlat_func_pack(TALLOC_CTX *ctx, fr_cursor_t *out, fr_assert(vb->vb_octets != NULL); } - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -2164,28 +2176,29 @@ static xlat_action_t xlat_func_pack(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_pairs(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_pairs(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { tmpl_t *vpt = NULL; fr_dcursor_t cursor; tmpl_cursor_ctx_t cc; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); /* * If there's no input, there's no output */ - if (!in) return XLAT_ACTION_DONE; + if (!in_head) return XLAT_ACTION_DONE; - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } fr_pair_t *vp; - if (tmpl_afrom_attr_str(ctx, NULL, &vpt, (*in)->vb_strvalue, + if (tmpl_afrom_attr_str(ctx, NULL, &vpt, in_head->vb_strvalue, &(tmpl_rules_t){ .dict_def = request->dict, .prefix = TMPL_ATTR_REF_PREFIX_AUTO @@ -2209,7 +2222,7 @@ static xlat_action_t xlat_func_pairs(TALLOC_CTX *ctx, fr_cursor_t *out, vb->vb_strvalue = buff; vb->vb_length = talloc_array_length(buff) - 1; - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); } tmpl_cursor_clear(&cc); talloc_free(vpt); @@ -2229,20 +2242,21 @@ static xlat_action_t xlat_func_pairs(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_rand(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_rand(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { int64_t result; - fr_value_box_t* vb; + fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); /* Make sure input can be converted to an unsigned 32 bit integer */ - if (fr_value_box_cast_in_place(ctx, (*in), FR_TYPE_UINT32, NULL) < 0) { + if (fr_value_box_cast_in_place(ctx, in_head, FR_TYPE_UINT32, NULL) < 0) { RPEDEBUG("Failed converting input to uint32"); return XLAT_ACTION_FAIL; } - result = (*in)->vb_uint32; + result = in_head->vb_uint32; /* Make sure it isn't too big */ if (result > (1 << 30)) result = (1 << 30); @@ -2253,7 +2267,7 @@ static xlat_action_t xlat_func_rand(TALLOC_CTX *ctx, fr_cursor_t *out, MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_UINT64, NULL, false)); vb->vb_uint64 = result; - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -2285,9 +2299,9 @@ static xlat_action_t xlat_func_rand(TALLOC_CTX *ctx, fr_cursor_t *out, @endverbatim * @ingroup xlat_functions */ -static xlat_action_t xlat_func_randstr(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_randstr(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { /* * Lookup tables for randstr char classes @@ -2308,6 +2322,7 @@ static xlat_action_t xlat_func_randstr(TALLOC_CTX *ctx, fr_cursor_t *out, unsigned int reps; size_t outlen = 0; fr_value_box_t* vb; + fr_value_box_t *in_head = fr_dlist_head(in); /** Max repetitions of a single character class * @@ -2317,18 +2332,17 @@ static xlat_action_t xlat_func_randstr(TALLOC_CTX *ctx, fr_cursor_t *out, /* * Nothing to do if input is empty */ - if (!(*in)) return XLAT_ACTION_DONE; - + if (!in_head) return XLAT_ACTION_DONE; /* * Concatenate all input */ - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - start = p = (*in)->vb_strvalue; - end = p + (*in)->vb_length; + start = p = in_head->vb_strvalue; + end = p + in_head->vb_length; /* * Calculate size of output @@ -2458,7 +2472,7 @@ static xlat_action_t xlat_func_randstr(TALLOC_CTX *ctx, fr_cursor_t *out, *buff_p++ = '\0'; - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -2476,14 +2490,15 @@ if ("foo" =~ /^(?.*)/) { * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_regex(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_regex(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { + fr_value_box_t *in_head = fr_dlist_head(in); /* * Return the complete capture if no other capture is specified */ - if (!(*in)) { + if (!in_head) { fr_value_box_t *vb; char *p; @@ -2496,12 +2511,12 @@ static xlat_action_t xlat_func_regex(TALLOC_CTX *ctx, fr_cursor_t *out, fr_assert(p); fr_value_box_bstrdup_buffer_shallow(NULL, vb, NULL, p, false); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } - switch ((*in)->type) { + switch (in_head->type) { /* * If the input is an integer value then get an * arbitrary subcapture index. @@ -2512,12 +2527,12 @@ static xlat_action_t xlat_func_regex(TALLOC_CTX *ctx, fr_cursor_t *out, fr_value_box_t *vb; char *p; - if ((*in)->next) { + if (fr_dlist_next(in, in_head)) { REDEBUG("Only one subcapture argument allowed"); return XLAT_ACTION_FAIL; } - if (fr_value_box_cast(NULL, &idx, FR_TYPE_UINT32, NULL, *in) < 0) { + if (fr_value_box_cast(NULL, &idx, FR_TYPE_UINT32, NULL, in_head) < 0) { RPEDEBUG("Bad subcapture index"); return XLAT_ACTION_FAIL; } @@ -2530,7 +2545,7 @@ static xlat_action_t xlat_func_regex(TALLOC_CTX *ctx, fr_cursor_t *out, } fr_assert(p); fr_value_box_bstrdup_buffer_shallow(NULL, vb, NULL, p, false); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -2543,13 +2558,13 @@ static xlat_action_t xlat_func_regex(TALLOC_CTX *ctx, fr_cursor_t *out, /* * Concatenate all input */ - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } MEM(vb = fr_value_box_alloc_null(ctx)); - if (regex_request_to_sub_named(vb, &p, request, (*in)->vb_strvalue) < 0) { + if (regex_request_to_sub_named(vb, &p, request, in_head->vb_strvalue) < 0) { REDEBUG2("No previous named regex capture group"); talloc_free(vb); return XLAT_ACTION_FAIL; @@ -2557,7 +2572,7 @@ static xlat_action_t xlat_func_regex(TALLOC_CTX *ctx, fr_cursor_t *out, fr_assert(p); fr_value_box_bstrdup_buffer_shallow(NULL, vb, NULL, p, false); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -2574,25 +2589,26 @@ static xlat_action_t xlat_func_regex(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_sha1(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_sha1(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { uint8_t digest[SHA1_DIGEST_LENGTH]; fr_sha1_ctx sha1_ctx; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); /* * Concatenate all input if there is some */ - if (*in && fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) { + if (in_head && fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } fr_sha1_init(&sha1_ctx); - if (*in) { - fr_sha1_update(&sha1_ctx, (*in)->vb_octets, (*in)->vb_length); + if (in_head) { + fr_sha1_update(&sha1_ctx, in_head->vb_octets, in_head->vb_length); } else { /* sha1 of empty string */ fr_sha1_update(&sha1_ctx, NULL, 0); @@ -2602,7 +2618,7 @@ static xlat_action_t xlat_func_sha1(TALLOC_CTX *ctx, fr_cursor_t *out, MEM(vb = fr_value_box_alloc_null(ctx)); fr_value_box_memdup(vb, vb, NULL, digest, sizeof(digest), false); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -2618,27 +2634,28 @@ static xlat_action_t xlat_func_sha1(TALLOC_CTX *ctx, fr_cursor_t *out, * @ingroup xlat_functions */ #ifdef HAVE_OPENSSL_EVP_H -static xlat_action_t xlat_evp_md(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_evp_md(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in, EVP_MD const *md) + fr_value_box_list_t *in, EVP_MD const *md) { uint8_t digest[EVP_MAX_MD_SIZE]; unsigned int digestlen; EVP_MD_CTX *md_ctx; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); /* * Concatenate all input if there is some */ - if (*in && fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) { + if (in_head && fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } md_ctx = EVP_MD_CTX_create(); EVP_DigestInit_ex(md_ctx, md, NULL); - if (*in) { - EVP_DigestUpdate(md_ctx, (*in)->vb_octets, (*in)->vb_length); + if (in_head) { + EVP_DigestUpdate(md_ctx, in_head->vb_octets, in_head->vb_length); } else { EVP_DigestUpdate(md_ctx, NULL, 0); } @@ -2648,15 +2665,15 @@ static xlat_action_t xlat_evp_md(TALLOC_CTX *ctx, fr_cursor_t *out, MEM(vb = fr_value_box_alloc_null(ctx)); fr_value_box_memdup(vb, vb, NULL, digest, digestlen, false); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } # define EVP_MD_XLAT(_md, _md_func) \ -static xlat_action_t xlat_func_##_md(TALLOC_CTX *ctx, fr_cursor_t *out,\ +static xlat_action_t xlat_func_##_md(TALLOC_CTX *ctx, fr_dcursor_t *out,\ request_t *request, void const *xlat_inst, void *xlat_thread_inst,\ - fr_value_box_t **in)\ + fr_value_box_list_t *in)\ {\ return xlat_evp_md(ctx, out, request, xlat_inst, xlat_thread_inst, in, EVP_##_md_func());\ } @@ -2686,23 +2703,24 @@ EVP_MD_XLAT(sha3_512, sha3_512) * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_string(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_string(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { - if (!*in) return XLAT_ACTION_DONE; + fr_value_box_t *in_head = fr_dlist_head(in); + if (!in_head) return XLAT_ACTION_DONE; /* * Concatenate all input */ - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - fr_cursor_append(out, *in); - *in = NULL; /* Let the caller know this was consumed */ + fr_dlist_remove(in, in_head); /* Let the caller know this was consumed */ + fr_dcursor_append(out, in_head); return XLAT_ACTION_DONE; } @@ -2719,30 +2737,31 @@ static xlat_action_t xlat_func_string(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_strlen(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_strlen(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, - UNUSED void *xlat_thread_inst, fr_value_box_t **in) + UNUSED void *xlat_thread_inst, fr_value_box_list_t *in) { fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); - if (!*in) { + if (!in_head) { MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_SIZE, NULL, false)); vb->vb_size = 0; - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } /* * Concatenate all input */ - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_SIZE, NULL, false)); - vb->vb_size = strlen((*in)->vb_strvalue); - fr_cursor_append(out, vb); + vb->vb_size = strlen(in_head->vb_strvalue); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -2766,9 +2785,9 @@ static xlat_action_t xlat_func_strlen(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_sub_regex(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_sub_regex(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { char const *p, *q, *end; char const *regex, *rep, *subject; @@ -2778,12 +2797,13 @@ static xlat_action_t xlat_func_sub_regex(TALLOC_CTX *ctx, fr_cursor_t *out, regex_t *pattern; fr_regex_flags_t flags; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); /* * If there's no input, there's no output */ - if (!*in) { + if (!in_head) { REDEBUG("No input arguments"); return XLAT_ACTION_FAIL; } @@ -2791,13 +2811,13 @@ static xlat_action_t xlat_func_sub_regex(TALLOC_CTX *ctx, fr_cursor_t *out, /* * Concatenate all input */ - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - p = (*in)->vb_strvalue; - end = p + (*in)->vb_length; + p = in_head->vb_strvalue; + end = p + in_head->vb_length; if (p == end) { REDEBUG("Regex must not be empty"); @@ -2882,9 +2902,9 @@ static xlat_action_t xlat_func_sub_regex(TALLOC_CTX *ctx, fr_cursor_t *out, talloc_free(pattern); return XLAT_ACTION_FAIL; } - fr_value_box_bstrdup_buffer_shallow(NULL, vb, NULL, buff, (*in)->tainted); + fr_value_box_bstrdup_buffer_shallow(NULL, vb, NULL, buff, in_head->tainted); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); talloc_free(pattern); @@ -2908,14 +2928,14 @@ static xlat_action_t xlat_func_sub_regex(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_sub(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_sub(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, #ifdef HAVE_REGEX_PCRE2 void const *xlat_inst, void *xlat_thread_inst, #else UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, #endif - fr_value_box_t **in) + fr_value_box_list_t *in) { char const *p, *q, *end; char *vb_str; @@ -2924,11 +2944,12 @@ static xlat_action_t xlat_func_sub(TALLOC_CTX *ctx, fr_cursor_t *out, size_t pattern_len, rep_len; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); /* * If there's no input, there's no output */ - if (!*in) { + if (!in_head) { REDEBUG("No input arguments"); return XLAT_ACTION_FAIL; } @@ -2936,13 +2957,13 @@ static xlat_action_t xlat_func_sub(TALLOC_CTX *ctx, fr_cursor_t *out, /* * Concatenate all input */ - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - p = (*in)->vb_strvalue; - end = p + (*in)->vb_length; + p = in_head->vb_strvalue; + end = p + in_head->vb_length; if (p == end) { REDEBUG("Substitution arguments must not be empty"); @@ -3002,14 +3023,14 @@ static xlat_action_t xlat_func_sub(TALLOC_CTX *ctx, fr_cursor_t *out, p = q + pattern_len; } - if (fr_value_box_bstrdup_buffer_shallow(vb, vb, NULL, vb_str, (*in)->vb_strvalue) < 0) { + if (fr_value_box_bstrdup_buffer_shallow(vb, vb, NULL, vb_str, in_head->vb_strvalue) < 0) { RPEDEBUG("Failed creating output box"); talloc_free(vb); return XLAT_ACTION_FAIL; } fr_assert(vb && (vb->type != FR_TYPE_INVALID)); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -3018,31 +3039,32 @@ static xlat_action_t xlat_func_sub(TALLOC_CTX *ctx, fr_cursor_t *out, * * If upper is true, change to uppercase, otherwise, change to lowercase */ -static xlat_action_t xlat_change_case(TALLOC_CTX *ctx, fr_cursor_t *out, - request_t *request, fr_value_box_t **in, bool upper) +static xlat_action_t xlat_change_case(TALLOC_CTX *ctx, fr_dcursor_t *out, + request_t *request, fr_value_box_list_t *in, bool upper) { char *buff_p; char const *p, *end; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); /* * If there's no input, there's no output */ - if (!*in) return XLAT_ACTION_DONE; + if (!in_head) return XLAT_ACTION_DONE; /* * Concatenate all input */ - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - p = (*in)->vb_strvalue; - end = p + (*in)->vb_length; + p = in_head->vb_strvalue; + end = p + in_head->vb_length; MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL, false)); - MEM(fr_value_box_bstr_alloc(vb, &buff_p, vb, NULL, (*in)->vb_length, (*in)->tainted) == 0); + MEM(fr_value_box_bstr_alloc(vb, &buff_p, vb, NULL, in_head->vb_length, in_head->tainted) == 0); while (p < end) { *(buff_p++) = upper ? toupper ((int) *(p++)) : tolower((int) *(p++)); @@ -3050,7 +3072,7 @@ static xlat_action_t xlat_change_case(TALLOC_CTX *ctx, fr_cursor_t *out, *buff_p = '\0'; - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -3067,9 +3089,9 @@ static xlat_action_t xlat_change_case(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_tolower(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_tolower(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { return xlat_change_case(ctx, out, request, in, false); } @@ -3086,9 +3108,9 @@ static xlat_action_t xlat_func_tolower(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_toupper(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_toupper(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { return xlat_change_case(ctx, out, request, in, true); } @@ -3103,30 +3125,31 @@ static xlat_action_t xlat_func_toupper(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_urlquote(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_urlquote(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { char const *p, *end; char *buff_p; size_t outlen = 0; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); /* * Nothing to do if input is empty */ - if (!(*in)) return XLAT_ACTION_DONE; + if (!in_head) return XLAT_ACTION_DONE; /* * Concatenate all input */ - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - p = (*in)->vb_strvalue; - end = p + (*in)->vb_length; + p = in_head->vb_strvalue; + end = p + in_head->vb_length; /* * Calculate size of output @@ -3148,7 +3171,7 @@ static xlat_action_t xlat_func_urlquote(TALLOC_CTX *ctx, fr_cursor_t *out, MEM(fr_value_box_bstr_alloc(vb, &buff_p, vb, NULL, outlen, false) == 0); /* Reset p to start position */ - p = (*in)->vb_strvalue; + p = in_head->vb_strvalue; while (p < end) { if (isalnum(*p)) { @@ -3174,7 +3197,7 @@ static xlat_action_t xlat_func_urlquote(TALLOC_CTX *ctx, fr_cursor_t *out, *buff_p = '\0'; - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -3191,31 +3214,32 @@ static xlat_action_t xlat_func_urlquote(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_urlunquote(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_urlunquote(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { char const *p, *end; char *buff_p; char *c1, *c2; size_t outlen = 0; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); /* * Nothing to do if input is empty */ - if (!*in) return XLAT_ACTION_DONE; + if (!in_head) return XLAT_ACTION_DONE; /* * Concatenate all input */ - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - p = (*in)->vb_strvalue; - end = p + (*in)->vb_length; + p = in_head->vb_strvalue; + end = p + in_head->vb_length; /* * Calculate size of output @@ -3233,7 +3257,7 @@ static xlat_action_t xlat_func_urlunquote(TALLOC_CTX *ctx, fr_cursor_t *out, MEM(fr_value_box_bstr_alloc(vb, &buff_p, vb, NULL, outlen, false) == 0); /* Reset p to start position */ - p = (*in)->vb_strvalue; + p = in_head->vb_strvalue; while (p < end) { if (*p != '%') { @@ -3245,7 +3269,7 @@ static xlat_action_t xlat_func_urlunquote(TALLOC_CTX *ctx, fr_cursor_t *out, /* Don't need \0 check, as it won't be in the hextab */ if (!(c1 = memchr(hextab, tolower(*++p), 16)) || !(c2 = memchr(hextab, tolower(*++p), 16))) { - REMARKER((*in)->vb_strvalue, p - (*in)->vb_strvalue, "Non-hex char in %% sequence"); + REMARKER(in_head->vb_strvalue, p - in_head->vb_strvalue, "Non-hex char in %% sequence"); talloc_free(vb); return XLAT_ACTION_FAIL; @@ -3255,7 +3279,7 @@ static xlat_action_t xlat_func_urlunquote(TALLOC_CTX *ctx, fr_cursor_t *out, } *buff_p = '\0'; - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } diff --git a/src/lib/unlang/xlat_eval.c b/src/lib/unlang/xlat_eval.c index e47cbf683f2..315f969ccf2 100644 --- a/src/lib/unlang/xlat_eval.c +++ b/src/lib/unlang/xlat_eval.c @@ -177,7 +177,7 @@ static char *xlat_fmt_aprint(TALLOC_CTX *ctx, xlat_exp_t const *node) * @param[in] node Being processed. * @param[in] args from previous expansion. */ -static inline void xlat_debug_log_expansion(request_t *request, xlat_exp_t const *node, fr_value_box_t const *args) +static inline void xlat_debug_log_expansion(request_t *request, xlat_exp_t const *node, fr_value_box_list_t const *args) { char *str; @@ -198,6 +198,18 @@ static inline void xlat_debug_log_expansion(request_t *request, xlat_exp_t const talloc_free(str); } +/** Output the list result of an expansion + * + * @param[in] request The current request. + * @param[in] result of the expansion. + */ +static inline void xlat_debug_log_list_result(request_t *request, fr_value_box_list_t const *result) +{ + if (!RDEBUG_ENABLED2) return; + + RDEBUG2(" --> %pM", result); +} + /** Output the result of an expansion * * @param[in] request The current request. @@ -207,7 +219,7 @@ static inline void xlat_debug_log_result(request_t *request, fr_value_box_t cons { if (!RDEBUG_ENABLED2) return; - RDEBUG2(" --> %pM", result); + RDEBUG2(" --> %pV", result); } /** One letter expansions @@ -221,7 +233,7 @@ static inline void xlat_debug_log_result(request_t *request, fr_value_box_t cons * - #XLAT_ACTION_DONE if we're done processing this node. * */ -static xlat_action_t xlat_eval_one_letter(TALLOC_CTX *ctx, fr_cursor_t *out, request_t *request, char letter) +static xlat_action_t xlat_eval_one_letter(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, char letter) { char buffer[64]; @@ -387,8 +399,8 @@ static xlat_action_t xlat_eval_one_letter(TALLOC_CTX *ctx, fr_cursor_t *out, req return XLAT_ACTION_FAIL; } - fr_cursor_append(out, value); - fr_cursor_next(out); /* Advance to our first value */ + fr_dcursor_append(out, value); + fr_dcursor_next(out); /* Advance to our first value */ return XLAT_ACTION_DONE; } @@ -407,7 +419,7 @@ static xlat_action_t xlat_eval_one_letter(TALLOC_CTX *ctx, fr_cursor_t *out, req * - #XLAT_ACTION_FAIL on memory allocation errors. * - #XLAT_ACTION_DONE if we're done processing this node. */ -static xlat_action_t xlat_eval_pair_virtual(TALLOC_CTX *ctx, fr_cursor_t *out, request_t *request, tmpl_t const *vpt) +static xlat_action_t xlat_eval_pair_virtual(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, tmpl_t const *vpt) { fr_radius_packet_t *packet = NULL; fr_value_box_t *value; @@ -539,8 +551,8 @@ static xlat_action_t xlat_eval_pair_virtual(TALLOC_CTX *ctx, fr_cursor_t *out, r } done: - fr_cursor_append(out, value); - fr_cursor_next(out); /* Advance to our first value */ + fr_dcursor_append(out, value); + fr_dcursor_next(out); /* Advance to our first value */ return XLAT_ACTION_DONE; } @@ -556,7 +568,7 @@ done: * - #XLAT_ACTION_FAIL we failed getting a value for the attribute. * - #XLAT_ACTION_DONE we successfully evaluated the xlat. */ -static xlat_action_t xlat_eval_pair_real(TALLOC_CTX *ctx, fr_cursor_t *out, request_t *request, tmpl_t const *vpt) +static xlat_action_t xlat_eval_pair_real(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, tmpl_t const *vpt) { fr_pair_t *vp = NULL; fr_value_box_t *value; @@ -598,8 +610,8 @@ static xlat_action_t xlat_eval_pair_real(TALLOC_CTX *ctx, fr_cursor_t *out, requ goto done; } value->datum.int32 = 0; - fr_cursor_append(out, value); - fr_cursor_next(out); /* Advance to our first value */ + fr_dcursor_append(out, value); + fr_dcursor_next(out); /* Advance to our first value */ } /* Fall through to being done */ goto done; @@ -620,8 +632,8 @@ static xlat_action_t xlat_eval_pair_real(TALLOC_CTX *ctx, fr_cursor_t *out, requ value = fr_value_box_alloc(ctx, FR_TYPE_UINT32, NULL, false); value->datum.uint32 = count; - fr_cursor_append(out, value); - fr_cursor_next(out); /* Advance to our first value */ + fr_dcursor_append(out, value); + fr_dcursor_next(out); /* Advance to our first value */ break; } @@ -640,9 +652,9 @@ static xlat_action_t xlat_eval_pair_real(TALLOC_CTX *ctx, fr_cursor_t *out, requ vp = fr_dcursor_next(&cursor)) { value = fr_value_box_alloc(ctx, vp->data.type, vp->da, vp->data.tainted); fr_value_box_copy(value, value, &vp->data); - fr_cursor_append(out, value); + fr_dcursor_append(out, value); } - fr_cursor_next(out); /* Advance to our first value */ + fr_dcursor_next(out); /* Advance to our first value */ break; default: @@ -655,8 +667,8 @@ static xlat_action_t xlat_eval_pair_real(TALLOC_CTX *ctx, fr_cursor_t *out, requ if (!value) goto oom; fr_value_box_copy(value, value, &vp->data); /* Also dups taint */ - fr_cursor_append(out, value); - fr_cursor_next(out); /* Advance to our first value */ + fr_dcursor_append(out, value); + fr_dcursor_next(out); /* Advance to our first value */ break; } @@ -695,9 +707,9 @@ void xlat_signal(xlat_func_signal_t signal, xlat_exp_t const *exp, * @param[in] rctx Opaque (to us), resume ctx provided by xlat function * when it yielded. */ -xlat_action_t xlat_frame_eval_resume(TALLOC_CTX *ctx, fr_cursor_t *out, +xlat_action_t xlat_frame_eval_resume(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_func_resume_t resume, xlat_exp_t const *exp, - request_t *request, fr_value_box_t **result, void *rctx) + request_t *request, fr_value_box_list_t *result, void *rctx) { xlat_thread_inst_t *thread_inst = xlat_thread_instance_find(exp); xlat_action_t xa; @@ -708,9 +720,9 @@ xlat_action_t xlat_frame_eval_resume(TALLOC_CTX *ctx, fr_cursor_t *out, * to debug problems if they free or change elements * and don't remove them from the list. */ - if (*result) (void) talloc_list_get_type_abort(*result, fr_value_box_t); + if (!fr_dlist_empty(result)) { fr_dlist_verify(result); } xa = resume(ctx, out, request, exp->call.inst, thread_inst->data, result, rctx); - if (*result) (void) talloc_list_get_type_abort(*result, fr_value_box_t); + if (!fr_dlist_empty(result)) { fr_dlist_verify(result); } RDEBUG2("EXPAND %%{%s:...}", exp->call.func->name); switch (xa) { @@ -722,8 +734,8 @@ xlat_action_t xlat_frame_eval_resume(TALLOC_CTX *ctx, fr_cursor_t *out, break; case XLAT_ACTION_DONE: - fr_cursor_next(out); /* Wind to the start of this functions output */ - RDEBUG2(" --> %pM", fr_cursor_current(out)); + fr_dcursor_next(out); /* Wind to the start of this functions output */ + RDEBUG2(" --> %pV", fr_dcursor_current(out)); break; case XLAT_ACTION_FAIL: @@ -749,14 +761,14 @@ xlat_action_t xlat_frame_eval_resume(TALLOC_CTX *ctx, fr_cursor_t *out, * additional #xlat_exp_t. * @param[in] result of a previous nested evaluation. */ -xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out, +xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_t const **child, bool *alternate, request_t *request, xlat_exp_t const **in, - fr_value_box_t **result) + fr_value_box_list_t *result) { xlat_exp_t const *node = *in; - fr_cursor_tail(out); /* Needed for reentrant behaviour and debugging */ + fr_dcursor_tail(out); /* Needed for reentrant behaviour and debugging */ switch (node->type) { case XLAT_FUNC: @@ -768,9 +780,9 @@ xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out, char *result_str = NULL; ssize_t slen; - if (*result) { - (void) talloc_list_get_type_abort(*result, fr_value_box_t); - result_str = fr_value_box_list_aprint(NULL, *result, NULL, NULL); + if (!fr_dlist_empty(result)) { + fr_dlist_verify(result); + result_str = fr_value_box_list_aprint(NULL, result, NULL, NULL); if (!result_str) return XLAT_ACTION_FAIL; } else { result_str = talloc_typed_strdup(NULL, ""); @@ -787,7 +799,7 @@ xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out, slen = node->call.func->func.sync(value, &str, node->call.func->buf_len, node->call.func->mod_inst, NULL, request, result_str); - xlat_debug_log_expansion(request, *in, *result); + xlat_debug_log_expansion(request, *in, result); if (slen < 0) { talloc_free(value); talloc_free(result_str); @@ -809,7 +821,7 @@ xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out, fr_value_box_bstrdup_buffer_shallow(NULL, value, NULL, str, false); } - fr_cursor_append(out, value); /* Append the result of the expansion */ + fr_dcursor_append(out, value); /* Append the result of the expansion */ talloc_free(result_str); xlat_debug_log_result(request, value); } @@ -819,26 +831,26 @@ xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out, { xlat_action_t xa; xlat_thread_inst_t *thread_inst; - fr_value_box_t *result_copy = NULL; + fr_value_box_list_t result_copy; + fr_value_box_list_init(&result_copy); thread_inst = xlat_thread_instance_find(node); XLAT_DEBUG("** [%i] %s(func-async) - %%{%s:%pM}", unlang_interpret_stack_depth(request), __FUNCTION__, - node->fmt, *result); + node->fmt, result); /* * Need to copy the input list in case * the async function mucks with it. */ - if (RDEBUG_ENABLED2) fr_value_box_list_acopy(NULL, &result_copy, *result); + if (RDEBUG_ENABLED2) fr_value_box_list_acopy(NULL, &result_copy, result); - if (*result) (void) talloc_list_get_type_abort(*result, fr_value_box_t); + if (!fr_dlist_empty(result)) { fr_dlist_verify(result); } xa = node->call.func->func.async(ctx, out, request, node->call.inst->data, thread_inst->data, result); - if (*result) (void) talloc_list_get_type_abort(*result, fr_value_box_t); - + if (!fr_dlist_empty(result)) { fr_dlist_verify(result); } if (RDEBUG_ENABLED2) { - xlat_debug_log_expansion(request, *in, result_copy); - talloc_list_free(&result_copy); + xlat_debug_log_expansion(request, *in, &result_copy); + fr_dlist_talloc_free(&result_copy); } switch (xa) { case XLAT_ACTION_FAIL: @@ -853,8 +865,8 @@ xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out, return xa; case XLAT_ACTION_DONE: /* Process the result */ - fr_cursor_next(out); - xlat_debug_log_result(request, fr_cursor_current(out)); + fr_dcursor_next(out); + xlat_debug_log_result(request, fr_dcursor_current(out)); break; } break; @@ -864,14 +876,14 @@ xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out, case XLAT_ALTERNATE: { - fr_cursor_t from; + fr_dcursor_t from; fr_assert(alternate); /* * No result from the first child, try the alternate */ - if (!*result) { + if (fr_dlist_empty(result)) { /* * Already tried the alternate */ @@ -896,25 +908,24 @@ xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out, *alternate = false; /* Reset */ xlat_debug_log_expansion(request, *in, NULL); - xlat_debug_log_result(request, *result); + xlat_debug_log_list_result(request, result); - (void) talloc_list_get_type_abort(*result, fr_value_box_t); - fr_cursor_init(&from, result); - fr_cursor_merge(out, &from); - fr_assert(!*result); + fr_dlist_verify(result); + fr_dcursor_init(&from, result); + fr_dcursor_merge(out, &from); + fr_assert(fr_dlist_empty(result)); } break; case XLAT_GROUP: { fr_value_box_t *value; - fr_cursor_t from; XLAT_DEBUG("** [%i] %s(child) - continuing %%{%s ...}", unlang_interpret_stack_depth(request), __FUNCTION__, node->fmt); - fr_assert(*result != NULL); - (void) talloc_list_get_type_abort(*result, fr_value_box_t); + fr_assert(!fr_dlist_empty(result)); + fr_dlist_verify(result); /* * If the input is a series of xlat expansions, @@ -927,28 +938,25 @@ xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out, MEM(value = fr_value_box_alloc_null(ctx)); - if (*result) { - (void) talloc_list_get_type_abort(*result, fr_value_box_t); - str = fr_value_box_list_aprint(value, *result, NULL, NULL); + if (!fr_dlist_empty(result)) { + fr_dlist_verify(result); + str = fr_value_box_list_aprint(value, result, NULL, NULL); if (!str) return XLAT_ACTION_FAIL; } else { str = talloc_typed_strdup(value, ""); } - fr_value_box_strdup_shallow(value, NULL, str, fr_value_box_list_tainted(*result)); - talloc_free(*result); - *result = value; + fr_value_box_strdup_shallow(value, NULL, str, fr_value_box_list_tainted(result)); + fr_dlist_talloc_free(result); + fr_dlist_insert_head(result, value); } MEM(value = fr_value_box_alloc(ctx, FR_TYPE_GROUP, NULL, false)); - value->vb_group = *result; - *result = NULL; + fr_dlist_move(&value->vb_group, result); xlat_debug_log_expansion(request, *in, NULL); xlat_debug_log_result(request, value); - fr_cursor_init(&from, &value); - fr_cursor_merge(out, &from); - fr_assert(!value); + fr_dcursor_insert(out, value); } break; @@ -990,7 +998,7 @@ xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out, * - XLAT_ACTION_DONE we're done, pop the frame. * - XLAT_ACTION_FAIL an xlat module failed. */ -xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_cursor_t *out, xlat_exp_t const **child, +xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_t const **child, request_t *request, xlat_exp_t const **in) { xlat_exp_t const *node = *in; @@ -1005,7 +1013,7 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_cursor_t *out, xlat_exp_t cons for (node = *in; node; node = (*in)->next) { *in = node; /* Update node in our caller */ - fr_cursor_tail(out); /* Needed for debugging */ + fr_dcursor_tail(out); /* Needed for debugging */ switch (node->type) { case XLAT_LITERAL: @@ -1026,7 +1034,7 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_cursor_t *out, xlat_exp_t cons */ MEM(value = fr_value_box_alloc_null(ctx)); fr_value_box_bstrdup_buffer(value, value, NULL, node->fmt, false); - fr_cursor_append(out, value); + fr_dcursor_append(out, value); continue; case XLAT_ONE_LETTER: @@ -1036,11 +1044,11 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_cursor_t *out, xlat_exp_t cons xlat_debug_log_expansion(request, node, NULL); if (xlat_eval_one_letter(ctx, out, request, node->fmt[0]) == XLAT_ACTION_FAIL) { fail: - fr_cursor_free_list(out); /* Only frees what we've added during this call */ + fr_dcursor_free_list(out); /* Only frees what we've added during this call */ xa = XLAT_ACTION_FAIL; goto finish; } - xlat_debug_log_result(request, fr_cursor_current(out)); + xlat_debug_log_result(request, fr_dcursor_current(out)); continue; case XLAT_ATTRIBUTE: @@ -1049,7 +1057,7 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_cursor_t *out, xlat_exp_t cons xlat_debug_log_expansion(request, node, NULL); if (xlat_eval_pair_real(ctx, out, request, node->attr) == XLAT_ACTION_FAIL) goto fail; - xlat_debug_log_result(request, fr_cursor_current(out)); + xlat_debug_log_result(request, fr_dcursor_current(out)); continue; case XLAT_VIRTUAL: @@ -1071,16 +1079,17 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_cursor_t *out, xlat_exp_t cons if (slen == 0) continue; fr_value_box_bstrdup_buffer_shallow(NULL, value, NULL, str, false); - fr_cursor_append(out, value); - fr_cursor_next(out); + fr_dcursor_append(out, value); + fr_dcursor_next(out); - xlat_debug_log_result(request, fr_cursor_current(out)); + xlat_debug_log_result(request, fr_dcursor_current(out)); } continue; case XLAT_FUNC: { - fr_value_box_t *result = NULL; + fr_value_box_list_t result; + fr_value_box_list_init(&result); XLAT_DEBUG("** [%i] %s(func) - %%{%s:...}", unlang_interpret_stack_depth(request), __FUNCTION__, node->fmt); @@ -1117,7 +1126,7 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_cursor_t *out, xlat_exp_t cons continue; } fr_value_box_bstrdup_buffer_shallow(NULL, value, NULL, str, false); - fr_cursor_append(out, value); + fr_dcursor_append(out, value); } continue; #endif @@ -1173,10 +1182,12 @@ static char *xlat_sync_eval(TALLOC_CTX *ctx, request_t *request, xlat_exp_t cons ssize_t slen; char *str = NULL, *child; char const *p; - fr_value_box_t *head = NULL, string, *value; - fr_cursor_t cursor; + fr_value_box_t string, *value; + fr_value_box_list_t head; + fr_dcursor_t cursor; - fr_cursor_talloc_init(&cursor, &head, fr_value_box_t); + fr_value_box_list_init(&head); + fr_dcursor_talloc_init(&cursor, &head, fr_value_box_t); XLAT_DEBUG("%.*sxlat aprint %d %s", lvl, xlat_spaces, node->type, node->fmt); @@ -1203,20 +1214,20 @@ static char *xlat_sync_eval(TALLOC_CTX *ctx, request_t *request, xlat_exp_t cons * cast to a string until we're actually doing * the concatenation. */ - if (fr_value_box_cast(ctx, &string, FR_TYPE_STRING, NULL, head) < 0) { + if (fr_value_box_cast(ctx, &string, FR_TYPE_STRING, NULL, fr_dlist_head(&head)) < 0) { RPERROR("Casting one letter expansion to string failed"); - fr_cursor_free_list(&cursor); + fr_dcursor_free_list(&cursor); return NULL; } memcpy(&str, &string.vb_strvalue, sizeof(str)); - fr_cursor_free_list(&cursor); + fr_dcursor_free_list(&cursor); break; case XLAT_ATTRIBUTE: XLAT_DEBUG("xlat_sync_eval ATTR"); if (xlat_eval_pair_real(ctx, &cursor, request, node->attr) == XLAT_ACTION_FAIL) return NULL; - value = fr_cursor_head(&cursor); + value = fr_dcursor_head(&cursor); if (!value) return NULL; /* @@ -1228,7 +1239,7 @@ static char *xlat_sync_eval(TALLOC_CTX *ctx, request_t *request, xlat_exp_t cons if (!str) { attr_error: RPERROR("Printing box to string failed"); - fr_cursor_free_list(&cursor); + fr_dcursor_free_list(&cursor); return NULL; } @@ -1237,7 +1248,7 @@ static char *xlat_sync_eval(TALLOC_CTX *ctx, request_t *request, xlat_exp_t cons * temporarily until we do aggregation with * value boxes. */ - while ((value = fr_cursor_next(&cursor))) { + while ((value = fr_dcursor_next(&cursor))) { char *more; fr_value_box_aprint(ctx, &more, value, &fr_value_escape_double); @@ -1246,7 +1257,7 @@ static char *xlat_sync_eval(TALLOC_CTX *ctx, request_t *request, xlat_exp_t cons str = talloc_strdup_append_buffer(str, more); talloc_free(more); } - fr_cursor_free_list(&cursor); + fr_dcursor_free_list(&cursor); break; case XLAT_VIRTUAL: @@ -1272,9 +1283,9 @@ static char *xlat_sync_eval(TALLOC_CTX *ctx, request_t *request, xlat_exp_t cons * Will not handle yields. */ if (node->call.func->type == XLAT_FUNC_NORMAL) { - fr_value_box_t *result = NULL; + fr_value_box_list_t result; TALLOC_CTX *pool = talloc_new(NULL); - + fr_value_box_list_init(&result); /* * Use the unlang stack to evaluate * the async xlat up until the point @@ -1301,8 +1312,8 @@ static char *xlat_sync_eval(TALLOC_CTX *ctx, request_t *request, xlat_exp_t cons return NULL; } - if (result) { - str = fr_value_box_list_aprint(ctx, result, NULL, &fr_value_escape_double); + if (!fr_dlist_empty(&result)) { + str = fr_value_box_list_aprint(ctx, &result, NULL, &fr_value_escape_double); if (!str) { RPEDEBUG("Failed concatenating xlat result string"); talloc_free(pool); diff --git a/src/lib/unlang/xlat_priv.h b/src/lib/unlang/xlat_priv.h index 7c174bfae53..b03079fd9b6 100644 --- a/src/lib/unlang/xlat_priv.h +++ b/src/lib/unlang/xlat_priv.h @@ -162,16 +162,16 @@ xlat_t *xlat_func_find(char const *name, ssize_t namelen); void xlat_signal(xlat_func_signal_t signal, xlat_exp_t const *exp, request_t *request, void *rctx, fr_state_signal_t action); -xlat_action_t xlat_frame_eval_resume(TALLOC_CTX *ctx, fr_cursor_t *out, +xlat_action_t xlat_frame_eval_resume(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_func_resume_t resume, xlat_exp_t const *exp, - request_t *request, fr_value_box_t **result, void *rctx); + request_t *request, fr_value_box_list_t *result, void *rctx); -xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out, +xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_t const **child, bool *alternate, request_t *request, xlat_exp_t const **in, - fr_value_box_t **result) CC_HINT(nonnull(1,2,3,5,6)); + fr_value_box_list_t *result) CC_HINT(nonnull(1,2,3,5,6)); -xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_cursor_t *out, xlat_exp_t const **child, +xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_t const **child, request_t *request, xlat_exp_t const **in); int xlat_eval_walk(xlat_exp_t *exp, xlat_walker_t walker, xlat_type_t type, void *uctx); diff --git a/src/lib/util/base.h b/src/lib/util/base.h index 59ba921a08f..f4a7795d9ef 100644 --- a/src/lib/util/base.h +++ b/src/lib/util/base.h @@ -35,7 +35,6 @@ RCSIDH(libradius_h, "$Id$") #include #include #include -#include #include #include #include diff --git a/src/lib/util/print.c b/src/lib/util/print.c index 5ead4b6ac4c..eeb132bbc8c 100644 --- a/src/lib/util/print.c +++ b/src/lib/util/print.c @@ -776,7 +776,7 @@ char *fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap) case 'M': { - fr_value_box_t const *in = va_arg(ap_q, fr_value_box_t const *); + fr_value_box_list_t const *in = va_arg(ap_q, fr_value_box_list_t const *); if (!in) { subst = talloc_strdup(NULL, "(null)"); diff --git a/src/lib/util/value.c b/src/lib/util/value.c index 6b38f8aeff5..094ad195b68 100644 --- a/src/lib/util/value.c +++ b/src/lib/util/value.c @@ -49,7 +49,7 @@ RCSID("$Id$") #undef _VALUE_PRIVATE #include -#include +#include #include #include #include @@ -500,7 +500,7 @@ static inline void fr_value_box_copy_meta(fr_value_box_t *dst, fr_value_box_t co dst->enumv = src->enumv; dst->type = src->type; dst->tainted = src->tainted; - dst->next = NULL; /* copy one */ + fr_dlist_entry_init(&dst->entry); } /** Compare two values @@ -1811,8 +1811,7 @@ static inline int fr_value_box_cast_to_strvalue(TALLOC_CTX *ctx, fr_value_box_t case FR_TYPE_GROUP: { - fr_cursor_t cursor; - fr_value_box_t *vb; + fr_value_box_t *vb = NULL; /* * Initialise an empty buffer we can @@ -1820,9 +1819,7 @@ static inline int fr_value_box_cast_to_strvalue(TALLOC_CTX *ctx, fr_value_box_t */ if (fr_value_box_bstrndup(ctx, dst, dst_enumv, NULL, 0, src->tainted) < 0) return -1; - for (vb = fr_cursor_init(&cursor, &src->vb_group); - vb; - vb = fr_cursor_next(&cursor)) { + while ((vb = fr_dlist_next(&src->vb_group, vb))) { /* * Attempt to cast to a string so * we can append. @@ -1895,8 +1892,7 @@ static inline int fr_value_box_cast_to_octets(TALLOC_CTX *ctx, fr_value_box_t *d case FR_TYPE_GROUP: { - fr_cursor_t cursor; - fr_value_box_t *vb; + fr_value_box_t *vb = NULL; /* * Initialise an empty buffer we can @@ -1904,9 +1900,7 @@ static inline int fr_value_box_cast_to_octets(TALLOC_CTX *ctx, fr_value_box_t *d */ if (fr_value_box_memdup(ctx, dst, dst_enumv, NULL, 0, src->tainted) < 0) return -1; - for (vb = fr_cursor_init(&cursor, &src->vb_group); - vb; - vb = fr_cursor_next(&cursor)) { + while ((vb = fr_dlist_next(&src->vb_group, vb))) { /* * Attempt to cast to octets so * we can append; @@ -3020,6 +3014,13 @@ int fr_value_box_cast_in_place(TALLOC_CTX *ctx, fr_value_box_t *vb, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv) { fr_value_box_t tmp; + /* + * Store list poiters to restore later - fr_value_box_cast clears them + */ + fr_dlist_t entry = { + .next = vb->entry.next, + .prev = vb->entry.prev + }; /* * Simple case, destination type and current @@ -3042,6 +3043,12 @@ int fr_value_box_cast_in_place(TALLOC_CTX *ctx, fr_value_box_t *vb, fr_value_box_clear(&tmp); /* Clear out any old buffers */ + /* + * Restore list pointers + */ + vb->entry.next = entry.next; + vb->entry.prev = entry.prev; + return 0; } @@ -3128,31 +3135,13 @@ void fr_value_box_clear_value(fr_value_box_t *data) * This ensures orderly freeing, regardless * of talloc hierarchy. */ - switch (data->datum.children.type) { - case FR_VALUE_BOX_LIST_SINGLE: - { - fr_cursor_t cursor; - fr_value_box_t *vb; - - for (vb = fr_cursor_init(&cursor, &data->datum.children.slist); - vb; - vb = fr_cursor_next(&cursor)) { - fr_value_box_clear_value(vb); - talloc_free(vb); - } - } - break; - - case FR_VALUE_BOX_LIST_DOUBLE: { fr_value_box_t *vb = NULL; - while ((vb = fr_dlist_next(&data->datum.children.dlist, vb))) { + while ((vb = fr_dlist_next(&data->datum.children, vb))) { fr_value_box_clear_value(vb); talloc_free(vb); } - } - break; } return; @@ -4549,7 +4538,7 @@ finish: * Fixup enumvs */ dst->enumv = dst_enumv; - dst->next = NULL; + fr_dlist_entry_init(&dst->entry); return 0; } @@ -4799,7 +4788,7 @@ ssize_t fr_value_box_print(fr_sbuff_t *out, fr_value_box_t const *data, fr_sbuff /* * Be lazy by just converting it to a string, and then printing the string. */ - if (fr_value_box_cast_to_strvalue(NULL, &vb, FR_TYPE_STRING, NULL, data->vb_group) < 0) return 0; + if (fr_value_box_cast_to_strvalue(NULL, &vb, FR_TYPE_STRING, NULL, data) < 0) return 0; slen = fr_value_box_print(&our_out, &vb, e_rules); fr_value_box_clear(&vb); @@ -4869,13 +4858,14 @@ ssize_t fr_value_box_print_quoted(fr_sbuff_t *out, fr_value_box_t const *data, f * - -1 on failure. */ int fr_value_box_list_concat(TALLOC_CTX *ctx, - fr_value_box_t *out, fr_value_box_t **list, fr_type_t type, bool free_input) + fr_value_box_t *out, fr_value_box_list_t *list, fr_type_t type, bool free_input) { TALLOC_CTX *pool; - fr_cursor_t cursor; + fr_dcursor_t cursor; fr_value_box_t const *vb; + fr_value_box_t *head_vb; - if (!list || !*list) { + if (!list || fr_dlist_empty(list)) { fr_strerror_const("Invalid arguments. List was NULL"); return -1; } @@ -4891,15 +4881,19 @@ int fr_value_box_list_concat(TALLOC_CTX *ctx, return -1; } - fr_cursor_init(&cursor, list); + head_vb = fr_dlist_head(list); + fr_dcursor_init(&cursor, list); /* * Allow concatenating in place */ - if (out == *list) { - if ((*list)->type != type) { + if (out == head_vb) { + if (head_vb->type != type) { fr_value_box_t from_cast; - fr_value_box_t *next = out->next; + fr_dlist_t entry = { + .next = out->entry.next, + .prev = out->entry.prev + }; /* * Two phase, as the casting code doesn't @@ -4907,30 +4901,33 @@ int fr_value_box_list_concat(TALLOC_CTX *ctx, */ if (fr_value_box_cast(ctx, &from_cast, type, NULL, out) < 0) return -1; if (fr_value_box_copy(ctx, out, &from_cast) < 0) return -1; - out->next = next; /* Restore the next pointer */ + + out->entry.next = entry.next; /* Restore the list pointers */ + out->entry.prev = entry.prev; + } - fr_cursor_next(&cursor); + fr_dcursor_next(&cursor); } else { - if (fr_value_box_cast(ctx, out, type, NULL, *list) < 0) return -1; /* Decomposes to copy */ + if (fr_value_box_cast(ctx, out, type, NULL, head_vb) < 0) return -1; /* Decomposes to copy */ if (free_input) { - fr_cursor_free_item(&cursor); /* Advances cursor */ + fr_dcursor_free_item(&cursor); /* Advances cursor */ } else { - fr_cursor_next(&cursor); + fr_dcursor_next(&cursor); } } /* * Imploding a one element list. */ - if (!fr_cursor_current(&cursor)) return 0; + if (!fr_dcursor_current(&cursor)) return 0; pool = talloc_pool(NULL, 255); /* To absorb the temporary strings */ /* * Join the remaining values */ - while ((vb = fr_cursor_current(&cursor))) { + while ((vb = fr_dcursor_current(&cursor))) { fr_value_box_t from_cast; fr_value_box_t const *n; @@ -4959,9 +4956,9 @@ int fr_value_box_list_concat(TALLOC_CTX *ctx, } if (free_input) { - fr_cursor_free_item(&cursor); /* Advances cursor */ + fr_dcursor_free_item(&cursor); /* Advances cursor */ } else { - fr_cursor_next(&cursor); + fr_dcursor_next(&cursor); } } @@ -4973,25 +4970,25 @@ int fr_value_box_list_concat(TALLOC_CTX *ctx, /** Concatenate the string representations of a list of value boxes together * * @param[in] ctx to allocate the buffer in. - * @param[in] head of the list of value boxes. + * @param[in] list of value boxes. * @param[in] delim to insert between value box values. * @param[in] e_rules to control escaping of the concatenated elements. * @return * - NULL on error. * - The concatenation of the string values of the value box list on success. */ -char *fr_value_box_list_aprint(TALLOC_CTX *ctx, fr_value_box_t const *head, char const *delim, +char *fr_value_box_list_aprint(TALLOC_CTX *ctx, fr_value_box_list_t const *list, char const *delim, fr_sbuff_escape_rules_t const *e_rules) { - fr_value_box_t const *vb = head; + fr_value_box_t const *vb = fr_dlist_head(list); char *aggr, *td = NULL; TALLOC_CTX *pool = NULL; - if (!head) return NULL; + if (!vb) return NULL; fr_value_box_aprint(ctx, &aggr, vb, e_rules); if (!aggr) return NULL; - if (!vb->next) return aggr; + if (!fr_dlist_next(list, vb)) return aggr; /* * If we're aggregating more values, @@ -5000,7 +4997,7 @@ char *fr_value_box_list_aprint(TALLOC_CTX *ctx, fr_value_box_t const *head, char pool = talloc_pool(NULL, 255); if (delim) td = talloc_typed_strdup(pool, delim); - while ((vb = vb->next)) { + while ((vb = fr_dlist_next(list, vb))) { char *str, *new_aggr; fr_value_box_aprint(pool, &str, vb, e_rules); @@ -5051,12 +5048,13 @@ uint32_t fr_value_box_hash_update(fr_value_box_t const *vb, uint32_t hash) * - >= 0 number of array elements in argv * - <0 on error */ -int fr_value_box_list_flatten_argv(TALLOC_CTX *ctx, char ***argv_p, fr_value_box_t const *in) +int fr_value_box_list_flatten_argv(TALLOC_CTX *ctx, char ***argv_p, fr_value_box_list_t const *in) { int i, argc; char **argv; + fr_value_box_t *head = fr_dlist_head(in); - if (in->type != FR_TYPE_GROUP) { + if (head->type != FR_TYPE_GROUP) { argc = 1; } else { @@ -5066,21 +5064,21 @@ int fr_value_box_list_flatten_argv(TALLOC_CTX *ctx, char ***argv_p, fr_value_box argv = talloc_zero_array(ctx, char *, argc + 1); if (!argv) return -1; - if (in->type != FR_TYPE_GROUP) { - fr_value_box_aprint(argv, &argv[0], in, NULL); + if (head->type != FR_TYPE_GROUP) { + fr_value_box_aprint(argv, &argv[0], head, NULL); } else { fr_value_box_t const *in_p; /* * Print the children of each group into the argv array. */ - for (in_p = in, i = 0; + for (in_p = head, i = 0; in_p; - in_p = in_p->next) { - if (!in_p->vb_group) { + in_p = fr_dlist_next(in, in_p)) { + if (fr_dlist_empty(&in_p->vb_group)) { argv[i] = talloc_typed_strdup(argv, ""); } else { - fr_value_box_aprint(argv, &argv[i], in_p->vb_group, NULL); + fr_value_box_aprint(argv, &argv[i], in_p, NULL); } if (!argv[i]) { talloc_free(argv); @@ -5116,30 +5114,22 @@ int fr_value_box_list_flatten_argv(TALLOC_CTX *ctx, char ***argv_p, fr_value_box * - A duplicate list of value boxes, allocated in the context of 'ctx' * - NULL on error, or empty input list. */ -int fr_value_box_list_acopy(TALLOC_CTX *ctx, fr_value_box_t **out, fr_value_box_t const *in) +int fr_value_box_list_acopy(TALLOC_CTX *ctx, fr_value_box_list_t *out, fr_value_box_list_t const *in) { - fr_value_box_t const *in_p; - fr_cursor_t cursor; - - *out = NULL; - - fr_cursor_init(&cursor, out); + fr_value_box_t const *in_p = NULL; - for (in_p = in; - in_p; - in_p = in_p->next) { + while ((in_p = fr_dlist_next(in, in_p))) { fr_value_box_t *n = NULL; n = fr_value_box_alloc_null(ctx); if (!n) { error: - fr_cursor_head(&cursor); - fr_cursor_free_list(&cursor); + fr_dlist_talloc_free(out); return -1; } if (fr_value_box_copy(n, n, in_p) < 0) goto error; - fr_cursor_append(&cursor, n); + fr_dlist_insert_tail(out, n); } return 0; @@ -5152,33 +5142,15 @@ int fr_value_box_list_acopy(TALLOC_CTX *ctx, fr_value_box_t **out, fr_value_box_ * - true if a list member is tainted. * - false if no list members are tainted. */ -bool fr_value_box_list_tainted(fr_value_box_t const *head) +bool fr_value_box_list_tainted(fr_value_box_list_t const *head) { - if (!head) return false; - - do { - if (head->tainted) return true; - } while ((head = head->next)); - - return false; -} + fr_value_box_t *vb = NULL; -/** Get list member at a given index - * - * @param[in] head of list. - * @param[in] index of member to return. - * @return - * - NULL if there is no member at given index - * - member if it exists - */ -fr_value_box_t *fr_value_box_list_get(fr_value_box_t *head, int index) -{ - int i = 0; + if (fr_dlist_empty(head)) return false; - while (i < index && head) { - head = head->next; - i++; + while ((vb = fr_dlist_next(head, vb))) { + if (vb->tainted) return true; } - return head; + return false; } diff --git a/src/lib/util/value.h b/src/lib/util/value.h index 2a5c32ccd0b..b2b20e172ed 100644 --- a/src/lib/util/value.h +++ b/src/lib/util/value.h @@ -84,22 +84,11 @@ extern fr_sbuff_escape_rules_t fr_value_escape_solidus; extern fr_sbuff_escape_rules_t fr_value_escape_backtick; extern fr_sbuff_escape_rules_t *fr_value_escape_by_quote[T_TOKEN_LAST]; -typedef enum { - FR_VALUE_BOX_LIST_SINGLE = 0, //!< Singly linked list. - FR_VALUE_BOX_LIST_DOUBLE, //!< Doubly linked list. -} fr_value_box_list_type_t; - -/** Placeholder structure to represent lists of value boxes +/** Lists of value boxes * - * Should have additional fields added later. + * Specifically define a type for lists of value_box_t to aid type checking */ -typedef struct { - union { - fr_value_box_t *slist; //!< The head of the list. - fr_dlist_head_t dlist; //!< Doubly linked list head. - }; - fr_value_box_list_type_t type; //!< What type of list this is. -} fr_value_box_list_t; +typedef fr_dlist_head_t fr_value_box_list_t; /** Union containing all data types supported by the server * @@ -164,7 +153,7 @@ struct value_box_s { fr_dict_attr_t const *enumv; //!< Enumeration values. - fr_value_box_t *next; //!< Next in a series of value_box. + fr_dlist_t entry; //!< Doubly linked list entry. }; /** @name Field accessors for #fr_value_box_t @@ -176,7 +165,7 @@ struct value_box_s { */ #define vb_strvalue datum.strvalue #define vb_octets datum.octets -#define vb_group datum.children.slist +#define vb_group datum.children #define vb_ip datum.ip @@ -295,36 +284,36 @@ struct value_box_s { /** Returns the number of boxes in a list of value boxes * - * @param[in] head of the value box list. + * @param[in] list of value boxes. * @return Number of boxes in the list. */ -static inline size_t fr_value_box_list_len(fr_value_box_t const *head) +static inline size_t fr_value_box_list_len(fr_value_box_list_t const *list) { - size_t i; - - for (i = 0; head; head = head->next, i++); - - return i; + return fr_dlist_num_elements(list); } /** Determines whether a list contains the number of boxes required * - * @note More efficient than fr_value_box_list_len for argument validation as it - * doesn't walk the entire list. - * - * @param[in] head of the list of value boxes. + * @param[in] list of value boxes. * @param[in] min The number of boxes required to return true. * @return * - true if the list has at least min boxes. * - false if the list has fewer than min boxes. */ -static inline bool fr_value_box_list_len_min(fr_value_box_t const *head, size_t min) +static inline bool fr_value_box_list_len_min(fr_value_box_list_t const *list, size_t min) { - size_t i; + size_t i = fr_dlist_num_elements(list); - for (i = 0; head && i < min; head = head->next, i++); + return (i >= min); +} - return (i == min); +/** Initialise a list of fr_value_box_t + * + * @param[in,out] list to initialise + */ +static inline void fr_value_box_list_init(fr_value_box_list_t *list) +{ + fr_dlist_talloc_init(list, fr_value_box_t, entry); } /** @} */ @@ -361,6 +350,8 @@ static inline CC_HINT(always_inline) void fr_value_box_init(fr_value_box_t *vb, .enumv = enumv, .tainted = tainted }, sizeof(*vb)); + fr_dlist_entry_init(&vb->entry); + if (type == FR_TYPE_GROUP) fr_value_box_list_init(&vb->vb_group); } /** Initialise an empty/null box that will be filled later @@ -731,19 +722,17 @@ int fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, * @{ */ int fr_value_box_list_concat(TALLOC_CTX *ctx, - fr_value_box_t *out, fr_value_box_t **list, + fr_value_box_t *out, fr_value_box_list_t *list, fr_type_t type, bool free_input); -char *fr_value_box_list_aprint(TALLOC_CTX *ctx, fr_value_box_t const *head, char const *delim, +char *fr_value_box_list_aprint(TALLOC_CTX *ctx, fr_value_box_list_t const *list, char const *delim, fr_sbuff_escape_rules_t const *e_rules); -int fr_value_box_list_acopy(TALLOC_CTX *ctx, fr_value_box_t **out, fr_value_box_t const *in); - -bool fr_value_box_list_tainted(fr_value_box_t const *head); +int fr_value_box_list_acopy(TALLOC_CTX *ctx, fr_value_box_list_t *out, fr_value_box_list_t const *in); -fr_value_box_t* fr_value_box_list_get(fr_value_box_t *head, int index); +bool fr_value_box_list_tainted(fr_value_box_list_t const *head); -int fr_value_box_list_flatten_argv(TALLOC_CTX *ctx, char ***argv_p, fr_value_box_t const *in); +int fr_value_box_list_flatten_argv(TALLOC_CTX *ctx, char ***argv_p, fr_value_box_list_t const *in); /** @} */ /* diff --git a/src/modules/rlm_always/rlm_always.c b/src/modules/rlm_always/rlm_always.c index 86a86fe5362..814009f314c 100644 --- a/src/modules/rlm_always/rlm_always.c +++ b/src/modules/rlm_always/rlm_always.c @@ -66,16 +66,17 @@ static int always_xlat_instantiate(void *xlat_inst, UNUSED xlat_exp_t const *exp * * Example: "%{db_status:fail}" */ -static xlat_action_t always_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t always_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { rlm_always_t const *inst = talloc_get_type_abort_const(*((void const * const *)xlat_inst),rlm_always_t); module_instance_t *mi; char const *status; char const *p; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); mi = module_by_name(NULL, inst->xlat_name); if (!mi) { @@ -91,8 +92,8 @@ static xlat_action_t always_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, p = fr_table_str_by_value(rcode_table, mi->code, ""); } - if (!(*in) || (*in)->vb_length == 0) goto done; - status = (*in)->vb_strvalue; + if (!in_head || in_head->vb_length == 0) goto done; + status = in_head->vb_strvalue; /* * Set the module status @@ -117,7 +118,7 @@ done: MEM(vb = fr_value_box_alloc_null(ctx)); fr_value_box_strdup(vb, vb, NULL, p, false); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; diff --git a/src/modules/rlm_chap/rlm_chap.c b/src/modules/rlm_chap/rlm_chap.c index cd82ece3c27..6b291cbfc8a 100644 --- a/src/modules/rlm_chap/rlm_chap.c +++ b/src/modules/rlm_chap/rlm_chap.c @@ -73,25 +73,26 @@ fr_dict_attr_autoload_t rlm_chap_dict_attr[] = { * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_chap_password(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_func_chap_password(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { uint8_t chap_password[1 + RADIUS_CHAP_CHALLENGE_LENGTH]; fr_value_box_t *vb; fr_pair_t *challenge; uint8_t const *vector; + fr_value_box_t *in_head = fr_dlist_head(in); /* * If there's no input, there's no output */ - if (!*in) { + if (!in_head) { REDEBUG("chap requires a password as input"); return XLAT_ACTION_FAIL; } - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } @@ -107,11 +108,11 @@ static xlat_action_t xlat_func_chap_password(TALLOC_CTX *ctx, fr_cursor_t *out, vector = request->packet->vector; } fr_radius_encode_chap_password(chap_password, (uint8_t)(fr_rand() & 0xff), vector, - (*in)->vb_strvalue, (*in)->vb_length); + in_head->vb_strvalue, in_head->vb_length); MEM(vb = fr_value_box_alloc_null(ctx)); fr_value_box_memdup(vb, vb, NULL, chap_password, sizeof(chap_password), false); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } diff --git a/src/modules/rlm_cipher/rlm_cipher.c b/src/modules/rlm_cipher/rlm_cipher.c index 4ef5a1a3582..b0cf3d83c15 100644 --- a/src/modules/rlm_cipher/rlm_cipher.c +++ b/src/modules/rlm_cipher/rlm_cipher.c @@ -463,9 +463,9 @@ static int cipher_rsa_certificate_file_load(TALLOC_CTX *ctx, void *out, UNUSED v * * @ingroup xlat_functions */ -static xlat_action_t cipher_rsa_encrypt_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t cipher_rsa_encrypt_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { rlm_cipher_rsa_thread_inst_t *xt = talloc_get_type_abort(*((void **)xlat_thread_inst), rlm_cipher_rsa_thread_inst_t); @@ -477,18 +477,19 @@ static xlat_action_t cipher_rsa_encrypt_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, size_t ciphertext_len; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); - if (!*in) { + if (!in_head) { REDEBUG("encrypt requires one or arguments (...)"); return XLAT_ACTION_FAIL; } - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { fr_tls_log_error(request, "Failed concatenating arguments to form plaintext"); return XLAT_ACTION_FAIL; } - plaintext = (*in)->vb_strvalue; - plaintext_len = (*in)->vb_length; + plaintext = in_head->vb_strvalue; + plaintext_len = in_head->vb_length; /* * Figure out the buffer we need @@ -510,7 +511,7 @@ static xlat_action_t cipher_rsa_encrypt_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, } RHEXDUMP3(ciphertext, ciphertext_len, "Ciphertext (%zu bytes)", ciphertext_len); MEM(fr_value_box_mem_realloc(vb, NULL, vb, ciphertext_len) == 0); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -527,9 +528,9 @@ static xlat_action_t cipher_rsa_encrypt_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t cipher_rsa_sign_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t cipher_rsa_sign_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, void const *xlat_inst, void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { rlm_cipher_t const *inst = talloc_get_type_abort_const(*((void const * const *)xlat_inst), rlm_cipher_t); @@ -545,18 +546,19 @@ static xlat_action_t cipher_rsa_sign_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, unsigned int digest_len = 0; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); - if (!*in) { + if (!in_head) { REDEBUG("sign requires one or arguments (<plaintext>...)"); return XLAT_ACTION_FAIL; } - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { REDEBUG("Failed concatenating arguments to form plaintext"); return XLAT_ACTION_FAIL; } - msg = (*in)->vb_strvalue; - msg_len = (*in)->vb_length; + msg = in_head->vb_strvalue; + msg_len = in_head->vb_length; /* * First produce a digest of the message @@ -593,7 +595,7 @@ static xlat_action_t cipher_rsa_sign_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, return XLAT_ACTION_FAIL; } MEM(fr_value_box_mem_realloc(vb, NULL, vb, sig_len) == 0); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -610,9 +612,9 @@ static xlat_action_t cipher_rsa_sign_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t cipher_rsa_decrypt_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t cipher_rsa_decrypt_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { rlm_cipher_rsa_thread_inst_t *xt = talloc_get_type_abort(*((void **)xlat_thread_inst), rlm_cipher_rsa_thread_inst_t); @@ -624,18 +626,19 @@ static xlat_action_t cipher_rsa_decrypt_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, size_t plaintext_len; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); - if (!*in) { + if (!in_head) { REDEBUG("decrypt requires one or more arguments (<ciphertext>...)"); return XLAT_ACTION_FAIL; } - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) { REDEBUG("Failed concatenating arguments to form plaintext"); return XLAT_ACTION_FAIL; } - ciphertext = (*in)->vb_octets; - ciphertext_len = (*in)->vb_length; + ciphertext = in_head->vb_octets; + ciphertext_len = in_head->vb_length; /* * Decrypt the ciphertext @@ -656,7 +659,7 @@ static xlat_action_t cipher_rsa_decrypt_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, } RHEXDUMP3((uint8_t const *)plaintext, plaintext_len, "Plaintext (%zu bytes)", plaintext_len); MEM(fr_value_box_bstr_realloc(vb, NULL, vb, plaintext_len) == 0); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -674,9 +677,9 @@ static xlat_action_t cipher_rsa_decrypt_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t cipher_rsa_verify_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t cipher_rsa_verify_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, void const *xlat_inst, void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { rlm_cipher_t const *inst = talloc_get_type_abort_const(*((void const * const *)xlat_inst), rlm_cipher_t); @@ -692,8 +695,10 @@ static xlat_action_t cipher_rsa_verify_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, unsigned int digest_len = 0; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_pop_head(in); + fr_value_box_t *args; - if (!*in) { + if (!in_head) { REDEBUG("verification requires two or more arguments (<signature>, <message>...)"); return XLAT_ACTION_FAIL; } @@ -701,7 +706,7 @@ static xlat_action_t cipher_rsa_verify_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, /* * Check we have at least two boxed values */ - if (!(*in)->next) { + if (fr_dlist_empty(in)) { REDEBUG("Missing message data arg or message data was (null)"); return XLAT_ACTION_FAIL; } @@ -711,25 +716,31 @@ static xlat_action_t cipher_rsa_verify_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, * isn't already in that form. * It could be hexits or base64 or some other encoding. */ - if ((*in)->type != FR_TYPE_OCTETS) { + if (in_head->type != FR_TYPE_OCTETS) { REDEBUG("Signature argument wrong type, expected %s, got %s. " "Use %%{base64_decode:<text>} or %%{hex_decode:<text>} if signature is armoured", fr_table_str_by_value(fr_value_box_type_table, FR_TYPE_OCTETS, "?Unknown?"), - fr_table_str_by_value(fr_value_box_type_table, (*in)->type, "?Unknown?")); + fr_table_str_by_value(fr_value_box_type_table, in_head->type, "?Unknown?")); return XLAT_ACTION_FAIL; } - sig = (*in)->vb_octets; - sig_len = (*in)->vb_length; + sig = in_head->vb_octets; + sig_len = in_head->vb_length; /* * Concat (...) args to get message data */ - if (fr_value_box_list_concat(ctx, (*in)->next, &((*in)->next), FR_TYPE_STRING, true) < 0) { + args = fr_dlist_head(in); + if (fr_value_box_list_concat(ctx, args, in, FR_TYPE_STRING, true) < 0) { REDEBUG("Failed concatenating arguments to form plaintext"); return XLAT_ACTION_FAIL; } - msg = (*in)->next->vb_strvalue; - msg_len = (*in)->next->vb_length; + msg = args->vb_strvalue; + msg_len = args->vb_length; + + /* + * Return the first entry to the "in" vb list + */ + fr_dlist_insert_head(in, in_head); /* * The argument separator also gets rolled into @@ -774,13 +785,13 @@ static xlat_action_t cipher_rsa_verify_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, case 1: /* success (signature valid) */ MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_BOOL, NULL, false)); vb->vb_bool = true; - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); break; case 0: /* failure (signature not valid) */ MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_BOOL, NULL, false)); vb->vb_bool = false; - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); break; default: diff --git a/src/modules/rlm_client/rlm_client.c b/src/modules/rlm_client/rlm_client.c index 22e06cffe8e..c696b536d1a 100644 --- a/src/modules/rlm_client/rlm_client.c +++ b/src/modules/rlm_client/rlm_client.c @@ -115,26 +115,27 @@ static int _map_proc_client_get_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request * - #RLM_MODULE_FAIL if an error occurred. */ static rlm_rcode_t map_proc_client(UNUSED void *mod_inst, UNUSED void *proc_inst, request_t *request, - fr_value_box_t **client_override, fr_map_list_t const *maps) + fr_value_box_list_t *client_override, fr_map_list_t const *maps) { rlm_rcode_t rcode = RLM_MODULE_OK; map_t const *map = NULL; RADCLIENT *client; client_get_vp_ctx_t uctx; - if (*client_override) { + if (!fr_dlist_empty(client_override)) { fr_ipaddr_t ip; char const *client_str; + fr_value_box_t *client_override_head = fr_dlist_head(client_override); /* * Concat don't asprint, as this becomes a noop * in the vast majority of cases. */ - if (fr_value_box_list_concat(request, *client_override, client_override, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(request, client_override_head, client_override, FR_TYPE_STRING, true) < 0) { REDEBUG("Failed concatenating input data"); return RLM_MODULE_FAIL; } - client_str = (*client_override)->vb_strvalue; + client_str = client_override_head->vb_strvalue; if (fr_inet_pton(&ip, client_str, -1, AF_UNSPEC, false, true) < 0) { REDEBUG("\"%s\" is not a valid IPv4 or IPv6 address", client_str); diff --git a/src/modules/rlm_csv/rlm_csv.c b/src/modules/rlm_csv/rlm_csv.c index eee486f8a0d..b82613690b0 100644 --- a/src/modules/rlm_csv/rlm_csv.c +++ b/src/modules/rlm_csv/rlm_csv.c @@ -31,7 +31,7 @@ RCSID("$Id$") #include <freeradius-devel/server/map_proc.h> static rlm_rcode_t mod_map_proc(void *mod_inst, UNUSED void *proc_inst, request_t *request, - fr_value_box_t **key, fr_map_list_t const *maps); + fr_value_box_list_t *key, fr_map_list_t const *maps); /* * Define a structure for our module configuration. @@ -975,23 +975,24 @@ finish: * - #RLM_MODULE_FAIL if an error occurred. */ static rlm_rcode_t mod_map_proc(void *mod_inst, UNUSED void *proc_inst, request_t *request, - fr_value_box_t **key, fr_map_list_t const *maps) + fr_value_box_list_t *key, fr_map_list_t const *maps) { rlm_csv_t *inst = talloc_get_type_abort(mod_inst, rlm_csv_t); + fr_value_box_t *key_head = fr_dlist_head(key); - if (!*key) { + if (!key_head) { REDEBUG("CSV key cannot be (null)"); return RLM_MODULE_FAIL; } if ((inst->key_data_type == FR_TYPE_OCTETS) || (inst->key_data_type == FR_TYPE_STRING)) { - if (fr_value_box_list_concat(request, *key, key, inst->key_data_type, true) < 0) { + if (fr_value_box_list_concat(request, key_head, key, inst->key_data_type, true) < 0) { REDEBUG("Failed parsing key"); return RLM_MODULE_FAIL; } } - return mod_map_apply(inst, request, *key, maps); + return mod_map_apply(inst, request, key_head, maps); } diff --git a/src/modules/rlm_delay/rlm_delay.c b/src/modules/rlm_delay/rlm_delay.c index 749ca590f39..42630d8c8ac 100644 --- a/src/modules/rlm_delay/rlm_delay.c +++ b/src/modules/rlm_delay/rlm_delay.c @@ -182,10 +182,10 @@ static unlang_action_t CC_HINT(nonnull) mod_delay(rlm_rcode_t *p_result, module_ return unlang_module_yield(request, mod_delay_return, mod_delay_cancel, yielded_at); } -static xlat_action_t xlat_delay_resume(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_delay_resume(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - UNUSED fr_value_box_t **in, void *rctx) + UNUSED fr_value_box_list_t *in, void *rctx) { fr_time_t *yielded_at = talloc_get_type_abort(rctx, fr_time_t); fr_time_t delayed; @@ -199,7 +199,7 @@ static xlat_action_t xlat_delay_resume(TALLOC_CTX *ctx, fr_cursor_t *out, RDEBUG3("Request delayed by %pVs", vb); - fr_cursor_insert(out, vb); + fr_dcursor_insert(out, vb); return XLAT_ACTION_DONE; } @@ -221,14 +221,15 @@ static void xlat_delay_cancel(request_t *request, UNUSED void *instance, UNUSED * * @ingroup xlat_functions */ -static xlat_action_t xlat_delay(TALLOC_CTX *ctx, UNUSED fr_cursor_t *out, +static xlat_action_t xlat_delay(TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, request_t *request, void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { rlm_delay_t const *inst; void *instance; fr_time_delta_t delay; fr_time_t resume_at, *yielded_at; + fr_value_box_t *in_head = fr_dlist_head(in); memcpy(&instance, xlat_inst, sizeof(instance)); /* Stupid const issues */ @@ -245,20 +246,20 @@ static xlat_action_t xlat_delay(TALLOC_CTX *ctx, UNUSED fr_cursor_t *out, * immediately re-enqueue the request. * This is very useful for testing. */ - if (!*in) { + if (!in_head) { if (!fr_cond_assert(delay_add(request, &resume_at, *yielded_at, 0, true, true) == 0)) { return XLAT_ACTION_FAIL; } goto yield; } - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); talloc_free(yielded_at); return XLAT_ACTION_FAIL; } - if (fr_time_delta_from_str(&delay, (*in)->vb_strvalue, FR_TIME_RES_SEC) < 0) { + if (fr_time_delta_from_str(&delay, in_head->vb_strvalue, FR_TIME_RES_SEC) < 0) { RPEDEBUG("Failed parsing delay time"); talloc_free(yielded_at); return XLAT_ACTION_FAIL; diff --git a/src/modules/rlm_dhcpv4/rlm_dhcpv4.c b/src/modules/rlm_dhcpv4/rlm_dhcpv4.c index 0d38e7e966e..8ca98fe041b 100644 --- a/src/modules/rlm_dhcpv4/rlm_dhcpv4.c +++ b/src/modules/rlm_dhcpv4/rlm_dhcpv4.c @@ -61,11 +61,11 @@ typedef struct { * * @ingroup xlat_functions */ -static xlat_action_t dhcpv4_decode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t dhcpv4_decode_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { - fr_cursor_t in_cursor; + fr_dcursor_t in_cursor; fr_value_box_t *vb, *vb_decoded; fr_pair_t *vp; fr_pair_list_t head; @@ -73,9 +73,9 @@ static xlat_action_t dhcpv4_decode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, fr_pair_list_init(&head); - for (vb = fr_cursor_talloc_init(&in_cursor, in, fr_value_box_t); + for (vb = fr_dcursor_talloc_init(&in_cursor, in, fr_value_box_t); vb; - vb = fr_cursor_next(&in_cursor)) { + vb = fr_dcursor_next(&in_cursor)) { uint8_t const *p, *end; ssize_t len; fr_pair_list_t vps; @@ -126,7 +126,7 @@ static xlat_action_t dhcpv4_decode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, /* create a value box to hold the decoded count */ MEM(vb_decoded = fr_value_box_alloc(ctx, FR_TYPE_UINT16, NULL, false)); vb_decoded->vb_uint16 = decoded; - fr_cursor_append(out, vb_decoded); + fr_dcursor_append(out, vb_decoded); return XLAT_ACTION_DONE; } @@ -142,9 +142,9 @@ static xlat_action_t dhcpv4_decode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t dhcpv4_encode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t dhcpv4_encode_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { fr_dcursor_t *cursor; bool tainted = false; @@ -153,15 +153,16 @@ static xlat_action_t dhcpv4_encode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, uint8_t binbuf[2048]; uint8_t *p = binbuf, *end = p + sizeof(binbuf); ssize_t len = 0; + fr_value_box_t *in_head = fr_dlist_head(in); - if (!*in) return XLAT_ACTION_DONE; + if (!in_head) return XLAT_ACTION_DONE; - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input string for attribute reference"); return XLAT_ACTION_FAIL; } - if (xlat_fmt_to_cursor(NULL, &cursor, &tainted, request, (*in)->vb_strvalue) < 0) return XLAT_ACTION_FAIL; + if (xlat_fmt_to_cursor(NULL, &cursor, &tainted, request, in_head->vb_strvalue) < 0) return XLAT_ACTION_FAIL; if (!fr_dcursor_head(cursor)) return XLAT_ACTION_DONE; /* Nothing to encode */ @@ -182,7 +183,7 @@ static xlat_action_t dhcpv4_encode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, */ MEM(encoded = fr_value_box_alloc_null(ctx)); fr_value_box_memdup(encoded, encoded, NULL, binbuf, (size_t)len, tainted); - fr_cursor_append(out, encoded); + fr_dcursor_append(out, encoded); return XLAT_ACTION_DONE; } diff --git a/src/modules/rlm_exec/rlm_exec.c b/src/modules/rlm_exec/rlm_exec.c index e00dccd9f04..c81e3a51e5f 100644 --- a/src/modules/rlm_exec/rlm_exec.c +++ b/src/modules/rlm_exec/rlm_exec.c @@ -260,7 +260,7 @@ static unlang_action_t mod_exec_nowait_resume(rlm_rcode_t *p_result, module_ctx_ request_t *request, void *rctx) { rlm_exec_t const *inst = talloc_get_type_abort_const(mctx->instance, rlm_exec_t); - fr_value_box_t *box = talloc_get_type_abort(rctx, fr_value_box_t); + fr_value_box_list_t *box = talloc_get_type_abort(rctx, fr_value_box_list_t); fr_pair_list_t env_pairs; fr_pair_list_init(&env_pairs); @@ -287,8 +287,8 @@ static unlang_action_t mod_exec_nowait_resume(rlm_rcode_t *p_result, module_ctx_ } typedef struct { - fr_value_box_t *box; - int status; + fr_value_box_list_t box; + int status; } rlm_exec_ctx_t; static const rlm_rcode_t status2rcode[] = { @@ -356,11 +356,12 @@ static unlang_action_t mod_exec_wait_resume(rlm_rcode_t *p_result, module_ctx_t rlm_exec_ctx_t *m = talloc_get_type_abort(rctx, rlm_exec_ctx_t); rlm_exec_t const *inst = talloc_get_type_abort_const(mctx->instance, rlm_exec_t); - if (inst->output && m->box) { + if (inst->output && !fr_dlist_empty(&m->box)) { TALLOC_CTX *ctx; fr_pair_list_t vps, *output_pairs; + fr_value_box_t *box = fr_dlist_head(&m->box); - RDEBUG("EXEC GOT -- %pV", m->box); + RDEBUG("EXEC GOT -- %pV", box); fr_pair_list_init(&vps); output_pairs = tmpl_list_head(request, inst->output_list); @@ -368,10 +369,10 @@ static unlang_action_t mod_exec_wait_resume(rlm_rcode_t *p_result, module_ctx_t ctx = tmpl_list_ctx(request, inst->output_list); - fr_pair_list_afrom_box(ctx, &vps, request->dict, m->box); + fr_pair_list_afrom_box(ctx, &vps, request->dict, box); if (!fr_pair_list_empty(&vps)) fr_pair_list_move(output_pairs, &vps); - m->box = NULL; /* has been consumed */ + fr_dlist_talloc_free(&m->box); /* has been consumed */ } status = m->status; @@ -385,7 +386,7 @@ static unlang_action_t mod_exec_wait_resume(rlm_rcode_t *p_result, module_ctx_t * The status rcodes aren't quite the same as the rcode * enumeration. */ - RETURN_MODULE_RCODE(rlm_exec_status2rcode(request, m->box, status)); + RETURN_MODULE_RCODE(rlm_exec_status2rcode(request, fr_dlist_head(&m->box), status)); } /* @@ -413,11 +414,11 @@ static unlang_action_t CC_HINT(nonnull) mod_exec_dispatch(rlm_rcode_t *p_result, * Do the asynchronous xlat expansion. */ if (!inst->wait) { - fr_value_box_t *box; + fr_value_box_list_t *box = talloc_zero(ctx, fr_value_box_list_t); - MEM(box = talloc_zero(ctx, fr_value_box_t)); + fr_value_box_list_init(box); - return unlang_module_yield_to_xlat(request, &box, request, tmpl_xlat(inst->tmpl), mod_exec_nowait_resume, NULL, box); + return unlang_module_yield_to_xlat(request, box, request, tmpl_xlat(inst->tmpl), mod_exec_nowait_resume, NULL, &box); } /* @@ -439,6 +440,7 @@ static unlang_action_t CC_HINT(nonnull) mod_exec_dispatch(rlm_rcode_t *p_result, } m = talloc_zero(ctx, rlm_exec_ctx_t); + fr_value_box_list_init(&m->box); return unlang_module_yield_to_tmpl(m, &m->box, &m->status, request, inst->tmpl, &env_pairs, mod_exec_wait_resume, NULL, m); } diff --git a/src/modules/rlm_icmp/rlm_icmp.c b/src/modules/rlm_icmp/rlm_icmp.c index 227964086b8..4753849ab45 100644 --- a/src/modules/rlm_icmp/rlm_icmp.c +++ b/src/modules/rlm_icmp/rlm_icmp.c @@ -123,10 +123,10 @@ static const CONF_PARSER module_config[] = { CONF_PARSER_TERMINATOR }; -static xlat_action_t xlat_icmp_resume(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t xlat_icmp_resume(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED request_t *request, UNUSED void const *xlat_inst, void *xlat_thread_inst, - UNUSED fr_value_box_t **in, void *rctx) + UNUSED fr_value_box_list_t *in, void *rctx) { rlm_icmp_echo_t *echo = talloc_get_type_abort(rctx, rlm_icmp_echo_t); xlat_icmp_thread_inst_t *thread = talloc_get_type_abort(xlat_thread_inst, xlat_icmp_thread_inst_t); @@ -138,7 +138,7 @@ static xlat_action_t xlat_icmp_resume(TALLOC_CTX *ctx, fr_cursor_t *out, (void) rbtree_deletebydata(thread->t->tree, echo); talloc_free(echo); - fr_cursor_insert(out, vb); + fr_dcursor_insert(out, vb); return XLAT_ACTION_DONE; } @@ -179,9 +179,9 @@ static void _xlat_icmp_timeout(request_t *request, * * @ingroup xlat_functions */ -static xlat_action_t xlat_icmp(TALLOC_CTX *ctx, UNUSED fr_cursor_t *out, +static xlat_action_t xlat_icmp(TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, request_t *request, void const *xlat_inst, void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { void *instance; rlm_icmp_t const *inst; @@ -192,6 +192,7 @@ static xlat_action_t xlat_icmp(TALLOC_CTX *ctx, UNUSED fr_cursor_t *out, ssize_t rcode; socklen_t salen; struct sockaddr_storage dst; + fr_value_box_t *in_head = fr_dlist_head(in); memcpy(&instance, xlat_inst, sizeof(instance)); /* Stupid const issues */ @@ -200,20 +201,20 @@ static xlat_action_t xlat_icmp(TALLOC_CTX *ctx, UNUSED fr_cursor_t *out, /* * If there's no input, do we can't ping anything. */ - if (!*in) return XLAT_ACTION_FAIL; + if (!in_head) return XLAT_ACTION_FAIL; - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - if (fr_value_box_cast_in_place(ctx, *in, thread->t->ipaddr_type, NULL) < 0) { + if (fr_value_box_cast_in_place(ctx, in_head, thread->t->ipaddr_type, NULL) < 0) { RPEDEBUG("Failed casting result to IP address"); return XLAT_ACTION_FAIL; } MEM(echo = talloc_zero(ctx, rlm_icmp_echo_t)); - echo->ip = *in; + echo->ip = in_head; echo->request = request; echo->counter = thread->t->counter++; diff --git a/src/modules/rlm_json/rlm_json.c b/src/modules/rlm_json/rlm_json.c index 6b99be6ef1a..8d925251fe0 100644 --- a/src/modules/rlm_json/rlm_json.c +++ b/src/modules/rlm_json/rlm_json.c @@ -102,30 +102,31 @@ typedef struct { * @param in list of value boxes as input * @return XLAT_ACTION_DONE or XLAT_ACTION_FAIL */ -static xlat_action_t json_quote_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, request_t *request, +static xlat_action_t json_quote_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); char *tmp; - if (!*in) return XLAT_ACTION_DONE; + if (!in_head) return XLAT_ACTION_DONE; - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } MEM(vb = fr_value_box_alloc_null(ctx)); - if (!(tmp = fr_json_from_string(vb, (*in)->vb_strvalue, false))) { + if (!(tmp = fr_json_from_string(vb, in_head->vb_strvalue, false))) { REDEBUG("Unable to JSON-quote string"); talloc_free(vb); return XLAT_ACTION_FAIL; } fr_value_box_bstrdup_buffer_shallow(NULL, vb, NULL, tmp, false); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -180,9 +181,9 @@ static ssize_t jpath_validate_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t ou * @param in list of value boxes as input * @return XLAT_ACTION_DONE or XLAT_ACTION_FAIL */ -static xlat_action_t json_encode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, request_t *request, +static xlat_action_t json_encode_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { rlm_json_t const *inst = talloc_get_type_abort_const(*((void const * const *)xlat_inst), rlm_json_t); @@ -195,20 +196,21 @@ static xlat_action_t json_encode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, request char *json_str = NULL; fr_value_box_t *vb; fr_sbuff_t sbuff; + fr_value_box_t *in_head = fr_dlist_head(in); fr_pair_list_init(&json_vps); fr_pair_list_init(&vps); - if (!*in) { + if (!in_head) { REDEBUG("Missing attribute(s)"); return XLAT_ACTION_FAIL; } - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - sbuff = FR_SBUFF_IN((*in)->vb_strvalue, (*in)->vb_length); + sbuff = FR_SBUFF_IN(in_head->vb_strvalue, in_head->vb_length); fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL); /* @@ -289,7 +291,7 @@ static xlat_action_t json_encode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, request } fr_value_box_bstrdup_buffer_shallow(NULL, vb, NULL, json_str, false); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); fr_pair_list_free(&json_vps); return XLAT_ACTION_DONE; @@ -397,10 +399,12 @@ static int _json_map_proc_get_value(TALLOC_CTX *ctx, fr_pair_list_t *out, reques { fr_pair_t *vp; rlm_json_jpath_to_eval_t *to_eval = uctx; - fr_value_box_t *head, *value; + fr_value_box_t *value; + fr_value_box_list_t head; int ret; fr_pair_list_free(out); + fr_value_box_list_init(&head); ret = fr_jpath_evaluate_leaf(request, &head, tmpl_da(map->lhs)->type, tmpl_da(map->lhs), to_eval->root, to_eval->jpath); @@ -409,11 +413,11 @@ static int _json_map_proc_get_value(TALLOC_CTX *ctx, fr_pair_list_t *out, reques return -1; } if (ret == 0) return 0; - fr_assert(head); + fr_assert(!fr_dlist_empty(&head)); - for (value = head; + for (value = fr_dlist_head(&head); value; - fr_pair_add(out, vp), value = value->next) { + fr_pair_add(out, vp), value = fr_dlist_next(&head, value)) { MEM(vp = fr_pair_afrom_da(ctx, tmpl_da(map->lhs))); vp->op = map->op; @@ -441,7 +445,7 @@ static int _json_map_proc_get_value(TALLOC_CTX *ctx, fr_pair_list_t *out, reques * - #RLM_MODULE_FAIL if a fault occurred. */ static rlm_rcode_t mod_map_proc(UNUSED void *mod_inst, void *proc_inst, request_t *request, - fr_value_box_t **json, fr_map_list_t const *maps) + fr_value_box_list_t *json, fr_map_list_t const *maps) { rlm_rcode_t rcode = RLM_MODULE_UPDATED; struct json_tokener *tok; @@ -452,17 +456,18 @@ static rlm_rcode_t mod_map_proc(UNUSED void *mod_inst, void *proc_inst, request_ rlm_json_jpath_to_eval_t to_eval; char const *json_str = NULL; + fr_value_box_t *json_head = fr_dlist_head(json); - if (!*json) { + if (!json_head) { REDEBUG("JSON map input cannot be (null)"); return RLM_MODULE_FAIL; } - if (fr_value_box_list_concat(request, *json, json, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(request, json_head, json, FR_TYPE_STRING, true) < 0) { REDEBUG("Failed concatenating input"); return RLM_MODULE_FAIL; } - json_str = (*json)->vb_strvalue; + json_str = json_head->vb_strvalue; if ((talloc_array_length(json_str) - 1) == 0) { REDEBUG("JSON map input length must be > 0"); diff --git a/src/modules/rlm_ldap/rlm_ldap.c b/src/modules/rlm_ldap/rlm_ldap.c index a25c31eaa99..113538217af 100644 --- a/src/modules/rlm_ldap/rlm_ldap.c +++ b/src/modules/rlm_ldap/rlm_ldap.c @@ -425,7 +425,7 @@ static int ldap_map_verify(CONF_SECTION *cs, UNUSED void *mod_inst, UNUSED void * - #RLM_MODULE_FAIL if an error occurred. */ static rlm_rcode_t mod_map_proc(void *mod_inst, UNUSED void *proc_inst, request_t *request, - fr_value_box_t **url, fr_map_list_t const *maps) + fr_value_box_list_t *url, fr_map_list_t const *maps) { rlm_rcode_t rcode = RLM_MODULE_UPDATED; rlm_ldap_t *inst = talloc_get_type_abort(mod_inst, rlm_ldap_t); @@ -443,20 +443,21 @@ static rlm_rcode_t mod_map_proc(void *mod_inst, UNUSED void *proc_inst, request_ LDAPControl *server_ctrls[] = { NULL, NULL }; fr_ldap_map_exp_t expanded; /* faster than allocing every time */ + fr_value_box_t *url_head = fr_dlist_head(url); /* * FIXME - Maybe it can be NULL? */ - if (!*url) { + if (!url_head) { REDEBUG("LDAP URL cannot be (null)"); return RLM_MODULE_FAIL; } - if (fr_value_box_list_concat(request, *url, url, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(request, url_head, url, FR_TYPE_STRING, true) < 0) { REDEBUG("Failed concatenating input"); return RLM_MODULE_FAIL; } - url_str = (*url)->vb_strvalue; + url_str = url_head->vb_strvalue; if (!ldap_is_ldap_url(url_str)) { REDEBUG("Map query string does not look like a valid LDAP URI"); diff --git a/src/modules/rlm_redis/rlm_redis.c b/src/modules/rlm_redis/rlm_redis.c index e86255ffbec..6a87f674111 100644 --- a/src/modules/rlm_redis/rlm_redis.c +++ b/src/modules/rlm_redis/rlm_redis.c @@ -156,10 +156,10 @@ static int redis_xlat_instantiate(void *xlat_inst, UNUSED xlat_exp_t const *exp, * * @ingroup xlat_functions */ -static xlat_action_t redis_remap_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t redis_remap_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { rlm_redis_t const *inst = talloc_get_type_abort_const(*((void const * const *)xlat_inst), rlm_redis_t); @@ -169,18 +169,19 @@ static xlat_action_t redis_remap_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, fr_redis_conn_t *conn; fr_redis_cluster_rcode_t rcode; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); - if (!*in) { + if (!in_head) { REDEBUG("Missing key"); return XLAT_ACTION_FAIL; } - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - if (fr_inet_pton_port(&node_addr.inet.dst_ipaddr, &node_addr.inet.dst_port, (*in)->vb_strvalue, (*in)->vb_length, + if (fr_inet_pton_port(&node_addr.inet.dst_ipaddr, &node_addr.inet.dst_port, in_head->vb_strvalue, in_head->vb_length, AF_UNSPEC, true, true) < 0) { RPEDEBUG("Failed parsing node address"); return XLAT_ACTION_FAIL; @@ -202,7 +203,7 @@ static xlat_action_t redis_remap_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, MEM(vb = fr_value_box_alloc_null(ctx)); fr_value_box_strdup(vb, vb, NULL, fr_table_str_by_value(fr_redis_cluster_rcodes_table, rcode, "<INVALID>"), false); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } @@ -211,10 +212,10 @@ static xlat_action_t redis_remap_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, * * @ingroup xlat_functions */ -static xlat_action_t redis_node_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t redis_node_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, void const *xlat_inst, UNUSED void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { rlm_redis_t const *inst = talloc_get_type_abort_const(*((void const * const *)xlat_inst), rlm_redis_t); @@ -230,18 +231,19 @@ static xlat_action_t redis_node_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, size_t key_len; unsigned long idx = 0; fr_value_box_t *vb; + fr_value_box_t *in_head = fr_dlist_head(in); - if (!*in) { + if (!in_head) { REDEBUG("Missing key"); return XLAT_ACTION_FAIL; } - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input"); return XLAT_ACTION_FAIL; } - key = p = (*in)->vb_strvalue; + key = p = in_head->vb_strvalue; p = strchr(p, ' '); /* Look for index */ if (p) { key_len = p - key; @@ -252,7 +254,7 @@ static xlat_action_t redis_node_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, return XLAT_ACTION_FAIL; } } else { - key_len = (*in)->vb_length; + key_len = in_head->vb_length; } key_slot = fr_redis_cluster_slot_by_key(inst->cluster, request, (uint8_t const *)key, key_len); @@ -274,7 +276,7 @@ static xlat_action_t redis_node_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, MEM(vb = fr_value_box_alloc_null(ctx)); fr_value_box_asprintf(vb, vb, NULL, false, "%pV:%u", fr_box_ipaddr(ipaddr), port); - fr_cursor_append(out, vb); + fr_dcursor_append(out, vb); return XLAT_ACTION_DONE; } diff --git a/src/modules/rlm_rest/rlm_rest.c b/src/modules/rlm_rest/rlm_rest.c index b356bcf00f5..e960b7271cd 100644 --- a/src/modules/rlm_rest/rlm_rest.c +++ b/src/modules/rlm_rest/rlm_rest.c @@ -219,9 +219,9 @@ static int rlm_rest_perform(rlm_rest_t const *instance, rlm_rest_thread_t *t, return 0; } -static xlat_action_t rest_xlat_resume(TALLOC_CTX *ctx, fr_cursor_t *out, +static xlat_action_t rest_xlat_resume(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, void *xlat_thread_inst, - UNUSED fr_value_box_t **in, void *rctx) + UNUSED fr_value_box_list_t *in, void *rctx) { rest_xlat_thread_inst_t *xti = talloc_get_type_abort(xlat_thread_inst, rest_xlat_thread_inst_t); rlm_rest_t const *mod_inst = xti->inst; @@ -279,7 +279,7 @@ error: MEM(vb = fr_value_box_alloc_null(ctx)); fr_value_box_bstrndup(vb, vb, NULL, body, len, true); - fr_cursor_insert(out, vb); + fr_dcursor_insert(out, vb); } finish: @@ -301,9 +301,9 @@ finish: * * @ingroup xlat_functions */ -static xlat_action_t rest_xlat(TALLOC_CTX *ctx, UNUSED fr_cursor_t *out, +static xlat_action_t rest_xlat(TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, request_t *request, UNUSED void const *xlat_inst, void *xlat_thread_inst, - fr_value_box_t **in) + fr_value_box_list_t *in) { rest_xlat_thread_inst_t *xti = talloc_get_type_abort(xlat_thread_inst, rest_xlat_thread_inst_t); rlm_rest_t const *mod_inst = xti->inst; @@ -315,21 +315,22 @@ static xlat_action_t rest_xlat(TALLOC_CTX *ctx, UNUSED fr_cursor_t *out, char *uri = NULL; char const *p = NULL, *q; http_method_t method; + fr_value_box_t *in_head = fr_dlist_head(in); /* There are no configurable parameters other than the URI */ rlm_rest_xlat_rctx_t *rctx; rlm_rest_section_t *section; - if (!*in) { + if (!in_head) { REDEBUG("Got empty URL string"); return XLAT_ACTION_FAIL; } - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) { REDEBUG("Failed concatenating arguments into URL string"); return XLAT_ACTION_FAIL; } - p = (*in)->vb_strvalue; + p = in_head->vb_strvalue; MEM(rctx = talloc(request, rlm_rest_xlat_rctx_t)); section = &rctx->section; diff --git a/src/modules/rlm_sql/rlm_sql.c b/src/modules/rlm_sql/rlm_sql.c index c03341e23d5..481c4d22da2 100644 --- a/src/modules/rlm_sql/rlm_sql.c +++ b/src/modules/rlm_sql/rlm_sql.c @@ -330,7 +330,7 @@ static int sql_map_verify(CONF_SECTION *cs, UNUSED void *mod_inst, UNUSED void * * - #RLM_MODULE_FAIL if a fault occurred. */ static rlm_rcode_t mod_map_proc(void *mod_inst, UNUSED void *proc_inst, request_t *request, - fr_value_box_t **query, fr_map_list_t const *maps) + fr_value_box_list_t *query, fr_map_list_t const *maps) { rlm_sql_t *inst = talloc_get_type_abort(mod_inst, rlm_sql_t); rlm_sql_handle_t *handle = NULL; @@ -350,6 +350,7 @@ static rlm_rcode_t mod_map_proc(void *mod_inst, UNUSED void *proc_inst, request_ char map_rhs_buff[128]; char const *query_str = NULL; + fr_value_box_t *query_head = fr_dlist_head(query); #define MAX_SQL_FIELD_INDEX (64) @@ -358,16 +359,16 @@ static rlm_rcode_t mod_map_proc(void *mod_inst, UNUSED void *proc_inst, request_ fr_assert(inst->driver->sql_fields); /* Should have been caught during validation... */ - if (!*query) { + if (!query_head) { REDEBUG("Query cannot be (null)"); return RLM_MODULE_FAIL; } - if (fr_value_box_list_concat(request, *query, query, FR_TYPE_STRING, true) < 0) { + if (fr_value_box_list_concat(request, query_head, query, FR_TYPE_STRING, true) < 0) { RPEDEBUG("Failed concatenating input string"); return RLM_MODULE_FAIL; } - query_str = (*query)->vb_strvalue; + query_str = query_head->vb_strvalue; for (i = 0; i < MAX_SQL_FIELD_INDEX; i++) field_index[i] = -1;