]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
xlat: Move function registration code into its own source file
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 29 Mar 2023 22:44:10 +0000 (16:44 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 29 Mar 2023 22:44:10 +0000 (16:44 -0600)
38 files changed:
src/bin/unit_test_attribute.c
src/lib/eap_aka_sim/xlat.c
src/lib/server/main_config.c
src/lib/server/module.c
src/lib/server/module_rlm.c
src/lib/unlang/all.mk
src/lib/unlang/foreach.c
src/lib/unlang/interpret.c
src/lib/unlang/xlat.h
src/lib/unlang/xlat_builtin.c
src/lib/unlang/xlat_expr.c
src/lib/unlang/xlat_register.c [new file with mode: 0644]
src/lib/unlang/xlat_register.h [new file with mode: 0644]
src/modules/rlm_always/rlm_always.c
src/modules/rlm_cache/rlm_cache.c
src/modules/rlm_chap/rlm_chap.c
src/modules/rlm_cipher/rlm_cipher.c
src/modules/rlm_client/rlm_client.c
src/modules/rlm_date/rlm_date.c
src/modules/rlm_delay/rlm_delay.c
src/modules/rlm_dict/rlm_dict.c
src/modules/rlm_escape/rlm_escape.c
src/modules/rlm_exec/rlm_exec.c
src/modules/rlm_icmp/rlm_icmp.c
src/modules/rlm_idn/rlm_idn.c
src/modules/rlm_json/rlm_json.c
src/modules/rlm_ldap/rlm_ldap.c
src/modules/rlm_linelog/rlm_linelog.c
src/modules/rlm_mschap/rlm_mschap.c
src/modules/rlm_perl/rlm_perl.c
src/modules/rlm_redis/rlm_redis.c
src/modules/rlm_rest/rlm_rest.c
src/modules/rlm_soh/rlm_soh.c
src/modules/rlm_sql/rlm_sql.c
src/modules/rlm_test/rlm_test.c
src/modules/rlm_unbound/rlm_unbound.c
src/modules/rlm_unpack/rlm_unpack.c
src/modules/rlm_yubikey/rlm_yubikey.c

index 2e18b63ee5c0dbcb8ed8afd0f46eba36731b9e5d..e85b7a73040cd7c1ff14730db6385261cdc4eca3 100644 (file)
@@ -42,6 +42,7 @@ typedef struct request_s request_t;
 #endif
 #include <freeradius-devel/unlang/base.h>
 #include <freeradius-devel/unlang/xlat.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 #include <freeradius-devel/util/atexit.h>
 #include <freeradius-devel/util/base64.h>
 #include <freeradius-devel/util/calc.h>
index 6714130cc3356480bab05c51ffe8aadeba5901b5..9597a1a510ff0d4bb6d69ffbb0aea34bca9bb134 100644 (file)
@@ -25,6 +25,8 @@
  */
 
 #include <freeradius-devel/server/base.h>
+#include <freeradius-devel/unlang/xlat_register.h>
+
 #include "base.h"
 #include "attrs.h"
 
index d13057bf7445e2c6b996ca8ecf0fc0f20467b8e3..8ce5d90f3a5eefd0a809919e9ab3db92f62ad70d 100644 (file)
@@ -45,6 +45,8 @@ RCSID("$Id$")
 #include <freeradius-devel/util/perm.h>
 #include <freeradius-devel/util/sem.h>
 
+#include <freeradius-devel/unlang/xlat_register.h>
+
 #include <sys/stat.h>
 #include <pwd.h>
 #include <grp.h>
@@ -1020,7 +1022,7 @@ int main_config_init(main_config_t *config)
        /*
         *      Initialize the xlats before we load the configuration files, so that we can later call xlat_register().
         */
-       xlat_init();
+       xlat_register_init();
 
        if (stat(config->raddb_dir, &statbuf) < 0) {
                ERROR("Error checking raddb_dir \"%s\": %s", config->raddb_dir, fr_syserror(errno));
index d9b301a47d5c745b1f4a3efedf7849ebda19ea85..4551f646f6d6fc50fcceba70283ac5e8f40e2291 100644 (file)
@@ -35,6 +35,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/module_rlm.h>
 #include <freeradius-devel/server/radmin.h>
 #include <freeradius-devel/server/request_data.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 /** Heap of all lists/modules used to get a common index with module_thread_inst_list
  *
index cddbd2f4ee788f12783b5090e226d1924f018614..6dafe3e31b13f3788d1763f8e54bd963da81a6e5 100644 (file)
@@ -35,6 +35,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/pair.h>
 #include <freeradius-devel/server/virtual_servers.h>
 #include <freeradius-devel/util/atexit.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 /** Lookup virtual module by name
  */
index 007a6f2497d31e415dae70565ff36f3c625f8f12..862e3ed319389ba9be50d0eb8f83f1fbcc1fae1f 100644 (file)
@@ -32,8 +32,9 @@ SOURCES       :=      base.c \
                xlat_expr.c \
                xlat_inst.c \
                xlat_pair.c \
-               xlat_tokenize.c \
-               xlat_purify.c
+               xlat_purify.c \
+               xlat_register.c \
+               xlat_tokenize.c
 
 HEADERS                := $(subst src/lib/,,$(wildcard src/lib/unlang/*.h))
 
index 37ea16d3ddd1c6e14c6e4990e60e6efe8383ba64..1de5aabf681a75dd9748a9864204638dc555f300 100644 (file)
@@ -25,6 +25,7 @@
 RCSID("$Id$")
 
 #include <freeradius-devel/server/request_data.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 #include "foreach_priv.h"
 #include "return_priv.h"
index fc23e36dc35836e8fe7d35239c9aca9486d81c1c..93a0079cf55887a953ceabb619cdc3abd3593e8e 100644 (file)
@@ -26,6 +26,7 @@ RCSID("$Id$")
 
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/server/modpriv.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 #include "interpret_priv.h"
 #include "module_priv.h"
index 1fca1b13eb6aa4b5dfd68da0a64cb9a06b5e19e5..0a6eeb10d4cb35537da788b2cd4f751483c2e093 100644 (file)
@@ -426,54 +426,6 @@ bool               xlat_to_string(TALLOC_CTX *ctx, char **str, xlat_exp_head_t **head);
 
 int            xlat_resolve(xlat_exp_head_t *head, xlat_res_rules_t const *xr_rules);
 
-xlat_t         *xlat_register_module(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx,
-                                     char const *name, xlat_func_t func, fr_type_t return_type);
-xlat_t         *xlat_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type) CC_HINT(nonnull(2));
-
-int            xlat_func_args_set(xlat_t *xlat, xlat_arg_parser_t const args[]) CC_HINT(nonnull);
-
-int            xlat_func_mono_set(xlat_t *xlat, xlat_arg_parser_t const *arg) CC_HINT(nonnull);
-
-void           xlat_func_flags_set(xlat_t *x, xlat_flags_t const *flags) CC_HINT(nonnull);
-
-/** Set a callback for global instantiation of xlat functions
- *
- * @param[in] _xlat            function to set the callback for (as returned by xlat_register).
- * @param[in] _instantiate     A instantiation callback.
- * @param[in] _inst_struct     The instance struct to pre-allocate.
- * @param[in] _detach          A destructor callback.
- * @param[in] _uctx            to pass to _instantiate and _detach callbacks.
- */
-#define        xlat_async_instantiate_set(_xlat, _instantiate, _inst_struct, _detach, _uctx) \
-       _xlat_async_instantiate_set(_xlat, _instantiate, #_inst_struct, sizeof(_inst_struct), _detach, _uctx)
-void _xlat_async_instantiate_set(xlat_t const *xlat,
-                                       xlat_instantiate_t instantiate, char const *inst_type, size_t inst_size,
-                                       xlat_detach_t detach,
-                                       void *uctx);
-
-/** Set a callback for thread-specific instantiation of xlat functions
- *
- * @param[in] _xlat            function to set the callback for (as returned by xlat_register).
- * @param[in] _instantiate     A instantiation callback.
- * @param[in] _inst_struct     The instance struct to pre-allocate.
- * @param[in] _detach          A destructor callback.
- * @param[in] _uctx            to pass to _instantiate and _detach callbacks.
- */
-#define        xlat_async_thread_instantiate_set(_xlat, _instantiate, _inst_struct, _detach, _uctx) \
-       _xlat_async_thread_instantiate_set(_xlat, _instantiate, #_inst_struct, sizeof(_inst_struct), _detach, _uctx)
-void _xlat_async_thread_instantiate_set(xlat_t const *xlat,
-                                       xlat_thread_instantiate_t thread_instantiate,
-                                       char const *thread_inst_type, size_t thread_inst_size,
-                                       xlat_thread_detach_t thread_detach,
-                                       void *uctx);
-
-void           xlat_unregister(char const *name);
-void           xlat_unregister_module(dl_module_inst_t const *inst);
-int            xlat_register_redundant(CONF_SECTION *cs);
-/** @hidecallgraph */
-int            xlat_init(void);
-void           xlat_free(void);
-
 void           xlat_debug_attr_list(request_t *request, fr_pair_list_t const *list);
 void           xlat_debug_attr_vp(request_t *request, fr_pair_t *vp, tmpl_t const *vpt);
 /*
@@ -541,6 +493,13 @@ int                unlang_xlat_push(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out
 xlat_action_t  unlang_xlat_yield(request_t *request,
                                  xlat_func_t callback, xlat_func_signal_t signal,
                                  void *rctx);
+
+/*
+ *     xlat_builtin.c
+ */
+int            xlat_init(void);
+void           xlat_free(void);
+
 #ifdef __cplusplus
 }
 #endif
index 9359831aab33b26b1fee2aa89b860dba0d514109..74ea1d74d43d67e5fc009c16a5a0e03796299920 100644 (file)
@@ -33,6 +33,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/server/tmpl_dcursor.h>
 #include <freeradius-devel/unlang/xlat_priv.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 #include <freeradius-devel/unlang/xlat.h>
 
 #include <freeradius-devel/io/test_point.h>
@@ -52,9 +53,6 @@ RCSID("$Id$")
 #ifdef HAVE_REGEX_PCRE2
 #endif
 
-
-static fr_rb_tree_t *xlat_root = NULL;
-
 static char const hextab[] = "0123456789abcdef";
 
 /** Return a VP from the specified request.
@@ -91,429 +89,6 @@ int xlat_fmt_get_vp(fr_pair_t **out, request_t *request, char const *name)
        return ret;
 }
 
-
-/*
- *     Compare two xlat_t structs, based ONLY on the module name.
- */
-static int8_t xlat_cmp(void const *one, void const *two)
-{
-       xlat_t const *a = one, *b = two;
-       size_t a_len, b_len;
-       int ret;
-
-       a_len = strlen(a->name);
-       b_len = strlen(b->name);
-
-       ret = CMP(a_len, b_len);
-       if (ret != 0) return ret;
-
-       ret = memcmp(a->name, b->name, a_len);
-       return CMP(ret, 0);
-}
-
-
-/*
- *     find the appropriate registered xlat function.
- */
-xlat_t *xlat_func_find(char const *in, ssize_t inlen)
-{
-       char buffer[256];
-
-       if (!xlat_root) return NULL;
-
-       if (inlen < 0) return fr_rb_find(xlat_root, &(xlat_t){ .name = in });
-
-       if ((size_t) inlen >= sizeof(buffer)) return NULL;
-
-       memcpy(buffer, in, inlen);
-       buffer[inlen] = '\0';
-
-       return fr_rb_find(xlat_root, &(xlat_t){ .name = buffer });
-}
-
-
-/** Remove an xlat function from the function tree
- *
- * @param[in] xlat     to free.
- * @return 0
- */
-static int _xlat_func_talloc_free(xlat_t *xlat)
-{
-       if (!xlat_root) return 0;
-
-       fr_rb_delete(xlat_root, xlat);
-       if (fr_rb_num_elements(xlat_root) == 0) TALLOC_FREE(xlat_root);
-
-       return 0;
-}
-
-
-/** Callback for the rbtree to clear out any xlats still registered
- *
- */
-static void _xlat_func_tree_free(void *xlat)
-{
-       talloc_free(xlat);
-}
-
-#if 0
-/** Compare two argument entries to see if they're equivalent
- *
- * @note Does not check escape function or uctx pointers.
- *
- * @param[in] a                First argument structure.
- * @param[in] b                Second argument structure.
- * @return
- *     - 1 if a > b
- *     - 0 if a == b
- *     - -1 if a < b
- */
-static int xlat_arg_cmp_no_escape(xlat_arg_parser_t const *a, xlat_arg_parser_t const *b)
-{
-       int8_t ret;
-
-       ret = CMP(a->required, b->required);
-       if (ret != 0) return ret;
-
-       ret = CMP(a->concat, b->concat);
-       if (ret != 0) return ret;
-
-       ret = CMP(a->single, b->single);
-       if (ret != 0) return ret;
-
-       ret = CMP(a->variadic, b->variadic);
-       if (ret != 0) return ret;
-
-       ret = CMP(a->always_escape, b->always_escape);
-       if (ret != 0) return ret;
-
-       return CMP(a->type, b->type);
-}
-
-/** Compare two argument lists to see if they're equivalent
- *
- * @note Does not check escape function or uctx pointers.
- *
- * @param[in] a                First argument structure.
- * @param[in] b                Second argument structure.
- * @return
- *     - 1 if a > b
- *     - 0 if a == b
- *     - -1 if a < b
- */
-static int xlat_arg_cmp_list_no_escape(xlat_arg_parser_t const a[], xlat_arg_parser_t const b[])
-{
-       xlat_arg_parser_t const *arg_a_p;
-       xlat_arg_parser_t const *arg_b_p;
-
-       for (arg_a_p = a, arg_b_p = b;
-            (arg_a_p->type != FR_TYPE_NULL) && (arg_b_p->type != FR_TYPE_NULL);
-            arg_a_p++, arg_b_p++) {
-               int8_t ret;
-
-               ret = xlat_arg_cmp_no_escape(arg_a_p, arg_b_p);
-               if (ret != 0) return ret;
-       }
-
-       return CMP(arg_a_p, arg_b_p);   /* Check we ended at the same point */
-}
-#endif
-
-/** Register an xlat function for a module
- *
- * @param[in] ctx              Used to automate deregistration of the xlat fnction.
- * @param[in] mctx             Instantiation context from the module.
- *                             Will be duplicated and passed to future xlat calls.
- * @param[in] name             of the xlat.
- * @param[in] func             to register.
- * @param[in] return_type      what type of output the xlat function will produce.
- * @return
- *     - A handle for the newly registered xlat function on success.
- *     - NULL on failure.
- */
-xlat_t *xlat_register_module(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx,
-                            char const *name, xlat_func_t func, fr_type_t return_type)
-{
-       xlat_t  *c;
-       module_inst_ctx_t *our_mctx = NULL;
-
-       fr_assert(xlat_root);
-
-       if (!*name) {
-               ERROR("%s: Invalid xlat name", __FUNCTION__);
-               return NULL;
-       }
-
-       /*
-        *      If it already exists, replace the instance.
-        */
-       c = fr_rb_find(xlat_root, &(xlat_t){ .name = name });
-       if (c) {
-               if (c->internal) {
-                       ERROR("%s: Cannot re-define internal expansion %s", __FUNCTION__, name);
-                       return NULL;
-               }
-
-               if (c->func != func) {
-                       ERROR("%s: Cannot change callback function for %s", __FUNCTION__, name);
-                       return NULL;
-               }
-
-               return c;
-       }
-
-       /*
-        *      Doesn't exist.  Create it.
-        */
-       MEM(c = talloc(ctx, xlat_t));
-       if (mctx) {
-               MEM(our_mctx = talloc_zero(c, module_inst_ctx_t));      /* Original won't stick around */
-               memcpy(our_mctx, mctx, sizeof(*our_mctx));
-       }
-       *c = (xlat_t){
-               .name = talloc_typed_strdup(c, name),
-               .func = func,
-               .return_type = return_type,
-               .mctx = our_mctx,
-               .input_type = XLAT_INPUT_UNPROCESSED    /* set default - will be overridden if args are registered */
-       };
-       talloc_set_destructor(c, _xlat_func_talloc_free);
-       DEBUG3("%s: %s", __FUNCTION__, c->name);
-
-       if (fr_rb_replace(NULL, xlat_root, c) < 0) {
-               ERROR("%s: Failed inserting xlat registration for %s", __FUNCTION__, c->name);
-               talloc_free(c);
-               return NULL;
-       }
-
-       return c;
-}
-
-/** Register an xlat function
- *
- * @param[in] ctx              Used to automate deregistration of the xlat fnction.
- * @param[in] name             of the xlat.
- * @param[in] func             to register.
- * @param[in] return_type      what type of output the xlat function will produce.
- * @return
- *     - A handle for the newly registered xlat function on success.
- *     - NULL on failure.
- */
-xlat_t *xlat_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
-{
-       return xlat_register_module(ctx, NULL, name, func, return_type);
-}
-
-/** Verify xlat arg specifications are valid
- *
- * @param[in] arg      specification to validate.
- * @param[in] last     Is this the last argument in the list.
- */
-static inline int xlat_arg_parser_validate(xlat_arg_parser_t const *arg, bool last)
-{
-       if (arg->concat) {
-               if (!fr_cond_assert_msg((arg->type == FR_TYPE_STRING) || (arg->type == FR_TYPE_OCTETS),
-                                       "concat type must be string or octets")) return -1;
-
-               if (!fr_cond_assert_msg(!arg->single, "concat and single are mutually exclusive")) return -1;
-       }
-
-       if (arg->single) {
-               if (!fr_cond_assert_msg(!arg->concat, "single and concat are mutually exclusive")) return -1;
-       }
-
-       if (arg->variadic) {
-               if (!fr_cond_assert_msg(last, "variadic can only be set on the last argument")) return -1;
-       }
-
-       if (arg->always_escape) {
-               if (!fr_cond_assert_msg(arg->func, "always_escape requires an escape func")) return -1;
-       }
-
-       if (arg->uctx) {
-               if (!fr_cond_assert_msg(arg->func, "uctx requires an escape func")) return -1;
-       }
-
-       switch (arg->type) {
-       case FR_TYPE_LEAF:
-       case FR_TYPE_VOID:
-               break;
-
-       default:
-               fr_assert_fail("type must be a leaf box type");
-               return -1;
-       }
-
-       return 0;
-}
-
-/** Register the arguments of an xlat
- *
- * For xlats that take multiple arguments
- *
- * @param[in,out] x            to have it's arguments registered
- * @param[in] args             to be registered
- * @return
- *     - 0 on success.
- *     - < 0 on failure.
- */
-int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
-{
-       xlat_arg_parser_t const *arg_p = args;
-       bool                    seen_optional = false;
-
-       for (arg_p = args; arg_p->type != FR_TYPE_NULL; arg_p++) {
-               if (xlat_arg_parser_validate(arg_p, (arg_p + 1)->type == FR_TYPE_NULL) < 0) return -1;
-
-               if (arg_p->required) {
-                       if (!fr_cond_assert_msg(!seen_optional,
-                                               "required arguments must be at the "
-                                               "start of the argument list")) return -1;
-               } else {
-                       seen_optional = true;
-               }
-       }
-       x->args = args;
-       x->input_type = XLAT_INPUT_ARGS;
-
-       return 0;
-}
-
-/** Register the argument of an xlat
- *
- * For xlats that take all their input as a single argument
- *
- * @param[in,out] x            to have it's arguments registered
- * @param[in] args             to be registered
- * @return
- *     - 0 on success.
- *     - < 0 on failure.
- */
-int xlat_func_mono_set(xlat_t *x, xlat_arg_parser_t const args[])
-{
-       if (xlat_func_args_set(x, args) < 0) return -1;
-       x->input_type = XLAT_INPUT_MONO;
-
-       return 0;
-}
-
-/** Specify flags that alter the xlat's behaviour
- *
- * @param[in] x                        xlat to set flags for.
- * @param[in] flags            to set.
- */
-void xlat_func_flags_set(xlat_t *x, xlat_flags_t const *flags)
-{
-       /*
-        *      If the function is async, it can't be pure.  But
-        *      non-pure functions don't need to be async.
-        */
-       fr_assert(!flags->needs_resolving);
-
-       x->flags = *flags;
-}
-
-/** Set global instantiation/detach callbacks
- *
- * @param[in] xlat             to set instantiation callbacks for.
- * @param[in] instantiate      Instantiation function. Called whenever a xlat is
- *                             compiled.
- * @param[in] inst_type                Name of the instance structure.
- * @param[in] inst_size                The size of the instance struct.
- *                             Pre-allocated for use by the instantiate function.
- *                             If 0, no memory will be allocated.
- * @param[in] detach           Called when an xlat_exp_t is freed.
- * @param[in] uctx             Passed to the instantiation function.
- */
-void _xlat_async_instantiate_set(xlat_t const *xlat,
-                                xlat_instantiate_t instantiate, char const *inst_type, size_t inst_size,
-                                xlat_detach_t detach,
-                                void *uctx)
-{
-       xlat_t *c = UNCONST(xlat_t *, xlat);
-
-       c->instantiate = instantiate;
-       c->inst_type = inst_type;
-       c->inst_size = inst_size;
-       c->detach = detach;
-       c->uctx = uctx;
-}
-
-/** Register an async xlat
- *
- * All functions registered must be !pure
- *
- * @param[in] xlat                     to set instantiation callbacks for.
- * @param[in] thread_instantiate       Instantiation function. Called for every compiled xlat
- *                                     every time a thread is started.
- * @param[in] thread_inst_type         Name of the thread instance structure.
- * @param[in] thread_inst_size         The size of the thread instance struct.
- *                                     Pre-allocated for use by the instantiate function.
- *                                     If 0, no memory will be allocated.
- * @param[in] thread_detach            Called when the thread is freed.
- * @param[in] uctx                     Passed to the thread instantiate function.
- */
-void _xlat_async_thread_instantiate_set(xlat_t const *xlat,
-                                       xlat_thread_instantiate_t thread_instantiate,
-                                       char const *thread_inst_type, size_t thread_inst_size,
-                                       xlat_thread_detach_t thread_detach,
-                                       void *uctx)
-{
-       xlat_t *c = UNCONST(xlat_t *, xlat);
-
-       /*
-        *      Pure functions can't use any thread-local
-        *      variables. They MUST operate only on constant
-        *      instantiation data, and on their (possibly constant)
-        *      inputs.
-        */
-       fr_assert(!c->flags.pure);
-
-       c->thread_instantiate = thread_instantiate;
-       c->thread_inst_type = thread_inst_type;
-       c->thread_inst_size = thread_inst_size;
-       c->thread_detach = thread_detach;
-       c->thread_uctx = uctx;
-}
-
-/** Unregister an xlat function
- *
- * We can only have one function to call per name, so the passing of "func"
- * here is extraneous.
- *
- * @param[in] name xlat to unregister.
- */
-void xlat_unregister(char const *name)
-{
-       xlat_t  *c;
-
-       if (!name || !xlat_root) return;
-
-       c = fr_rb_find(xlat_root, &(xlat_t){ .name = name });
-       if (!c) return;
-
-       (void) talloc_get_type_abort(c, xlat_t);
-
-       talloc_free(c); /* Should also remove from tree */
-}
-
-void xlat_unregister_module(dl_module_inst_t const *inst)
-{
-       xlat_t                          *c;
-       fr_rb_iter_inorder_t    iter;
-
-       if (!xlat_root) return; /* All xlats have already been freed */
-
-       for (c = fr_rb_iter_init_inorder(&iter, xlat_root);
-            c;
-            c = fr_rb_iter_next_inorder(&iter)) {
-               if (!c->mctx) continue;
-               if (c->mctx->inst != inst) continue;
-
-               fr_rb_iter_delete_inorder(&iter);
-       }
-}
-
 /*
  *     Internal redundant handler for xlats
  */
@@ -4113,7 +3688,7 @@ int xlat_init(void)
 {
        xlat_t *xlat;
 
-       if (xlat_root) return 0;
+       if (xlat_register_init() < 0) return -1;
 
        /*
         *      Lookup attributes used by virtual xlat expansions.
@@ -4125,15 +3700,6 @@ int xlat_init(void)
         */
        unlang_xlat_init();
 
-       /*
-        *      Create the function tree
-        */
-       xlat_root = fr_rb_inline_talloc_alloc(NULL, xlat_t, node, xlat_cmp, _xlat_func_tree_free);
-       if (!xlat_root) {
-               ERROR("%s: Failed to create tree", __FUNCTION__);
-               return -1;
-       }
-
        /*
         *      Define encode/decode xlats for the various protocols.
         */
@@ -4260,18 +3826,12 @@ do { \
        return xlat_register_expressions();
 }
 
-
 /** De-register all xlat functions we created
  *
  */
 void xlat_free(void)
 {
-       fr_rb_tree_t *xr = xlat_root;           /* Make sure the tree can't be freed multiple times */
-
-       if (!xr) return;
-
-       xlat_root = NULL;
-       talloc_free(xr);
+       xlat_register_free();
 
        xlat_eval_free();
 }
index 5f68d7d45ee2b6b40c01ff957a69c1411eab3245..6ae560812a61ea9bdae60fd21e4267e16b77b788 100644 (file)
@@ -30,6 +30,7 @@ RCSID("$Id$")
 #include <freeradius-devel/unlang/xlat_priv.h>
 #include <freeradius-devel/util/calc.h>
 #include <freeradius-devel/server/tmpl_dcursor.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 #undef XLAT_DEBUG
 #ifdef DEBUG_XLAT
diff --git a/src/lib/unlang/xlat_register.c b/src/lib/unlang/xlat_register.c
new file mode 100644 (file)
index 0000000..92bc251
--- /dev/null
@@ -0,0 +1,478 @@
+/*
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * $Id$
+ *
+ * @file xlat_register.c
+ * @brief Registration API for xlat functions
+ *
+ * @copyright 2023 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
+ */
+
+RCSID("$Id$")
+
+#include <freeradius-devel/unlang/xlat_priv.h>
+#include <freeradius-devel/unlang/xlat.h>
+#include <freeradius-devel/unlang/xlat_register.h>
+
+static fr_rb_tree_t *xlat_root = NULL;
+
+/*
+ *     Compare two xlat_t structs, based ONLY on the module name.
+ */
+static int8_t xlat_cmp(void const *one, void const *two)
+{
+       xlat_t const *a = one, *b = two;
+       size_t a_len, b_len;
+       int ret;
+
+       a_len = strlen(a->name);
+       b_len = strlen(b->name);
+
+       ret = CMP(a_len, b_len);
+       if (ret != 0) return ret;
+
+       ret = memcmp(a->name, b->name, a_len);
+       return CMP(ret, 0);
+}
+
+/*
+ *     find the appropriate registered xlat function.
+ */
+xlat_t *xlat_func_find(char const *in, ssize_t inlen)
+{
+       char buffer[256];
+
+       if (!xlat_root) return NULL;
+
+       if (inlen < 0) return fr_rb_find(xlat_root, &(xlat_t){ .name = in });
+
+       if ((size_t) inlen >= sizeof(buffer)) return NULL;
+
+       memcpy(buffer, in, inlen);
+       buffer[inlen] = '\0';
+
+       return fr_rb_find(xlat_root, &(xlat_t){ .name = buffer });
+}
+
+/** Remove an xlat function from the function tree
+ *
+ * @param[in] xlat     to free.
+ * @return 0
+ */
+static int _xlat_func_talloc_free(xlat_t *xlat)
+{
+       if (!xlat_root) return 0;
+
+       fr_rb_delete(xlat_root, xlat);
+       if (fr_rb_num_elements(xlat_root) == 0) TALLOC_FREE(xlat_root);
+
+       return 0;
+}
+
+
+/** Callback for the rbtree to clear out any xlats still registered
+ *
+ */
+static void _xlat_func_tree_free(void *xlat)
+{
+       talloc_free(xlat);
+}
+
+#if 0
+/** Compare two argument entries to see if they're equivalent
+ *
+ * @note Does not check escape function or uctx pointers.
+ *
+ * @param[in] a                First argument structure.
+ * @param[in] b                Second argument structure.
+ * @return
+ *     - 1 if a > b
+ *     - 0 if a == b
+ *     - -1 if a < b
+ */
+static int xlat_arg_cmp_no_escape(xlat_arg_parser_t const *a, xlat_arg_parser_t const *b)
+{
+       int8_t ret;
+
+       ret = CMP(a->required, b->required);
+       if (ret != 0) return ret;
+
+       ret = CMP(a->concat, b->concat);
+       if (ret != 0) return ret;
+
+       ret = CMP(a->single, b->single);
+       if (ret != 0) return ret;
+
+       ret = CMP(a->variadic, b->variadic);
+       if (ret != 0) return ret;
+
+       ret = CMP(a->always_escape, b->always_escape);
+       if (ret != 0) return ret;
+
+       return CMP(a->type, b->type);
+}
+
+/** Compare two argument lists to see if they're equivalent
+ *
+ * @note Does not check escape function or uctx pointers.
+ *
+ * @param[in] a                First argument structure.
+ * @param[in] b                Second argument structure.
+ * @return
+ *     - 1 if a > b
+ *     - 0 if a == b
+ *     - -1 if a < b
+ */
+static int xlat_arg_cmp_list_no_escape(xlat_arg_parser_t const a[], xlat_arg_parser_t const b[])
+{
+       xlat_arg_parser_t const *arg_a_p;
+       xlat_arg_parser_t const *arg_b_p;
+
+       for (arg_a_p = a, arg_b_p = b;
+            (arg_a_p->type != FR_TYPE_NULL) && (arg_b_p->type != FR_TYPE_NULL);
+            arg_a_p++, arg_b_p++) {
+               int8_t ret;
+
+               ret = xlat_arg_cmp_no_escape(arg_a_p, arg_b_p);
+               if (ret != 0) return ret;
+       }
+
+       return CMP(arg_a_p, arg_b_p);   /* Check we ended at the same point */
+}
+#endif
+
+/** Register an xlat function for a module
+ *
+ * @param[in] ctx              Used to automate deregistration of the xlat fnction.
+ * @param[in] mctx             Instantiation context from the module.
+ *                             Will be duplicated and passed to future xlat calls.
+ * @param[in] name             of the xlat.
+ * @param[in] func             to register.
+ * @param[in] return_type      what type of output the xlat function will produce.
+ * @return
+ *     - A handle for the newly registered xlat function on success.
+ *     - NULL on failure.
+ */
+xlat_t *xlat_register_module(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx,
+                            char const *name, xlat_func_t func, fr_type_t return_type)
+{
+       xlat_t  *c;
+       module_inst_ctx_t *our_mctx = NULL;
+
+       fr_assert(xlat_root);
+
+       if (!*name) {
+               ERROR("%s: Invalid xlat name", __FUNCTION__);
+               return NULL;
+       }
+
+       /*
+        *      If it already exists, replace the instance.
+        */
+       c = fr_rb_find(xlat_root, &(xlat_t){ .name = name });
+       if (c) {
+               if (c->internal) {
+                       ERROR("%s: Cannot re-define internal expansion %s", __FUNCTION__, name);
+                       return NULL;
+               }
+
+               if (c->func != func) {
+                       ERROR("%s: Cannot change callback function for %s", __FUNCTION__, name);
+                       return NULL;
+               }
+
+               return c;
+       }
+
+       /*
+        *      Doesn't exist.  Create it.
+        */
+       MEM(c = talloc(ctx, xlat_t));
+       if (mctx) {
+               MEM(our_mctx = talloc_zero(c, module_inst_ctx_t));      /* Original won't stick around */
+               memcpy(our_mctx, mctx, sizeof(*our_mctx));
+       }
+       *c = (xlat_t){
+               .name = talloc_typed_strdup(c, name),
+               .func = func,
+               .return_type = return_type,
+               .mctx = our_mctx,
+               .input_type = XLAT_INPUT_UNPROCESSED    /* set default - will be overridden if args are registered */
+       };
+       talloc_set_destructor(c, _xlat_func_talloc_free);
+       DEBUG3("%s: %s", __FUNCTION__, c->name);
+
+       if (fr_rb_replace(NULL, xlat_root, c) < 0) {
+               ERROR("%s: Failed inserting xlat registration for %s", __FUNCTION__, c->name);
+               talloc_free(c);
+               return NULL;
+       }
+
+       return c;
+}
+
+/** Register an xlat function
+ *
+ * @param[in] ctx              Used to automate deregistration of the xlat fnction.
+ * @param[in] name             of the xlat.
+ * @param[in] func             to register.
+ * @param[in] return_type      what type of output the xlat function will produce.
+ * @return
+ *     - A handle for the newly registered xlat function on success.
+ *     - NULL on failure.
+ */
+xlat_t *xlat_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
+{
+       return xlat_register_module(ctx, NULL, name, func, return_type);
+}
+
+/** Verify xlat arg specifications are valid
+ *
+ * @param[in] arg      specification to validate.
+ * @param[in] last     Is this the last argument in the list.
+ */
+static inline int xlat_arg_parser_validate(xlat_arg_parser_t const *arg, bool last)
+{
+       if (arg->concat) {
+               if (!fr_cond_assert_msg((arg->type == FR_TYPE_STRING) || (arg->type == FR_TYPE_OCTETS),
+                                       "concat type must be string or octets")) return -1;
+
+               if (!fr_cond_assert_msg(!arg->single, "concat and single are mutually exclusive")) return -1;
+       }
+
+       if (arg->single) {
+               if (!fr_cond_assert_msg(!arg->concat, "single and concat are mutually exclusive")) return -1;
+       }
+
+       if (arg->variadic) {
+               if (!fr_cond_assert_msg(last, "variadic can only be set on the last argument")) return -1;
+       }
+
+       if (arg->always_escape) {
+               if (!fr_cond_assert_msg(arg->func, "always_escape requires an escape func")) return -1;
+       }
+
+       if (arg->uctx) {
+               if (!fr_cond_assert_msg(arg->func, "uctx requires an escape func")) return -1;
+       }
+
+       switch (arg->type) {
+       case FR_TYPE_LEAF:
+       case FR_TYPE_VOID:
+               break;
+
+       default:
+               fr_assert_fail("type must be a leaf box type");
+               return -1;
+       }
+
+       return 0;
+}
+
+/** Register the arguments of an xlat
+ *
+ * For xlats that take multiple arguments
+ *
+ * @param[in,out] x            to have it's arguments registered
+ * @param[in] args             to be registered
+ * @return
+ *     - 0 on success.
+ *     - < 0 on failure.
+ */
+int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
+{
+       xlat_arg_parser_t const *arg_p = args;
+       bool                    seen_optional = false;
+
+       for (arg_p = args; arg_p->type != FR_TYPE_NULL; arg_p++) {
+               if (xlat_arg_parser_validate(arg_p, (arg_p + 1)->type == FR_TYPE_NULL) < 0) return -1;
+
+               if (arg_p->required) {
+                       if (!fr_cond_assert_msg(!seen_optional,
+                                               "required arguments must be at the "
+                                               "start of the argument list")) return -1;
+               } else {
+                       seen_optional = true;
+               }
+       }
+       x->args = args;
+       x->input_type = XLAT_INPUT_ARGS;
+
+       return 0;
+}
+
+/** Register the argument of an xlat
+ *
+ * For xlats that take all their input as a single argument
+ *
+ * @param[in,out] x            to have it's arguments registered
+ * @param[in] args             to be registered
+ * @return
+ *     - 0 on success.
+ *     - < 0 on failure.
+ */
+int xlat_func_mono_set(xlat_t *x, xlat_arg_parser_t const args[])
+{
+       if (xlat_func_args_set(x, args) < 0) return -1;
+       x->input_type = XLAT_INPUT_MONO;
+
+       return 0;
+}
+
+/** Specify flags that alter the xlat's behaviour
+ *
+ * @param[in] x                        xlat to set flags for.
+ * @param[in] flags            to set.
+ */
+void xlat_func_flags_set(xlat_t *x, xlat_flags_t const *flags)
+{
+       /*
+        *      If the function is async, it can't be pure.  But
+        *      non-pure functions don't need to be async.
+        */
+       fr_assert(!flags->needs_resolving);
+
+       x->flags = *flags;
+}
+
+/** Set global instantiation/detach callbacks
+ *
+ * @param[in] xlat             to set instantiation callbacks for.
+ * @param[in] instantiate      Instantiation function. Called whenever a xlat is
+ *                             compiled.
+ * @param[in] inst_type                Name of the instance structure.
+ * @param[in] inst_size                The size of the instance struct.
+ *                             Pre-allocated for use by the instantiate function.
+ *                             If 0, no memory will be allocated.
+ * @param[in] detach           Called when an xlat_exp_t is freed.
+ * @param[in] uctx             Passed to the instantiation function.
+ */
+void _xlat_async_instantiate_set(xlat_t const *xlat,
+                                xlat_instantiate_t instantiate, char const *inst_type, size_t inst_size,
+                                xlat_detach_t detach,
+                                void *uctx)
+{
+       xlat_t *c = UNCONST(xlat_t *, xlat);
+
+       c->instantiate = instantiate;
+       c->inst_type = inst_type;
+       c->inst_size = inst_size;
+       c->detach = detach;
+       c->uctx = uctx;
+}
+
+/** Register an async xlat
+ *
+ * All functions registered must be !pure
+ *
+ * @param[in] xlat                     to set instantiation callbacks for.
+ * @param[in] thread_instantiate       Instantiation function. Called for every compiled xlat
+ *                                     every time a thread is started.
+ * @param[in] thread_inst_type         Name of the thread instance structure.
+ * @param[in] thread_inst_size         The size of the thread instance struct.
+ *                                     Pre-allocated for use by the instantiate function.
+ *                                     If 0, no memory will be allocated.
+ * @param[in] thread_detach            Called when the thread is freed.
+ * @param[in] uctx                     Passed to the thread instantiate function.
+ */
+void _xlat_async_thread_instantiate_set(xlat_t const *xlat,
+                                       xlat_thread_instantiate_t thread_instantiate,
+                                       char const *thread_inst_type, size_t thread_inst_size,
+                                       xlat_thread_detach_t thread_detach,
+                                       void *uctx)
+{
+       xlat_t *c = UNCONST(xlat_t *, xlat);
+
+       /*
+        *      Pure functions can't use any thread-local
+        *      variables. They MUST operate only on constant
+        *      instantiation data, and on their (possibly constant)
+        *      inputs.
+        */
+       fr_assert(!c->flags.pure);
+
+       c->thread_instantiate = thread_instantiate;
+       c->thread_inst_type = thread_inst_type;
+       c->thread_inst_size = thread_inst_size;
+       c->thread_detach = thread_detach;
+       c->thread_uctx = uctx;
+}
+
+/** Unregister an xlat function
+ *
+ * We can only have one function to call per name, so the passing of "func"
+ * here is extraneous.
+ *
+ * @param[in] name xlat to unregister.
+ */
+void xlat_unregister(char const *name)
+{
+       xlat_t  *c;
+
+       if (!name || !xlat_root) return;
+
+       c = fr_rb_find(xlat_root, &(xlat_t){ .name = name });
+       if (!c) return;
+
+       (void) talloc_get_type_abort(c, xlat_t);
+
+       talloc_free(c); /* Should also remove from tree */
+}
+
+void xlat_unregister_module(dl_module_inst_t const *inst)
+{
+       xlat_t                          *c;
+       fr_rb_iter_inorder_t    iter;
+
+       if (!xlat_root) return; /* All xlats have already been freed */
+
+       for (c = fr_rb_iter_init_inorder(&iter, xlat_root);
+            c;
+            c = fr_rb_iter_next_inorder(&iter)) {
+               if (!c->mctx) continue;
+               if (c->mctx->inst != inst) continue;
+
+               fr_rb_iter_delete_inorder(&iter);
+       }
+}
+
+int xlat_register_init(void)
+{
+       if (xlat_root) return 0;
+
+       /*
+        *      Create the function tree
+        */
+       xlat_root = fr_rb_inline_talloc_alloc(NULL, xlat_t, node, xlat_cmp, _xlat_func_tree_free);
+       if (!xlat_root) {
+               ERROR("%s: Failed to create tree", __FUNCTION__);
+               return -1;
+       }
+
+       return 0;
+}
+
+void xlat_register_free(void)
+{
+       fr_rb_tree_t *xr = xlat_root;           /* Make sure the tree can't be freed multiple times */
+
+       if (!xr) return;
+
+       xlat_root = NULL;
+       talloc_free(xr);
+}
diff --git a/src/lib/unlang/xlat_register.h b/src/lib/unlang/xlat_register.h
new file mode 100644 (file)
index 0000000..f79ac7a
--- /dev/null
@@ -0,0 +1,77 @@
+#pragma once
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * $Id$
+ *
+ * @file lib/unlang/xlat_register.h
+ * @brief Registration API for xlat functions.
+ *
+ * @copyright 2023 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
+ */
+RCSIDH(xlat_register_h, "$Id$")
+
+#include <freeradius-devel/unlang/xlat.h>
+
+xlat_t         *xlat_register_module(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx,
+                                     char const *name, xlat_func_t func, fr_type_t return_type);
+xlat_t         *xlat_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type) CC_HINT(nonnull(2));
+
+int            xlat_func_args_set(xlat_t *xlat, xlat_arg_parser_t const args[]) CC_HINT(nonnull);
+
+int            xlat_func_mono_set(xlat_t *xlat, xlat_arg_parser_t const *arg) CC_HINT(nonnull);
+
+void           xlat_func_flags_set(xlat_t *x, xlat_flags_t const *flags) CC_HINT(nonnull);
+
+/** Set a callback for global instantiation of xlat functions
+ *
+ * @param[in] _xlat            function to set the callback for (as returned by xlat_register).
+ * @param[in] _instantiate     A instantiation callback.
+ * @param[in] _inst_struct     The instance struct to pre-allocate.
+ * @param[in] _detach          A destructor callback.
+ * @param[in] _uctx            to pass to _instantiate and _detach callbacks.
+ */
+#define        xlat_async_instantiate_set(_xlat, _instantiate, _inst_struct, _detach, _uctx) \
+       _xlat_async_instantiate_set(_xlat, _instantiate, #_inst_struct, sizeof(_inst_struct), _detach, _uctx)
+void _xlat_async_instantiate_set(xlat_t const *xlat,
+                                       xlat_instantiate_t instantiate, char const *inst_type, size_t inst_size,
+                                       xlat_detach_t detach,
+                                       void *uctx);
+
+/** Set a callback for thread-specific instantiation of xlat functions
+ *
+ * @param[in] _xlat            function to set the callback for (as returned by xlat_register).
+ * @param[in] _instantiate     A instantiation callback.
+ * @param[in] _inst_struct     The instance struct to pre-allocate.
+ * @param[in] _detach          A destructor callback.
+ * @param[in] _uctx            to pass to _instantiate and _detach callbacks.
+ */
+#define        xlat_async_thread_instantiate_set(_xlat, _instantiate, _inst_struct, _detach, _uctx) \
+       _xlat_async_thread_instantiate_set(_xlat, _instantiate, #_inst_struct, sizeof(_inst_struct), _detach, _uctx)
+void _xlat_async_thread_instantiate_set(xlat_t const *xlat,
+                                       xlat_thread_instantiate_t thread_instantiate,
+                                       char const *thread_inst_type, size_t thread_inst_size,
+                                       xlat_thread_detach_t thread_detach,
+                                       void *uctx);
+
+void           xlat_unregister(char const *name);
+void           xlat_unregister_module(dl_module_inst_t const *inst);
+int            xlat_register_redundant(CONF_SECTION *cs);
+/** @hidecallgraph */
+
+int            xlat_register_init(void);
+void           xlat_register_free(void);
index 7c9d4835e1cc31dfbb2efd1ead639274e6357fd2..7b858532bd1a988ef1071f6be9e7af899ba0e373 100644 (file)
@@ -28,6 +28,7 @@ RCSID("$Id$")
 
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/server/module_rlm.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 /*
  *     The instance data for rlm_always is the list of fake values we are
index b854f8ecb28ffc2bf4a965a2365628fffd7d7305..9caaf926ee01c83fb0637296d46d3ec172b5f6da 100644 (file)
@@ -30,6 +30,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/modpriv.h>
 #include <freeradius-devel/server/dl_module.h>
 #include <freeradius-devel/util/debug.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 #include "rlm_cache.h"
 
index 127b928a599d7729e42f0821937f71b8558948bb..a08e31916fd966550f678a6afaebda12dca14de7 100644 (file)
@@ -29,6 +29,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/password.h>
 #include <freeradius-devel/server/module_rlm.h>
 #include <freeradius-devel/radius/radius.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 typedef struct {
        fr_dict_enum_value_t            *auth_type;
index 8f6bc673266b9a36e32bdf75b0e6d96b0a634473..4a4dc49faa510d06cbd1cae3a2e554163411c5d3 100644 (file)
@@ -34,6 +34,7 @@ RCSID("$Id$")
 #include <freeradius-devel/tls/log.h>
 #include <freeradius-devel/tls/strerror.h>
 #include <freeradius-devel/util/debug.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 #include <freeradius-devel/tls/openssl_user_macros.h>
 #include <openssl/crypto.h>
index ed62e5145d05403cfadcc4f64fe8ec1372c523c2..9a30b6c3bd431347dec38b4f732667237e14012e 100644 (file)
@@ -30,6 +30,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/module_rlm.h>
 #include <freeradius-devel/server/map_proc.h>
 #include <freeradius-devel/util/debug.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 /** Client field
  *
index 65007aed4aa3477b8000f8a173e75719d7787a0a..3841f7b684fae153980bb137efb6ccf11c4a3d5f 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/server/module_rlm.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 #include <ctype.h>
 #include <time.h>
 
index d12254f5fd5da5d990711ccd3cf8cd27420c2aa3..f53b32770b2bd8f9cde48aa05112e94925a2ce15 100644 (file)
@@ -29,6 +29,7 @@ RCSID("$Id$")
 #include <freeradius-devel/util/debug.h>
 #include <freeradius-devel/server/map_proc.h>
 #include <freeradius-devel/util/time.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 typedef struct {
        tmpl_t          *delay;                 //!< How long we delay for.
index 7df7a36b2f75bd75cec46c5481910f0c95f04680..020b6fd29a97b58bc8620aee0a4c769b06c950cf 100644 (file)
@@ -26,6 +26,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/server/module_rlm.h>
 #include <freeradius-devel/util/debug.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 static xlat_arg_parser_t const xlat_dict_attr_by_num_args[] = {
        { .required = true, .single = true, .type = FR_TYPE_UINT32 },
index eb103a6067dbde7346f5b0512e2a75f68b9b31bb..ce4a8f5d9463cec3a3962eee03a458aacf53d6de 100644 (file)
@@ -29,6 +29,7 @@ USES_APPLE_DEPRECATED_API
 
 #include <freeradius-devel/server/module_rlm.h>
 #include <freeradius-devel/util/debug.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 #include <ctype.h>
 
index 7d5671a2423fb86be3b1c32cc3ad0cfc4432f931..6f65e60541d6830804ad56543e1f6e4be67df540 100644 (file)
@@ -32,6 +32,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/tmpl.h>
 #include <freeradius-devel/unlang/interpret.h>
 #include <freeradius-devel/util/debug.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 /*
  *     Define a structure for our module configuration.
index 8eac48013fd9d34c78161c15ddfde684cfce0d56..15d946fd96bb4767918c0f616ec17e837fb4c0a5 100644 (file)
@@ -29,6 +29,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/module_rlm.h>
 #include <freeradius-devel/util/cap.h>
 #include <freeradius-devel/util/debug.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 #include <fcntl.h>
 #include <unistd.h>
index 256d9831d4af425f38b4e1d3bdb74e21deaa9082..646eb42488c672713a337e8555be5dce0265c979 100644 (file)
@@ -25,6 +25,7 @@ RCSID("$Id$")
 
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/server/module_rlm.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 #include <idna.h>
 
index e4755a3e857e7afcd50e6632233527909a18a0e1..3bd6c16aa06e11b20e71834846d57a8ef346789b 100644 (file)
@@ -32,6 +32,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/module_rlm.h>
 #include <freeradius-devel/server/map_proc.h>
 #include <freeradius-devel/util/debug.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 #include <freeradius-devel/json/base.h>
 
 #include <ctype.h>
index 75c91c5d6774f580dc4c04b4fa7244614d0afb73..c99782047fbac91e90132cd39c90456d9ac1d291 100644 (file)
@@ -40,6 +40,8 @@ USES_APPLE_DEPRECATED_API
 #include <freeradius-devel/server/map_proc.h>
 #include <freeradius-devel/server/module_rlm.h>
 
+#include <freeradius-devel/unlang/xlat_register.h>
+
 static CONF_PARSER sasl_mech_dynamic[] = {
        { FR_CONF_OFFSET("mech", FR_TYPE_TMPL | FR_TYPE_NOT_EMPTY, fr_ldap_sasl_t_dynamic_t, mech) },
        { FR_CONF_OFFSET("proxy", FR_TYPE_TMPL, fr_ldap_sasl_t_dynamic_t, proxy) },
index a6ec31073fe087373c026884ca1745edcc7d3e72..24208b08f8fa5d8fe665f0d6ae63c52f777112c6 100644 (file)
@@ -31,6 +31,8 @@ RCSID("$Id$")
 #include <freeradius-devel/util/iovec.h>
 #include <freeradius-devel/util/perm.h>
 
+#include <freeradius-devel/unlang/xlat_register.h>
+
 #ifdef HAVE_FCNTL_H
 #  include <fcntl.h>
 #endif
index d423fbc0c49704db44bf125ba2d2c59fe18bd2cd..ecbbc7f6ee02dbfbb92928454a7867b8e126edeb 100644 (file)
@@ -41,6 +41,8 @@ RCSID("$Id$")
 #include <freeradius-devel/util/misc.h>
 #include <freeradius-devel/util/sha1.h>
 
+#include <freeradius-devel/unlang/xlat_register.h>
+
 #include <sys/wait.h>
 #include <ctype.h>
 
index 3199aaf02c1be9c71a42b81b7bff49a60a559c8e..2b246b0db549c46c25602da61023b8ae61cf3df0 100644 (file)
@@ -29,6 +29,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/server/module_rlm.h>
 #include <freeradius-devel/util/debug.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 #include <freeradius-devel/radius/radius.h>
 
 DIAG_OFF(DIAG_UNKNOWN_PRAGMAS)
index a596b6d78fe43f3db26970dfdd59557714455d90..1c61528b3fafd6053d2525216fd20a53b6142c8d 100644 (file)
@@ -32,6 +32,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/module_rlm.h>
 #include <freeradius-devel/server/modpriv.h>
 #include <freeradius-devel/util/debug.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 #include <freeradius-devel/redis/base.h>
 #include <freeradius-devel/redis/cluster.h>
index 07a64501c1c5376d2dec18d4027f9ee857f8289a..56f15bab14c395f36433be51959b7f6b6fe92eff 100644 (file)
@@ -33,6 +33,7 @@ RCSID("$Id$")
 #include <freeradius-devel/util/debug.h>
 #include <freeradius-devel/util/table.h>
 #include <freeradius-devel/util/uri.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 #include <ctype.h>
 #include "rest.h"
index fac9349083e9f83c2c2209a7975fde3796a1b41a..105627097e4ccc708a363d28111e2c8d72d74019 100644 (file)
@@ -26,6 +26,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/server/module_rlm.h>
 #include <freeradius-devel/soh/base.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 typedef struct {
        bool dhcp;
index c98ddcd61c679ae4b3a5bc8cfd30aa54672846d0..b6a06d82cd34e425a316e1d08e380becee6f8b70 100644 (file)
@@ -37,6 +37,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/pairmove.h>
 #include <freeradius-devel/util/debug.h>
 #include <freeradius-devel/util/table.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 #include <sys/stat.h>
 
index c84667e8bf9380ddd4abe9198fbd5a1b0cf44906..2fcff357dfd2a4b79eb6076c70c3732e6d062e9b 100644 (file)
@@ -30,6 +30,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/module_rlm.h>
 #include <freeradius-devel/server/tmpl.h>
 #include <freeradius-devel/util/debug.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 
 /*
  *     Define a structure for our module configuration.
index 4a93d3d58d91c62558e117ba16a0fbe35669ccdf..1d773b21aecd887a1599e0f8ea276bbcf122abc1 100644 (file)
@@ -29,6 +29,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/server/module_rlm.h>
 #include <freeradius-devel/server/log.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 #include <fcntl.h>
 
 #include "io.h"
index 34164038dbfc6acb93e9cc9efda983fd46e54237..92d8567b382c19826c33dd85b0e83f92b8d8251e 100644 (file)
@@ -26,7 +26,7 @@ RCSID("$Id$")
 
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/server/module_rlm.h>
-
+#include <freeradius-devel/unlang/xlat_register.h>
 #include <freeradius-devel/util/base16.h>
 
 #include <ctype.h>
index ccb82b546b2afd556a43f3d8cf56a474e9f7c419..ff7e60c36b537c02c83ce8015849f364405283bf 100644 (file)
@@ -26,6 +26,7 @@
 RCSID("$Id$")
 
 #include <freeradius-devel/radius/radius.h>
+#include <freeradius-devel/unlang/xlat_register.h>
 #include "rlm_yubikey.h"
 
 #ifdef HAVE_YKCLIENT