hwdb: fix screen rotation for EXO Wings 2in1 w1125 (#36283)
[systemd.io.git] / test / units / TEST-35-LOGIN.sh
blob5a83b5847a18fe7a3b2cb8b36f1f28446737892f
1 #!/usr/bin/env bash
2 # SPDX-License-Identifier: LGPL-2.1-or-later
3 set -eux
4 set -o pipefail
6 # shellcheck source=test/units/test-control.sh
7 . "$(dirname "$0")"/test-control.sh
8 # shellcheck source=test/units/util.sh
9 . "$(dirname "$0")"/util.sh
11 cleanup_test_user() (
12 set +ex
14 pkill -u "$(id -u logind-test-user)"
15 sleep 1
16 pkill -KILL -u "$(id -u logind-test-user)"
17 userdel -r logind-test-user
19 return 0
22 setup_test_user() {
23 mkdir -p /var/spool/cron /var/spool/mail
24 useradd -m -s /bin/bash logind-test-user
25 trap cleanup_test_user EXIT
28 test_write_dropin() {
29 systemctl edit --runtime --stdin systemd-logind.service --drop-in=debug.conf <<EOF
30 [Service]
31 Environment=SYSTEMD_LOG_LEVEL=debug
32 EOF
34 # We test "coldplug" (completely stop and start logind) here. So we need to preserve
35 # the fdstore, which might contain session leader pidfds. This is extremely rare use case
36 # and shall not be considered fully supported.
37 # See also: https://github.com/systemd/systemd/pull/30610#discussion_r1440507850
38 systemctl edit --runtime --stdin systemd-logind.service --drop-in=fdstore-preserve.conf <<EOF
39 [Service]
40 FileDescriptorStorePreserve=yes
41 EOF
43 systemctl restart systemd-logind.service
46 testcase_properties() {
47 mkdir -p /run/systemd/logind.conf.d
49 cat >/run/systemd/logind.conf.d/kill-user-processes.conf <<EOF
50 [Login]
51 KillUserProcesses=no
52 EOF
54 systemctl restart systemd-logind.service
55 assert_eq "$(busctl get-property org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager KillUserProcesses)" "b false"
57 cat >/run/systemd/logind.conf.d/kill-user-processes.conf <<EOF
58 [Login]
59 KillUserProcesses=yes
60 EOF
62 systemctl restart systemd-logind.service
63 assert_eq "$(busctl get-property org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager KillUserProcesses)" "b true"
65 rm -rf /run/systemd/logind.conf.d
68 testcase_sleep_automated() {
69 assert_eq "$(busctl get-property org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager SleepOperation)" 'as 3 "suspend-then-hibernate" "suspend" "hibernate"'
71 mkdir -p /run/systemd/logind.conf.d
73 cat >/run/systemd/logind.conf.d/sleep-operations.conf <<EOF
74 [Login]
75 SleepOperation=suspend hybrid-sleep
76 EOF
78 systemctl restart systemd-logind.service
80 assert_eq "$(busctl get-property org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager SleepOperation)" 'as 2 "hybrid-sleep" "suspend"'
82 busctl call org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager CanSleep
84 rm -rf /run/systemd/logind.conf.d
87 testcase_started() {
88 local pid
90 systemctl restart systemd-logind.service
92 # should start at boot, not with D-BUS activation
93 pid=$(systemctl show systemd-logind.service -p ExecMainPID --value)
95 # loginctl should succeed
96 loginctl
98 # logind should still be running
99 assert_eq "$(systemctl show systemd-logind.service -p ExecMainPID --value)" "$pid"
102 wait_suspend() {
103 timeout "${1?}" bash -c "while [[ ! -e /run/suspend.flag ]]; do sleep 1; done"
104 rm /run/suspend.flag
107 teardown_suspend() (
108 set +eux
110 pkill evemu-device
112 rm -rf /run/systemd/system/systemd-suspend.service.d
113 systemctl daemon-reload
115 rm -f /run/udev/rules.d/70-logindtest-lid.rules
116 udevadm control --reload
118 return 0
121 testcase_suspend_on_lid() {
122 local pid input_name lid_dev
124 if systemd-detect-virt --quiet --container; then
125 echo "Skipping suspend test in container"
126 return
128 if ! grep -s -q mem /sys/power/state; then
129 echo "suspend not supported on this testbed, skipping"
130 return
132 if ! command -v evemu-device >/dev/null; then
133 echo "command evemu-device not found, skipping"
134 return
136 if ! command -v evemu-event >/dev/null; then
137 echo "command evemu-event not found, skipping"
138 return
141 trap teardown_suspend RETURN
143 # save pid
144 pid=$(systemctl show systemd-logind.service -p ExecMainPID --value)
146 # create fake suspend
147 mkdir -p /run/systemd/system/systemd-suspend.service.d
148 cat >/run/systemd/system/systemd-suspend.service.d/override.conf <<EOF
149 [Service]
150 ExecStart=
151 ExecStart=touch /run/suspend.flag
153 systemctl daemon-reload
155 # create fake lid switch
156 mkdir -p /run/udev/rules.d
157 cat >/run/udev/rules.d/70-logindtest-lid.rules <<EOF
158 SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="Fake Lid Switch", TAG+="power-switch"
160 udevadm control --reload
162 cat >/run/lidswitch.evemu <<EOF
163 # EVEMU 1.2
164 # Input device name: "Lid Switch"
165 # Input device ID: bus 0x19 vendor 0000 product 0x05 version 0000
166 # Supported events:
167 # Event type 0 (EV_SYN)
168 # Event code 0 (SYN_REPORT)
169 # Event code 5 (FF_STATUS_MAX)
170 # Event type 5 (EV_SW)
171 # Event code 0 (SW_LID)
172 # Properties:
173 N: Fake Lid Switch
174 I: 0019 0000 0005 0000
175 P: 00 00 00 00 00 00 00 00
176 B: 00 21 00 00 00 00 00 00 00
177 B: 01 00 00 00 00 00 00 00 00
178 B: 01 00 00 00 00 00 00 00 00
179 B: 01 00 00 00 00 00 00 00 00
180 B: 01 00 00 00 00 00 00 00 00
181 B: 01 00 00 00 00 00 00 00 00
182 B: 01 00 00 00 00 00 00 00 00
183 B: 01 00 00 00 00 00 00 00 00
184 B: 01 00 00 00 00 00 00 00 00
185 B: 01 00 00 00 00 00 00 00 00
186 B: 01 00 00 00 00 00 00 00 00
187 B: 01 00 00 00 00 00 00 00 00
188 B: 01 00 00 00 00 00 00 00 00
189 B: 02 00 00 00 00 00 00 00 00
190 B: 03 00 00 00 00 00 00 00 00
191 B: 04 00 00 00 00 00 00 00 00
192 B: 05 01 00 00 00 00 00 00 00
193 B: 11 00 00 00 00 00 00 00 00
194 B: 12 00 00 00 00 00 00 00 00
195 B: 15 00 00 00 00 00 00 00 00
196 B: 15 00 00 00 00 00 00 00 00
199 evemu-device /run/lidswitch.evemu &
201 timeout 20 bash -c 'until grep "^Fake Lid Switch" /sys/class/input/*/device/name; do sleep .5; done'
202 input_name=$(grep -l '^Fake Lid Switch' /sys/class/input/*/device/name || :)
203 if [[ -z "$input_name" ]]; then
204 echo "cannot find fake lid switch." >&2
205 exit 1
207 input_name=${input_name%/device/name}
208 lid_dev=/dev/${input_name#/sys/class/}
209 udevadm info --wait-for-initialization=10s "$lid_dev"
210 udevadm settle
212 # close lid
213 evemu-event "$lid_dev" --sync --type 5 --code 0 --value 1
214 # need to wait for 30s suspend inhibition after boot
215 wait_suspend 31
216 # open lid again
217 evemu-event "$lid_dev" --sync --type 5 --code 0 --value 0
219 # waiting for 30s inhibition time between suspends
220 sleep 30
222 # now closing lid should cause instant suspend
223 evemu-event "$lid_dev" --sync --type 5 --code 0 --value 1
224 wait_suspend 2
225 evemu-event "$lid_dev" --sync --type 5 --code 0 --value 0
227 assert_eq "$(systemctl show systemd-logind.service -p ExecMainPID --value)" "$pid"
230 testcase_shutdown() {
231 local pid
233 # save pid
234 pid=$(systemctl show systemd-logind.service -p ExecMainPID --value)
236 # scheduled shutdown with wall message
237 shutdown 2>&1
238 sleep 5
239 shutdown -c || :
240 # logind should still be running
241 assert_eq "$(systemctl show systemd-logind.service -p ExecMainPID --value)" "$pid"
243 # scheduled shutdown without wall message
244 shutdown --no-wall 2>&1
245 sleep 5
246 shutdown -c --no-wall || true
247 assert_eq "$(systemctl show systemd-logind.service -p ExecMainPID --value)" "$pid"
250 cleanup_session() (
251 set +ex
253 local uid s
255 uid=$(id -u logind-test-user)
257 loginctl disable-linger logind-test-user
259 systemctl stop getty@tty2.service
261 for s in $(loginctl --no-legend list-sessions | grep -v manager | awk '$3 == "logind-test-user" { print $1 }'); do
262 echo "INFO: stopping session $s"
263 loginctl terminate-session "$s"
264 done
266 loginctl terminate-user logind-test-user
268 if ! timeout 30 bash -c "while loginctl --no-legend | grep -q logind-test-user; do sleep 1; done"; then
269 echo "WARNING: session for logind-test-user still active, ignoring."
272 pkill -u "$uid"
273 sleep 1
274 pkill -KILL -u "$uid"
276 if ! timeout 30 bash -c "while systemctl is-active --quiet user@${uid}.service; do sleep 1; done"; then
277 echo "WARNING: user@${uid}.service is still active, ignoring."
280 if ! timeout 30 bash -c "while systemctl is-active --quiet user-runtime-dir@${uid}.service; do sleep 1; done"; then
281 echo "WARNING: user-runtime-dir@${uid}.service is still active, ignoring."
284 if ! timeout 30 bash -c "while systemctl is-active --quiet user-${uid}.slice; do sleep 1; done"; then
285 echo "WARNING: user-${uid}.slice is still active, ignoring."
288 rm -rf /run/systemd/system/getty@tty2.service.d
289 systemctl daemon-reload
291 return 0
294 teardown_session() (
295 set +ex
297 cleanup_session
299 rm -f /run/udev/rules.d/70-logindtest-scsi_debug-user.rules
300 udevadm control --reload
301 rmmod scsi_debug
303 return 0
306 check_session() (
307 set +ex
309 local seat session leader_pid
311 if [[ $(loginctl --no-legend | grep -v manager | grep -c "logind-test-user") != 1 ]]; then
312 echo "no session or multiple sessions for logind-test-user." >&2
313 return 1
316 seat=$(loginctl --no-legend | grep -v manager | grep 'logind-test-user *seat' | awk '{ print $4 }')
317 if [[ -z "$seat" ]]; then
318 echo "no seat found for user logind-test-user" >&2
319 return 1
322 session=$(loginctl --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $1 }')
323 if [[ -z "$session" ]]; then
324 echo "no session found for user logind-test-user" >&2
325 return 1
328 if ! loginctl session-status "$session" | grep -q "Unit: session-${session}\.scope"; then
329 echo "cannot find scope unit for session $session" >&2
330 return 1
333 leader_pid=$(loginctl session-status "$session" | awk '$1 == "Leader:" { print $2 }')
334 if [[ -z "$leader_pid" ]]; then
335 echo "cannot found leader process for session $session" >&2
336 return 1
339 # cgroup v1: "1:name=systemd:/user.slice/..."; unified hierarchy: "0::/user.slice"
340 if ! grep -q -E '(name=systemd|^0:):.*session.*scope' /proc/"$leader_pid"/cgroup; then
341 echo "FAIL: process $leader_pid is not in the session cgroup" >&2
342 cat /proc/self/cgroup
343 return 1
347 create_session() {
348 # login with the test user to start a session
349 mkdir -p /run/systemd/system/getty@tty2.service.d
350 cat >/run/systemd/system/getty@tty2.service.d/override.conf <<EOF
351 [Service]
352 Type=simple
353 ExecStart=
354 ExecStart=-/sbin/agetty --autologin logind-test-user --noclear %I $TERM
355 Restart=no
357 systemctl daemon-reload
359 systemctl restart getty@tty2.service
361 # check session
362 for i in {1..30}; do
363 (( i > 1 )) && sleep 1
364 check_session && break
365 done
366 check_session
367 assert_eq "$(loginctl --no-legend | grep -v manager | awk '$3=="logind-test-user" { print $7 }')" "tty2"
370 testcase_sanity_check() {
371 # Exercise basic loginctl options
373 if [[ ! -c /dev/tty2 ]]; then
374 echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}."
375 return
378 trap cleanup_session RETURN
379 create_session
381 # Run most of the loginctl commands from a user session to make
382 # the seat/session autodetection work-ish
383 systemd-run --user --pipe --wait -M "logind-test-user@.host" bash -eux <<\EOF
384 loginctl list-sessions
385 loginctl list-sessions -j
386 loginctl list-sessions --json=short
387 loginctl session-status
388 loginctl show-session
389 loginctl show-session -P DelayInhibited
391 # We're not in the same session scope, so in this case we need to specify
392 # the session ID explicitly
393 session=$(loginctl --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $1; exit; }')
394 loginctl kill-session --signal=SIGCONT "$session"
395 # FIXME(?)
396 #loginctl kill-session --signal=SIGCONT --kill-whom=leader "$session"
398 loginctl list-users
399 loginctl user-status
400 loginctl show-user -a
401 loginctl show-user -P IdleAction
402 loginctl kill-user --signal=SIGCONT ""
404 loginctl list-seats
405 loginctl seat-status
406 loginctl show-seat
407 loginctl show-seat -P IdleActionUSec
410 # Requires root privileges
411 loginctl lock-sessions
412 loginctl unlock-sessions
413 loginctl flush-devices
416 testcase_session() {
417 local dev
419 if systemd-detect-virt --quiet --container; then
420 echo "Skipping ACL tests in container"
421 return
424 if [[ ! -c /dev/tty2 ]]; then
425 echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}."
426 return
429 trap teardown_session RETURN
431 create_session
433 # scsi_debug should not be loaded yet
434 if [[ -d /sys/bus/pseudo/drivers/scsi_debug ]]; then
435 echo "scsi_debug module is already loaded." >&2
436 exit 1
439 # we use scsi_debug to create new devices which we can put ACLs on
440 # tell udev about the tagging, so that logind can pick it up
441 mkdir -p /run/udev/rules.d
442 cat >/run/udev/rules.d/70-logindtest-scsi_debug-user.rules <<EOF
443 SUBSYSTEM=="block", ATTRS{model}=="scsi_debug*", TAG+="uaccess"
445 udevadm control --reload
447 # coldplug: logind started with existing device
448 systemctl stop systemd-logind.service
449 modprobe scsi_debug
450 timeout 30 bash -c 'until ls /sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block 2>/dev/null; do sleep 1; done'
451 dev=/dev/$(ls /sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block 2>/dev/null)
452 if [[ ! -b "$dev" ]]; then
453 echo "cannot find suitable scsi block device" >&2
454 exit 1
456 udevadm settle
457 udevadm info "$dev"
459 # trigger logind and activate session
460 loginctl activate "$(loginctl --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $1 }')"
462 # check ACL
463 sleep 1
464 assert_in "user:logind-test-user:rw-" "$(getfacl -p "$dev")"
466 # hotplug: new device appears while logind is running
467 rmmod scsi_debug
468 modprobe scsi_debug
469 timeout 30 bash -c 'until ls /sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block 2>/dev/null; do sleep 1; done'
470 dev=/dev/$(ls /sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block 2>/dev/null)
471 if [[ ! -b "$dev" ]]; then
472 echo "cannot find suitable scsi block device" >&2
473 exit 1
475 udevadm settle
477 # check ACL
478 sleep 1
479 assert_in "user:logind-test-user:rw-" "$(getfacl -p "$dev")"
482 teardown_lock_idle_action() (
483 set +eux
485 rm -f /run/systemd/logind.conf.d/idle-action-lock.conf
486 systemctl restart systemd-logind.service
488 cleanup_session
490 return 0
493 testcase_lock_idle_action() {
494 local ts
496 if [[ ! -c /dev/tty2 ]]; then
497 echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}."
498 return
501 if loginctl --no-legend | grep -v manager | grep -q logind-test-user; then
502 echo >&2 "Session of the 'logind-test-user' is already present."
503 exit 1
506 trap teardown_lock_idle_action RETURN
508 create_session
510 journalctl --sync
511 ts="$(date '+%H:%M:%S')"
513 mkdir -p /run/systemd/logind.conf.d
514 cat >/run/systemd/logind.conf.d/idle-action-lock.conf <<EOF
515 [Login]
516 IdleAction=lock
517 IdleActionSec=1s
519 systemctl restart systemd-logind.service
521 # Wait for 35s, in that interval all sessions should have become idle
522 # and "Lock" signal should have been sent out. Then we wrote to tty to make
523 # session active again and next we slept for another 35s so sessions have
524 # become idle again. 'Lock' signal is sent out for each session, we have at
525 # least one session, so minimum of 2 "Lock" signals must have been sent.
526 journalctl --sync
527 set +o pipefail
528 timeout -v 35 journalctl -b -u systemd-logind.service --since="$ts" -n all --follow | grep -m 1 -q 'Sent message type=signal .* member=Lock'
529 set -o pipefail
531 # We need to know that a new message was sent after waking up,
532 # so we must track how many happened before sleeping to check we have extra.
533 locks="$(journalctl -b -u systemd-logind.service --since="$ts" | grep -c 'Sent message type=signal .* member=Lock')"
535 # Wakeup
536 touch /dev/tty2
538 # Wait again
539 journalctl --sync
540 set +o pipefail
541 timeout -v 35 journalctl -b -u systemd-logind.service --since="$ts" -n all --follow | grep -m "$((locks + 1))" -q 'Sent message type=signal .* member=Lock'
542 timeout -v 35 journalctl -b -u systemd-logind.service --since="$ts" -n all --follow | grep -m 2 -q -F 'System idle. Will be locked now.'
543 set -o pipefail
546 testcase_session_properties() {
547 local s
549 if [[ ! -c /dev/tty2 ]]; then
550 echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}."
551 return
554 trap cleanup_session RETURN
555 create_session
557 s=$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $1 }')
558 /usr/lib/systemd/tests/unit-tests/manual/test-session-properties "/org/freedesktop/login1/session/_3${s?}" /dev/tty2
561 testcase_list_users_sessions_seats() {
562 local session seat
564 if [[ ! -c /dev/tty2 ]]; then
565 echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}."
566 return
569 trap cleanup_session RETURN
570 create_session
572 # Activate the session
573 loginctl activate "$(loginctl --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $1 }')"
575 session=$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $1 }')
576 : check that we got a valid session id
577 busctl get-property org.freedesktop.login1 "/org/freedesktop/login1/session/_3${session?}" org.freedesktop.login1.Session Id
578 busctl get-property org.freedesktop.login1 "/org/freedesktop/login1/session/_3${session?}" org.freedesktop.login1.Session CanIdle
579 busctl get-property org.freedesktop.login1 "/org/freedesktop/login1/session/_3${session?}" org.freedesktop.login1.Session CanLock
580 assert_eq "$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $2 }')" "$(id -ru logind-test-user)"
581 seat=$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $4 }')
582 assert_eq "$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $6 }')" user
583 assert_eq "$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $7 }')" tty2
584 assert_eq "$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $8 }')" no
585 assert_eq "$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $9 }')" '-'
587 loginctl list-seats --no-legend | grep -Fwq "${seat?}"
589 assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $1 }')" "$(id -ru logind-test-user)"
590 assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $3 }')" no
591 assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $4 }')" active
593 loginctl enable-linger logind-test-user
594 assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $3 }')" yes
596 for s in $(loginctl list-sessions --no-legend | grep tty | awk '$3 == "logind-test-user" { print $1 }'); do
597 loginctl terminate-session "$s"
598 done
599 if ! timeout 30 bash -c "while loginctl --no-legend | grep tty | grep -q logind-test-user; do sleep 1; done"; then
600 echo "WARNING: session for logind-test-user still active, ignoring."
601 return
604 timeout 30 bash -c "until [[ \"\$(loginctl list-users --no-legend | awk '\$2 == \"logind-test-user\" { print \$4 }')\" == lingering ]]; do sleep 1; done"
607 teardown_stop_idle_session() (
608 set +eux
610 rm -f /run/systemd/logind.conf.d/stop-idle-session.conf
611 systemctl restart systemd-logind.service
613 cleanup_session
616 testcase_stop_idle_session() {
617 local id ts
619 if [[ ! -c /dev/tty2 ]]; then
620 echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}."
621 return
624 create_session
625 trap teardown_stop_idle_session RETURN
627 id="$(loginctl --no-legend | grep tty | awk '$3 == "logind-test-user" { print $1; }')"
629 journalctl --sync
630 ts="$(date '+%H:%M:%S')"
632 mkdir -p /run/systemd/logind.conf.d
633 cat >/run/systemd/logind.conf.d/stop-idle-session.conf <<EOF
634 [Login]
635 StopIdleSessionSec=2s
637 systemctl restart systemd-logind.service
638 sleep 5
640 journalctl --sync
641 assert_eq "$(journalctl -b -u systemd-logind.service --since="$ts" --grep "Session \"$id\" of user \"logind-test-user\" is idle, stopping." | wc -l)" 1
642 assert_eq "$(loginctl --no-legend | grep -v manager | grep tty | grep -c "logind-test-user")" 0
645 testcase_ambient_caps() {
646 local PAMSERVICE TRANSIENTUNIT SCRIPT
648 # Verify that pam_systemd works and assigns ambient caps as it should
650 if ! grep -q 'CapAmb:' /proc/self/status ; then
651 echo "ambient caps not available, skipping test." >&2
652 return
655 typeset -i BND MASK
657 # Get PID 1's bounding set
658 BND="0x$(grep 'CapBnd:' /proc/1/status | cut -d: -f2 | tr -d '[:space:]')"
660 # CAP_CHOWN | CAP_KILL
661 MASK=$(((1 << 0) | (1 << 5)))
663 if [ $((BND & MASK)) -ne "$MASK" ] ; then
664 echo "CAP_CHOWN or CAP_KILL not available in bounding set, skipping test." >&2
665 return
668 PAMSERVICE="pamserv$RANDOM"
669 TRANSIENTUNIT="capwakealarm$RANDOM.service"
670 SCRIPT="/tmp/capwakealarm$RANDOM.sh"
672 cat > /etc/pam.d/"$PAMSERVICE" <<EOF
673 auth sufficient pam_unix.so
674 auth required pam_deny.so
675 account sufficient pam_unix.so
676 account required pam_permit.so
677 session optional pam_systemd.so default-capability-ambient-set=CAP_CHOWN,CAP_KILL debug
678 session required pam_unix.so
681 cat > "$SCRIPT" <<'EOF'
682 #!/bin/bash
683 set -ex
684 typeset -i AMB MASK
685 AMB="0x$(grep 'CapAmb:' /proc/self/status | cut -d: -f2 | tr -d '[:space:]')"
686 MASK=$(((1 << 0) | (1 << 5)))
687 test "$AMB" -eq "$MASK"
690 chmod +x "$SCRIPT"
692 systemd-run -u "$TRANSIENTUNIT" -p PAMName="$PAMSERVICE" -p Type=oneshot -p User=logind-test-user -p StandardError=tty "$SCRIPT"
694 rm -f "$SCRIPT" "$PAMSERVICE"
697 background_at_return() {
698 rm -f /etc/pam.d/"$PAMSERVICE"
699 unset PAMSERVICE
702 testcase_background() {
704 local uid TRANSIENTUNIT0 TRANSIENTUNIT1 TRANSIENTUNIT2
706 uid=$(id -u logind-test-user)
708 systemctl stop user@"$uid".service
710 PAMSERVICE="pamserv$RANDOM"
711 TRANSIENTUNIT0="none$RANDOM.service"
712 TRANSIENTUNIT1="bg$RANDOM.service"
713 TRANSIENTUNIT2="bgg$RANDOM.service"
714 TRANSIENTUNIT3="bggg$RANDOM.service"
715 TRANSIENTUNIT4="bgggg$RANDOM.service"
716 RUN0UNIT0="run0$RANDOM.service"
717 RUN0UNIT1="runn0$RANDOM.service"
718 RUN0UNIT2="runnn0$RANDOM.service"
719 RUN0UNIT3="runnnn0$RANDOM.service"
721 trap background_at_return RETURN
723 cat > /etc/pam.d/"$PAMSERVICE" <<EOF
724 auth sufficient pam_unix.so
725 auth required pam_deny.so
726 account sufficient pam_unix.so
727 account required pam_permit.so
728 session optional pam_systemd.so debug
729 session required pam_unix.so
732 systemd-run -u "$TRANSIENTUNIT0" -p PAMName="$PAMSERVICE" -p "Environment=XDG_SESSION_CLASS=none" -p Type=exec -p User=logind-test-user sleep infinity
734 # This was a 'none' service, so logind should take no action
735 (! systemctl is-active user@"$uid".service )
737 systemctl stop "$TRANSIENTUNIT0"
739 systemd-run -u "$TRANSIENTUNIT1" -p PAMName="$PAMSERVICE" -p "Environment=XDG_SESSION_CLASS=background-light" -p Type=exec -p User=logind-test-user sleep infinity
741 # This was a 'light' background service, hence the service manager should not be running
742 (! systemctl is-active user@"$uid".service )
744 systemctl stop "$TRANSIENTUNIT1"
746 systemd-run -u "$TRANSIENTUNIT2" -p PAMName="$PAMSERVICE" -p "Environment=XDG_SESSION_CLASS=background" -p Type=exec -p User=logind-test-user sleep infinity
748 # This was a regular background service, hence the service manager should be running
749 systemctl is-active user@"$uid".service
751 systemctl stop "$TRANSIENTUNIT2"
753 systemctl stop user@"$uid".service
755 # Now check that system users automatically get the light session class assigned
756 systemd-sysusers --inline "u lightuser"
758 systemd-run -u "$TRANSIENTUNIT3" -p PAMName="$PAMSERVICE" -p "Environment=XDG_SESSION_TYPE=unspecified" -p Type=exec -p User=lightuser sleep infinity
759 loginctl | grep lightuser | grep -q background-light
760 systemctl stop "$TRANSIENTUNIT3"
762 systemd-run -u "$TRANSIENTUNIT4" -p PAMName="$PAMSERVICE" -p "Environment=XDG_SESSION_TYPE=tty" -p Type=exec -p User=lightuser sleep infinity
763 loginctl | grep lightuser | grep -q user-light
764 systemctl stop "$TRANSIENTUNIT4"
766 # Now check that run0's session class control works
767 systemd-run --service-type=notify run0 -u lightuser --unit="$RUN0UNIT0" sleep infinity
768 loginctl | grep lightuser | grep -q "background-light "
769 systemctl stop "$RUN0UNIT0"
771 systemd-run --service-type=notify run0 -u lightuser --unit="$RUN0UNIT1" --lightweight=yes sleep infinity
772 loginctl | grep lightuser | grep -q "background-light "
773 systemctl stop "$RUN0UNIT1"
775 systemd-run --service-type=notify run0 -u lightuser --unit="$RUN0UNIT2" --lightweight=no sleep infinity
776 loginctl | grep lightuser | grep -q "background "
777 systemctl stop "$RUN0UNIT2"
779 systemd-run --service-type=notify run0 -u root --unit="$RUN0UNIT3" sleep infinity
780 loginctl | grep root | grep -q "background-light "
781 systemctl stop "$RUN0UNIT3"
784 testcase_varlink() {
785 varlinkctl introspect /run/systemd/io.systemd.Login
788 setup_test_user
789 test_write_dropin
790 run_testcases
792 touch /testok