#include <systemd/sd-event.h>
#include <unistd.h>
-#include "audit.h"
#include "log.h"
+#include "module.h"
+
+struct audit_listener {
+ struct faultd_module module;
+ int audit_fd;
+ sd_event_source *event_source;
+};
+
+#define to_audit_listener(MOD) \
+ container_of(MOD, struct audit_listener, module)
static struct audit_rule_data rule_data = {
.flags = AUDIT_FILTER_EXIT, /* trigger on exit from syscall */
return 0;
}
-int faultd_audit_init(sd_event *event)
+static int audit_listener_init(struct faultd_module *module, sd_event *event)
{
+ struct audit_listener alistener = to_audit_listener(module);
int fd;
+ sd_event_source *event_source;
int ret;
fd = audit_open();
if (fd < 0) {
- log_error("Could not open audit socket: %m\n");
+ log_error("Could not open audit socket: %m\n");
return fd;
}
ret = audit_set_pid(fd, getpid(), WAIT_YES);
if (ret < 0) {
log_error("Could not set pid (%d)\n", ret);
- return ret;
+ goto close_audit;
}
- ret = sd_event_add_io(event, NULL, fd, EPOLLIN, audit_handler, NULL);
+ /*
+ * TODO: Is this in a correct place?
+ * Shouldn't be after filter registration
+ */
+ ret = sd_event_add_io(event, &event_source,
+ fd, EPOLLIN, audit_handler, NULL);
if (ret < 0) {
log_error_errno(ret, "Could not add io event: %m");
- return ret;
+ goto unset_pid;
}
/* TODO: select only relevant syscalls */
ret = audit_add_rule_data(fd, &rule_data, AUDIT_FILTER_EXIT, AUDIT_ALWAYS);
if (ret <= 0 && ret != -EEXIST) {
log_error("Could not add rule (%d).", ret);
- return ret;
+ goto remove_from_event_loop;
}
- return fd;
+ alistener->audit_fd = fd;
+ alistener->event_source = event_source;
+
+ return 0;
+
+remove_from_event_loop:
+ sd_event_source_unref(event_source);
+unset_pid:
+ audit_set_pid(fd, 0, WAIT_YES);
+close_audit:
+ audit_close(fd);
+
+ return ret;
}
-int faultd_audit_close(int fd)
+static void audit_listener_cleanup(struct faultd_module *module)
{
+ struct audit_listener alistener = to_audit_listener(module);
+ int fd = alistener->audit_fd;
+ sd_event_source *event_source = alistener->event_source;
int ret;
+ /* We log errors but go forward to cleanup everything we can */
+ ret = sd_event_source_set_enabled(event_source, SD_EVENT_OFF);
+ if (ret < 0)
+ log_error("Could not disable audit event source %d", ret);
+
+ sd_event_source_unref(event_source);
+
ret = audit_delete_rule_data(fd, &rule_data, AUDIT_FILTER_EXIT, AUDIT_ALWAYS);
- if (ret < 0 && ret != -EEXIST) {
+ if (ret < 0 && ret != -EEXIST)
log_error("Could not add rule (%d)", ret);
- return ret;
- }
ret = audit_set_pid(fd, 0, WAIT_YES);
- if (ret < 0) {
+ if (ret < 0)
log_error("Could not set pid (%d)", ret);
- return ret;
- }
audit_close(fd);
return 0;
}
+
+struct audit_listener audit_listener = {
+ .module = {
+ .name = "audit_listener",
+ .type = FAULTD_MODULE_TYPE_LISTENER,
+
+ .init = audit_listener_init,
+ .cleanup = audit_listener_cleanup,
+ .node = LIST_HEAD_INIT,
+ },
+ .audit_fd = -1,
+};
+
+FAULTD_MODULE_REGISTER(&audit_listener)