26 #include <freeradius-devel/protocol/freeradius/freeradius.internal.h>
27 #include <freeradius-devel/server/exfile.h>
28 #include <freeradius-devel/server/trigger.h>
30 #include <freeradius-devel/util/debug.h>
31 #include <freeradius-devel/util/file.h>
32 #include <freeradius-devel/util/misc.h>
33 #include <freeradius-devel/util/perm.h>
34 #include <freeradius-devel/util/syserror.h>
61 #define MAX_TRY_LOCK 4
85 ERROR(
"Incomplete internal dictionary: Missing definition for \"Exfile-Name\"");
92 talloc_array_length(entry->
filename) - 1,
false);
124 pthread_mutex_lock(&ef->
mutex);
132 pthread_mutex_unlock(&ef->
mutex);
133 pthread_mutex_destroy(&ef->
mutex);
153 if (!ef)
return NULL;
175 if (pthread_mutex_init(&ef->
mutex, NULL) != 0) {
205 if (!trigger_args)
return;
219 fd = open(filename, O_RDWR | O_CREAT, permissions);
230 p = strrchr(dir, FR_DIR_SEP);
242 dirperm = permissions;
243 if ((dirperm & 0600) != 0) dirperm |= 0100;
244 if ((dirperm & 0060) != 0) dirperm |= 0010;
245 if ((dirperm & 0006) != 0) dirperm |= 0001;
247 if (
fr_mkdir(NULL, dir, -1, dirperm, NULL, NULL) < 0) {
254 fd = open(filename, O_RDWR | O_CREAT, permissions);
271 int i, tries, unused = -1, found = -1, oldest = -1;
272 bool do_cleanup =
false;
286 pthread_mutex_lock(&ef->
mutex);
298 if (unused < 0) unused = i;
324 if (!do_cleanup)
break;
331 }
else if (do_cleanup) {
391 if (lseek(ef->
entries[i].
fd, 0, SEEK_SET) < 0) {
396 pthread_mutex_unlock(&(ef->
mutex));
409 if (errno != EAGAIN) {
415 ef->
entries[i].
fd = open(filename, O_RDWR | O_CREAT, permissions);
436 if (st.st_nlink == 0) {
452 if ((st.st_mode & ~S_IFMT) != permissions) {
453 char str_need[10], oct_need[5];
454 char str_have[10], oct_have[5];
462 WARN(
"File %s permissions are %s (%s) not %s (%s))", filename,
463 oct_have, str_have, oct_need, str_need);
465 if (((st.st_mode | permissions) != st.st_mode) &&
466 (fchmod(ef->
entries[i].
fd, (st.st_mode & ~S_IFMT) | permissions) < 0)) {
470 WARN(
"Failed resetting file %s permissions to %s (%s): %s",
479 real_offset = lseek(ef->
entries[i].
fd, 0, SEEK_END);
480 if (offset) *offset = real_offset;
508 if (!ef || !filename)
return -1;
514 if (found < 0)
return -1;
515 real_offset = lseek(found, 0, SEEK_END);
516 if (offset) *offset = real_offset;
536 (void) lseek(ef->
entries[i].
fd, 0, SEEK_SET);
538 pthread_mutex_unlock(&(ef->
mutex));
544 pthread_mutex_unlock(&(ef->
mutex));
A section grouping multiple CONF_PAIR.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
fr_dict_t const * fr_dict_internal(void)
fr_dict_attr_t const * fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr)
Check if a child attribute exists in a parent using an attribute number.
static void exfile_cleanup_entry(exfile_t *ef, exfile_entry_t *entry)
#define MAX_TRY_LOCK
How many times we attempt to acquire a lock.
uint32_t max_entries
How many file descriptors we keep track of.
static int exfile_open_lock(exfile_t *ef, char const *filename, mode_t permissions, off_t *offset)
static int exfile_open_mkdir(exfile_t *ef, char const *filename, mode_t permissions)
static void exfile_trigger_exec(exfile_t *ef, exfile_entry_t *entry, char const *name_suffix)
Send an exfile trigger.
char const * trigger_prefix
Trigger path in the global trigger section.
uint32_t hash
Hash for cheap comparison.
void exfile_enable_triggers(exfile_t *ef, CONF_SECTION *conf, char const *trigger_prefix, fr_pair_list_t *trigger_args)
Enable triggers for an exfiles handle.
exfile_t * exfile_init(TALLOC_CTX *ctx, uint32_t max_entries, fr_time_delta_t max_idle, bool locking)
Initialize a way for multiple threads to log to one or more files.
static int _exfile_free(exfile_t *ef)
fr_time_t last_used
Last time the entry was used.
fr_pair_list_t trigger_args
Arguments to pass to trigger.
CONF_SECTION * conf
Conf section to search for triggers.
fr_time_delta_t max_idle
Maximum idle time for a descriptor.
int exfile_open(exfile_t *ef, char const *filename, mode_t permissions, off_t *offset)
Open a new log file, or maybe an existing one.
int fd
File descriptor associated with an entry.
static int exfile_close_lock(exfile_t *ef, int fd)
int exfile_close(exfile_t *ef, int fd)
Close the log file.
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.
uint32_t fr_hash_string(char const *p)
unlang_interpret_t * unlang_interpret_get_thread_default(void)
Get the default interpreter for this thread.
int rad_unlockfd(int fd, int lock_len)
int rad_lockfd_nonblock(int fd, int lock_len)
int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from)
Duplicate a list of pairs.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
char const * fr_perm_mode_to_oct(char out[static 5], mode_t mode)
char const * fr_perm_mode_to_str(char out[static 10], mode_t mode)
Convert mode_t into humanly readable permissions flags.
static unsigned int hash(char const *username, unsigned int tablesize)
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
#define fr_time()
Allow us to arbitrarily manipulate time.
Stores an attribute, a value and various bits of other data.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
int talloc_link_ctx(TALLOC_CTX *parent, TALLOC_CTX *child)
Link two different parent and child contexts, so the child is freed before the parent.
static int talloc_const_free(void const *ptr)
Free const'd memory.
#define fr_time_gteq(_a, _b)
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
#define fr_time_add(_a, _b)
Add a time/time delta together.
#define fr_time_gt(_a, _b)
#define fr_time_lt(_a, _b)
A time delta, a difference in time measured in nanoseconds.
int trigger_exec(unlang_interpret_t *intp, CONF_SECTION const *cs, char const *name, bool rate_limit, fr_pair_list_t *args)
Execute a trigger - call an executable to process an event.
#define fr_pair_list_prepend_by_da_len(_ctx, _vp, _list, _attr, _val, _len, _tainted)
Prepend a pair to a list, assigning its value.
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)