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