28RCSID(
"$Id: 1d75fcd03baf3eea974e11e0848308ab2d2eac43 $")
 
   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        return (request->log.lvl >= lvl);
 
 
  295                  char const *
fmt, va_list ap, 
void *uctx)
 
  297        char const      *filename;
 
  301        char const      *extra = 
"";
 
  302        uint8_t         unlang_indent, module_indent;
 
  305        char const      *fmt_location = 
"";
 
  306        char const      *fmt_prefix = 
"";
 
  307        char const      *fmt_module = 
"";
 
  325                pool = talloc_pool(NULL, 4096);
 
  327                        fr_perror(
"Failed allocating memory for vlog_request_pool");
 
  349                        fp = fopen(
log_dst->file, 
"a");
 
  350                        if (!fp) 
goto finish;
 
  353#if defined(HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN) 
  356#  ifdef HAVE_FOPENCOOKIE 
  369                        fp = funopen(
log_dst->cookie, NULL, 
log_dst->cookie_write, NULL, NULL);
 
  372                        if (!fp) 
goto finish;
 
  386                dst = request->log.dst;
 
  392                request->log.dst = NULL;
 
  403                request->log.dst = dst;
 
  409                p = strrchr(exp, FR_DIR_SEP);
 
  412                        if (
fr_mkdir(NULL, exp, -1, S_IRWXU, NULL, NULL) < 0) {
 
  420                fp = fopen(exp, 
"a");
 
  431                if ((request->seq_start == 0) || (request->number == request->seq_start)) {
 
  435                                                           request->name, request->seq_start);
 
  442        unlang_indent = request->log.indent.unlang > 
sizeof(
spaces) - 1 ?
 
  444                        request->log.indent.unlang;
 
  446        module_indent = request->log.indent.module > 
sizeof(
spaces) - 1 ?
 
  448                        request->log.indent.module;
 
  455        if (request->module) {
 
  469        if (!
log_dst->suppress_secrets) {
 
  483                timeval = time(NULL);
 
  493                        ASCTIME_R(&utc, time_buff, 
sizeof(time_buff));
 
  497                        CTIME_R(&timeval, time_buff, 
sizeof(time_buff));
 
  503                p = strrchr(time_buff, 
'\n');
 
  556        talloc_free_children(pool);
 
 
  571        if (!
fmt || !request || !request->packet) 
return;
 
  590        if (request->module && (request->module[0] != 
'\0')) {
 
 
  616        if (!request->log.dst) 
return;
 
  619        for (dst = request->log.dst; dst; dst = dst->
next) {
 
  620                if ((lvl > request->log.lvl) && (lvl > dst->
lvl)) 
continue;
 
 
  651        if (!request->log.dst) 
return;
 
  654        for (dst_p = request->log.dst; dst_p; dst_p = dst_p->
next) {
 
 
  682        if (!request->log.dst) 
return;
 
  695                for (dst_p = request->log.dst; dst_p; dst_p = dst_p->
next) {
 
 
  751                        fr_perror(
"Failed allocating memory for fr_log_request_oid_buff");
 
  756                        fr_perror(
"Failed allocating memory for fr_sbuff_uctx_talloc_t");
 
 
  785        if (!request->log.dst) 
return;
 
  799        switch (
vp->vp_type) {
 
  801                RDEBUGX(lvl, 
"%s%pV {", prefix ? prefix : 
"",
 
  808                RDEBUGX(lvl, 
"%s%pV = \"%pV\"", prefix ? prefix : 
"",
 
  813                RDEBUGX(lvl, 
"%s%pV = %pV", prefix ? prefix : 
"",
 
 
  886                        char const *str, 
size_t str_len,
 
  887                        ssize_t marker_idx, 
char const *marker_fmt, ...)
 
  889        char const              *ellipses = 
"";
 
  893        static char const       marker_spaces[] = 
"                                                            "; 
 
  895        if (str_len == SIZE_MAX) str_len = strlen(str);
 
  897        if (marker_idx < 0) marker_idx = marker_idx * -1;
 
  899        if ((
size_t)marker_idx >= 
sizeof(marker_spaces)) {
 
  900                size_t offset = (marker_idx - (
sizeof(marker_spaces) - 1)) + (
sizeof(marker_spaces) * 0.75);
 
  901                marker_idx -= offset;
 
  911        indent = request->log.indent;
 
  912        request->log.indent.module = 0;
 
  913        request->log.indent.unlang = 0;
 
  923        request->log.indent = indent;
 
 
  931        char buffer[(0x10 * 3) + 1];
 
  934        for (i = 0; i < data_len; i += 0x10) {
 
  936                if ((i + len) > data_len) len = data_len - i;
 
  938                for (p = 
buffer, j = 0; j < len; j++, p += 3) 
snprintf(p, end - p, 
"%02x ", 
data[i + j]);
 
 
  970        fr_sbuff_marker(&m_start, &sbuff);
 
  971        fr_sbuff_marker(&m_end, &sbuff);
 
  982                        if (errno == EINTR) 
continue;
 
  993                        if (errno == EWOULDBLOCK) slen = 0;
 
  995                if ((slen < 0) && (errno == EINTR)) 
continue;
 
 1014                                    log_info->
prefix ? 
" - " : 
"",
 
 1025                if (slen <= 0) 
break;
 
 
 1076        memset(&find, 0, 
sizeof(find));
 
 1080        return (found) ? found->
log : NULL;
 
 
 1193                        fr_strerror_const(
"Specified \"files\" as a log destination, but no log filename was given!");
 
 
 1270        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 DICT_AUTOLOAD_TERMINATOR
#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, bool move_end)
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)