mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
20e94309a7
Let's remove the unneeded NotifyAccess=all and start the socket and service in the test itself instead of via the service unit. This makes the test unit identical to the other test units which will allow us to autogenerate it in a later commit.
615 lines
22 KiB
Bash
Executable File
615 lines
22 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
set -eux
|
|
set -o pipefail
|
|
|
|
# Check if homectl is installed, and if it isn't bail out early instead of failing
|
|
if ! test -x /usr/bin/homectl ; then
|
|
echo "no homed" >/skipped
|
|
exit 77
|
|
fi
|
|
|
|
inspect() {
|
|
# As updating disk-size-related attributes can take some time on some
|
|
# filesystems, let's drop these fields before comparing the outputs to
|
|
# avoid unexpected fails. To see the full outputs of both homectl &
|
|
# userdbctl (for debugging purposes) drop the fields just before the
|
|
# comparison.
|
|
local USERNAME="${1:?}"
|
|
homectl inspect "$USERNAME" | tee /tmp/a
|
|
userdbctl user "$USERNAME" | tee /tmp/b
|
|
|
|
# diff uses the grep BREs for pattern matching
|
|
diff -I '^\s*Disk \(Size\|Free\|Floor\|Ceiling\|Usage\):' /tmp/{a,b}
|
|
rm /tmp/{a,b}
|
|
|
|
homectl inspect --json=pretty "$USERNAME"
|
|
}
|
|
|
|
wait_for_state() {
|
|
for i in {1..10}; do
|
|
(( i > 1 )) && sleep 0.5
|
|
homectl inspect "$1" | grep -qF "State: $2" && break
|
|
done
|
|
}
|
|
|
|
FSTYPE="$(stat --file-system --format "%T" /)"
|
|
|
|
systemctl start systemd-homed.service systemd-userdbd.socket
|
|
|
|
systemd-analyze log-level debug
|
|
systemctl service-log-level systemd-homed debug
|
|
|
|
# Create a tmpfs to use as backing store for the home dir. That way we can enforce a size limit nicely.
|
|
mkdir -p /home
|
|
mount -t tmpfs tmpfs /home -o size=290M
|
|
|
|
# we enable --luks-discard= since we run our tests in a tight VM, hence don't
|
|
# needlessly pressure for storage. We also set the cheapest KDF, since we don't
|
|
# want to waste CI CPU cycles on it. We also effectively disable rate-limiting on
|
|
# the user by allowing 1000 logins per second
|
|
NEWPASSWORD=xEhErW0ndafV4s homectl create test-user \
|
|
--disk-size=min \
|
|
--luks-discard=yes \
|
|
--image-path=/home/test-user.home \
|
|
--luks-pbkdf-type=pbkdf2 \
|
|
--luks-pbkdf-time-cost=1ms \
|
|
--rate-limit-interval=1s \
|
|
--rate-limit-burst=1000
|
|
inspect test-user
|
|
|
|
PASSWORD=xEhErW0ndafV4s homectl authenticate test-user
|
|
|
|
PASSWORD=xEhErW0ndafV4s homectl activate test-user
|
|
inspect test-user
|
|
|
|
PASSWORD=xEhErW0ndafV4s homectl update test-user --real-name="Inline test"
|
|
inspect test-user
|
|
|
|
homectl deactivate test-user
|
|
inspect test-user
|
|
|
|
PASSWORD=xEhErW0ndafV4s NEWPASSWORD=yPN4N0fYNKUkOq homectl passwd test-user
|
|
inspect test-user
|
|
|
|
PASSWORD=yPN4N0fYNKUkOq homectl activate test-user
|
|
inspect test-user
|
|
|
|
SYSTEMD_LOG_LEVEL=debug PASSWORD=yPN4N0fYNKUkOq NEWPASSWORD=xEhErW0ndafV4s homectl passwd test-user
|
|
inspect test-user
|
|
|
|
homectl deactivate test-user
|
|
inspect test-user
|
|
|
|
homectl update test-user --real-name "Offline test" --offline
|
|
inspect test-user
|
|
|
|
PASSWORD=xEhErW0ndafV4s homectl activate test-user
|
|
inspect test-user
|
|
|
|
# Ensure that the offline changes were propagated in
|
|
grep "Offline test" /home/test-user/.identity
|
|
|
|
homectl deactivate test-user
|
|
inspect test-user
|
|
|
|
PASSWORD=xEhErW0ndafV4s homectl update test-user --real-name="Inactive test"
|
|
inspect test-user
|
|
|
|
PASSWORD=xEhErW0ndafV4s homectl activate test-user
|
|
inspect test-user
|
|
|
|
homectl deactivate test-user
|
|
inspect test-user
|
|
|
|
# Do some keyring tests, but only on real kernels, since keyring access inside of containers will fail
|
|
# (See: https://github.com/systemd/systemd/issues/17606)
|
|
if ! systemd-detect-virt -cq ; then
|
|
PASSWORD=xEhErW0ndafV4s homectl activate test-user
|
|
inspect test-user
|
|
|
|
# Key should now be in the keyring
|
|
homectl update test-user --real-name "Keyring Test"
|
|
inspect test-user
|
|
|
|
# These commands shouldn't use the keyring
|
|
(! timeout 5s homectl authenticate test-user )
|
|
(! NEWPASSWORD="foobar" timeout 5s homectl passwd test-user )
|
|
|
|
homectl lock test-user
|
|
inspect test-user
|
|
|
|
# Key should be gone from keyring
|
|
(! timeout 5s homectl update test-user --real-name "Keyring Test 2" )
|
|
|
|
PASSWORD=xEhErW0ndafV4s homectl unlock test-user
|
|
inspect test-user
|
|
|
|
# Key should have been re-instantiated into the keyring
|
|
homectl update test-user --real-name "Keyring Test 3"
|
|
inspect test-user
|
|
|
|
homectl deactivate test-user
|
|
inspect test-user
|
|
fi
|
|
|
|
# Do some resize tests, but only if we run on real kernels and are on btrfs, as quota inside of containers
|
|
# will fail and minimizing while active only works on btrfs.
|
|
if ! systemd-detect-virt -cq && [[ "$FSTYPE" == "btrfs" ]]; then
|
|
# grow while inactive
|
|
PASSWORD=xEhErW0ndafV4s homectl resize test-user 300M
|
|
inspect test-user
|
|
|
|
# minimize while inactive
|
|
PASSWORD=xEhErW0ndafV4s homectl resize test-user min
|
|
inspect test-user
|
|
|
|
PASSWORD=xEhErW0ndafV4s homectl activate test-user
|
|
inspect test-user
|
|
|
|
# grow while active
|
|
PASSWORD=xEhErW0ndafV4s homectl resize test-user max
|
|
inspect test-user
|
|
|
|
# minimize while active
|
|
PASSWORD=xEhErW0ndafV4s homectl resize test-user 0
|
|
inspect test-user
|
|
|
|
# grow while active
|
|
PASSWORD=xEhErW0ndafV4s homectl resize test-user 300M
|
|
inspect test-user
|
|
|
|
# shrink to original size while active
|
|
PASSWORD=xEhErW0ndafV4s homectl resize test-user 256M
|
|
inspect test-user
|
|
|
|
# minimize again
|
|
PASSWORD=xEhErW0ndafV4s homectl resize test-user min
|
|
inspect test-user
|
|
|
|
# Increase space, so that we can reasonably rebalance free space between to home dirs
|
|
mount /home -o remount,size=800M
|
|
|
|
# create second user
|
|
NEWPASSWORD=uuXoo8ei homectl create test-user2 \
|
|
--disk-size=min \
|
|
--luks-discard=yes \
|
|
--image-path=/home/test-user2.home \
|
|
--luks-pbkdf-type=pbkdf2 \
|
|
--luks-pbkdf-time-cost=1ms \
|
|
--rate-limit-interval=1s \
|
|
--rate-limit-burst=1000
|
|
inspect test-user2
|
|
|
|
# activate second user
|
|
PASSWORD=uuXoo8ei homectl activate test-user2
|
|
inspect test-user2
|
|
|
|
# set second user's rebalance weight to 100
|
|
PASSWORD=uuXoo8ei homectl update test-user2 --rebalance-weight=100
|
|
inspect test-user2
|
|
|
|
# set first user's rebalance weight to quarter of that of the second
|
|
PASSWORD=xEhErW0ndafV4s homectl update test-user --rebalance-weight=25
|
|
inspect test-user
|
|
|
|
# synchronously rebalance
|
|
homectl rebalance
|
|
inspect test-user
|
|
inspect test-user2
|
|
|
|
wait_for_state test-user2 active
|
|
homectl deactivate test-user2
|
|
wait_for_state test-user2 inactive
|
|
homectl remove test-user2
|
|
fi
|
|
|
|
PASSWORD=xEhErW0ndafV4s homectl with test-user -- test ! -f /home/test-user/xyz
|
|
(! PASSWORD=xEhErW0ndafV4s homectl with test-user -- test -f /home/test-user/xyz)
|
|
PASSWORD=xEhErW0ndafV4s homectl with test-user -- touch /home/test-user/xyz
|
|
PASSWORD=xEhErW0ndafV4s homectl with test-user -- test -f /home/test-user/xyz
|
|
PASSWORD=xEhErW0ndafV4s homectl with test-user -- rm /home/test-user/xyz
|
|
PASSWORD=xEhErW0ndafV4s homectl with test-user -- test ! -f /home/test-user/xyz
|
|
(! PASSWORD=xEhErW0ndafV4s homectl with test-user -- test -f /home/test-user/xyz)
|
|
|
|
# Regression tests
|
|
wait_for_state test-user inactive
|
|
/usr/lib/systemd/tests/unit-tests/manual/test-homed-regression-31896 test-user
|
|
|
|
wait_for_state test-user inactive
|
|
homectl remove test-user
|
|
|
|
# blob directory tests
|
|
# See docs/USER_RECORD_BLOB_DIRS.md
|
|
checkblob() {
|
|
test -f "/var/cache/systemd/home/blob-user/$1"
|
|
stat -c "%u %#a" "/var/cache/systemd/home/blob-user/$1" | grep "^0 0644"
|
|
test -f "/home/blob-user/.identity-blob/$1"
|
|
stat -c "%u %#a" "/home/blob-user/.identity-blob/$1" | grep "^12345 0644"
|
|
|
|
diff "/var/cache/systemd/home/blob-user/$1" "$2"
|
|
diff "/var/cache/systemd/home/blob-user/$1" "/home/blob-user/.identity-blob/$1"
|
|
}
|
|
|
|
mkdir /tmp/blob1 /tmp/blob2
|
|
echo data1 blob1 >/tmp/blob1/test1
|
|
echo data1 blob2 >/tmp/blob2/test1
|
|
echo data2 blob1 >/tmp/blob1/test2
|
|
echo data2 blob2 >/tmp/blob2/test2
|
|
echo invalid filename >/tmp/blob1/файл
|
|
echo data3 >/tmp/external-test3
|
|
echo avatardata >/tmp/external-avatar
|
|
ln -s /tmp/external-avatar /tmp/external-avatar-lnk
|
|
dd if=/dev/urandom of=/tmp/external-barely-fits bs=1M count=64
|
|
dd if=/dev/urandom of=/tmp/external-toobig bs=1M count=65
|
|
|
|
# create w/ prepopulated blob dir
|
|
NEWPASSWORD=EMJuc3zQaMibJo homectl create blob-user \
|
|
--disk-size=min --luks-discard=yes \
|
|
--luks-pbkdf-type=pbkdf2 --luks-pbkdf-time-cost=1ms \
|
|
--rate-limit-interval=1s --rate-limit-burst=1000 \
|
|
--uid=12345 \
|
|
--blob=/tmp/blob1
|
|
inspect blob-user
|
|
PASSWORD=EMJuc3zQaMibJo homectl activate blob-user
|
|
inspect blob-user
|
|
|
|
test -d /var/cache/systemd/home/blob-user
|
|
stat -c "%u %#a" /var/cache/systemd/home/blob-user | grep "^0 0755"
|
|
test -d /home/blob-user/.identity-blob
|
|
stat -c "%u %#a" /home/blob-user/.identity-blob | grep "^12345 0700"
|
|
|
|
checkblob test1 /tmp/blob1/test1
|
|
(! checkblob test1 /tmp/blob2/test1 )
|
|
checkblob test2 /tmp/blob1/test2
|
|
(! checkblob test2 /tmp/blob2/test2 )
|
|
(! checkblob фаил /tmp/blob1/фаил )
|
|
(! checkblob test3 /tmp/external-test3 )
|
|
(! checkblob avatar /tmp/external-avatar )
|
|
|
|
# append files to existing blob, both well-known and other
|
|
PASSWORD=EMJuc3zQaMibJo homectl update blob-user \
|
|
-b test3=/tmp/external-test3 --avatar=/tmp/external-avatar
|
|
inspect blob-user
|
|
checkblob test1 /tmp/blob1/test1
|
|
(! checkblob test1 /tmp/blob2/test1 )
|
|
checkblob test2 /tmp/blob1/test2
|
|
(! checkblob test2 /tmp/blob2/test2 )
|
|
(! checkblob фаил /tmp/blob1/фаил )
|
|
checkblob test3 /tmp/external-test3
|
|
checkblob avatar /tmp/external-avatar
|
|
|
|
# delete files from existing blob, both well-known and other
|
|
PASSWORD=EMJuc3zQaMibJo homectl update blob-user \
|
|
-b test3= --avatar=
|
|
inspect blob-user
|
|
checkblob test1 /tmp/blob1/test1
|
|
(! checkblob test1 /tmp/blob2/test1 )
|
|
checkblob test2 /tmp/blob1/test2
|
|
(! checkblob test2 /tmp/blob2/test2 )
|
|
(! checkblob фаил /tmp/blob1/фаил )
|
|
(! checkblob test3 /tmp/external-test3 )
|
|
(! checkblob avatar /tmp/external-avatar )
|
|
|
|
# swap entire blob directory
|
|
PASSWORD=EMJuc3zQaMibJo homectl update blob-user \
|
|
-b /tmp/blob2
|
|
inspect blob-user
|
|
(! checkblob test1 /tmp/blob1/test1 )
|
|
checkblob test1 /tmp/blob2/test1
|
|
(! checkblob test2 /tmp/blob1/test2 )
|
|
checkblob test2 /tmp/blob2/test2
|
|
(! checkblob фаил /tmp/blob1/фаил )
|
|
(! checkblob test3 /tmp/external-test3 )
|
|
(! checkblob avatar /tmp/external-avatar )
|
|
|
|
# create and delete files while swapping blob directory. Also symlinks.
|
|
PASSWORD=EMJuc3zQaMibJo homectl update blob-user \
|
|
-b /tmp/blob1 -b test2= -b test3=/tmp/external-test3 --avatar=/tmp/external-avatar-lnk
|
|
inspect blob-user
|
|
checkblob test1 /tmp/blob1/test1
|
|
(! checkblob test1 /tmp/blob2/test1 )
|
|
(! checkblob test2 /tmp/blob1/test2 )
|
|
(! checkblob test2 /tmp/blob2/test2 )
|
|
(! checkblob фаил /tmp/blob1/фаил )
|
|
checkblob test3 /tmp/external-test3
|
|
checkblob avatar /tmp/external-avatar # target of the link
|
|
|
|
# clear the blob directory
|
|
PASSWORD=EMJuc3zQaMibJo homectl update blob-user \
|
|
-b /tmp/blob2 -b test3=/tmp/external-test3 --blob=
|
|
inspect blob-user
|
|
(! checkblob test1 /tmp/blob1/test1 )
|
|
(! checkblob test1 /tmp/blob2/test1 )
|
|
(! checkblob test2 /tmp/blob1/test2 )
|
|
(! checkblob test2 /tmp/blob2/test2 )
|
|
(! checkblob фаил /tmp/blob1/фаил )
|
|
(! checkblob test3 /tmp/external-test3 )
|
|
(! checkblob avatar /tmp/external-avatar )
|
|
|
|
# file that's exactly 64M still fits
|
|
# FIXME: Figure out why this fails on ext4.
|
|
if [[ "$FSTYPE" != "ext2/ext3" ]]; then
|
|
PASSWORD=EMJuc3zQaMibJo homectl update blob-user \
|
|
-b barely-fits=/tmp/external-barely-fits
|
|
(! checkblob test1 /tmp/blob1/test1 )
|
|
(! checkblob test1 /tmp/blob2/test1 )
|
|
(! checkblob test2 /tmp/blob1/test2 )
|
|
(! checkblob test2 /tmp/blob2/test2 )
|
|
(! checkblob фаил /tmp/blob1/фаил )
|
|
(! checkblob test3 /tmp/external-test3 )
|
|
(! checkblob avatar /tmp/external-avatar )
|
|
checkblob barely-fits /tmp/external-barely-fits
|
|
fi
|
|
|
|
# error out if the file is too big
|
|
(! PASSWORD=EMJuc3zQaMibJo homectl update blob-user -b huge=/tmp/external-toobig )
|
|
|
|
# error out if filenames are invalid
|
|
(! PASSWORD=EMJuc3zQaMibJo homectl update blob-user -b .hidden=/tmp/external-test3 )
|
|
(! PASSWORD=EMJuc3zQaMibJo homectl update blob-user -b "with spaces=/tmp/external-test3" )
|
|
(! PASSWORD=EMJuc3zQaMibJo homectl update blob-user -b with=equals=/tmp/external-test3 )
|
|
(! PASSWORD=EMJuc3zQaMibJo homectl update blob-user -b файл=/tmp/external-test3 )
|
|
(! PASSWORD=EMJuc3zQaMibJo homectl update blob-user -b special@chars=/tmp/external-test3 )
|
|
|
|
# Make sure offline updates to blobs get propagated in
|
|
homectl deactivate blob-user
|
|
inspect blob-user
|
|
homectl update blob-user --offline -b barely-fits= -b propagated=/tmp/external-test3
|
|
inspect blob-user
|
|
PASSWORD=EMJuc3zQaMibJo homectl activate blob-user
|
|
inspect blob-user
|
|
(! checkblob barely-fits /tmp/external-barely-fits )
|
|
checkblob propagated /tmp/external-test3
|
|
|
|
homectl deactivate blob-user
|
|
wait_for_state blob-user inactive
|
|
homectl remove blob-user
|
|
|
|
# userdbctl tests
|
|
export PAGER=
|
|
|
|
# Create a couple of user/group records to test io.systemd.DropIn
|
|
# See docs/USER_RECORD.md and docs/GROUP_RECORD.md
|
|
mkdir -p /run/userdb/
|
|
cat >"/run/userdb/dropingroup.group" <<\EOF
|
|
{
|
|
"groupName" : "dropingroup",
|
|
"gid" : 1000000
|
|
}
|
|
EOF
|
|
cat >"/run/userdb/dropinuser.user" <<\EOF
|
|
{
|
|
"userName" : "dropinuser",
|
|
"uid" : 2000000,
|
|
"realName" : "🐱",
|
|
"memberOf" : [
|
|
"dropingroup"
|
|
]
|
|
}
|
|
EOF
|
|
cat >"/run/userdb/dropinuser.user-privileged" <<\EOF
|
|
{
|
|
"privileged" : {
|
|
"hashedPassword" : [
|
|
"$6$WHBKvAFFT9jKPA4k$OPY4D4TczKN/jOnJzy54DDuOOagCcvxxybrwMbe1SVdm.Bbr.zOmBdATp.QrwZmvqyr8/SafbbQu.QZ2rRvDs/"
|
|
],
|
|
"sshAuthorizedKeys" : [
|
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA//dxI2xLg4MgxIKKZv1nqwTEIlE/fdakii2Fb75pG+ foo@bar.tld",
|
|
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMlaqG2rTMje5CQnfjXJKmoSpEVJ2gWtx4jBvsQbmee2XbU/Qdq5+SRisssR9zVuxgg5NA5fv08MgjwJQMm+csc= hello@world.tld"
|
|
]
|
|
}
|
|
}
|
|
EOF
|
|
# Set permissions and create necessary symlinks as described in nss-systemd(8)
|
|
chmod 0600 "/run/userdb/dropinuser.user-privileged"
|
|
ln -svrf "/run/userdb/dropingroup.group" "/run/userdb/1000000.group"
|
|
ln -svrf "/run/userdb/dropinuser.user" "/run/userdb/2000000.user"
|
|
ln -svrf "/run/userdb/dropinuser.user-privileged" "/run/userdb/2000000.user-privileged"
|
|
|
|
userdbctl
|
|
userdbctl --version
|
|
userdbctl --help --no-pager
|
|
userdbctl --no-legend
|
|
userdbctl --output=classic
|
|
userdbctl --output=friendly
|
|
userdbctl --output=table
|
|
userdbctl --output=json | jq
|
|
userdbctl -j --json=pretty | jq
|
|
userdbctl -j --json=short | jq
|
|
userdbctl --with-varlink=no
|
|
|
|
userdbctl user
|
|
userdbctl user testuser
|
|
userdbctl user root
|
|
userdbctl user testuser root
|
|
userdbctl user -j testuser root | jq
|
|
# Check only UID for the nobody user, since the name is build-configurable
|
|
userdbctl user --with-nss=no --synthesize=yes
|
|
userdbctl user --with-nss=no --synthesize=yes 0 root 65534
|
|
userdbctl user dropinuser
|
|
userdbctl user 2000000
|
|
userdbctl user --with-nss=no --with-varlink=no --synthesize=no --multiplexer=no dropinuser
|
|
userdbctl user --with-nss=no 2000000
|
|
(! userdbctl user '')
|
|
(! userdbctl user 🐱)
|
|
(! userdbctl user 🐱 '' bar)
|
|
(! userdbctl user i-do-not-exist)
|
|
(! userdbctl user root i-do-not-exist testuser)
|
|
(! userdbctl user --with-nss=no --synthesize=no 0 root 65534)
|
|
(! userdbctl user -N root nobody)
|
|
(! userdbctl user --with-dropin=no dropinuser)
|
|
(! userdbctl user --with-dropin=no 2000000)
|
|
|
|
userdbctl group
|
|
userdbctl group testuser
|
|
userdbctl group root
|
|
userdbctl group testuser root
|
|
userdbctl group -j testuser root | jq
|
|
# Check only GID for the nobody group, since the name is build-configurable
|
|
userdbctl group --with-nss=no --synthesize=yes
|
|
userdbctl group --with-nss=no --synthesize=yes 0 root 65534
|
|
userdbctl group dropingroup
|
|
userdbctl group 1000000
|
|
userdbctl group --with-nss=no --with-varlink=no --synthesize=no --multiplexer=no dropingroup
|
|
userdbctl group --with-nss=no 1000000
|
|
(! userdbctl group '')
|
|
(! userdbctl group 🐱)
|
|
(! userdbctl group 🐱 '' bar)
|
|
(! userdbctl group i-do-not-exist)
|
|
(! userdbctl group root i-do-not-exist testuser)
|
|
(! userdbctl group --with-nss=no --synthesize=no 0 root 65534)
|
|
(! userdbctl group --with-dropin=no dropingroup)
|
|
(! userdbctl group --with-dropin=no 1000000)
|
|
|
|
userdbctl users-in-group
|
|
userdbctl users-in-group testuser
|
|
userdbctl users-in-group testuser root
|
|
userdbctl users-in-group -j testuser root | jq
|
|
userdbctl users-in-group 🐱
|
|
(! userdbctl users-in-group '')
|
|
(! userdbctl users-in-group foo '' bar)
|
|
|
|
userdbctl groups-of-user
|
|
userdbctl groups-of-user testuser
|
|
userdbctl groups-of-user testuser root
|
|
userdbctl groups-of-user -j testuser root | jq
|
|
userdbctl groups-of-user 🐱
|
|
(! userdbctl groups-of-user '')
|
|
(! userdbctl groups-of-user foo '' bar)
|
|
|
|
userdbctl services
|
|
userdbctl services -j | jq
|
|
|
|
varlinkctl call /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetUserRecord '{"userName":"testuser","service":"io.systemd.Multiplexer"}'
|
|
varlinkctl call /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetUserRecord '{"userName":"root","service":"io.systemd.Multiplexer"}'
|
|
varlinkctl call /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetUserRecord '{"userName":"dropinuser","service":"io.systemd.Multiplexer"}'
|
|
varlinkctl call /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetUserRecord '{"uid":2000000,"service":"io.systemd.Multiplexer"}'
|
|
(! varlinkctl call /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetUserRecord '{"userName":"","service":"io.systemd.Multiplexer"}')
|
|
(! varlinkctl call /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetUserRecord '{"userName":"🐱","service":"io.systemd.Multiplexer"}')
|
|
(! varlinkctl call /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetUserRecord '{"userName":"i-do-not-exist","service":"io.systemd.Multiplexer"}')
|
|
|
|
userdbctl ssh-authorized-keys dropinuser | tee /tmp/authorized-keys
|
|
grep "ssh-ed25519" /tmp/authorized-keys
|
|
grep "ecdsa-sha2-nistp256" /tmp/authorized-keys
|
|
echo "my-top-secret-key 🐱" >/tmp/my-top-secret-key
|
|
userdbctl ssh-authorized-keys dropinuser --chain /bin/cat /tmp/my-top-secret-key | tee /tmp/authorized-keys
|
|
grep "ssh-ed25519" /tmp/authorized-keys
|
|
grep "ecdsa-sha2-nistp256" /tmp/authorized-keys
|
|
grep "my-top-secret-key 🐱" /tmp/authorized-keys
|
|
(! userdbctl ssh-authorized-keys 🐱)
|
|
(! userdbctl ssh-authorized-keys dropin-user --chain)
|
|
(! userdbctl ssh-authorized-keys dropin-user --chain '')
|
|
(! SYSTEMD_LOG_LEVEL=debug userdbctl ssh-authorized-keys dropin-user --chain /bin/false)
|
|
|
|
(! userdbctl '')
|
|
for opt in json multiplexer output synthesize with-dropin with-nss with-varlink; do
|
|
(! userdbctl "--$opt=''")
|
|
(! userdbctl "--$opt='🐱'")
|
|
(! userdbctl "--$opt=foo")
|
|
(! userdbctl "--$opt=foo" "--$opt=''" "--$opt=🐱")
|
|
done
|
|
|
|
# FIXME: sshd seems to crash inside asan currently, skip the actual ssh test hence
|
|
if command -v ssh &>/dev/null && command -v sshd &>/dev/null && ! [[ -v ASAN_OPTIONS ]]; then
|
|
at_exit() {
|
|
set +e
|
|
|
|
systemctl is-active -q mysshserver.socket && systemctl stop mysshserver.socket
|
|
rm -f /tmp/homed.id_ecdsa /run/systemd/system/mysshserver{@.service,.socket}
|
|
systemctl daemon-reload
|
|
homectl remove homedsshtest
|
|
for dir in /etc /usr/lib; do
|
|
if [[ -f "$dir/pam.d/sshd.bak" ]]; then
|
|
mv "$dir/pam.d/sshd.bak" "$dir/pam.d/sshd"
|
|
fi
|
|
done
|
|
}
|
|
|
|
trap at_exit EXIT
|
|
|
|
# Test that SSH logins work with delayed unlocking
|
|
ssh-keygen -N '' -C '' -t ecdsa -f /tmp/homed.id_ecdsa
|
|
NEWPASSWORD=hunter4711 homectl create \
|
|
--disk-size=min \
|
|
--luks-discard=yes \
|
|
--luks-pbkdf-type=pbkdf2 \
|
|
--luks-pbkdf-time-cost=1ms \
|
|
--rate-limit-interval=1s \
|
|
--rate-limit-burst=1000 \
|
|
--enforce-password-policy=no \
|
|
--ssh-authorized-keys=@/tmp/homed.id_ecdsa.pub \
|
|
--stop-delay=0 \
|
|
homedsshtest
|
|
homectl inspect homedsshtest
|
|
|
|
mkdir -p /etc/ssh
|
|
test -f /etc/ssh/ssh_host_ecdsa_key || ssh-keygen -t ecdsa -C '' -N '' -f /etc/ssh/ssh_host_ecdsa_key
|
|
|
|
# ssh wants this dir around, but distros cannot agree on a common name for it, let's just create all that
|
|
# are aware of distros use
|
|
mkdir -p /usr/share/empty.sshd /var/empty /var/empty/sshd /run/sshd
|
|
|
|
for dir in /etc /usr/lib; do
|
|
if [[ -f "$dir/pam.d/sshd" ]]; then
|
|
mv "$dir/pam.d/sshd" "$dir/pam.d/sshd.bak"
|
|
cat >"$dir/pam.d/sshd" <<EOF
|
|
auth sufficient pam_unix.so nullok
|
|
auth sufficient pam_systemd_home.so debug
|
|
auth required pam_deny.so
|
|
account sufficient pam_systemd_home.so debug
|
|
account sufficient pam_unix.so
|
|
account required pam_permit.so
|
|
session optional pam_systemd_home.so debug
|
|
session optional pam_systemd.so
|
|
session required pam_unix.so
|
|
EOF
|
|
break
|
|
fi
|
|
done
|
|
|
|
mkdir -p /etc/sshd/
|
|
cat >/etc/ssh/sshd_config <<EOF
|
|
AuthorizedKeysCommand /usr/bin/userdbctl ssh-authorized-keys %u
|
|
AuthorizedKeysCommandUser root
|
|
UsePAM yes
|
|
AcceptEnv PASSWORD
|
|
LogLevel DEBUG3
|
|
EOF
|
|
|
|
cat >/run/systemd/system/mysshserver.socket <<EOF
|
|
[Socket]
|
|
ListenStream=4711
|
|
Accept=yes
|
|
EOF
|
|
|
|
cat >/run/systemd/system/mysshserver@.service <<EOF
|
|
[Service]
|
|
ExecStart=-/usr/sbin/sshd -i -d -e
|
|
StandardInput=socket
|
|
StandardOutput=socket
|
|
StandardError=journal
|
|
EOF
|
|
|
|
systemctl daemon-reload
|
|
systemctl start mysshserver.socket
|
|
|
|
userdbctl user -j homedsshtest
|
|
|
|
ssh -t -t -4 -p 4711 -i /tmp/homed.id_ecdsa \
|
|
-o "SetEnv PASSWORD=hunter4711" -o "StrictHostKeyChecking no" \
|
|
homedsshtest@localhost echo zzz | tr -d '\r' | tee /tmp/homedsshtest.out
|
|
grep -E "^zzz$" /tmp/homedsshtest.out
|
|
rm /tmp/homedsshtest.out
|
|
|
|
ssh -t -t -4 -p 4711 -i /tmp/homed.id_ecdsa \
|
|
-o "SetEnv PASSWORD=hunter4711" -o "StrictHostKeyChecking no" \
|
|
homedsshtest@localhost env
|
|
|
|
wait_for_state homedsshtest inactive
|
|
fi
|
|
|
|
systemd-analyze log-level info
|
|
|
|
touch /testok
|