Add preliminary stage of 'exec' module, which currently only
authoraland <aland>
Thu, 23 Jan 2003 19:50:15 +0000 (19:50 +0000)
committeraland <aland>
Thu, 23 Jan 2003 19:50:15 +0000 (19:50 +0000)
supports calling via xlat.

src/modules/rlm_exec/Makefile [new file with mode: 0644]
src/modules/rlm_exec/rlm_exec.c [new file with mode: 0644]

diff --git a/src/modules/rlm_exec/Makefile b/src/modules/rlm_exec/Makefile
new file mode 100644 (file)
index 0000000..ef62013
--- /dev/null
@@ -0,0 +1,11 @@
+TARGET         = rlm_exec
+SRCS           = rlm_exec.c
+HEADERS                = 
+RLM_CFLAGS     =
+RLM_LIBS       = 
+
+include ../rules.mak
+
+$(STATIC_OBJS): $(HEADERS)
+
+$(DYNAMIC_OBJS): $(HEADERS)
diff --git a/src/modules/rlm_exec/rlm_exec.c b/src/modules/rlm_exec/rlm_exec.c
new file mode 100644 (file)
index 0000000..d3769a7
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * rlm_exe.c
+ *
+ * Version:    $Id$
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Copyright 2002  The FreeRADIUS server project
+ * Copyright 2002  Alan DeKok <aland@ox.org>
+ */
+
+#include "autoconf.h"
+#include "libradius.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
+
+static const char rcsid[] = "$Id$";
+
+/*
+ *     Define a structure for our module configuration.
+ */
+typedef struct rlm_exec_t {
+       char *xlat_name;
+       int wait;
+} rlm_exec_t;
+
+/*
+ *     A mapping of configuration file names to internal variables.
+ *
+ *     Note that the string is dynamically allocated, so it MUST
+ *     be freed.  When the configuration file parse re-reads the string,
+ *     it free's the old one, and strdup's the new one, placing the pointer
+ *     to the strdup'd string into 'config.string'.  This gets around
+ *     buffer over-flows.
+ */
+static CONF_PARSER module_config[] = {
+       { "wait", PW_TYPE_BOOLEAN,    offsetof(rlm_exec_t,wait), NULL, "yes" },
+       { NULL, -1, 0, NULL, NULL }             /* end the list */
+};
+
+/*
+ *  Do xlat of strings!
+ */ 
+static int exec_xlat(void *instance, REQUEST *request,
+                    char *fmt, char *out, int outlen,
+                    RADIUS_ESCAPE_STRING func)
+{
+       int             result;
+       rlm_exec_t      *inst = instance;
+       char            buffer[256];
+
+       inst = inst;            /* -Wunused */
+
+       /*
+        * Do an xlat on the provided string (nice recursive operation).
+        */
+       if (!radius_xlat(buffer, sizeof(buffer), fmt, request, NULL)) {
+               radlog(L_ERR, "rlm_exec: xlat failed.");
+               return 0;
+       }
+
+       DEBUG2("rlm_exec: %d %s", inst->wait, buffer);
+       result = radius_exec_program(buffer, request, inst->wait,
+                                    out, outlen, FALSE);
+       DEBUG2("rlm_exec: result %d", result);
+       if (result != 0) {
+               out[0] = '\0';
+               return 0;
+       }
+
+       return strlen(out);
+}
+
+/*
+ *     Do any per-module initialization that is separate to each
+ *     configured instance of the module.  e.g. set up connections
+ *     to external databases, read configuration files, set up
+ *     dictionary entries, etc.
+ *
+ *     If configuration information is given in the config section
+ *     that must be referenced in later calls, store a handle to it
+ *     in *instance otherwise put a null pointer there.
+ */
+static int exec_instantiate(CONF_SECTION *conf, void **instance)
+{
+       rlm_exec_t      *inst;
+       char            *xlat_name;
+       
+       /*
+        *      Set up a storage area for instance data
+        */
+       
+       inst = rad_malloc(sizeof(rlm_exec_t));
+       memset(inst, 0, sizeof(rlm_exec_t));
+               
+       /*
+        *      If the configuration parameters can't be parsed, then
+        *      fail.
+        */
+       if (cf_section_parse(conf, inst, module_config) < 0) {
+               free(inst);
+               return -1;
+       }
+       
+       xlat_name = cf_section_name2(conf);
+       if (xlat_name == NULL) 
+               xlat_name = cf_section_name1(conf);
+       if (xlat_name){ 
+               inst->xlat_name = strdup(xlat_name);
+               xlat_register(xlat_name, exec_xlat, inst); 
+       } 
+
+       *instance = inst;
+       
+       return 0;
+}
+
+/*
+ * Detach a instance free all ..
+ */
+static int exec_detach(void *instance)
+{
+       rlm_exec_t      *inst = instance;
+
+       xlat_unregister(inst->xlat_name, exec_xlat);
+       free(inst->xlat_name);
+
+       free(inst);
+       return 0;
+}
+
+/*
+ *     The module name should be the only globally exported symbol.
+ *     That is, everything else should be 'static'.
+ *
+ *     If the module needs to temporarily modify it's instantiation
+ *     data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
+ *     The server will then take care of ensuring that the module
+ *     is single-threaded.
+ */
+module_t rlm_exec = {
+       "exec",                         /* Name */
+       RLM_TYPE_THREAD_SAFE,           /* type */
+       NULL,                           /* initialization */
+       exec_instantiate,               /* instantiation */
+       {
+               NULL,                   /* authentication */
+               NULL,                   /* authorization */
+               NULL,                   /* pre-accounting */
+               NULL,                   /* accounting */
+               NULL,                   /* check simul */
+               NULL,                   /* pre-proxy */
+               NULL,                   /* post-proxy */
+               NULL                    /* post-auth */
+       },
+       exec_detach,                    /* detach */
+       NULL,                           /* destroy */
+};