From: Alan T. DeKok Date: Wed, 29 Jun 2022 13:20:48 +0000 (-0400) Subject: added tmpl_eval() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=272f08f3633ea3d5c1ca5a2371d7d6de98557530;p=thirdparty%2Ffreeradius-server.git added tmpl_eval() which only does asynchronous tmpls --- diff --git a/src/lib/server/tmpl.h b/src/lib/server/tmpl.h index 078532f5e7f..6d83b67a60c 100644 --- a/src/lib/server/tmpl.h +++ b/src/lib/server/tmpl.h @@ -1136,6 +1136,8 @@ void tmpl_extents_debug(fr_dlist_head_t *head) CC_HINT(nonnull); int tmpl_eval_pair(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt); +int tmpl_eval(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt); + int tmpl_eval_cast(TALLOC_CTX *ctx, fr_value_box_list_t *out, tmpl_t const *vpt); /** @} */ diff --git a/src/lib/server/tmpl_eval.c b/src/lib/server/tmpl_eval.c index 5361d26432f..2a476b0bef6 100644 --- a/src/lib/server/tmpl_eval.c +++ b/src/lib/server/tmpl_eval.c @@ -1360,6 +1360,91 @@ fail: return ret; } + +/** Gets the value of a tmpl + * + * The result is returned "raw". The caller must do any escaping it desires. + * + * @param[in] ctx to allocate boxed value, and buffers in. + * @param[out] out Where to write the boxed value. + * @param[in] request The current request. + * @param[in] vpt Representing the tmpl + * @return + * - <0 we failed getting a value for the tmpl + * - 0 we successfully evaluated the tmpl + */ +int tmpl_eval(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt) +{ + char *p; + fr_value_box_t *value; + fr_value_box_list_t list; + + if (tmpl_needs_resolving(vpt)) { + fr_strerror_const("Cannot evaluate unresolved tmpl"); + return -1; + } + + if (tmpl_async_required(vpt)) { + fr_strerror_const("Cannot statically evaluate asynchronous expansions"); + return -1; + } + + if (tmpl_contains_regex(vpt)) { + fr_strerror_const("Cannot statically evaluate regular expression"); + return -1; + } + + if (tmpl_is_attr(vpt) || tmpl_is_list(vpt)) { + return tmpl_eval_pair(ctx, out, request, vpt); + } + + if (tmpl_is_data(vpt)) { + MEM(value = fr_value_box_alloc(ctx, tmpl_value_type(vpt), NULL, + tmpl_value(vpt)->tainted)); + + fr_value_box_copy(value, value, tmpl_value(vpt)); /* Also dups taint */ + goto done; + } + + fr_assert(tmpl_is_xlat(vpt)); + + if (xlat_async_required(tmpl_xlat(vpt))) { + fr_strerror_const("Cannot evaluate async xlat"); + return -1; + } + + /* + * @todo - respect escaping functions. But the sync + * escaping uses a different method than the async ones. + * And we then also need to escape the output of + * tmpl_eval_pair(), too. + */ + MEM(value = fr_value_box_alloc_null(ctx)); + + if (tmpl_aexpand(value, &p, request, vpt, NULL, NULL) < 0) { + talloc_free(value); + return -1; + } + fr_value_box_bstrndup_shallow(value, NULL, p, talloc_array_length(p) - 1, true); + + /* + * Cast the results if necessary. + */ +done: + fr_value_box_list_init(&list); + fr_dlist_insert_tail(&list, value); + + if (tmpl_eval_cast(ctx, &list, vpt) < 0) { + fr_dlist_talloc_free(&list); + return -1; + }; + + fr_dlist_move(out, &list); + return 0; +} + + + /** Casts a value or list of values according to the tmpl * * @param[in] ctx to allocate boxed value, and buffers in. @@ -1424,6 +1509,8 @@ int tmpl_eval_cast(TALLOC_CTX *ctx, fr_value_box_list_t *list, tmpl_t const *vpt return 0; } + + int tmpl_global_init(void) { if (fr_dict_autoload(tmpl_dict) < 0) {