]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
added tmpl_eval()
authorAlan T. DeKok <aland@freeradius.org>
Wed, 29 Jun 2022 13:20:48 +0000 (09:20 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 30 Jun 2022 11:24:32 +0000 (07:24 -0400)
which only does asynchronous tmpls

src/lib/server/tmpl.h
src/lib/server/tmpl_eval.c

index 078532f5e7fbc2485c68980850af588647955c39..6d83b67a60c98a65727edff4aab594c7a5f4fefc 100644 (file)
@@ -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);
 /** @} */
 
index 5361d26432f88a5a2ade063e05041a65f082cfde..2a476b0bef67931e705676ce1b2b4df608d24cac 100644 (file)
@@ -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) {