The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 2acf642fcd61161be0c9b442fab28f12c0e5dafb $
19  * @file rlm_detail.c
20  * @brief Write plaintext versions of packets to flatfiles.
21  *
22  * @copyright 2000,2006 The FreeRADIUS server project
23  */
24 RCSID("$Id: 2acf642fcd61161be0c9b442fab28f12c0e5dafb $")
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  */
49 typedef struct {
50  uint32_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 } rlm_detail_t;
62 
63 typedef struct {
64  fr_value_box_t filename; //!< File / path to write to.
65  tmpl_t *filename_tmpl; //!< tmpl used to expand filename (for debug output)
66  fr_value_box_t header; //!< Header format
67  fr_hash_table_t *ht; //!< Holds suppressed attributes.
69 
70 int detail_group_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent,
71  CONF_ITEM *ci, conf_parser_t const *rule);
72 
73 static const conf_parser_t module_config[] = {
74  { FR_CONF_OFFSET("permissions", rlm_detail_t, perm), .dflt = "0600" },
75  { FR_CONF_OFFSET_IS_SET("group", FR_TYPE_VOID, 0, rlm_detail_t, group), .func = detail_group_parse },
76  { FR_CONF_OFFSET("locking", rlm_detail_t, locking), .dflt = "no" },
77  { FR_CONF_OFFSET("escape_filenames", rlm_detail_t, escape), .dflt = "no" },
78  { FR_CONF_OFFSET("log_packet_header", rlm_detail_t, log_srcdst), .dflt = "no" },
80 };
81 
82 static fr_dict_t const *dict_freeradius;
83 static fr_dict_t const *dict_radius;
84 
87  { .out = &dict_freeradius, .proto = "freeradius" },
88  { .out = &dict_radius, .proto = "radius" },
89  { NULL }
90 };
91 
92 static fr_dict_attr_t const *attr_net;
98 
100 
103  { .out = &attr_net, .name = "Net", .type = FR_TYPE_TLV, .dict = &dict_freeradius },
104  { .out = &attr_net_dst_address, .name = "Net.Dst.IP", .type = FR_TYPE_COMBO_IP_ADDR, .dict = &dict_freeradius },
105  { .out = &attr_net_dst_port, .name = "Net.Dst.Port", .type = FR_TYPE_UINT16, .dict = &dict_freeradius },
106  { .out = &attr_net_src_address, .name = "Net.Src.IP", .type = FR_TYPE_COMBO_IP_ADDR, .dict = &dict_freeradius },
107  { .out = &attr_net_src_port, .name = "Net.Src.Port", .type = FR_TYPE_UINT16, .dict = &dict_freeradius },
108  { .out = &attr_protocol, .name = "Protocol", .type = FR_TYPE_UINT32, .dict = &dict_freeradius },
109 
110  { .out = &attr_user_password, .name = "User-Password", .type = FR_TYPE_STRING, .dict = &dict_radius },
111 
112  { NULL }
113 };
114 
115 /** Print one attribute and value to FP
116  *
117  * Complete string with '\\t' and '\\n' is written to buffer before printing to
118  * avoid issues when running with multiple threads.
119  *
120  * @todo - This function should print *flattened* lists.
121  *
122  * @param fp to output to.
123  * @param vp to print.
124  */
125 static void CC_HINT(nonnull) fr_pair_fprint(FILE *fp, fr_pair_t const *vp)
126 {
127  char buff[1024];
128  fr_sbuff_t sbuff = FR_SBUFF_OUT(buff, sizeof(buff));
129 
130  PAIR_VERIFY(vp);
131 
132  (void) fr_sbuff_in_char(&sbuff, '\t');
133  (void) fr_pair_print(&sbuff, NULL, vp);
134  (void) fr_sbuff_in_char(&sbuff, '\n');
135 
136  fputs(buff, fp);
137 }
138 
139 
140 
141 /** Generic function for parsing conf pair values as int
142  *
143  * @note This should be used for enum types as c99 6.4.4.3 states that the enumeration
144  * constants are of type int.
145  *
146  */
147 int detail_group_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent,
148  CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
149 {
150  char const *group;
151  char *endptr;
152  gid_t gid;
153 
154  group = cf_pair_value(cf_item_to_pair(ci));
155  gid = strtol(group, &endptr, 10);
156  if (*endptr != '\0') {
157  if (fr_perm_gid_from_str(parent, &gid, group) < 0) {
158  cf_log_err(ci, "Unable to find system group '%s'", group);
159  return -1;
160  }
161  }
162  *((gid_t *)out) = gid;
163 
164  return 0;
165 }
166 
167 static uint32_t detail_hash(void const *data)
168 {
169  fr_dict_attr_t const *da = data;
170  return fr_hash(&da, sizeof(da));
171 }
172 
173 static int8_t detail_cmp(void const *a, void const *b)
174 {
175  return CMP(a, b);
176 }
177 
178 /*
179  * (Re-)read radiusd.conf into memory.
180  */
181 static int mod_instantiate(module_inst_ctx_t const *mctx)
182 {
183  rlm_detail_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_detail_t);
184  CONF_SECTION *conf = mctx->mi->conf;
185 
186  inst->ef = module_rlm_exfile_init(inst, conf, 256, fr_time_delta_from_sec(30), inst->locking, NULL, NULL);
187  if (!inst->ef) {
188  cf_log_err(conf, "Failed creating log file context");
189  return -1;
190  }
191 
192  return 0;
193 }
194 
195 /*
196  * Wrapper for VPs allocated on the stack.
197  */
198 static void detail_fr_pair_fprint(TALLOC_CTX *ctx, FILE *out, fr_pair_t const *stacked)
199 {
200  fr_pair_t *vp;
201 
202  vp = fr_pair_copy(ctx, stacked);
203  if (unlikely(vp == NULL)) return;
204 
205  vp->op = T_OP_EQ;
207  talloc_free(vp);
208 }
209 
210 
211 /** Write a single detail entry to file pointer
212  *
213  * @param[in] out Where to write entry.
214  * @param[in] inst Instance of rlm_detail.
215  * @param[in] request The current request.
216  * @param[in] header To print above packet
217  * @param[in] packet associated with the request (request, reply...).
218  * @param[in] list of pairs to write.
219  * @param[in] compat Write out entry in compatibility mode.
220  * @param[in] ht Hash table containing attributes to be suppressed in the output.
221  */
222 static int detail_write(FILE *out, rlm_detail_t const *inst, request_t *request, fr_value_box_t *header,
223  fr_packet_t *packet, fr_pair_list_t *list, bool compat, fr_hash_table_t *ht)
224 {
225  if (fr_pair_list_empty(list)) {
226  RWDEBUG("Skipping empty packet");
227  return 0;
228  }
229 
230 #define WRITE(fmt, ...) do {\
231  if (fprintf(out, fmt, ## __VA_ARGS__) < 0) {\
232  RERROR("Failed writing to detail file: %s", fr_syserror(errno));\
233  return -1;\
234  }\
235 } while(0)
236 
237  WRITE("%s\n", header->vb_strvalue);
238 
239  /*
240  * Write the information to the file.
241  */
242  if (!compat) {
243  fr_dict_attr_t const *da;
244  char const *name = NULL;
245 
246  da = fr_dict_attr_by_name(NULL, fr_dict_root(request->dict), "Packet-Type");
247  if (da) name = fr_dict_enum_name_by_value(da, fr_box_uint32(packet->code));
248 
249  /*
250  * Print out names, if they're OK.
251  * Numbers, if not.
252  */
253  if (name) {
254  WRITE("\tPacket-Type = %s\n", name);
255  } else {
256  WRITE("\tPacket-Type = %u\n", packet->code);
257  }
258  }
259 
260  /*
261  * Put these at the top as distinct (not nested) VPs.
262  */
263  if (inst->log_srcdst) {
264  fr_pair_t *src_vp, *dst_vp;
265 
266  src_vp = fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_net_src_address);
267  dst_vp = fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_net_dst_address);
268 
269  /*
270  * These pairs will exist, but Coverity doesn't know that
271  */
272  if (src_vp) detail_fr_pair_fprint(request, out, src_vp);
273  if (dst_vp) detail_fr_pair_fprint(request, out, dst_vp);
274 
275  src_vp = fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_net_src_port);
276  dst_vp = fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_net_dst_port);
277 
278  if (src_vp) detail_fr_pair_fprint(request, out, src_vp);
279  if (dst_vp) detail_fr_pair_fprint(request, out, dst_vp);
280  }
281 
282  /* Write each attribute/value to the log file */
284  if (ht && fr_hash_table_find(ht, vp->da)) continue;
285 
286  /*
287  * Skip Net.* if we're not logging src/dst
288  */
289  if (!inst->log_srcdst && (fr_dict_by_da(vp->da) == dict_freeradius)) {
290  fr_dict_attr_t const *da = vp->da;
291 
292  while (da->depth > attr_net->depth) {
293  da = da->parent;
294  }
295 
296  if (da == attr_net) continue;
297  }
298 
299  /*
300  * Don't print passwords in old format...
301  */
302  if (compat && (vp->da == attr_user_password)) continue;
303 
305  }
306 
307  /*
308  * Add the original protocol of the request, this should
309  * be used by the detail reader to set the default
310  * dictionary used for decoding.
311  */
312 // WRITE("\t%s = %s", attr_protocol->name, fr_dict_root(request->dict)->name);
313  WRITE("\tTimestamp = %lu\n", (unsigned long) fr_time_to_sec(request->packet->timestamp));
314 
315  WRITE("\n");
316 
317  return 0;
318 }
319 
320 /*
321  * Do detail, compatible with old accounting
322  */
323 static unlang_action_t CC_HINT(nonnull) detail_do(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request,
324  fr_packet_t *packet, fr_pair_list_t *list,
325  bool compat)
326 {
327  rlm_detail_env_t *env = talloc_get_type_abort(mctx->env_data, rlm_detail_env_t);
328  int outfd, dupfd;
329  FILE *outfp = NULL;
330 
332 
333  RDEBUG2("%s expands to %pV", env->filename_tmpl->name, &env->filename);
334 
335  outfd = exfile_open(inst->ef, env->filename.vb_strvalue, inst->perm, NULL);
336  if (outfd < 0) {
337  RPERROR("Couldn't open file %pV", &env->filename);
338  *p_result = RLM_MODULE_FAIL;
339  /* coverity[missing_unlock] */
341  }
342 
343  if (inst->group_is_set) {
344  if (chown(env->filename.vb_strvalue, -1, inst->group) == -1) {
345  RERROR("Unable to set detail file group to '%d': %s", inst->group, fr_syserror(errno));
346  goto fail;
347  }
348  }
349 
350  dupfd = dup(outfd);
351  if (dupfd < 0) {
352  RERROR("Failed to dup() file descriptor for detail file");
353  goto fail;
354  }
355 
356  /*
357  * Open the output fp for buffering.
358  */
359  if ((outfp = fdopen(dupfd, "a")) == NULL) {
360  RERROR("Couldn't open file %pV: %s", &env->filename, fr_syserror(errno));
361  fail:
362  if (outfp) fclose(outfp);
363  exfile_close(inst->ef, outfd);
365  }
366 
367  if (detail_write(outfp, inst, request, &env->header, packet, list, compat, env->ht) < 0) goto fail;
368 
369  /*
370  * Flush everything
371  */
372  fclose(outfp);
373  exfile_close(inst->ef, outfd);
374 
375  /*
376  * And everything is fine.
377  */
379 }
380 
381 /*
382  * Accounting - write the detail files.
383  */
384 static unlang_action_t CC_HINT(nonnull) mod_accounting(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
385 {
386  return detail_do(p_result, mctx, request, request->packet, &request->request_pairs, true);
387 }
388 
389 /*
390  * Incoming Access Request - write the detail files.
391  */
392 static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
393 {
394  return detail_do(p_result, mctx, request, request->packet, &request->request_pairs, false);
395 }
396 
397 /*
398  * Outgoing Access-Request Reply - write the detail files.
399  */
400 static unlang_action_t CC_HINT(nonnull) mod_post_auth(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
401 {
402  return detail_do(p_result, mctx, request, request->reply, &request->reply_pairs, false);
403 }
404 
405 static int call_env_filename_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules,
406  CONF_ITEM *ci,
407  call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule)
408 {
410  tmpl_t *parsed;
411  CONF_PAIR const *to_parse = cf_item_to_pair(ci);
412  tmpl_rules_t our_rules;
413 
414  our_rules = *t_rules;
418  our_rules.escape.mode = TMPL_ESCAPE_PRE_CONCAT;
419  our_rules.literals_safe_for = our_rules.escape.safe_for;
420 
421  if (tmpl_afrom_substr(ctx, &parsed,
422  &FR_SBUFF_IN(cf_pair_value(to_parse), talloc_array_length(cf_pair_value(to_parse)) - 1),
424  &our_rules) < 0) return -1;
425 
426  *(void **)out = parsed;
427  return 0;
428 }
429 
430 static int call_env_suppress_parse(TALLOC_CTX *ctx, call_env_parsed_head_t *out, tmpl_rules_t const *t_rules,
431  CONF_ITEM *ci,
432  UNUSED call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule)
433 {
434  CONF_SECTION const *cs = cf_item_to_section(ci);
436  call_env_parsed_t *parsed;
437  CONF_ITEM const *to_parse = NULL;
438  char const *attr;
439  fr_dict_attr_t const *da;
440  fr_hash_table_t *ht;
441 
442  MEM(parsed = call_env_parsed_add(ctx, out,
444 
445  ht = fr_hash_table_alloc(parsed, detail_hash, detail_cmp, NULL);
446 
447  while ((to_parse = cf_item_next(cs, to_parse))) {
448  if (!cf_item_is_pair(to_parse)) continue;
449 
450  attr = cf_pair_attr(cf_item_to_pair(to_parse));
451  if (!attr) continue;
452 
453  da = fr_dict_attr_search_by_qualified_oid(NULL, t_rules->attr.dict_def, attr, false, false);
454  if (!da) {
455  cf_log_perr(to_parse, "Failed resolving attribute");
456  return -1;
457  }
458 
459  /*
460  * Be kind to minor mistakes
461  */
462  if (fr_hash_table_find(ht, da)) {
463  cf_log_warn(to_parse, "Ignoring duplicate entry '%s'", attr);
464  continue;
465  }
466 
467  if (!fr_hash_table_insert(ht, da)) {
468  cf_log_perr(to_parse, "Failed inserting '%s' into suppression table", attr);
469  return -1;
470  }
471 
472  DEBUG("%s - '%s' suppressed, will not appear in detail output", cf_section_name(parent), attr);
473  }
474 
475  /*
476  * Clear up if nothing is actually to be suppressed
477  */
478  if (fr_hash_table_num_elements(ht) == 0) {
479  talloc_free(ht);
480  call_env_parsed_free(out, parsed);
481  return 0;
482  }
483 
484  fr_hash_table_fill(ht);
485  call_env_parsed_set_data(parsed, ht);
486 
487  return 0;
488 }
489 
492  .env = (call_env_parser_t[]){
493  { FR_CALL_ENV_PARSE_OFFSET("filename", FR_TYPE_STRING, CALL_ENV_FLAG_REQUIRED, rlm_detail_env_t, filename, filename_tmpl),
494  .pair.func = call_env_filename_parse },
496  .pair.dflt = "%t", .pair.dflt_quote = T_DOUBLE_QUOTED_STRING },
499  }
500 };
501 
502 /* globally exported name */
503 extern module_rlm_t rlm_detail;
505  .common = {
506  .magic = MODULE_MAGIC_INIT,
507  .name = "detail",
508  .inst_size = sizeof(rlm_detail_t),
511  },
512  .method_group = {
513  .bindings = (module_method_binding_t[]){
514  { .section = SECTION_NAME("accounting", CF_IDENT_ANY), .method = mod_accounting, .method_env = &method_env },
515  { .section = SECTION_NAME("recv", "accounting-request"), .method = mod_accounting, .method_env = &method_env },
516  { .section = SECTION_NAME("send", "accounting-response"), .method = mod_accounting, .method_env = &method_env },
517  { .section = SECTION_NAME("recv", CF_IDENT_ANY), .method = mod_authorize, .method_env = &method_env },
518  { .section = SECTION_NAME("send", CF_IDENT_ANY), .method = mod_post_auth, .method_env = &method_env },
520  }
521  }
522 };
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition: action.h:35
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
Definition: action.h:37
#define RCSID(id)
Definition: build.h:481
#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:110
#define unlikely(_x)
Definition: build.h:379
#define UNUSED
Definition: build.h:313
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:718
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:631
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:688
#define CALL_ENV_TERMINATOR
Definition: call_env.h:231
#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:360
#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:235
@ 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:224
#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:407
#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:335
#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:384
Per method call config.
Definition: call_env.h:175
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:627
#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:268
#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:282
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:564
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:632
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition: cf_util.c:664
char const * cf_pair_attr(CONF_PAIR const *pair)
Return the attr of a CONF_PAIR.
Definition: cf_util.c:1578
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition: cf_util.c:1594
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition: cf_util.c:684
fr_token_t cf_pair_value_quote(CONF_PAIR const *pair)
Return the value (rhs) quoting of a pair.
Definition: cf_util.c:1638
char const * cf_section_name(CONF_SECTION const *cs)
Return name2 if set, else name1.
Definition: cf_util.c:1197
#define cf_log_err(_cf, _fmt,...)
Definition: cf_util.h:289
#define cf_parent(_cf)
Definition: cf_util.h:101
#define cf_log_perr(_cf, _fmt,...)
Definition: cf_util.h:296
#define cf_log_warn(_cf, _fmt,...)
Definition: cf_util.h:290
#define cf_item_next(_ci, _curr)
Definition: cf_util.h:92
#define CF_IDENT_ANY
Definition: cf_util.h:78
#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:3081
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:3263
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition: dict.h:267
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition: dict.h:280
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_dict_t const * fr_dict_by_da(fr_dict_attr_t const *da)
Attempt to locate the protocol dictionary containing an attribute.
Definition: dict_util.c:2606
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:3382
Specifies an attribute which must be present for the module to function.
Definition: dict.h:266
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition: dict.h:279
#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:506
int exfile_close(exfile_t *ef, int fd)
Close the log file.
Definition: exfile.c:562
uint32_t fr_hash(void const *data, size_t size)
Definition: hash.c:812
void fr_hash_table_fill(fr_hash_table_t *ht)
Ensure all buckets are filled.
Definition: hash.c:719
void * fr_hash_table_find(fr_hash_table_t *ht, void const *data)
bool fr_hash_table_insert(fr_hash_table_t *ht, void const *data)
#define fr_hash_table_alloc(_ctx, _hash_node, _cmp_node, _free_node)
Definition: hash.h:58
uint32_t fr_hash_table_num_elements(fr_hash_table_t *ht)
#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:292
int rad_filename_box_make_safe(fr_value_box_t *vb, UNUSED void *uxtc)
Definition: util.c:167
talloc_free(reap)
@ FR_TYPE_TLV
Contains nested attributes.
Definition: merged_model.c:118
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
@ FR_TYPE_UINT16
16 Bit unsigned integer.
Definition: merged_model.c:98
@ FR_TYPE_UINT32
32 Bit unsigned integer.
Definition: merged_model.c:99
@ FR_TYPE_VOID
User data.
Definition: merged_model.c:127
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
Definition: merged_model.c:91
unsigned int uint32_t
Definition: merged_model.c:33
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, char const *trigger_prefix, fr_pair_list_t *trigger_args)
Initialise a module specific exfile handle.
Definition: module_rlm.c:116
module_t common
Common fields presented by all modules.
Definition: module_rlm.h:39
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp)
Copy a single valuepair.
Definition: pair.c:489
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:770
int fr_perm_gid_from_str(TALLOC_CTX *ctx, gid_t *out, char const *name)
Resolve a group name to a GID.
Definition: perm.c:345
static const conf_parser_t config[]
Definition: base.c:183
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
static rs_t * conf
Definition: radsniff.c:53
#define RETURN_MODULE_OK
Definition: rcode.h:57
rlm_rcode_t
Return codes indicating the result of the module call.
Definition: rcode.h:40
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition: rcode.h:42
static void detail_fr_pair_fprint(TALLOC_CTX *ctx, FILE *out, fr_pair_t const *stacked)
Definition: rlm_detail.c:198
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:405
static fr_dict_attr_t const * attr_user_password
Definition: rlm_detail.c:99
bool group_is_set
Whether group was set.
Definition: rlm_detail.c:52
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:430
static fr_dict_attr_t const * attr_protocol
Definition: rlm_detail.c:97
fr_value_box_t filename
File / path to write to.
Definition: rlm_detail.c:64
static fr_dict_attr_t const * attr_net_dst_port
Definition: rlm_detail.c:96
gid_t group
Resolved group.
Definition: rlm_detail.c:51
static const call_env_method_t method_env
Definition: rlm_detail.c:490
static fr_dict_t const * dict_freeradius
Definition: rlm_detail.c:82
int detail_group_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
static fr_dict_attr_t const * attr_net
Definition: rlm_detail.c:92
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:93
static fr_dict_t const * dict_radius
Definition: rlm_detail.c:83
tmpl_t * filename_tmpl
tmpl used to expand filename (for debug output)
Definition: rlm_detail.c:65
exfile_t * ef
Log file handler.
Definition: rlm_detail.c:60
#define WRITE(fmt,...)
uint32_t perm
Permissions to use for new files.
Definition: rlm_detail.c:50
bool log_srcdst
Add IP src/dst attributes to entries.
Definition: rlm_detail.c:56
static unlang_action_t mod_accounting(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition: rlm_detail.c:384
fr_value_box_t header
Header format.
Definition: rlm_detail.c:66
static unlang_action_t mod_authorize(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition: rlm_detail.c:392
static fr_dict_attr_t const * attr_net_dst_address
Definition: rlm_detail.c:94
module_rlm_t rlm_detail
Definition: rlm_detail.c:504
fr_dict_attr_autoload_t rlm_detail_dict_attr[]
Definition: rlm_detail.c:102
static const conf_parser_t module_config[]
Definition: rlm_detail.c:73
static uint32_t detail_hash(void const *data)
Definition: rlm_detail.c:167
static void fr_pair_fprint(FILE *fp, fr_pair_t const *vp)
Print one attribute and value to FP.
Definition: rlm_detail.c:125
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, bool compat, fr_hash_table_t *ht)
Write a single detail entry to file pointer.
Definition: rlm_detail.c:222
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:95
static int mod_instantiate(module_inst_ctx_t const *mctx)
Definition: rlm_detail.c:181
fr_dict_autoload_t rlm_detail_dict[]
Definition: rlm_detail.c:86
static int8_t detail_cmp(void const *a, void const *b)
Definition: rlm_detail.c:173
fr_hash_table_t * ht
Holds suppressed attributes.
Definition: rlm_detail.c:67
static unlang_action_t detail_do(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request, fr_packet_t *packet, fr_pair_list_t *list, bool compat)
Definition: rlm_detail.c:323
static unlang_action_t mod_post_auth(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition: rlm_detail.c:400
Instance configuration for rlm_detail.
Definition: rlm_detail.c:49
static char const * name
static int instantiate(module_inst_ctx_t const *mctx)
Definition: rlm_rest.c:1302
#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:329
void * data
Module's instance data.
Definition: module.h:271
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition: module.h:151
Named methods exported by a module.
Definition: module.h:173
tmpl_escape_t escape
How escaping should be handled during evaluation.
Definition: tmpl.h:358
fr_value_box_safe_for_t literals_safe_for
safe_for value assigned to literal values in xlats, execs, and data.
Definition: tmpl.h:356
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:344
Optional arguments passed to vp_tmpl functions.
Definition: tmpl.h:341
static char buff[sizeof("18446744073709551615")+3]
Definition: size_tests.c:41
RETURN_MODULE_FAIL
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
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:285
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:282
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 func
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
fr_value_box_safe_for_t safe_for
Value to set on boxes which have been escaped by the fr_value_box_escape_t function.
Definition: tmpl_escape.h:83
tmpl_escape_mode_t mode
Whether to apply escape function after concatenation, i.e.
Definition: tmpl_escape.h:86
@ 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.
Definition: pair_inline.c:125
#define PAIR_VERIFY(_x)
Definition: pair.h:191
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:104
#define fr_pair_list_foreach_leaf(_list_head, _iter)
Iterate over the leaf nodes of a fr_pair_list_t.
Definition: pair.h:272
static fr_slen_t parent
Definition: pair.h:851
fr_sbuff_parse_rules_t const * value_parse_rules_quoted[T_TOKEN_LAST]
Parse rules for quoted strings.
Definition: value.c:606
static fr_slen_t data
Definition: value.h:1265
uintptr_t fr_value_box_safe_for_t
Escaping that's been applied to a value box.
Definition: value.h:155
int nonnull(2, 5))
#define fr_box_uint32(_val)
Definition: value.h:312
static size_t char ** out
Definition: value.h:997