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: e4d7b0f1d3b89592f128bade78433aa0f60f9d6d $
19 * @file rlm_sometimes.c
20 * @brief Switches between retuning different return codes.
21 *
22 * @copyright 2012 The FreeRADIUS server project
23 */
24RCSID("$Id: e4d7b0f1d3b89592f128bade78433aa0f60f9d6d $")
25
26#include <freeradius-devel/server/base.h>
27#include <freeradius-devel/server/module_rlm.h>
28#include <freeradius-devel/util/debug.h>
29
30/*
31 * The instance data for rlm_sometimes is the list of fake values we are
32 * going to return.
33 */
34typedef struct {
35 char const *rcode_str;
40
41static const conf_parser_t module_config[] = {
42 { FR_CONF_OFFSET("rcode", rlm_sometimes_t, rcode_str), .dflt = "fail" },
43 { FR_CONF_OFFSET_FLAGS("key", CONF_FLAG_ATTRIBUTE, rlm_sometimes_t, key), .dflt = "User-Name", .quote = T_BARE_WORD },
44 { FR_CONF_OFFSET("percentage", rlm_sometimes_t, percentage), .dflt = "0" },
46};
47
48static int mod_instantiate(module_inst_ctx_t const *mctx)
49{
50 rlm_sometimes_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_sometimes_t);
51 CONF_SECTION *conf = mctx->mi->conf;
52
53 /*
54 * Convert the rcode string to an int, and get rid of it
55 */
57 if (inst->rcode == RLM_MODULE_NOT_SET) {
58 cf_log_err(conf, "Unknown module return code '%s'", inst->rcode_str);
59 return -1;
60 }
61
62 if ((inst->percentage < 0) || (inst->percentage > 100)) {
63 cf_log_err(conf, "Invalid value for 'percentage'. It must be 0..100 inclusive");
64 return -1;
65 }
66
67 return 0;
68}
69
70/*
71 * A lie! It always returns!
72 */
74 fr_packet_t *packet, fr_packet_t *reply)
75{
79 float value;
80
81 /*
82 * Set it to NOOP and the module will always do nothing
83 */
84 if (inst->rcode == RLM_MODULE_NOOP) RETURN_UNLANG_RCODE(inst->rcode);
85
86 /*
87 * Hash based on the given key. Usually User-Name.
88 */
89 if (tmpl_find_vp(&vp, request, inst->key) < 0) RETURN_UNLANG_NOOP;
90
91 switch (vp->vp_type) {
92 case FR_TYPE_OCTETS:
93 case FR_TYPE_STRING:
94 hash = fr_hash(vp->data.datum.ptr, vp->vp_length);
95 break;
96
99
100 default:
101 hash = fr_hash(&vp->data.datum, fr_value_box_field_sizes[vp->vp_type]);
102 break;
103 }
104
105 hash &= 0xffff; /* all we need are 2^16 bits of precision */
106 value = hash;
107 value /= (1 << 16);
108 value *= 100;
109
110 if (value > inst->percentage) RETURN_UNLANG_NOOP;
111
112 /*
113 * If we're returning "handled", then set the packet
114 * code in the reply, so that the server responds.
115 *
116 * @todo - MULTI_PROTOCOL - make this protocol agnostic
117 */
118 if ((inst->rcode == RLM_MODULE_HANDLED) && reply) {
119 switch (packet->code) {
122 break;
123
126 break;
127
130 break;
131
134 break;
135
136 default:
137 break;
138 }
139 }
140
142}
143
144static unlang_action_t CC_HINT(nonnull) mod_sometimes_packet(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
145{
146 return sometimes_return(p_result, mctx, request, request->packet, request->reply);
147}
148
149static unlang_action_t CC_HINT(nonnull) mod_sometimes_reply(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
150{
151 return sometimes_return(p_result, mctx, request, request->reply, NULL);
152}
153
156 .common = {
157 .magic = MODULE_MAGIC_INIT,
158 .name = "sometimes",
159 .inst_size = sizeof(rlm_sometimes_t),
161 .instantiate = mod_instantiate
162 },
163 .method_group = {
164 .bindings = (module_method_binding_t[]){
165 { .section = SECTION_NAME("send", CF_IDENT_ANY), .method = mod_sometimes_reply },
168 }
169 }
170};
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:506
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:657
#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:280
fr_token_t quote
Quoting around the default value. Only used for templates.
Definition cf_parse.h:649
#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:268
@ CONF_FLAG_ATTRIBUTE
Value must resolve to attribute in dict (deprecated, use CONF_FLAG_TMPL).
Definition cf_parse.h:431
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:594
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:285
#define CF_IDENT_ANY
Definition cf_util.h:75
@ 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:847
@ 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:163
static rs_t * conf
Definition radsniff.c:52
fr_table_num_sorted_t const rcode_table[]
Definition rcode.c:35
#define RETURN_UNLANG_RCODE(_rcode)
Definition rcode.h:61
#define RETURN_UNLANG_FAIL
Definition rcode.h:63
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:44
@ RLM_MODULE_NOT_SET
Error resolving rcode (should not be returned by modules).
Definition rcode.h:45
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition rcode.h:54
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
Definition rcode.h:50
#define RETURN_UNLANG_NOOP
Definition rcode.h:69
static unsigned int hash(char const *username, unsigned int tablesize)
Definition rlm_passwd.c:132
rlm_rcode_t rcode
char const * rcode_str
static unlang_action_t sometimes_return(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request, fr_packet_t *packet, fr_packet_t *reply)
static unlang_action_t mod_sometimes_packet(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
module_rlm_t rlm_sometimes
static unlang_action_t mod_sometimes_reply(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static const conf_parser_t module_config[]
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:39
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:351
size_t inst_size
Size of the module's instance data.
Definition module.h:212
void * data
Module's instance data.
Definition module.h:293
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:152
Named methods exported by a module.
Definition module.h:174
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:776
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:110
@ T_BARE_WORD
Definition token.h:118
unsigned int code
Packet code (type).
Definition packet.h:61
#define FR_TYPE_STRUCTURAL
Definition types.h:316
size_t const fr_value_box_field_sizes[]
How many bytes wide each of the value data fields are.
Definition value.c:151
int nonnull(2, 5))