28RCSID(
"$Id: 520be9d127d0ef2f097b486752105788dd41418c $")
30#include <freeradius-devel/util/debug.h>
31#include <freeradius-devel/util/dict.h>
32#include <freeradius-devel/util/log.h>
33#include <freeradius-devel/util/syserror.h>
34#include <freeradius-devel/util/file.h>
36#include <freeradius-devel/server/log.h>
37#include <freeradius-devel/server/pair.h>
38#include <freeradius-devel/server/util.h>
40#include <freeradius-devel/unlang/xlat.h>
68 {
L(
"auth"), LOG_AUTH },
72 {
L(
"authpriv"), LOG_AUTHPRIV },
76 {
L(
"cron"), LOG_CRON },
80 {
L(
"daemon"), LOG_DAEMON },
84 {
L(
"ftp"), LOG_FTP },
88 {
L(
"kern"), LOG_KERN },
92 {
L(
"local0"), LOG_LOCAL0 },
96 {
L(
"local1"), LOG_LOCAL1 },
100 {
L(
"local2"), LOG_LOCAL2 },
104 {
L(
"local3"), LOG_LOCAL3 },
108 {
L(
"local4"), LOG_LOCAL4 },
112 {
L(
"local5"), LOG_LOCAL5 },
116 {
L(
"local6"), LOG_LOCAL6 },
120 {
L(
"local7"), LOG_LOCAL7 },
124 {
L(
"lpr"), LOG_LPR },
128 {
L(
"mail"), LOG_MAIL },
132 {
L(
"news"), LOG_NEWS },
136 {
L(
"user"), LOG_USER },
140 {
L(
"uucp"), LOG_UUCP }
153 {
L(
"alert"), LOG_ALERT },
157 {
L(
"critical"), LOG_CRIT },
161 {
L(
"debug"), LOG_DEBUG },
165 {
L(
"emergency"), LOG_EMERG },
169 {
L(
"error"), LOG_ERR },
173 {
L(
"info"), LOG_INFO },
177 {
L(
"notice"), LOG_NOTICE },
181 {
L(
"warning"), LOG_WARNING },
247static CC_HINT(format (printf, 5, 6))
250 char const *
fmt, ...)
269 if (!request->log.dst)
return false;
271 if (lvl <= request->log.lvl)
return true;
297 char const *
fmt, va_list ap,
void *uctx)
299 char const *filename;
303 char const *extra =
"";
304 uint8_t unlang_indent, module_indent;
307 char const *fmt_location =
"";
308 char const *fmt_prefix =
"";
309 char const *fmt_module =
"";
327 pool = talloc_pool(NULL, 4096);
329 fr_perror(
"Failed allocating memory for vlog_request_pool");
351 fp = fopen(
log_dst->file,
"a");
352 if (!fp)
goto finish;
355#if defined(HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN)
358# ifdef HAVE_FOPENCOOKIE
371 fp = funopen(
log_dst->cookie, NULL,
log_dst->cookie_write, NULL, NULL);
374 if (!fp)
goto finish;
388 dst = request->log.dst;
394 request->log.dst = NULL;
405 request->log.dst = dst;
411 p = strrchr(exp, FR_DIR_SEP);
414 if (
fr_mkdir(NULL, exp, -1, S_IRWXU, NULL, NULL) < 0) {
422 fp = fopen(exp,
"a");
433 if ((request->seq_start == 0) || (request->number == request->seq_start)) {
437 request->name, request->seq_start);
444 unlang_indent = request->log.indent.unlang >
sizeof(
spaces) - 1 ?
446 request->log.indent.unlang;
448 module_indent = request->log.indent.module >
sizeof(
spaces) - 1 ?
450 request->log.indent.module;
457 if (request->module) {
471 if (!
log_dst->suppress_secrets) {
485 timeval = time(NULL);
495 ASCTIME_R(&utc, time_buff,
sizeof(time_buff));
499 CTIME_R(&timeval, time_buff,
sizeof(time_buff));
505 p = strrchr(time_buff,
'\n');
558 talloc_free_children(pool);
573 if (!
fmt || !request || !request->packet)
return;
592 if (request->module && (request->module[0] !=
'\0')) {
618 if (!request->log.dst)
return;
621 for (dst = request->log.dst; dst; dst = dst->
next) {
622 if (lvl > dst->
lvl)
continue;
653 if (!request->log.dst)
return;
656 for (dst_p = request->log.dst; dst_p; dst_p = dst_p->
next) {
684 if (!request->log.dst)
return;
697 for (dst_p = request->log.dst; dst_p; dst_p = dst_p->
next) {
753 fr_perror(
"Failed allocating memory for fr_log_request_oid_buff");
758 fr_perror(
"Failed allocating memory for fr_sbuff_uctx_talloc_t");
787 if (!request->log.dst)
return;
801 switch (
vp->vp_type) {
803 RDEBUGX(lvl,
"%s%pV {", prefix ? prefix :
"",
810 RDEBUGX(lvl,
"%s%pV = \"%pV\"", prefix ? prefix :
"",
815 RDEBUGX(lvl,
"%s%pV = %pV", prefix ? prefix :
"",
888 char const *str,
size_t str_len,
889 ssize_t marker_idx,
char const *marker_fmt, ...)
891 char const *ellipses =
"";
895 static char const marker_spaces[] =
" ";
897 if (str_len == SIZE_MAX) str_len = strlen(str);
899 if (marker_idx < 0) marker_idx = marker_idx * -1;
901 if ((
size_t)marker_idx >=
sizeof(marker_spaces)) {
902 size_t offset = (marker_idx - (
sizeof(marker_spaces) - 1)) + (
sizeof(marker_spaces) * 0.75);
903 marker_idx -= offset;
913 indent = request->log.indent;
914 request->log.indent.module = 0;
915 request->log.indent.unlang = 0;
925 request->log.indent = indent;
933 char buffer[(0x10 * 3) + 1];
936 for (i = 0; i < data_len; i += 0x10) {
938 if ((i + len) > data_len) len = data_len - i;
940 for (p =
buffer, j = 0; j < len; j++, p += 3)
snprintf(p, end - p,
"%02x ",
data[i + j]);
972 fr_sbuff_marker(&m_start, &sbuff);
973 fr_sbuff_marker(&m_end, &sbuff);
984 if (errno == EINTR)
continue;
995 if (errno == EWOULDBLOCK) slen = 0;
997 if ((slen < 0) && (errno == EINTR))
continue;
1016 log_info->
prefix ?
" - " :
"",
1027 if (slen <= 0)
break;
1078 memset(&find, 0,
sizeof(find));
1082 return (found) ? found->
log : NULL;
1195 fr_strerror_const(
"Specified \"files\" as a log destination, but no log filename was given!");
1272 if (ret < 0)
return ret;
static int const char char buffer[256]
static int const char * fmt
#define fr_atexit_thread_local(_name, _free, _uctx)
#define L(_str)
Helper for initialising arrays of string literals.
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs)
Parse a configuration section into user-supplied variables.
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.
#define CONF_PARSER_TERMINATOR
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
#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
#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...
#define cf_section_rules_push(_cs, _rule)
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
Defines a CONF_PAIR to C data type mapping.
A section grouping multiple CONF_PAIR.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
static fr_atomic_queue_t * aq
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
#define fr_dict_autofree(_to_free)
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.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
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.
#define fr_dict_autoload(_to_load)
#define FR_DICT_MAX_TLV_STACK
Maximum TLV stack size.
#define FR_DICT_ATTR_MAX_NAME_LEN
Maximum length of a attribute name.
Specifies an attribute which must be present for the module to function.
Specifies a dictionary which must be loaded/loadable for the module to function.
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.
FILE * fopencookie(void *cookie, const char *mode, cookie_io_functions_t io_funcs)
cookie_close_function_t close
cookie_seek_function_t seek
cookie_read_function_t read
cookie_write_function_t write
static fr_rb_tree_t * filename_tree
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)
static const conf_parser_t log_config[]
static bool log_timestamp
fr_rb_node_t filename_node
tree by name
static int8_t _log_track_name_cmp(void const *two, void const *one)
static fr_sbuff_t * log_request_oid_buff(void)
Allocate an extensible sbuff for printing OID strings.
static fr_dict_attr_t const * attr_module_failure_message
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.
static char const * log_destination
fr_rb_node_t id_node
tree by ID
fr_table_num_sorted_t const log_destination_table[]
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.
int log_global_init(fr_log_t *log, bool daemonize)
Initialises the server logging functionality, and the underlying libfreeradius log.
static fr_rb_tree_t * dst_tree
static _Thread_local fr_sbuff_t * fr_log_request_oid_buff
fr_dict_autoload_t log_dict[]
static fr_dict_t const * dict_freeradius
static int _fr_log_request_oid_buff_free(void *arg)
Cleanup the memory pool used by the OID sbuff.
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.
static int _log_free(fr_log_t *log)
size_t log_destination_table_len
bool log_rdebug_enabled(fr_log_lvl_t lvl, request_t const *request)
Whether a request specific debug message should be logged.
fr_rb_node_t name_node
tree by name only
static int8_t _log_track_filename_cmp(void const *two, void const *one)
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.
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.
int log_parse_section(CONF_SECTION *cs)
Parse a named logging section.
fr_table_num_sorted_t const syslog_severity_table[]
Syslog severity table.
fr_log_t * log_dst_by_name(char const *name)
Get a logging destination by name.
fr_dict_attr_autoload_t log_dict_attr[]
fr_log_t ** log
where the logs should go
static fr_rb_tree_t * src_tree
fr_log_t * original
the original fr_log_t
void log_fatal(fr_log_t const *log, char const *file, int line, char const *fmt,...)
Log a fatal error, then exit.
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.
fr_log_t * log
pointer to the log structure
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.
size_t syslog_facility_table_len
static bool log_timestamp_is_set
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.
CONF_SECTION * cs
where this log configuration came from
size_t syslog_severity_table_len
static char const spaces[]
char const * name
name of this logging source
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.
char const * name
name of this logging destination
uint32_t id
LOG_ID of this source.
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.
static void log_register_dst(char const *name, fr_log_t *log, CONF_SECTION *cs)
Register a logging destination.
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.
fr_rb_node_t name_node
tree by name
static _Thread_local TALLOC_CTX * fr_vlog_request_pool
fr_table_num_sorted_t const syslog_facility_table[]
Syslog facility table.
void log_global_free(void)
static int _fr_vlog_request_pool_free(void *arg)
Cleanup the memory pool used by vlog_request.
#define REXDENT()
Exdent (unindent) R* messages by one level.
fr_log_lvl_t lvl
Log messages with lvl >= to this should be logged.
request_t * request
request to log messages in the context of.
#define RDEBUG_ENABLEDX(_x)
True if specified lvl is enabled.
#define RDEBUGX(_l, fmt,...)
fr_log_lvl_t lvl
Priority of the message.
void * uctx
Context to pass to the logging function.
log_dst_t * next
Next logging destination.
#define DEBUG_ENABLED3
True if global debug level 1-3 messages are enabled.
char const * prefix
To add to log messages.
fr_log_type_t type
What type of log message it is.
log_func_t func
Function to call to log to this destination.
#define RINDENT()
Indent R* messages by one level.
Context structure for the log fd event function.
ssize_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.
Stores all information relating to an event list.
fr_table_num_ordered_t const fr_log_levels[]
Maps log categories to message prefixes.
int fr_log_init_legacy(fr_log_t *log, bool daemonize)
Initialise file descriptors based on logging destination.
int fr_log_init_syslog(fr_log_t *log)
Initialise a syslog logging destination.
int fr_log_init_std(fr_log_t *log, fr_log_dst_t dst_type)
Initialise log dst for stdout, stderr or /dev/null.
int fr_log_init_file(fr_log_t *log, char const *file)
Initialise a file logging destination.
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.
@ L_DST_NULL
Discard log messages.
@ L_DST_STDERR
Log to stderr.
@ L_DST_FILES
Log to a file on disk.
@ L_DST_FUNC
Send log messages to a FILE*, via fopencookie()
@ L_DST_STDOUT
Log to stdout.
@ L_DST_SYSLOG
Log to syslog.
@ L_TIMESTAMP_ON
Always log timestamps.
@ L_TIMESTAMP_OFF
Never log timestamps.
@ L_TIMESTAMP_AUTO
Timestamp logging preference not specified.
@ L_DBG_WARN_REQ
Less severe warning only displayed when debugging is enabled.
@ L_DBG_ERR
Error only displayed when debugging is enabled.
@ L_DBG_ERR_REQ
Less severe error only displayed when debugging is enabled.
@ L_DBG_WARN
Warning only displayed when debugging is enabled.
@ L_DBG
Only displayed when debugging is enabled.
Main server configuration.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_GROUP
A grouping of other attributes.
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)
struct tm * gmtime_r(time_t const *l_clock, struct tm *result)
int fr_pair_value_aprintf(fr_pair_t *vp, char const *fmt,...)
Print data into an "string" data type.
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.
char * fr_vasprintf_secure(TALLOC_CTX *ctx, char const *fmt, va_list ap)
char * fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
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.
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
#define fr_rb_inline_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black tree.
The main red black tree structure.
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.
bool fr_sbuff_is_terminal(fr_sbuff_t *in, fr_sbuff_term_t const *tt)
Efficient terminal string search.
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.
#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.
#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.
Talloc sbuff extension structure.
#define pair_prepend_request(_attr, _da)
Allocate and prepend a fr_pair_t to the request list.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
fr_aka_sim_id_type_t type
fr_log_dst_t dst
Log destination.
fr_log_timestamp_t timestamp
Prefix log messages with timestamps.
char const * file
Path to log file.
FILE * handle
Path to log file.
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
An element in a lexicographically sorted array of name to num mappings.
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
static int talloc_const_free(void const *ptr)
Free const'd memory.
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))
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
#define fr_pair_list_foreach(_list_head, _iter)
Iterate over the contents of a fr_pair_list_t.
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
char const * fr_strerror_pop(void)
Pop the last library error.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
#define FR_TYPE_STRUCTURAL
#define fr_box_strvalue_len(_val, _len)