All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rlm_expiration.c
Go to the documentation of this file.
1 /*
2  * This program is is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or (at
5  * your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /**
18  * $Id: da81ac13280fc7cf691e28300bcbfb111470e597 $
19  * @file rlm_expiration.c
20  * @brief Lockout user accounts based on control attributes.
21  *
22  * @copyright 2001,2006 The FreeRADIUS server project
23  * @copyright 2004 Kostas Kalevras <kkalev@noc.ntua.gr>
24  */
25 RCSID("$Id: da81ac13280fc7cf691e28300bcbfb111470e597 $")
26 
27 #include <freeradius-devel/radiusd.h>
28 #include <freeradius-devel/modules.h>
29 
30 #include <ctype.h>
31 
32 /*
33  * Check if account has expired, and if user may login now.
34  */
35 static rlm_rcode_t CC_HINT(nonnull) mod_authorize(UNUSED void *instance, REQUEST *request)
36 {
37  VALUE_PAIR *vp, *check_item = NULL;
38 
39  check_item = fr_pair_find_by_num(request->config, 0, PW_EXPIRATION, TAG_ANY);
40  if (check_item != NULL) {
41  char date[50];
42  /*
43  * Has this user's password expired?
44  *
45  * If so, remove ALL reply attributes,
46  * and add our own Reply-Message, saying
47  * why they're being rejected.
48  */
49  if (((time_t) check_item->vp_date) <= request->timestamp.tv_sec) {
50  fr_pair_value_snprint(date, sizeof(date), check_item, 0);
51  REDEBUG("Account expired at '%s'", date);
52 
53  return RLM_MODULE_USERLOCK;
54  } else {
55  if (RDEBUG_ENABLED) {
56  fr_pair_value_snprint(date, sizeof(date), check_item, 0);
57  RDEBUG("Account will expire at '%s'", date);
58  }
59  }
60 
61  /*
62  * Else the account hasn't expired, but it may do so
63  * in the future. Set Session-Timeout.
64  */
65  vp = fr_pair_find_by_num(request->reply->vps, 0, PW_SESSION_TIMEOUT, TAG_ANY);
66  if (!vp) {
67  vp = radius_pair_create(request->reply, &request->reply->vps, PW_SESSION_TIMEOUT, 0);
68  vp->vp_date = (uint32_t) (((time_t) check_item->vp_date) - request->timestamp.tv_sec);
69  } else if (vp->vp_date > ((uint32_t) (((time_t) check_item->vp_date) - request->timestamp.tv_sec))) {
70  vp->vp_date = (uint32_t) (((time_t) check_item->vp_date) - request->timestamp.tv_sec);
71  }
72  } else {
73  return RLM_MODULE_NOOP;
74  }
75 
76  return RLM_MODULE_OK;
77 }
78 
79 /*
80  * Compare the expiration date.
81  */
82 static int expirecmp(UNUSED void *instance, REQUEST *req, UNUSED VALUE_PAIR *request, VALUE_PAIR *check,
83  UNUSED VALUE_PAIR *check_pairs, UNUSED VALUE_PAIR **reply_pairs)
84 {
85  time_t now = 0;
86 
87  now = (req) ? req->timestamp.tv_sec : time(NULL);
88 
89  if (now <= ((time_t) check->vp_date))
90  return 0;
91  return +1;
92 }
93 
94 
95 /*
96  * Do any per-module initialization that is separate to each
97  * configured instance of the module. e.g. set up connections
98  * to external databases, read configuration files, set up
99  * dictionary entries, etc.
100  *
101  * If configuration information is given in the config section
102  * that must be referenced in later calls, store a handle to it
103  * in *instance otherwise put a null pointer there.
104  */
105 static int mod_instantiate(UNUSED CONF_SECTION *conf, void *instance)
106 {
107  /*
108  * Register the expiration comparison operation.
109  */
110  paircompare_register(fr_dict_attr_by_num(NULL, 0, PW_EXPIRATION), NULL, false, expirecmp, instance);
111  return 0;
112 }
113 
114 /*
115  * The module name should be the only globally exported symbol.
116  * That is, everything else should be 'static'.
117  *
118  * If the module needs to temporarily modify it's instantiation
119  * data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
120  * The server will then take care of ensuring that the module
121  * is single-threaded.
122  */
123 extern module_t rlm_expiration;
124 module_t rlm_expiration = {
126  .name = "expiration",
127  .type = RLM_TYPE_THREAD_SAFE,
128  .instantiate = mod_instantiate,
129  .methods = {
132  },
133 };
int paircompare_register(fr_dict_attr_t const *attribute, fr_dict_attr_t const *from, bool first_only, RAD_COMPARE_FUNC func, void *instance)
Register a function as compare function.
Definition: pair.c:395
The module is OK, continue.
Definition: radiusd.h:91
Metadata exported by the module.
Definition: modules.h:134
7 methods index for postauth section.
Definition: modules.h:48
VALUE_PAIR * radius_pair_create(TALLOC_CTX *ctx, VALUE_PAIR **vps, unsigned int attribute, unsigned int vendor)
Create a VALUE_PAIR and add it to a list of VALUE_PAIR s.
Definition: pair.c:704
static rlm_rcode_t mod_authorize(void *instance, REQUEST *request)
Handle authorization requests using Couchbase document data.
#define RLM_TYPE_THREAD_SAFE
Module is threadsafe.
Definition: modules.h:75
#define RDEBUG_ENABLED
True if request debug level 1 messages are enabled.
Definition: log.h:237
#define UNUSED
Definition: libradius.h:134
#define RLM_MODULE_INIT
Definition: modules.h:86
void size_t fr_pair_value_snprint(char *out, size_t outlen, VALUE_PAIR const *vp, char quote)
Print the value of an attribute to a string.
Definition: pair.c:2107
Reject the request (user is locked out).
Definition: radiusd.h:94
static rlm_rcode_t CC_HINT(nonnull)
Stores an attribute, a value and various bits of other data.
Definition: pair.h:112
module_t rlm_expiration
enum rlm_rcodes rlm_rcode_t
Return codes indicating the result of the module call.
static rs_t * conf
Definition: radsniff.c:46
static int expirecmp(UNUSED void *instance, REQUEST *req, UNUSED VALUE_PAIR *request, VALUE_PAIR *check, UNUSED VALUE_PAIR *check_pairs, UNUSED VALUE_PAIR **reply_pairs)
Module succeeded without doing anything.
Definition: radiusd.h:96
uint64_t magic
Used to validate module struct.
Definition: modules.h:135
#define TAG_ANY
Definition: pair.h:191
struct timeval timestamp
When we started processing the request.
Definition: radiusd.h:214
#define REDEBUG(fmt,...)
Definition: log.h:254
VALUE_PAIR * fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag)
Find the pair with the matching attribute.
Definition: pair.c:639
static int mod_instantiate(UNUSED CONF_SECTION *conf, void *instance)
fr_dict_attr_t const * fr_dict_attr_by_num(fr_dict_t *dict, unsigned int vendor, unsigned int attr)
Lookup a fr_dict_attr_t by its vendor and attribute numbers.
Definition: dict.c:3519
1 methods index for authorize section.
Definition: modules.h:42
#define RCSID(id)
Definition: build.h:135
#define RDEBUG(fmt,...)
Definition: log.h:243