The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
map_proc.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 * $Id: 4d4034b484575e6c2427cf14c1de3b7a572ac5e3 $
19 *
20 * @brief Map processor functions
21 * @file src/lib/server/map_proc.c
22 *
23 * @copyright 2015 The FreeRADIUS server project
24 * @copyright 2015 Arran Cudbard-bell (a.cudbardb@freeradius.org)
25 */
26
27RCSID("$Id: 4d4034b484575e6c2427cf14c1de3b7a572ac5e3 $")
28
29#include <freeradius-devel/server/base.h>
30
32
33/** Compare two map_proc_t structs, based ONLY on the name
34 *
35 * @param[in] one First map struct.
36 * @param[in] two Second map struct.
37 * @return Integer specifying order of map func instances.
38 */
39static int8_t map_proc_cmp(void const *one, void const *two)
40{
41 map_proc_t const *a = one, *b = two;
42
43 MEMCMP_RETURN(a, b, name, length);
44 return 0;
45}
46
47/** Unregister a map processor
48 *
49 * @param[in] proc to unregister.
50 */
52{
53 map_proc_t find;
54 map_proc_t *found;
55
56 if (!map_proc_root) return 0;
57
58 strlcpy(find.name, proc->name, sizeof(find.name));
59 find.length = strlen(find.name);
60
61 found = fr_rb_find(map_proc_root, &find);
62 if (!found) return 0;
63
65
66 return 0;
67}
68
73
74/** Find a map processor by name
75 *
76 * @param[in] name of map processor.
77 * @return
78 * - #map_proc matching name.
79 * - NULL if none was found.
80 */
82{
83 map_proc_t find;
84
85 if (!map_proc_root) return NULL;
86
87 strlcpy(find.name, name, sizeof(find.name));
88 find.length = strlen(find.name);
89
90 return fr_rb_find(map_proc_root, &find);
91}
92
93static int _map_proc_tree_init(UNUSED void *uctx)
94{
96 return 0;
97}
98
99static int _map_proc_tree_free(UNUSED void *uctx)
100{
102
103 fr_assert_msg(fr_rb_num_elements(mpr) == 0, "map_proc_t still registered");
104
105 map_proc_root = NULL;
106 talloc_free(mpr);
107 return 0;
108}
109
110/** Register a map processor
111 *
112 * This should be called by every module that provides a map processing function.
113 *
114 * @param[in] ctx if non-null, the ctx to bind this map processor to.
115 * @param[in] mod_inst of module registering the map_proc.
116 * @param[in] name of map processor. If processor already exists, it is replaced.
117 * @param[in] evaluate Module's map processor function.
118 * @param[in] instantiate function (optional).
119 * @param[in] inst_size of talloc chunk to allocate for instance data (optional).
120 * @param[in] literals_safe_for What safe_for value to assign to literals.
121 * @return
122 * - 0 on success.
123 * - -1 on failure.
124 */
125int map_proc_register(TALLOC_CTX *ctx, void const *mod_inst, char const *name,
126 map_proc_func_t evaluate,
127 map_proc_instantiate_t instantiate, size_t inst_size, fr_value_box_safe_for_t literals_safe_for)
128{
129 map_proc_t *proc;
130
131 fr_assert(name && name[0]);
132
134
135 /*
136 * If it already exists, replace it.
137 */
138 proc = map_proc_find(name);
139 if (!proc) {
140 /*
141 * Don't allocate directly in the parent ctx, it might be mprotected
142 * later, and that'll cause segfaults if any of the map_proc_t are still
143 * protected when we start shuffling the contents of the rbtree.
144 */
145 proc = talloc_zero(NULL, map_proc_t);
146 if (ctx) talloc_link_ctx(ctx, proc);
147
148 strlcpy(proc->name, name, sizeof(proc->name));
149 proc->length = strlen(proc->name);
150
151 if (fr_rb_replace(NULL, map_proc_root, proc) < 0) {
152 talloc_free(proc);
153 return -1;
154 }
155
156 talloc_set_destructor(proc, _map_proc_talloc_free);
157 }
158
159 DEBUG3("map_proc_register: %s", proc->name);
160
161 proc->mod_inst = mod_inst;
162 proc->evaluate = evaluate;
163 proc->instantiate = instantiate;
164 proc->inst_size = inst_size;
165 proc->literals_safe_for = literals_safe_for;
166
167 return 0;
168}
169
170/** Unregister a map processor by name
171 *
172 * @param[in] name of map processor to unregister.
173 * @return
174 * - 0 if map processor was found and unregistered.
175 * - -1 if map processor was not found.
176 */
177int map_proc_unregister(char const *name)
178{
179 map_proc_t *proc;
180
181 proc = map_proc_find(name);
182 if (proc) {
183 talloc_free(proc);
184 return 0;
185 }
186
187 return -1;
188}
189
190
191/** Create a new map proc instance
192 *
193 * This should be called for every map {} section in the configuration.
194 *
195 * @param[in] ctx to allocate proc instance in.
196 * @param[in] proc resolved with #map_proc_find.
197 * @param[in] cs #CONF_SECTION representing this instance of a map processor.
198 * @param[in] src template.
199 * @param[in] maps Head of the list of maps.
200 * @return
201 * - New #map_proc_inst_t on success.
202 * - NULL on error.
203 */
204map_proc_inst_t *map_proc_instantiate(TALLOC_CTX *ctx, map_proc_t const *proc,
205 CONF_SECTION *cs, tmpl_t const *src, map_list_t const *maps)
206{
208
209 inst = talloc_zero(ctx, map_proc_inst_t);
210 inst->proc = proc;
211 inst->src = src;
212 inst->maps = maps;
213
214 if (proc->instantiate) {
215 if (proc->inst_size > 0) {
216 inst->data = talloc_zero_array(inst, uint8_t, proc->inst_size);
217 if (!inst->data) return NULL;
218 }
219
220 if (proc->instantiate(cs, proc->mod_inst, inst->data, src, maps) < 0) {
222 return NULL;
223 }
224 }
225
226 return inst;
227}
228
229/** Evaluate a set of maps using the specified map processor
230 *
231 * Evaluate the map processor src template, then call a map processor function to do
232 * something with the expanded src template and map the result to attributes in the request.
233 *
234 * @param[out] p_result Result code of evaluating the map.
235 * @param[in] request The current request.
236 * @param[in] inst of a map processor.
237 * @param[in,out] result Result of expanding the map input. May be consumed
238 * by the map processor.
239 * @return one of UNLANG_ACTION_*
240 */
241unlang_action_t map_proc(rlm_rcode_t *p_result, request_t *request, map_proc_inst_t const *inst, fr_value_box_list_t *result)
242{
243 return inst->proc->evaluate(p_result, inst->proc->mod_inst, inst->data, request, result, inst->maps);
244}
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
#define fr_atexit_global_once(_init, _free, _uctx)
Definition atexit.h:211
#define RCSID(id)
Definition build.h:485
#define MEMCMP_RETURN(_a, _b, _field, _len_field)
Return if the contents of the specified field is not identical between the specified structures.
Definition build.h:156
#define UNUSED
Definition build.h:317
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
Definition debug.h:210
#define MEM(x)
Definition debug.h:36
#define DEBUG3(_fmt,...)
Definition log.h:266
talloc_free(reap)
static int _map_proc_tree_init(UNUSED void *uctx)
Definition map_proc.c:93
map_proc_t * map_proc_find(char const *name)
Find a map processor by name.
Definition map_proc.c:81
static int _map_proc_talloc_free(map_proc_t *proc)
Unregister a map processor.
Definition map_proc.c:51
static int _map_proc_tree_free(UNUSED void *uctx)
Definition map_proc.c:99
int map_proc_unregister(char const *name)
Unregister a map processor by name.
Definition map_proc.c:177
static fr_rb_tree_t * map_proc_root
Definition map_proc.c:31
int map_proc_register(TALLOC_CTX *ctx, void const *mod_inst, char const *name, map_proc_func_t evaluate, map_proc_instantiate_t instantiate, size_t inst_size, fr_value_box_safe_for_t literals_safe_for)
Register a map processor.
Definition map_proc.c:125
static int8_t map_proc_cmp(void const *one, void const *two)
Compare two map_proc_t structs, based ONLY on the name.
Definition map_proc.c:39
map_proc_inst_t * map_proc_instantiate(TALLOC_CTX *ctx, map_proc_t const *proc, CONF_SECTION *cs, tmpl_t const *src, map_list_t const *maps)
Create a new map proc instance.
Definition map_proc.c:204
fr_value_box_safe_for_t map_proc_literals_safe_for(map_proc_t const *proc)
Definition map_proc.c:69
int(* map_proc_instantiate_t)(CONF_SECTION *cs, void const *mod_inst, void *proc_inst, tmpl_t const *src, map_list_t const *maps)
Allocate new instance data for a map processor.
Definition map_proc.h:77
unlang_action_t(* map_proc_func_t)(rlm_rcode_t *p_result, void const *mod_inst, void *proc_inst, request_t *request, fr_value_box_list_t *result, map_list_t const *maps)
Function to evaluate the src string and map the result to server attributes.
Definition map_proc.h:63
char name[FR_MAX_STRING_LEN]
Name of the map function.
int length
Length of name.
void const * mod_inst
Module instance.
fr_value_box_safe_for_t literals_safe_for
Safe for values to be set for literals in the map source.
size_t inst_size
Size of map_proc instance data to allocate.
map_proc_func_t evaluate
Module's map processor function.
map_proc_instantiate_t instantiate
Callback to create new instance struct.
Map processor registration.
Map processor instance.
unsigned char uint8_t
#define fr_assert(_expr)
Definition rad_assert.h:38
uint32_t fr_rb_num_elements(fr_rb_tree_t *tree)
Return how many nodes there are in a tree.
Definition rb.c:781
int fr_rb_replace(void **old, fr_rb_tree_t *tree, void const *data)
Replace old data with new data, OR insert if there is no old.
Definition rb.c:647
void * fr_rb_find(fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
Definition rb.c:577
bool fr_rb_delete(fr_rb_tree_t *tree, void const *data)
Remove node and free data (if a free function was specified)
Definition rb.c:741
#define fr_rb_inline_talloc_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black that verifies elements are of a specific talloc type.
Definition rb.h:246
The main red black tree structure.
Definition rb.h:73
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
static char const * name
static int instantiate(module_inst_ctx_t const *mctx)
Definition rlm_rest.c:1313
eap_aka_sim_process_conf_t * inst
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition strlcpy.c:34
int talloc_link_ctx(TALLOC_CTX *parent, TALLOC_CTX *child)
Link two different parent and child contexts, so the child is freed before the parent.
Definition talloc.c:167
uintptr_t fr_value_box_safe_for_t
Escaping that's been applied to a value box.
Definition value.h:155