]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: add test case for PrivateUsers=true in user manager
authorFilipe Brandenburger <filbranden@gmail.com>
Wed, 13 Nov 2019 18:32:24 +0000 (10:32 -0800)
committerAnita Zhang <the.anitazha@gmail.com>
Wed, 18 Dec 2019 19:09:30 +0000 (11:09 -0800)
The test exercises that PrivateTmp=yes and ProtectHome={read-only,tmpfs}
directives work as expected when PrivateUsers=yes in a user manager.

Some code is also added to test-functions to help set up test cases that
exercise the user manager.

test/TEST-43-PRIVATEUSER-UNPRIV/Makefile [new file with mode: 0644]
test/TEST-43-PRIVATEUSER-UNPRIV/test.sh [new file with mode: 0755]
test/TEST-43-PRIVATEUSER-UNPRIV/testsuite.sh [new file with mode: 0755]
test/test-functions

diff --git a/test/TEST-43-PRIVATEUSER-UNPRIV/Makefile b/test/TEST-43-PRIVATEUSER-UNPRIV/Makefile
new file mode 100644 (file)
index 0000000..45e9bfc
--- /dev/null
@@ -0,0 +1,9 @@
+BUILD_DIR=$(shell ../../tools/find-build-dir.sh)
+
+all setup run:
+       @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@
+
+clean clean-again:
+       @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --clean
+
+.PHONY: all setup run clean clean-again
diff --git a/test/TEST-43-PRIVATEUSER-UNPRIV/test.sh b/test/TEST-43-PRIVATEUSER-UNPRIV/test.sh
new file mode 100755 (executable)
index 0000000..23904a3
--- /dev/null
@@ -0,0 +1,45 @@
+#!/bin/bash
+set -e
+TEST_DESCRIPTION="Test PrivateUsers=yes on user manager"
+. $TEST_BASE_DIR/test-functions
+
+test_setup() {
+    create_empty_image_rootdir
+
+    (
+        LOG_LEVEL=5
+        eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+        setup_basic_environment
+
+        mask_supporting_services
+
+        usermod --root $initdir -d /home/nobody -s /bin/bash nobody
+        mkdir $initdir/home $initdir/home/nobody
+        # Ubuntu's equivalent is nogroup
+        chown nobody:nobody $initdir/home/nobody || chown nobody:nogroup $initdir/home/nobody
+
+        enable_user_manager nobody
+
+        nobody_uid=$(id -u nobody)
+
+        # setup the testsuite service
+        cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+[Unit]
+Description=Testsuite service
+After=systemd-logind.service user@$nobody_uid.service
+
+[Service]
+ExecStart=/testsuite.sh
+Type=oneshot
+EOF
+        cp testsuite.sh $initdir/
+
+        setup_testsuite
+    )
+    setup_nspawn_root
+}
+
+has_user_dbus_socket || exit 0
+
+do_test "$@"
diff --git a/test/TEST-43-PRIVATEUSER-UNPRIV/testsuite.sh b/test/TEST-43-PRIVATEUSER-UNPRIV/testsuite.sh
new file mode 100755 (executable)
index 0000000..3cabd78
--- /dev/null
@@ -0,0 +1,61 @@
+#!/bin/bash
+set -ex
+set -o pipefail
+
+systemd-analyze log-level debug
+
+runas() {
+    declare userid=$1
+    shift
+    su "$userid" -c 'XDG_RUNTIME_DIR=/run/user/$UID "$@"' -- sh "$@"
+}
+
+runas nobody systemctl --user --wait is-system-running
+
+runas nobody systemd-run --user --unit=test-private-users \
+    -p PrivateUsers=yes -P echo hello
+
+runas nobody systemd-run --user --unit=test-private-tmp-innerfile \
+    -p PrivateUsers=yes -p PrivateTmp=yes \
+    -P touch /tmp/innerfile.txt
+# File should not exist outside the job's tmp directory.
+test ! -e /tmp/innerfile.txt
+
+touch /tmp/outerfile.txt
+# File should not appear in unit's private tmp.
+runas nobody systemd-run --user --unit=test-private-tmp-outerfile \
+    -p PrivateUsers=yes -p PrivateTmp=yes \
+    -P test ! -e /tmp/outerfile.txt
+
+# Confirm that creating a file in home works
+runas nobody systemd-run --user --unit=test-unprotected-home \
+    -P touch /home/nobody/works.txt
+test -e /home/nobody/works.txt
+
+# Confirm that creating a file in home is blocked under read-only
+runas nobody systemd-run --user --unit=test-protect-home-read-only \
+    -p PrivateUsers=yes -p ProtectHome=read-only \
+    -P bash -c '
+        test -e /home/nobody/works.txt
+        ! touch /home/nobody/blocked.txt
+    '
+test ! -e /home/nobody/blocked.txt
+
+# Check that tmpfs hides the whole directory
+runas nobody systemd-run --user --unit=test-protect-home-tmpfs \
+    -p PrivateUsers=yes -p ProtectHome=tmpfs \
+    -P test ! -e /home/nobody
+
+# Confirm we cannot change groups because we only have one mapping in the user
+# namespace (no CAP_SETGID in the parent namespace to write the additional
+# mapping of the user supplied group and thus cannot change groups to an
+# unmapped group ID)
+! runas nobody systemd-run --user --unit=test-group-fail \
+    -p PrivateUsers=yes -p Group=daemon \
+    -P true
+
+systemd-analyze log-level info
+
+echo OK > /testok
+
+exit 0
index 468a36d310feda25d843d107780a2f91ab23f611..5fffa5b9f862a20560b692f2d586776755678ae6 100644 (file)
@@ -787,7 +787,7 @@ install_libnss() {
 install_dbus() {
     inst $ROOTLIBDIR/system/dbus.socket
 
-    # Newer Fedora versions use dbus-broker by default. Let's install it is available.
+    # Newer Fedora versions use dbus-broker by default. Let's install it if it's available.
     if [ -f $ROOTLIBDIR/system/dbus-broker.service ]; then
         inst $ROOTLIBDIR/system/dbus-broker.service
         inst_symlink /etc/systemd/system/dbus.service
@@ -809,6 +809,31 @@ install_dbus() {
     done
 }
 
+install_user_dbus() {
+    inst $ROOTLIBDIR/user/dbus.socket
+    inst_symlink /usr/lib/systemd/user/sockets.target.wants/dbus.socket || inst_symlink /etc/systemd/user/sockets.target.wants/dbus.socket
+
+    # Append the After= dependency on dbus in case it isn't already set up
+    mkdir -p "$initdir/etc/systemd/system/user@.service.d/"
+    cat <<EOF >"$initdir/etc/systemd/system/user@.service.d/dbus.conf"
+[Unit]
+After=dbus.service
+EOF
+
+    # Newer Fedora versions use dbus-broker by default. Let's install it if it's available.
+    if [ -f $ROOTLIBDIR/user/dbus-broker.service ]; then
+        inst $ROOTLIBDIR/user/dbus-broker.service
+        inst_symlink /etc/systemd/user/dbus.service
+    elif [ -f $ROOTLIBDIR/system/dbus-daemon.service ]; then
+        # Fedora rawhide replaced dbus.service with dbus-daemon.service
+        inst $ROOTLIBDIR/user/dbus-daemon.service
+        # Alias symlink
+        inst_symlink /etc/systemd/user/dbus.service
+    else
+        inst $ROOTLIBDIR/user/dbus.service
+    fi
+}
+
 install_pam() {
     (
     if [[ "$LOOKS_LIKE_DEBIAN" ]] && type -p dpkg-architecture &>/dev/null; then
@@ -879,6 +904,28 @@ install_terminfo() {
     dracut_install -o ${_terminfodir}/l/linux
 }
 
+has_user_dbus_socket() {
+    if [ -f /usr/lib/systemd/user/dbus.socket ] || [ -f /etc/systemd/user/dbus.socket ]; then
+        return 0
+    else
+        echo "Per-user instances are not supported. Skipping..."
+        return 1
+    fi
+}
+
+enable_user_manager() {
+    has_user_dbus_socket || return 0
+
+    local _userid
+    [[ $# -gt 0 ]] || set -- nobody
+    mkdir -p "$initdir/var/lib/systemd/linger"
+    for _userid; do
+        touch "$initdir/var/lib/systemd/linger/$_userid"
+    done
+    dracut_install su
+    install_user_dbus
+}
+
 setup_testsuite() {
     cp $TEST_BASE_DIR/testsuite.target $initdir/etc/systemd/system/
     cp $TEST_BASE_DIR/end.service $initdir/etc/systemd/system/