]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add optional pointer to original tmpl_t when expanding module environment
authorNick Porter <nick@portercomputing.co.uk>
Wed, 15 Mar 2023 13:35:15 +0000 (13:35 +0000)
committerNick Porter <nick@portercomputing.co.uk>
Mon, 20 Mar 2023 09:58:47 +0000 (09:58 +0000)
Allows the module receiving value boxes from expanded tmpls to know
where the data came from e.g. was it static data or an expanded
attribute.

src/lib/server/module.h
src/lib/unlang/module.c

index bfe32706c9181506fc486a0c4a515b08c8d67206..48abe84a77d78c7f783e2957951f7cb07de41258 100644 (file)
@@ -267,6 +267,7 @@ struct module_env_s {
                        mod_env_dest_t  type;           //!< Type of structure boxes will be written to.
                        size_t          size;           //!< Size of structure boxes will be written to.
                        char const      *type_name;     //!< Name of structure type boxes will be written to.
+                       size_t          tmpl_offset;    //!< Where to write pointer to tmpl in the output structure.  Optional.
                } pair;
 
                struct {
@@ -355,6 +356,23 @@ _Generic((((_s *)NULL)->_f), \
                  .size = FR_MODULE_ENV_DST_SIZE(_struct, _field), \
                  .type_name = FR_MODULE_ENV_DST_TYPE_NAME(_struct, _field) }
 
+/** Version of the above which sets optional field for pointer to tmpl
+ */
+#define FR_MODULE_ENV_TMPL_OFFSET(_name, _cast_type, _struct, _field, _tmpl_field, _dflt, _dflt_quote, _required, _concat) \
+       .name = _name, \
+       .type = _cast_type, \
+       .offset = offsetof(_struct, _field), \
+       .dflt = _dflt, \
+       .dflt_quote = _dflt_quote, \
+       .pair = { .required = _required, \
+                 .concat = FR_MODULE_ENV_CONCAT(_concat, _cast_type), \
+                 .single = FR_MODULE_ENV_SINGLE(_struct, _field, _concat), \
+                 .multi = FR_MODULE_ENV_MULTI(_struct, _field), \
+                 .type = FR_MODULE_ENV_DST_TYPE(_struct, _field), \
+                 .size = FR_MODULE_ENV_DST_SIZE(_struct, _field), \
+                 .type_name = FR_MODULE_ENV_DST_TYPE_NAME(_struct, _field), \
+                 .tmpl_offset = offsetof(_struct, _tmpl_field) }
+
 /** A list of modules
  *
  * This allows modules to be instantiated and freed in phases,
index de28e3e6a7e8e7687de14135dd7d2ef4d62d75b0..05c83653f5b14335eb1c7fb0f1a0f06b3f3a2813 100644 (file)
@@ -873,7 +873,8 @@ static void unlang_module_event_retry_handler(UNUSED fr_event_list_t *el, fr_tim
 
 /** Parse the result of module_env tmpl expansion
  */
-static inline CC_HINT(always_inline) int module_env_value_parse(request_t *request, void * out, unlang_frame_state_module_t *state) {
+static inline CC_HINT(always_inline) int module_env_value_parse(request_t *request, void *out, void **tmpl_out,
+                                                               unlang_frame_state_module_t *state) {
        fr_value_box_t                  *vb;
        module_env_parsed_t const       *env = state->last_expanded;
 
@@ -916,6 +917,8 @@ static inline CC_HINT(always_inline) int module_env_value_parse(request_t *reque
                }
        }
 
+       if (tmpl_out) *tmpl_out = env->tmpl;
+
        return 0;
 }
 
@@ -955,7 +958,7 @@ static unlang_action_t unlang_module(rlm_rcode_t *p_result, request_t *request,
        }
 
        if (mc->method_env) {
-               void                            *out, **array;
+               void                            *out, **array, *tmpl_out = NULL;
                module_env_parsed_t const       *env;
                TALLOC_CTX                      *ctx;
 
@@ -993,7 +996,9 @@ static unlang_action_t unlang_module(rlm_rcode_t *p_result, request_t *request,
                                out = ((uint8_t *)array) + env->rule->pair.size * env->multi_index;
                        }
 
-                       if (module_env_value_parse(request, out, state) < 0) {
+                       if (env->rule->pair.tmpl_offset) tmpl_out = ((uint8_t *)state->env_data) + env->rule->pair.tmpl_offset;
+
+                       if (module_env_value_parse(request, out, tmpl_out, state) < 0) {
                                ua = UNLANG_ACTION_FAIL;
                                goto fail;
                        }