The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
log.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
5  * (at 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: 66def098fb2e293d9a6e82c24fe52646e75c67ff $
19  *
20  * @brief Logging functions used by the server core.
21  * @file src/lib/server/log.c
22  *
23  * @copyright 2000,2006 The FreeRADIUS server project
24  * @copyright 2000 Miquel van Smoorenburg (miquels@cistron.nl)
25  * @copyright 2000 Alan DeKok (aland@freeradius.org)
26  * @copyright 2001 Chad Miller (cmiller@surfsouth.com)
27  */
28 RCSID("$Id: 66def098fb2e293d9a6e82c24fe52646e75c67ff $")
29 
30 #include <freeradius-devel/server/base.h>
31 #include <freeradius-devel/util/debug.h>
32 
33 #ifdef HAVE_SYS_STAT_H
34 # include <sys/stat.h>
35 #endif
36 
37 #include <fcntl.h>
38 
39 #ifdef HAVE_SYSLOG_H
40 # include <syslog.h>
41 #endif
42 
43 #include <sys/file.h>
44 #include <pthread.h>
45 
46 static _Thread_local TALLOC_CTX *fr_vlog_request_pool;
47 static _Thread_local fr_sbuff_t *fr_log_request_oid_buff;
48 
49 /** Syslog facility table
50  *
51  * Maps syslog facility keywords, to the syslog facility macros defined
52  * in the system's syslog.h.
53  *
54  * @note Not all facilities are supported by every operating system.
55  * If a facility is unavailable it will not appear in the table.
56  */
58 #ifdef LOG_AUTH
59  { L("auth"), LOG_AUTH },
60 #endif
61 
62 #ifdef LOG_AUTHPRIV
63  { L("authpriv"), LOG_AUTHPRIV },
64 #endif
65 
66 #ifdef LOG_CRON
67  { L("cron"), LOG_CRON },
68 #endif
69 
70 #ifdef LOG_DAEMON
71  { L("daemon"), LOG_DAEMON },
72 #endif
73 
74 #ifdef LOG_FTP
75  { L("ftp"), LOG_FTP },
76 #endif
77 
78 #ifdef LOG_KERN
79  { L("kern"), LOG_KERN },
80 #endif
81 
82 #ifdef LOG_LOCAL0
83  { L("local0"), LOG_LOCAL0 },
84 #endif
85 
86 #ifdef LOG_LOCAL1
87  { L("local1"), LOG_LOCAL1 },
88 #endif
89 
90 #ifdef LOG_LOCAL2
91  { L("local2"), LOG_LOCAL2 },
92 #endif
93 
94 #ifdef LOG_LOCAL3
95  { L("local3"), LOG_LOCAL3 },
96 #endif
97 
98 #ifdef LOG_LOCAL4
99  { L("local4"), LOG_LOCAL4 },
100 #endif
101 
102 #ifdef LOG_LOCAL5
103  { L("local5"), LOG_LOCAL5 },
104 #endif
105 
106 #ifdef LOG_LOCAL6
107  { L("local6"), LOG_LOCAL6 },
108 #endif
109 
110 #ifdef LOG_LOCAL7
111  { L("local7"), LOG_LOCAL7 },
112 #endif
113 
114 #ifdef LOG_LPR
115  { L("lpr"), LOG_LPR },
116 #endif
117 
118 #ifdef LOG_MAIL
119  { L("mail"), LOG_MAIL },
120 #endif
121 
122 #ifdef LOG_NEWS
123  { L("news"), LOG_NEWS },
124 #endif
125 
126 #ifdef LOG_USER
127  { L("user"), LOG_USER },
128 #endif
129 
130 #ifdef LOG_UUCP
131  { L("uucp"), LOG_UUCP }
132 #endif
133 };
135 
136 /** Syslog severity table
137  *
138  * Maps syslog severity keywords, to the syslog severity macros defined
139  * in the system's syslog.h file.
140  *
141  */
143 #ifdef LOG_ALERT
144  { L("alert"), LOG_ALERT },
145 #endif
146 
147 #ifdef LOG_CRIT
148  { L("critical"), LOG_CRIT },
149 #endif
150 
151 #ifdef LOG_DEBUG
152  { L("debug"), LOG_DEBUG },
153 #endif
154 
155 #ifdef LOG_EMERG
156  { L("emergency"), LOG_EMERG },
157 #endif
158 
159 #ifdef LOG_ERR
160  { L("error"), LOG_ERR },
161 #endif
162 
163 #ifdef LOG_INFO
164  { L("info"), LOG_INFO },
165 #endif
166 
167 #ifdef LOG_NOTICE
168  { L("notice"), LOG_NOTICE },
169 #endif
170 
171 #ifdef LOG_WARNING
172  { L("warning"), LOG_WARNING },
173 #endif
174 };
176 
178  { L("file"), L_DST_FILES },
179  { L("files"), L_DST_FILES },
180  { L("null"), L_DST_NULL },
181  { L("stderr"), L_DST_STDERR },
182  { L("stdout"), L_DST_STDOUT },
183  { L("syslog"), L_DST_SYSLOG },
184 };
186 
187 static char const spaces[] = " ";
188 
190 
193  { .out = &dict_freeradius, .proto = "freeradius" },
194  { NULL }
195 };
196 
198 
201  { .out = &attr_module_failure_message, .name = "Module-Failure-Message", .type = FR_TYPE_STRING, .dict = &dict_freeradius },
202  { NULL }
203 };
204 
205 typedef struct {
206  char const *name; //!< name of this logging destination
207  fr_log_t *log; //!< pointer to the log structure
208  CONF_SECTION *cs; //!< where this log configuration came from
209 
210  fr_rb_node_t name_node; //!< tree by name
211  fr_rb_node_t filename_node; //!< tree by name
213 
214 typedef struct {
215  char const *name; //!< name of this logging source
216  uint32_t id; //!< LOG_ID of this source
217  fr_log_t *original; //!< the original fr_log_t
218  fr_log_t **log; //!< where the logs should go
219 
220  fr_rb_node_t name_node; //!< tree by name only
221  fr_rb_node_t id_node; //!< tree by ID
222 } fr_log_src_t;
223 
224 static fr_rb_tree_t *dst_tree = NULL;
226 static fr_rb_tree_t *src_tree = NULL;
227 
228 /** Send a server log message to its destination without evaluating its debug level
229  *
230  * @param[in] log destination.
231  * @param[in] type of log message.
232  * @param[in] file src file the log message was generated in.
233  * @param[in] line number the log message was generated on.
234  * @param[in] fmt with printf style substitution tokens.
235  * @param[in] ... Substitution arguments.
236  */
237 
238 static CC_HINT(format (printf, 5, 6))
240  char const *file, int line,
241  char const *fmt, ...)
242 {
243  va_list ap;
244 
245  va_start(ap, fmt);
246  fr_vlog(log, type, file, line, fmt, ap);
247  va_end(ap);
248 }
249 
250 /** Whether a request specific debug message should be logged
251  *
252  * @param lvl of debugging this message should be logged at.
253  * @param request The current request.
254  * @return
255  * - true if message should be logged.
256  * - false if message shouldn't be logged.
257  */
258 inline bool log_rdebug_enabled(fr_log_lvl_t lvl, request_t const *request)
259 {
260  if (!request->log.dst) return false;
261 
262  if (lvl <= request->log.lvl) return true;
263 
264  return false;
265 }
266 
267 /** Cleanup the memory pool used by vlog_request
268  *
269  */
270 static int _fr_vlog_request_pool_free(void *arg)
271 {
272  return talloc_free(arg);
273 }
274 
275 /** Send a log message to its destination, possibly including fields from the request
276  *
277  * @param[in] type of log message, #L_ERR, #L_WARN, #L_INFO, #L_DBG.
278  * @param[in] lvl Minimum required server or request level to output this message.
279  * @param[in] request The current request.
280  * @param[in] file src file the log message was generated in.
281  * @param[in] line number the log message was generated on.
282  * @param[in] fmt with printf style substitution tokens.
283  * @param[in] ap Substitution arguments.
284  * @param[in] uctx The #fr_log_t specifying the destination for log messages.
285  */
287  char const *file, int line,
288  char const *fmt, va_list ap, void *uctx)
289 {
290  char const *filename;
291  FILE *fp = NULL;
292 
293  char *p;
294  char const *extra = "";
295  uint8_t unlang_indent, module_indent;
296  va_list aq;
297 
298  char const *fmt_location = "";
299  char const *fmt_prefix = "";
300  char const *fmt_module = "";
301  char const *fmt_exp;
302 
303  fr_log_t *log_dst = uctx;
304  TALLOC_CTX *pool;
305 
306  /*
307  * No output means no output.
308  */
309  if (!log_dst) return;
310  if (!log_rdebug_enabled(lvl, request)) return;
311 
312  /*
313  * Allocate a thread local, 4k pool so we don't
314  * need to keep allocating memory on the heap.
315  */
316  pool = fr_vlog_request_pool;
317  if (!pool) {
318  pool = talloc_pool(NULL, 4096);
319  if (!pool) {
320  fr_perror("Failed allocating memory for vlog_request_pool");
321  return;
322  }
324  }
325 
326  filename = log_dst->file;
327 
328  /*
329  * Debug messages get treated specially.
330  */
331  if ((type & L_DBG) != 0) {
332  /*
333  * If we're debugging to a file, then use that.
334  *
335  * @todo: have fr_vlog() take a fr_log_t*, so
336  * that we can cache the opened descriptor, and
337  * we don't need to re-open it on every log
338  * message.
339  */
340  switch (log_dst->dst) {
341  case L_DST_FILES:
342  fp = fopen(log_dst->file, "a");
343  if (!fp) goto finish;
344  break;
345 
346 #if defined(HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN)
347  case L_DST_FUNC:
348  {
349 # ifdef HAVE_FOPENCOOKIE
351 
352  /*
353  * These must be set separately as they have different prototypes.
354  */
355  io.read = NULL;
356  io.seek = NULL;
357  io.close = NULL;
358  io.write = log_dst->cookie_write;
359 
360  fp = fopencookie(log_dst->cookie, "w", io);
361 # else
362  fp = funopen(log_dst->cookie, NULL, log_dst->cookie_write, NULL, NULL);
363 
364 # endif
365  if (!fp) goto finish;
366  }
367  break;
368 #endif
369  default:
370  break;
371  }
372  goto print_fmt;
373  }
374 
375  if (filename) {
376  char *exp;
377  log_dst_t *dst;
378 
379  dst = request->log.dst;
380 
381  /*
382  * Prevent infinitely recursive calls if
383  * xlat_aeval attempts to write to the request log.
384  */
385  request->log.dst = NULL;
386 
387  /*
388  * This is SLOW! Doing it for every log message
389  * in every request is NOT recommended!
390  */
391  if (xlat_aeval(request, &exp, request, filename, rad_filename_escape, NULL) < 0) return;
392 
393  /*
394  * Restore the original logging function
395  */
396  request->log.dst = dst;
397 
398  /*
399  * Ensure the directory structure exists, for
400  * where we're going to write the log file.
401  */
402  p = strrchr(exp, FR_DIR_SEP);
403  if (p) {
404  *p = '\0';
405  if (fr_mkdir(NULL, exp, -1, S_IRWXU, NULL, NULL) < 0) {
406  ERROR("Failed creating %s: %s", exp, fr_syserror(errno));
407  talloc_free(exp);
408  return;
409  }
410  *p = FR_DIR_SEP;
411  }
412 
413  fp = fopen(exp, "a");
414  talloc_free(exp);
415  }
416 
417 print_fmt:
418  /*
419  * Request prefix i.e.
420  *
421  * (0) <fmt>
422  */
423  if (request->name) {
424  if ((request->seq_start == 0) || (request->number == request->seq_start)) {
425  fmt_prefix = talloc_typed_asprintf(pool, "(%s) ", request->name);
426  } else {
427  fmt_prefix = talloc_typed_asprintf(pool, "(%s,%" PRIu64 ") ",
428  request->name, request->seq_start);
429  }
430  }
431 
432  /*
433  * Make sure the indent isn't set to something crazy
434  */
435  unlang_indent = request->log.indent.unlang > sizeof(spaces) - 1 ?
436  sizeof(spaces) - 1 :
437  request->log.indent.unlang;
438 
439  module_indent = request->log.indent.module > sizeof(spaces) - 1 ?
440  sizeof(spaces) - 1 :
441  request->log.indent.module;
442 
443  /*
444  * Module name and indentation i.e.
445  *
446  * test - <fmt>
447  */
448  if (request->module) {
449  fmt_module = talloc_typed_asprintf(pool, "%s - %.*s", request->module, module_indent, spaces);
450  }
451 
452  /*
453  * If we don't copy the original ap we get a segfault from vasprintf. This is apparently
454  * due to ap sometimes being implemented with a stack offset which is invalidated if
455  * ap is passed into another function. See here:
456  * http://julipedia.meroh.net/2011/09/using-vacopy-to-safely-pass-ap.html
457  *
458  * I don't buy that explanation, but doing a va_copy here does prevent SEGVs seen when
459  * running unit tests which generate errors under CI.
460  */
461  va_copy(aq, ap);
462  if (!log_dst->suppress_secrets) {
463  fmt_exp = fr_vasprintf(pool, fmt, aq);
464  } else {
465  fmt_exp = fr_vasprintf_secure(pool, fmt, aq);
466  }
467  va_end(aq);
468 
469  /*
470  * Logging to a file descriptor
471  */
472  if (fp) {
473  char time_buff[64]; /* The current timestamp */
474 
475  time_t timeval;
476  timeval = time(NULL);
477 
478 #if 0
479  fmt_location = talloc_typed_asprintf(pool, "%s[%i]: ", file, line);
480 #endif
481 
482 #ifdef HAVE_GMTIME_R
483  if (log_dates_utc) {
484  struct tm utc;
485  gmtime_r(&timeval, &utc);
486  ASCTIME_R(&utc, time_buff, sizeof(time_buff));
487  } else
488 #endif
489  {
490  CTIME_R(&timeval, time_buff, sizeof(time_buff));
491  }
492 
493  /*
494  * Strip trailing new lines
495  */
496  p = strrchr(time_buff, '\n');
497  if (p) p[0] = '\0';
498 
499  fprintf(fp,
500  "%s" /* location */
501  "%s" /* prefix */
502  "%s : " /* time */
503  "%s" /* facility */
504  "%.*s" /* indent */
505  "%s" /* module */
506  "%s" /* message */
507  "\n",
508  fmt_location,
509  fmt_prefix,
510  time_buff,
512  unlang_indent, spaces,
513  fmt_module,
514  fmt_exp);
515  fclose(fp);
516  goto finish;
517  }
518 
519  /*
520  * Logging everywhere else
521  */
522  if (!DEBUG_ENABLED3) switch (type) {
523  case L_DBG_WARN:
524  extra = "WARNING: ";
526  break;
527 
528  case L_DBG_ERR:
529  extra = "ERROR: ";
531  break;
532  default:
533  break;
534  }
535 
537  "%s" /* prefix */
538  "%.*s" /* indent */
539  "%s" /* module */
540  "%s" /* extra */
541  "%s", /* message */
542  fmt_prefix,
543  unlang_indent, spaces,
544  fmt_module,
545  extra,
546  fmt_exp);
547 
548 finish:
549  talloc_free_children(pool);
550 }
551 
552 /** Add a module failure message fr_pair_t to the request
553  *
554  * @param[in] request The current request.
555  * @param[in] fmt with printf style substitution tokens.
556  * @param[in] ap Substitution arguments.
557  */
558 static void vlog_module_failure_msg(request_t *request, char const *fmt, va_list ap)
559 {
560  char *p;
561  fr_pair_t *vp;
562  va_list aq;
563 
564  if (!fmt || !request || !request->packet) return;
565 
567 
569 
570  /*
571  * If we don't copy the original ap we get a segfault from vasprintf. This is apparently
572  * due to ap sometimes being implemented with a stack offset which is invalidated if
573  * ap is passed into another function. See here:
574  * http://julipedia.meroh.net/2011/09/using-vacopy-to-safely-pass-ap.html
575  *
576  * I don't buy that explanation, but doing a va_copy here does prevent SEGVs seen when
577  * running unit tests which generate errors under CI.
578  */
579  va_copy(aq, ap);
580  p = fr_vasprintf(vp, fmt, aq);
581  va_end(aq);
582 
583  if (request->module && (request->module[0] != '\0')) {
584  fr_pair_value_aprintf(vp, "%s: %s", request->module, p);
585  talloc_free(p);
586  } else {
588  }
589 }
590 
591 /** Marshal variadic log arguments into a va_list and pass to normal logging functions
592  *
593  * @see log_request_error for more details.
594  *
595  * @param[in] type the log category.
596  * @param[in] lvl of debugging this message should be logged at.
597  * @param[in] request The current request.
598  * @param[in] file src file the log message was generated in.
599  * @param[in] line number the log message was generated on.
600  * @param[in] fmt with printf style substitution tokens.
601  * @param[in] ... Substitution arguments.
602  */
604  char const *file, int line, char const *fmt, ...)
605 {
606  va_list ap;
607  log_dst_t *dst;
608 
609  if (!request->log.dst) return;
610 
611  va_start(ap, fmt);
612  for (dst = request->log.dst; dst; dst = dst->next) {
613  if (lvl > dst->lvl) continue;
614 
615  dst->func(type, lvl, request, file, line, fmt, ap, dst->uctx);
616  }
617  va_end(ap);
618 }
619 
620 /** Marshal variadic log arguments into a va_list and pass to error logging functions
621  *
622  * This could all be done in a macro, but it turns out some implementations of the
623  * variadic macros do not work at all well if the va_list being written to is further
624  * up the stack (which is required as you still need a function to convert the ellipsis
625  * into a va_list).
626  *
627  * So, we use this small wrapper function instead, which will hopefully guarantee
628  * consistent behaviour.
629  *
630  * @param[in] type the log category.
631  * @param[in] lvl of debugging this message should be logged at.
632  * @param[in] request The current request.
633  * @param[in] file src file the log message was generated in.
634  * @param[in] line number the log message was generated on.
635  * @param[in] fmt with printf style substitution tokens.
636  * @param[in] ... Substitution arguments.
637  */
639  char const *file, int line, char const *fmt, ...)
640 {
641  va_list ap;
642  log_dst_t *dst_p;
643 
644  if (!request->log.dst) return;
645 
646  va_start(ap, fmt);
647  for (dst_p = request->log.dst; dst_p; dst_p = dst_p->next) {
648  dst_p->func(type, lvl, request, file, line, fmt, ap, dst_p->uctx);
649  }
650  if ((type == L_ERR) || (type == L_DBG_ERR) || (type == L_DBG_ERR_REQ)) {
651  vlog_module_failure_msg(request, fmt, ap);
652  }
653 
654  va_end(ap);
655 }
656 
657 /** Drain any outstanding messages from the fr_strerror buffers
658  *
659  * This function drains any messages from fr_strerror buffer adding a prefix (fmt)
660  * to the first message.
661  *
662  * @param[in] type the log category.
663  * @param[in] lvl of debugging this message should be logged at.
664  * @param[in] request The current request.
665  * @param[in] file src file the log message was generated in.
666  * @param[in] line number the log message was generated on.
667  * @param[in] fmt with printf style substitution tokens.
668  * @param[in] ... Substitution arguments.
669  */
671  char const *file, int line, char const *fmt, ...)
672 {
673  char const *error;
674 
675  if (!request->log.dst) return;
676 
677  /*
678  * No strerror gets us identical behaviour to log_request_error
679  */
680  error = fr_strerror_pop();
681  if (!error) {
682  va_list ap;
683  log_dst_t *dst_p;
684 
685  if (!fmt) return; /* NOOP */
686 
687  va_start(ap, fmt);
688  for (dst_p = request->log.dst; dst_p; dst_p = dst_p->next) {
689  dst_p->func(type, lvl, request, file, line, fmt, ap, dst_p->uctx);
690  }
691  if ((type == L_ERR) || (type == L_DBG_ERR) || (type == L_DBG_ERR_REQ)) {
692  vlog_module_failure_msg(request, fmt, ap);
693  }
694  va_end(ap);
695 
696  return; /* DONE */
697  }
698 
699  /*
700  * Concatenate fmt with fr_strerror()
701  */
702  if (fmt) {
703  va_list ap;
704  char *tmp;
705 
706  va_start(ap, fmt);
707  tmp = fr_vasprintf(request, fmt, ap);
708  va_end(ap);
709 
710  if (!tmp) return;
711 
712  log_request_error(type, lvl, request, file, line, "%s: %s", tmp, error);
713  talloc_free(tmp);
714  } else {
715  log_request_error(type, lvl, request, file, line, "%s", error);
716  }
717 
718  /*
719  * Only the first message gets the prefix
720  */
721  while ((error = fr_strerror_pop())) log_request_error(type, lvl, request, file, line, "%s", error);
722 }
723 
724 /** Cleanup the memory pool used by the OID sbuff
725  *
726  */
727 static int _fr_log_request_oid_buff_free(void *arg)
728 {
729  return talloc_free(arg);
730 }
731 
732 /** Allocate an extensible sbuff for printing OID strings
733  *
734  */
735 static inline CC_HINT(always_inline) fr_sbuff_t *log_request_oid_buff(void)
736 {
737  fr_sbuff_t *sbuff;
739 
740  sbuff = fr_log_request_oid_buff;
741  if (unlikely(!sbuff)) {
742  sbuff = talloc(NULL, fr_sbuff_t);
743  if (!sbuff) {
744  fr_perror("Failed allocating memory for fr_log_request_oid_buff");
745  return NULL;
746  }
747  tctx = talloc(sbuff, fr_sbuff_uctx_talloc_t);
748  if (!tctx) {
749  fr_perror("Failed allocating memory for fr_sbuff_uctx_talloc_t");
750  talloc_free(sbuff);
751  return NULL;
752  }
753 
754  fr_sbuff_init_talloc(sbuff, sbuff, tctx, 1024, (FR_DICT_ATTR_MAX_NAME_LEN + 1) * FR_DICT_MAX_TLV_STACK);
755 
757  } else {
758  fr_sbuff_set(sbuff, fr_sbuff_start(sbuff)); /* Reset position */
759  }
760 
761  return sbuff;
762 }
763 
764 /** Print a #fr_pair_t.
765  *
766  * @param[in] lvl Debug lvl (1-4).
767  * @param[in] request to read logging params from.
768  * @param[in] parent of pair to print, may be NULL.
769  * @param[in] vp to print.
770  * @param[in] prefix (optional).
771  */
773  fr_pair_t const *parent, fr_pair_t const *vp, char const *prefix)
774 {
775  fr_dict_attr_t const *parent_da = NULL;
776  fr_sbuff_t *oid_buff;
777 
778  if (!request->log.dst) return;
779 
780  if (!log_rdebug_enabled(lvl, request)) return;
781 
782  PAIR_VERIFY(vp);
783 
784  oid_buff = log_request_oid_buff();
785 
786  if (parent && (parent->vp_type != FR_TYPE_GROUP)) parent_da = parent->da;
787  if (fr_dict_attr_oid_print(oid_buff, parent_da, vp->da, false) <= 0) return;
788 
789  /*
790  * Recursively print grouped attributes.
791  */
792  switch (vp->vp_type) {
793  case FR_TYPE_STRUCTURAL:
794  RDEBUGX(lvl, "%s%pV {", prefix ? prefix : "",
795  fr_box_strvalue_len(fr_sbuff_start(oid_buff), fr_sbuff_used(oid_buff)));
796  log_request_pair_list(lvl, request, vp, &vp->vp_group, NULL);
797  RDEBUGX(lvl, "}");
798  break;
799 
800  case FR_TYPE_QUOTED:
801  RDEBUGX(lvl, "%s%pV = \"%pV\"", prefix ? prefix : "",
802  fr_box_strvalue_len(fr_sbuff_start(oid_buff), fr_sbuff_used(oid_buff)),
803  &vp->data);
804  break;
805  default:
806  RDEBUGX(lvl, "%s%pV = %pV", prefix ? prefix : "",
807  fr_box_strvalue_len(fr_sbuff_start(oid_buff), fr_sbuff_used(oid_buff)),
808  &vp->data);
809  break;
810  }
811 }
812 
813 /** Print a #fr_pair_list_t
814  *
815  * @param[in] lvl Debug lvl (1-4).
816  * @param[in] request to read logging params from.
817  * @param[in] parent of vps to print, may be NULL.
818  * @param[in] vps to print.
819  * @param[in] prefix (optional).
820  */
822  fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
823 {
824  if (fr_pair_list_empty(vps) || !request->log.dst) return;
825 
826  if (!log_rdebug_enabled(lvl, request)) return;
827 
828  RINDENT();
829  fr_pair_list_foreach(vps, vp) {
830  PAIR_VERIFY(vp);
831 
832  log_request_pair(lvl, request, parent, vp, prefix);
833  }
834  REXDENT();
835 }
836 
837 /** Print a list of protocol fr_pair_ts.
838  *
839  * @param[in] lvl Debug lvl (1-4).
840  * @param[in] request to read logging params from.
841  * @param[in] parent of vps to print, may be NULL.
842  * @param[in] vps to print.
843  * @param[in] prefix (optional).
844  */
846  fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
847 {
848  if (fr_pair_list_empty(vps) || !request->log.dst) return;
849 
850  if (!log_rdebug_enabled(lvl, request)) return;
851 
852  RINDENT();
853  fr_pair_list_foreach(vps, vp) {
854  PAIR_VERIFY(vp);
855 
856  if (!fr_dict_attr_common_parent(fr_dict_root(request->dict), vp->da, true)) continue;
857 
858  log_request_pair(lvl, request, parent, vp, prefix);
859  }
860  REXDENT();
861 }
862 
863 /** Write the string being parsed, and a marker showing where the parse error occurred
864  *
865  * @param[in] type the log category.
866  * @param[in] lvl of debugging this message should be logged at.
867  * @param[in] request The current request.
868  * @param[in] file src file the log message was generated in.
869  * @param[in] line number the log message was generated on.
870  * @param[in] str Subject string we're printing a marker for.
871  * @param[in] str_len Subject string length. Use SIZE_MAX for the
872  * length of the string.
873  * @param[in] marker_idx The position of the marker relative to the string.
874  * @param[in] marker_fmt What the parse error was.
875  * @param[in] ... Arguments for fmt string.
876  */
878  char const *file, int line,
879  char const *str, size_t str_len,
880  ssize_t marker_idx, char const *marker_fmt, ...)
881 {
882  char const *ellipses = "";
883  rindent_t indent;
884  va_list ap;
885  char *error;
886  static char const marker_spaces[] = " "; /* 60 */
887 
888  if (str_len == SIZE_MAX) str_len = strlen(str);
889 
890  if (marker_idx < 0) marker_idx = marker_idx * -1;
891 
892  if ((size_t)marker_idx >= sizeof(marker_spaces)) {
893  size_t offset = (marker_idx - (sizeof(marker_spaces) - 1)) + (sizeof(marker_spaces) * 0.75);
894  marker_idx -= offset;
895  str += offset;
896  str_len -= offset;
897 
898  ellipses = "... ";
899  }
900 
901  /*
902  * Don't want format markers being indented
903  */
904  indent = request->log.indent;
905  request->log.indent.module = 0;
906  request->log.indent.unlang = 0;
907 
908  va_start(ap, marker_fmt);
909  error = fr_vasprintf(request, marker_fmt, ap);
910  va_end(ap);
911 
912  log_request(type, lvl, request, file, line, "%s%.*s", ellipses, (int)str_len, str);
913  log_request(type, lvl, request, file, line, "%s%.*s^ %s", ellipses, (int) marker_idx, marker_spaces, error);
914  talloc_free(error);
915 
916  request->log.indent = indent;
917 }
918 
920  char const *file, int line,
921  uint8_t const *data, size_t data_len)
922 {
923  size_t i, j, len;
924  char buffer[(0x10 * 3) + 1];
925  char *p, *end = buffer + sizeof(buffer);
926 
927  for (i = 0; i < data_len; i += 0x10) {
928  len = 0x10;
929  if ((i + len) > data_len) len = data_len - i;
930 
931  for (p = buffer, j = 0; j < len; j++, p += 3) snprintf(p, end - p, "%02x ", data[i + j]);
932  log_request(type, lvl, request, file, line, "%04x: %s", (int)i, buffer);
933  }
934 }
935 
936 /** Function to provide as the readable callback to the event loop
937  *
938  * Writes any data read from a file descriptor to the request log,
939  * tries very hard not to chop lines in the middle, but will split
940  * at 1024 byte boundaries if forced to.
941  *
942  * @param[in] el UNUSED
943  * @param[in] fd UNUSED
944  * @param[in] flags UNUSED
945  * @param[in] uctx Pointer to a log_fd_event_ctx_t
946  */
947 void log_request_fd_event(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, void *uctx)
948 {
949  char buffer[1024];
950  log_fd_event_ctx_t *log_info = uctx;
951  request_t *request = log_info->request;
952  fr_sbuff_t sbuff;
953  fr_sbuff_marker_t m_start, m_end;
954 
955  fr_sbuff_term_t const line_endings = FR_SBUFF_TERMS(L("\n"), L("\r"));
956 
957  if (!RDEBUG_ENABLEDX(log_info->lvl)) {
958  while (read(fd, buffer, sizeof(buffer) > 0));
959  return;
960  }
961 
962  fr_sbuff_init_out(&sbuff, buffer, sizeof(buffer));
963  fr_sbuff_marker(&m_start, &sbuff);
964  fr_sbuff_marker(&m_end, &sbuff);
965 
966 #ifndef NDEBUG
967  memset(buffer, 0x42, sizeof(buffer));
968 #endif
969 
970  for (;;) {
971  ssize_t slen;
972 
973  slen = read(fd, fr_sbuff_current(&m_end), fr_sbuff_remaining(&m_end));
974  if (slen < 0) {
975  if (errno == EINTR) continue;
976 
977  /*
978  * This can happen if the I/O handler is
979  * manually called to clear out any pending
980  * data, and we're using a nonblocking FD.
981  *
982  * This can happen with the exec code if
983  * the EVFILT_PROC event gets passed before
984  * the EVFILT_READ event.
985  */
986  if (errno == EWOULDBLOCK) slen = 0;
987  }
988  if ((slen < 0) && (errno == EINTR)) continue;
989 
990  if (slen > 0) fr_sbuff_advance(&m_end, slen);
991 
992  while (fr_sbuff_ahead(&m_end) > 0) {
993  fr_sbuff_adv_until(&sbuff, fr_sbuff_ahead(&m_end), &line_endings, '\0');
994 
995  /*
996  * Incomplete line, try and read the rest.
997  */
998  if ((slen > 0) && (fr_sbuff_used(&m_start) > 0) &&
999  !fr_sbuff_is_terminal(&sbuff, &line_endings)) {
1000  break;
1001  }
1002 
1003  log_request(log_info->type, log_info->lvl, log_info->request,
1004  __FILE__, __LINE__,
1005  "%s%s%pV",
1006  log_info->prefix ? log_info->prefix : "",
1007  log_info->prefix ? " - " : "",
1009  fr_sbuff_behind(&m_start)));
1010 
1011  fr_sbuff_advance(&sbuff, 1); /* Skip the whitespace */
1012  fr_sbuff_set(&m_start, &sbuff);
1013  }
1014 
1015  /*
1016  * Error or done
1017  */
1018  if (slen <= 0) break;
1019 
1020  /*
1021  * Clear out the existing data
1022  */
1023  fr_sbuff_shift(&sbuff, fr_sbuff_used(&m_start));
1024  }
1025 }
1026 
1027 /** Log a fatal error, then exit
1028  *
1029  */
1030 void log_fatal(fr_log_t const *log, char const *file, int line, char const *fmt, ...)
1031 {
1032  va_list ap;
1033 
1034  va_start(ap, fmt);
1035  fr_vlog(log, L_ERR, file, line, fmt, ap);
1036  va_end(ap);
1037 
1038  fr_exit_now(EXIT_FAILURE);
1039 }
1040 
1041 /** Register a logging destination.
1042  *
1043  */
1044 static void log_register_dst(char const *name, fr_log_t *log, CONF_SECTION *cs)
1045 {
1046  fr_log_track_t *dst;
1047 
1048  MEM(dst = talloc_zero(dst_tree, fr_log_track_t));
1049  dst->name = name;
1050  dst->log = log;
1051  dst->cs = cs;
1052 
1053  fr_rb_insert(dst_tree, dst);
1054 
1055  if (log->dst != L_DST_FILES) return;
1056 
1058 }
1059 
1060 /** Get a logging destination by name.
1061  *
1062  */
1064 {
1065  fr_log_track_t find, *found;
1066 
1067  memset(&find, 0, sizeof(find));
1068  find.name = name;
1069 
1070  found = fr_rb_find(dst_tree, &find);
1071  return (found) ? found->log : NULL;
1072 }
1073 
1074 static int _log_free(fr_log_t *log)
1075 {
1076  fr_assert(log->dst == L_DST_FILES);
1077 
1078  fclose(log->handle);
1079  return 0;
1080 }
1081 
1082 static char const *log_destination = NULL;
1083 static bool log_timestamp;
1085 
1086 /*
1087  * Parse an fr_log_t configuration.
1088  */
1089 static const conf_parser_t log_config[] = {
1090  { FR_CONF_POINTER("destination", FR_TYPE_STRING, 0, &log_destination), .dflt = "file" },
1091 #if 0
1092  /*
1093  * @todo - once we allow this, also check that there's only _one_ destination
1094  * which uses syslog_facility.
1095  */
1096  { FR_CONF_OFFSET("syslog_facility", main_config_t, syslog_facility), .dflt = "daemon",
1097  .func = cf_table_parse_int,
1098  .uctx = &(cf_table_parse_ctx_t){
1099  .table = syslog_facility_table,
1101  }
1102  },
1103 #endif
1104  { FR_CONF_POINTER_IS_SET("timestamp", FR_TYPE_BOOL, 0, &log_timestamp) },
1105  { FR_CONF_OFFSET("file", fr_log_t, file), },
1106  { FR_CONF_OFFSET("colourise", fr_log_t, colourise) },
1107  { FR_CONF_OFFSET("line_number", fr_log_t, line_number) },
1108  { FR_CONF_OFFSET("use_utc", fr_log_t, dates_utc) },
1109  { FR_CONF_OFFSET("print_level", fr_log_t, print_level) },
1111 };
1112 
1113 /** Parse a named logging section.
1114  *
1115  * @todo - we should probably allow for TCP sockets, too. But then
1116  * those can block. So we then also need a way to buffer outbound
1117  * log messages, and discard log messages if the buffer is full.
1118  *
1119  * This should probably be done with a FILE*, and L_DST_FUNC.
1120  */
1122 {
1123  fr_log_track_t *dst;
1124  fr_log_t *log;
1125  char const *name;
1126 
1127  name = cf_section_name2(cs);
1128  if (!name) name = cf_section_name1(cs);
1129 
1130  dst = fr_rb_find(dst_tree, &(fr_log_track_t) {
1131  .name = name,
1132  });
1133  if (dst) {
1134  fr_strerror_printf("Cannot add duplicate log destination '%s'", name);
1135  return -1;
1136  }
1137 
1138  MEM(log = talloc_zero(dst_tree, fr_log_t));
1139 
1140  if (cf_section_rules_push(cs, log_config) < 0) {
1141  error:
1142  talloc_free(log);
1143  return -1;
1144  }
1145 
1146  if (cf_section_parse(log, log, cs) < 0) goto error;
1147 
1149  switch (log->dst) {
1150  case L_DST_NUM_DEST:
1151  fr_strerror_printf("Unknown log_destination '%s'", log_destination);
1153  log_destination = NULL;
1154  goto error;
1155 
1156 #ifdef HAVE_SYSLOG_H
1157  case L_DST_SYSLOG:
1159  log_destination = NULL;
1160 
1161  if (fr_log_init_syslog(log) < 0) goto error;
1162  break;
1163 #endif
1164 
1165  case L_DST_STDOUT:
1167  log_destination = NULL;
1168 
1169  if (fr_log_init_std(log, L_DST_STDOUT) < 0) goto error;
1170  break;
1171 
1172  case L_DST_STDERR:
1174  log_destination = NULL;
1175 
1176  if (fr_log_init_std(log, L_DST_STDERR) < 0) goto error;
1177  break;
1178 
1179  case L_DST_FILES:
1181  log_destination = NULL;
1182 
1183  if (!log->file) {
1184  fr_strerror_const("Specified \"files\" as a log destination, but no log filename was given!");
1185  goto error;
1186  }
1187 
1189  .log = log,
1190  });
1191  if (dst) {
1192  fr_strerror_printf("The log destination '%s' is already logging to file %s",
1193  dst->name, log->file);
1194  goto error;
1195  }
1196 
1197  if (fr_log_init_file(log, log->file) < 0) goto error;
1198 
1199  talloc_set_destructor(log, _log_free);
1200  break;
1201 
1202  case L_DST_NULL:
1203  break;
1204 
1205  default:
1207  log_destination = NULL;
1208 
1209  fr_assert(0);
1210  break;
1211  }
1212 
1213  if (log_timestamp_is_set) {
1215  } else {
1216  log->timestamp = L_TIMESTAMP_AUTO;
1217  }
1218 
1219  log_register_dst(name, log, cs);
1220 
1221  return 0;
1222 }
1223 
1224 static int8_t _log_track_name_cmp(void const *two, void const *one)
1225 {
1226  fr_log_track_t const *a = one;
1227  fr_log_track_t const *b = two;
1228 
1229  return CMP(strcmp(a->name, b->name), 0);
1230 }
1231 
1232 static int8_t _log_track_filename_cmp(void const *two, void const *one)
1233 {
1234  fr_log_track_t const *a = one;
1235  fr_log_track_t const *b = two;
1236 
1237  fr_assert(a->log);
1238  fr_assert(a->log->dst == L_DST_FILES);
1239 
1240  fr_assert(b->log);
1241  fr_assert(b->log->dst == L_DST_FILES);
1242 
1243  return CMP(strcmp(a->log->file, b->log->file), 0);
1244 }
1245 
1246 /** Initialises the server logging functionality, and the underlying libfreeradius log
1247  *
1248  * @note Call log free when the server is done to fix any spurious memory leaks.
1249  *
1250  * @param[in] log Logging parameters.
1251  * @param[in] daemonize Changes what we do with stdout/stderr.
1252  * @return
1253  * - 0 on success.
1254  * - -1 on failure.
1255  */
1256 int log_global_init(fr_log_t *log, bool daemonize)
1257 {
1258  int ret;
1259 
1260  ret = fr_log_init_legacy(log, daemonize);
1261  if (ret < 0) return ret;
1262 
1263  if (fr_dict_autoload(log_dict) < 0) {
1264  fr_perror("log_init");
1265  return -1;
1266  }
1267 
1269  fr_perror("log_init");
1270  return -1;
1271  }
1272 
1273  dst_tree = fr_rb_inline_alloc(NULL, fr_log_track_t, name_node,
1274  _log_track_name_cmp, NULL);
1275  if (!dst_tree) {
1276  fr_perror("log_init");
1277  return -1;
1278  }
1279 
1280  filename_tree = fr_rb_inline_alloc(NULL, fr_log_track_t, filename_node,
1281  _log_track_filename_cmp, NULL);
1282  if (!filename_tree) {
1283  fr_perror("log_init");
1284  return -1;
1285  }
1286 
1287  log_register_dst("default", log, NULL);
1288 
1289  return ret;
1290 }
1291 
1293 {
1295  TALLOC_FREE(src_tree);
1296  TALLOC_FREE(dst_tree);
1297  TALLOC_FREE(filename_tree);
1298 }
static int const char char buffer[256]
Definition: acutest.h:574
int const char * file
Definition: acutest.h:702
va_end(args)
static int const char * fmt
Definition: acutest.h:573
int const char int line
Definition: acutest.h:702
va_start(args, fmt)
#define fr_atexit_thread_local(_name, _free, _uctx)
Definition: atexit.h:221
#define RCSID(id)
Definition: build.h:444
#define L(_str)
Helper for initialising arrays of string literals.
Definition: build.h:207
#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:378
#define UNUSED
Definition: build.h:313
#define NUM_ELEMENTS(_t)
Definition: build.h:335
int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs)
Parse a configuration section into user-supplied variables.
Definition: cf_parse.c:985
int cf_table_parse_int(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Generic function for parsing conf pair values as int.
Definition: cf_parse.c:1474
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:626
#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_POINTER_IS_SET(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result, recording if a defaul...
Definition: cf_parse.h:325
#define cf_section_rules_push(_cs, _rule)
Definition: cf_parse.h:658
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
Definition: cf_parse.h:310
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:563
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:89
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition: cf_util.c:1126
char const * cf_section_name1(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition: cf_util.c:1112
static fr_atomic_queue_t * aq
Definition: control_test.c:47
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
Definition: debug.h:232
#define ERROR(fmt,...)
Definition: dhcpclient.c:41
#define fr_dict_autofree(_to_free)
Definition: dict.h:674
fr_dict_attr_t const * fr_dict_attr_common_parent(fr_dict_attr_t const *a, fr_dict_attr_t const *b, bool is_ancestor)
Find a common ancestor that two TLV type attributes share.
Definition: dict_util.c:1631
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition: dict.h:250
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition: dict.h:263
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition: dict_util.c:1997
int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
Definition: dict_util.c:3647
#define fr_dict_autoload(_to_load)
Definition: dict.h:671
#define FR_DICT_MAX_TLV_STACK
Maximum TLV stack size.
Definition: dict.h:384
#define FR_DICT_ATTR_MAX_NAME_LEN
Maximum length of a attribute name.
Definition: dict.h:364
Specifies an attribute which must be present for the module to function.
Definition: dict.h:249
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition: dict.h:262
ssize_t fr_mkdir(int *fd_out, char const *path, ssize_t len, mode_t mode, fr_mkdir_func_t func, void *uctx)
Create directories that are missing in the specified path.
Definition: file.c:200
FILE * fopencookie(void *cookie, const char *mode, cookie_io_functions_t io_funcs)
Definition: fopencookie.c:99
cookie_close_function_t close
Definition: fopencookie.h:55
cookie_seek_function_t seek
Definition: fopencookie.h:54
cookie_read_function_t read
Definition: fopencookie.h:52
cookie_write_function_t write
Definition: fopencookie.h:53
static fr_rb_tree_t * filename_tree
Definition: log.c:225
void log_request_hex(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, uint8_t const *data, size_t data_len)
Definition: log.c:919
static const conf_parser_t log_config[]
Definition: log.c:1089
static bool log_timestamp
Definition: log.c:1083
static fr_sbuff_t * log_request_oid_buff(void)
Allocate an extensible sbuff for printing OID strings.
Definition: log.c:735
fr_rb_node_t filename_node
tree by name
Definition: log.c:211
static int8_t _log_track_name_cmp(void const *two, void const *one)
Definition: log.c:1224
static fr_dict_attr_t const * attr_module_failure_message
Definition: log.c:197
void log_request_proto_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a list of protocol fr_pair_ts.
Definition: log.c:845
static char const * log_destination
Definition: log.c:1082
fr_log_t * log_dst_by_name(char const *name)
Get a logging destination by name.
Definition: log.c:1063
fr_rb_node_t id_node
tree by ID
Definition: log.c:221
fr_table_num_sorted_t const log_destination_table[]
Definition: log.c:177
void log_request(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Marshal variadic log arguments into a va_list and pass to normal logging functions.
Definition: log.c:603
int log_global_init(fr_log_t *log, bool daemonize)
Initialises the server logging functionality, and the underlying libfreeradius log.
Definition: log.c:1256
static fr_rb_tree_t * dst_tree
Definition: log.c:224
static _Thread_local fr_sbuff_t * fr_log_request_oid_buff
Definition: log.c:47
fr_dict_autoload_t log_dict[]
Definition: log.c:192
static fr_dict_t const * dict_freeradius
Definition: log.c:189
static int _fr_log_request_oid_buff_free(void *arg)
Cleanup the memory pool used by the OID sbuff.
Definition: log.c:727
void log_request_perror(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Drain any outstanding messages from the fr_strerror buffers.
Definition: log.c:670
static int _log_free(fr_log_t *log)
Definition: log.c:1074
size_t log_destination_table_len
Definition: log.c:185
bool log_rdebug_enabled(fr_log_lvl_t lvl, request_t const *request)
Whether a request specific debug message should be logged.
Definition: log.c:258
fr_rb_node_t name_node
tree by name only
Definition: log.c:220
static int8_t _log_track_filename_cmp(void const *two, void const *one)
Definition: log.c:1232
void log_request_marker(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *str, size_t str_len, ssize_t marker_idx, char const *marker_fmt,...)
Write the string being parsed, and a marker showing where the parse error occurred.
Definition: log.c:877
void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a fr_pair_list_t.
Definition: log.c:821
int log_parse_section(CONF_SECTION *cs)
Parse a named logging section.
Definition: log.c:1121
fr_table_num_sorted_t const syslog_severity_table[]
Syslog severity table.
Definition: log.c:142
fr_dict_attr_autoload_t log_dict_attr[]
Definition: log.c:200
fr_log_t ** log
where the logs should go
Definition: log.c:218
static fr_rb_tree_t * src_tree
Definition: log.c:226
fr_log_t * original
the original fr_log_t
Definition: log.c:217
void log_fatal(fr_log_t const *log, char const *file, int line, char const *fmt,...)
Log a fatal error, then exit.
Definition: log.c:1030
static void vlog_module_failure_msg(request_t *request, char const *fmt, va_list ap)
Add a module failure message fr_pair_t to the request.
Definition: log.c:558
fr_log_t * log
pointer to the log structure
Definition: log.c:207
void log_request_fd_event(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, void *uctx)
Function to provide as the readable callback to the event loop.
Definition: log.c:947
size_t syslog_facility_table_len
Definition: log.c:134
static bool log_timestamp_is_set
Definition: log.c:1084
static void log_always(fr_log_t const *log, fr_log_type_t type, char const *file, int line, char const *fmt,...)
Send a server log message to its destination without evaluating its debug level.
Definition: log.c:239
CONF_SECTION * cs
where this log configuration came from
Definition: log.c:208
size_t syslog_severity_table_len
Definition: log.c:175
static char const spaces[]
Definition: log.c:187
char const * name
name of this logging source
Definition: log.c:215
void log_request_error(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Marshal variadic log arguments into a va_list and pass to error logging functions.
Definition: log.c:638
char const * name
name of this logging destination
Definition: log.c:206
uint32_t id
LOG_ID of this source.
Definition: log.c:216
void vlog_request(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt, va_list ap, void *uctx)
Send a log message to its destination, possibly including fields from the request.
Definition: log.c:286
static void log_register_dst(char const *name, fr_log_t *log, CONF_SECTION *cs)
Register a logging destination.
Definition: log.c:1044
void log_request_pair(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_t const *vp, char const *prefix)
Print a fr_pair_t.
Definition: log.c:772
fr_rb_node_t name_node
tree by name
Definition: log.c:210
static _Thread_local TALLOC_CTX * fr_vlog_request_pool
Definition: log.c:46
fr_table_num_sorted_t const syslog_facility_table[]
Syslog facility table.
Definition: log.c:57
void log_global_free(void)
Definition: log.c:1292
static int _fr_vlog_request_pool_free(void *arg)
Cleanup the memory pool used by vlog_request.
Definition: log.c:270
#define REXDENT()
Exdent (unindent) R* messages by one level.
Definition: log.h:443
fr_log_lvl_t lvl
Log messages with lvl >= to this should be logged.
Definition: log.h:73
request_t * request
request to log messages in the context of.
Definition: log.h:86
#define RDEBUG_ENABLEDX(_x)
True if specified lvl is enabled.
Definition: log.h:338
#define RDEBUGX(_l, fmt,...)
Definition: log.h:340
fr_log_lvl_t lvl
Priority of the message.
Definition: log.h:85
void * uctx
Context to pass to the logging function.
Definition: log.h:72
log_dst_t * next
Next logging destination.
Definition: log.h:74
#define DEBUG_ENABLED3
True if global debug level 1-3 messages are enabled.
Definition: log.h:259
char const * prefix
To add to log messages.
Definition: log.h:87
fr_log_type_t type
What type of log message it is.
Definition: log.h:84
log_func_t func
Function to call to log to this destination.
Definition: log.h:71
#define RINDENT()
Indent R* messages by one level.
Definition: log.h:430
Definition: log.h:70
Context structure for the log fd event function.
Definition: log.h:83
Definition: log.h:40
size_t rad_filename_escape(UNUSED request_t *request, char *out, size_t outlen, char const *in, UNUSED void *arg)
Escapes the raw string such that it should be safe to use as part of a file path.
Definition: util.c:214
talloc_free(reap)
Stores all information relating to an event list.
Definition: event.c:411
fr_table_num_ordered_t const fr_log_levels[]
Maps log categories to message prefixes.
Definition: log.c:244
int fr_log_init_legacy(fr_log_t *log, bool daemonize)
Initialise file descriptors based on logging destination.
Definition: log.c:923
int fr_log_init_syslog(fr_log_t *log)
Initialise a syslog logging destination.
Definition: log.c:1145
int fr_log_init_std(fr_log_t *log, fr_log_dst_t dst_type)
Initialise log dst for stdout, stderr or /dev/null.
Definition: log.c:1044
int fr_log_init_file(fr_log_t *log, char const *file)
Initialise a file logging destination.
Definition: log.c:1099
void fr_vlog(fr_log_t const *log, fr_log_type_t type, char const *file, int line, char const *fmt, va_list ap)
Send a server log message to its destination.
Definition: log.c:343
bool log_dates_utc
Definition: log.c:288
@ L_DST_NULL
Discard log messages.
Definition: log.h:83
@ L_DST_STDERR
Log to stderr.
Definition: log.h:81
@ L_DST_FILES
Log to a file on disk.
Definition: log.h:79
@ L_DST_FUNC
Send log messages to a FILE*, via fopencookie()
Definition: log.h:82
@ L_DST_NUM_DEST
Definition: log.h:84
@ L_DST_STDOUT
Log to stdout.
Definition: log.h:78
@ L_DST_SYSLOG
Log to syslog.
Definition: log.h:80
@ L_TIMESTAMP_ON
Always log timestamps.
Definition: log.h:90
@ L_TIMESTAMP_OFF
Never log timestamps.
Definition: log.h:91
@ L_TIMESTAMP_AUTO
Timestamp logging preference not specified.
Definition: log.h:88
fr_log_lvl_t
Definition: log.h:67
fr_log_type_t
Definition: log.h:54
@ L_DBG_WARN_REQ
Less severe warning only displayed when debugging is enabled.
Definition: log.h:63
@ L_ERR
Error message.
Definition: log.h:56
@ L_DBG_ERR
Error only displayed when debugging is enabled.
Definition: log.h:62
@ L_DBG_ERR_REQ
Less severe error only displayed when debugging is enabled.
Definition: log.h:64
@ L_DBG_WARN
Warning only displayed when debugging is enabled.
Definition: log.h:61
@ L_DBG
Only displayed when debugging is enabled.
Definition: log.h:59
Main server configuration.
Definition: main_config.h:51
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
@ FR_TYPE_BOOL
A truth value.
Definition: merged_model.c:95
@ FR_TYPE_GROUP
A grouping of other attributes.
Definition: merged_model.c:124
unsigned int uint32_t
Definition: merged_model.c:33
long int ssize_t
Definition: merged_model.c:24
ssize_t fr_dict_attr_oid_print(fr_sbuff_t *out, fr_dict_attr_t const *ancestor, fr_dict_attr_t const *da, bool numeric)
Definition: merged_model.c:188
unsigned char uint8_t
Definition: merged_model.c:30
struct tm * gmtime_r(time_t const *l_clock, struct tm *result)
Definition: missing.c:201
int fr_pair_value_aprintf(fr_pair_t *vp, char const *fmt,...)
Print data into an "string" data type.
Definition: pair.c:2695
int fr_pair_value_strdup_shallow(fr_pair_t *vp, char const *src, bool tainted)
Assign a buffer containing a nul terminated string to a vp, but don't copy it.
Definition: pair.c:2655
char * fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
Definition: print.c:853
char * fr_vasprintf_secure(TALLOC_CTX *ctx, char const *fmt, va_list ap)
Definition: print.c:858
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
Definition: rb.c:624
void * fr_rb_find(fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
Definition: rb.c:576
#define fr_rb_inline_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black tree.
Definition: rb.h:271
The main red black tree structure.
Definition: rb.h:73
static char const * name
size_t fr_sbuff_shift(fr_sbuff_t *sbuff, size_t shift)
Shift the contents of the sbuff, returning the number of bytes we managed to shift.
Definition: sbuff.c:187
bool fr_sbuff_is_terminal(fr_sbuff_t *in, fr_sbuff_term_t const *tt)
Efficient terminal string search.
Definition: sbuff.c:2111
size_t fr_sbuff_adv_until(fr_sbuff_t *sbuff, size_t len, fr_sbuff_term_t const *tt, char escape_chr)
Wind position until we hit a character in the terminal set.
Definition: sbuff.c:1811
#define fr_sbuff_start(_sbuff_or_marker)
#define fr_sbuff_set(_dst, _src)
#define fr_sbuff_current(_sbuff_or_marker)
#define FR_SBUFF_TERMS(...)
Initialise a terminal structure with a list of sorted strings.
Definition: sbuff.h:167
#define fr_sbuff_init_out(_out, _start, _len_or_end)
#define fr_sbuff_advance(_sbuff_or_marker, _len)
#define fr_sbuff_remaining(_sbuff_or_marker)
#define fr_sbuff_used(_sbuff_or_marker)
#define fr_sbuff_behind(_sbuff_or_marker)
#define fr_sbuff_ahead(_sbuff_or_marker)
Set of terminal elements.
Definition: merged_model.c:161
Talloc sbuff extension structure.
Definition: sbuff.h:114
#define pair_prepend_request(_attr, _da)
Allocate and prepend a fr_pair_t to the request list.
Definition: pair.h:77
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition: snprintf.c:689
fr_assert(0)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
fr_aka_sim_id_type_t type
fr_pair_t * vp
Definition: log.h:96
fr_log_dst_t dst
Log destination.
Definition: log.h:97
fr_log_timestamp_t timestamp
Prefix log messages with timestamps.
Definition: log.h:110
char const * file
Path to log file.
Definition: log.h:113
FILE * handle
Path to log file.
Definition: log.h:116
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 fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
Definition: table.h:134
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition: table.h:253
An element in a lexicographically sorted array of name to num mappings.
Definition: table.h:45
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition: talloc.c:380
static int talloc_const_free(void const *ptr)
Free const'd memory.
Definition: talloc.h:212
static fr_event_list_t * el
ssize_t xlat_aeval(TALLOC_CTX *ctx, char **out, request_t *request, char const *fmt, xlat_escape_legacy_t escape, void const *escape_ctx))
Definition: xlat_eval.c:1470
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:190
#define fr_pair_list_foreach(_list_head, _iter)
Iterate over the contents of a fr_pair_list_t.
Definition: pair.h:260
static fr_slen_t parent
Definition: pair.h:844
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
Definition: strerror.c:733
char const * fr_strerror_pop(void)
Pop the last library error.
Definition: strerror.c:681
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64
#define fr_strerror_const(_msg)
Definition: strerror.h:223
#define FR_TYPE_QUOTED
Definition: types.h:292
#define FR_TYPE_STRUCTURAL
Definition: types.h:296
static fr_slen_t data
Definition: value.h:1259
#define fr_box_strvalue_len(_val, _len)
Definition: value.h:279
int format(printf, 5, 0))