From: Alan T. DeKok Date: Wed, 8 Sep 2021 11:59:03 +0000 (-0400) Subject: replace rlm_expiration with a ~10 line unlang policy X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=75e54b3f46a14ef08c7527bec671bbeb8c17150e;p=thirdparty%2Ffreeradius-server.git replace rlm_expiration with a ~10 line unlang policy --- diff --git a/debian/freeradius-config.postinst b/debian/freeradius-config.postinst index 696ce390778..1ab7ab30be1 100644 --- a/debian/freeradius-config.postinst +++ b/debian/freeradius-config.postinst @@ -35,7 +35,7 @@ case "$1" in # Create links for default modules for mod in always attr_filter cache_eap chap client \ delay detail detail.log dhcpv4 digest eap \ - eap_inner echo exec expiration expr files linelog logintime \ + eap_inner echo exec expr files linelog logintime \ mschap ntlm_auth pap pam passwd radutmp \ soh sradutmp stats unix unpack utf8 ; do if test ! -h /etc/freeradius/mods-enabled/$mod && \ diff --git a/doc/antora/modules/howto/pages/modules/expiration/index.adoc b/doc/antora/modules/howto/pages/modules/expiration/index.adoc index b8b85c62125..74ba7400689 100644 --- a/doc/antora/modules/howto/pages/modules/expiration/index.adoc +++ b/doc/antora/modules/howto/pages/modules/expiration/index.adoc @@ -1,15 +1,15 @@ = Expiration -Module to expire user accounts. +Policy to expire user accounts. -This module can be used to expire user accounts. Expired users receive +This policy can be used to expire user accounts. Expired users receive an `Access-Reject` on every authentication attempt. Expiration is based on the Expiration attribute which should be present in the check item list for the user we wish to perform expiration checks. == Topics -Expiration attribute format: +Expiration attribute is of type `date`: You can use `Expiration := 23 Sep 2004` and the user will no longer be able to connect at 00:00 (midnight) on September 23rd, 2004. If you want @@ -20,3 +20,7 @@ calculated to kick the user off when the Expiration time occurs. Example entry (users files): `user1 Expiration := "23 Sep 2004"` + +== Location + +The `expiration` policy is located in `policy.d/time` diff --git a/doc/antora/modules/installation/pages/upgrade.adoc b/doc/antora/modules/installation/pages/upgrade.adoc index 0dc28dd3a13..93ed74ef37d 100644 --- a/doc/antora/modules/installation/pages/upgrade.adoc +++ b/doc/antora/modules/installation/pages/upgrade.adoc @@ -635,6 +635,12 @@ Note that `%{expr:1 * &Attr-Name[*]}` does _not_ mean repeated multiplication. Instead, the sum of the attributes is taken as before, and then the result is multiplied by one. +=== rlm_expiration + +The `expiration` module has been replaced with an `unlang` policy. +The policy is located in `raddb/policy.d/time`. The `Expiration` +attribute should continue to work the same as with v3. + === rlm_mschap The `winbind_*` configuration options are now in a `winbind` diff --git a/doc/antora/modules/raddb/pages/mods-available/expiration.adoc b/doc/antora/modules/raddb/pages/mods-available/expiration.adoc deleted file mode 100644 index 0e1f477c3a8..00000000000 --- a/doc/antora/modules/raddb/pages/mods-available/expiration.adoc +++ /dev/null @@ -1,26 +0,0 @@ - - - - -= Expiration Module - -The `expiration` module manages the `Expiration` attribute. - -It should be included in the *end* of the `recv` section in order to -handle user `Expiration`. It should also be included in the `instantiate` -section in order to register the `Expiration` compare function. - - - -## Configuration Settings - -This module takes no configuration. - - - -== Default Configuration - -``` -expiration { -} -``` diff --git a/raddb/all.mk b/raddb/all.mk index e441c7b8404..450d69f02f1 100644 --- a/raddb/all.mk +++ b/raddb/all.mk @@ -9,7 +9,7 @@ LOCAL_SITES := $(addprefix raddb/sites-enabled/,$(DEFAULT_SITES)) DEFAULT_MODULES := always attr_filter cache_eap chap client \ delay detail detail.log digest eap \ - eap_inner echo escape exec expiration expr files linelog logintime \ + eap_inner echo escape exec expr files linelog logintime \ mschap ntlm_auth pap passwd radutmp \ soh sradutmp stats unix unpack utf8 diff --git a/raddb/mods-available/expiration b/raddb/mods-available/expiration deleted file mode 100644 index 73d5ae9fa83..00000000000 --- a/raddb/mods-available/expiration +++ /dev/null @@ -1,24 +0,0 @@ -# -*- text -*- -# -# -# $Id$ - -####################################################################### -# -# = Expiration Module -# -# The `expiration` module manages the `Expiration` attribute. -# -# It should be included in the *end* of the `recv` section in order to -# handle user `Expiration`. It should also be included in the `instantiate` -# section in order to register the `Expiration` compare function. -# - -# -# ## Configuration Settings -# -# This module takes no configuration. -# -expiration { - -} diff --git a/raddb/policy.d/time b/raddb/policy.d/time index bf3560ab6dc..308d8fa7184 100644 --- a/raddb/policy.d/time +++ b/raddb/policy.d/time @@ -15,3 +15,19 @@ time_elapsed_ms { Tmp-Integer64-1 := "%{expr:(%c*1000) + (%C/1000) - %{Tmp-Integer64-0}}" } } + +# Handles the Expiration attribute +# +expiration { + if (&control.Expiration) { + if (&control.Expiration < "%l") { + disallow + } + + elsif (!&reply.Session-Timeout || (&Session-Timeout > "%{expr:%{Expiration} - %l}")) { + update reply { + &Session-Timeout := "%{expr:%{Expiration} - %l}" + } + } + } +} diff --git a/src/modules/rlm_expiration/README.md b/src/modules/rlm_expiration/README.md deleted file mode 100644 index 75b0175b7b3..00000000000 --- a/src/modules/rlm_expiration/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# rlm_expiration -## Metadata -
-
category
policy
-
- -## Summary -Determines whether a user account has expired, with the expiration time set by another module. diff --git a/src/modules/rlm_expiration/all.mk b/src/modules/rlm_expiration/all.mk deleted file mode 100644 index 6bbd6b9b761..00000000000 --- a/src/modules/rlm_expiration/all.mk +++ /dev/null @@ -1,2 +0,0 @@ -TARGET := rlm_expiration.a -SOURCES := rlm_expiration.c diff --git a/src/modules/rlm_expiration/rlm_expiration.c b/src/modules/rlm_expiration/rlm_expiration.c deleted file mode 100644 index e735db8012f..00000000000 --- a/src/modules/rlm_expiration/rlm_expiration.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * This program is 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 rlm_expiration.c - * @brief Lockout user accounts based on control attributes. - * - * @copyright 2001,2006 The FreeRADIUS server project - * @copyright 2004 Kostas Kalevras (kkalev@noc.ntua.gr) - */ -RCSID("$Id$") - -#include -#include - -#include - -static fr_dict_t const *dict_freeradius; -static fr_dict_t const *dict_radius; - -extern fr_dict_autoload_t rlm_expiration_dict[]; -fr_dict_autoload_t rlm_expiration_dict[] = { - { .out = &dict_freeradius, .proto = "freeradius" }, - { .out = &dict_radius, .proto = "radius" }, - { NULL } -}; - -static fr_dict_attr_t const *attr_expiration; - -static fr_dict_attr_t const *attr_session_timeout; - -extern fr_dict_attr_autoload_t rlm_expiration_dict_attr[]; -fr_dict_attr_autoload_t rlm_expiration_dict_attr[] = { - { .out = &attr_expiration, .name = "Expiration", .type = FR_TYPE_DATE, .dict = &dict_freeradius }, - - { .out = &attr_session_timeout, .name = "Session-Timeout", .type = FR_TYPE_UINT32, .dict = &dict_radius }, - - { NULL } -}; - -/* - * Check if account has expired, and if user may login now. - */ -static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request) -{ - fr_pair_t *vp, *check_item = NULL; - - check_item = fr_pair_find_by_da(&request->control_pairs, attr_expiration, 0); - if (check_item != NULL) { - uint32_t left; - - /* - * Has this user's password expired? - * - * If so, remove ALL reply attributes, - * and add our own Reply-Message, saying - * why they're being rejected. - */ - if (check_item->vp_date <= fr_time_to_unix_time(request->packet->timestamp)) { - REDEBUG("Account expired at '%pV'", &check_item->data); - - RETURN_MODULE_DISALLOW; - } - RDEBUG2("Account will expire at '%pV'", &check_item->data); - - left = fr_unix_time_to_sec(check_item->vp_date - fr_time_to_unix_time(request->packet->timestamp)); - - /* - * Else the account hasn't expired, but it may do so - * in the future. Set Session-Timeout. - */ - switch (pair_update_reply(&vp, attr_session_timeout)) { - case 1: - /* just update... */ - if (vp->vp_uint32 > (uint32_t)left) { - vp->vp_uint32 = (uint32_t)left; - RDEBUG2("&reply.Session-Timeout := %pV", &vp->data); - } - break; - - case 0: /* no pre-existing */ - vp->vp_uint32 = (uint32_t)left; - RDEBUG2("&reply.Session-Timeout := %pV", &vp->data); - break; - - default: /* malloc failure */ - MEM(NULL); - } - } else { - RETURN_MODULE_NOOP; - } - - RETURN_MODULE_OK; -} - -/* - * Compare the expiration date. - */ -static int expirecmp(UNUSED void *instance, request_t *req, UNUSED fr_pair_list_t *request_list, fr_pair_t const *check) -{ - time_t now = 0; - - now = (req) ? fr_time_to_sec(req->packet->timestamp) : time(NULL); - - if (now <= (time_t) fr_unix_time_to_sec(check->vp_date)) return 0; - - return 1; -} - - -/* - * Do any per-module initialization that is separate to each - * configured instance of the module. e.g. set up connections - * to external databases, read configuration files, set up - * dictionary entries, etc. - * - * If configuration information is given in the config section - * that must be referenced in later calls, store a handle to it - * in *instance otherwise put a null pointer there. - */ -static int mod_instantiate(void *instance, UNUSED CONF_SECTION *conf) -{ - /* - * Register the expiration comparison operation. - */ - paircmp_register(attr_expiration, NULL, false, expirecmp, instance); - return 0; -} - -/* - * The module name should be the only globally exported symbol. - * That is, everything else should be 'static'. - * - * If the module needs to temporarily modify it's instantiation - * data, the type should be changed to RLM_TYPE_THREAD_UNSAFE. - * The server will then take care of ensuring that the module - * is single-threaded. - */ -extern module_t rlm_expiration; -module_t rlm_expiration = { - .magic = RLM_MODULE_INIT, - .name = "expiration", - .type = RLM_TYPE_THREAD_SAFE, - .instantiate = mod_instantiate, - .methods = { - [MOD_AUTHORIZE] = mod_authorize, - [MOD_POST_AUTH] = mod_authorize - }, -};