chiark / gitweb /
core: store and expose SELinuxContext field normalized as bool + string
authorLennart Poettering <lennart@poettering.net>
Mon, 17 Feb 2014 15:52:52 +0000 (16:52 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 17 Feb 2014 15:52:52 +0000 (16:52 +0100)
src/core/dbus-execute.c
src/core/execute.c
src/core/execute.h
src/core/load-fragment-gperf.gperf.m4
src/core/load-fragment.c
src/core/load-fragment.h

index a62f517..ff5245a 100644 (file)
@@ -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),
index 06ddd5c..be15fb9 100644 (file)
@@ -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
index 06b6b3f..b98ef95 100644 (file)
@@ -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;
index c8add14..39fe458 100644 (file)
@@ -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)
index c923874..2ee4616 100644 (file)
@@ -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,
index 23e9d11..cc77fcc 100644 (file)
@@ -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);