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