The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_detail.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: c0928e39b4c984cbd22c26b68d5561b0409e26dd $
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: c0928e39b4c984cbd22c26b68d5561b0409e26dd $")
25
26#include <freeradius-devel/server/base.h>
27#include <freeradius-devel/server/cf_util.h>
28#include <freeradius-devel/server/exfile.h>
29#include <freeradius-devel/server/module_rlm.h>
30#include <freeradius-devel/util/debug.h>
31#include <freeradius-devel/util/perm.h>
32
33#include <ctype.h>
34#include <fcntl.h>
35#include <sys/stat.h>
36
37#ifdef HAVE_UNISTD_H
38# include <unistd.h>
39#endif
40
41#ifdef HAVE_GRP_H
42# include <grp.h>
43#endif
44
45/** Instance configuration for rlm_detail
46 *
47 * Holds the configuration and preparsed data for a instance of rlm_detail.
48 */
49typedef struct {
50 mode_t perm; //!< Permissions to use for new files.
51 gid_t group; //!< Resolved group.
52 bool group_is_set; //!< Whether group was set.
53
54 bool locking; //!< Whether the file should be locked.
55
56 bool log_srcdst; //!< Add IP src/dst attributes to entries.
57
58 bool escape; //!< do filename escaping, yes / no
59
60 exfile_t *ef; //!< Log file handler
61
62 bool triggers; //!< Do we run triggers.
64
65typedef struct {
66 fr_value_box_t filename; //!< File / path to write to.
67 tmpl_t *filename_tmpl; //!< tmpl used to expand filename (for debug output)
68 fr_value_box_t header; //!< Header format
69 fr_hash_table_t *ht; //!< Holds suppressed attributes.
71
72/*
73 * @todo - put this into common function in cf_parse.c ?
74 */
75
76static const conf_parser_t module_config[] = {
77 { FR_CONF_OFFSET("permissions", rlm_detail_t, perm), .dflt = "0600", .func = cf_parse_permissions },
78 { FR_CONF_OFFSET_IS_SET("group", FR_TYPE_VOID, 0, rlm_detail_t, group), .func = cf_parse_gid },
79 { FR_CONF_OFFSET("locking", rlm_detail_t, locking), .dflt = "no" },
80 { FR_CONF_OFFSET("escape_filenames", rlm_detail_t, escape), .dflt = "no" },
81 { FR_CONF_OFFSET("log_packet_header", rlm_detail_t, log_srcdst), .dflt = "no" },
82 { FR_CONF_OFFSET("triggers", rlm_detail_t, triggers) },
84};
85
87static fr_dict_t const *dict_radius;
88
91 { .out = &dict_freeradius, .proto = "freeradius" },
92 { .out = &dict_radius, .proto = "radius" },
93 { NULL }
94};
95
101
104 { .out = &attr_net, .name = "Net", .type = FR_TYPE_TLV, .dict = &dict_freeradius },
105 { .out = &attr_net_dst_address, .name = "Net.Dst.IP", .type = FR_TYPE_COMBO_IP_ADDR, .dict = &dict_freeradius },
106 { .out = &attr_net_dst_port, .name = "Net.Dst.Port", .type = FR_TYPE_UINT16, .dict = &dict_freeradius },
107 { .out = &attr_net_src_address, .name = "Net.Src.IP", .type = FR_TYPE_COMBO_IP_ADDR, .dict = &dict_freeradius },
108 { .out = &attr_net_src_port, .name = "Net.Src.Port", .type = FR_TYPE_UINT16, .dict = &dict_freeradius },
109
110 { NULL }
111};
112
113/** Print one attribute and value to FP
114 *
115 * Complete string with '\\t' and '\\n' is written to buffer before printing to
116 * avoid issues when running with multiple threads.
117 *
118 * @todo - This function should print *flattened* lists.
119 *
120 * @param fp to output to.
121 * @param vp to print.
122 * @return
123 * - >=0 on success
124 * - <0 on error
125 */
126static int CC_HINT(nonnull) fr_pair_fprint(FILE *fp, fr_pair_t const *vp)
127{
128 char buff[1024];
129 fr_sbuff_t sbuff = FR_SBUFF_OUT(buff, sizeof(buff));
130
132
133 (void) fr_sbuff_in_char(&sbuff, '\t');
134 (void) fr_pair_print(&sbuff, NULL, vp);
135 (void) fr_sbuff_in_char(&sbuff, '\n');
136
137 if (fputs(buff, fp) == EOF) return -1;
138
139 return 0;
140}
141
142
143
144static uint32_t detail_hash(void const *data)
145{
146 fr_dict_attr_t const *da = data;
147 return fr_hash(&da, sizeof(da));
148}
149
150static int8_t detail_cmp(void const *a, void const *b)
151{
152 return CMP(a, b);
153}
154
155/*
156 * (Re-)read radiusd.conf into memory.
157 */
158static int mod_instantiate(module_inst_ctx_t const *mctx)
159{
160 rlm_detail_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_detail_t);
161 CONF_SECTION *conf = mctx->mi->conf;
162
164 inst->triggers, "modules.detail", NULL);
165 if (!inst->ef) {
166 cf_log_err(conf, "Failed creating log file context");
167 return -1;
168 }
169
170 return 0;
171}
172
173/*
174 * Wrapper for VPs allocated on the stack.
175 */
176static void detail_fr_pair_fprint(TALLOC_CTX *ctx, FILE *out, fr_pair_t const *stacked)
177{
178 fr_pair_t *vp;
179
180 vp = fr_pair_copy(ctx, stacked);
181 if (unlikely(vp == NULL)) return;
182
183 vp->op = T_OP_EQ;
184 (void) fr_pair_fprint(out, vp);
186}
187
188
190{
191 fr_pair_list_foreach(list, vp) {
192 if (ht && fr_hash_table_find(ht, vp->da)) continue;
193
194 if (fr_type_is_leaf(vp->vp_type)) {
195 if (fr_pair_fprint(out, vp) < 0) return -1;
196 continue;
197 }
198
200
201 if (detail_recurse(out, ht, &vp->vp_group) < 0) return -1;
202 }
203
204 return 0;
205}
206
207/** Write a single detail entry to file pointer
208 *
209 * @param[in] out Where to write entry.
210 * @param[in] inst Instance of rlm_detail.
211 * @param[in] request The current request.
212 * @param[in] header To print above packet
213 * @param[in] packet associated with the request (request, reply...).
214 * @param[in] list of pairs to write.
215 * @param[in] ht Hash table containing attributes to be suppressed in the output.
216 */
217static int detail_write(FILE *out, rlm_detail_t const *inst, request_t *request, fr_value_box_t *header,
218 fr_packet_t *packet, fr_pair_list_t *list, fr_hash_table_t *ht)
219{
220 fr_dict_attr_t const *da;
221
222 if (fr_pair_list_empty(list)) {
223 RWDEBUG("Skipping empty packet");
224 return 0;
225 }
226
227#define WRITE(fmt, ...) do { \
228 if (fprintf(out, fmt, ## __VA_ARGS__) < 0) goto fail; \
229 } while(0)
230
231 WRITE("%s\n", header->vb_strvalue);
232
233 /*
234 * Write the Packet-Type, but only if we're not suppressing it.
235 */
236 da = fr_dict_attr_by_name(NULL, fr_dict_root(request->proto_dict), "Packet-Type");
237 if (ht && da && !fr_hash_table_find(ht, da)) {
238 char const *name = NULL;
239
241
242 /*
243 * Print out names, if they're OK.
244 * Numbers, if not.
245 */
246 if (name) {
247 WRITE("\tPacket-Type = %s\n", name);
248 } else {
249 WRITE("\tPacket-Type = %u\n", packet->code);
250 }
251 }
252
253 /*
254 * Put these at the top as distinct (not nested) VPs.
255 */
256 if (inst->log_srcdst) {
257 fr_pair_t *src_vp, *dst_vp;
258
259 src_vp = fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_net_src_address);
260 dst_vp = fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_net_dst_address);
261
262 /*
263 * These pairs will exist, but Coverity doesn't know that
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 src_vp = fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_net_src_port);
269 dst_vp = fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_net_dst_port);
270
271 if (src_vp) detail_fr_pair_fprint(request, out, src_vp);
272 if (dst_vp) detail_fr_pair_fprint(request, out, dst_vp);
273 }
274
275 /*
276 * Write each attribute/value to the log file
277 */
278 fr_pair_list_foreach(list, vp) {
279 if (ht && fr_hash_table_find(ht, vp->da)) continue;
280
281 /*
282 * Skip Net.* if we're not logging src/dst
283 */
284 if (!inst->log_srcdst && (da == attr_net)) continue;
285
286 if (fr_type_is_leaf(vp->vp_type)) {
287 if (fr_pair_fprint(out, vp) < 0) {
288 fail:
289 RERROR("Failed writing to detail file: %s", fr_syserror(errno));
290 return -1;
291 }
292
293 continue;
294 }
295
297
298 if (detail_recurse(out, ht, &vp->vp_group) < 0) goto fail;
299 }
300
301 WRITE("\tTimestamp = %lu\n", (unsigned long) fr_time_to_sec(request->packet->timestamp));
302
303 WRITE("\n");
304
305 return 0;
306}
307
308/*
309 * Do detail, compatible with old accounting
310 */
311static unlang_action_t CC_HINT(nonnull) detail_do(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request,
312 fr_packet_t *packet, fr_pair_list_t *list)
313{
314 rlm_detail_env_t *env = talloc_get_type_abort(mctx->env_data, rlm_detail_env_t);
315 int outfd, dupfd;
316 FILE *outfp = NULL;
317
319
320 RDEBUG2("%s expands to %pV", env->filename_tmpl->name, &env->filename);
321
322 outfd = exfile_open(inst->ef, env->filename.vb_strvalue, inst->perm, NULL);
323 if (outfd < 0) {
324 RPERROR("Couldn't open file %pV", &env->filename);
325
326 /* coverity[missing_unlock] */
328 }
329
330 if (inst->group_is_set) {
331 if (chown(env->filename.vb_strvalue, -1, inst->group) == -1) {
332 RERROR("Unable to set detail file group to '%d': %s", inst->group, fr_syserror(errno));
333 goto fail;
334 }
335 }
336
337 dupfd = dup(outfd);
338 if (dupfd < 0) {
339 RERROR("Failed to dup() file descriptor for detail file");
340 goto fail;
341 }
342
343 /*
344 * Open the output fp for buffering.
345 */
346 if ((outfp = fdopen(dupfd, "a")) == NULL) {
347 RERROR("Couldn't open file %pV: %s", &env->filename, fr_syserror(errno));
348 fail:
349 if (outfp) fclose(outfp);
350 exfile_close(inst->ef, outfd);
352 }
353
354 if (detail_write(outfp, inst, request, &env->header, packet, list, env->ht) < 0) goto fail;
355
356 /*
357 * Flush everything
358 */
359 fclose(outfp);
360 exfile_close(inst->ef, outfd);
361
362 /*
363 * And everything is fine.
364 */
366}
367
368/*
369 * Accounting - write the detail files.
370 */
371static unlang_action_t CC_HINT(nonnull) mod_accounting(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
372{
373 return detail_do(p_result, mctx, request, request->packet, &request->request_pairs);
374}
375
376/*
377 * Incoming Access Request - write the detail files.
378 */
379static unlang_action_t CC_HINT(nonnull) mod_authorize(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
380{
381 return detail_do(p_result, mctx, request, request->packet, &request->request_pairs);
382}
383
384/*
385 * Outgoing Access-Request Reply - write the detail files.
386 */
387static unlang_action_t CC_HINT(nonnull) mod_post_auth(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
388{
389 return detail_do(p_result, mctx, request, request->reply, &request->reply_pairs);
390}
391
392static int call_env_filename_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules,
393 CONF_ITEM *ci,
394 call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule)
395{
397 tmpl_t *parsed;
398 CONF_PAIR const *to_parse = cf_item_to_pair(ci);
399 tmpl_rules_t our_rules;
400
401 our_rules = *t_rules;
404 .safe_for = (inst->escape) ? (fr_value_box_safe_for_t)rad_filename_box_escape :
406 .always_escape = false,
407 };
409 our_rules.literals_safe_for = our_rules.escape.box_escape.safe_for;
410
411 if (tmpl_afrom_substr(ctx, &parsed,
412 &FR_SBUFF_IN(cf_pair_value(to_parse), talloc_array_length(cf_pair_value(to_parse)) - 1),
414 &our_rules) < 0) return -1;
415
416 *(void **)out = parsed;
417 return 0;
418}
419
420static int call_env_suppress_parse(TALLOC_CTX *ctx, call_env_parsed_head_t *out, tmpl_rules_t const *t_rules,
421 CONF_ITEM *ci,
422 UNUSED call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule)
423{
424 CONF_SECTION const *cs = cf_item_to_section(ci);
426 call_env_parsed_t *parsed;
427 CONF_ITEM const *to_parse = NULL;
428 char const *attr;
429 fr_dict_attr_t const *da;
430 fr_hash_table_t *ht;
431
432 MEM(parsed = call_env_parsed_add(ctx, out,
434
435 ht = fr_hash_table_alloc(parsed, detail_hash, detail_cmp, NULL);
436
437 while ((to_parse = cf_item_next(cs, to_parse))) {
438 if (!cf_item_is_pair(to_parse)) continue;
439
440 attr = cf_pair_attr(cf_item_to_pair(to_parse));
441 if (!attr) continue;
442
443 da = fr_dict_attr_search_by_qualified_oid(NULL, t_rules->attr.dict_def, attr, false, false);
444 if (!da) {
445 cf_log_perr(to_parse, "Failed resolving attribute");
446 return -1;
447 }
448
449 /*
450 * Be kind to minor mistakes
451 */
452 if (fr_hash_table_find(ht, da)) {
453 cf_log_warn(to_parse, "Ignoring duplicate entry '%s'", attr);
454 continue;
455 }
456
457 if (!fr_hash_table_insert(ht, da)) {
458 cf_log_perr(to_parse, "Failed inserting '%s' into suppression table", attr);
459 return -1;
460 }
461
462 DEBUG("%s - '%s' suppressed, will not appear in detail output", cf_section_name(parent), attr);
463 }
464
465 /*
466 * Clear up if nothing is actually to be suppressed
467 */
468 if (fr_hash_table_num_elements(ht) == 0) {
469 talloc_free(ht);
470 call_env_parsed_free(out, parsed);
471 return 0;
472 }
473
475 call_env_parsed_set_data(parsed, ht);
476
477 return 0;
478}
479
491
492/* globally exported name */
495 .common = {
496 .magic = MODULE_MAGIC_INIT,
497 .name = "detail",
498 .inst_size = sizeof(rlm_detail_t),
500 .instantiate = mod_instantiate
501 },
502 .method_group = {
503 .bindings = (module_method_binding_t[]){
504 { .section = SECTION_NAME("accounting", CF_IDENT_ANY), .method = mod_accounting, .method_env = &method_env },
505 { .section = SECTION_NAME("recv", "accounting-request"), .method = mod_accounting, .method_env = &method_env },
506 { .section = SECTION_NAME("send", "accounting-response"), .method = mod_accounting, .method_env = &method_env },
507 { .section = SECTION_NAME("recv", CF_IDENT_ANY), .method = mod_authorize, .method_env = &method_env },
508 { .section = SECTION_NAME("send", CF_IDENT_ANY), .method = mod_post_auth, .method_env = &method_env },
510 }
511 }
512};
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:485
#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:112
#define unlikely(_x)
Definition build.h:383
#define UNUSED
Definition build.h:317
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:775
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:688
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:745
#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:1700
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:1715
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:660
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
Definition cf_parse.h:614
#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:283
#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:297
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:597
Common header for all CONF_* types.
Definition cf_priv.h:49
Configuration AVP similar to a fr_pair_t.
Definition cf_priv.h:70
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:631
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition cf_util.c:683
char const * cf_section_name(CONF_SECTION const *cs)
Return name2 if set, else name1.
Definition cf_util.c:1196
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:663
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:286
#define cf_parent(_cf)
Definition cf_util.h:101
#define cf_item_next(_parent, _curr)
Definition cf_util.h:92
#define cf_log_perr(_cf, _fmt,...)
Definition cf_util.h:293
#define cf_log_warn(_cf, _fmt,...)
Definition cf_util.h:287
#define CF_IDENT_ANY
Definition cf_util.h:78
#define MEM(x)
Definition debug.h:36
#define DEBUG(fmt,...)
Definition dhcpclient.c:39
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:3177
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:3359
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2496
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:287
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:300
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:3519
Specifies an attribute which must be present for the module to function.
Definition dict.h:286
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:299
#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, off_t *offset)
Open a new log file, or maybe an existing one.
Definition exfile.c:526
int exfile_close(exfile_t *ef, int fd)
Close the log file.
Definition exfile.c:582
void * fr_hash_table_find(fr_hash_table_t *ht, void const *data)
Find data in a hash table.
Definition hash.c:429
uint32_t fr_hash(void const *data, size_t size)
Definition hash.c:812
bool fr_hash_table_insert(fr_hash_table_t *ht, void const *data)
Insert data into a hash table.
Definition hash.c:468
void fr_hash_table_fill(fr_hash_table_t *ht)
Ensure all buckets are filled.
Definition hash.c:719
uint32_t fr_hash_table_num_elements(fr_hash_table_t *ht)
Definition hash.c:610
#define fr_hash_table_alloc(_ctx, _hash_node, _cmp_node, _free_node)
Definition hash.h:58
#define RWDEBUG(fmt,...)
Definition log.h:361
#define RERROR(fmt,...)
Definition log.h:298
#define RPERROR(fmt,...)
Definition log.h:302
int rad_filename_box_escape(fr_value_box_t *vb, UNUSED void *uxtc)
Definition util.c:281
int rad_filename_box_make_safe(fr_value_box_t *vb, UNUSED void *uxtc)
Definition util.c:160
talloc_free(reap)
@ 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:777
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp)
Copy a single valuepair.
Definition pair.c:495
static const conf_parser_t config[]
Definition base.c:186
#define fr_assert(_expr)
Definition rad_assert.h:38
#define RDEBUG2(fmt,...)
Definition radclient.h:54
static rs_t * conf
Definition radsniff.c:53
#define RETURN_UNLANG_FAIL
Definition rcode.h:59
#define RETURN_UNLANG_OK
Definition rcode.h:60
static void detail_fr_pair_fprint(TALLOC_CTX *ctx, FILE *out, fr_pair_t const *stacked)
Definition rlm_detail.c:176
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:392
bool group_is_set
Whether group was set.
Definition rlm_detail.c:52
static unlang_action_t mod_post_auth(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_detail.c:387
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:420
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:217
mode_t perm
Permissions to use for new files.
Definition rlm_detail.c:50
fr_value_box_t filename
File / path to write to.
Definition rlm_detail.c:66
static fr_dict_attr_t const * attr_net_dst_port
Definition rlm_detail.c:100
gid_t group
Resolved group.
Definition rlm_detail.c:51
static const call_env_method_t method_env
Definition rlm_detail.c:480
bool triggers
Do we run triggers.
Definition rlm_detail.c:62
static fr_dict_t const * dict_freeradius
Definition rlm_detail.c:86
static fr_dict_attr_t const * attr_net
Definition rlm_detail.c:96
bool escape
do filename escaping, yes / no
Definition rlm_detail.c:58
static fr_dict_attr_t const * attr_net_src_address
Definition rlm_detail.c:97
static fr_dict_t const * dict_radius
Definition rlm_detail.c:87
static int detail_recurse(FILE *out, fr_hash_table_t *ht, fr_pair_list_t *list)
Definition rlm_detail.c:189
static unlang_action_t mod_accounting(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_detail.c:371
tmpl_t * filename_tmpl
tmpl used to expand filename (for debug output)
Definition rlm_detail.c:67
exfile_t * ef
Log file handler.
Definition rlm_detail.c:60
static unlang_action_t mod_authorize(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_detail.c:379
#define WRITE(fmt,...)
bool log_srcdst
Add IP src/dst attributes to entries.
Definition rlm_detail.c:56
fr_value_box_t header
Header format.
Definition rlm_detail.c:68
static int fr_pair_fprint(FILE *fp, fr_pair_t const *vp)
Print one attribute and value to FP.
Definition rlm_detail.c:126
static fr_dict_attr_t const * attr_net_dst_address
Definition rlm_detail.c:98
module_rlm_t rlm_detail
Definition rlm_detail.c:494
fr_dict_attr_autoload_t rlm_detail_dict_attr[]
Definition rlm_detail.c:103
static const conf_parser_t module_config[]
Definition rlm_detail.c:76
static uint32_t detail_hash(void const *data)
Definition rlm_detail.c:144
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:311
bool locking
Whether the file should be locked.
Definition rlm_detail.c:54
static fr_dict_attr_t const * attr_net_src_port
Definition rlm_detail.c:99
static int mod_instantiate(module_inst_ctx_t const *mctx)
Definition rlm_detail.c:158
fr_dict_autoload_t rlm_detail_dict[]
Definition rlm_detail.c:90
static int8_t detail_cmp(void const *a, void const *b)
Definition rlm_detail.c:150
fr_hash_table_t * ht
Holds suppressed attributes.
Definition rlm_detail.c:69
Instance configuration for rlm_detail.
Definition rlm_detail.c:49
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:40
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:349
size_t inst_size
Size of the module's instance data.
Definition module.h:212
void * data
Module's instance data.
Definition module.h:291
#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:349
fr_value_box_safe_for_t literals_safe_for
safe_for value assigned to literal values in xlats, execs, and data.
Definition tmpl.h:347
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:335
Optional arguments passed to vp_tmpl functions.
Definition tmpl.h:332
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:287
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:83
@ T_DOUBLE_QUOTED_STRING
Definition token.h:121
unsigned int code
Packet code (type).
Definition packet.h:61
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
#define PAIR_VERIFY(_x)
Definition pair.h:193
static fr_slen_t quote 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:117
#define fr_pair_list_foreach(_list_head, _iter)
Iterate over the contents of a fr_pair_list_t.
Definition pair.h:263
static fr_slen_t parent
Definition pair.h:841
#define fr_type_is_structural(_x)
Definition types.h:393
#define fr_type_is_leaf(_x)
Definition types.h:394
fr_sbuff_parse_rules_t const * value_parse_rules_quoted[T_TOKEN_LAST]
Parse rules for quoted strings.
Definition value.c:612
static fr_slen_t data
Definition value.h:1291
fr_value_box_safe_for_t safe_for
Definition value.h:677
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:676
#define fr_box_uint32(_val)
Definition value.h:334
static size_t char ** out
Definition value.h:1023