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: 0638a97c8f5b167bd53d2d122725762ca6bd2e20 $
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: 0638a97c8f5b167bd53d2d122725762ca6bd2e20 $")
25
26#include <freeradius-devel/server/base.h>
27#include <freeradius-devel/server/module_rlm.h>
28#include <freeradius-devel/util/debug.h>
29#include <freeradius-devel/unlang/xlat_func.h>
30
31/** Return a VP from the specified request.
32 *
33 * @param out where to write the pointer to the resolved VP. Will be NULL if the attribute couldn't
34 * be resolved.
35 * @param request current request.
36 * @param name attribute name including qualifiers.
37 * @return
38 * - -4 if either the attribute or qualifier were invalid.
39 * - The same error codes as #tmpl_find_vp for other error conditions.
40 */
41static int xlat_fmt_get_vp(fr_pair_t **out, request_t *request, char const *name)
42{
43 int ret;
44 tmpl_t *vpt;
45
46 *out = NULL;
47
48 if (tmpl_afrom_attr_str(request, NULL, &vpt, name,
49 &(tmpl_rules_t){
50 .attr = {
51 .dict_def = request->local_dict,
52 .list_def = request_attr_request,
53 }
54 }) <= 0) return -4;
55
56 ret = tmpl_find_vp(out, request, vpt);
58
59 return ret;
60}
61
62
64 { .required = true, .single = true, .type = FR_TYPE_STRING },
66};
67
68/** Xlat for %attr_by_oid(<oid>)
69 *
70 * @ingroup xlat_functions
71 */
73 UNUSED xlat_ctx_t const *xctx,
74 request_t *request, fr_value_box_list_t *in)
75{
76 fr_dict_attr_t const *parent = fr_dict_root(request->proto_dict);
77 fr_dict_attr_t const *da;
78 fr_value_box_t *attr_vb = fr_value_box_list_head(in);
80
81 fr_sbuff_t sbuff = FR_SBUFF_IN(attr_vb->vb_strvalue, attr_vb->vb_length);
83
84 if (fr_sbuff_next_if_char(&sbuff, '@')) {
85 fr_dict_t const *dict;
86
87 if (fr_dict_by_protocol_substr(NULL, &dict, &sbuff, NULL) < 0) {
88 RPEDEBUG("OID resolution failed");
89 return XLAT_ACTION_FAIL;
90 }
91 parent = fr_dict_root(dict);
92 }
93
94 (void)fr_dict_attr_by_oid_substr(&err, &da, parent, &sbuff, NULL);
95 if (err != FR_DICT_ATTR_OK) {
96 RPEDEBUG("OID resolution failed");
97 return XLAT_ACTION_FAIL;
98 }
99
100 MEM(vb = fr_value_box_alloc_null(ctx));
101
102 if (fr_value_box_bstrndup(vb, vb, NULL, da->name, strlen(da->name), false) < 0) {
103 talloc_free(vb);
104 return XLAT_ACTION_FAIL;
105 }
106
108 return XLAT_ACTION_DONE;
109}
110
112 { .required = true, .single = true, .type = FR_TYPE_STRING },
114};
115
116/** Return the vendor of an attribute reference
117 *
118 * @ingroup xlat_functions
119 */
120static xlat_action_t xlat_vendor(TALLOC_CTX *ctx, fr_dcursor_t *out,
121 UNUSED xlat_ctx_t const *xctx,
122 request_t *request, fr_value_box_list_t *in)
123{
124 fr_pair_t *vp;
125 fr_dict_vendor_t const *vendor;
126 fr_value_box_t *attr = fr_value_box_list_head(in);
127 fr_value_box_t *vb;
128
129 if ((xlat_fmt_get_vp(&vp, request, attr->vb_strvalue) < 0) || !vp) return XLAT_ACTION_FAIL;
130
131 vendor = fr_dict_vendor_by_da(vp->da);
132 if (!vendor) return XLAT_ACTION_FAIL;
133
134 MEM(vb = fr_value_box_alloc_null(ctx));
135
136 if (fr_value_box_bstrndup(vb, vb, NULL, vendor->name, strlen(vendor->name), false) < 0) {
137 talloc_free(vb);
138 return XLAT_ACTION_FAIL;
139 }
140
142 return XLAT_ACTION_DONE;
143}
144
146 { .required = true, .single = true, .type = FR_TYPE_STRING },
148};
149
150/** Return the vendor number of an attribute reference
151 *
152 * @ingroup xlat_functions
153 */
155 UNUSED xlat_ctx_t const *xctx,
156 request_t *request, fr_value_box_list_t *in)
157{
158 fr_pair_t *vp;
159 fr_value_box_t *attr = fr_value_box_list_head(in);
160 fr_value_box_t *vb;
161
162 if ((xlat_fmt_get_vp(&vp, request, attr->vb_strvalue) < 0) || !vp) return XLAT_ACTION_FAIL;
163
164 MEM(vb = fr_value_box_alloc_null(ctx));
165 fr_value_box_uint32(vb, NULL, fr_dict_vendor_num_by_da(vp->da), false);
167 return XLAT_ACTION_DONE;
168}
169
171 { .required = true, .single = true, .type = FR_TYPE_STRING },
173};
174
175/** Return the attribute name of an attribute reference
176 *
177 * @ingroup xlat_functions
178 */
179static xlat_action_t xlat_attr(TALLOC_CTX *ctx, fr_dcursor_t *out,
180 UNUSED xlat_ctx_t const *xctx,
181 request_t *request, fr_value_box_list_t *in)
182{
183 fr_pair_t *vp;
184 fr_value_box_t *attr = fr_value_box_list_head(in);
185 fr_value_box_t *vb;
186
187 if ((xlat_fmt_get_vp(&vp, request, attr->vb_strvalue) < 0) || !vp) return XLAT_ACTION_FAIL;
188
189 MEM(vb = fr_value_box_alloc_null(ctx));
190
191 if (fr_value_box_bstrndup(vb, vb, NULL, vp->da->name, strlen(vp->da->name), false) < 0) {
192 talloc_free(vb);
193 return XLAT_ACTION_FAIL;
194 }
195
197 return XLAT_ACTION_DONE;
198}
199
201 { .required = true, .single = true, .type = FR_TYPE_STRING },
203};
204
205/** Return the attribute number of an attribute reference
206 *
207 * @ingroup xlat_functions
208 */
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 fr_value_box_uint32(vb, NULL, vp->da->attr, false);
223 return XLAT_ACTION_DONE;
224}
225
227 { .required = true, .single = true, .type = FR_TYPE_STRING },
229};
230
231/** Return the attribute number of an attribute reference
232 *
233 * @ingroup xlat_functions
234 */
236 UNUSED xlat_ctx_t const *xctx,
237 request_t *request, fr_value_box_list_t *in)
238{
239 fr_pair_t *vp;
240 fr_value_box_t *attr = fr_value_box_list_head(in);
241 fr_value_box_t *vb;
242 fr_sbuff_t *oid_buff;
243
244 FR_SBUFF_TALLOC_THREAD_LOCAL(&oid_buff, 50, SIZE_MAX);
245
246 if ((xlat_fmt_get_vp(&vp, request, attr->vb_strvalue) < 0) || !vp) return XLAT_ACTION_FAIL;
247
248 MEM(vb = fr_value_box_alloc_null(ctx));
249
250 /*
251 * Print to an extendable buffer, so we don't have to worry
252 * about the size of the OID.
253 */
254 if (fr_dict_attr_oid_print(oid_buff, NULL, vp->da, true) < 0) {
255 RPEDEBUG("Printing OID for '%s' failed", vp->da->name);
256 return XLAT_ACTION_FAIL;
257 }
258
259 MEM(fr_value_box_strdup(vb, vb, NULL, fr_sbuff_start(oid_buff), false) >= 0);
261
262 return XLAT_ACTION_DONE;
263}
264
265/** Return the data type of an attribute reference
266 *
267 * @ingroup xlat_functions
268 */
270 UNUSED xlat_ctx_t const *xctx,
271 request_t *request, fr_value_box_list_t *in)
272{
273 fr_pair_t *vp;
274 fr_value_box_t *attr = fr_value_box_list_head(in);
275 fr_value_box_t *vb;
276
277 if ((xlat_fmt_get_vp(&vp, request, attr->vb_strvalue) < 0) || !vp) return XLAT_ACTION_FAIL;
278
279 MEM(vb = fr_value_box_alloc_null(ctx));
280
281 fr_value_box_strdup(vb, vb, vp->da, fr_type_to_str(vp->vp_type), false);
283 return XLAT_ACTION_DONE;
284}
285
286#define XLAT_REGISTER(_name, _func, _type, _args) \
287if (unlikely(!(xlat = xlat_func_register(NULL, _name, _func, _type)))) return -1; \
288xlat_func_args_set(xlat, _args)
289
303
304static void mod_unload(void)
305{
306 xlat_func_unregister("dict.attr.by_oid");
307 xlat_func_unregister("dict.vendor");
308 xlat_func_unregister("dict.vendor.num");
309 xlat_func_unregister("dict.attr");
310 xlat_func_unregister("dict.attr.num");
311 xlat_func_unregister("dict.attr.oid");
312 xlat_func_unregister("dict.attr.type");
313}
314
317 .common = {
318 .magic = MODULE_MAGIC_INIT,
319 .name = "dict",
320 .onload = mod_load,
321 .unload = mod_unload
322 }
323};
#define RCSID(id)
Definition build.h:506
#define UNUSED
Definition build.h:336
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:46
char const * name
Vendor name.
Definition dict.h:274
static fr_slen_t err
Definition dict.h:882
fr_slen_t fr_dict_attr_by_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_attr_t const *parent, fr_sbuff_t *in, fr_sbuff_term_t const *tt))
Resolve an attribute using an OID string.
Definition dict_util.c:2589
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2665
fr_slen_t fr_dict_by_protocol_substr(fr_dict_attr_err_t *err, fr_dict_t const **out, fr_sbuff_t *name, fr_dict_t const *dict_def)
Look up a protocol name embedded in another string.
Definition dict_util.c:2762
fr_dict_attr_err_t
Errors returned by attribute lookup functions.
Definition dict.h:317
@ FR_DICT_ATTR_OK
No error.
Definition dict.h:318
static fr_slen_t in
Definition dict.h:882
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:2900
Private enterprise.
Definition dict.h:269
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:176
#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:209
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:179
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:235
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:269
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:72
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:154
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:120
talloc_free(hp)
#define RPEDEBUG(fmt,...)
Definition log.h:388
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
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
fr_dict_attr_t const * request_attr_request
Definition request.c:43
static xlat_arg_parser_t const xlat_attr_oid_args[]
Definition rlm_dict.c:226
static xlat_arg_parser_t const xlat_vendor_num_args[]
Definition rlm_dict.c:145
static int mod_load(void)
Definition rlm_dict.c:290
static xlat_arg_parser_t const xlat_attr_num_args[]
Definition rlm_dict.c:200
static xlat_arg_parser_t const xlat_vendor_args[]
Definition rlm_dict.c:111
static xlat_arg_parser_t const xlat_attr_args[]
Definition rlm_dict.c:170
static xlat_arg_parser_t const xlat_dict_attr_by_oid_args[]
Definition rlm_dict.c:63
#define XLAT_REGISTER(_name, _func, _type, _args)
Definition rlm_dict.c:286
static void mod_unload(void)
Definition rlm_dict.c:304
module_rlm_t rlm_dict
Definition rlm_dict.c:316
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:41
static char const * name
bool fr_sbuff_next_if_char(fr_sbuff_t *sbuff, char c)
Return true if the current char matches, and if it does, advance.
Definition sbuff.c:2128
#define fr_sbuff_start(_sbuff_or_marker)
#define FR_SBUFF_IN(_start, _len_or_end)
#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:776
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.
static fr_slen_t vpt
Definition tmpl.h:1269
Optional arguments passed to vp_tmpl functions.
Definition tmpl.h:336
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
unsigned int required
Argument must be present, and non-empty.
Definition xlat.h:146
#define XLAT_ARG_PARSER_TERMINATOR
Definition xlat.h:170
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 consumed by an xlat function.
Definition xlat.h:145
static fr_slen_t parent
Definition pair.h:858
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
Definition types.h:454
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:4604
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:4823
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
Definition value.h:655
static size_t char ** out
Definition value.h:1030
An xlat calling ctx.
Definition xlat_ctx.h:49
void xlat_func_unregister(char const *name)
Unregister an xlat function.
Definition xlat_func.c:516