redmine

Porting to FreeBSD, chapter 6: BSM support started

... ... @@ -7,18 +7,22 @@ clsync_CFLAGS = $(AM_CFLAGS)
if HAVE_KQUEUE
clsync_CFLAGS += -DKQUEUE_SUPPORT
clsync_SOURCES += kqueue.c
clsync_SOURCES += mon_kqueue.c
endif
if HAVE_INOTIFY
clsync_CFLAGS += -DINOTIFY_SUPPORT
clsync_SOURCES += inotify.c
clsync_SOURCES += mon_inotify.c
if INOTIFY_OLD
clsync_CFLAGS += -DINOTIFY_OLD
endif
endif
if HAVE_FANOTIFY
clsync_CFLAGS += -DFANOTIFY_SUPPORT
clsync_SOURCES += fanotify.c
clsync_SOURCES += mon_fanotify.c
endif
if HAVE_BSM
clsync_CFLAGS += -DBSM_SUPPORT
clsync_SOURCES += mon_bsm.c
endif
if SOCKET
... ...
... ... @@ -85,3 +85,14 @@
// size of event chain size to be processes at a time
#define KQUEUE_EVENTLISTSIZE 256
#define AUDIT_CONTROL_PATH "/etc/security/audit_control"
#define AUDIT_CONTROL_INITSCRIPT "/etc/rc.d/auditd"
#define AUDIT_CONTROL_CONTENT "\n\
dir:/var/audit\n\
flags:fc,fd,fw,fm\n\
minfree:0\n\
naflags:fc,fd,fw,fm\n\
policy:cnt\n\
filesz:1M\n\
"
... ...
... ... @@ -147,6 +147,13 @@ AC_ARG_WITH(inotify,
[with_inotify=check]
)
AC_ARG_WITH(bsm,
AS_HELP_STRING(--with-bsm,
[Enable BSM (Sun/*BSD audit) support as FS monitor subsystem; values: no, native, check; default: check]),
[],
[with_inotify=check]
)
case "$with_kqueue" in
check)
AC_CHECK_FUNC([kqueue],
... ... @@ -226,14 +233,44 @@ case "$with_inotify" in
;;
esac
INOTIFY_LIBS=-lbsm
case "$with_bsm" in
check)
AC_CHECK_FUNC([au_fetch_tok],
[
HAVE_BSM=1
],
AC_CHECK_LIB([bsm], [au_fetch_tok],
[
LDFLAGS="${LDFLAGS} -lbsm"
HAVE_BSM=1
],
)
)
;;
lib)
AC_CHECK_LIB([bsm], [au_fetch_tok],
[
LDFLAGS="${LDFLAGS} -lbsm"
HAVE_BSM=1
],
[
AC_MSG_FAILURE(
[Cannot find libbsm])
]
)
;;
esac
AS_IF([test "$HAVE_INOTIFY" != ""], [AC_CHECK_FUNC([inotify_init1], [], [INOTIFY_OLD=1])])
AM_CONDITIONAL([HAVE_KQUEUE], [test "$HAVE_KQUEUE" != ""])
AM_CONDITIONAL([HAVE_INOTIFY], [test "$HAVE_INOTIFY" != ""])
AM_CONDITIONAL([INOTIFY_OLD], [test "$INOTIFY_OLD" != ""])
AM_CONDITIONAL([HAVE_FANOTIFY], [test "$HAVE_FANOTIFY" != ""])
AM_CONDITIONAL([HAVE_BSM], [test "$HAVE_BSM" != ""])
AS_IF([test "$HAVE_KQUEUE" = '' -a "$HAVE_INOTIFY" = '' -a "$HAVE_FANOTIFY" = ''], [AC_MSG_FAILURE([kqueue and inotify are not supported on this system])])
AS_IF([test "$HAVE_KQUEUE" = '' -a "$HAVE_INOTIFY" = '' -a "$HAVE_FANOTIFY" = '' -a "$HAVE_BSM" = '' ], [AC_MSG_FAILURE([kqueue, inotify and bsm are not supported on this system])])
LIBS="${GLIB_LIBS} ${LIBS}"
AM_CPPFLAGS="${GLIB_CFLAGS}"
... ...
... ... @@ -851,7 +851,7 @@ Possible values:
.RS 8
.IR inotify
.RS
.BR inotify (7)
.BR inotify "(7) [Linux]"
Native, fast, reliable and well tested Linux FS monitor subsystem.
... ... @@ -862,7 +862,7 @@ well tested and may be useful even via "libinotify".
.RE
.IR kqueue
.RS
.BR kqueue (2)
.BR kqueue "(2) [FreeBSD]"
A *BSD kernel event notification mechanism (inc. timer, sockets, files etc).
... ... @@ -883,7 +883,42 @@ CPU/HDD expensive way.
.B Warning! May be problems with hard links.
FreeBSD users: notify me about found bugs, please. And before the bugfix
you can switch to "inotify" through libinotify.
you can switch to "inotify" through libinotify or to "bsm".
.RE
.IR bsm
.RS
.BR bsm "(3) [FreeBSD]"
Basic Security Module (BSM) Audit API.
This is not a FS monitor subsystem, actually. It's just an API to access to
audit information (inc. logs).
.B clsync
can setup audit to watch FS events and report it into log. After that
.B clsync
will just parse the log via
.BR auditpipe "(4) [FreeBSD]."
Fast (relative to
.BR kqueue ),
reliable, but hacky way. It requires global audit reconfiguration that
may hopple audit analysis.
.B Use with caution!
File /etc/security/audit_control will be overwritten with:
.RS
dir:/var/audit
.br
flags:fc,fd,fw,fm
.br
minfree:0
.br
naflags:fc,fd,fw,fm
.br
policy:cnt
.br
filesz:1M
.RE
.RE
.RE
... ...
/*
clsync - file tree sync utility based on inotify/kqueue
Copyright (C) 2013-2014 Dmitry Yu Okunev <dyokunev@ut.mephi.ru> 0x8E30679C
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
int bsm_init(ctx_t *ctx_p) {
char backup_path[4096];
sprintf(backup_path, AUDIT_CONTROL_PATH"-%u", getpid());
if (stat)
rename(AUDIT_CONTROL_PATH, backup_path);
int fd = open(AUDIT_CONTROL_PATH, O_WRONLY|O_CREAT);
if (fd == -1)
return -1;
if (write(fd, AUDIT_CONTROL_CONTENT, sizeof(AUDIT_CONTROL_CONTENT)-1) != AUDIT_CONTROL_CONTENT-1)
return -1;
close(fd);
debug(1, "Running \""AUDIT_CONTROL_INITSCRIPT" restart\"");
pid_t pid = fork();
switch (pid) {
case -1:
error("Cannot fork().");
return -1;
case 0:
execl(AUDIT_CONTROL_INITSCRIPT, "restart");
return -1;
}
int status;
if (waitpid(pid, &status, 0) != pid) {
error("Cannot waitid().");
return -1;
}
int exitcode = WEXITSTATUS(status);
if (exitcode)
error("Got error while running \""AUDIT_CONTROL_INITSCRIPT" restart\"");
return exitcode;
}
int bsm_wait(struct ctx *ctx_p, struct timeval *tv_p) {
return -1;
}
int bsm_handle(struct ctx *ctx_p, struct indexes *indexes_p) {
return -1;
}
int bsm_add_watch_dir(struct ctx *ctx_p, struct indexes *indexes_p, const char *const accpath) {
return -1;
}
int bsm_deinit(ctx_t *ctx_p) {
char backup_path[4096];
sprintf(backup_path, AUDIT_CONTROL_PATH"-%u", getpid());
if (stat)
rename(backup_path, AUDIT_CONTROL_PATH);
return 0;
}
... ...
/*
clsync - file tree sync utility based on inotify/kqueue
Copyright (C) 2013-2014 Dmitry Yu Okunev <dyokunev@ut.mephi.ru> 0x8E30679C
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
extern int bsm_init(ctx_t *ctx_p);
extern int bsm_wait(struct ctx *ctx_p, struct timeval *tv_p);
extern int bsm_handle(struct ctx *ctx_p, struct indexes *indexes_p);
extern int bsm_add_watch_dir(struct ctx *ctx_p, struct indexes *indexes_p, const char *const accpath);
extern int bsm_deinit(ctx_t *ctx_p);
... ...
... ... @@ -22,13 +22,16 @@
#include "port-hacks.h"
#if KQUEUE_SUPPORT
# include "kqueue.h"
# include "mon_kqueue.h"
#endif
#if INOTIFY_SUPPORT
# include "inotify.h"
# include "mon_inotify.h"
#endif
#if FANOTIFY_SUPPORT
# include "fanotify.h"
# include "mon_fanotify.h"
#endif
#if BSM_SUPPORT
# include "mon_bsm.h"
#endif
#include "main.h"
... ... @@ -1313,6 +1316,9 @@ int sync_initialsync_walk(ctx_t *ctx_p, const char *dirpath, indexes_t *indexes_
#ifdef KQUEUE_SUPPORT
case NE_KQUEUE:
#endif
#ifdef BSM_SUPPORT
case NE_KQUEUE:
#endif
evinfo.evmask = IN_CREATE_SELF;
if(node->fts_info==FTS_D) {
evinfo.evmask |= IN_ISDIR;
... ... @@ -1632,7 +1638,18 @@ int sync_notify_init(ctx_t *ctx_p) {
case NE_KQUEUE: {
int kqueue_d = kqueue_init(ctx_p);
if(kqueue_d == -1) {
error("cannot kqueue().");
error("cannot kqueue_init(ctx_p).");
return -1;
}
return 0;
}
#endif
#ifdef BSM_SUPPORT
case NE_BSM: {
int bsm_d = bsm_init(ctx_p);
if(bsm_d == -1) {
error("cannot bsm_init(ctx_p).");
return -1;
}
... ... @@ -1685,6 +1702,9 @@ static inline uint8_t monsystems_unifyevmask(ctx_t *ctx_p, uint32_t event_mask)
#ifdef KQUEUE_SUPPORT
case NE_KQUEUE:
#endif
#ifdef BSM_SUPPORT
case NE_BSM:
#endif
is_dir = event_mask & IN_ISDIR;
is_created = event_mask & (IN_CREATE|IN_MOVED_TO);
is_deleted = event_mask & (IN_DELETE_SELF|IN_DELETE|IN_MOVED_FROM);
... ... @@ -3481,6 +3501,13 @@ int sync_run(ctx_t *ctx_p) {
ctx_p->notifyenginefunct.handle = kqueue_handle;
break;
#endif
#ifdef BSM_SUPPORT
case NE_KQUEUE:
ctx_p->notifyenginefunct.add_watch_dir = bsm_add_watch_dir;
ctx_p->notifyenginefunct.wait = bsm_wait;
ctx_p->notifyenginefunct.handle = bsm_handle;
break;
#endif
#ifdef VERYPARANOID
default:
critical("Unknown FS monitor subsystem: %i", ctx_p->flags[MONITOR]);
... ... @@ -3521,6 +3548,11 @@ int sync_run(ctx_t *ctx_p) {
kqueue_deinit(ctx_p);
break;
#endif
#ifdef BSM_SUPPORT
case NE_BSM:
bsm_deinit(ctx_p);
break;
#endif
}
// Closing shared libraries
... ...