]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared: add %g, %G specifiers for group / gid (#10368)
authorDavide Cavalca <davide125@tiscali.it>
Sat, 13 Oct 2018 08:26:48 +0000 (01:26 -0700)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 13 Oct 2018 08:26:48 +0000 (17:26 +0900)
15 files changed:
man/systemd.unit.xml
man/tmpfiles.d.xml
src/core/unit-printf.c
src/shared/install-printf.c
src/shared/specifier.c
src/shared/specifier.h
src/test/test-systemd-tmpfiles.py
src/test/test-unit-file.c
src/test/test-unit-name.c
src/tmpfiles/tmpfiles.c
test/test-execute/exec-specifier.service
test/test-execute/exec-specifier@.service
test/test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service
test/test-execute/exec-supplementarygroups-multiple-groups-withgid.service
test/test-execute/exec-supplementarygroups.service

index 35221335323185464ac8f7eda187049ff2db073a..f418f5b5eec4747deca5add05cd063f1f0d91e40 100644 (file)
     </variablelist>
 
     <para>The following specifiers are interpreted in the Install
-    section: %n, %N, %p, %i, %j, %U, %u, %m, %H, %b, %v. For their meaning
-    see the next section.
+    section: %n, %N, %p, %i, %j, %g, %G, %U, %u, %m, %H, %b, %v. For their
+    meaning see the next section.
     </para>
   </refsect1>
 
             <entry>Directory for temporary files</entry>
             <entry>This is either <filename>/tmp</filename> or the path <literal>$TMPDIR</literal>, <literal>$TEMP</literal> or <literal>$TMP</literal> are set to.</entry>
           </row>
+          <row>
+            <entry><literal>%g</literal></entry>
+            <entry>User group</entry>
+            <entry>This is the name of the group running the service manager instance. In case of the system manager this resolves to <literal>root</literal>.</entry>
+          </row>
+          <row>
+            <entry><literal>%G</literal></entry>
+            <entry>User GID</entry>
+            <entry>This is the numeric GID of the user running the service manager instance. In case of the system manager this resolves to <literal>0</literal>.</entry>
+          </row>
           <row>
             <entry><literal>%u</literal></entry>
             <entry>User name</entry>
index 814a01240a862bc945ca5d2bcfeb9e37bd4f151e..49a5bdd166feff4b21352acdc118dd5cd74dd0a4 100644 (file)
@@ -628,6 +628,16 @@ w- /proc/sys/vm/swappiness - - - - 10</programlisting></para>
               <entry>Directory for temporary files</entry>
               <entry>This is either <filename>/tmp</filename> or the path <literal>$TMPDIR</literal>, <literal>$TEMP</literal> or <literal>$TMP</literal> are set to.</entry>
             </row>
+            <row>
+              <entry><literal>%g</literal></entry>
+              <entry>User group</entry>
+              <entry>This is the name of the group running the command. In case of the system instance this resolves to <literal>root</literal>.</entry>
+            </row>
+            <row>
+              <entry><literal>%G</literal></entry>
+              <entry>User GID</entry>
+              <entry>This is the numeric GID of the group running the command. In case of the system instance this resolves to <constant>0</constant>.</entry>
+            </row>
             <row>
               <entry><literal>%u</literal></entry>
               <entry>User name</entry>
index 046e937e92ad2426c6f0a9a7b676fbbfd745f0bf..547d9d885200b269a2ad25fae2d514c3e8e28af5 100644 (file)
@@ -196,6 +196,8 @@ int unit_name_printf(Unit *u, const char* format, char **ret) {
                 { 'p', specifier_prefix,              NULL },
                 { 'i', specifier_string,              u->instance },
 
+                { 'g', specifier_group_name,          NULL },
+                { 'G', specifier_group_id,            NULL },
                 { 'U', specifier_user_id,             NULL },
                 { 'u', specifier_user_name,           NULL },
 
@@ -264,6 +266,8 @@ int unit_full_printf(Unit *u, const char *format, char **ret) {
                 { 'T', specifier_tmp_dir,                  NULL },
                 { 'V', specifier_var_tmp_dir,              NULL },
 
+                { 'g', specifier_group_name,               NULL },
+                { 'G', specifier_group_id,                 NULL },
                 { 'U', specifier_user_id,                  NULL },
                 { 'u', specifier_user_name,                NULL },
                 { 'h', specifier_user_home,                NULL },
index 078d5734be1bf2fca9fd5d053ac3f29f8384cdeb..b87d6b9d55e9dbaa001b3beaf342041cf262d4fb 100644 (file)
@@ -129,6 +129,8 @@ int install_full_printf(UnitFileInstallInfo *i, const char *format, char **ret)
                 { 'i', specifier_instance,            NULL },
                 { 'j', specifier_last_component,      NULL },
 
+                { 'g', specifier_group_name,          NULL },
+                { 'G', specifier_group_id,            NULL },
                 { 'U', specifier_user_id,             NULL },
                 { 'u', specifier_user_name,           NULL },
 
index b5f22c8d1e6fc37cd2c4464de10d16a3ec97a166..78dda05b4868b2afa2b1cf1c08583baeb8deaadd 100644 (file)
@@ -175,6 +175,24 @@ int specifier_kernel_release(char specifier, void *data, void *userdata, char **
         return 0;
 }
 
+int specifier_group_name(char specifier, void *data, void *userdata, char **ret) {
+        char *t;
+
+        t = gid_to_name(getgid());
+        if (!t)
+                return -ENOMEM;
+
+        *ret = t;
+        return 0;
+}
+
+int specifier_group_id(char specifier, void *data, void *userdata, char **ret) {
+        if (asprintf(ret, UID_FMT, getgid()) < 0)
+                return -ENOMEM;
+
+        return 0;
+}
+
 int specifier_user_name(char specifier, void *data, void *userdata, char **ret) {
         char *t;
 
index e1895129d765d76cb29d133573fb6bcc895160d8..722200b9980101757995d336df4d4d837d995918 100644 (file)
@@ -20,6 +20,8 @@ int specifier_boot_id(char specifier, void *data, void *userdata, char **ret);
 int specifier_host_name(char specifier, void *data, void *userdata, char **ret);
 int specifier_kernel_release(char specifier, void *data, void *userdata, char **ret);
 
+int specifier_group_name(char specifier, void *data, void *userdata, char **ret);
+int specifier_group_id(char specifier, void *data, void *userdata, char **ret);
 int specifier_user_name(char specifier, void *data, void *userdata, char **ret);
 int specifier_user_id(char specifier, void *data, void *userdata, char **ret);
 int specifier_user_home(char specifier, void *data, void *userdata, char **ret);
index 13a44f3c4ab7b3779f607732574bd75ea4a68e3d..28dadd0c5b4219651a1d0ad7e8a11ac689f34d74 100755 (executable)
@@ -12,6 +12,7 @@ import socket
 import subprocess
 import tempfile
 import pwd
+import grp
 
 try:
     from systemd import id128
@@ -95,9 +96,13 @@ def test_valid_specifiers(*, user):
     test_content('f {} - - - - %H', '{}'.format(socket.gethostname()), user=user)
     test_content('f {} - - - - %v', '{}'.format(os.uname().release), user=user)
     test_content('f {} - - - - %U', '{}'.format(os.getuid()), user=user)
+    test_content('f {} - - - - %G', '{}'.format(os.getgid()), user=user)
 
-    user = pwd.getpwuid(os.getuid())
-    test_content('f {} - - - - %u', '{}'.format(user.pw_name), user=user)
+    puser = pwd.getpwuid(os.getuid())
+    test_content('f {} - - - - %u', '{}'.format(puser.pw_name), user=user)
+
+    pgroup = grp.getgrgid(os.getgid())
+    test_content('f {} - - - - %g', '{}'.format(pgroup.gr_name), user=user)
 
     # Note that %h is the only specifier in which we look the environment,
     # because we check $HOME. Should we even be doing that?
index cb074aaa4d9e4d2dccb842e0aabd565de414829c..fe6da4fe2d8840f327a3f80a7a3b817267a20f04 100644 (file)
@@ -621,11 +621,13 @@ static void test_install_printf(void) {
         UnitFileInstallInfo i3 = { .name = name3, .path = path3, };
         UnitFileInstallInfo i4 = { .name = name3, .path = path3, };
 
-        _cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *uid = NULL, *user = NULL;
+        _cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *gid = NULL, *group = NULL, *uid = NULL, *user = NULL;
 
         assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
         assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
         assert_se(host = gethostname_malloc());
+        assert_se(group = gid_to_name(getgid()));
+        assert_se(asprintf(&gid, UID_FMT, getgid()) >= 0);
         assert_se(user = uid_to_name(getuid()));
         assert_se(asprintf(&uid, UID_FMT, getuid()) >= 0);
 
@@ -652,6 +654,8 @@ static void test_install_printf(void) {
         expect(i, "%p", "name");
         expect(i, "%i", "");
         expect(i, "%j", "name");
+        expect(i, "%g", group);
+        expect(i, "%G", gid);
         expect(i, "%u", user);
         expect(i, "%U", uid);
 
@@ -659,12 +663,16 @@ static void test_install_printf(void) {
         expect(i, "%b", bid);
         expect(i, "%H", host);
 
+        expect(i2, "%g", group);
+        expect(i2, "%G", gid);
         expect(i2, "%u", user);
         expect(i2, "%U", uid);
 
         expect(i3, "%n", "name@inst.service");
         expect(i3, "%N", "name@inst");
         expect(i3, "%p", "name");
+        expect(i3, "%g", group);
+        expect(i3, "%G", gid);
         expect(i3, "%u", user);
         expect(i3, "%U", uid);
 
@@ -672,6 +680,8 @@ static void test_install_printf(void) {
         expect(i3, "%b", bid);
         expect(i3, "%H", host);
 
+        expect(i4, "%g", group);
+        expect(i4, "%G", gid);
         expect(i4, "%u", user);
         expect(i4, "%U", uid);
 }
index 157c900276edc58622488042d71f7405e3d917ad..0d3674cff8635b8c0f7bb3fead279ad33011c7be 100644 (file)
@@ -191,7 +191,7 @@ static void test_unit_name_mangle(void) {
 }
 
 static int test_unit_printf(void) {
-        _cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *uid = NULL, *user = NULL, *shell = NULL, *home = NULL;
+        _cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *gid = NULL, *group = NULL, *uid = NULL, *user = NULL, *shell = NULL, *home = NULL;
         _cleanup_(manager_freep) Manager *m = NULL;
         Unit *u;
         int r;
@@ -200,7 +200,9 @@ static int test_unit_printf(void) {
         assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
         assert_se(host = gethostname_malloc());
         assert_se(user = uid_to_name(getuid()));
+        assert_se(group = gid_to_name(getgid()));
         assert_se(asprintf(&uid, UID_FMT, getuid()));
+        assert_se(asprintf(&gid, UID_FMT, getgid()));
         assert_se(get_home_dir(&home) >= 0);
         assert_se(get_shell(&shell) >= 0);
 
@@ -241,6 +243,8 @@ static int test_unit_printf(void) {
         expect(u, "%I", "");
         expect(u, "%j", "blah");
         expect(u, "%J", "blah");
+        expect(u, "%g", group);
+        expect(u, "%G", gid);
         expect(u, "%u", user);
         expect(u, "%U", uid);
         expect(u, "%h", home);
@@ -263,6 +267,8 @@ static int test_unit_printf(void) {
         expect(u, "%I", "foo/foo");
         expect(u, "%j", "blah");
         expect(u, "%J", "blah");
+        expect(u, "%g", group);
+        expect(u, "%G", gid);
         expect(u, "%u", user);
         expect(u, "%U", uid);
         expect(u, "%h", home);
index 1b3cb5fbd3780bcfb0354a5eccc60682bc1b3789..d7e02c400e1204192e3d84ff5aa46ecd095ca487 100644 (file)
@@ -174,6 +174,8 @@ static const Specifier specifier_table[] = {
         { 'H', specifier_host_name,       NULL },
         { 'v', specifier_kernel_release,  NULL },
 
+        { 'g', specifier_group_name,      NULL },
+        { 'G', specifier_group_id,        NULL },
         { 'U', specifier_user_id,         NULL },
         { 'u', specifier_user_name,       NULL },
         { 'h', specifier_user_home,       NULL },
index 13ba859879ec72cf23a4a3c52c2ec2c9c6ab2cff..7c3f81f2b53fec4bc2294c86708e98c10846260f 100644 (file)
@@ -19,9 +19,11 @@ ExecStart=test %L = /var/log
 ExecStart=test %E = /etc
 ExecStart=test %T = /tmp
 ExecStart=test %V = /var/tmp
-ExecStart=sh -c 'test %u = $$(id -un 0)'
-ExecStart=test %U = 0
-ExecStart=sh -c 'test %h = $$(getent passwd 0 | cut -d: -f 6)'
+ExecStart=sh -c 'test %u = $$(id -un)'
+ExecStart=sh -c 'test %U = $$(id -u)'
+ExecStart=sh -c 'test %g = $$(id -gn)'
+ExecStart=sh -c 'test %G = $$(id -g)'
+ExecStart=test %h = /root
 ExecStart=sh -c 'test %s = /bin/sh'
 ExecStart=sh -c 'test %m = $$(cat /etc/machine-id)'
 ExecStart=sh -c 'test %b = $$(cat /proc/sys/kernel/random/boot_id | sed -e 's/-//g')'
index 174559dbd1bdfe9a12b1b7911bff5bee0ee23415..a388926846a18b8a4cc5f1209d02757c5066ab93 100644 (file)
@@ -17,9 +17,11 @@ ExecStart=test %S = /var/lib
 ExecStart=test %C = /var/cache
 ExecStart=test %L = /var/log
 ExecStart=test %E = /etc
-ExecStart=sh -c 'test %u = $$(id -un 0)'
-ExecStart=test %U = 0
-ExecStart=sh -c 'test %h = $$(getent passwd 0 | cut -d: -f 6)'
+ExecStart=sh -c 'test %u = $$(id -un)'
+ExecStart=sh -c 'test %U = $$(id -u)'
+ExecStart=sh -c 'test %g = $$(id -gn)'
+ExecStart=sh -c 'test %G = $$(id -g)'
+ExecStart=test %h = /root
 ExecStart=sh -c 'test %s = /bin/sh'
 ExecStart=sh -c 'test %m = $$(cat /etc/machine-id)'
 ExecStart=sh -c 'test %b = $$(cat /proc/sys/kernel/random/boot_id | sed -e 's/-//g')'
index 3b8cf2445bad9685b87cf4285d3074c55d6d57c3..2a7ce87bb4a6a9f2b479cbf32b3affd4353eed0b 100644 (file)
@@ -2,10 +2,10 @@
 Description=Test for Supplementary Group with multiple groups without Group and User
 
 [Service]
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "0" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "%G" && HAVE=1; done; test "$$HAVE" -eq 1'
 ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
 ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "2" && HAVE=1; done; test "$$HAVE" -eq 1'
 ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "3" && HAVE=1; done; test "$$HAVE" -eq 1'
-ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "0" && test "$$(id -u)" = "0"'
+ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "%G" && test "$$(id -u)" = "%U"'
 Type=oneshot
 SupplementaryGroups=1 2 3
index b7feedff61f8f0258c86f7cc32adeefb420a5fb9..aae20fbf951cc0475fce3518c5e41c8cbd195849 100644 (file)
@@ -5,7 +5,7 @@ Description=Test for Supplementary Group with multiple groups and Group=1
 ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
 ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "2" && HAVE=1; done; test "$$HAVE" -eq 1'
 ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "3" && HAVE=1; done; test "$$HAVE" -eq 1'
-ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "1" && test "$$(id -u)" = "0"'
+ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "1" && test "$$(id -u)" = "%U"'
 Type=oneshot
 Group=1
 SupplementaryGroups=1 2 3
index 5822c6b870766a196f8dd17fada15bb44b1756a2..6f6e2ba8226527b102bc90e4a40bffde2b8c117a 100644 (file)
@@ -2,7 +2,7 @@
 Description=Test for Supplementary Group
 
 [Service]
-ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "0" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "%G" && HAVE=1; done; test "$$HAVE" -eq 1'
 ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
 Type=oneshot
 SupplementaryGroups=1