diff options
| author | Michael Scherer <misc@zarb.org> | 2014-02-06 10:05:16 +0100 | 
|---|---|---|
| committer | Lennart Poettering <lennart@poettering.net> | 2014-02-10 13:18:16 +0100 | 
| commit | 7b52a628f8b43ba521c302a7f32bccf9d0dc8bfd (patch) | |
| tree | d23ed2ee1153ffa4e45c1752a077ae2df6901a36 | |
| parent | 36e0e6311bb4df37385db19b5eca03973b26b5ff (diff) | |
exec: Add SELinuxContext configuration item
This permit to let system administrators decide of the domain of a service.
This can be used with templated units to have each service in a différent
domain ( for example, a per customer database, using MLS or anything ),
or can be used to force a non selinux enabled system (jvm, erlang, etc)
to start in a different domain for each service.
| -rw-r--r-- | man/systemd.exec.xml | 11 | ||||
| -rw-r--r-- | src/core/dbus-execute.c | 1 | ||||
| -rw-r--r-- | src/core/execute.c | 27 | ||||
| -rw-r--r-- | src/core/execute.h | 2 | ||||
| -rw-r--r-- | src/core/load-fragment-gperf.gperf.m4 | 3 | ||||
| -rw-r--r-- | src/shared/exit-status.c | 3 | ||||
| -rw-r--r-- | src/shared/exit-status.h | 3 | 
7 files changed, 48 insertions, 2 deletions
| diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 7eaf52bc5b..4281c03cf6 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -951,6 +951,17 @@                          </varlistentry>                          <varlistentry> +                                <term><varname>SELinuxContext=</varname></term> + +                                <listitem><para>Set the SELinux context of the +                                executed process. If set, this will override the +                                automated domain transition. However, the policy +                                still need to autorize the transition. See +                                <citerefentry><refentrytitle>setexeccon</refentrytitle><manvolnum>3</manvolnum></citerefentry> +                                for details.</para></listitem> +                        </varlistentry> + +                        <varlistentry>                                  <term><varname>IgnoreSIGPIPE=</varname></term>                                  <listitem><para>Takes a boolean diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 4236b98087..db16990233 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -419,6 +419,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("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", "au", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/core/execute.c b/src/core/execute.c index 91e4352f9a..c02c768c68 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -47,6 +47,10 @@  #include <security/pam_appl.h>  #endif +#ifdef HAVE_SELINUX +#include <selinux/selinux.h> +#endif +  #include "execute.h"  #include "strv.h"  #include "macro.h" @@ -1564,6 +1568,20 @@ int exec_spawn(ExecCommand *command,                                          goto fail_child;                                  }                          } +#ifdef HAVE_SELINUX +                        if (context->selinux_context) { +                                err = security_check_context(context->selinux_context); +                                if (err < 0) { +                                        r = EXIT_SELINUX_CONTEXT; +                                        goto fail_child; +                                } +                                err = setexeccon(context->selinux_context); +                                if (err < 0) { +                                        r = EXIT_SELINUX_CONTEXT; +                                        goto fail_child; +                                } +                        } +#endif                  }                  err = build_environment(context, n_fds, watchdog_usec, home, username, shell, &our_env); @@ -1722,6 +1740,9 @@ void exec_context_done(ExecContext *c) {          free(c->utmp_id);          c->utmp_id = NULL; +        free(c->selinux_context); +        c->selinux_context = NULL; +          free(c->syscall_filter);          c->syscall_filter = NULL;  } @@ -2091,6 +2112,12 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {                  fprintf(f,                          "%sUtmpIdentifier: %s\n",                          prefix, c->utmp_id); + +        if (c->selinux_context) +                fprintf(f, +                        "%sSELinuxContext: %s\n", +                        prefix, c->selinux_context); +  }  void exec_status_start(ExecStatus *s, pid_t pid) { diff --git a/src/core/execute.h b/src/core/execute.h index 4851152743..be811a97c1 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -133,6 +133,8 @@ struct ExecContext {          char *utmp_id; +        char *selinux_context; +          char **read_write_dirs, **read_only_dirs, **inaccessible_dirs;          unsigned long mount_flags; diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 59b2a645d0..7d405788d7 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -76,7 +76,8 @@ $1.MountFlags,                   config_parse_exec_mount_flags,      0,  $1.TCPWrapName,                  config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.tcpwrap_name)  $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.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)'  )m4_dnl  m4_define(`KILL_CONTEXT_CONFIG_ITEMS',  `$1.SendSIGKILL,                 config_parse_bool,                  0,                             offsetof($1, kill_context.send_sigkill) diff --git a/src/shared/exit-status.c b/src/shared/exit-status.c index ef2d63f57d..70789f5136 100644 --- a/src/shared/exit-status.c +++ b/src/shared/exit-status.c @@ -130,6 +130,9 @@ const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) {                  case EXIT_SECCOMP:                          return "SECCOMP"; + +                case EXIT_SELINUX_CONTEXT: +                        return "SELINUX_CONTEXT";                  }          } diff --git a/src/shared/exit-status.h b/src/shared/exit-status.h index 1ecf9d5784..e84bfe3704 100644 --- a/src/shared/exit-status.h +++ b/src/shared/exit-status.h @@ -67,7 +67,8 @@ typedef enum ExitStatus {          EXIT_NETWORK,          EXIT_NAMESPACE,          EXIT_NO_NEW_PRIVILEGES, -        EXIT_SECCOMP +        EXIT_SECCOMP, +        EXIT_SELINUX_CONTEXT  } ExitStatus;  typedef enum ExitStatusLevel { | 
