]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
"sometimes" module which generates random errors for testing
authorAlan T. DeKok <aland@freeradius.org>
Sun, 29 Apr 2012 19:56:38 +0000 (21:56 +0200)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 30 Apr 2012 09:32:14 +0000 (11:32 +0200)
raddb/mods-available/sometimes [new file with mode: 0644]
src/modules/rlm_sometimes/Makefile [new file with mode: 0644]
src/modules/rlm_sometimes/all.mk [new file with mode: 0644]
src/modules/rlm_sometimes/rlm_sometimes.c [new file with mode: 0644]
src/modules/stable

diff --git a/raddb/mods-available/sometimes b/raddb/mods-available/sometimes
new file mode 100644 (file)
index 0000000..3a96622
--- /dev/null
@@ -0,0 +1,12 @@
+# -*- text -*-
+#
+#  $Id$
+
+#
+# The "sometimes" module is here for debugging purposes. Each instance
+# randomly returns the configured result, or "noop".
+#
+# It is based on the "always" module.
+sometimes {
+       rcode = fail
+}
diff --git a/src/modules/rlm_sometimes/Makefile b/src/modules/rlm_sometimes/Makefile
new file mode 100644 (file)
index 0000000..2f2f352
--- /dev/null
@@ -0,0 +1,10 @@
+#
+# Makefile
+#
+# Version:     $Id$
+#
+
+TARGET         = rlm_sometimes
+SRCS           = rlm_sometimes.c
+
+include ../rules.mak
diff --git a/src/modules/rlm_sometimes/all.mk b/src/modules/rlm_sometimes/all.mk
new file mode 100644 (file)
index 0000000..1aab7db
--- /dev/null
@@ -0,0 +1,3 @@
+TARGET         := rlm_sometimess.a
+
+SOURCES                := rlm_sometimes.c
diff --git a/src/modules/rlm_sometimes/rlm_sometimes.c b/src/modules/rlm_sometimes/rlm_sometimes.c
new file mode 100644 (file)
index 0000000..5b02e52
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * rlm_sometimes.c
+ *
+ *   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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ * Copyright 2000,2006  The FreeRADIUS server project
+ */
+
+#include <freeradius-devel/ident.h>
+RCSID("$Id$")
+
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/modules.h>
+
+/*
+ *     The instance data for rlm_sometimes is the list of fake values we are
+ *     going to return.
+ */
+typedef struct rlm_sometimes_t {
+       char    *rcode_str;
+       int     rcode;
+       int     start;
+       int     end;
+} rlm_sometimes_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 const CONF_PARSER module_config[] = {
+  { "rcode",      PW_TYPE_STRING_PTR, offsetof(rlm_sometimes_t,rcode_str),
+    NULL, "fail" },
+
+  { "start", PW_TYPE_INTEGER,    offsetof(rlm_sometimes_t,start),
+    NULL, "0" },
+
+  { "end", PW_TYPE_INTEGER,    offsetof(rlm_sometimes_t,end),
+    NULL, "127" },
+
+  { NULL, -1, 0, NULL, NULL }          /* end the list */
+};
+
+static int str2rcode(const char *s)
+{
+       if(!strcasecmp(s, "reject"))
+               return RLM_MODULE_REJECT;
+       else if(!strcasecmp(s, "fail"))
+               return RLM_MODULE_FAIL;
+       else if(!strcasecmp(s, "ok"))
+               return RLM_MODULE_OK;
+       else if(!strcasecmp(s, "handled"))
+               return RLM_MODULE_HANDLED;
+       else if(!strcasecmp(s, "invalid"))
+               return RLM_MODULE_INVALID;
+       else if(!strcasecmp(s, "userlock"))
+               return RLM_MODULE_USERLOCK;
+       else if(!strcasecmp(s, "notfound"))
+               return RLM_MODULE_NOTFOUND;
+       else if(!strcasecmp(s, "noop"))
+               return RLM_MODULE_NOOP;
+       else if(!strcasecmp(s, "updated"))
+               return RLM_MODULE_UPDATED;
+       else {
+               radlog(L_ERR|L_CONS,
+                       "rlm_sometimes: Unknown module rcode '%s'.\n", s);
+               return -1;
+       }
+}
+
+static int sometimes_instantiate(CONF_SECTION *conf, void **instance)
+{
+       rlm_sometimes_t *inst;
+
+       /*
+        *      Set up a storage area for instance data
+        */
+       inst = rad_malloc(sizeof(*inst));
+       if (!inst) {
+               return -1;
+       }
+       memset(inst, 0, sizeof(*inst));
+
+       /*
+        *      If the configuration parameters can't be parsed, then
+        *      fail.
+        */
+       if (cf_section_parse(conf, inst, module_config) < 0) {
+               free(inst);
+               return -1;
+       }
+
+       /*
+        *      Convert the rcode string to an int, and get rid of it
+        */
+       inst->rcode = str2rcode(inst->rcode_str);
+       if (inst->rcode == -1) {
+               free(inst);
+               return -1;
+       }
+
+       *instance = inst;
+
+       return 0;
+}
+
+/*
+ *     A lie!  It always returns!
+ */
+static int sometimes_return(void *instance, RADIUS_PACKET *packet,
+                           RADIUS_PACKET *reply)
+{
+       uint32_t hash;
+       int value;
+       rlm_sometimes_t *inst = instance;
+
+       /*
+        *      Set it to NOOP and the module will always do nothing
+        */
+       if (inst->rcode == RLM_MODULE_NOOP) return inst->rcode;
+
+       /*
+        *      Take into account src/dst ip/port, ID, code, vector, etc.
+        */
+       hash = fr_hash(packet, sizeof(*packet));
+       hash &= 0xff;           /* ensure it's 0..255 */
+       value = hash;
+
+       /*
+        *      Ranges are INCLUSIVE.
+        *      [start,end] returns "rcode"
+        *      Everything else returns "noop"
+        */
+       if (value < inst->start) return RLM_MODULE_NOOP;
+       if (value > inst->end) return RLM_MODULE_NOOP;
+
+       /*
+        *      If we're returning "handled", then set the packet
+        *      code in the reply, so that the server responds.
+        */
+       if ((inst->rcode == RLM_MODULE_HANDLED) && reply) {
+               switch (packet->code) {
+               case PW_AUTHENTICATION_REQUEST:
+                       reply->code = PW_AUTHENTICATION_ACK;
+                       break;
+
+               case PW_ACCOUNTING_REQUEST:
+                       reply->code = PW_ACCOUNTING_RESPONSE;
+                       break;
+
+               case PW_COA_REQUEST:
+                       reply->code = PW_COA_ACK;
+                       break;
+
+               case PW_DISCONNECT_REQUEST:
+                       reply->code = PW_DISCONNECT_ACK;
+                       break;
+
+               default:
+                       break;
+               }
+       }
+
+       return inst->rcode;
+}
+
+static int sometimes_packet(void *instance, REQUEST *request)
+{
+       return sometimes_return(instance, request->packet, request->reply);
+}
+
+static int sometimes_reply(void *instance, REQUEST *request)
+{
+       return sometimes_return(instance, request->reply, NULL);
+}
+
+static int sometimes_pre_proxy(void *instance, REQUEST *request)
+{
+       if (!request->proxy) return RLM_MODULE_NOOP;
+
+       return sometimes_return(instance, request->proxy, request->proxy_reply);
+}
+
+static int sometimes_post_proxy(void *instance, REQUEST *request)
+{
+       if (!request->proxy_reply) return RLM_MODULE_NOOP;
+
+       return sometimes_return(instance, request->proxy_reply, NULL);
+}
+
+module_t rlm_sometimes = {
+       RLM_MODULE_INIT,
+       "sometimes",
+       RLM_TYPE_CHECK_CONFIG_SAFE | RLM_TYPE_HUP_SAFE,         /* type */
+       sometimes_instantiate,          /* instantiation */
+       NULL,                           /* detach */
+       {
+               sometimes_packet,       /* authentication */
+               sometimes_packet,       /* authorization */
+               sometimes_packet,       /* preaccounting */
+               sometimes_packet,       /* accounting */
+               NULL,
+               sometimes_pre_proxy,    /* pre-proxy */
+               sometimes_post_proxy,   /* post-proxy */
+               sometimes_reply         /* post-auth */
+#ifdef WITH_COA
+               ,
+               sometimes_packet,       /* recv-coa */
+               sometimes_reply         /* send-coa */
+#endif
+       },
+};
index 39d45160f29cdba6e07712a58af31c7a8d46367c..0dc1548e6a582fc167902075d01454118ed943aa 100644 (file)
@@ -41,3 +41,4 @@ rlm_unix
 rlm_policy
 rlm_dynamic_clients
 rlm_replicate
+rlm_sometimes