diff options
-rw-r--r-- | man/systemd.exec.xml | 12 | ||||
-rw-r--r-- | src/cgroup.c | 44 | ||||
-rw-r--r-- | src/cgroup.h | 6 | ||||
-rw-r--r-- | src/dbus-execute.h | 6 | ||||
-rw-r--r-- | src/execute.c | 13 | ||||
-rw-r--r-- | src/execute.h | 2 | ||||
-rw-r--r-- | src/load-fragment.c | 3 |
7 files changed, 81 insertions, 5 deletions
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index ffc257383d..b9a37da38e 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -630,6 +630,18 @@ </varlistentry> <varlistentry> + <term><varname>ControlGroupModify=</varname></term> + <listitem><para>Takes a boolean + argument. If true, the control groups + created for this unit will be owned by + ther user specified with + <varname>User=</varname> (and the + configured group), and he can create + subgroups as well as add processes to + the group.</para></listitem> + </varlistentry> + + <varlistentry> <term><varname>CapabilityBoundingSet=</varname></term> <listitem><para>Controls which diff --git a/src/cgroup.c b/src/cgroup.c index 0c6f20d4b7..a3491582be 100644 --- a/src/cgroup.c +++ b/src/cgroup.c @@ -140,6 +140,50 @@ int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid) { return 0; } +int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid) { + assert(b); + + if (!b->realized) + return -EINVAL; + + return cg_set_group_access(b->controller, b->path, mode, uid, gid); +} + +int cgroup_bonding_set_group_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid) { + CGroupBonding *b; + int r; + + LIST_FOREACH(by_unit, b, first) { + r = cgroup_bonding_set_group_access(b, mode, uid, gid); + if (r < 0) + return r; + } + + return 0; +} + +int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid) { + assert(b); + + if (!b->realized) + return -EINVAL; + + return cg_set_task_access(b->controller, b->path, mode, uid, gid); +} + +int cgroup_bonding_set_task_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid) { + CGroupBonding *b; + int r; + + LIST_FOREACH(by_unit, b, first) { + r = cgroup_bonding_set_task_access(b, mode, uid, gid); + if (r < 0) + return r; + } + + return 0; +} + int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s) { assert(b); assert(sig >= 0); diff --git a/src/cgroup.h b/src/cgroup.h index c6dff4313e..f33d8440e6 100644 --- a/src/cgroup.h +++ b/src/cgroup.h @@ -59,6 +59,12 @@ void cgroup_bonding_free_list(CGroupBonding *first, bool remove_or_trim); int cgroup_bonding_install(CGroupBonding *b, pid_t pid); int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid); +int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); +int cgroup_bonding_set_group_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); + +int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); +int cgroup_bonding_set_task_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); + int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s); int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s); diff --git a/src/dbus-execute.h b/src/dbus-execute.h index 56c5bcd4f4..49ad6cb82a 100644 --- a/src/dbus-execute.h +++ b/src/dbus-execute.h @@ -91,7 +91,8 @@ " <property name=\"SameProcessGroup\" type=\"b\" access=\"read\"/>\n" \ " <property name=\"KillMode\" type=\"s\" access=\"read\"/>\n" \ " <property name=\"KillSignal\" type=\"i\" access=\"read\"/>\n" \ - " <property name=\"UtmpIdentifier\" type=\"s\" access=\"read\"/>\n" + " <property name=\"UtmpIdentifier\" type=\"s\" access=\"read\"/>\n" \ + " <property name=\"ControlGroupModify\" type=\"b\" access=\"read\"/>\n" #define BUS_EXEC_COMMAND_INTERFACE(name) \ " <property name=\"" name "\" type=\"a(sasbttuii)\" access=\"read\"/>\n" @@ -153,7 +154,8 @@ { interface, "SameProcessGroup", bus_property_append_bool, "b", &(context).same_pgrp }, \ { interface, "KillMode", bus_execute_append_kill_mode, "s", &(context).kill_mode }, \ { interface, "KillSignal", bus_property_append_int, "i", &(context).kill_signal }, \ - { interface, "UtmpIdentifier", bus_property_append_string, "s", (context).utmp_id } + { interface, "UtmpIdentifier", bus_property_append_string, "s", (context).utmp_id }, \ + { interface, "ControlGroupModify", bus_property_append_bool, "b", &(context).control_group_modify } #define BUS_EXEC_STATUS_PROPERTIES(interface, estatus, prefix) \ { interface, prefix "StartTimestamp", bus_property_append_usec, "t", &(estatus).start_timestamp.realtime }, \ diff --git a/src/execute.c b/src/execute.c index b00ccde4d5..6f0f5d09d9 100644 --- a/src/execute.c +++ b/src/execute.c @@ -1246,6 +1246,13 @@ int exec_spawn(ExecCommand *command, r = EXIT_STDIN; goto fail_child; } + + if (cgroup_bondings && context->control_group_modify) + if (cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid) < 0 || + cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid) < 0) { + r = EXIT_CGROUP; + goto fail_child; + } } #ifdef HAVE_PAM @@ -1649,12 +1656,14 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { "%sWorkingDirectory: %s\n" "%sRootDirectory: %s\n" "%sNonBlocking: %s\n" - "%sPrivateTmp: %s\n", + "%sPrivateTmp: %s\n" + "%sControlGroupModify: %s\n", prefix, c->umask, prefix, c->working_directory ? c->working_directory : "/", prefix, c->root_directory ? c->root_directory : "/", prefix, yes_no(c->non_blocking), - prefix, yes_no(c->private_tmp)); + prefix, yes_no(c->private_tmp), + prefix, yes_no(c->control_group_modify)); STRV_FOREACH(e, c->environment) fprintf(f, "%sEnvironment: %s\n", prefix, *e); diff --git a/src/execute.h b/src/execute.h index 55bae24a21..a2d9072357 100644 --- a/src/execute.h +++ b/src/execute.h @@ -160,6 +160,8 @@ struct ExecContext { bool non_blocking; bool private_tmp; + bool control_group_modify; + /* This is not exposed to the user but available * internally. We need it to make sure that whenever we spawn * /bin/mount it is run in the same process group as us so diff --git a/src/load-fragment.c b/src/load-fragment.c index 352db6b385..0c2ef91652 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -1911,7 +1911,8 @@ static int load_from_path(Unit *u, const char *path) { { "KillMode", config_parse_kill_mode, 0, &(context).kill_mode, section }, \ { "KillSignal", config_parse_kill_signal, 0, &(context).kill_signal, section }, \ { "SendSIGKILL", config_parse_bool, 0, &(context).send_sigkill, section }, \ - { "UtmpIdentifier", config_parse_string_printf, 0, &(context).utmp_id, section } + { "UtmpIdentifier", config_parse_string_printf, 0, &(context).utmp_id, section }, \ + { "ControlGroupModify", config_parse_bool, 0, &(context).control_group_modify, section } const ConfigItem items[] = { { "Names", config_parse_names, 0, u, "Unit" }, |