From: Lennart Poettering Date: Mon, 17 Sep 2012 23:55:49 +0000 (+0200) Subject: selinux: use existing library calls for audit data X-Git-Tag: v190~41 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=c3090674833c8bd34fbdb0e743f1c47d85dd14fb selinux: use existing library calls for audit data --- diff --git a/Makefile.am b/Makefile.am index 637a5367b..c7aff7848 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1038,6 +1038,7 @@ libsystemd_core_la_LIBADD = \ libsystemd-label.la \ libsystemd-shared.la \ libsystemd-dbus.la \ + libsystemd-audit.la \ libsystemd-id128-internal.la \ libudev.la \ $(LIBWRAP_LIBS) \ diff --git a/TODO b/TODO index 22d847398..bdfbffbbf 100644 --- a/TODO +++ b/TODO @@ -26,6 +26,8 @@ F18: * https://bugzilla.gnome.org/show_bug.cgi?id=680689 +* Retest multi-seat + * selinux: merge systemd selinux access controls (dwalsh) Features: diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index ae8854607..2235e3649 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -580,7 +580,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, member = dbus_message_get_member(message); r = selinux_manager_access_check(connection, message, m, &error); - if (r) + if (r < 0) return bus_send_error_reply(connection, message, &error, r); if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnit")) { diff --git a/src/core/manager.c b/src/core/manager.c index cf0691719..f56d39007 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -734,7 +734,8 @@ int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode assert(name); assert(mode < _JOB_MODE_MAX); - if ((r = manager_load_unit(m, name, NULL, NULL, &unit)) < 0) + r = manager_load_unit(m, name, NULL, NULL, &unit); + if (r < 0) return r; return manager_add_job(m, type, unit, mode, override, e, _ret); @@ -846,7 +847,8 @@ int manager_load_unit(Manager *m, const char *name, const char *path, DBusError /* This will load the service information files, but not actually * start any services or anything. */ - if ((r = manager_load_unit_prepare(m, name, path, e, _ret)) != 0) + r = manager_load_unit_prepare(m, name, path, e, _ret); + if (r != 0) return r; manager_dispatch_load_queue(m); diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c index fc1df866c..b207b0d32 100644 --- a/src/core/selinux-access.c +++ b/src/core/selinux-access.c @@ -1,4 +1,3 @@ - /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ /*** @@ -31,6 +30,7 @@ #include "dbus-unit.h" #include "bus-errors.h" #include "dbus-common.h" +#include "audit.h" #include #include @@ -212,49 +212,6 @@ finish: return r; } -static int get_cmdline(pid_t pid, char **cmdline) { - char buf[PATH_MAX]; - FILE *f; - int count; - int n; - - snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long) pid); - f = fopen(buf, "re"); - if (!f) { - return -errno; - } - count = fread(buf, 1, sizeof(buf), f); - fclose(f); - if (! count) { - return -errno; - } - for (n = 0; n < count - 1; n++) - { - if (buf[n] == '\0') - buf[n] = ' '; - } - (*cmdline) = strdup(buf); - if (! (*cmdline)) { - return -errno; - } - return 0; -} - -static int get_pid_id(pid_t pid, const char *file, uid_t *id) { - char buf[PATH_MAX]; - int r = 0; - FILE *f; - snprintf(buf, sizeof(buf), "/proc/%lu/%s", (unsigned long) pid, file); - f = fopen(buf, "re"); - if (!f) - return -errno; - fscanf(f, "%d", id); - if (ferror(f)) - r = -errno; - fclose(f); - return r; -} - /* This mimics dbus_bus_get_unix_user() */ static int bus_get_audit_data( DBusConnection *connection, @@ -263,74 +220,29 @@ static int bus_get_audit_data( DBusError *error) { pid_t pid; - DBusMessage *m = NULL, *reply = NULL; - int r = -1; - - m = dbus_message_new_method_call( - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - "GetConnectionUnixProcessID"); - if (!m) { - r = -errno; - dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL); - goto finish; - } - - r = dbus_message_append_args( - m, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID); - if (!r) { - r = -errno; - dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL); - goto finish; - } - - reply = dbus_connection_send_with_reply_and_block(connection, m, -1, error); - if (!reply) { - r = -errno; - goto finish; - } - - r = dbus_set_error_from_message(error, reply); - if (!r) { - r = -errno; - goto finish; - } + int r; - r = dbus_message_get_args( - reply, error, - DBUS_TYPE_UINT32, &pid, - DBUS_TYPE_INVALID); - if (!r) { - r = -errno; - goto finish; - } + pid = bus_get_unix_process_id(connection, name, error); + if (pid <= 0) + return -EINVAL; - r = get_pid_id(pid, "loginuid", &(audit->loginuid)); - if (r) - goto finish; + r = audit_loginuid_from_pid(pid, &audit->loginuid); + if (r < 0) + return r; - r = get_pid_id(pid, "uid", &(audit->uid)); - if (r) - goto finish; + r = get_process_uid(pid, &audit->uid); + if (r < 0) + return r; - r = get_pid_id(pid, "gid", &(audit->gid)); - if (r) - goto finish; + r = get_process_gid(pid, &audit->gid); + if (r < 0) + return r; - r = get_cmdline(pid, &(audit->cmdline)); - if (r) - goto finish; + r = get_process_cmdline(pid, LINE_MAX, true, &audit->cmdline); + if (r < 0) + return r; - r = 0; -finish: - if (m) - dbus_message_unref(m); - if (reply) - dbus_message_unref(reply); - return r; + return 0; } /* @@ -435,49 +347,38 @@ static int get_audit_data( DBusError *error) { const char *sender; - int r = -1; + int r; sender = dbus_message_get_sender(message); - if (sender) { - r = bus_get_audit_data( - connection, - sender, - audit, - error); - if (r) - goto finish; - } else { + if (sender) + return bus_get_audit_data(connection, sender, audit, error); + else { int fd; struct ucred ucred; socklen_t len; - r = dbus_connection_get_unix_fd(connection, &fd); - if (!r) { - r = -EINVAL; - goto finish; - } + + if (!dbus_connection_get_unix_fd(connection, &fd)) + return -EINVAL; r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len); if (r < 0) { - r = -errno; log_error("Failed to determine peer credentials: %m"); - goto finish; + return -errno; } + audit->uid = ucred.uid; audit->gid = ucred.gid; - r = get_pid_id(ucred.pid, "loginuid", &(audit->loginuid)); - if (r) - goto finish; - - r = get_cmdline(ucred.pid, &(audit->cmdline)); - if (r) - goto finish; - } + r = audit_loginuid_from_pid(ucred.pid, &audit->loginuid); + if (r < 0) + return r; - r = 0; + r = get_process_cmdline(ucred.pid, LINE_MAX, true, &audit->cmdline); + if (r < 0) + return r; -finish: - return r; + return 0; + } } /* @@ -561,7 +462,9 @@ static int selinux_access_check(DBusConnection *connection, DBusMessage *message int r = 0; const char *tclass = NULL; struct auditstruct audit; - audit.uid = audit.loginuid = audit.gid = -1; + + audit.uid = audit.loginuid = (uid_t) -1; + audit.gid = (gid_t) -1; audit.cmdline = NULL; audit.path = path; @@ -589,9 +492,9 @@ static int selinux_access_check(DBusConnection *connection, DBusMessage *message (void) get_audit_data(connection, message, &audit, error); - errno=0; + errno= 0; r = selinux_check_access(scon, fcon, tclass, perm, &audit); - if ( r < 0) { + if (r < 0) { r = -errno; log_error("SELinux Denied \"%s\"", audit.cmdline); @@ -622,21 +525,23 @@ void selinux_access_finish(void) { int selinux_unit_access_check(DBusConnection *connection, DBusMessage *message, Manager *m, const char *path, DBusError *error) { const char *perm; int require_unit; - const char *member = dbus_message_get_member(message); + const char *member; int r; r = selinux_init(m, error); - if (r) + if (r < 0) return r; if (! selinux_enabled) return 0; + member = dbus_message_get_member(message); + selinux_perm_lookup(member, &perm, &require_unit); log_debug("SELinux dbus-unit Look %s up perm %s require_unit %d", member, perm, require_unit); r = selinux_access_check(connection, message, m, error, perm, path); - if ((r < 0) && (!selinux_enforcing)) { + if (r < 0 && !selinux_enforcing) { dbus_error_init(error); r = 0; } @@ -652,7 +557,7 @@ int selinux_manager_access_check(DBusConnection *connection, DBusMessage *messag char *path = NULL; r = selinux_init(m, error); - if (r) + if (r < 0) return r; if (! selinux_enabled) @@ -667,21 +572,19 @@ int selinux_manager_access_check(DBusConnection *connection, DBusMessage *messag const char *name; Unit *u; - r = dbus_message_get_args( + if (!dbus_message_get_args( message, error, DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID); - if (!r) + DBUS_TYPE_INVALID)) { + r = -EINVAL; goto finish; + } - u = manager_get_unit(m, name); - if ( !u ) { - if ((r = manager_load_unit(m, name, NULL, error, &u)) < 0) { - r = -errno; - dbus_set_error(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); - goto finish; - } + r = manager_load_unit(m, name, NULL, error, &u); + if (r < 0) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); + goto finish; } path = u->source_path ? u->source_path : u->fragment_path; @@ -706,5 +609,6 @@ int selinux_manager_access_check(DBusConnection *connection, DBusMessage *messag return 0; } -void selinux_access_finish(void) {} +void selinux_access_finish(void) { +} #endif