The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_sometimes.c
Go to the documentation of this file.
1/*
2 * This program is is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 5db3c666482776066857f6a25939f3137f3dfac4 $
19 * @file rlm_sometimes.c
20 * @brief Switches between retuning different return codes.
21 *
22 * @copyright 2012 The FreeRADIUS server project
23 */
24RCSID("$Id: 5db3c666482776066857f6a25939f3137f3dfac4 $")
25
26#include <freeradius-devel/server/base.h>
27#include <freeradius-devel/server/module_rlm.h>
28#include <freeradius-devel/radius/radius.h>
29#include <freeradius-devel/util/debug.h>
30
31/*
32 * The instance data for rlm_sometimes is the list of fake values we are
33 * going to return.
34 */
35typedef struct {
36 char const *rcode_str;
41
42static const conf_parser_t module_config[] = {
43 { FR_CONF_OFFSET("rcode", rlm_sometimes_t, rcode_str), .dflt = "fail" },
44 { FR_CONF_OFFSET_FLAGS("key", CONF_FLAG_ATTRIBUTE, rlm_sometimes_t, key), .dflt = "&User-Name", .quote = T_BARE_WORD },
45 { FR_CONF_OFFSET("percentage", rlm_sometimes_t, percentage), .dflt = "0" },
47};
48
49static int mod_instantiate(module_inst_ctx_t const *mctx)
50{
51 rlm_sometimes_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_sometimes_t);
52 CONF_SECTION *conf = mctx->mi->conf;
53
54 /*
55 * Convert the rcode string to an int, and get rid of it
56 */
58 if (inst->rcode == RLM_MODULE_NOT_SET) {
59 cf_log_err(conf, "Unknown module return code '%s'", inst->rcode_str);
60 return -1;
61 }
62
63 if ((inst->percentage < 0) || (inst->percentage > 100)) {
64 cf_log_err(conf, "Invalid value for 'percentage'. It must be 0..100 inclusive");
65 return -1;
66 }
67
68 return 0;
69}
70
71/*
72 * A lie! It always returns!
73 */
74static unlang_action_t sometimes_return(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request,
75 fr_packet_t *packet, fr_packet_t *reply)
76{
80 float value;
81
82 /*
83 * Set it to NOOP and the module will always do nothing
84 */
85 if (inst->rcode == RLM_MODULE_NOOP) RETURN_MODULE_RCODE(inst->rcode);
86
87 /*
88 * Hash based on the given key. Usually User-Name.
89 */
90 if (tmpl_find_vp(&vp, request, inst->key) < 0) RETURN_MODULE_NOOP;
91
92 switch (vp->vp_type) {
93 case FR_TYPE_OCTETS:
94 case FR_TYPE_STRING:
95 hash = fr_hash(vp->data.datum.ptr, vp->vp_length);
96 break;
97
100
101 default:
102 hash = fr_hash(&vp->data.datum, fr_value_box_field_sizes[vp->vp_type]);
103 break;
104 }
105
106 hash &= 0xffff; /* all we need are 2^16 bits of precision */
107 value = hash;
108 value /= (1 << 16);
109 value *= 100;
110
111 if (value > inst->percentage) RETURN_MODULE_NOOP;
112
113 /*
114 * If we're returning "handled", then set the packet
115 * code in the reply, so that the server responds.
116 *
117 * @todo - MULTI_PROTOCOL - make this protocol agnostic
118 */
119 if ((inst->rcode == RLM_MODULE_HANDLED) && reply) {
120 switch (packet->code) {
123 break;
124
127 break;
128
131 break;
132
135 break;
136
137 default:
138 break;
139 }
140 }
141
143}
144
145static unlang_action_t CC_HINT(nonnull) mod_sometimes_packet(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
146{
147 return sometimes_return(p_result, mctx, request, request->packet, request->reply);
148}
149
150static unlang_action_t CC_HINT(nonnull) mod_sometimes_reply(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
151{
152 return sometimes_return(p_result, mctx, request, request->reply, NULL);
153}
154
157 .common = {
158 .magic = MODULE_MAGIC_INIT,
159 .name = "sometimes",
160 .inst_size = sizeof(rlm_sometimes_t),
163 },
164 .method_group = {
165 .bindings = (module_method_binding_t[]){
166 { .section = SECTION_NAME("send", CF_IDENT_ANY), .method = mod_sometimes_reply },
169 }
170 }
171};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
#define RCSID(id)
Definition build.h:483
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:642
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:268
fr_token_t quote
Quoting around the default value. Only used for templates.
Definition cf_parse.h:634
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:256
@ CONF_FLAG_ATTRIBUTE
Value must resolve to attribute in dict (deprecated, use CONF_FLAG_TMPL).
Definition cf_parse.h:420
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:579
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:289
#define CF_IDENT_ANY
Definition cf_util.h:78
@ FR_RADIUS_CODE_ACCESS_REQUEST
RFC2865 - Access-Request.
Definition defs.h:33
@ FR_RADIUS_CODE_DISCONNECT_REQUEST
RFC3575/RFC5176 - Disconnect-Request.
Definition defs.h:46
@ FR_RADIUS_CODE_DISCONNECT_ACK
RFC3575/RFC5176 - Disconnect-Ack (positive)
Definition defs.h:47
@ FR_RADIUS_CODE_COA_REQUEST
RFC3575/RFC5176 - CoA-Request.
Definition defs.h:49
@ FR_RADIUS_CODE_ACCESS_ACCEPT
RFC2865 - Access-Accept.
Definition defs.h:34
@ FR_RADIUS_CODE_ACCOUNTING_RESPONSE
RFC2866 - Accounting-Response.
Definition defs.h:37
@ FR_RADIUS_CODE_COA_ACK
RFC3575/RFC5176 - CoA-Ack (positive)
Definition defs.h:50
@ FR_RADIUS_CODE_ACCOUNTING_REQUEST
RFC2866 - Accounting-Request.
Definition defs.h:36
Test enumeration values.
Definition dict_test.h:92
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
uint32_t fr_hash(void const *data, size_t size)
Definition hash.c:812
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_OCTETS
Raw octets.
unsigned int uint32_t
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for module calls.
Definition module_ctx.h:41
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
static const conf_parser_t config[]
Definition base.c:183
static rs_t * conf
Definition radsniff.c:53
fr_table_num_sorted_t const rcode_table[]
Definition rcode.c:35
#define RETURN_MODULE_NOOP
Definition rcode.h:62
#define RETURN_MODULE_RCODE(_rcode)
Definition rcode.h:64
#define RETURN_MODULE_FAIL
Definition rcode.h:56
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
@ RLM_MODULE_NOT_SET
Error resolving rcode (should not be returned by modules).
Definition rcode.h:51
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition rcode.h:48
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
Definition rcode.h:44
static unsigned int hash(char const *username, unsigned int tablesize)
Definition rlm_passwd.c:132
static int instantiate(module_inst_ctx_t const *mctx)
Definition rlm_rest.c:1310
static unlang_action_t mod_sometimes_reply(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
rlm_rcode_t rcode
char const * rcode_str
static unlang_action_t sometimes_return(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request, fr_packet_t *packet, fr_packet_t *reply)
module_rlm_t rlm_sometimes
static const conf_parser_t module_config[]
static unlang_action_t mod_sometimes_packet(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
static int mod_instantiate(module_inst_ctx_t const *mctx)
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition section.h:40
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:329
size_t inst_size
Size of the module's instance data.
Definition module.h:203
void * data
Module's instance data.
Definition module.h:271
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:151
Named methods exported by a module.
Definition module.h:173
int tmpl_find_vp(fr_pair_t **out, request_t *request, tmpl_t const *vpt))
Returns the first VP matching a tmpl_t.
Definition tmpl_eval.c:889
eap_aka_sim_process_conf_t * inst
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
Definition table.h:653
#define talloc_get_type_abort_const
Definition talloc.h:282
@ T_BARE_WORD
Definition token.h:120
unsigned int code
Packet code (type).
Definition packet.h:61
#define FR_TYPE_STRUCTURAL
Definition types.h:296
size_t const fr_value_box_field_sizes[]
How many bytes wide each of the value data fields are.
Definition value.c:149
int nonnull(2, 5))