From: Nick Porter Date: Fri, 9 May 2025 17:20:45 +0000 (+0100) Subject: Add record_query_number to rlm_sql X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d64e2f10752dafbad94ec61dd61c27b0dc79a3c5;p=thirdparty%2Ffreeradius-server.git Add record_query_number to rlm_sql In order to optionally record which query from a list of resulted in the data being updated. --- diff --git a/raddb/mods-available/sql b/raddb/mods-available/sql index 68ac4da753..38a8f76b64 100644 --- a/raddb/mods-available/sql +++ b/raddb/mods-available/sql @@ -403,6 +403,19 @@ sql { # function. # auto_escape = no + # When the SQL module is called in accounting and post-auth one or + # more queries may be run, until at least one record is updated. + # + # It can be helpful to know which query was run. E.g. the default + # queries for Interim-Update handling, start with an UPDATE and + # if that does not update any records, an INSERT is run. Knowing + # which query updated data indicates the state of the data prior + # to the update. + # + # Setting this to 'yes', will cause `&control:SQL-Query-Number` to be + # populated with the number of the query which updated data. +# record_query_number = no + # Read database-specific queries $INCLUDE ${modconfdir}/${.:name}/main/${dialect}/queries.conf } diff --git a/share/dictionary.freeradius.internal b/share/dictionary.freeradius.internal index e8cde0c231..71611c6f66 100644 --- a/share/dictionary.freeradius.internal +++ b/share/dictionary.freeradius.internal @@ -109,6 +109,7 @@ ATTRIBUTE Module-Failure-Message 1076 string # X99-Fast 1077 integer ATTRIBUTE Rewrite-Rule 1078 string # SQL-Group is now dynamically created +ATTRIBUTE SQL-Query-Number 1079 integer ATTRIBUTE Response-Packet-Type 1080 integer virtual ATTRIBUTE Digest-HA1 1081 string ATTRIBUTE MS-CHAP-Use-NTLM-Auth 1082 integer diff --git a/src/modules/rlm_sql/rlm_sql.c b/src/modules/rlm_sql/rlm_sql.c index 9d21243683..762654feb2 100644 --- a/src/modules/rlm_sql/rlm_sql.c +++ b/src/modules/rlm_sql/rlm_sql.c @@ -111,6 +111,7 @@ static const CONF_PARSER module_config[] = { { "safe-characters", FR_CONF_OFFSET(PW_TYPE_STRING | PW_TYPE_DEPRECATED, rlm_sql_config_t, allowed_chars), NULL }, { "safe_characters", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_sql_config_t, allowed_chars), "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /" }, { "auto_escape", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_sql_config_t, driver_specific_escape), "no" }, + { "record_query_number", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_sql_config_t, record_query_number), "no" }, /* * This only works for a few drivers. @@ -1396,6 +1397,7 @@ static int acct_redundant(rlm_sql_t *inst, REQUEST *request, sql_acct_section_t rlm_sql_handle_t *handle = NULL; int sql_ret; int numaffected = 0; + int query_number = 1; CONF_ITEM *item; CONF_PAIR *pair; @@ -1523,7 +1525,14 @@ static int acct_redundant(rlm_sql_t *inst, REQUEST *request, sql_acct_section_t (inst->module->sql_finish_query)(handle, inst->config); RDEBUG("%i record(s) updated", numaffected); - if (numaffected > 0) break; /* A query succeeded, we're done! */ + if (numaffected > 0) { + if (inst->config->record_query_number) { + VALUE_PAIR *vp = fr_pair_find_by_num(request->config, PW_SQL_QUERY_NUMBER, 0, 0); + if (!vp) vp = radius_pair_create(request, &request->config, PW_SQL_QUERY_NUMBER, 0); + vp->vp_integer = query_number; + } + break; /* A query succeeded, we're done! */ + } next: /* * We assume all entries with the same name form a redundant @@ -1552,6 +1561,7 @@ static int acct_redundant(rlm_sql_t *inst, REQUEST *request, sql_acct_section_t goto finish; } + query_number ++; RDEBUG("Trying next query..."); } diff --git a/src/modules/rlm_sql/rlm_sql.h b/src/modules/rlm_sql/rlm_sql.h index 78ab86b041..d5237a1605 100644 --- a/src/modules/rlm_sql/rlm_sql.h +++ b/src/modules/rlm_sql/rlm_sql.h @@ -125,6 +125,9 @@ typedef struct sql_config { //!< a fake stop packet, to terminate any //!< stale sessions. + bool record_query_number; //!< Whether we should populate SQL-Query-Number + ///< when an "acct_redundant" query succeeds + char const *allowed_chars; //!< Chars which done need escaping.. bool driver_specific_escape; //!< Use the driver specific SQL escape method uint32_t query_timeout; //!< How long to allow queries to run for.