27#include <bsm/libbsm.h>
28#include <bsm/audit_kevents.h>
31#include <security/audit/audit_ioctl.h>
90 int is_created, is_deleted, is_moved;
172 error (
"Cannot fork()." );
182 debug ( 6,
"Waiting for %u", pid );
185 if ( waitpid ( pid, &status, 0 ) != pid ) {
186 error (
"Cannot waitid()." );
190 int exitcode = WEXITSTATUS ( status );
235 debug ( 4,
"bsm_config_backup(): no reconfig required" );
239 debug ( 4,
"bsm_config_backup(): error" );
274 flock ( fd, LOCK_UN );
276 if ( flock ( fd, LOCK_NB | LOCK_EX ) )
279 debug ( 1,
"I'm the last BSM clsync instance." );
286 flock ( fd, LOCK_UN );
297#define BSM_INIT_ERROR {\
298 free(ctx_p->fsmondata);\
299 ctx_p->fsmondata = NULL;\
315 if ( pipe == NULL ) {
324 fd = fileno ( pipe );
326 if ( ioctl ( fd, AUDITPIPE_GET_QLIMIT_MAX, &len ) < 0 ) {
327 error (
"Cannot read QLIMIT_MAX from auditpipe" );
331 if ( ioctl ( fd, AUDITPIPE_SET_QLIMIT, &len ) < 0 ) {
332 error (
"Cannot set QLIMIT through auditpipe" );
336 if ( ioctl ( fd, AUDITPIPE_GET_QLIMIT, &len ) < 0 ) {
337 error (
"Cannot read QLIMIT from auditpipe" );
342 debug ( 5,
"auditpipe QLIMIT -> %i", (
int ) len );
345 if ( setvbuf ( pipe, NULL, _IONBF, 0 ) ) {
346 error (
"Cannot set unbuffered mode for auditpipe" );
378 debug ( 9,
"%i, {%li, %li}", fd, timeout_p == NULL ? -1 : timeout_p->tv_sec, timeout_p == NULL ? 0 : timeout_p->tv_usec );
381 FD_SET ( fd, &rfds );
382 rc = select ( fd + 1, &rfds, NULL, NULL, timeout_p );
383 debug ( 9,
"rc -> %i", rc );
394 static int dont_wait = 0;
395 struct timeval tv_abs;
396 struct timeval timeout_zero = {0};
400 if ( timeout_p != NULL )
401 if ( timeout_p->tv_sec != 0 || timeout_p->tv_usec != 0 )
408 if ( *event_p->
path ) {
409 debug ( 2,
"we have an event. return 1." );
419 debug ( 4,
"select() without waiting" );
434 }
else if ( rc > 0 ) {
443 if ( recalc_timeout == 2 ) {
444 debug ( 5,
"old timeout_p->: tv_sec == %lu; tv_usec == %lu", timeout_p->tv_sec, timeout_p->tv_usec );
445 gettimeofday ( &tv_abs, NULL );
447 if ( timercmp ( timeout_abs_p, &tv_abs, < ) )
448 timersub ( timeout_abs_p, &tv_abs, timeout_p );
450 memset ( timeout_p, 0,
sizeof ( *timeout_p ) );
452 debug ( 5,
"new timeout_p->: tv_sec == %lu; tv_usec == %lu", timeout_p->tv_sec, timeout_p->tv_usec );
455 debug ( 3,
"select() with timeout %li.%06li secs (recalc_timeout == %u).",
456 timeout_p == NULL ? -1 : timeout_p->tv_sec,
457 timeout_p == NULL ? 0 : timeout_p->tv_usec,
464 if ( recalc_timeout == 1 )
468 critical_on ( ( rc == -1 ) && ( errno != EINTR ) );
470 if ( rc == 0 || rc == -1 ) {
471 debug ( 3,
"rc == %i; errno == %i; return 0", rc, errno );
482 debug ( 3,
"parsing the event (au_parsed == %u; au_len == %u)", au_parsed, au_len );
484 while ( au_parsed < au_len ) {
485 critical_on ( au_fetch_tok ( &tok, &au_buf[au_parsed], au_len - au_parsed ) == -1 );
486 au_parsed += tok.len;
487 debug ( 4,
"au_fetch_tok(): au_parsed -> %u", tok.len );
491 case AUT_HEADER32_EX:
493 case AUT_HEADER64_EX: {
494 event_p->
type = tok.tt.hdr32.e_type;
501 int dir_wd, dir_iswatched;
502 ptr = memrchr ( tok.tt.path.path,
'/', tok.tt.path.len );
506 critical (
"relative path received from au_fetch_tok(): \"%s\" (len: %u)", tok.tt.path.path, tok.tt.path.len );
509 debug ( 6,
"Event on \"%s\".", tok.tt.path.path );
511 dir_wd = indexes_fpath2wd ( indexes_p, tok.tt.path.path );
512 dir_iswatched = ( dir_wd != -1 );
513 debug ( 7,
"Directory is \"%s\". dir_wd == %i; dir_iswatched == %u", tok.tt.path.path, dir_wd, dir_iswatched );
516 if ( dir_iswatched ) {
517 debug ( 5,
"Event on \"%s\" is watched. Pushing. path_count == %u", tok.tt.path.path, path_count );
519 switch ( path_count ) {
521 memcpy ( event_p->
path, tok.tt.path.path, tok.tt.path.len + 1 );
525 memcpy ( event_p->
path_to, tok.tt.path.path, tok.tt.path.len + 1 );
530 warning (
"To many paths on BSM event: \"%s\" (already count: %u)", tok.tt.path.path, path_count );
546 debug ( 4,
"clean up" );
550 critical (
"This code shouldn't be reached" );
561 static struct timeval tv = {0};
563 int count, event_num;
564 char *path_rel = NULL;
565 size_t path_rel_len = 0;
570 g_hash_table_remove_all ( indexes_p->
fpath2ei_ht );
576 struct stat st, *st_p;
593 path_stat = event_p->
path;
606 st_mode = st.st_mode;
607 st_size = st.st_size;
611 if ( *event_p->
path ) {
612 if (
sync_prequeue_loadmark ( 1,
ctx_p, indexes_p, event_p->
path, NULL, st_p, r.
f.
objtype_old, r.
f.
objtype_new, event_p->
type, event_p->
w_id, st_mode, st_size, &path_rel, &path_rel_len, NULL ) ) {
613 error (
"Got error while load_mark-ing into pre-queue \"%s\"", event_p->
path );
624 if (
sync_prequeue_loadmark ( 1,
ctx_p, indexes_p, event_p->
path_to, NULL, st_p, r.
t.
objtype_old, r.
t.
objtype_new, event_p->
type, event_p->
w_id, st_mode, st_size, &path_rel, &path_rel_len, NULL ) ) {
625 error (
"Got error while load_mark-ing into pre-queue \"%s\"", event_p->
path_to );
637 debug ( 15,
"BSM_HANDLE_CALLWAIT" );
642 debug ( 15,
"BSM_HANDLE_ITERATE" );
648 debug ( 10,
"left_count: %i; event_num: %i; mondata->event_count: %i", left_count, event_num,
mondata->
event_count );
649 }
while ( left_count > 0 );
653 if ( event_num < mondata->event_count ) {
686 debug ( 2,
"signal -> %i. Sending pthread_cond_broadcast() to bsm_cond_gotevent and bsm_cond_queueend.", signal );
707 debug ( 5,
"We have an event. Pushing." );
721 memcpy ( event_p, &
event,
sizeof ( *event_p ) );
733 debug ( 3,
"(ctx_p, indexes_p, %p {%u, %u})", timeout_p, timeout_p == NULL ? -1 : timeout_p->tv_sec, timeout_p == NULL ? 0 : timeout_p->tv_usec );
738 struct timespec ts_abs;
739 struct timeval tv_abs, timeout_abs;
740#define INFINITETIME (3600 * 24 * 365 * 10)
746 gettimeofday ( &tv_abs, NULL );
747 timeradd ( &tv_abs, timeout_p, &timeout_abs );
748 ts_abs.tv_sec = timeout_abs.tv_sec;
749 ts_abs.tv_nsec = timeout_abs.tv_usec * 1000;
758 if ( timeout_p->tv_sec == 0 && timeout_p->tv_sec == 0 ) {
759 debug ( 2,
"Zero timeout. Waiting for the current queue to be processed." )
767 debug ( 10,
"pthread_cond_timedwait(&bsm_cond_gotevent, &bsm_mutex_prefetcher, {%i, %i})", ts_abs.tv_sec, ts_abs.tv_nsec );
784 critical (
"Got unhandled error on pthread_cond_timedwait()" );
806 debug ( 3,
"(ctx_p, indexes_p, %p {%u, %u})", timeout_p, timeout_p == NULL ? -1 : timeout_p->tv_sec, timeout_p == NULL ? 0 : timeout_p->tv_usec );
808 struct timeval timeout_abs, tv_abs;
811 if ( timeout_p->tv_sec != 0 || timeout_p->tv_usec != 0 ) {
812 gettimeofday ( &tv_abs, NULL );
813 timeradd ( &tv_abs, timeout_p, &timeout_abs );
818 if ( *event_p->
path ) {
819 debug ( 2,
"We already have an event. Return 1." );
824 debug ( 2,
"No events. Return 0" );
828 if ( *event_p->
path ) {
829 debug ( 2,
"We have an event. Return 1." );
833 critical (
"This code shouldn't be reached" );
846 id = ( int ) ( (
unsigned int ) ~0 >> 2 );
849 while ( indexes_wd2fpath ( indexes_p,
id ) != NULL )
865 rc |= bsm_config_revert (
mondata );
enum eventobjtype eventobjtype_t
#define BSM_QUEUE_LENGTH_MAX
#define AUDIT_CONTROL_HEADER
#define AUDIT_CONTROL_INITSCRIPT
#define AUDIT_CONTROL_PATH
#define AUDIT_CONTROL_CONTENT
#define register_blockthread(thread)
#define debug(debug_level,...)
#define critical_on(cond)
#define critical_or_warning(cond,...)
int bsm_fetch(ctx_t *ctx_p, indexes_t *indexes_p, struct bsm_event *event_p, int pipe_fd, struct timeval *timeout_p, struct timeval *timeout_abs_p)
int bsm_wait_prefetched(struct ctx *ctx_p, struct indexes *indexes_p, struct timeval *timeout_p)
int(* bsm_handle)(struct ctx *ctx_p, struct indexes *indexes_p)
int bsm_wait_noprefetch(struct ctx *ctx_p, struct indexes *indexes_p, struct timeval *timeout_p)
int select_rfd(int fd, struct timeval *timeout_p)
int bsm_handle_prefetched(struct ctx *ctx_p, struct indexes *indexes_p)
pthread_cond_t bsm_cond_queueend
int bsm_deinit(ctx_t *ctx_p)
int bsm_handle_noprefetch(struct ctx *ctx_p, struct indexes *indexes_p)
int(* bsm_wait)(struct ctx *ctx_p, struct indexes *indexes_p, struct timeval *timeout_p)
int bsm_config_setup(mondata_t *mondata)
int bsm_handle_allevents(struct ctx *ctx_p, struct indexes *indexes_p, bsm_handletype_t how)
static int bsm_prefetcher_running
void bsm_prefetcher_sig_int(int signal)
pthread_mutex_t bsm_mutex_prefetcher
enum bsm_handletype bsm_handletype_t
int bsm_prefetcher(struct ctx *ctx_p)
pthread_t prefetcher_thread
int bsm_init(ctx_t *ctx_p)
static void recognize_event(struct recognize_event_return *r, uint32_t event)
int bsm_add_watch_dir(struct ctx *ctx_p, struct indexes *indexes_p, const char *const accpath)
pthread_cond_t bsm_cond_gotevent
int bsm_config_backup(mondata_t *mondata)
size_t event_count_wasinqueue
struct recognize_event_return::@3 t
eventobjtype_t objtype_old
eventobjtype_t objtype_new
struct recognize_event_return::@2 f
int sync_prequeue_unload(ctx_t *ctx_p, indexes_t *indexes_p)
int sync_prequeue_loadmark(int monitored, ctx_t *ctx_p, indexes_t *indexes_p, const char *path_full, const char *path_rel, stat64_t *lst_p, eventobjtype_t objtype_old, eventobjtype_t objtype_new, uint32_t event_mask, int event_wd, mode_t st_mode, off_t st_size, char **path_buf_p, size_t *path_buf_len_p, eventinfo_t *evinfo)