summaryrefslogtreecommitdiffstats
path: root/test/units/TEST-22-TMPFILES.03.sh
diff options
context:
space:
mode:
Diffstat (limited to 'test/units/TEST-22-TMPFILES.03.sh')
-rwxr-xr-xtest/units/TEST-22-TMPFILES.03.sh275
1 files changed, 275 insertions, 0 deletions
diff --git a/test/units/TEST-22-TMPFILES.03.sh b/test/units/TEST-22-TMPFILES.03.sh
new file mode 100755
index 0000000..d158498
--- /dev/null
+++ b/test/units/TEST-22-TMPFILES.03.sh
@@ -0,0 +1,275 @@
+#!/bin/bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# Basic tests for types creating/writing files
+set -eux
+set -o pipefail
+
+rm -fr /tmp/{f,F,w}
+mkdir /tmp/{f,F,w}
+touch /tmp/file-owned-by-root
+
+#
+# 'f'
+#
+systemd-tmpfiles --dry-run --create - <<EOF
+f /tmp/f/1 0644 - - - -
+f /tmp/f/2 0644 - - - This string should be written
+EOF
+
+test ! -e /tmp/f/1
+test ! -e /tmp/f/2
+
+systemd-tmpfiles --create - <<EOF
+f /tmp/f/1 0644 - - - -
+f /tmp/f/2 0644 - - - This string should be written
+EOF
+
+### '1' should exist and be empty
+test -f /tmp/f/1; test ! -s /tmp/f/1
+test "$(stat -c %U:%G:%a /tmp/f/1)" = "root:root:644"
+
+test "$(stat -c %U:%G:%a /tmp/f/2)" = "root:root:644"
+test "$(< /tmp/f/2)" = "This string should be written"
+
+### The perms are supposed to be updated even if the file already exists.
+systemd-tmpfiles --create - <<EOF
+f /tmp/f/1 0666 daemon daemon - This string should not be written
+EOF
+
+# file should be empty
+test ! -s /tmp/f/1
+test "$(stat -c %U:%G:%a /tmp/f/1)" = "daemon:daemon:666"
+
+### But we shouldn't try to set perms on an existing file which is not a
+### regular one.
+mkfifo /tmp/f/fifo
+chmod 644 /tmp/f/fifo
+
+(! systemd-tmpfiles --create -) <<EOF
+f /tmp/f/fifo 0666 daemon daemon - This string should not be written
+EOF
+
+test -p /tmp/f/fifo
+test "$(stat -c %U:%G:%a /tmp/f/fifo)" = "root:root:644"
+
+### 'f' should not follow symlinks.
+ln -s missing /tmp/f/dangling
+ln -s /tmp/file-owned-by-root /tmp/f/symlink
+
+(! systemd-tmpfiles --create -) <<EOF
+f /tmp/f/dangling 0644 daemon daemon - -
+f /tmp/f/symlink 0644 daemon daemon - -
+EOF
+test ! -e /tmp/f/missing
+test "$(stat -c %U:%G:%a /tmp/file-owned-by-root)" = "root:root:644"
+
+### Handle read-only filesystem gracefully: we shouldn't fail if the target
+### already exists and have the correct perms.
+mkdir /tmp/f/rw-fs
+mkdir /tmp/f/ro-fs
+
+touch /tmp/f/rw-fs/foo
+chmod 644 /tmp/f/rw-fs/foo
+
+mount -o bind,ro /tmp/f/rw-fs /tmp/f/ro-fs
+
+systemd-tmpfiles --create - <<EOF
+f /tmp/f/ro-fs/foo 0644 - - - - This string should not be written
+EOF
+test -f /tmp/f/ro-fs/foo; test ! -s /tmp/f/ro-fs/foo
+
+(! systemd-tmpfiles --create -) <<EOF
+f /tmp/f/ro-fs/foo 0666 - - - -
+EOF
+test "$(stat -c %U:%G:%a /tmp/f/fifo)" = "root:root:644"
+
+(! systemd-tmpfiles --create -) <<EOF
+f /tmp/f/ro-fs/bar 0644 - - - -
+EOF
+test ! -e /tmp/f/ro-fs/bar
+
+### 'f' shouldn't follow unsafe paths.
+mkdir /tmp/f/daemon
+ln -s /root /tmp/f/daemon/unsafe-symlink
+chown -R --no-dereference daemon:daemon /tmp/f/daemon
+
+(! systemd-tmpfiles --create -) <<EOF
+f /tmp/f/daemon/unsafe-symlink/exploit 0644 daemon daemon - -
+EOF
+test ! -e /tmp/f/daemon/unsafe-symlink/exploit
+
+#
+# 'F'
+#
+echo "This should be truncated" >/tmp/F/truncated
+echo "This should be truncated" >/tmp/F/truncated-with-content
+
+systemd-tmpfiles --create - <<EOF
+F /tmp/F/created 0644 - - - -
+F /tmp/F/created-with-content 0644 - - - new content
+F /tmp/F/truncated 0666 daemon daemon - -
+F /tmp/F/truncated-with-content 0666 daemon daemon - new content
+EOF
+
+test -f /tmp/F/created; test ! -s /tmp/F/created
+test -f /tmp/F/created-with-content
+test "$(< /tmp/F/created-with-content)" = "new content"
+test -f /tmp/F/truncated; test ! -s /tmp/F/truncated
+test "$(stat -c %U:%G:%a /tmp/F/truncated)" = "daemon:daemon:666"
+test -s /tmp/F/truncated-with-content
+test "$(stat -c %U:%G:%a /tmp/F/truncated-with-content)" = "daemon:daemon:666"
+
+### We shouldn't try to truncate anything but regular files since the behavior is
+### unspecified in the other cases.
+mkfifo /tmp/F/fifo
+
+(! systemd-tmpfiles --create -) <<EOF
+F /tmp/F/fifo 0644 - - - -
+EOF
+
+test -p /tmp/F/fifo
+
+### 'F' should not follow symlinks.
+ln -s missing /tmp/F/dangling
+ln -s /tmp/file-owned-by-root /tmp/F/symlink
+
+(! systemd-tmpfiles --create -) <<EOF
+f /tmp/F/dangling 0644 daemon daemon - -
+f /tmp/F/symlink 0644 daemon daemon - -
+EOF
+test ! -e /tmp/F/missing
+test "$(stat -c %U:%G:%a /tmp/file-owned-by-root)" = "root:root:644"
+
+### Handle read-only filesystem gracefully: we shouldn't fail if the target
+### already exists and is empty.
+mkdir /tmp/F/rw-fs
+mkdir /tmp/F/ro-fs
+
+touch /tmp/F/rw-fs/foo
+chmod 644 /tmp/F/rw-fs/foo
+
+mount -o bind,ro /tmp/F/rw-fs /tmp/F/ro-fs
+
+systemd-tmpfiles --create - <<EOF
+F /tmp/F/ro-fs/foo 0644 - - - -
+EOF
+test -f /tmp/F/ro-fs/foo; test ! -s /tmp/F/ro-fs/foo
+
+echo "truncating is not allowed anymore" >/tmp/F/rw-fs/foo
+(! systemd-tmpfiles --create -) <<EOF
+F /tmp/F/ro-fs/foo 0644 - - - -
+EOF
+
+(! systemd-tmpfiles --create -) <<EOF
+F /tmp/F/ro-fs/foo 0644 - - - - This string should not be written
+EOF
+test -f /tmp/F/ro-fs/foo
+grep -q 'truncating is not allowed' /tmp/F/ro-fs/foo
+
+# Trying to change the perms should fail.
+: >/tmp/F/rw-fs/foo
+(! systemd-tmpfiles --create -) <<EOF
+F /tmp/F/ro-fs/foo 0666 - - - -
+EOF
+test "$(stat -c %U:%G:%a /tmp/F/ro-fs/foo)" = "root:root:644"
+
+### Try to create a new file.
+(! systemd-tmpfiles --create -) <<EOF
+F /tmp/F/ro-fs/bar 0644 - - - -
+EOF
+test ! -e /tmp/F/ro-fs/bar
+
+### 'F' shouldn't follow unsafe paths.
+mkdir /tmp/F/daemon
+ln -s /root /tmp/F/daemon/unsafe-symlink
+chown -R --no-dereference daemon:daemon /tmp/F/daemon
+
+(! systemd-tmpfiles --create -) <<EOF
+F /tmp/F/daemon/unsafe-symlink/exploit 0644 daemon daemon - -
+EOF
+test ! -e /tmp/F/daemon/unsafe-symlink/exploit
+
+#
+# 'w'
+#
+touch /tmp/w/overwritten
+touch /tmp/w/appended
+
+### nop if the target does not exist.
+systemd-tmpfiles --dry-run --create - <<EOF
+w /tmp/w/unexistent 0644 - - - new content
+EOF
+test ! -e /tmp/w/unexistent
+
+systemd-tmpfiles --create - <<EOF
+w /tmp/w/unexistent 0644 - - - new content
+EOF
+test ! -e /tmp/w/unexistent
+
+### no argument given -> fails.
+(! systemd-tmpfiles --create -) <<EOF
+w /tmp/w/unexistent 0644 - - - -
+EOF
+
+### write into an empty file.
+systemd-tmpfiles --dry-run --create - <<EOF
+w /tmp/w/overwritten 0644 - - - old content
+EOF
+test -f /tmp/w/overwritten
+test -z "$(< /tmp/w/overwritten)"
+
+systemd-tmpfiles --create - <<EOF
+w /tmp/w/overwritten 0644 - - - old content
+EOF
+test -f /tmp/w/overwritten
+test "$(< /tmp/w/overwritten)" = "old content"
+
+### old content is overwritten
+systemd-tmpfiles --dry-run --create - <<EOF
+w /tmp/w/overwritten 0644 - - - new content
+EOF
+test -f /tmp/w/overwritten
+test "$(< /tmp/w/overwritten)" = "old content"
+
+systemd-tmpfiles --create - <<EOF
+w /tmp/w/overwritten 0644 - - - new content
+EOF
+test -f /tmp/w/overwritten
+test "$(< /tmp/w/overwritten)" = "new content"
+
+### append lines
+systemd-tmpfiles --create - <<EOF
+w+ /tmp/w/appended 0644 - - - 1
+w+ /tmp/w/appended 0644 - - - 2\n
+w+ /tmp/w/appended 0644 - - - 3
+EOF
+test -f /tmp/w/appended
+test "$(< /tmp/w/appended)" = "$(echo -ne '12\n3')"
+
+### writing into an 'exotic' file should be allowed.
+systemd-tmpfiles --dry-run --create - <<EOF
+w /dev/null - - - - new content
+EOF
+
+systemd-tmpfiles --create - <<EOF
+w /dev/null - - - - new content
+EOF
+
+### 'w' follows symlinks
+ln -s ./overwritten /tmp/w/symlink
+systemd-tmpfiles --create - <<EOF
+w /tmp/w/symlink - - - - $(readlink -e /tmp/w/symlink)
+EOF
+readlink -e /tmp/w/symlink
+test "$(< /tmp/w/overwritten)" = "/tmp/w/overwritten"
+
+### 'w' shouldn't follow unsafe paths.
+mkdir /tmp/w/daemon
+ln -s /root /tmp/w/daemon/unsafe-symlink
+chown -R --no-dereference daemon:daemon /tmp/w/daemon
+
+(! systemd-tmpfiles --create -) <<EOF
+f /tmp/w/daemon/unsafe-symlink/exploit 0644 daemon daemon - -
+EOF
+test ! -e /tmp/w/daemon/unsafe-symlink/exploit