The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 3452d679c08ed0c180c7969b1ff2f00a7b960e86 $
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 
27 
28 RCSID("$Id: 3452d679c08ed0c180c7969b1ff2f00a7b960e86 $")
29 
30 #include <freeradius-devel/server/base.h>
31 #include <freeradius-devel/server/map_proc_priv.h>
32 #include <freeradius-devel/util/debug.h>
33 #include <freeradius-devel/util/value.h>
34 
35 static fr_rb_tree_t *map_proc_root = NULL;
36 
37 /** Compare two map_proc_t structs, based ONLY on the name
38  *
39  * @param[in] one First map struct.
40  * @param[in] two Second map struct.
41  * @return Integer specifying order of map func instances.
42  */
43 static int8_t map_proc_cmp(void const *one, void const *two)
44 {
45  map_proc_t const *a = one, *b = two;
46 
47  MEMCMP_RETURN(a, b, name, length);
48  return 0;
49 }
50 
51 /** Unregister a map processor
52  *
53  * @param[in] proc to unregister.
54  */
56 {
57  map_proc_t find;
58  map_proc_t *found;
59 
60  if (!map_proc_root) return 0;
61 
62  strlcpy(find.name, proc->name, sizeof(find.name));
63  find.length = strlen(find.name);
64 
65  found = fr_rb_find(map_proc_root, &find);
66  if (!found) return 0;
67 
69 
70  return 0;
71 }
72 
73 static void _map_proc_tree_free(void *proc)
74 {
75  talloc_free(proc);
76 }
77 
78 /** Find a map processor by name
79  *
80  * @param[in] name of map processor.
81  * @return
82  * - #map_proc matching name.
83  * - NULL if none was found.
84  */
86 {
87  map_proc_t find;
88 
89  if (!map_proc_root) return NULL;
90 
91  strlcpy(find.name, name, sizeof(find.name));
92  find.length = strlen(find.name);
93 
94  return fr_rb_find(map_proc_root, &find);
95 }
96 
97 /** Register a map processor
98  *
99  * This should be called by every module that provides a map processing function.
100  *
101  * @param[in] mod_inst of module registering the map_proc.
102  * @param[in] name of map processor. If processor already exists, it is replaced.
103  * @param[in] evaluate Module's map processor function.
104  * @param[in] instantiate function (optional).
105  * @param[in] inst_size of talloc chunk to allocate for instance data (optional).
106  * @param[in] literals_safe_for What safe_for value to assign to literals.
107  * @return
108  * - 0 on success.
109  * - -1 on failure.
110  */
111 int map_proc_register(void *mod_inst, char const *name,
112  map_proc_func_t evaluate,
113  map_proc_instantiate_t instantiate, size_t inst_size, fr_value_box_safe_for_t literals_safe_for)
114 {
115  map_proc_t *proc;
116 
117  fr_assert(name && name[0]);
118 
119  if (!map_proc_root) {
122  if (!map_proc_root) {
123  DEBUG("map_proc: Failed to create tree");
124  return -1;
125  }
126  }
127 
128  /*
129  * If it already exists, replace it.
130  */
131  proc = map_proc_find(name);
132  if (!proc) {
133  proc = talloc_zero(mod_inst, map_proc_t);
134  strlcpy(proc->name, name, sizeof(proc->name));
135  proc->length = strlen(proc->name);
136 
137  if (fr_rb_replace(NULL, map_proc_root, proc) < 0) {
138  talloc_free(proc);
139  return -1;
140  }
141 
142  talloc_set_destructor(proc, _map_proc_talloc_free);
143  }
144 
145  DEBUG3("map_proc_register: %s", proc->name);
146 
147  proc->mod_inst = mod_inst;
148  proc->evaluate = evaluate;
149  proc->instantiate = instantiate;
150  proc->inst_size = inst_size;
151  proc->literals_safe_for = literals_safe_for;
152 
153  return 0;
154 }
155 
156 /** Create a new map proc instance
157  *
158  * This should be called for every map {} section in the configuration.
159  *
160  * @param[in] ctx to allocate proc instance in.
161  * @param[in] proc resolved with #map_proc_find.
162  * @param[in] cs #CONF_SECTION representing this instance of a map processor.
163  * @param[in] src template.
164  * @param[in] maps Head of the list of maps.
165  * @return
166  * - New #map_proc_inst_t on success.
167  * - NULL on error.
168  */
169 map_proc_inst_t *map_proc_instantiate(TALLOC_CTX *ctx, map_proc_t const *proc,
170  CONF_SECTION *cs, tmpl_t const *src, map_list_t const *maps)
171 {
173 
174  inst = talloc_zero(ctx, map_proc_inst_t);
175  inst->proc = proc;
176  inst->src = src;
177  inst->maps = maps;
178 
179  if (proc->instantiate) {
180  if (proc->inst_size > 0) {
181  inst->data = talloc_zero_array(inst, uint8_t, proc->inst_size);
182  if (!inst->data) return NULL;
183  }
184 
185  if (proc->instantiate(cs, proc->mod_inst, inst->data, src, maps) < 0) {
186  talloc_free(inst);
187  return NULL;
188  }
189  }
190 
191  return inst;
192 }
193 
194 /** Evaluate a set of maps using the specified map processor
195  *
196  * Evaluate the map processor src template, then call a map processor function to do
197  * something with the expanded src template and map the result to attributes in the request.
198  *
199  * @param[out] p_result Result code of evaluating the map.
200  * @param[in] request The current request.
201  * @param[in] inst of a map processor.
202  * @param[in,out] result Result of expanding the map input. May be consumed
203  * by the map processor.
204  * @return one of UNLANG_ACTION_*
205  */
206 unlang_action_t map_proc(rlm_rcode_t *p_result, request_t *request, map_proc_inst_t const *inst, fr_value_box_list_t *result)
207 {
208  return inst->proc->evaluate(p_result, inst->proc->mod_inst, inst->data, request, result, inst->maps);
209 }
210 
211 /** Free all map_processors unregistering them
212  *
213  */
214 void map_proc_free(void)
215 {
217 
218  map_proc_root = NULL;
219  talloc_free(mpr);
220 }
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:444
#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:154
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:89
#define DEBUG(fmt,...)
Definition: dhcpclient.c:39
#define DEBUG3(_fmt,...)
Definition: log.h:266
talloc_free(reap)
int map_proc_register(void *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:111
unlang_action_t map_proc(rlm_rcode_t *p_result, request_t *request, map_proc_inst_t const *inst, fr_value_box_list_t *result)
Evaluate a set of maps using the specified map processor.
Definition: map_proc.c:206
map_proc_t * map_proc_find(char const *name)
Find a map processor by name.
Definition: map_proc.c:85
static void _map_proc_tree_free(void *proc)
Definition: map_proc.c:73
static int _map_proc_talloc_free(map_proc_t *proc)
Unregister a map processor.
Definition: map_proc.c:55
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:169
void map_proc_free(void)
Free all map_processors unregistering them.
Definition: map_proc.c:214
static fr_rb_tree_t * map_proc_root
Definition: map_proc.c:35
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:43
unlang_action_t(* map_proc_func_t)(rlm_rcode_t *p_result, void *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
int(* map_proc_instantiate_t)(CONF_SECTION *cs, void *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
char name[FR_MAX_STRING_LEN]
Name of the map function.
Definition: map_proc_priv.h:42
int length
Length of name.
Definition: map_proc_priv.h:43
fr_value_box_safe_for_t literals_safe_for
Safe for values to be set for literals in the map source.
Definition: map_proc_priv.h:48
size_t inst_size
Size of map_proc instance data to allocate.
Definition: map_proc_priv.h:47
map_proc_func_t evaluate
Module's map processor function.
Definition: map_proc_priv.h:45
void * mod_inst
Module instance.
Definition: map_proc_priv.h:41
map_proc_instantiate_t instantiate
Callback to create new instance struct.
Definition: map_proc_priv.h:46
Map processor registration.
Definition: map_proc_priv.h:39
Map processor instance.
Definition: map_proc_priv.h:53
unsigned char uint8_t
Definition: merged_model.c:30
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:644
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:736
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:576
#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:1312
fr_assert(0)
eap_aka_sim_process_conf_t * inst
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition: strlcpy.c:34
uintptr_t fr_value_box_safe_for_t
Escaping that's been applied to a value box.
Definition: value.h:155