24 RCSID(
"$Id: 76c72157d8fc933c1b4c4ce1190ab0ba5065907c $")
26 #include <freeradius-devel/radiusd.h>
27 #include <freeradius-devel/modules.h>
28 #include <freeradius-devel/rad_assert.h>
29 #include <freeradius-devel/exfile.h>
103 uint32_t permissions;
104 char const *group_str;
113 struct timeval timeout;
214 DEBUG2(
"rlm_linelog (%s): Opening UNIX socket at \"%s\"", inst->
name, inst->
unix_sock.path);
228 DEBUG2(
"rlm_linelog (%s): Opening TCP connection to %s:%u", inst->
name, buff, inst->
tcp.
port);
244 DEBUG2(
"rlm_linelog (%s): Opening UDP connection to %s:%u", inst->
name, buff, inst->
udp.
port);
264 if (errno == EINPROGRESS) {
266 DEBUG2(
"rlm_linelog (%s): Waiting for connection to complete...", inst->
name);
268 DEBUG2(
"rlm_linelog (%s): Blocking until connection complete...", inst->
name);
276 DEBUG2(
"rlm_linelog (%s): Connection successful", inst->
name);
282 ERROR(
"rlm_linelog (%s): Failed setting nonblock flag on fd", inst->
name);
315 if (inst->
file.escape) {
328 cf_log_err_cs(conf,
"Must specify a log format, or reference");
335 snprintf(prefix,
sizeof(prefix),
"rlm_linelog (%s)", inst->
name);
349 if (!inst->
file.ef) {
354 if (inst->
file.group_str) {
357 inst->
file.group = strtol(inst->
file.group_str, &endptr, 10);
358 if (*endptr !=
'\0') {
361 inst->
file.group_str);
373 #ifndef HAVE_SYSLOG_H
374 cf_log_err_cs(conf,
"Syslog output is not supported on this system");
377 if (inst->
syslog.facility) {
383 inst->
syslog.priority |= num;
391 inst->
syslog.priority |= num;
397 #ifndef HAVE_SYS_UN_H
398 cf_log_err_cs(conf,
"Unix sockets are not supported on this sytem");
403 if (!inst->
pool)
return -1;
410 if (!inst->
pool)
return -1;
416 if (!inst->
pool)
return -1;
443 char const *in,
UNUSED void *arg)
447 if (outlen == 0)
return 0;
456 if (outlen <= 2)
break;
463 if (outlen == 1)
break;
471 if (outlen <= 2)
break;
479 if (outlen <= 2)
break;
487 if (outlen <= 4)
break;
488 snprintf(out, outlen,
"\\%03o", (uint8_t) *in);
517 struct timeval *
timeout = NULL;
523 vp_tmpl_t empty, *vpt = NULL, *vpt_p = NULL;
527 struct iovec vector_s[2];
528 struct iovec *vector = NULL, *vector_p;
543 char const *tmpl_str;
550 if (buff[1] ==
'.') p++;
555 if (buff[2] ==
'.') {
556 REDEBUG(
"Invalid path \"%s\"", p);
562 RDEBUG2(
"Path \"%s\" doesn't exist", p);
567 REDEBUG(
"Path \"%s\" resolves to a section (should be a pair)", p);
573 if (!tmpl_str || (tmpl_str[0] ==
'\0')) {
574 RDEBUG2(
"Path \"%s\" resolves to an empty config pair", p);
583 slen =
tmpl_afrom_str(request, &vpt, tmpl_str, talloc_array_length(tmpl_str) - 1,
596 RDEBUG2(
"No default message configured");
602 RDEBUG2(
"Using default message");
612 switch (vpt_p->type) {
616 #define VECTOR_INCREMENT 20
621 MEM(vector = talloc_array(request,
struct iovec, alloced));
626 if ((with_delim && ((i + 1) >= alloced)) ||
629 MEM(vector = talloc_realloc(request, vector,
struct iovec, alloced));
635 vector[i].iov_base = vp->
data.ptr;
636 vector[i].iov_len = vp->vp_length;
641 vector[i].iov_base = p;
642 vector[i].iov_len = talloc_array_length(p) - 1;
651 memcpy(&vector[i].iov_base, &(inst->
delimiter),
sizeof(vector[i].iov_base));
671 memcpy(&vector_s[0].iov_base, &value,
sizeof(vector_s[0].iov_base));
672 vector_s[0].iov_len = slen;
677 memcpy(&vector_s[1].iov_base, &(inst->
delimiter),
sizeof(vector_s[1].iov_base));
682 vector_p = &vector_s[0];
685 if (vector_len == 0) {
686 RDEBUG(
"No data to write");
704 p = strrchr(path,
'/');
722 if (inst->
file.group_str && (chown(path, -1, inst->
file.group) == -1)) {
726 if (writev(fd, vector_p, vector_len) < 0) {
731 rad_assert((errno != EINVAL) && (errno != EFAULT));
763 for (i = num; i >= 0; i--) {
768 if (wrote < 0)
switch (errno) {
777 RWARN(
"Failed writing to socket: %s. Will reconnect and try again...",
798 RDEBUG2(
"Wrote %zi bytes", wrote);
801 while (read(conn->
sockfd, discard,
sizeof(discard)) > 0);
814 for (i = 0; i < vector_len; i++) {
815 syslog(inst->
syslog.priority,
"%.*s", (
int)vector_p[i].iov_len, (
char *)vector_p[i].iov_base);
843 .config = module_config,
5 methods index for preproxy section.
vp_tmpl_t * log_src
Source of log messages.
#define PW_TYPE_FILE_INPUT
File matching value must exist, and must be readable.
ssize_t tmpl_expand(char const **out, char *buff, size_t outlen, REQUEST *request, vp_tmpl_t const *vpt, xlat_escape_t escape, void *escape_ctx)
Expand a vp_tmpl_t to a string writing the result to a buffer.
FR_TOKEN cf_pair_value_type(CONF_PAIR const *pair)
Return the value (rhs) type.
ssize_t tmpl_afrom_str(TALLOC_CTX *ctx, vp_tmpl_t **out, char const *name, size_t inlen, FR_TOKEN type, request_refs_t request_def, pair_lists_t list_def, bool do_escape)
Convert an arbitrary string into a vp_tmpl_t.
int fr_socket_client_tcp(fr_ipaddr_t *src_ipaddr, fr_ipaddr_t *dst_ipaddr, uint16_t dst_port, bool async)
Establish a connected TCP socket.
Time value (struct timeval), only for config items.
int sockfd
File descriptor associated with socket.
The module is OK, continue.
Metadata exported by the module.
linelog_net_t udp
UDP server.
linelog_dst_t log_dst
Logging destination.
7 methods index for postauth section.
struct linelog_instance_t::@18 file
WiMAX IPv4 or IPv6 address depending on length.
size_t rad_filename_escape(UNUSED REQUEST *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. ...
int fr_socket_client_unix(char const *path, bool async)
#define REMARKER(_m, _i, _e)
Output string with error marker, showing where format error occurred.
struct linelog_instance_t::@17 syslog
#define CONF_PARSER_TERMINATOR
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
char * fr_inet_ntop_prefix(char out[FR_IPADDR_PREFIX_STRLEN], size_t outlen, fr_ipaddr_t *addr)
Print a fr_ipaddr_t as a CIDR style network prefix.
#define PW_TYPE_DEPRECATED
If a matching CONF_PAIR is found, error out with a deprecated message.
size_t(* xlat_escape_t)(REQUEST *request, char *out, size_t outlen, char const *in, void *arg)
static FR_NAME_NUMBER const linelog_dst_table[]
#define RLM_TYPE_HUP_SAFE
Will be restarted on HUP.
uint16_t port
Network port.
int rad_mkdir(char *directory, mode_t mode, uid_t uid, gid_t gid)
Create possibly many directories.
#define PW_TYPE_SUBSECTION
fr_connection_pool_t * pool
Connection pool instance.
Defines a CONF_PAIR to C data type mapping.
Abstraction to allow iterating over different configurations of VALUE_PAIRs.
struct linelog_instance_t linelog_instance_t
linelog module instance
char const * cf_pair_value(CONF_PAIR const *pair)
char * fr_pair_value_asprint(TALLOC_CTX *ctx, VALUE_PAIR const *vp, char quote)
Print one attribute value to a string.
int rad_getgid(TALLOC_CTX *ctx, gid_t *out, char const *name)
Resolve a group name to a GID.
int fr_str2int(FR_NAME_NUMBER const *table, char const *name, int def)
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
VALUE_PAIR * tmpl_cursor_init(int *err, vp_cursor_t *cursor, REQUEST *request, vp_tmpl_t const *vpt)
Initialise a vp_cursor_t to the VALUE_PAIR specified by a vp_tmpl_t.
fr_connection_pool_t * module_connection_pool_init(CONF_SECTION *module, void *opaque, fr_connection_create_t c, fr_connection_alive_t a, char const *prefix)
Initialise a module specific connection pool.
static rlm_rcode_t mod_do_linelog(void *instance, REQUEST *request) CC_HINT(nonnull)
Write a linelog message.
static const CONF_PARSER tcp_config[]
char const * name
Module instance name.
int exfile_open(exfile_t *lf, char const *filename, mode_t permissions, bool append)
Open a new log file, or maybe an existing one.
#define PW_TYPE_XLAT
string will be dynamically expanded.
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *item)
Cast a CONF_ITEM to a CONF_PAIR.
FR_NAME_NUMBER const syslog_severity_table[]
Syslog severity table.
struct linelog_net linelog_net_t
Attributes in incoming or internally proxied request.
static const CONF_PARSER file_config[]
static const CONF_PARSER unix_config[]
3 methods index for accounting section.
int exfile_close(exfile_t *lf, int fd)
Close the log file.
static size_t linelog_escape_func(UNUSED REQUEST *request, char *out, size_t outlen, char const *in, UNUSED void *arg)
Escape unprintable characters.
Stores an attribute, a value and various bits of other data.
static const CONF_PARSER udp_config[]
void void cf_log_err_cs(CONF_SECTION const *cs, char const *fmt,...) CC_HINT(format(printf
0 methods index for authenticate section.
size_t rad_filename_make_safe(UNUSED REQUEST *request, char *out, size_t outlen, char const *in, UNUSED void *arg)
Ensures that a filename cannot walk up the directory structure.
static int _mod_conn_free(linelog_conn_t *conn)
bool cf_item_is_pair(CONF_ITEM const *item)
Configuration AVP similar to a VALUE_PAIR.
enum rlm_rcodes rlm_rcode_t
Return codes indicating the result of the module call.
ssize_t fr_writev(int fd, struct iovec[], int iovcnt, struct timeval *timeout)
Write out a vector to a file descriptor.
ssize_t radius_xlat(char *out, size_t outlen, REQUEST *request, char const *fmt, xlat_escape_t escape, void *escape_ctx) CC_HINT(nonnull(1
char const * fr_strerror(void)
Get the last library error.
static const CONF_PARSER module_config[]
CONF_SECTION * cf_section_sub_find(CONF_SECTION const *, char const *name)
Find a sub-section in a section.
vp_tmpl_t * log_ref
Path to a CONF_PAIR (to use as the source of log messages).
size_t delimiter_len
Length of line termination string.
char const * cf_section_name1(CONF_SECTION const *cs)
vp_tmpl_t * tmpl_init(vp_tmpl_t *vpt, tmpl_type_t type, char const *name, ssize_t len, FR_TOKEN quote)
Initialise stack allocated vp_tmpl_t.
fr_ipaddr_t src_ipaddr
Send requests from a given src_ipaddr.
Module succeeded without doing anything.
static char const * prefix
uint64_t magic
Used to validate module struct.
Module failed, don't reply.
#define PW_TYPE_FILE_OUTPUT
File matching value must exist, and must be writeable.
#define FR_CONF_OFFSET(_n, _t, _s, _f)
uint32_t num
Number of connections in the pool.
static int mod_detach(void *instance)
struct linelog_instance_t::@19 unix_sock
void * fr_connection_get(fr_connection_pool_t *pool)
Reserve a connection in the connection pool.
struct timeval timeout
How long to wait for read/write operations.
fr_ipaddr_t dst_ipaddr
Network server.
linelog_net_t tcp
TCP server.
6 methods index for postproxy section.
2 methods index for preacct section.
#define PW_TYPE_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
static int mod_instantiate(CONF_SECTION *conf, void *instance)
FR_NAME_NUMBER const syslog_facility_table[]
Syslog facility table.
8 methods index for recvcoa section.
exfile_t * exfile_init(TALLOC_CTX *ctx, uint32_t entries, uint32_t idle, bool locking)
Initialize a way for multiple threads to log to one or more files.
fr_dict_attr_t const * da
Dictionary attribute defines the attribute.
void fr_connection_release(fr_connection_pool_t *pool, void *conn)
Release a connection.
struct linelog_conn linelog_conn_t
#define FR_TIMEVAL_TO_MS(_x)
CONF_SECTION * cs
CONF_SECTION to use as the root for log_ref lookups.
9 methods index for sendcoa section.
char const * delimiter
Line termination string (usually ).
String of printable characters.
#define FR_CONF_POINTER(_n, _t, _p)
int fr_socket_client_udp(fr_ipaddr_t *src_ipaddr, fr_ipaddr_t *dst_ipaddr, uint16_t dst_port, bool async)
Establish a connected UDP socket.
#define PW_TYPE_TMPL
CONF_PAIR should be parsed as a template.
1 methods index for authorize section.
VALUE_PAIR * tmpl_cursor_next(vp_cursor_t *cursor, vp_tmpl_t const *vpt)
Returns the next VALUE_PAIR specified by vpt.
static void * mod_conn_create(TALLOC_CTX *ctx, void *instance, struct timeval const *timeout)
fr_connection_pool_state_t const * fr_connection_pool_state(fr_connection_pool_t *pool)
Get the number of connections currently in the pool.
int fr_socket_wait_for_connect(int sockfd, struct timeval const *timeout)
Wait for a socket to be connected, with an optional timeout.
char const * log_dst_str
Logging destination string.
void * fr_connection_reconnect(fr_connection_pool_t *pool, void *conn)
Reconnect a suspected inviable connection.
#define FR_IPADDR_PREFIX_STRLEN
Like FR_IPADDR_STRLEN but with space for a prefix.
A source or sink of value data.
char const * cf_section_name2(CONF_SECTION const *cs)
void fr_connection_pool_free(fr_connection_pool_t *pool)
Delete a connection pool.
#define DEBUG_ENABLED2
True if global debug level 1-2 messages are enabled.
static const CONF_PARSER syslog_config[]
CONF_ITEM * cf_reference_item(CONF_SECTION const *parentcs, CONF_SECTION *outercs, char const *ptr)