Require that the modules call talloc for their instance handle.
[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 #include <freeradius-devel/ident.h>
26 RCSID("$Id$")
27
28 #include <freeradius-devel/radiusd.h>
29 #include <freeradius-devel/modules.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            *rcode_str;
37         rlm_rcode_t     rcode;
38         int             simulcount;
39         int             mpp;
40 } rlm_always_t;
41
42 /*
43  *      A mapping of configuration file names to internal variables.
44  */
45 static const CONF_PARSER module_config[] = {
46   { "rcode",      PW_TYPE_STRING_PTR, offsetof(rlm_always_t,rcode_str),
47     NULL, "fail" },
48   { "simulcount", PW_TYPE_INTEGER,    offsetof(rlm_always_t,simulcount),
49     NULL, "0" },
50   { "mpp",        PW_TYPE_BOOLEAN,    offsetof(rlm_always_t,mpp),
51     NULL, "no" },
52
53   { NULL, -1, 0, NULL, NULL }           /* end the list */
54 };
55
56 static rlm_rcode_t str2rcode(const char *s)
57 {
58         if(!strcasecmp(s, "reject"))
59                 return RLM_MODULE_REJECT;
60         else if(!strcasecmp(s, "fail"))
61                 return RLM_MODULE_FAIL;
62         else if(!strcasecmp(s, "ok"))
63                 return RLM_MODULE_OK;
64         else if(!strcasecmp(s, "handled"))
65                 return RLM_MODULE_HANDLED;
66         else if(!strcasecmp(s, "invalid"))
67                 return RLM_MODULE_INVALID;
68         else if(!strcasecmp(s, "userlock"))
69                 return RLM_MODULE_USERLOCK;
70         else if(!strcasecmp(s, "notfound"))
71                 return RLM_MODULE_NOTFOUND;
72         else if(!strcasecmp(s, "noop"))
73                 return RLM_MODULE_NOOP;
74         else if(!strcasecmp(s, "updated"))
75                 return RLM_MODULE_UPDATED;
76         else {
77                 radlog(L_ERR,
78                         "rlm_always: Unknown module rcode '%s'.\n", s);
79                 return RLM_MODULE_UNKNOWN;
80         }
81 }
82
83 static int always_instantiate(CONF_SECTION *conf, void **instance)
84 {
85         rlm_always_t *inst;
86
87         /*
88          *      Set up a storage area for instance data
89          */
90         *instance = inst = talloc_zero(conf, rlm_always_t);
91         if (!inst) {
92                 return -1;
93         }
94
95         /*
96          *      If the configuration parameters can't be parsed, then
97          *      fail.
98          */
99         if (cf_section_parse(conf, inst, module_config) < 0) {
100                 return -1;
101         }
102
103         /*
104          *      Convert the rcode string to an int, and get rid of it
105          */
106         inst->rcode = str2rcode(inst->rcode_str);
107         if (inst->rcode == RLM_MODULE_UNKNOWN) {
108                 return -1;
109         }
110
111         return 0;
112 }
113
114 /*
115  *      Just return the rcode ... this function is autz, auth, acct, and
116  *      preacct!
117  */
118 static rlm_rcode_t always_return(void *instance, UNUSED REQUEST *request)
119 {
120         return ((struct rlm_always_t *)instance)->rcode;
121 }
122
123 #ifdef WITH_SESSION_MGMT
124 /*
125  *      checksimul fakes some other variables besides the rcode...
126  */
127 static rlm_rcode_t always_checksimul(void *instance, REQUEST *request)
128 {
129         struct rlm_always_t *inst = instance;
130
131         request->simul_count = inst->simulcount;
132
133         if (inst->mpp)
134                 request->simul_mpp = 2;
135
136         return inst->rcode;
137 }
138 #endif
139
140 module_t rlm_always = {
141         RLM_MODULE_INIT,
142         "always",
143         RLM_TYPE_CHECK_CONFIG_SAFE,     /* type */
144         always_instantiate,             /* instantiation */
145         NULL,                           /* detach */
146         {
147                 always_return,          /* authentication */
148                 always_return,          /* authorization */
149                 always_return,          /* preaccounting */
150                 always_return,          /* accounting */
151 #ifdef WITH_SESSION_MGMT
152                 always_checksimul,      /* checksimul */
153 #else
154                 NULL,
155 #endif
156                 always_return,          /* pre-proxy */
157                 always_return,          /* post-proxy */
158                 always_return           /* post-auth */
159 #ifdef WITH_COA
160                 ,
161                 always_return,          /* recv-coa */
162                 always_return           /* send-coa */
163 #endif
164         },
165 };