803fb7
From f2300a5c3226d3a66d77c34ae811401c638f430f Mon Sep 17 00:00:00 2001
803fb7
From: Ronny Chevalier <chevalier.ronny@gmail.com>
803fb7
Date: Mon, 21 Sep 2015 15:45:51 +0200
803fb7
Subject: [PATCH] core: fix group ownership when Group is set
803fb7
803fb7
When Group is set in the unit, the runtime directories are owned by
803fb7
this group and not the default group of the user (same for cgroup paths
803fb7
and standard outputs)
803fb7
803fb7
Fix #1231
803fb7
803fb7
Cherry-picked from: 5bc7452b3219456e07f931e40da30bb94a884293
803fb7
Resolves: #1324826
803fb7
---
803fb7
 src/core/execute.c                       | 19 +++++++++++--------
803fb7
 src/test/test-execute.c                  |  1 +
803fb7
 test/exec-runtimedirectory-owner.service |  9 +++++++++
803fb7
 3 files changed, 21 insertions(+), 8 deletions(-)
803fb7
 create mode 100644 test/exec-runtimedirectory-owner.service
803fb7
803fb7
diff --git a/src/core/execute.c b/src/core/execute.c
803fb7
index 1815e3de2..8172c8b44 100644
803fb7
--- a/src/core/execute.c
803fb7
+++ b/src/core/execute.c
803fb7
@@ -629,14 +629,6 @@ static int enforce_groups(const ExecContext *context, const char *username, gid_
803fb7
          * we avoid NSS lookups for gid=0. */
803fb7
 
803fb7
         if (context->group || username) {
803fb7
-
803fb7
-                if (context->group) {
803fb7
-                        const char *g = context->group;
803fb7
-
803fb7
-                        if ((r = get_group_creds(&g, &gid)) < 0)
803fb7
-                                return r;
803fb7
-                }
803fb7
-
803fb7
                 /* First step, initialize groups from /etc/groups */
803fb7
                 if (username && gid != 0) {
803fb7
                         if (initgroups(username, gid) < 0)
803fb7
@@ -1374,6 +1366,17 @@ static int exec_child(
803fb7
                 }
803fb7
         }
803fb7
 
803fb7
+        if (context->group) {
803fb7
+                const char *g = context->group;
803fb7
+
803fb7
+                r = get_group_creds(&g, &gid;;
803fb7
+                if (r < 0) {
803fb7
+                        *exit_status = EXIT_GROUP;
803fb7
+                        return r;
803fb7
+                }
803fb7
+        }
803fb7
+
803fb7
+
803fb7
         /* If a socket is connected to STDIN/STDOUT/STDERR, we
803fb7
          * must sure to drop O_NONBLOCK */
803fb7
         if (socket_fd >= 0)
803fb7
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
803fb7
index 90b1c871c..38522a168 100644
803fb7
--- a/src/test/test-execute.c
803fb7
+++ b/src/test/test-execute.c
803fb7
@@ -144,6 +144,7 @@ static void test_exec_umask(Manager *m) {
803fb7
 static void test_exec_runtimedirectory(Manager *m) {
803fb7
         test(m, "exec-runtimedirectory.service", 0, CLD_EXITED);
803fb7
         test(m, "exec-runtimedirectory-mode.service", 0, CLD_EXITED);
803fb7
+        test(m, "exec-runtimedirectory-owner.service", 0, CLD_EXITED);
803fb7
 }
803fb7
 
803fb7
 int main(int argc, char *argv[]) {
803fb7
diff --git a/test/exec-runtimedirectory-owner.service b/test/exec-runtimedirectory-owner.service
803fb7
new file mode 100644
803fb7
index 000000000..077e08d1c
803fb7
--- /dev/null
803fb7
+++ b/test/exec-runtimedirectory-owner.service
803fb7
@@ -0,0 +1,9 @@
803fb7
+[Unit]
803fb7
+Description=Test for RuntimeDirectory owner (must not be the default group of the user if Group is set)
803fb7
+
803fb7
+[Service]
803fb7
+ExecStart=/bin/sh -c 'f=/tmp/test-exec_runtimedirectory-owner;g=$(stat -c %G $f); echo "$g"; exit $(test $g = "nobody")'
803fb7
+Type=oneshot
803fb7
+Group=nobody
803fb7
+User=root
803fb7
+RuntimeDirectory=test-exec_runtimedirectory-owner