]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Allow for differing arguments to sql escape function
authorNick Porter <nick@portercomputing.co.uk>
Mon, 6 May 2024 14:29:51 +0000 (15:29 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 7 Jun 2024 02:26:58 +0000 (22:26 -0400)
Drivers using the builtin escape function just need the SQL instance for
access to the allowed chars.
Those using connection pools will use a pool connection.
Those using trunks will use a per thread fr_connection_t - no actual data
is transferred, but the driver escaping functions refer to server side
data such as character sets.

src/modules/rlm_sql/rlm_sql.c
src/modules/rlm_sql/rlm_sql.h
src/modules/rlm_sqlippool/rlm_sqlippool.c

index cbe7314d7b6f26a26baf3d714a24f44f4378c424..58ff3f5f0d496c305609f1c481ef9e2fe0e601c4 100644 (file)
@@ -321,18 +321,25 @@ static int CC_HINT(nonnull(2,3)) sql_xlat_escape(request_t *request, fr_value_bo
        fr_sbuff_uctx_talloc_t          sbuff_ctx;
 
        size_t                          len;
-       rlm_sql_handle_t                *handle;
+       void                            *arg;
        rlm_sql_escape_uctx_t           *ctx = uctx;
        rlm_sql_t const                 *inst = talloc_get_type_abort_const(ctx->sql, rlm_sql_t);
        fr_value_box_entry_t            entry;
+       rlm_sql_thread_t                *thread = talloc_get_type_abort(module_thread(inst->mi)->data, rlm_sql_thread_t);
 
        /*
         *      If it's already safe, don't do anything.
         */
        if (fr_value_box_is_safe_for(vb, inst->driver)) return 0;
 
-       handle = ctx->handle ? ctx->handle : fr_pool_connection_get(inst->pool, request);
-       if (!handle) {
+       if (inst->sql_escape_arg) {
+               arg = inst->sql_escape_arg;
+       } else if (thread->sql_escape_arg) {
+               arg = thread->sql_escape_arg;
+       } else {
+               arg = ctx->handle ? ctx->handle : fr_pool_connection_get(inst->pool, request);
+       }
+       if (!arg) {
        error:
                fr_value_box_clear_value(vb);
                return -1;
@@ -351,7 +358,7 @@ static int CC_HINT(nonnull(2,3)) sql_xlat_escape(request_t *request, fr_value_bo
                return -1;
        }
 
-       len = inst->sql_escape_func(request, fr_sbuff_buff(&sbuff), vb->vb_length * 3 + 1, vb->vb_strvalue, handle);
+       len = inst->sql_escape_func(request, fr_sbuff_buff(&sbuff), vb->vb_length * 3 + 1, vb->vb_strvalue, arg);
 
        /*
         *      fr_value_box_strdup_shallow resets the dlist entries - take a copy
@@ -370,7 +377,7 @@ static int CC_HINT(nonnull(2,3)) sql_xlat_escape(request_t *request, fr_value_bo
        fr_value_box_mark_safe_for(vb, inst->driver);
        vb->entry = entry;
 
-       if (!ctx->handle) fr_pool_connection_release(inst->pool, request, handle);
+       if (!inst->sql_escape_arg && !thread->sql_escape_arg && !ctx->handle) fr_pool_connection_release(inst->pool, request, arg);
        return 0;
 }
 
@@ -733,8 +740,7 @@ finish:
  */
 static size_t sql_escape_func(UNUSED request_t *request, char *out, size_t outlen, char const *in, void *arg)
 {
-       rlm_sql_handle_t        *handle = arg;
-       rlm_sql_t const         *inst = talloc_get_type_abort_const(handle->inst, rlm_sql_t);
+       rlm_sql_t const         *inst = talloc_get_type_abort_const(arg, rlm_sql_t);
        size_t                  len = 0;
 
        while (in[0]) {
@@ -1082,7 +1088,7 @@ static int check_map_process(request_t *request, map_list_t *check_map, map_list
 
 static int sql_autz_ctx_free(sql_autz_ctx_t *to_free)
 {
-       (void) request_data_get(to_free->request, (void *)sql_escape_uctx_alloc, 0);
+       if (!to_free->inst->sql_escape_arg) (void) request_data_get(to_free->request, (void *)sql_escape_uctx_alloc, 0);
        if (to_free->handle) fr_pool_connection_release(to_free->inst->pool, to_free->request, to_free->handle);
        map_list_talloc_free(&to_free->check_tmp);
        map_list_talloc_free(&to_free->reply_tmp);
@@ -1464,7 +1470,8 @@ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, mod
        autz_ctx->handle = fr_pool_connection_get(inst->pool, request);
        if (!autz_ctx->handle) RETURN_MODULE_FAIL;
 
-       request_data_add(request, (void *)sql_escape_uctx_alloc, 0, autz_ctx->handle, false, false, false);
+       if (!inst->sql_escape_arg && !thread->sql_escape_arg) request_data_add(request, (void *)sql_escape_uctx_alloc, 0,
+                                                                              autz_ctx->handle, false, false, false);
 
        if (unlang_function_push(request, NULL, mod_authorize_resume, NULL, 0,
                                 UNLANG_SUB_FRAME, autz_ctx) < 0) {
@@ -1504,7 +1511,7 @@ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, mod
  */
 static int sql_redundant_ctx_free(sql_redundant_ctx_t *to_free)
 {
-       (void) request_data_get(to_free->request, (void *)sql_escape_uctx_alloc, 0);
+       if (!to_free->inst->sql_escape_arg) (void) request_data_get(to_free->request, (void *)sql_escape_uctx_alloc, 0);
        if (to_free->handle) fr_pool_connection_release(to_free->inst->pool, to_free->request, to_free->handle);
        sql_unset_user(to_free->inst, to_free->request);
 
@@ -1638,7 +1645,8 @@ static unlang_action_t CC_HINT(nonnull) mod_sql_redundant(rlm_rcode_t *p_result,
        redundant_ctx->handle = fr_pool_connection_get(inst->pool, request);
        if (!redundant_ctx->handle) RETURN_MODULE_FAIL;
 
-       request_data_add(request, (void *)sql_escape_uctx_alloc, 0, redundant_ctx->handle, false, false, false);
+       if (!inst->sql_escape_arg && !thread->sql_escape_arg) request_data_add(request, (void *)sql_escape_uctx_alloc, 0,
+                                                                              redundant_ctx->handle, false, false, false);
 
        sql_set_user(inst, request, &call_env->user);
 
@@ -1868,9 +1876,12 @@ static int mod_instantiate(module_inst_ctx_t const *mctx)
         *      Either use the module specific escape function
         *      or our default one.
         */
-       inst->sql_escape_func = inst->driver->sql_escape_func ?
-                               inst->driver->sql_escape_func :
-                               sql_escape_func;
+       if (inst->driver->sql_escape_func) {
+               inst->sql_escape_func = inst->driver->sql_escape_func;
+       } else {
+               inst->sql_escape_func = sql_escape_func;
+               inst->sql_escape_arg = inst;
+       }
        inst->box_escape_func = sql_box_escape;
 
        inst->ef = module_rlm_exfile_init(inst, conf, 256, fr_time_delta_from_sec(30), true, NULL, NULL);
index fb3082d65a18ec5421cca30878bc9b08668e78f3..a3a2a52ac6dfb1856b87dafd320423938ed234f6 100644 (file)
@@ -107,6 +107,7 @@ typedef struct sql_inst rlm_sql_t;
 typedef struct {
        fr_trunk_t              *trunk;                         //!< Trunk connection for this thread.
        rlm_sql_t const         *inst;                          //!< Module instance data.
+       void                    *sql_escape_arg;                //!< Thread specific argument to be passed to escape function.
 } rlm_sql_thread_t;
 
 typedef struct {
@@ -225,6 +226,7 @@ struct sql_inst {
 
        xlat_escape_legacy_t    sql_escape_func;
        fr_value_box_escape_t   box_escape_func;
+       void                    *sql_escape_arg;        //!< Instance specific argument to be passed to escape function.
        unlang_function_t       query;
        unlang_function_t       select;
        unlang_function_t       fetch_row;
index 82c4df34ee7de247252adecd99cd5fd167a88f60..8d6a833114b9396f768c3cd30ecc4d28461b9eb9 100644 (file)
@@ -279,7 +279,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx)
  */
 static int sqlippool_alloc_ctx_free(ippool_alloc_ctx_t *to_free)
 {
-       (void) request_data_get(to_free->request, (void *)sql_escape_uctx_alloc, 0);
+       if (!to_free->sql->sql_escape_arg) (void) request_data_get(to_free->request, (void *)sql_escape_uctx_alloc, 0);
        if (to_free->handle) fr_pool_connection_release(to_free->sql->pool, to_free->request, to_free->handle);
        return 0;
 }
@@ -505,7 +505,8 @@ static unlang_action_t CC_HINT(nonnull) mod_alloc(rlm_rcode_t *p_result, module_
        }
 
        RESERVE_CONNECTION(handle, inst->sql->pool, request);
-       request_data_add(request, (void *)sql_escape_uctx_alloc, 0, handle, false, false, false);
+       if (!sql->sql_escape_arg && !thread->sql_escape_arg) request_data_add(request, (void *)sql_escape_uctx_alloc, 0,
+                                                                             handle, false, false, false);
 
        DO_PART(begin, thread->trunk);