61830459dcb9ee0fe89e5d4ae7f0b799b2c8eb75
[freeradius.git] / src / modules / rlm_always / rlm_always.c
1 /*
2  *   This program 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
5  *   (at 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 /**
19  * $Id$
20  * @file rlm_always.c
21  * @brief Return preconfigured fixed rcodes.
22  *
23  * @copyright 2000,2006  The FreeRADIUS server project
24  */
25 RCSID("$Id$")
26
27 #include <freeradius-devel/radiusd.h>
28 #include <freeradius-devel/modules.h>
29 #include <freeradius-devel/modcall.h>
30
31 /*
32  *      The instance data for rlm_always is the list of fake values we are
33  *      going to return.
34  */
35 typedef struct rlm_always_t {
36         char const      *name;          //!< Name of this instance of the always module.
37         char const      *rcode_str;     //!< The base value.
38         char const      *rcode_old;     //!< Make changing the rcode work with %{poke:} and radmin.
39
40         rlm_rcode_t     rcode;          //!< The integer constant representing rcode_str.
41         uint32_t        simulcount;
42         bool            mpp;
43 } rlm_always_t;
44
45 /*
46  *      A mapping of configuration file names to internal variables.
47  */
48 static const CONF_PARSER module_config[] = {
49         { "rcode", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_always_t, rcode_str), "fail" },
50         { "simulcount", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_always_t, simulcount), "0" },
51         { "mpp", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_always_t, mpp), "no" },
52
53         { NULL, -1, 0, NULL, NULL }             /* end the list */
54 };
55
56 static int mod_instantiate(CONF_SECTION *conf, void *instance)
57 {
58         rlm_always_t *inst = instance;
59
60         inst->name = cf_section_name1(conf);
61         if (!inst->name) inst->name = cf_section_name2(conf);
62         /*
63          *      Convert the rcode string to an int
64          */
65         inst->rcode = fr_str2int(mod_rcode_table, inst->rcode_str, RLM_MODULE_UNKNOWN);
66         if (inst->rcode == RLM_MODULE_UNKNOWN) {
67                 cf_log_err_cs(conf, "rcode value \"%s\" is invalid", inst->rcode_str);
68                 return -1;
69         }
70         inst->rcode_old = NULL; /* Hack - forces the compiler not to optimise away rcode_old */
71
72         return 0;
73 }
74
75 /** Reparse the rcode if it changed
76  *
77  * @note Look ma, no locks...
78  *
79  * @param inst Module instance.
80  */
81 static void reparse_rcode(rlm_always_t *inst)
82 {
83         rlm_rcode_t rcode;
84
85         rcode = fr_str2int(mod_rcode_table, inst->rcode_str, RLM_MODULE_UNKNOWN);
86         if (rcode == RLM_MODULE_UNKNOWN) {
87                 WARN("rlm_always (%s): Ignoring rcode change.  rcode value \"%s\" is invalid ", inst->name,
88                      inst->rcode_str);
89                 return;
90         }
91
92         inst->rcode = rcode;
93         inst->rcode_old = inst->rcode_str;
94 }
95
96 /*
97  *      Just return the rcode ... this function is autz, auth, acct, and
98  *      preacct!
99  */
100 static rlm_rcode_t CC_HINT(nonnull) mod_always_return(void *instance, UNUSED REQUEST *request)
101 {
102         rlm_always_t *inst = instance;
103
104         if (inst->rcode_old != inst->rcode_str) reparse_rcode(inst);
105
106         return inst->rcode;
107 }
108
109 #ifdef WITH_SESSION_MGMT
110 /*
111  *      checksimul fakes some other variables besides the rcode...
112  */
113 static rlm_rcode_t CC_HINT(nonnull) mod_checksimul(void *instance, REQUEST *request)
114 {
115         struct rlm_always_t *inst = instance;
116
117         if (inst->rcode_old != inst->rcode_str) reparse_rcode(inst);
118
119         request->simul_count = inst->simulcount;
120
121         if (inst->mpp) request->simul_mpp = 2;
122
123         return inst->rcode;
124 }
125 #endif
126
127 extern module_t rlm_always;
128 module_t rlm_always = {
129         .magic          = RLM_MODULE_INIT,
130         .name           = "always",
131         .type           = RLM_TYPE_HUP_SAFE,
132         .inst_size      = sizeof(rlm_always_t),
133         .config         = module_config,
134         .instantiate    = mod_instantiate,
135         .methods = {
136                 [MOD_AUTHENTICATE]      = mod_always_return,
137                 [MOD_AUTHORIZE]         = mod_always_return,
138                 [MOD_PREACCT]           = mod_always_return,
139                 [MOD_ACCOUNTING]        = mod_always_return,
140 #ifdef WITH_SESSION_MGMT
141                 [MOD_SESSION]           = mod_checksimul,
142 #endif
143                 [MOD_PRE_PROXY]         = mod_always_return,
144                 [MOD_POST_PROXY]        = mod_always_return,
145                 [MOD_POST_AUTH]         = mod_always_return,
146 #ifdef WITH_COA
147                 [MOD_RECV_COA]          = mod_always_return,
148                 [MOD_SEND_COA]          = mod_always_return
149 #endif
150         },
151 };