5e688f63b63d3b5883576f6efd54274f4156134f
[freeradius.git] / src / modules / rlm_always / rlm_always.c
1 /*
2  * rlm_always.c
3  *
4  *   This program is free software; you can redistribute it and/or modify
5  *   it under the terms of the GNU General Public License as published by
6  *   the Free Software Foundation; either version 2 of the License, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *   GNU General Public License for more details.
13  *
14  *   You should have received a copy of the GNU General Public License
15  *   along with this program; if not, write to the Free Software
16  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  *
18  * Copyright 2000,2006  The FreeRADIUS server project
19  */
20
21 #include <freeradius-devel/ident.h>
22 RCSID("$Id$")
23
24 #include <freeradius-devel/radiusd.h>
25 #include <freeradius-devel/modules.h>
26
27 /*
28  *      The instance data for rlm_always is the list of fake values we are
29  *      going to return.
30  */
31 typedef struct rlm_always_t {
32         char    *rcode_str;
33         int     rcode;
34         int     simulcount;
35         int     mpp;
36 } rlm_always_t;
37
38 /*
39  *      A mapping of configuration file names to internal variables.
40  *
41  *      Note that the string is dynamically allocated, so it MUST
42  *      be freed.  When the configuration file parse re-reads the string,
43  *      it free's the old one, and strdup's the new one, placing the pointer
44  *      to the strdup'd string into 'config.string'.  This gets around
45  *      buffer over-flows.
46  */
47 static const CONF_PARSER module_config[] = {
48   { "rcode",      PW_TYPE_STRING_PTR, offsetof(rlm_always_t,rcode_str),
49     NULL, "fail" },
50   { "simulcount", PW_TYPE_INTEGER,    offsetof(rlm_always_t,simulcount),
51     NULL, "0" },
52   { "mpp",        PW_TYPE_BOOLEAN,    offsetof(rlm_always_t,mpp),
53     NULL, "no" },
54
55   { NULL, -1, 0, NULL, NULL }           /* end the list */
56 };
57
58 static int str2rcode(const char *s)
59 {
60         if(!strcasecmp(s, "reject"))
61                 return RLM_MODULE_REJECT;
62         else if(!strcasecmp(s, "fail"))
63                 return RLM_MODULE_FAIL;
64         else if(!strcasecmp(s, "ok"))
65                 return RLM_MODULE_OK;
66         else if(!strcasecmp(s, "handled"))
67                 return RLM_MODULE_HANDLED;
68         else if(!strcasecmp(s, "invalid"))
69                 return RLM_MODULE_INVALID;
70         else if(!strcasecmp(s, "userlock"))
71                 return RLM_MODULE_USERLOCK;
72         else if(!strcasecmp(s, "notfound"))
73                 return RLM_MODULE_NOTFOUND;
74         else if(!strcasecmp(s, "noop"))
75                 return RLM_MODULE_NOOP;
76         else if(!strcasecmp(s, "updated"))
77                 return RLM_MODULE_UPDATED;
78         else {
79                 radlog(L_ERR|L_CONS,
80                         "rlm_always: Unknown module rcode '%s'.\n", s);
81                 return -1;
82         }
83 }
84
85 static int always_instantiate(CONF_SECTION *conf, void **instance)
86 {
87         rlm_always_t *data;
88
89         /*
90          *      Set up a storage area for instance data
91          */
92         data = rad_malloc(sizeof(*data));
93         if (!data) {
94                 return -1;
95         }
96         memset(data, 0, sizeof(*data));
97
98         /*
99          *      If the configuration parameters can't be parsed, then
100          *      fail.
101          */
102         if (cf_section_parse(conf, data, module_config) < 0) {
103                 free(data);
104                 return -1;
105         }
106
107         /*
108          *      Convert the rcode string to an int, and get rid of it
109          */
110         data->rcode = str2rcode(data->rcode_str);
111         if (data->rcode == -1) {
112                 free(data);
113                 return -1;
114         }
115
116         *instance = data;
117
118         return 0;
119 }
120
121 /*
122  *      Just return the rcode ... this function is autz, auth, acct, and
123  *      preacct!
124  */
125 static int always_return(void *instance, REQUEST *request)
126 {
127         /* quiet the compiler */
128         request = request;
129
130         return ((struct rlm_always_t *)instance)->rcode;
131 }
132
133 /*
134  *      checksimul fakes some other variables besides the rcode...
135  */
136 static int always_checksimul(void *instance, REQUEST *request)
137 {
138         struct rlm_always_t *inst = instance;
139
140         request->simul_count = inst->simulcount;
141
142         if (inst->mpp)
143                 request->simul_mpp = 2;
144
145         return inst->rcode;
146 }
147
148 static int always_detach(void *instance)
149 {
150         free(instance);
151         return 0;
152 }
153
154 module_t rlm_always = {
155         RLM_MODULE_INIT,
156         "always",
157         RLM_TYPE_CHECK_CONFIG_SAFE,     /* type */
158         always_instantiate,             /* instantiation */
159         always_detach,                  /* detach */
160         {
161                 always_return,          /* authentication */
162                 always_return,          /* authorization */
163                 always_return,          /* preaccounting */
164                 always_return,          /* accounting */
165                 always_checksimul,      /* checksimul */
166                 always_return,          /* pre-proxy */
167                 always_return,          /* post-proxy */
168                 always_return           /* post-auth */
169 #ifdef WITH_COA
170                 ,
171                 always_return,          /* recv-coa */
172                 always_return           /* send-coa */
173 #endif
174         },
175 };