]> git.ipfire.org Git - thirdparty/systemd.git/blob - test/test-sysusers.sh.in
NEWS: fix typo
[thirdparty/systemd.git] / test / test-sysusers.sh.in
1 #!/usr/bin/env bash
2 # SPDX-License-Identifier: LGPL-2.1-or-later
3 set -e
4
5 SYSUSERS="${1:-systemd-sysusers}"
6
7 # shellcheck disable=SC1090
8 [ -e "$(dirname "$0")/../systemd-runtest.env" ] && . "$(dirname "$0")/../systemd-runtest.env"
9 SYSTEMD_TEST_DATA=${SYSTEMD_TEST_DATA:-@SYSTEMD_TEST_DATA@}
10 SOURCE=$SYSTEMD_TEST_DATA/test-sysusers
11
12 TESTDIR=$(mktemp --tmpdir --directory "test-sysusers.XXXXXXXXXX")
13 # shellcheck disable=SC2064
14 trap "rm -rf '$TESTDIR'" EXIT INT QUIT PIPE
15
16 prepare_testdir() {
17 mkdir -p "$TESTDIR/etc/sysusers.d/"
18 mkdir -p "$TESTDIR/usr/lib/sysusers.d/"
19 rm -f "$TESTDIR"/etc/*{passwd,group,shadow}
20 for i in $1.initial-{passwd,group,shadow}; do
21 test -f "$i" && cp "$i" "$TESTDIR/etc/${i#*.initial-}"
22 done
23 return 0
24 }
25
26 # shellcheck disable=SC2050
27 [ @SYSTEM_UID_MAX@ -lt @SYSTEM_GID_MAX@ ] && system_guid_max=@SYSTEM_UID_MAX@ || system_guid_max=@SYSTEM_GID_MAX@
28
29 preprocess() {
30 m=${2:-$system_guid_max}
31
32 # shellcheck disable=SC2140
33 sed -e "s/SYSTEM_UGID_MAX/$m/g;
34 s#NOLOGIN#@NOLOGIN@#g" "$1"
35 }
36
37 compare() {
38 if ! diff -u "$TESTDIR/etc/passwd" <(preprocess "$1.expected-passwd" "$3"); then
39 echo >&2 "**** Unexpected output for $f $2"
40 exit 1
41 fi
42
43 if ! diff -u "$TESTDIR/etc/group" <(preprocess "$1.expected-group" "$3"); then
44 echo >&2 "**** Unexpected output for $f $2"
45 exit 1
46 fi
47 }
48
49 rm -f "$TESTDIR"/etc/sysusers.d/* "$TESTDIR"/usr/lib/sysusers.d/*
50
51 # happy tests
52 for f in $(find "$SOURCE"/test-*.input | sort -V); do
53 echo "*** Running $f"
54 prepare_testdir "${f%.input}"
55 cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
56 $SYSUSERS --root="$TESTDIR"
57
58 compare "${f%.*}" ""
59 done
60
61 for f in $(find "$SOURCE"/test-*.input | sort -V); do
62 echo "*** Running $f on stdin"
63 prepare_testdir "${f%.input}"
64 touch "$TESTDIR/etc/sysusers.d/test.conf"
65 $SYSUSERS --root="$TESTDIR" - <"$f"
66
67 compare "${f%.*}" "on stdin"
68 done
69
70 for f in $(find "$SOURCE"/test-*.input | sort -V); do
71 echo "*** Running $f on stdin with --replace"
72 prepare_testdir "${f%.input}"
73 touch "$TESTDIR/etc/sysusers.d/test.conf"
74 # this overrides test.conf which is masked on disk
75 $SYSUSERS --root="$TESTDIR" --replace=/etc/sysusers.d/test.conf - <"$f"
76 # this should be ignored
77 $SYSUSERS --root="$TESTDIR" --replace=/usr/lib/sysusers.d/test.conf - <"$SOURCE/test-1.input"
78
79 compare "${f%.*}" "on stdin with --replace"
80 done
81
82 # test --inline
83 echo "*** Testing --inline"
84 prepare_testdir "$SOURCE/inline"
85 # copy a random file to make sure it is ignored
86 cp "$f" "$TESTDIR/etc/sysusers.d/confuse.conf"
87 $SYSUSERS --root="$TESTDIR" --inline \
88 "u u1 222 - - /bin/zsh" \
89 "g g1 111"
90
91 compare "$SOURCE/inline" "(--inline)"
92
93 # test --replace
94 echo "*** Testing --inline with --replace"
95 prepare_testdir "$SOURCE/inline"
96 # copy a random file to make sure it is ignored
97 cp "$f" "$TESTDIR/etc/sysusers.d/confuse.conf"
98 $SYSUSERS --root="$TESTDIR" \
99 --inline \
100 --replace=/etc/sysusers.d/confuse.conf \
101 "u u1 222 - - /bin/zsh" \
102 "g g1 111"
103
104 compare "$SOURCE/inline" "(--inline --replace=…)"
105
106 echo "*** Testing --inline with no /etc"
107 rm -rf "${TESTDIR:?}/etc"
108 $SYSUSERS --root="$TESTDIR" --inline \
109 "u u1 222 - - /bin/zsh" \
110 "g g1 111"
111
112 compare "$SOURCE/inline" "(--inline)"
113
114 rm -f "$TESTDIR"/etc/sysusers.d/* "$TESTDIR"/usr/lib/sysusers.d/*
115
116 cat >"$TESTDIR/etc/login.defs" <<EOF
117 SYS_UID_MIN abcd
118 SYS_UID_MAX abcd
119 SYS_GID_MIN abcd
120 SYS_GID_MAX abcd
121 SYS_UID_MIN 401
122 SYS_UID_MAX 555
123 SYS_GID_MIN 405
124 SYS_GID_MAX 666
125 SYS_UID_MIN abcd
126 SYS_UID_MAX abcd
127 SYS_GID_MIN abcd
128 SYS_GID_MAX abcd
129 SYS_UID_MIN999
130 SYS_UID_MAX999
131 SYS_GID_MIN999
132 SYS_GID_MAX999
133 EOF
134
135 for f in $(find "$SOURCE"/test-*.input | sort -V); do
136 echo "*** Running $f (with login.defs)"
137 prepare_testdir "${f%.input}"
138 cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
139 $SYSUSERS --root="$TESTDIR"
140
141 # shellcheck disable=SC2050
142 [ @ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES@ = 1 ] && bound=555 || bound=$system_guid_max
143 compare "${f%.*}" "(with login.defs)" "$bound"
144 done
145
146 rm -f "$TESTDIR"/etc/sysusers.d/* "$TESTDIR"/usr/lib/sysusers.d/*
147
148 mv "$TESTDIR/etc/login.defs" "$TESTDIR/etc/login.defs.moved"
149 ln -s ../../../../../etc/login.defs.moved "$TESTDIR/etc/login.defs"
150
151 for f in $(find "$SOURCE"/test-*.input | sort -V); do
152 echo "*** Running $f (with login.defs symlinked)"
153 prepare_testdir "${f%.input}"
154 cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
155 $SYSUSERS --root="$TESTDIR"
156
157 # shellcheck disable=SC2050
158 [ @ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES@ = 1 ] && bound=555 || bound=$system_guid_max
159 compare "${f%.*}" "(with login.defs symlinked)" "$bound"
160 done
161
162 rm -f "$TESTDIR"/etc/sysusers.d/* "$TESTDIR"/usr/lib/sysusers.d/*
163
164 # tests for error conditions
165 for f in $(find "$SOURCE"/unhappy-*.input | sort -V); do
166 echo "*** Running test $f"
167 prepare_testdir "${f%.input}"
168 cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
169 SYSTEMD_LOG_LEVEL=info $SYSUSERS --root="$TESTDIR" 2>&1 | tail -n1 | sed -r 's/^[^:]+:[^:]+://' >"$TESTDIR/err"
170 if ! diff -u "$TESTDIR/err" "${f%.*}.expected-err"; then
171 echo >&2 "**** Unexpected error output for $f"
172 cat >&2 "$TESTDIR/err"
173 exit 1
174 fi
175 done