6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Copyright 2002 The FreeRADIUS server project
21 * Copyright 2002 Alan DeKok <aland@ox.org>
25 #include "libradius.h"
35 static const char rcsid[] = "$Id$";
38 * Define a structure for our module configuration.
40 typedef struct rlm_exec_t {
46 * A mapping of configuration file names to internal variables.
48 * Note that the string is dynamically allocated, so it MUST
49 * be freed. When the configuration file parse re-reads the string,
50 * it free's the old one, and strdup's the new one, placing the pointer
51 * to the strdup'd string into 'config.string'. This gets around
54 static CONF_PARSER module_config[] = {
55 { "wait", PW_TYPE_BOOLEAN, offsetof(rlm_exec_t,wait), NULL, "yes" },
56 { NULL, -1, 0, NULL, NULL } /* end the list */
62 static int exec_xlat(void *instance, REQUEST *request,
63 char *fmt, char *out, int outlen,
64 RADIUS_ESCAPE_STRING func)
67 rlm_exec_t *inst = instance;
70 inst = inst; /* -Wunused */
73 * Do an xlat on the provided string (nice recursive operation).
75 if (!radius_xlat(buffer, sizeof(buffer), fmt, request, NULL)) {
76 radlog(L_ERR, "rlm_exec: xlat failed.");
80 DEBUG2("rlm_exec: %d %s", inst->wait, buffer);
81 result = radius_exec_program(buffer, request, inst->wait,
83 DEBUG2("rlm_exec: result %d", result);
93 * Do any per-module initialization that is separate to each
94 * configured instance of the module. e.g. set up connections
95 * to external databases, read configuration files, set up
96 * dictionary entries, etc.
98 * If configuration information is given in the config section
99 * that must be referenced in later calls, store a handle to it
100 * in *instance otherwise put a null pointer there.
102 static int exec_instantiate(CONF_SECTION *conf, void **instance)
108 * Set up a storage area for instance data
111 inst = rad_malloc(sizeof(rlm_exec_t));
112 memset(inst, 0, sizeof(rlm_exec_t));
115 * If the configuration parameters can't be parsed, then
118 if (cf_section_parse(conf, inst, module_config) < 0) {
123 xlat_name = cf_section_name2(conf);
124 if (xlat_name == NULL)
125 xlat_name = cf_section_name1(conf);
127 inst->xlat_name = strdup(xlat_name);
128 xlat_register(xlat_name, exec_xlat, inst);
137 * Detach a instance free all ..
139 static int exec_detach(void *instance)
141 rlm_exec_t *inst = instance;
143 xlat_unregister(inst->xlat_name, exec_xlat);
144 free(inst->xlat_name);
151 * The module name should be the only globally exported symbol.
152 * That is, everything else should be 'static'.
154 * If the module needs to temporarily modify it's instantiation
155 * data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
156 * The server will then take care of ensuring that the module
157 * is single-threaded.
159 module_t rlm_exec = {
161 RLM_TYPE_THREAD_SAFE, /* type */
162 NULL, /* initialization */
163 exec_instantiate, /* instantiation */
165 NULL, /* authentication */
166 NULL, /* authorization */
167 NULL, /* pre-accounting */
168 NULL, /* accounting */
169 NULL, /* check simul */
170 NULL, /* pre-proxy */
171 NULL, /* post-proxy */
174 exec_detach, /* detach */