The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
rlm_always.c
Go to the documentation of this file.
1 /*
2  * This program 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
5  * (at 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 /**
19  * $Id: f954669b977ef0da53694bfe10ae3ed4889588f1 $
20  * @file rlm_always.c
21  * @brief Return preconfigured fixed rcodes.
22  *
23  * @copyright 2000,2006 The FreeRADIUS server project
24  */
25 RCSID("$Id: f954669b977ef0da53694bfe10ae3ed4889588f1 $")
26 
27 #define LOG_PREFIX mctx->mi->name
28 
29 #include <freeradius-devel/server/base.h>
30 #include <freeradius-devel/server/module.h>
31 #include <freeradius-devel/server/module_rlm.h>
32 #include <freeradius-devel/unlang/xlat_func.h>
33 
34 /*
35  * Instance data is mprotected for runtime
36  * this is fine for the majority of module
37  * instances, but not for rlm_always.
38  *
39  * This struct is allocated outside of the
40  */
41 typedef struct {
42  rlm_rcode_t rcode; //!< The integer constant representing rcode_str.
43  bool force; //!< If true, we force the rcode.
45 
46 /*
47  * The instance data for rlm_always is the list of fake values we are
48  * going to return.
49  */
50 typedef struct {
51  char const *rcode_str; //!< The base value.
54 } rlm_always_t;
55 
56 /*
57  * A mapping of configuration file names to internal variables.
58  */
59 static const conf_parser_t module_config[] = {
60  { FR_CONF_OFFSET("rcode", rlm_always_t, rcode_str), .dflt = "fail" },
62 };
63 
65  { .single = true, .type = FR_TYPE_STRING },
67 };
68 
69 /** Set module status or rcode
70  *
71  * Look ma, no locks...
72  *
73  * Example: %db_status(fail)
74  */
75 static xlat_action_t always_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out,
76  xlat_ctx_t const *xctx,
77  request_t *request, fr_value_box_list_t *in)
78 {
79  rlm_always_t *inst = talloc_get_type_abort(xctx->mctx->mi->data, rlm_always_t);
80  module_instance_t *mi = inst->mi;
81  char const *status;
82  char const *p;
83  fr_value_box_t *vb;
84  fr_value_box_t *in_head = fr_value_box_list_head(in);
85 
86  /*
87  * Expand to the existing status
88  */
89  p = "alive";
90  if (mi->force) {
91  p = fr_table_str_by_value(rcode_table, mi->code, "<invalid>");
92  }
93 
94  if (!in_head || in_head->vb_length == 0) goto done;
95  status = in_head->vb_strvalue;
96 
97  /*
98  * Set the module status
99  */
100  if (strcmp(status, "alive") == 0) {
101  mi->force = false;
102  } else {
103  int rcode;
104 
106  if (rcode == RLM_MODULE_NOT_SET) {
107  RWARN("Unknown status \"%s\"", status);
108  return XLAT_ACTION_FAIL;
109  }
110 
111  mi->code = rcode;
112  mi->force = true;
113 
114  }
115 
116 done:
117 
118  MEM(vb = fr_value_box_alloc_null(ctx));
119  fr_value_box_strdup(vb, vb, NULL, p, false);
120  fr_dcursor_append(out, vb);
121 
122  return XLAT_ACTION_DONE;
123 
124 }
125 
126 /*
127  * Just return the rcode ... this function is autz, auth, acct, and
128  * preacct!
129  */
130 static unlang_action_t CC_HINT(nonnull) mod_always_return(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
131 {
133 
134  RETURN_MODULE_RCODE(inst->mutable->rcode);
135 }
136 
137 static int mod_detach(module_detach_ctx_t const *mctx)
138 {
139  rlm_always_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_always_t);
140 
141  talloc_free(inst->mutable);
142  return 0;
143 }
144 
145 static int mod_instantiate(module_inst_ctx_t const *mctx)
146 {
147  rlm_always_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_always_t);
148 
149  inst->mi = UNCONST(module_instance_t *, mctx->mi);
150  if (!inst->mi) {
151  cf_log_err(mctx->mi->conf, "Can't find the module instance data for this module: %s", mctx->mi->name);
152  return -1;
153  }
154 
155  /*
156  * Allocate this outside of the module instance data,
157  * as that gets mprotected
158  */
159  MEM(inst->mutable = talloc_zero(NULL, rlm_always_mutable_t));
160 
161  /*
162  * Convert the rcode string to an int
163  */
164  inst->mutable->rcode = fr_table_value_by_str(rcode_table, inst->rcode_str, RLM_MODULE_NOT_SET);
165  if (inst->mutable->rcode == RLM_MODULE_NOT_SET) {
166  cf_log_err(mctx->mi->conf, "rcode value \"%s\" is invalid", inst->rcode_str);
167  return -1;
168  }
169 
170  return 0;
171 }
172 
173 static int mod_bootstrap(module_inst_ctx_t const *mctx)
174 {
175  xlat_t *xlat;
176 
177  xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, NULL, always_xlat, FR_TYPE_STRING);
179 
180  return 0;
181 }
182 
183 extern module_rlm_t rlm_always;
185  .common = {
186  .magic = MODULE_MAGIC_INIT,
187  .name = "always",
188  .inst_size = sizeof(rlm_always_t),
190  .bootstrap = mod_bootstrap,
192  .detach = mod_detach
193  },
194  .method_group = {
195  .bindings = (module_method_binding_t[]){
196  { .section = SECTION_NAME(CF_IDENT_ANY, CF_IDENT_ANY), .method = mod_always_return },
198  }
199  }
200 };
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition: action.h:35
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition: build.h:165
#define RCSID(id)
Definition: build.h:481
#define UNUSED
Definition: build.h:313
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:627
#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
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:564
#define cf_log_err(_cf, _fmt,...)
Definition: cf_util.h:289
#define CF_IDENT_ANY
Definition: cf_util.h:78
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
Definition: dcursor.h:406
static fr_slen_t in
Definition: dict.h:821
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:63
#define RWARN(fmt,...)
Definition: log.h:297
talloc_free(reap)
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
module_instance_t const * mi
Instance of the module being instantiated.
Definition: module_ctx.h:42
module_instance_t * mi
Module instance to detach.
Definition: module_ctx.h:57
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 detach calls.
Definition: module_ctx.h:56
Temporary structure to hold arguments for instantiation calls.
Definition: module_ctx.h:50
xlat_t * module_rlm_xlat_register(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
Definition: module_rlm.c:257
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 bool done
Definition: radclient.c:80
fr_table_num_sorted_t const rcode_table[]
Definition: rcode.c:35
#define RETURN_MODULE_RCODE(_rcode)
Definition: rcode.h:64
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
static int mod_detach(module_detach_ctx_t const *mctx)
Definition: rlm_always.c:137
static xlat_action_t always_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Set module status or rcode.
Definition: rlm_always.c:75
module_instance_t * mi
Definition: rlm_always.c:52
static unlang_action_t mod_always_return(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
Definition: rlm_always.c:130
char const * rcode_str
The base value.
Definition: rlm_always.c:51
module_rlm_t rlm_always
Definition: rlm_always.c:184
static int mod_bootstrap(module_inst_ctx_t const *mctx)
Definition: rlm_always.c:173
static xlat_arg_parser_t const always_xlat_args[]
Definition: rlm_always.c:64
static const conf_parser_t module_config[]
Definition: rlm_always.c:59
bool force
If true, we force the rcode.
Definition: rlm_always.c:43
static int mod_instantiate(module_inst_ctx_t const *mctx)
Definition: rlm_always.c:145
rlm_rcode_t rcode
The integer constant representing rcode_str.
Definition: rlm_always.c:42
static int instantiate(module_inst_ctx_t const *mctx)
Definition: rlm_rest.c:1302
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition: section.h:40
char const * name
Instance name e.g. user_database.
Definition: module.h:335
CONF_SECTION * conf
Module's instance configuration.
Definition: module.h:329
bool force
Force the module to return a specific code.
Definition: module.h:297
void * data
Module's instance data.
Definition: module.h:271
void * boot
Data allocated during the boostrap phase.
Definition: module.h:274
rlm_rcode_t code
Code module will return when 'force' has has been set to true.
Definition: module.h:300
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition: module.h:151
Module instance data.
Definition: module.h:265
Named methods exported by a module.
Definition: module.h:173
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
#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 fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition: table.h:772
#define talloc_get_type_abort_const
Definition: talloc.h:282
bool single
Argument must only contain a single box.
Definition: xlat.h:148
#define XLAT_ARG_PARSER_TERMINATOR
Definition: xlat.h:166
xlat_action_t
Definition: xlat.h:35
@ XLAT_ACTION_FAIL
An xlat function failed.
Definition: xlat.h:42
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition: xlat.h:41
Definition for a single argument consumend by an xlat function.
Definition: xlat.h:145
int fr_value_box_strdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Copy a nul terminated string to a fr_value_box_t.
Definition: value.c:3927
int nonnull(2, 5))
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
Definition: value.h:632
static size_t char ** out
Definition: value.h:997
module_ctx_t const * mctx
Synthesised module calling ctx.
Definition: xlat_ctx.h:52
An xlat calling ctx.
Definition: xlat_ctx.h:49
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
Definition: xlat_func.c:365