From: Václav Pavlín <vpav...@redhat.com> --- src/core/selinux-access.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++- src/core/selinux-access.h | 15 +++++++++--- 2 files changed, 70 insertions(+), 4 deletions(-)
diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c index 0a3ee18..5908a79 100644 --- a/src/core/selinux-access.c +++ b/src/core/selinux-access.c @@ -333,6 +333,50 @@ static int get_calling_context( return 0; } +static int load_context( + const char *path, + const char *name, + char **context) { + + int r = 0; + char l[LINE_MAX]; + char *p; + FILE *fd; + + fd = fopen(path, "r"); + if (!fd) + return -EEXIST; + + if (!fgets(l, sizeof(l), fd)) { + if (feof(fd)) { + r = -EINVAL; + goto finish; + } + + log_error("Failed to read context file '%s': %m", path); + r = -errno; + goto finish; + } + + p = strtok (l, "="); + if (p && streq(p, name)) { + p = strtok (NULL, "="); + if (!p) { + r = -EINVAL; + goto finish; + } + + *context = strdup(p); + } else + r = -EINVAL; + +finish: + if (fd) + fclose(fd); + + return r; +} + /* This function communicates with the kernel to check whether or not it should allow the access. @@ -342,6 +386,7 @@ static int get_calling_context( int selinux_access_check( DBusConnection *connection, DBusMessage *message, + int class, const char *path, const char *permission, DBusError *error) { @@ -374,7 +419,7 @@ int selinux_access_check( goto finish; } - if (path) { + if (class == CLASS_SERVICE) { tclass = "service"; /* get the file context of the unit file */ r = getfilecon(path, &fcon); @@ -384,7 +429,19 @@ int selinux_access_check( log_error("Failed to get security context on %s: %m",path); goto finish; } + } else if (class == CLASS_TRANSIENT) { + const char *context_path = selinux_systemd_contexts_path(); + + tclass = "service"; + /* get the context transient unit */ + r = load_context(context_path, "runtime", &fcon); + if (r < 0) { + dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "Failed to get context for transient unit"); + r = -errno; + log_error("Failed to get security context on transient unit %s: %m", context_path); + goto finish; + } } else { tclass = "system"; r = getcon(&fcon); diff --git a/src/core/selinux-access.h b/src/core/selinux-access.h index 2d7ac64..79eea6a 100644 --- a/src/core/selinux-access.h +++ b/src/core/selinux-access.h @@ -25,7 +25,13 @@ void selinux_access_free(void); -int selinux_access_check(DBusConnection *connection, DBusMessage *message, const char *path, const char *permission, DBusError *error); +int selinux_access_check(DBusConnection *connection, DBusMessage *message, int class, const char *path, const char *permission, DBusError *error); + +enum { + CLASS_SYSTEM, + CLASS_SERVICE, + CLASS_TRANSIENT +}; #ifdef HAVE_SELINUX @@ -36,7 +42,7 @@ int selinux_access_check(DBusConnection *connection, DBusMessage *message, const DBusConnection *_c = (connection); \ DBusMessage *_m = (message); \ dbus_error_init(&_error); \ - _r = selinux_access_check(_c, _m, NULL, (permission), &_error); \ + _r = selinux_access_check(_c, _m, CLASS_SYSTEM, NULL, (permission), &_error); \ if (_r < 0) \ return bus_send_error_reply(_c, _m, &_error, _r); \ } while (false) @@ -49,7 +55,10 @@ int selinux_access_check(DBusConnection *connection, DBusMessage *message, const DBusMessage *_m = (message); \ Unit *_u = (unit); \ dbus_error_init(&_error); \ - _r = selinux_access_check(_c, _m, _u->source_path ?: _u->fragment_path, (permission), &_error); \ + if (_u->source_path || _u->fragment_path) \ + _r = selinux_access_check(_c, _m, CLASS_SERVICE, _u->source_path ?: _u->fragment_path, (permission), &_error); \ + else \ + _r = selinux_access_check(_c, _m, CLASS_TRANSIENT, _u->id, (permission), &_error); \ if (_r < 0) \ return bus_send_error_reply(_c, _m, &_error, _r); \ } while (false) -- 1.8.3.1 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel