From: Alan T. DeKok Date: Sun, 29 Apr 2012 19:56:38 +0000 (+0200) Subject: "sometimes" module which generates random errors for testing X-Git-Tag: release_3_0_0_beta0~208 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7c3ca4fe1c452c27702b0834582a371fc5529473;p=thirdparty%2Ffreeradius-server.git "sometimes" module which generates random errors for testing --- diff --git a/raddb/mods-available/sometimes b/raddb/mods-available/sometimes new file mode 100644 index 00000000000..3a96622cc93 --- /dev/null +++ b/raddb/mods-available/sometimes @@ -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 index 00000000000..2f2f35245f9 --- /dev/null +++ b/src/modules/rlm_sometimes/Makefile @@ -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 index 00000000000..1aab7db73d8 --- /dev/null +++ b/src/modules/rlm_sometimes/all.mk @@ -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 index 00000000000..5b02e522224 --- /dev/null +++ b/src/modules/rlm_sometimes/rlm_sometimes.c @@ -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 +RCSID("$Id$") + +#include +#include + +/* + * 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 + }, +}; diff --git a/src/modules/stable b/src/modules/stable index 39d45160f29..0dc1548e6a5 100644 --- a/src/modules/stable +++ b/src/modules/stable @@ -41,3 +41,4 @@ rlm_unix rlm_policy rlm_dynamic_clients rlm_replicate +rlm_sometimes