From c1165f822cd9f8c3467b5f825ce933ab8374b361 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Oct 2012 17:40:09 -0400 Subject: 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. --- src/core/audit-fd.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/core/audit-fd.c (limited to 'src/core/audit-fd.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 . +***/ + +#include +#include + +#include "audit-fd.h" +#include "log.h" + +#ifdef HAVE_AUDIT + +#include + +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 -- cgit v1.2.3-54-g00ecf From ffc227c9568eb0a12dc750761d1e5d68ea125aad Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Oct 2012 17:56:54 -0400 Subject: selinux: remove anything PID1-specific from selinux-access.[ch] so that we can reuse it in logind --- src/core/audit-fd.c | 8 ++-- src/core/dbus-job.c | 2 +- src/core/dbus-manager.c | 50 ++++++++++++------------ src/core/dbus-unit.c | 2 +- src/core/selinux-access.c | 98 +++++++++++++---------------------------------- src/core/selinux-access.h | 17 ++++---- 6 files changed, 69 insertions(+), 108 deletions(-) (limited to 'src/core/audit-fd.c') diff --git a/src/core/audit-fd.c b/src/core/audit-fd.c index 0a8626fbc2..5955bd846e 100644 --- a/src/core/audit-fd.c +++ b/src/core/audit-fd.c @@ -19,16 +19,18 @@ along with systemd; If not, see . ***/ -#include -#include +#include #include "audit-fd.h" -#include "log.h" #ifdef HAVE_AUDIT +#include #include +#include "log.h" +#include "util.h" + static bool initialized = false; static int audit_fd; diff --git a/src/core/dbus-job.c b/src/core/dbus-job.c index 5a746840c8..fdc1dce177 100644 --- a/src/core/dbus-job.c +++ b/src/core/dbus-job.c @@ -143,7 +143,7 @@ static DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBu Iterator i; size_t size; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "status"); + SELINUX_ACCESS_CHECK(connection, message, "status"); reply = dbus_message_new_method_return(message); if (!reply) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index b1b90787a9..9cdecfc6b8 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -755,7 +755,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ClearJobs")) { - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "reboot"); + SELINUX_ACCESS_CHECK(connection, message, "reboot"); manager_clear_jobs(m); @@ -765,7 +765,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ResetFailed")) { - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "reload"); + SELINUX_ACCESS_CHECK(connection, message, "reload"); manager_reset_failed(m); @@ -804,7 +804,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, Unit *u; const char *k; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "status"); + SELINUX_ACCESS_CHECK(connection, message, "status"); reply = dbus_message_new_method_return(message); if (!reply) @@ -887,7 +887,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, Iterator i; Job *j; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "status"); + SELINUX_ACCESS_CHECK(connection, message, "status"); reply = dbus_message_new_method_return(message); if (!reply) @@ -946,7 +946,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, char *client; Set *s; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "status"); + SELINUX_ACCESS_CHECK(connection, message, "status"); s = BUS_CONNECTION_SUBSCRIBED(m, connection); if (!s) { @@ -977,7 +977,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Unsubscribe")) { char *client; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "status"); + SELINUX_ACCESS_CHECK(connection, message, "status"); client = set_remove(BUS_CONNECTION_SUBSCRIBED(m, connection), (char*) bus_message_get_sender_with_fallback(message)); if (!client) { @@ -996,7 +996,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, char *dump = NULL; size_t size; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "status"); + SELINUX_ACCESS_CHECK(connection, message, "status"); reply = dbus_message_new_method_return(message); if (!reply) @@ -1028,7 +1028,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, dbus_bool_t cleanup; Snapshot *s; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "start"); + SELINUX_ACCESS_CHECK(connection, message, "start"); if (!dbus_message_get_args( message, @@ -1068,7 +1068,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, const char *k; size_t size; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "status"); + SELINUX_ACCESS_CHECK(connection, message, "status"); reply = dbus_message_new_method_return(message); if (!reply) @@ -1127,7 +1127,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reload")) { - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "reload"); + SELINUX_ACCESS_CHECK(connection, message, "reload"); assert(!m->queued_message); @@ -1145,7 +1145,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reexecute")) { - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "reload"); + SELINUX_ACCESS_CHECK(connection, message, "reload"); /* We don't send a reply back here, the client should * just wait for us disconnecting. */ @@ -1154,7 +1154,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Exit")) { - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "halt"); + SELINUX_ACCESS_CHECK(connection, message, "halt"); if (m->running_as == SYSTEMD_SYSTEM) { dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers."); @@ -1169,7 +1169,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reboot")) { - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "reboot"); + SELINUX_ACCESS_CHECK(connection, message, "reboot"); if (m->running_as != SYSTEMD_SYSTEM) { dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers."); @@ -1184,7 +1184,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "PowerOff")) { - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "halt"); + SELINUX_ACCESS_CHECK(connection, message, "halt"); if (m->running_as != SYSTEMD_SYSTEM) { dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers."); @@ -1199,7 +1199,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Halt")) { - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "halt"); + SELINUX_ACCESS_CHECK(connection, message, "halt"); if (m->running_as != SYSTEMD_SYSTEM) { dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Halting is only supported for system managers."); @@ -1214,7 +1214,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "KExec")) { - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "reboot"); + SELINUX_ACCESS_CHECK(connection, message, "reboot"); if (m->running_as != SYSTEMD_SYSTEM) { dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "kexec is only supported for system managers."); @@ -1232,7 +1232,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, char *u, *v; int k; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "reboot"); + SELINUX_ACCESS_CHECK(connection, message, "reboot"); if (!dbus_message_get_args( message, @@ -1296,7 +1296,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SetEnvironment")) { char **l = NULL, **e = NULL; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "reboot"); + SELINUX_ACCESS_CHECK(connection, message, "reboot"); r = bus_parse_strv(message, &l); if (r == -ENOMEM) @@ -1321,7 +1321,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnsetEnvironment")) { char **l = NULL, **e = NULL; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "reboot"); + SELINUX_ACCESS_CHECK(connection, message, "reboot"); r = bus_parse_strv(message, &l); if (r == -ENOMEM) @@ -1347,7 +1347,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, char **l_set = NULL, **l_unset = NULL, **e = NULL, **f = NULL; DBusMessageIter iter; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "reboot"); + SELINUX_ACCESS_CHECK(connection, message, "reboot"); if (!dbus_message_iter_init(message, &iter)) goto oom; @@ -1400,7 +1400,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, Iterator i; UnitFileList *item; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "status"); + SELINUX_ACCESS_CHECK(connection, message, "status"); reply = dbus_message_new_method_return(message); if (!reply) @@ -1449,7 +1449,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, UnitFileState state; const char *s; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "status"); + SELINUX_ACCESS_CHECK(connection, message, "status"); if (!dbus_message_get_args( message, @@ -1488,7 +1488,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, dbus_bool_t runtime, force; int carries_install_info = -1; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, streq(member, "MaskUnitFiles") ? "disable" : "enable"); + SELINUX_ACCESS_CHECK(connection, message, streq(member, "MaskUnitFiles") ? "disable" : "enable"); if (!dbus_message_iter_init(message, &iter)) goto oom; @@ -1548,7 +1548,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, unsigned n_changes = 0; dbus_bool_t runtime; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, streq(member, "UnmaskUnitFiles") ? "enable" : "disable"); + SELINUX_ACCESS_CHECK(connection, message, streq(member, "UnmaskUnitFiles") ? "enable" : "disable"); if (!dbus_message_iter_init(message, &iter)) goto oom; @@ -1595,7 +1595,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, { NULL, } }; - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "status"); + SELINUX_ACCESS_CHECK(connection, message, "status"); return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, bps); } diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 6bf331ee58..83ee018ff3 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -526,7 +526,7 @@ static DBusHandlerResult bus_unit_message_handler(DBusConnection *connection, DB if (streq(dbus_message_get_path(message), "/org/freedesktop/systemd1/unit")) { /* Be nice to gdbus and return introspection data for our mid-level paths */ - SELINUX_MANAGER_ACCESS_CHECK(m, connection, message, "status"); + SELINUX_ACCESS_CHECK(connection, message, "status"); if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) { char *introspection = NULL; diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c index 9ddc042eca..4b1dc74e93 100644 --- a/src/core/selinux-access.c +++ b/src/core/selinux-access.c @@ -19,30 +19,28 @@ along with systemd; If not, see . ***/ -#include "util.h" -#include "job.h" -#include "manager.h" #include "selinux-access.h" #ifdef HAVE_SELINUX -#include "dbus.h" -#include "log.h" -#include "dbus-unit.h" -#include "bus-errors.h" -#include "dbus-common.h" -#include "audit.h" -#include "selinux-util.h" -#include "audit-fd.h" #include #include #include +#include #include #include #ifdef HAVE_AUDIT #include #endif -#include +#include + +#include "util.h" +#include "log.h" +#include "bus-errors.h" +#include "dbus-common.h" +#include "audit.h" +#include "selinux-util.h" +#include "audit-fd.h" static bool initialized = false; @@ -210,7 +208,7 @@ static int access_init(void) { return r; } -static int selinux_init(DBusError *error) { +static int selinux_access_init(DBusError *error) { int r; if (initialized) @@ -228,6 +226,14 @@ static int selinux_init(DBusError *error) { return 0; } +void selinux_access_free(void) { + if (!initialized) + return; + + avc_destroy(); + initialized = false; +} + static int get_audit_data( DBusConnection *connection, DBusMessage *message, @@ -314,7 +320,7 @@ static int get_calling_context( If the machine is in permissive mode it will return ok. Audit messages will still be generated if the access would be denied in enforcing mode. */ -static int selinux_access_check( +int selinux_access_check( DBusConnection *connection, DBusMessage *message, const char *path, @@ -331,13 +337,13 @@ static int selinux_access_check( assert(permission); assert(error); - r = selinux_init(error); - if (r < 0) - return r; - if (!use_selinux()) return 0; + r = selinux_access_init(error); + if (r < 0) + return r; + log_debug("SELinux access check for path=%s permission=%s", strna(path), permission); audit.uid = audit.loginuid = (uid_t) -1; @@ -398,69 +404,19 @@ finish: return r; } -int selinux_unit_access_check( - Unit *u, - DBusConnection *connection, - DBusMessage *message, - const char *permission, - DBusError *error) { - - assert(u); - assert(connection); - assert(message); - assert(permission); - assert(error); - - return selinux_access_check(connection, message, u->source_path ? u->source_path : u->fragment_path, permission, error); -} - -int selinux_manager_access_check( - Manager *m, - DBusConnection *connection, - DBusMessage *message, - const char *permission, - DBusError *error) { - - assert(m); - assert(connection); - assert(message); - assert(permission); - assert(error); - - return selinux_access_check(connection, message, NULL, permission, error); -} - -void selinux_access_finish(void) { - if (!initialized) - return; - - avc_destroy(); - initialized = false; -} - #else -int selinux_unit_access_check( - Unit *u, - DBusConnection *connection, - DBusMessage *message, - const char *permission, - DBusError *error) { - - return 0; -} - -int selinux_manager_access_check( - Manager *m, +int selinux_access_check( DBusConnection *connection, DBusMessage *message, + const char *path, const char *permission, DBusError *error) { return 0; } -void selinux_access_finish(void) { +void selinux_access_free(void) { } #endif diff --git a/src/core/selinux-access.h b/src/core/selinux-access.h index 5902b2f862..9183cbc9a6 100644 --- a/src/core/selinux-access.h +++ b/src/core/selinux-access.h @@ -21,20 +21,22 @@ along with systemd; If not, see . ***/ -void selinux_access_finish(void); -int selinux_manager_access_check(Manager *manager, DBusConnection *connection, DBusMessage *message, const char *permission, DBusError *error); -int selinux_unit_access_check(Unit *unit, DBusConnection *connection, DBusMessage *message, const char *permission, DBusError *error); +#include + +void selinux_access_free(void); + +int selinux_access_check(DBusConnection *connection, DBusMessage *message, const char *path, const char *permission, DBusError *error); #ifdef HAVE_SELINUX -#define SELINUX_MANAGER_ACCESS_CHECK(manager, connection, message, permission) \ +#define SELINUX_ACCESS_CHECK(connection, message, permission) \ do { \ DBusError _error; \ int _r; \ DBusConnection *_c = (connection); \ DBusMessage *_m = (message); \ dbus_error_init(&_error); \ - _r = selinux_manager_access_check((manager), _c, _m, (permission), &_error); \ + _r = selinux_access_check(_c, _m, NULL, (permission), &_error); \ if (_r < 0) \ return bus_send_error_reply(_c, _m, &_error, _r); \ } while (false) @@ -45,15 +47,16 @@ int selinux_unit_access_check(Unit *unit, DBusConnection *connection, DBusMessag int _r; \ DBusConnection *_c = (connection); \ DBusMessage *_m = (message); \ + Unit *_u = (unit); \ dbus_error_init(&_error); \ - _r = selinux_unit_access_check((unit), _c, _m, (permission), &_error); \ + _r = selinux_access_check(_c, _m, _u->source_path ?: _u->fragment_path, (permission), &_error); \ if (_r < 0) \ return bus_send_error_reply(_c, _m, &_error, _r); \ } while (false) #else -#define SELINUX_MANAGER_ACCESS_CHECK(manager, connection, message, permission) do { } while (false) +#define SELINUX_ACCESS_CHECK(connection, message, permission) do { } while (false) #define SELINUX_UNIT_ACCESS_CHECK(unit, connection, message, permission) do { } while (false) #endif -- cgit v1.2.3-54-g00ecf