From 25a1df7c652d180eb716412885c3ce3fcc1bbded Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 26 Jul 2018 11:42:54 +0900 Subject: [PATCH 1/2] core: fix gid when DynamicUser=yes with static User= When DynamicUser=yes and static User= are set, and the user has different uid and gid, then as the storage socket for the dynamic user does not contains gid, we need to obtain gid. Follow-up for 9ec655cbbd7505ef465e0444da0622e46099ce42. Fixes #9702. --- src/core/dynamic-user.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c index 7c5111ddf6..f380db553e 100644 --- a/src/core/dynamic-user.c +++ b/src/core/dynamic-user.c @@ -525,6 +525,16 @@ static int dynamic_user_realize( num = new_uid; uid_lock_fd = new_uid_lock_fd; } + } else if (is_user && !uid_is_dynamic(num)) { + struct passwd *p; + + /* Statically allocated user may have different uid and gid. So, let's obtain the gid. */ + errno = 0; + p = getpwuid(num); + if (!p) + return errno > 0 ? -errno : -ESRCH; + + gid = p->pw_gid; } /* If the UID/GID was already allocated dynamically, push the data we popped out back in. If it was already From 9f82d685f3ee2af3a534b05f2826295375133e9e Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 26 Jul 2018 11:59:53 +0900 Subject: [PATCH 2/2] test: add tests for DynamicUser= with static User= whose UID and GID are different --- src/test/test-execute.c | 23 +++++++++++++++++++ test/meson.build | 2 ++ .../exec-dynamicuser-fixeduser-adm.service | 11 +++++++++ .../exec-dynamicuser-fixeduser-games.service | 11 +++++++++ 4 files changed, 47 insertions(+) create mode 100644 test/test-execute/exec-dynamicuser-fixeduser-adm.service create mode 100644 test/test-execute/exec-dynamicuser-fixeduser-games.service diff --git a/src/test/test-execute.c b/src/test/test-execute.c index acf28d82c4..9ef18bb211 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -105,6 +105,25 @@ invalid: return false; } +static bool check_user_has_group_with_same_name(const char *name) { + struct passwd *p; + struct group *g; + + assert(name); + + p = getpwnam(name); + if (!p || + !streq(p->pw_name, name)) + return false; + + g = getgrgid(p->pw_gid); + if (!g || + !streq(g->gr_name, name)) + return false; + + return true; +} + static bool is_inaccessible_available(void) { char *p; @@ -427,6 +446,10 @@ static void test_exec_supplementarygroups(Manager *m) { static void test_exec_dynamicuser(Manager *m) { test(m, "exec-dynamicuser-fixeduser.service", 0, CLD_EXITED); + if (check_user_has_group_with_same_name("adm")) + test(m, "exec-dynamicuser-fixeduser-adm.service", 0, CLD_EXITED); + if (check_user_has_group_with_same_name("games")) + test(m, "exec-dynamicuser-fixeduser-games.service", 0, CLD_EXITED); test(m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", 0, CLD_EXITED); test(m, "exec-dynamicuser-supplementarygroups.service", 0, CLD_EXITED); test(m, "exec-dynamicuser-statedir.service", 0, CLD_EXITED); diff --git a/test/meson.build b/test/meson.build index 4aab7437e4..616ffb9728 100644 --- a/test/meson.build +++ b/test/meson.build @@ -45,6 +45,8 @@ test_data_files = ''' test-execute/exec-cpuaffinity1.service test-execute/exec-cpuaffinity2.service test-execute/exec-cpuaffinity3.service + test-execute/exec-dynamicuser-fixeduser-adm.service + test-execute/exec-dynamicuser-fixeduser-games.service test-execute/exec-dynamicuser-fixeduser-one-supplementarygroup.service test-execute/exec-dynamicuser-fixeduser.service test-execute/exec-dynamicuser-statedir-migrate-step1.service diff --git a/test/test-execute/exec-dynamicuser-fixeduser-adm.service b/test/test-execute/exec-dynamicuser-fixeduser-adm.service new file mode 100644 index 0000000000..90040ee533 --- /dev/null +++ b/test/test-execute/exec-dynamicuser-fixeduser-adm.service @@ -0,0 +1,11 @@ +[Unit] +Description=Test DynamicUser with static User= whose uid and gid are different +# On Fedora, user adm has uid==3 and gid==4. + +[Service] +Type=oneshot +ExecStart=/bin/sh -x -c 'test "$$(id -nG)" = "adm" && test "$$(id -ng)" = "adm" && test "$$(id -nu)" = "adm"' +# Multiple ExecStart= lines causes the issue #9702. +ExecStart=/bin/sh -x -c 'test "$$(id -nG)" = "adm" && test "$$(id -ng)" = "adm" && test "$$(id -nu)" = "adm"' +DynamicUser=yes +User=adm diff --git a/test/test-execute/exec-dynamicuser-fixeduser-games.service b/test/test-execute/exec-dynamicuser-fixeduser-games.service new file mode 100644 index 0000000000..1cc9518fc6 --- /dev/null +++ b/test/test-execute/exec-dynamicuser-fixeduser-games.service @@ -0,0 +1,11 @@ +[Unit] +Description=Test DynamicUser with static User= whose uid and gid are different +# On Ubuntu or Debian, user games has uid==5 and gid==60. + +[Service] +Type=oneshot +ExecStart=/bin/sh -x -c 'test "$$(id -nG)" = "games" && test "$$(id -ng)" = "games" && test "$$(id -nu)" = "games"' +# Multiple ExecStart= lines causes the issue #9702. +ExecStart=/bin/sh -x -c 'test "$$(id -nG)" = "games" && test "$$(id -ng)" = "games" && test "$$(id -nu)" = "games"' +DynamicUser=yes +User=games