Michal Schmidt e43452
From 2c023ff55f1449a841aa8449f03792a8436c2481 Mon Sep 17 00:00:00 2001
Michal Schmidt e43452
From: Michal Schmidt <mschmidt@redhat.com>
Michal Schmidt e43452
Date: Fri, 16 Dec 2011 18:00:11 +0100
Michal Schmidt f1996e
Subject: [PATCH] tmpfiles: apply chown, chmod for 'Z' entries too
Michal Schmidt e43452
Michal Schmidt e43452
If changing ownership or permissions is not desired, they can be
Michal Schmidt e43452
configured to '-' or omitted entirely.
Michal Schmidt e43452
(cherry picked from commit 062e01bbdbc3201e4c99bc0b702cb04a0ae2190c)
Michal Schmidt e43452
---
Michal Schmidt e43452
 man/systemd-tmpfiles.xml |    3 +-
Michal Schmidt e43452
 man/tmpfiles.d.xml       |   16 ++++++++-----
Michal Schmidt e43452
 src/tmpfiles.c           |   55 +++++++++++++++++++++++----------------------
Michal Schmidt e43452
 3 files changed, 40 insertions(+), 34 deletions(-)
Michal Schmidt e43452
Michal Schmidt e43452
diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml
Michal Schmidt e43452
index 20e399b..74dfd5a 100644
Michal Schmidt e43452
--- a/man/systemd-tmpfiles.xml
Michal Schmidt e43452
+++ b/man/systemd-tmpfiles.xml
Michal Schmidt e43452
@@ -85,7 +85,8 @@
Michal Schmidt e43452
                                 files and directories marked with f,
Michal Schmidt e43452
                                 F, d, D in the configuration files are
Michal Schmidt e43452
                                 created. Files and directories marked with Z
Michal Schmidt e43452
-                                are relabeled.</para></listitem>
Michal Schmidt e43452
+                                have their ownership, access mode and security
Michal Schmidt e43452
+                                labels set.</para></listitem>
Michal Schmidt e43452
                         </varlistentry>
Michal Schmidt e43452
 
Michal Schmidt e43452
                         <varlistentry>
Michal Schmidt e43452
diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
Michal Schmidt e43452
index 6a2a377..e137967 100644
Michal Schmidt e43452
--- a/man/tmpfiles.d.xml
Michal Schmidt e43452
+++ b/man/tmpfiles.d.xml
Michal Schmidt e43452
@@ -158,8 +158,9 @@ d    /run/user 0755 root root 10d</programlisting>
Michal Schmidt e43452
 
Michal Schmidt e43452
                                 <varlistentry>
Michal Schmidt e43452
                                         <term><varname>Z</varname></term>
Michal Schmidt e43452
-                                        <listitem><para>Recursively
Michal Schmidt e43452
-                                        relabel security context of a path and
Michal Schmidt e43452
+                                        <listitem><para>Recursively set
Michal Schmidt e43452
+                                        ownership, access mode and relabel
Michal Schmidt e43452
+                                        security context of a path and
Michal Schmidt e43452
                                         all its subdirectories (if it is a
Michal Schmidt e43452
                                         directory). Lines of this type accept
Michal Schmidt e43452
                                         shell-style globs in place of normal
Michal Schmidt e43452
@@ -174,8 +175,10 @@ d    /run/user 0755 root root 10d</programlisting>
Michal Schmidt e43452
                         <para>The file access mode to use when
Michal Schmidt e43452
                         creating this file or directory. If omitted or
Michal Schmidt e43452
                         when set to - the default is used: 0755 for
Michal Schmidt e43452
-                        directories, 0644 for files. This parameter is
Michal Schmidt e43452
-                        ignored for x, r, R, Z lines.</para>
Michal Schmidt e43452
+                        directories, 0644 for files. For Z lines
Michal Schmidt e43452
+                        if omitted or when set to - the file access mode will
Michal Schmidt e43452
+                        not be modified. This parameter is ignored for x, r, R
Michal Schmidt e43452
+                        lines.</para>
Michal Schmidt e43452
                 </refsect2>
Michal Schmidt e43452
 
Michal Schmidt e43452
                 <refsect2>
Michal Schmidt e43452
@@ -185,8 +188,9 @@ d    /run/user 0755 root root 10d</programlisting>
Michal Schmidt e43452
                         or directory. This may either be a numeric
Michal Schmidt e43452
                         user/group ID or a user or group name. If
Michal Schmidt e43452
                         omitted or when set to - the default 0 (root)
Michal Schmidt e43452
-                        is used. . These parameters are ignored for x,
Michal Schmidt e43452
-                        r, R, Z lines.</para>
Michal Schmidt e43452
+                        is used. For Z lines when omitted or when set to -
Michal Schmidt e43452
+                        the file ownership will not be modified.
Michal Schmidt e43452
+                        These parameters are ignored for x, r, R lines.</para>
Michal Schmidt e43452
                 </refsect2>
Michal Schmidt e43452
 
Michal Schmidt e43452
                 <refsect2>
Michal Schmidt e43452
diff --git a/src/tmpfiles.c b/src/tmpfiles.c
Michal Schmidt e43452
index 18067c4..1395082 100644
Michal Schmidt e43452
--- a/src/tmpfiles.c
Michal Schmidt e43452
+++ b/src/tmpfiles.c
Michal Schmidt e43452
@@ -406,7 +406,27 @@ finish:
Michal Schmidt e43452
         return r;
Michal Schmidt e43452
 }
Michal Schmidt e43452
 
Michal Schmidt e43452
-static int recursive_relabel_children(const char *path) {
Michal Schmidt e43452
+static int item_set_perms(Item *i, const char *path) {
Michal Schmidt e43452
+        /* not using i->path directly because it may be a glob */
Michal Schmidt e43452
+        if (i->mode_set)
Michal Schmidt e43452
+                if (chmod(path, i->mode) < 0) {
Michal Schmidt e43452
+                        log_error("chmod(%s) failed: %m", path);
Michal Schmidt e43452
+                        return -errno;
Michal Schmidt e43452
+                }
Michal Schmidt e43452
+
Michal Schmidt e43452
+        if (i->uid_set || i->gid_set)
Michal Schmidt e43452
+                if (chown(path,
Michal Schmidt e43452
+                          i->uid_set ? i->uid : (uid_t) -1,
Michal Schmidt e43452
+                          i->gid_set ? i->gid : (gid_t) -1) < 0) {
Michal Schmidt e43452
+
Michal Schmidt e43452
+                        log_error("chown(%s) failed: %m", path);
Michal Schmidt e43452
+                        return -errno;
Michal Schmidt e43452
+                }
Michal Schmidt e43452
+
Michal Schmidt e43452
+        return label_fix(path, false);
Michal Schmidt e43452
+}
Michal Schmidt e43452
+
Michal Schmidt e43452
+static int recursive_relabel_children(Item *i, const char *path) {
Michal Schmidt e43452
         DIR *d;
Michal Schmidt e43452
         int ret = 0;
Michal Schmidt e43452
 
Michal Schmidt e43452
@@ -457,7 +477,7 @@ static int recursive_relabel_children(const char *path) {
Michal Schmidt e43452
                 } else
Michal Schmidt e43452
                         is_dir = de->d_type == DT_DIR;
Michal Schmidt e43452
 
Michal Schmidt e43452
-                r = label_fix(entry_path, false);
Michal Schmidt e43452
+                r = item_set_perms(i, entry_path);
Michal Schmidt e43452
                 if (r < 0) {
Michal Schmidt e43452
                         if (ret == 0 && r != -ENOENT)
Michal Schmidt e43452
                                 ret = r;
Michal Schmidt e43452
@@ -466,7 +486,7 @@ static int recursive_relabel_children(const char *path) {
Michal Schmidt e43452
                 }
Michal Schmidt e43452
 
Michal Schmidt e43452
                 if (is_dir) {
Michal Schmidt e43452
-                        r = recursive_relabel_children(entry_path);
Michal Schmidt e43452
+                        r = recursive_relabel_children(i, entry_path);
Michal Schmidt e43452
                         if (r < 0 && ret == 0)
Michal Schmidt e43452
                                 ret = r;
Michal Schmidt e43452
                 }
Michal Schmidt e43452
@@ -483,7 +503,7 @@ static int recursive_relabel(Item *i, const char *path) {
Michal Schmidt e43452
         int r;
Michal Schmidt e43452
         struct stat st;
Michal Schmidt e43452
 
Michal Schmidt e43452
-        r = label_fix(path, false);
Michal Schmidt e43452
+        r = item_set_perms(i, path);
Michal Schmidt e43452
         if (r < 0)
Michal Schmidt e43452
                 return r;
Michal Schmidt e43452
 
Michal Schmidt e43452
@@ -491,7 +511,7 @@ static int recursive_relabel(Item *i, const char *path) {
Michal Schmidt e43452
                 return -errno;
Michal Schmidt e43452
 
Michal Schmidt e43452
         if (S_ISDIR(st.st_mode))
Michal Schmidt e43452
-                r = recursive_relabel_children(path);
Michal Schmidt e43452
+                r = recursive_relabel_children(i, path);
Michal Schmidt e43452
 
Michal Schmidt e43452
         return r;
Michal Schmidt e43452
 }
Michal Schmidt e43452
@@ -523,25 +543,6 @@ static int glob_item(Item *i, int (*action)(Item *, const char *)) {
Michal Schmidt e43452
         return r;
Michal Schmidt e43452
 }
Michal Schmidt e43452
 
Michal Schmidt e43452
-static int item_set_perms(Item *i) {
Michal Schmidt e43452
-        if (i->mode_set)
Michal Schmidt e43452
-                if (chmod(i->path, i->mode) < 0) {
Michal Schmidt e43452
-                        log_error("chmod(%s) failed: %m", i->path);
Michal Schmidt e43452
-                        return -errno;
Michal Schmidt e43452
-                }
Michal Schmidt e43452
-
Michal Schmidt e43452
-        if (i->uid_set || i->gid_set)
Michal Schmidt e43452
-                if (chown(i->path,
Michal Schmidt e43452
-                          i->uid_set ? i->uid : (uid_t) -1,
Michal Schmidt e43452
-                          i->gid_set ? i->gid : (gid_t) -1) < 0) {
Michal Schmidt e43452
-
Michal Schmidt e43452
-                        log_error("chown(%s) failed: %m", i->path);
Michal Schmidt e43452
-                        return -errno;
Michal Schmidt e43452
-                }
Michal Schmidt e43452
-
Michal Schmidt e43452
-        return label_fix(i->path, false);
Michal Schmidt e43452
-}
Michal Schmidt e43452
-
Michal Schmidt e43452
 static int create_item(Item *i) {
Michal Schmidt e43452
         int r;
Michal Schmidt e43452
         mode_t u;
Michal Schmidt e43452
@@ -582,7 +583,7 @@ static int create_item(Item *i) {
Michal Schmidt e43452
                         return -EEXIST;
Michal Schmidt e43452
                 }
Michal Schmidt e43452
 
Michal Schmidt e43452
-                r = item_set_perms(i);
Michal Schmidt e43452
+                r = item_set_perms(i, i->path);
Michal Schmidt e43452
                 if (r < 0)
Michal Schmidt e43452
                         return r;
Michal Schmidt e43452
 
Michal Schmidt e43452
@@ -612,7 +613,7 @@ static int create_item(Item *i) {
Michal Schmidt e43452
                         return -EEXIST;
Michal Schmidt e43452
                 }
Michal Schmidt e43452
 
Michal Schmidt e43452
-                r = item_set_perms(i);
Michal Schmidt e43452
+                r = item_set_perms(i, i->path);
Michal Schmidt e43452
                 if (r < 0)
Michal Schmidt e43452
                         return r;
Michal Schmidt e43452
 
Michal Schmidt e43452
@@ -639,7 +640,7 @@ static int create_item(Item *i) {
Michal Schmidt e43452
                         return -EEXIST;
Michal Schmidt e43452
                 }
Michal Schmidt e43452
 
Michal Schmidt e43452
-                r = item_set_perms(i);
Michal Schmidt e43452
+                r = item_set_perms(i, i->path);
Michal Schmidt e43452
                 if (r < 0)
Michal Schmidt e43452
                         return r;
Michal Schmidt e43452