]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Use a config option to extend reply attribute value
authorNick Porter <nick@portercomputing.co.uk>
Thu, 15 Feb 2024 11:21:33 +0000 (11:21 +0000)
committerNick Porter <nick@portercomputing.co.uk>
Thu, 15 Feb 2024 18:32:01 +0000 (18:32 +0000)
Rather than doing hidden magic on a specific attribute.  Allows the same
principle to be used for protocols other than RADIUS.

raddb/mods-available/sqlcounter
src/modules/rlm_sqlcounter/rlm_sqlcounter.c

index 68ca154e6bde5a983c18c57a186f814430f6a0ee..752b36d4cf80b8039bc61a3c2160325447ca303e 100644 (file)
 #               reject
 #      }
 #
+#  check_name:: Name of the attribute containing the limit to compare the counter to.
+#
 #  reply_name:: Name of the attribute to populate with the remaining session time.
 #  e.g. `&reply.Session-Timeout`.  If the attribute already exists and contains
 #  a lower value, then it will not be updated.
 #
 #  reply_message_name:: Name of the attribute into which a message should be placed
 #  if the limit has been exeeded for the counter.
+#
+#  auto_extend:: If set to `yes` and the remaining session time goes past the time for
+#  the next counter reset, the value in the `reply_name` attribute will be set to
+#  the time to the next reset plus the value of the `check_name` attribute.
+#  This is most useful if the limit is a time based one, and, for example,
+#  `Session-Timeout` is the `reply_name` attribute.  If there is sufficient allocation
+#  left for the session to get to the next counter period, the user will not have
+#  to re-authenticate before they have used their allocation for the next counter period.
 
 #
 #  ## Configuration Settings
@@ -118,6 +128,7 @@ sqlcounter dailycounter {
        counter_name = &control.Daily-Session-Time
        check_name = &control.Max-Daily-Session
        reply_name = &reply.Session-Timeout
+       auto_extend = yes
        key = "%{&Stripped-User-Name || &User-Name}"
        reply_message_name = &Reply-Message
 
@@ -136,6 +147,7 @@ sqlcounter monthlycounter {
        counter_name = &Monthly-Session-Time
        check_name = &control.Max-Monthly-Session
        reply_name = &reply.Session-Timeout
+       auto_extend = yes
        key = &User-Name
 
        reset = monthly
index d01b63cae89b0b13bdf32bb366c6e9205460ee86..f87881a282f70021f4aa6563b59d629c80fce8e1 100644 (file)
@@ -70,6 +70,8 @@ typedef struct {
        char const      *sql_name;      //!< Instance of SQL module to use, usually just 'sql'.
        char const      *query;         //!< SQL query to retrieve current session time.
        char const      *reset;         //!< Daily, weekly, monthly, never or user defined.
+       bool            auto_extend;    //!< If the remaining allowance is sufficient to reach the next
+                                       ///< period allow for that in setting the reply attribute.
 
        fr_time_t       reset_time;
        fr_time_t       last_reset;
@@ -81,6 +83,7 @@ static const conf_parser_t module_config[] = {
 
        { FR_CONF_OFFSET_FLAGS("query", CONF_FLAG_XLAT | CONF_FLAG_REQUIRED, rlm_sqlcounter_t, query) },
        { FR_CONF_OFFSET_FLAGS("reset", CONF_FLAG_REQUIRED, rlm_sqlcounter_t, reset) },
+       { FR_CONF_OFFSET_FLAGS("auto_extend", CONF_FLAG_OK_MISSING, rlm_sqlcounter_t, auto_extend) },
 
        { FR_CONF_OFFSET_FLAGS("key", CONF_FLAG_NOT_EMPTY, rlm_sqlcounter_t, key), .dflt = "%{%{Stripped-User-Name} || %{User-Name}}", .quote = T_DOUBLE_QUOTED_STRING },
 
@@ -103,20 +106,10 @@ typedef struct {
 } sqlcounter_call_env_t;
 
 static fr_dict_t const *dict_freeradius;
-static fr_dict_t const *dict_radius;
 
 extern fr_dict_autoload_t rlm_sqlcounter_dict[];
 fr_dict_autoload_t rlm_sqlcounter_dict[] = {
        { .out = &dict_freeradius, .proto = "freeradius" },
-       { .out = &dict_radius, .proto = "radius" },
-       { NULL }
-};
-
-static fr_dict_attr_t const *attr_session_timeout;
-
-extern fr_dict_attr_autoload_t rlm_sqlcounter_dict_attr[];
-fr_dict_attr_autoload_t rlm_sqlcounter_dict_attr[] = {
-       { .out = &attr_session_timeout, .name = "Session-Timeout", .type = FR_TYPE_UINT32, .dict = &dict_radius },
        { NULL }
 };
 
@@ -317,9 +310,9 @@ static unlang_action_t mod_authorize_resume(rlm_rcode_t *p_result, UNUSED int *p
                /*
                 *      If we are near a reset then add the next
                 *      limit, so that the user will not need to login
-                *      again.  Do this only for Session-Timeout.
+                *      again.  Do this only if auto_extend is set.
                 */
-               if ((tmpl_attr_tail_da(env->reply_attr) == attr_session_timeout) &&
+               if (inst->auto_extend &&
                    fr_time_gt(inst->reset_time, fr_time_wrap(0)) &&
                    ((int64_t)res >= fr_time_delta_to_sec(fr_time_sub(inst->reset_time, request->packet->timestamp)))) {
                        fr_time_delta_t to_reset = fr_time_sub(inst->reset_time, request->packet->timestamp);