selinux: use existing library calls for audit data
This commit is contained in:
parent
aba15a0391
commit
c309067483
|
@ -1038,6 +1038,7 @@ libsystemd_core_la_LIBADD = \
|
||||||
libsystemd-label.la \
|
libsystemd-label.la \
|
||||||
libsystemd-shared.la \
|
libsystemd-shared.la \
|
||||||
libsystemd-dbus.la \
|
libsystemd-dbus.la \
|
||||||
|
libsystemd-audit.la \
|
||||||
libsystemd-id128-internal.la \
|
libsystemd-id128-internal.la \
|
||||||
libudev.la \
|
libudev.la \
|
||||||
$(LIBWRAP_LIBS) \
|
$(LIBWRAP_LIBS) \
|
||||||
|
|
2
TODO
2
TODO
|
@ -26,6 +26,8 @@ F18:
|
||||||
|
|
||||||
* https://bugzilla.gnome.org/show_bug.cgi?id=680689
|
* https://bugzilla.gnome.org/show_bug.cgi?id=680689
|
||||||
|
|
||||||
|
* Retest multi-seat
|
||||||
|
|
||||||
* selinux: merge systemd selinux access controls (dwalsh)
|
* selinux: merge systemd selinux access controls (dwalsh)
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
|
@ -580,7 +580,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
|
||||||
|
|
||||||
member = dbus_message_get_member(message);
|
member = dbus_message_get_member(message);
|
||||||
r = selinux_manager_access_check(connection, message, m, &error);
|
r = selinux_manager_access_check(connection, message, m, &error);
|
||||||
if (r)
|
if (r < 0)
|
||||||
return bus_send_error_reply(connection, message, &error, r);
|
return bus_send_error_reply(connection, message, &error, r);
|
||||||
|
|
||||||
if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnit")) {
|
if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnit")) {
|
||||||
|
|
|
@ -734,7 +734,8 @@ int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode
|
||||||
assert(name);
|
assert(name);
|
||||||
assert(mode < _JOB_MODE_MAX);
|
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 r;
|
||||||
|
|
||||||
return manager_add_job(m, type, unit, mode, override, e, _ret);
|
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
|
/* This will load the service information files, but not actually
|
||||||
* start any services or anything. */
|
* 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;
|
return r;
|
||||||
|
|
||||||
manager_dispatch_load_queue(m);
|
manager_dispatch_load_queue(m);
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
@ -31,6 +30,7 @@
|
||||||
#include "dbus-unit.h"
|
#include "dbus-unit.h"
|
||||||
#include "bus-errors.h"
|
#include "bus-errors.h"
|
||||||
#include "dbus-common.h"
|
#include "dbus-common.h"
|
||||||
|
#include "audit.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -212,49 +212,6 @@ finish:
|
||||||
return r;
|
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() */
|
/* This mimics dbus_bus_get_unix_user() */
|
||||||
static int bus_get_audit_data(
|
static int bus_get_audit_data(
|
||||||
DBusConnection *connection,
|
DBusConnection *connection,
|
||||||
|
@ -263,74 +220,29 @@ static int bus_get_audit_data(
|
||||||
DBusError *error) {
|
DBusError *error) {
|
||||||
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
DBusMessage *m = NULL, *reply = NULL;
|
int r;
|
||||||
int r = -1;
|
|
||||||
|
|
||||||
m = dbus_message_new_method_call(
|
pid = bus_get_unix_process_id(connection, name, error);
|
||||||
DBUS_SERVICE_DBUS,
|
if (pid <= 0)
|
||||||
DBUS_PATH_DBUS,
|
return -EINVAL;
|
||||||
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(
|
r = audit_loginuid_from_pid(pid, &audit->loginuid);
|
||||||
m,
|
if (r < 0)
|
||||||
DBUS_TYPE_STRING, &name,
|
return r;
|
||||||
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);
|
r = get_process_uid(pid, &audit->uid);
|
||||||
if (!reply) {
|
if (r < 0)
|
||||||
r = -errno;
|
return r;
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = dbus_set_error_from_message(error, reply);
|
r = get_process_gid(pid, &audit->gid);
|
||||||
if (!r) {
|
if (r < 0)
|
||||||
r = -errno;
|
return r;
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = dbus_message_get_args(
|
r = get_process_cmdline(pid, LINE_MAX, true, &audit->cmdline);
|
||||||
reply, error,
|
if (r < 0)
|
||||||
DBUS_TYPE_UINT32, &pid,
|
return r;
|
||||||
DBUS_TYPE_INVALID);
|
|
||||||
if (!r) {
|
|
||||||
r = -errno;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = get_pid_id(pid, "loginuid", &(audit->loginuid));
|
return 0;
|
||||||
if (r)
|
|
||||||
goto finish;
|
|
||||||
|
|
||||||
r = get_pid_id(pid, "uid", &(audit->uid));
|
|
||||||
if (r)
|
|
||||||
goto finish;
|
|
||||||
|
|
||||||
r = get_pid_id(pid, "gid", &(audit->gid));
|
|
||||||
if (r)
|
|
||||||
goto finish;
|
|
||||||
|
|
||||||
r = get_cmdline(pid, &(audit->cmdline));
|
|
||||||
if (r)
|
|
||||||
goto finish;
|
|
||||||
|
|
||||||
r = 0;
|
|
||||||
finish:
|
|
||||||
if (m)
|
|
||||||
dbus_message_unref(m);
|
|
||||||
if (reply)
|
|
||||||
dbus_message_unref(reply);
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -435,49 +347,38 @@ static int get_audit_data(
|
||||||
DBusError *error) {
|
DBusError *error) {
|
||||||
|
|
||||||
const char *sender;
|
const char *sender;
|
||||||
int r = -1;
|
int r;
|
||||||
|
|
||||||
sender = dbus_message_get_sender(message);
|
sender = dbus_message_get_sender(message);
|
||||||
if (sender) {
|
if (sender)
|
||||||
r = bus_get_audit_data(
|
return bus_get_audit_data(connection, sender, audit, error);
|
||||||
connection,
|
else {
|
||||||
sender,
|
|
||||||
audit,
|
|
||||||
error);
|
|
||||||
if (r)
|
|
||||||
goto finish;
|
|
||||||
} else {
|
|
||||||
int fd;
|
int fd;
|
||||||
struct ucred ucred;
|
struct ucred ucred;
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
r = dbus_connection_get_unix_fd(connection, &fd);
|
|
||||||
if (!r) {
|
if (!dbus_connection_get_unix_fd(connection, &fd))
|
||||||
r = -EINVAL;
|
return -EINVAL;
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len);
|
r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
r = -errno;
|
|
||||||
log_error("Failed to determine peer credentials: %m");
|
log_error("Failed to determine peer credentials: %m");
|
||||||
goto finish;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
audit->uid = ucred.uid;
|
audit->uid = ucred.uid;
|
||||||
audit->gid = ucred.gid;
|
audit->gid = ucred.gid;
|
||||||
|
|
||||||
r = get_pid_id(ucred.pid, "loginuid", &(audit->loginuid));
|
r = audit_loginuid_from_pid(ucred.pid, &audit->loginuid);
|
||||||
if (r)
|
if (r < 0)
|
||||||
goto finish;
|
return r;
|
||||||
|
|
||||||
r = get_cmdline(ucred.pid, &(audit->cmdline));
|
r = get_process_cmdline(ucred.pid, LINE_MAX, true, &audit->cmdline);
|
||||||
if (r)
|
if (r < 0)
|
||||||
goto finish;
|
return r;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = 0;
|
|
||||||
|
|
||||||
finish:
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -561,7 +462,9 @@ static int selinux_access_check(DBusConnection *connection, DBusMessage *message
|
||||||
int r = 0;
|
int r = 0;
|
||||||
const char *tclass = NULL;
|
const char *tclass = NULL;
|
||||||
struct auditstruct audit;
|
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.cmdline = NULL;
|
||||||
audit.path = path;
|
audit.path = path;
|
||||||
|
|
||||||
|
@ -589,9 +492,9 @@ static int selinux_access_check(DBusConnection *connection, DBusMessage *message
|
||||||
|
|
||||||
(void) get_audit_data(connection, message, &audit, error);
|
(void) get_audit_data(connection, message, &audit, error);
|
||||||
|
|
||||||
errno=0;
|
errno= 0;
|
||||||
r = selinux_check_access(scon, fcon, tclass, perm, &audit);
|
r = selinux_check_access(scon, fcon, tclass, perm, &audit);
|
||||||
if ( r < 0) {
|
if (r < 0) {
|
||||||
r = -errno;
|
r = -errno;
|
||||||
log_error("SELinux Denied \"%s\"", audit.cmdline);
|
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) {
|
int selinux_unit_access_check(DBusConnection *connection, DBusMessage *message, Manager *m, const char *path, DBusError *error) {
|
||||||
const char *perm;
|
const char *perm;
|
||||||
int require_unit;
|
int require_unit;
|
||||||
const char *member = dbus_message_get_member(message);
|
const char *member;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = selinux_init(m, error);
|
r = selinux_init(m, error);
|
||||||
if (r)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (! selinux_enabled)
|
if (! selinux_enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
member = dbus_message_get_member(message);
|
||||||
|
|
||||||
selinux_perm_lookup(member, &perm, &require_unit);
|
selinux_perm_lookup(member, &perm, &require_unit);
|
||||||
log_debug("SELinux dbus-unit Look %s up perm %s require_unit %d", 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);
|
r = selinux_access_check(connection, message, m, error, perm, path);
|
||||||
if ((r < 0) && (!selinux_enforcing)) {
|
if (r < 0 && !selinux_enforcing) {
|
||||||
dbus_error_init(error);
|
dbus_error_init(error);
|
||||||
r = 0;
|
r = 0;
|
||||||
}
|
}
|
||||||
|
@ -652,7 +557,7 @@ int selinux_manager_access_check(DBusConnection *connection, DBusMessage *messag
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
|
|
||||||
r = selinux_init(m, error);
|
r = selinux_init(m, error);
|
||||||
if (r)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (! selinux_enabled)
|
if (! selinux_enabled)
|
||||||
|
@ -667,21 +572,19 @@ int selinux_manager_access_check(DBusConnection *connection, DBusMessage *messag
|
||||||
const char *name;
|
const char *name;
|
||||||
Unit *u;
|
Unit *u;
|
||||||
|
|
||||||
r = dbus_message_get_args(
|
if (!dbus_message_get_args(
|
||||||
message,
|
message,
|
||||||
error,
|
error,
|
||||||
DBUS_TYPE_STRING, &name,
|
DBUS_TYPE_STRING, &name,
|
||||||
DBUS_TYPE_INVALID);
|
DBUS_TYPE_INVALID)) {
|
||||||
if (!r)
|
r = -EINVAL;
|
||||||
goto finish;
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
u = manager_get_unit(m, name);
|
r = manager_load_unit(m, name, NULL, error, &u);
|
||||||
if ( !u ) {
|
if (r < 0) {
|
||||||
if ((r = manager_load_unit(m, name, NULL, error, &u)) < 0) {
|
dbus_set_error(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
|
||||||
r = -errno;
|
goto finish;
|
||||||
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;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void selinux_access_finish(void) {}
|
void selinux_access_finish(void) {
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue