The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_dict.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: f95cedb1e85d180651987a4ffa161e87b4b2de04 $
19 * @file rlm_dict.c
20 * @brief Retrieve attributes from a dict.
21 *
22 * @copyright 2016 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
23 */
24RCSID("$Id: f95cedb1e85d180651987a4ffa161e87b4b2de04 $")
25
26#include <freeradius-devel/server/base.h>
27#include <freeradius-devel/server/module_rlm.h>
28#include <freeradius-devel/server/log.h>
29#include <freeradius-devel/util/debug.h>
30#include <freeradius-devel/util/sbuff.h>
31#include <freeradius-devel/util/value.h>
32#include <freeradius-devel/unlang/xlat.h>
33#include <freeradius-devel/unlang/xlat_func.h>
34
35/** Return a VP from the specified request.
36 *
37 * @param out where to write the pointer to the resolved VP. Will be NULL if the attribute couldn't
38 * be resolved.
39 * @param request current request.
40 * @param name attribute name including qualifiers.
41 * @return
42 * - -4 if either the attribute or qualifier were invalid.
43 * - The same error codes as #tmpl_find_vp for other error conditions.
44 */
45static int xlat_fmt_get_vp(fr_pair_t **out, request_t *request, char const *name)
46{
47 int ret;
48 tmpl_t *vpt;
49
50 *out = NULL;
51
52 if (tmpl_afrom_attr_str(request, NULL, &vpt, name,
53 &(tmpl_rules_t){
54 .attr = {
55 .dict_def = request->dict,
56 .list_def = request_attr_request,
58 }
59 }) <= 0) return -4;
60
61 ret = tmpl_find_vp(out, request, vpt);
63
64 return ret;
65}
66
67
69 { .required = true, .single = true, .type = FR_TYPE_UINT32 },
71};
72
73/** Xlat for %attr_by_num(<number>)
74 *
75 * @ingroup xlat_functions
76 */
78 UNUSED xlat_ctx_t const *xctx,
79 request_t *request, fr_value_box_list_t *in)
80{
81 fr_dict_attr_t const *da;
82 fr_value_box_t *attr = fr_value_box_list_head(in);
84
85 da = fr_dict_attr_child_by_num(fr_dict_root(request->dict), attr->vb_uint32);
86 if (!da) {
87 REDEBUG("No attribute found with number %pV", attr);
88 return XLAT_ACTION_FAIL;
89 }
90
92
93 if (fr_value_box_bstrndup(vb, vb, NULL, da->name, strlen(da->name), false) < 0) {
94 talloc_free(vb);
95 return XLAT_ACTION_FAIL;
96 }
97
99 return XLAT_ACTION_DONE;
100}
101
103 { .required = true, .single = true, .type = FR_TYPE_STRING },
105};
106
107/** Xlat for %attr_by_oid(<oid>)
108 *
109 * @ingroup xlat_functions
110 */
112 UNUSED xlat_ctx_t const *xctx,
113 request_t *request, fr_value_box_list_t *in)
114{
115 unsigned int attr = 0;
116 fr_dict_attr_t const *parent = fr_dict_root(request->dict);
117 fr_dict_attr_t const *da;
118 ssize_t ret;
119 fr_value_box_t *attr_vb = fr_value_box_list_head(in);
120 fr_value_box_t *vb;
121
122 ret = fr_dict_attr_by_oid_legacy(fr_dict_internal(), &parent, &attr, attr_vb->vb_strvalue);
123 if (ret <= 0) {
124 REMARKER(attr_vb->vb_strvalue, -(ret), "%s", fr_strerror());
125 return XLAT_ACTION_FAIL;
126 }
127
129
130 MEM(vb = fr_value_box_alloc_null(ctx));
131
132 if (fr_value_box_bstrndup(vb, vb, NULL, da->name, strlen(da->name), false) < 0) {
133 talloc_free(vb);
134 return XLAT_ACTION_FAIL;
135 }
136
138 return XLAT_ACTION_DONE;
139}
140
142 { .required = true, .single = true, .type = FR_TYPE_STRING },
144};
145
146/** Return the vendor of an attribute reference
147 *
148 * @ingroup xlat_functions
149 */
150static xlat_action_t xlat_vendor(TALLOC_CTX *ctx, fr_dcursor_t *out,
151 UNUSED xlat_ctx_t const *xctx,
152 request_t *request, fr_value_box_list_t *in)
153{
154 fr_pair_t *vp;
155 fr_dict_vendor_t const *vendor;
156 fr_value_box_t *attr = fr_value_box_list_head(in);
157 fr_value_box_t *vb;
158
159 if ((xlat_fmt_get_vp(&vp, request, attr->vb_strvalue) < 0) || !vp) return XLAT_ACTION_FAIL;
160
161 vendor = fr_dict_vendor_by_da(vp->da);
162 if (!vendor) return XLAT_ACTION_FAIL;
163
164 MEM(vb = fr_value_box_alloc_null(ctx));
165
166 if (fr_value_box_bstrndup(vb, vb, NULL, vendor->name, strlen(vendor->name), false) < 0) {
167 talloc_free(vb);
168 return XLAT_ACTION_FAIL;
169 }
170
172 return XLAT_ACTION_DONE;
173}
174
176 { .required = true, .single = true, .type = FR_TYPE_STRING },
178};
179
180/** Return the vendor number of an attribute reference
181 *
182 * @ingroup xlat_functions
183 */
185 UNUSED xlat_ctx_t const *xctx,
186 request_t *request, fr_value_box_list_t *in)
187{
188 fr_pair_t *vp;
189 fr_value_box_t *attr = fr_value_box_list_head(in);
190 fr_value_box_t *vb;
191
192 if ((xlat_fmt_get_vp(&vp, request, attr->vb_strvalue) < 0) || !vp) return XLAT_ACTION_FAIL;
193
194 MEM(vb = fr_value_box_alloc_null(ctx));
195 fr_value_box_uint32(vb, NULL, fr_dict_vendor_num_by_da(vp->da), false);
197 return XLAT_ACTION_DONE;
198}
199
201 { .required = true, .single = true, .type = FR_TYPE_STRING },
203};
204
205/** Return the attribute name of an attribute reference
206 *
207 * @ingroup xlat_functions
208 */
209static xlat_action_t xlat_attr(TALLOC_CTX *ctx, fr_dcursor_t *out,
210 UNUSED xlat_ctx_t const *xctx,
211 request_t *request, fr_value_box_list_t *in)
212{
213 fr_pair_t *vp;
214 fr_value_box_t *attr = fr_value_box_list_head(in);
215 fr_value_box_t *vb;
216
217 if ((xlat_fmt_get_vp(&vp, request, attr->vb_strvalue) < 0) || !vp) return XLAT_ACTION_FAIL;
218
219 MEM(vb = fr_value_box_alloc_null(ctx));
220
221 if (fr_value_box_bstrndup(vb, vb, NULL, vp->da->name, strlen(vp->da->name), false) < 0) {
222 talloc_free(vb);
223 return XLAT_ACTION_FAIL;
224 }
225
227 return XLAT_ACTION_DONE;
228}
229
231 { .required = true, .single = true, .type = FR_TYPE_STRING },
233};
234
235/** Return the attribute number of an attribute reference
236 *
237 * @ingroup xlat_functions
238 */
240 UNUSED xlat_ctx_t const *xctx,
241 request_t *request, fr_value_box_list_t *in)
242{
243 fr_pair_t *vp;
244 fr_value_box_t *attr = fr_value_box_list_head(in);
245 fr_value_box_t *vb;
246
247 if ((xlat_fmt_get_vp(&vp, request, attr->vb_strvalue) < 0) || !vp) return XLAT_ACTION_FAIL;
248
249 MEM(vb = fr_value_box_alloc_null(ctx));
250
251 fr_value_box_uint32(vb, NULL, vp->da->attr, false);
253 return XLAT_ACTION_DONE;
254}
255
257 { .required = true, .single = true, .type = FR_TYPE_STRING },
259};
260
261/** Return the attribute number of an attribute reference
262 *
263 * @ingroup xlat_functions
264 */
266 UNUSED xlat_ctx_t const *xctx,
267 request_t *request, fr_value_box_list_t *in)
268{
269 fr_pair_t *vp;
270 fr_value_box_t *attr = fr_value_box_list_head(in);
271 fr_value_box_t *vb;
272 fr_sbuff_t *oid_buff;
273
274 FR_SBUFF_TALLOC_THREAD_LOCAL(&oid_buff, 50, SIZE_MAX);
275
276 if ((xlat_fmt_get_vp(&vp, request, attr->vb_strvalue) < 0) || !vp) return XLAT_ACTION_FAIL;
277
278 MEM(vb = fr_value_box_alloc_null(ctx));
279
280 /*
281 * Print to an extendable buffer, so we don't have to worry
282 * about the size of the OID.
283 */
284 if (fr_dict_attr_oid_print(oid_buff, NULL, vp->da, true) < 0) {
285 RPEDEBUG("Printing OID for '%s' failed", vp->da->name);
286 return XLAT_ACTION_FAIL;
287 }
288
289 fr_value_box_strdup(vb, vb, NULL, fr_sbuff_start(oid_buff), false);
291
292 return XLAT_ACTION_DONE;
293}
294
295/** Return the data type of an attribute reference
296 *
297 * @ingroup xlat_functions
298 */
300 UNUSED xlat_ctx_t const *xctx,
301 request_t *request, fr_value_box_list_t *in)
302{
303 fr_pair_t *vp;
304 fr_value_box_t *attr = fr_value_box_list_head(in);
305 fr_value_box_t *vb;
306
307 if ((xlat_fmt_get_vp(&vp, request, attr->vb_strvalue) < 0) || !vp) return XLAT_ACTION_FAIL;
308
309 MEM(vb = fr_value_box_alloc_null(ctx));
310
311 fr_value_box_strdup(vb, vb, vp->da, fr_type_to_str(vp->vp_type), false);
313 return XLAT_ACTION_DONE;
314}
315
316#define XLAT_REGISTER(_name, _func, _type, _args) \
317if (unlikely(!(xlat = xlat_func_register(NULL, _name, _func, _type)))) return -1; \
318xlat_func_args_set(xlat, _args)
319
334
335static void mod_unload(void)
336{
337 xlat_func_unregister("dict.attr.by_num");
338 xlat_func_unregister("dict.attr.by_oid");
339 xlat_func_unregister("dict.vendor");
340 xlat_func_unregister("dict.vendor.num");
341 xlat_func_unregister("dict.attr");
342 xlat_func_unregister("dict.attr.num");
343 xlat_func_unregister("dict.attr.oid");
344 xlat_func_unregister("dict.attr.type");
345}
346
349 .common = {
350 .magic = MODULE_MAGIC_INIT,
351 .name = "dict",
352 .onload = mod_load,
353 .unload = mod_unload
354 }
355};
#define RCSID(id)
Definition build.h:483
#define UNUSED
Definition build.h:315
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
#define MEM(x)
Definition debug.h:36
char const * name
Vendor name.
Definition dict.h:250
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2400
fr_slen_t fr_dict_attr_by_oid_legacy(fr_dict_t const *dict, fr_dict_attr_t const **parent, unsigned int *attr, char const *oid)
Get the leaf attribute of an OID string.
Definition dict_util.c:2125
fr_dict_t const * fr_dict_internal(void)
Definition dict_util.c:4610
fr_dict_attr_t const * fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr)
Check if a child attribute exists in a parent using an attribute number.
Definition dict_util.c:3328
static fr_slen_t in
Definition dict.h:824
fr_dict_vendor_t const * fr_dict_vendor_by_da(fr_dict_attr_t const *da)
Look up a vendor by one of its child attributes.
Definition dict_util.c:2635
Private enterprise.
Definition dict.h:245
static uint32_t fr_dict_vendor_num_by_da(fr_dict_attr_t const *da)
Return the vendor number for an attribute.
Definition dict_ext.h:212
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
static xlat_action_t xlat_attr_num(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Return the attribute number of an attribute reference.
Definition rlm_dict.c:239
static xlat_action_t xlat_dict_attr_by_num(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Xlat for attr_by_num(<number>)
Definition rlm_dict.c:77
static xlat_action_t xlat_attr(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Return the attribute name of an attribute reference.
Definition rlm_dict.c:209
static xlat_action_t xlat_attr_oid(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Return the attribute number of an attribute reference.
Definition rlm_dict.c:265
static xlat_action_t xlat_attr_type(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Return the data type of an attribute reference.
Definition rlm_dict.c:299
static xlat_action_t xlat_dict_attr_by_oid(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Xlat for attr_by_oid(<oid>)
Definition rlm_dict.c:111
static xlat_action_t xlat_vendor_num(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Return the vendor number of an attribute reference.
Definition rlm_dict.c:184
static xlat_action_t xlat_vendor(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Return the vendor of an attribute reference.
Definition rlm_dict.c:150
#define REMARKER(_str, _marker_idx, _marker,...)
Output string with error marker, showing where format error occurred.
Definition log.h:498
#define RPEDEBUG(fmt,...)
Definition log.h:376
talloc_free(reap)
@ TMPL_ATTR_REF_PREFIX_AUTO
Attribute refs may have a '&' prefix.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
long int ssize_t
ssize_t fr_dict_attr_oid_print(fr_sbuff_t *out, fr_dict_attr_t const *ancestor, fr_dict_attr_t const *da, bool numeric)
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
#define REDEBUG(fmt,...)
Definition radclient.h:52
fr_dict_attr_t const * request_attr_request
Definition request.c:45
static xlat_arg_parser_t const xlat_attr_oid_args[]
Definition rlm_dict.c:256
static xlat_arg_parser_t const xlat_vendor_num_args[]
Definition rlm_dict.c:175
static int mod_load(void)
Definition rlm_dict.c:320
static xlat_arg_parser_t const xlat_attr_num_args[]
Definition rlm_dict.c:230
static xlat_arg_parser_t const xlat_vendor_args[]
Definition rlm_dict.c:141
static xlat_arg_parser_t const xlat_attr_args[]
Definition rlm_dict.c:200
static xlat_arg_parser_t const xlat_dict_attr_by_oid_args[]
Definition rlm_dict.c:102
#define XLAT_REGISTER(_name, _func, _type, _args)
Definition rlm_dict.c:316
static void mod_unload(void)
Definition rlm_dict.c:335
static xlat_arg_parser_t const xlat_dict_attr_by_num_args[]
Definition rlm_dict.c:68
module_rlm_t rlm_dict
Definition rlm_dict.c:348
static int xlat_fmt_get_vp(fr_pair_t **out, request_t *request, char const *name)
Return a VP from the specified request.
Definition rlm_dict.c:45
static char const * name
#define fr_sbuff_start(_sbuff_or_marker)
#define FR_SBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max)
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
static fr_slen_t vpt
Definition tmpl.h:1272
ssize_t tmpl_afrom_attr_str(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t **out, char const *name, tmpl_rules_t const *rules))
Parse a string into a TMPL_TYPE_ATTR_* type tmpl_t.
Optional arguments passed to vp_tmpl functions.
Definition tmpl.h:341
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
Definition pair.h:69
bool required
Argument must be present, and non-empty.
Definition xlat.h:148
#define XLAT_ARG_PARSER_TERMINATOR
Definition xlat.h:168
xlat_action_t
Definition xlat.h:37
@ XLAT_ACTION_FAIL
An xlat function failed.
Definition xlat.h:44
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition xlat.h:43
Definition for a single argument consumend by an xlat function.
Definition xlat.h:147
static fr_slen_t parent
Definition pair.h:851
char const * fr_strerror(void)
Get the last library error.
Definition strerror.c:554
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
Definition types.h:433
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 fr_value_box_bstrndup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Copy a string to to a fr_value_box_t.
Definition value.c:4148
#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
An xlat calling ctx.
Definition xlat_ctx.h:49
void xlat_func_unregister(char const *name)
Unregister an xlat function.
Definition xlat_func.c:519