The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_detail.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 (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: e941b1066c2698df44e0ecde88a76d9aa8e567aa $
19 * @file rlm_detail.c
20 * @brief Write plaintext versions of packets to flatfiles.
21 *
22 * @copyright 2000,2006 The FreeRADIUS server project
23 */
24RCSID("$Id: e941b1066c2698df44e0ecde88a76d9aa8e567aa $")
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/util/perm.h>
30
31#include <fcntl.h>
32
33#ifdef HAVE_UNISTD_H
34#endif
35
36#ifdef HAVE_GRP_H
37#endif
38
39/** Instance configuration for rlm_detail
40 *
41 * Holds the configuration and preparsed data for a instance of rlm_detail.
42 */
43typedef struct {
44 mode_t perm; //!< Permissions to use for new files.
45 gid_t group; //!< Resolved group.
46 bool group_is_set; //!< Whether group was set.
47
48 bool locking; //!< Whether the file should be locked.
49
50 bool log_srcdst; //!< Add IP src/dst attributes to entries.
51
52 bool escape; //!< do filename escaping, yes / no
53
54 exfile_t *ef; //!< Log file handler
55
56 bool triggers; //!< Do we run triggers.
58
59typedef struct {
60 fr_value_box_t filename; //!< File / path to write to.
61 tmpl_t *filename_tmpl; //!< tmpl used to expand filename (for debug output)
62 fr_value_box_t header; //!< Header format
63 fr_hash_table_t *ht; //!< Holds suppressed attributes.
65
66/*
67 * @todo - put this into common function in cf_parse.c ?
68 */
69
70static const conf_parser_t module_config[] = {
71 { FR_CONF_OFFSET("permissions", rlm_detail_t, perm), .dflt = "0600", .func = cf_parse_permissions },
72 { FR_CONF_OFFSET_IS_SET("group", FR_TYPE_VOID, 0, rlm_detail_t, group), .func = cf_parse_gid },
73 { FR_CONF_OFFSET("locking", rlm_detail_t, locking), .dflt = "no" },
74 { FR_CONF_OFFSET("escape_filenames", rlm_detail_t, escape), .dflt = "no" },
75 { FR_CONF_OFFSET("log_packet_header", rlm_detail_t, log_srcdst), .dflt = "no" },
76 { FR_CONF_OFFSET("triggers", rlm_detail_t, triggers) },
78};
79
81static fr_dict_t const *dict_radius;
82
85 { .out = &dict_freeradius, .proto = "freeradius" },
86 { .out = &dict_radius, .proto = "radius" },
88};
89
95
98 { .out = &attr_net, .name = "Net", .type = FR_TYPE_TLV, .dict = &dict_freeradius },
99 { .out = &attr_net_dst_address, .name = "Net.Dst.IP", .type = FR_TYPE_COMBO_IP_ADDR, .dict = &dict_freeradius },
100 { .out = &attr_net_dst_port, .name = "Net.Dst.Port", .type = FR_TYPE_UINT16, .dict = &dict_freeradius },
101 { .out = &attr_net_src_address, .name = "Net.Src.IP", .type = FR_TYPE_COMBO_IP_ADDR, .dict = &dict_freeradius },
102 { .out = &attr_net_src_port, .name = "Net.Src.Port", .type = FR_TYPE_UINT16, .dict = &dict_freeradius },
103
105};
106
107/** Print one attribute and value to FP
108 *
109 * Complete string with '\\t' and '\\n' is written to buffer before printing to
110 * avoid issues when running with multiple threads.
111 *
112 * @todo - This function should print *flattened* lists.
113 *
114 * @param fp to output to.
115 * @param vp to print.
116 * @return
117 * - >=0 on success
118 * - <0 on error
119 */
120static int CC_HINT(nonnull) fr_pair_fprint(FILE *fp, fr_pair_t const *vp)
121{
122 char buff[1024];
123 fr_sbuff_t sbuff = FR_SBUFF_OUT(buff, sizeof(buff));
124
126
127 (void) fr_sbuff_in_char(&sbuff, '\t');
128 (void) fr_pair_print(&sbuff, NULL, vp);
129 (void) fr_sbuff_in_char(&sbuff, '\n');
130
131 if (fputs(buff, fp) == EOF) return -1;
132
133 return 0;
134}
135
136
137
138static uint32_t detail_hash(void const *data)
139{
140 fr_dict_attr_t const *da = data;
141 return fr_hash(&da, sizeof(da));
142}
143
144static int8_t detail_cmp(void const *a, void const *b)
145{
146 return CMP(a, b);
147}
148
149/*
150 * (Re-)read radiusd.conf into memory.
151 */
152static int mod_instantiate(module_inst_ctx_t const *mctx)
153{
154 rlm_detail_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_detail_t);
155 CONF_SECTION *conf = mctx->mi->conf;
156
158 inst->triggers, "modules.detail", NULL);
159 if (!inst->ef) {
160 cf_log_err(conf, "Failed creating log file context");
161 return -1;
162 }
163
164 return 0;
165}
166
167/*
168 * Wrapper for VPs allocated on the stack.
169 */
170static void detail_fr_pair_fprint(TALLOC_CTX *ctx, FILE *out, fr_pair_t const *stacked)
171{
172 fr_pair_t *vp;
173
174 vp = fr_pair_copy(ctx, stacked);
175 if (unlikely(vp == NULL)) return;
176
177 vp->op = T_OP_EQ;
178 (void) fr_pair_fprint(out, vp);
180}
181
182
184{
185 fr_pair_list_foreach(list, vp) {
186 if (ht && fr_hash_table_find(ht, vp->da)) continue;
187
188 if (fr_type_is_leaf(vp->vp_type)) {
189 if (fr_pair_fprint(out, vp) < 0) return -1;
190 continue;
191 }
192
194
195 if (detail_recurse(out, ht, &vp->vp_group) < 0) return -1;
196 }
197
198 return 0;
199}
200
201/** Write a single detail entry to file pointer
202 *
203 * @param[in] out Where to write entry.
204 * @param[in] inst Instance of rlm_detail.
205 * @param[in] request The current request.
206 * @param[in] header To print above packet
207 * @param[in] packet associated with the request (request, reply...).
208 * @param[in] list of pairs to write.
209 * @param[in] ht Hash table containing attributes to be suppressed in the output.
210 */
211static int detail_write(FILE *out, rlm_detail_t const *inst, request_t *request, fr_value_box_t *header,
212 fr_packet_t *packet, fr_pair_list_t *list, fr_hash_table_t *ht)
213{
214 fr_dict_attr_t const *da;
215
216 if (fr_pair_list_empty(list)) {
217 RWDEBUG("Skipping empty packet");
218 return 0;
219 }
220
221#define WRITE(fmt, ...) do { \
222 if (fprintf(out, fmt, ## __VA_ARGS__) < 0) goto fail; \
223 } while(0)
224
225 WRITE("%s\n", header->vb_strvalue);
226
227 /*
228 * Write the Packet-Type, but only if we're not suppressing it.
229 */
230 da = fr_dict_attr_by_name(NULL, fr_dict_root(request->proto_dict), "Packet-Type");
231 if (ht && da && !fr_hash_table_find(ht, da)) {
232 char const *name = NULL;
233
235
236 /*
237 * Print out names, if they're OK.
238 * Numbers, if not.
239 */
240 if (name) {
241 WRITE("\tPacket-Type = %s\n", name);
242 } else {
243 WRITE("\tPacket-Type = %u\n", packet->code);
244 }
245 }
246
247 /*
248 * Put these at the top as distinct (not nested) VPs.
249 */
250 if (inst->log_srcdst) {
251 fr_pair_t *src_vp, *dst_vp;
252
253 src_vp = fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_net_src_address);
254 dst_vp = fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_net_dst_address);
255
256 /*
257 * These pairs will exist, but Coverity doesn't know that
258 */
259 if (src_vp) detail_fr_pair_fprint(request, out, src_vp);
260 if (dst_vp) detail_fr_pair_fprint(request, out, dst_vp);
261
262 src_vp = fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_net_src_port);
263 dst_vp = fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_net_dst_port);
264
265 if (src_vp) detail_fr_pair_fprint(request, out, src_vp);
266 if (dst_vp) detail_fr_pair_fprint(request, out, dst_vp);
267 }
268
269 /*
270 * Write each attribute/value to the log file
271 */
272 fr_pair_list_foreach(list, vp) {
273 if (ht && fr_hash_table_find(ht, vp->da)) continue;
274
275 /*
276 * Skip Net.* if we're not logging src/dst
277 */
278 if (!inst->log_srcdst && (vp->da == attr_net)) continue;
279
280 if (fr_type_is_leaf(vp->vp_type)) {
281 if (fr_pair_fprint(out, vp) < 0) {
282 fail:
283 RERROR("Failed writing to detail file: %s", fr_syserror(errno));
284 return -1;
285 }
286
287 continue;
288 }
289
291
292 if (detail_recurse(out, ht, &vp->vp_group) < 0) goto fail;
293 }
294
295 WRITE("\tTimestamp = %lu\n", (unsigned long) fr_time_to_sec(request->packet->timestamp));
296
297 WRITE("\n");
298
299 return 0;
300}
301
302/*
303 * Do detail, compatible with old accounting
304 */
305static unlang_action_t CC_HINT(nonnull) detail_do(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request,
306 fr_packet_t *packet, fr_pair_list_t *list)
307{
308 rlm_detail_env_t *env = talloc_get_type_abort(mctx->env_data, rlm_detail_env_t);
309 int outfd, dupfd;
310 FILE *outfp = NULL;
311
313
314 RDEBUG2("%s expands to %pV", env->filename_tmpl->name, &env->filename);
315
316 outfd = exfile_open(inst->ef, env->filename.vb_strvalue, inst->perm, 0, NULL);
317 if (outfd < 0) {
318 RPERROR("Couldn't open file %pV", &env->filename);
319
320 /* coverity[missing_unlock] */
322 }
323
324 if (inst->group_is_set) {
325 if (chown(env->filename.vb_strvalue, -1, inst->group) == -1) {
326 RERROR("Unable to set detail file group to '%d': %s", inst->group, fr_syserror(errno));
327 goto fail;
328 }
329 }
330
331 dupfd = dup(outfd);
332 if (dupfd < 0) {
333 RERROR("Failed to dup() file descriptor for detail file");
334 goto fail;
335 }
336
337 /*
338 * Open the output fp for buffering.
339 */
340 if ((outfp = fdopen(dupfd, "a")) == NULL) {
341 RERROR("Couldn't open file %pV: %s", &env->filename, fr_syserror(errno));
342 fail:
343 if (outfp) fclose(outfp);
344 exfile_close(inst->ef, outfd);
346 }
347
348 if (detail_write(outfp, inst, request, &env->header, packet, list, env->ht) < 0) goto fail;
349
350 /*
351 * Flush everything
352 */
353 fclose(outfp);
354 exfile_close(inst->ef, outfd);
355
356 /*
357 * And everything is fine.
358 */
360}
361
362/*
363 * Accounting - write the detail files.
364 */
365static unlang_action_t CC_HINT(nonnull) mod_accounting(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
366{
367 return detail_do(p_result, mctx, request, request->packet, &request->request_pairs);
368}
369
370/*
371 * Incoming Access Request - write the detail files.
372 */
373static unlang_action_t CC_HINT(nonnull) mod_authorize(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
374{
375 return detail_do(p_result, mctx, request, request->packet, &request->request_pairs);
376}
377
378/*
379 * Outgoing Access-Request Reply - write the detail files.
380 */
381static unlang_action_t CC_HINT(nonnull) mod_post_auth(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
382{
383 return detail_do(p_result, mctx, request, request->reply, &request->reply_pairs);
384}
385
386static int call_env_filename_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules,
387 CONF_ITEM *ci,
388 call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule)
389{
391 tmpl_t *parsed;
392 CONF_PAIR const *to_parse = cf_item_to_pair(ci);
393 tmpl_rules_t our_rules;
394
395 our_rules = *t_rules;
398 .safe_for = (inst->escape) ? (fr_value_box_safe_for_t)rad_filename_box_escape :
400 .always_escape = false,
401 };
403 our_rules.literals_safe_for = our_rules.escape.box_escape.safe_for;
404
405 if (tmpl_afrom_substr(ctx, &parsed,
408 &our_rules) < 0) return -1;
409
410 *(void **)out = parsed;
411 return 0;
412}
413
414static int call_env_suppress_parse(TALLOC_CTX *ctx, call_env_parsed_head_t *out, tmpl_rules_t const *t_rules,
415 CONF_ITEM *ci,
416 UNUSED call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule)
417{
418 CONF_SECTION const *cs = cf_item_to_section(ci);
420 call_env_parsed_t *parsed;
421 CONF_ITEM const *to_parse = NULL;
422 char const *attr;
423 fr_dict_attr_t const *da;
424 fr_hash_table_t *ht;
425
426 MEM(parsed = call_env_parsed_add(ctx, out,
428
429 ht = fr_hash_table_alloc(parsed, detail_hash, detail_cmp, NULL);
430
431 while ((to_parse = cf_item_next(cs, to_parse))) {
432 if (!cf_item_is_pair(to_parse)) continue;
433
434 attr = cf_pair_attr(cf_item_to_pair(to_parse));
435 if (!attr) continue;
436
437 da = fr_dict_attr_search_by_qualified_oid(NULL, t_rules->attr.dict_def, attr, false, false);
438 if (!da) {
439 cf_log_perr(to_parse, "Failed resolving attribute");
440 return -1;
441 }
442
443 /*
444 * Be kind to minor mistakes
445 */
446 if (fr_hash_table_find(ht, da)) {
447 cf_log_warn(to_parse, "Ignoring duplicate entry '%s'", attr);
448 continue;
449 }
450
451 if (!fr_hash_table_insert(ht, da)) {
452 cf_log_perr(to_parse, "Failed inserting '%s' into suppression table", attr);
453 return -1;
454 }
455
456 DEBUG("%s - '%s' suppressed, will not appear in detail output", cf_section_name(parent), attr);
457 }
458
459 /*
460 * Clear up if nothing is actually to be suppressed
461 */
462 if (fr_hash_table_num_elements(ht) == 0) {
463 talloc_free(ht);
464 call_env_parsed_free(out, parsed);
465 return 0;
466 }
467
469 call_env_parsed_set_data(parsed, ht);
470
471 return 0;
472}
473
485
486/* globally exported name */
489 .common = {
490 .magic = MODULE_MAGIC_INIT,
491 .name = "detail",
492 .inst_size = sizeof(rlm_detail_t),
494 .instantiate = mod_instantiate
495 },
496 .method_group = {
497 .bindings = (module_method_binding_t[]){
498 { .section = SECTION_NAME("accounting", CF_IDENT_ANY), .method = mod_accounting, .method_env = &method_env },
499 { .section = SECTION_NAME("recv", "Accounting-Request"), .method = mod_accounting, .method_env = &method_env },
500 { .section = SECTION_NAME("send", "Accounting-Response"), .method = mod_accounting, .method_env = &method_env },
501 { .section = SECTION_NAME("recv", CF_IDENT_ANY), .method = mod_authorize, .method_env = &method_env },
502 { .section = SECTION_NAME("send", CF_IDENT_ANY), .method = mod_post_auth, .method_env = &method_env },
504 }
505 }
506};
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:506
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
Definition build.h:113
#define unlikely(_x)
Definition build.h:402
#define UNUSED
Definition build.h:336
void call_env_parsed_free(call_env_parsed_head_t *parsed, call_env_parsed_t *ptr)
Remove a call_env_parsed_t from the list of parsed call envs.
Definition call_env.c:777
call_env_parsed_t * call_env_parsed_add(TALLOC_CTX *ctx, call_env_parsed_head_t *head, call_env_parser_t const *rule)
Allocate a new call_env_parsed_t structure and add it to the list of parsed call envs.
Definition call_env.c:690
void call_env_parsed_set_data(call_env_parsed_t *parsed, void const *data)
Assign data to a call_env_parsed_t.
Definition call_env.c:747
#define CALL_ENV_TERMINATOR
Definition call_env.h:236
#define FR_CALL_ENV_PARSE_OFFSET(_name, _cast_type, _flags, _struct, _field, _parse_field)
Specify a call_env_parser_t which writes out runtime results and the result of the parsing phase to t...
Definition call_env.h:365
#define FR_CALL_ENV_METHOD_OUT(_inst)
Helper macro for populating the size/type fields of a call_env_method_t from the output structure typ...
Definition call_env.h:240
call_env_parser_t const * env
Parsing rules for call method env.
Definition call_env.h:247
@ CALL_ENV_FLAG_CONCAT
If the tmpl produced multiple boxes they should be concatenated.
Definition call_env.h:76
@ CALL_ENV_FLAG_NONE
Definition call_env.h:74
@ CALL_ENV_FLAG_REQUIRED
Associated conf pair or section is required.
Definition call_env.h:75
module_instance_t const * mi
Module instance that the callenv is registered to.
Definition call_env.h:229
#define FR_CALL_ENV_SUBSECTION_FUNC(_name, _name2, _flags, _func)
Specify a call_env_parser_t which parses a subsection using a callback function.
Definition call_env.h:412
#define FR_CALL_ENV_OFFSET(_name, _cast_type, _flags, _struct, _field)
Specify a call_env_parser_t which writes out runtime results to the specified field.
Definition call_env.h:340
#define FR_CALL_ENV_PARSE_ONLY_OFFSET(_name, _cast_type, _flags, _struct, _parse_field)
Specify a call_env_parser_t which writes out the result of the parsing phase to the field specified.
Definition call_env.h:389
Per method call config.
Definition call_env.h:180
int cf_parse_gid(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
Generic function for resolving GID strings to uid_t values.
Definition cf_parse.c:1703
int cf_parse_permissions(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
Generic function for resolving permissions to a mode-t.
Definition cf_parse.c:1718
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:657
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
Definition cf_parse.h:611
#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:280
#define FR_CONF_OFFSET_IS_SET(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct,...
Definition cf_parse.h:294
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:594
Common header for all CONF_* types.
Definition cf_priv.h:49
Configuration AVP similar to a fr_pair_t.
Definition cf_priv.h:72
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
bool cf_item_is_pair(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_PAIR.
Definition cf_util.c:633
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition cf_util.c:685
char const * cf_section_name(CONF_SECTION const *cs)
Return name2 if set, else name1.
Definition cf_util.c:1199
fr_token_t cf_pair_value_quote(CONF_PAIR const *pair)
Return the value (rhs) quoting of a pair.
Definition cf_util.c:1625
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition cf_util.c:665
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition cf_util.c:1581
char const * cf_pair_attr(CONF_PAIR const *pair)
Return the attr of a CONF_PAIR.
Definition cf_util.c:1565
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:285
#define cf_parent(_cf)
Definition cf_util.h:98
#define cf_item_next(_parent, _curr)
Definition cf_util.h:89
#define cf_log_perr(_cf, _fmt,...)
Definition cf_util.h:292
#define cf_log_warn(_cf, _fmt,...)
Definition cf_util.h:286
#define CF_IDENT_ANY
Definition cf_util.h:75
#define MEM(x)
Definition debug.h:46
#define DEBUG(fmt,...)
Definition dhcpclient.c:38
fr_dict_attr_t const * fr_dict_attr_search_by_qualified_oid(fr_dict_attr_err_t *err, fr_dict_t const *dict_def, char const *attr, bool internal, bool foreign))
Locate a qualified fr_dict_attr_t by its name and a dictionary qualifier.
Definition dict_util.c:3346
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *attr))
Locate a fr_dict_attr_t by its name.
Definition dict_util.c:3528
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_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:292
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:305
char const * fr_dict_enum_name_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value)
Lookup the name of an enum value in a fr_dict_attr_t.
Definition dict_util.c:3688
#define DICT_AUTOLOAD_TERMINATOR
Definition dict.h:311
Specifies an attribute which must be present for the module to function.
Definition dict.h:291
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:304
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
int exfile_open(exfile_t *ef, char const *filename, mode_t permissions, int flags, off_t *offset)
Open a new log file, or maybe an existing one.
Definition exfile.c:529
int exfile_close(exfile_t *ef, int fd)
Close the log file.
Definition exfile.c:596
void * fr_hash_table_find(fr_hash_table_t *ht, void const *data)
Find data in a hash table.
Definition hash.c:450
uint32_t fr_hash(void const *data, size_t size)
Definition hash.c:847
bool fr_hash_table_insert(fr_hash_table_t *ht, void const *data)
Insert data into a hash table.
Definition hash.c:489
void fr_hash_table_fill(fr_hash_table_t *ht)
Ensure all buckets are filled.
Definition hash.c:745
uint32_t fr_hash_table_num_elements(fr_hash_table_t *ht)
Definition hash.c:633
#define fr_hash_table_alloc(_ctx, _hash_node, _cmp_node, _free_node)
Definition hash.h:61
talloc_free(hp)
#define RWDEBUG(fmt,...)
Definition log.h:373
#define RERROR(fmt,...)
Definition log.h:310
#define RPERROR(fmt,...)
Definition log.h:314
int rad_filename_box_escape(fr_value_box_t *vb, UNUSED void *uxtc)
Definition util.c:253
int rad_filename_box_make_safe(fr_value_box_t *vb, UNUSED void *uxtc)
Definition util.c:131
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_VOID
User data.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
unsigned int uint32_t
unsigned int mode_t
void * env_data
Per call environment data.
Definition module_ctx.h:44
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
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 instantiation calls.
Definition module_ctx.h:50
exfile_t * module_rlm_exfile_init(TALLOC_CTX *ctx, CONF_SECTION *module, uint32_t max_entries, fr_time_delta_t max_idle, bool locking, bool triggers, char const *trigger_prefix, fr_pair_list_t *trigger_args)
Initialise a module specific exfile handle.
Definition module_rlm.c:103
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
fr_pair_t * fr_pair_find_by_da_nested(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find a pair with a matching fr_dict_attr_t, by walking the nested fr_dict_attr_t tree.
Definition pair.c:784
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp)
Copy a single valuepair.
Definition pair.c:503
static const conf_parser_t config[]
Definition base.c:163
#define fr_assert(_expr)
Definition rad_assert.h:37
#define RDEBUG2(fmt,...)
static rs_t * conf
Definition radsniff.c:52
#define RETURN_UNLANG_FAIL
Definition rcode.h:63
#define RETURN_UNLANG_OK
Definition rcode.h:64
static void detail_fr_pair_fprint(TALLOC_CTX *ctx, FILE *out, fr_pair_t const *stacked)
Definition rlm_detail.c:170
static int call_env_filename_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule)
Definition rlm_detail.c:386
bool group_is_set
Whether group was set.
Definition rlm_detail.c:46
static unlang_action_t mod_post_auth(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_detail.c:381
static int call_env_suppress_parse(TALLOC_CTX *ctx, call_env_parsed_head_t *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, UNUSED call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule)
Definition rlm_detail.c:414
static int detail_write(FILE *out, rlm_detail_t const *inst, request_t *request, fr_value_box_t *header, fr_packet_t *packet, fr_pair_list_t *list, fr_hash_table_t *ht)
Write a single detail entry to file pointer.
Definition rlm_detail.c:211
mode_t perm
Permissions to use for new files.
Definition rlm_detail.c:44
fr_value_box_t filename
File / path to write to.
Definition rlm_detail.c:60
static fr_dict_attr_t const * attr_net_dst_port
Definition rlm_detail.c:94
gid_t group
Resolved group.
Definition rlm_detail.c:45
static const call_env_method_t method_env
Definition rlm_detail.c:474
bool triggers
Do we run triggers.
Definition rlm_detail.c:56
static fr_dict_t const * dict_freeradius
Definition rlm_detail.c:80
static fr_dict_attr_t const * attr_net
Definition rlm_detail.c:90
bool escape
do filename escaping, yes / no
Definition rlm_detail.c:52
static fr_dict_attr_t const * attr_net_src_address
Definition rlm_detail.c:91
static fr_dict_t const * dict_radius
Definition rlm_detail.c:81
static int detail_recurse(FILE *out, fr_hash_table_t *ht, fr_pair_list_t *list)
Definition rlm_detail.c:183
static unlang_action_t mod_accounting(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_detail.c:365
tmpl_t * filename_tmpl
tmpl used to expand filename (for debug output)
Definition rlm_detail.c:61
exfile_t * ef
Log file handler.
Definition rlm_detail.c:54
static unlang_action_t mod_authorize(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_detail.c:373
#define WRITE(fmt,...)
bool log_srcdst
Add IP src/dst attributes to entries.
Definition rlm_detail.c:50
fr_value_box_t header
Header format.
Definition rlm_detail.c:62
static int fr_pair_fprint(FILE *fp, fr_pair_t const *vp)
Print one attribute and value to FP.
Definition rlm_detail.c:120
static fr_dict_attr_t const * attr_net_dst_address
Definition rlm_detail.c:92
module_rlm_t rlm_detail
Definition rlm_detail.c:488
fr_dict_attr_autoload_t rlm_detail_dict_attr[]
Definition rlm_detail.c:97
static const conf_parser_t module_config[]
Definition rlm_detail.c:70
static uint32_t detail_hash(void const *data)
Definition rlm_detail.c:138
static unlang_action_t detail_do(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request, fr_packet_t *packet, fr_pair_list_t *list)
Definition rlm_detail.c:305
bool locking
Whether the file should be locked.
Definition rlm_detail.c:48
static fr_dict_attr_t const * attr_net_src_port
Definition rlm_detail.c:93
static int mod_instantiate(module_inst_ctx_t const *mctx)
Definition rlm_detail.c:152
fr_dict_autoload_t rlm_detail_dict[]
Definition rlm_detail.c:84
static int8_t detail_cmp(void const *a, void const *b)
Definition rlm_detail.c:144
fr_hash_table_t * ht
Holds suppressed attributes.
Definition rlm_detail.c:63
Instance configuration for rlm_detail.
Definition rlm_detail.c:43
static char const * name
#define FR_SBUFF_IN(_start, _len_or_end)
#define FR_SBUFF_OUT(_start, _len_or_end)
#define fr_sbuff_in_char(_sbuff,...)
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition section.h:39
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:351
size_t inst_size
Size of the module's instance data.
Definition module.h:212
void * data
Module's instance data.
Definition module.h:293
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:152
Named methods exported by a module.
Definition module.h:174
tmpl_escape_t escape
How escaping should be handled during evaluation.
Definition tmpl.h:353
fr_value_box_safe_for_t literals_safe_for
safe_for value assigned to literal values in xlats, execs, and data.
Definition tmpl.h:351
ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_token_t quote, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Convert an arbitrary string into a tmpl_t.
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
Definition tmpl.h:339
Optional arguments passed to vp_tmpl functions.
Definition tmpl.h:336
static char buff[sizeof("18446744073709551615")+3]
Definition size_tests.c:41
eap_aka_sim_process_conf_t * inst
fr_pair_t * vp
fr_dict_t const * dict_def
Default dictionary to use with unqualified attribute references.
Definition tmpl.h:273
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
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition syserror.c:243
#define talloc_get_type_abort_const
Definition talloc.h:110
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
Definition talloc.h:136
static int64_t fr_time_to_sec(fr_time_t when)
Convert an fr_time_t (internal time) to number of sec since the unix epoch (wallclock time)
Definition time.h:731
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
Definition time.h:590
fr_value_box_escape_t box_escape
How to escape when returned from evaluation.
Definition tmpl_escape.h:81
@ TMPL_ESCAPE_PRE_CONCAT
Pre-concatenation escaping is useful for DSLs where elements of the expansion are static,...
Definition tmpl_escape.h:61
tmpl_escape_mode_t mode
Whether to apply escape function after concatenation, i.e.
Definition tmpl_escape.h:83
@ T_OP_EQ
Definition token.h:81
@ T_DOUBLE_QUOTED_STRING
Definition token.h:119
unsigned int code
Packet code (type).
Definition packet.h:61
ssize_t fr_pair_print(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_pair_t const *vp))
Print one attribute and value to a string.
Definition pair_print.c:232
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
#define PAIR_VERIFY(_x)
Definition pair.h:204
#define fr_pair_list_foreach(_list_head, _iter)
Iterate over the contents of a fr_pair_list_t.
Definition pair.h:279
static fr_slen_t parent
Definition pair.h:858
#define fr_type_is_structural(_x)
Definition types.h:392
#define fr_type_is_leaf(_x)
Definition types.h:393
fr_sbuff_parse_rules_t const * value_parse_rules_quoted[T_TOKEN_LAST]
Parse rules for quoted strings.
Definition value.c:611
static fr_slen_t data
Definition value.h:1340
fr_value_box_safe_for_t safe_for
Definition value.h:678
uintptr_t fr_value_box_safe_for_t
Escaping that's been applied to a value box.
Definition value.h:162
int nonnull(2, 5))
fr_value_box_escape_func_t func
Definition value.h:677
#define fr_box_uint32(_val)
Definition value.h:335
static size_t char ** out
Definition value.h:1030