summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2012-10-02 17:40:09 -0400
committerLennart Poettering <lennart@poettering.net>2012-10-02 17:40:09 -0400
commitc1165f822cd9f8c3467b5f825ce933ab8374b361 (patch)
treeb986e9e6ead9693bdd4785f52ea7e6503bbf92bc
parentcad45ba11ec3572296361f53f5852ffb97a97fa3 (diff)
downloadsystemd-c1165f822cd9f8c3467b5f825ce933ab8374b361.tar.gz
audit: turn the audit fd into a static variable
As audit is pretty much just a special kind of logging we should treat it similar, and manage the audit fd in a static variable. This simplifies the audit fd sharing with the SELinux access checking code quite a bit.
-rw-r--r--Makefile.am4
-rw-r--r--src/core/audit-fd.c71
-rw-r--r--src/core/audit-fd.h25
-rw-r--r--src/core/manager.c27
-rw-r--r--src/core/manager.h5
-rw-r--r--src/core/selinux-access.c19
-rw-r--r--src/shared/audit.h3
7 files changed, 115 insertions, 39 deletions
diff --git a/Makefile.am b/Makefile.am
index 031e1ac27d..6836851921 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1020,7 +1020,9 @@ libsystemd_core_la_SOURCES = \
src/core/killall.h \
src/core/killall.c \
src/core/syscall-list.c \
- src/core/syscall-list.h
+ src/core/syscall-list.h \
+ src/core/audit-fd.c \
+ src/core/audit-fd.h
nodist_libsystemd_core_la_SOURCES = \
src/core/load-fragment-gperf.c \
diff --git a/src/core/audit-fd.c b/src/core/audit-fd.c
new file mode 100644
index 0000000000..0a8626fbc2
--- /dev/null
+++ b/src/core/audit-fd.c
@@ -0,0 +1,71 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2012 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <errno.h>
+
+#include "audit-fd.h"
+#include "log.h"
+
+#ifdef HAVE_AUDIT
+
+#include <libaudit.h>
+
+static bool initialized = false;
+static int audit_fd;
+
+int get_audit_fd(void) {
+
+ if (!initialized) {
+ audit_fd = audit_open();
+
+ if (audit_fd < 0) {
+ if (errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
+ log_error("Failed to connect to audit log: %m");
+
+ audit_fd = errno ? -errno : -EINVAL;
+ }
+
+ initialized = true;
+ }
+
+ return audit_fd;
+}
+
+void close_audit_fd(void) {
+
+ if (initialized && audit_fd >= 0)
+ close_nointr_nofail(audit_fd);
+
+ initialized = true;
+ audit_fd = -ECONNRESET;
+}
+
+#else
+
+int get_audit_fd(void) {
+ return -EAFNOSUPPORT;
+}
+
+void close_audit_fd(void) {
+}
+
+#endif
diff --git a/src/core/audit-fd.h b/src/core/audit-fd.h
new file mode 100644
index 0000000000..8b58289dc5
--- /dev/null
+++ b/src/core/audit-fd.h
@@ -0,0 +1,25 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2012 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int get_audit_fd(void);
+void close_audit_fd(void);
diff --git a/src/core/manager.c b/src/core/manager.c
index 3cd99154e6..6fecbc3f71 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -68,6 +68,7 @@
#include "watchdog.h"
#include "cgroup-util.h"
#include "path-util.h"
+#include "audit-fd.h"
/* As soon as 16 units are in our GC queue, make sure to run a gc sweep */
#define GC_QUEUE_ENTRIES_MAX 16
@@ -257,10 +258,6 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) {
m->pin_cgroupfs_fd = -1;
m->idle_pipe[0] = m->idle_pipe[1] = -1;
-#ifdef HAVE_AUDIT
- m->audit_fd = -1;
-#endif
-
m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = m->swap_watch.fd = -1;
m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
@@ -307,14 +304,6 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) {
if ((r = bus_init(m, running_as != SYSTEMD_SYSTEM)) < 0)
goto fail;
-#ifdef HAVE_AUDIT
- if ((m->audit_fd = audit_open()) < 0 &&
- /* If the kernel lacks netlink or audit support,
- * don't worry about it. */
- errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
- log_error("Failed to connect to audit log: %m");
-#endif
-
m->taint_usr = dir_is_empty("/usr") > 0;
*_m = m;
@@ -498,11 +487,6 @@ void manager_free(Manager *m) {
if (m->notify_watch.fd >= 0)
close_nointr_nofail(m->notify_watch.fd);
-#ifdef HAVE_AUDIT
- if (m->audit_fd >= 0)
- audit_close(m->audit_fd);
-#endif
-
free(m->notify_socket);
lookup_paths_free(&m->lookup_paths);
@@ -1553,8 +1537,10 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
#ifdef HAVE_AUDIT
char *p;
+ int audit_fd;
- if (m->audit_fd < 0)
+ audit_fd = get_audit_fd();
+ if (audit_fd < 0)
return;
/* Don't generate audit events if the service was already
@@ -1573,12 +1559,11 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
return;
}
- if (audit_log_user_comm_message(m->audit_fd, type, "", p, NULL, NULL, NULL, success) < 0) {
+ if (audit_log_user_comm_message(audit_fd, type, "", p, NULL, NULL, NULL, success) < 0) {
if (errno == EPERM) {
/* We aren't allowed to send audit messages?
* Then let's not retry again. */
- audit_close(m->audit_fd);
- m->audit_fd = -1;
+ close_audit_fd();
} else
log_warning("Failed to send audit message: %m");
}
diff --git a/src/core/manager.h b/src/core/manager.h
index 913752f9ef..22145024f1 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -200,11 +200,6 @@ struct Manager {
* file system */
int pin_cgroupfs_fd;
- /* Audit fd */
-#ifdef HAVE_AUDIT
- int audit_fd;
-#endif
-
/* Flags */
SystemdRunningAs running_as;
ManagerExitCode exit_code:5;
diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c
index 3a244ad9ff..9ddc042eca 100644
--- a/src/core/selinux-access.c
+++ b/src/core/selinux-access.c
@@ -32,6 +32,7 @@
#include "dbus-common.h"
#include "audit.h"
#include "selinux-util.h"
+#include "audit-fd.h"
#include <stdio.h>
#include <string.h>
@@ -44,7 +45,6 @@
#include <limits.h>
static bool initialized = false;
-static int audit_fd = -1;
struct auditstruct {
const char *path;
@@ -169,11 +169,11 @@ static int log_callback(int type, const char *fmt, ...) {
va_start(ap, fmt);
#ifdef HAVE_AUDIT
- if (audit_fd >= 0) {
+ if (get_audit_fd() >= 0) {
char buf[LINE_MAX];
vsnprintf(buf, sizeof(buf), fmt, ap);
- audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0);
+ audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0);
va_end(ap);
return 0;
@@ -210,12 +210,9 @@ static int access_init(void) {
return r;
}
-static int selinux_init(Manager *m, DBusError *error) {
+static int selinux_init(DBusError *error) {
int r;
-#ifdef HAVE_AUDIT
- audit_fd = m->audit_fd;
-#endif
if (initialized)
return 0;
@@ -318,7 +315,6 @@ static int get_calling_context(
still be generated if the access would be denied in enforcing mode.
*/
static int selinux_access_check(
- Manager *m,
DBusConnection *connection,
DBusMessage *message,
const char *path,
@@ -330,13 +326,12 @@ static int selinux_access_check(
const char *tclass = NULL;
struct auditstruct audit;
- assert(m);
assert(connection);
assert(message);
assert(permission);
assert(error);
- r = selinux_init(m, error);
+ r = selinux_init(error);
if (r < 0)
return r;
@@ -416,7 +411,7 @@ int selinux_unit_access_check(
assert(permission);
assert(error);
- return selinux_access_check(u->manager, connection, message, u->source_path ? u->source_path : u->fragment_path, permission, error);
+ return selinux_access_check(connection, message, u->source_path ? u->source_path : u->fragment_path, permission, error);
}
int selinux_manager_access_check(
@@ -432,7 +427,7 @@ int selinux_manager_access_check(
assert(permission);
assert(error);
- return selinux_access_check(m, connection, message, NULL, permission, error);
+ return selinux_access_check(connection, message, NULL, permission, error);
}
void selinux_access_finish(void) {
diff --git a/src/shared/audit.h b/src/shared/audit.h
index f2740bc42c..490a0b0320 100644
--- a/src/shared/audit.h
+++ b/src/shared/audit.h
@@ -22,8 +22,11 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <sys/types.h>
+
#include "capability.h"
int audit_session_from_pid(pid_t pid, uint32_t *id);
int audit_loginuid_from_pid(pid_t pid, uid_t *uid);
+
#endif