summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-02-17 16:52:52 +0100
committerLennart Poettering <lennart@poettering.net>2014-02-17 16:52:52 +0100
commit5f8640fb628cb034981e02d741fd9ddf26fdf38d (patch)
treea861f6da5ba7e87cc413683b5e66a4302d17c61a
parent4a3fa6ac77c5236f95963c0a0fdd541d02c6883a (diff)
core: store and expose SELinuxContext field normalized as bool + string
-rw-r--r--src/core/dbus-execute.c20
-rw-r--r--src/core/execute.c18
-rw-r--r--src/core/execute.h1
-rw-r--r--src/core/load-fragment-gperf.gperf.m42
-rw-r--r--src/core/load-fragment.c49
-rw-r--r--src/core/load-fragment.h1
6 files changed, 75 insertions, 16 deletions
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index a62f517dc6..ff5245a0eb 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -464,6 +464,24 @@ static int property_get_syscall_errno(
return sd_bus_message_append(reply, "i", (int32_t) c->syscall_errno);
}
+static int property_get_selinux_context(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ ExecContext *c = userdata;
+
+ assert(bus);
+ assert(reply);
+ assert(c);
+
+ return sd_bus_message_append(reply, "(bs)", c->selinux_context_ignore, c->selinux_context);
+}
+
const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -523,7 +541,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SELinuxContext", "s", NULL, offsetof(ExecContext, selinux_context), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
diff --git a/src/core/execute.c b/src/core/execute.c
index 06ddd5c91c..be15fb95ee 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1572,18 +1572,8 @@ int exec_spawn(ExecCommand *command,
#ifdef HAVE_SELINUX
if (context->selinux_context && use_selinux()) {
- bool ignore;
- char* c;
-
- c = context->selinux_context;
- if (c[0] == '-') {
- c++;
- ignore = true;
- } else
- ignore = false;
-
- err = setexeccon(c);
- if (err < 0 && !ignore) {
+ err = setexeccon(context->selinux_context);
+ if (err < 0 && !context->selinux_context_ignore) {
r = EXIT_SELINUX_CONTEXT;
goto fail_child;
}
@@ -2127,8 +2117,8 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
if (c->selinux_context)
fprintf(f,
- "%sSELinuxContext: %s\n",
- prefix, c->selinux_context);
+ "%sSELinuxContext: %s%s\n",
+ prefix, c->selinux_context_ignore ? "-" : "", c->selinux_context);
if (c->syscall_filter) {
#ifdef HAVE_SECCOMP
diff --git a/src/core/execute.h b/src/core/execute.h
index 06b6b3fb2d..b98ef952e1 100644
--- a/src/core/execute.h
+++ b/src/core/execute.h
@@ -138,6 +138,7 @@ struct ExecContext {
char *utmp_id;
+ bool selinux_context_ignore;
char *selinux_context;
char **read_write_dirs, **read_only_dirs, **inaccessible_dirs;
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index c8add14c80..39fe458968 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -83,7 +83,7 @@ $1.TCPWrapName, config_parse_unit_string_printf, 0,
$1.PAMName, config_parse_unit_string_printf, 0, offsetof($1, exec_context.pam_name)
$1.IgnoreSIGPIPE, config_parse_bool, 0, offsetof($1, exec_context.ignore_sigpipe)
$1.UtmpIdentifier, config_parse_unit_string_printf, 0, offsetof($1, exec_context.utmp_id)
-$1.SELinuxContext, config_parse_unit_string_printf, 0, offsetof($1, exec_context.selinux_context)'
+$1.SELinuxContext, config_parse_exec_selinux_context, 0, offsetof($1, exec_context)'
)m4_dnl
m4_define(`KILL_CONTEXT_CONFIG_ITEMS',
`$1.SendSIGKILL, config_parse_bool, 0, offsetof($1, kill_context.send_sigkill)
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index c923874394..2ee4616a1c 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -1143,6 +1143,55 @@ int config_parse_exec_mount_flags(const char *unit,
return 0;
}
+int config_parse_exec_selinux_context(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ ExecContext *c = data;
+ Unit *u = userdata;
+ bool ignore;
+ char *k;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ free(c->selinux_context);
+ c->selinux_context = NULL;
+ c->selinux_context_ignore = false;
+ return 0;
+ }
+
+ if (rvalue[0] == '-') {
+ ignore = true;
+ rvalue++;
+ } else
+ ignore = false;
+
+ r = unit_name_printf(u, rvalue, &k);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve specifiers, ignoring: %s", strerror(-r));
+ return 0;
+ }
+
+ free(c->selinux_context);
+ c->selinux_context = k;
+ c->selinux_context_ignore = ignore;
+
+ return 0;
+}
+
int config_parse_timer(const char *unit,
const char *filename,
unsigned line,
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
index 23e9d1131b..cc77fccf94 100644
--- a/src/core/load-fragment.h
+++ b/src/core/load-fragment.h
@@ -87,6 +87,7 @@ int config_parse_blockio_device_weight(const char *unit, const char *filename, u
int config_parse_blockio_bandwidth(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_job_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_job_mode_isolate(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec_selinux_context(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
/* gperf prototypes */
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length);