Patch from "Alan Curry" <pacman-radius@cqc.com>
[freeradius.git] / src / modules / rlm_example / rlm_example.c
1 #include "autoconf.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 #include "radiusd.h"
7 #include "modules.h"
8 #include "conffile.h"
9
10 static const char rcsid[] = "$Id$";
11
12 /*
13  *      Define a structure for our module configuration.
14  *
15  *      These variables do not need to be in a structure, but it's
16  *      a lot cleaner to do so, and a pointer to the structure can
17  *      be used as the instance handle.
18  */
19 typedef struct example_config_t {
20         int             boolean;
21         int             value;
22         char            *string;
23         uint32_t        ipaddr;
24 } example_config_t;
25
26 /*
27  *      A temporary holding area for config values to be extracted
28  *      into, before they are copied into the instance data
29  */
30 static example_config_t config;
31
32 /*
33  *      A mapping of configuration file names to internal variables.
34  *
35  *      Note that the string is dynamically allocated, so it MUST
36  *      be freed.  When the configuration file parse re-reads the string,
37  *      it free's the old one, and strdup's the new one, placing the pointer
38  *      to the strdup'd string into 'config.string'.  This gets around
39  *      buffer over-flows.
40  */
41 static CONF_PARSER module_config[] = {
42   { "integer", PW_TYPE_INTEGER,    &config.value,   "1" },
43   { "boolean", PW_TYPE_BOOLEAN,    &config.boolean, "no" },
44   { "string",  PW_TYPE_STRING_PTR, &config.string,  NULL },
45   { "ipaddr",  PW_TYPE_IPADDR,     &config.ipaddr,  "*" },
46
47   { NULL, -1, NULL, NULL }              /* end the list */
48 };
49
50 /*
51  *      Do any per-module initialization.  e.g. set up connections
52  *      to external databases, read configuration files, set up
53  *      dictionary entries, etc.
54  *
55  *      Try to avoid putting too much stuff in here - it's better to
56  *      do it in instantiate() where it is not global.
57  */
58 static int radius_init(void)
59 {
60         /*
61          *      Everything's OK, return without an error.
62          */
63         return 0;
64 }
65
66 /*
67  *      Do any per-module initialization that is separate to each
68  *      configured instance of the module.  e.g. set up connections
69  *      to external databases, read configuration files, set up
70  *      dictionary entries, etc.
71  *
72  *      If configuration information is given in the config section
73  *      that must be referenced in later calls, store a handle to it
74  *      in *instance otherwise put a null pointer there.
75  */
76 static int radius_instantiate(CONF_SECTION *conf, void **instance)
77 {
78   /*
79    *    Set up a storage area for instance data
80    */
81   *instance = malloc(sizeof(struct example_config_t));
82   if(!*instance) {
83         return -1;
84   }
85
86   /*
87    *    If the configuration parameters can't be parsed, then
88    *    fail.
89    */
90   if (cf_section_parse(conf, module_config) < 0) {
91           free(*instance);
92           return -1;
93   }
94
95   /*
96    *    Copy the configuration into the instance data
97    */
98 #define inst ((struct example_config_t *)*instance)
99   inst->boolean = config.boolean;
100   inst->value = config.value;
101   inst->string = config.string;
102   inst->ipaddr = config.ipaddr;
103 #undef inst
104   config.string = 0; /* So cf_section_parse won't free it next time */
105
106   return 0;
107 }
108
109 /*
110  *      Find the named user in this modules database.  Create the set
111  *      of attribute-value pairs to check and reply with for this user
112  *      from the database. The authentication code only needs to check
113  *      the password, the rest is done here.
114  */
115 static int radius_authorize(void *instance, REQUEST *request)
116 {
117         /* quiet the compiler */
118         instance = instance;
119         request = request;
120         
121         return RLM_MODULE_HANDLED;
122 }
123
124 /*
125  *      Authenticate the user with the given password.
126  */
127 static int radius_authenticate(void *instance, REQUEST *request)
128 {
129         /* quiet the compiler */
130         instance = instance;
131         request = request;
132         
133         return RLM_MODULE_OK;
134 }
135
136 /*
137  *      Massage the request before recording it or proxying it
138  */
139 static int radius_preacct(void *instance, REQUEST *request)
140 {
141         /* quiet the compiler */
142         instance = instance;
143         request = request;
144         
145         return RLM_MODULE_OK;
146 }
147
148 /*
149  *      Write accounting information to this modules database.
150  */
151 static int radius_accounting(void *instance, REQUEST *request)
152 {
153         /* quiet the compiler */
154         instance = instance;
155         request = request;
156         
157         return RLM_MODULE_OK;
158 }
159
160 static int radius_detach(void *instance)
161 {
162         free(((struct example_config_t *)instance)->string);
163         free(instance);
164         return 0;
165 }
166
167 /* globally exported name */
168 module_t rlm_example = {
169         "example",
170         0,                              /* type: reserved */
171         radius_init,                    /* initialization */
172         radius_instantiate,             /* instantiation */
173         radius_authorize,               /* authorization */
174         radius_authenticate,            /* authentication */
175         radius_preacct,                 /* preaccounting */
176         radius_accounting,              /* accounting */
177         radius_detach,                  /* detach */
178         NULL,                           /* destroy */
179 };