mirror of
https://github.com/agelesslinux/agelesslinux.git
synced 2026-11-06 05:17:22 +00:00
Additional userdb carefulness
see #1 Bug 1 fixed — revert_userdb blindly reloaded userdbd (30-userdb.sh): During --revert, analyze_userdb is never called so DM_NAME is always "unknown". The unconditional userdbd reload would break the lock screen again for users reverting while SDDM was active. Now it detects the active DM directly and skips the reload with a warning if one is found. Bug 2 fixed — revert_no_conf printed rm -rf /etc/userdb (99-main.sh): The legacy manual-revert instructions nuked all of /etc/userdb, including any pre-existing records that ageless had backed up. Now it prints per-file commands: mv *.pre-ageless where a backup exists, rm only where there's no backup.
This commit is contained in:
1 parent
fd430934ad
commit
1e1b00f45d
4 files changed
+160
-12
No files matched your search
+32
-4
@@ -629,11 +629,25 @@ revert_userdb() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Restart userdbd to clear any cached records (safe during revert)
|
||||
# Restart userdbd to clear cached records — but NOT if a display manager
|
||||
# is active: reloading userdbd mid-session breaks the lock screen (same
|
||||
# bug that affected the install path).
|
||||
if command -v systemctl &>/dev/null; then
|
||||
if systemctl list-unit-files systemd-userdbd.service &>/dev/null 2>&1; then
|
||||
systemctl try-reload-or-restart systemd-userdbd.service 2>/dev/null || true
|
||||
echo -e " [${GREEN}✓${NC}] Reloaded systemd-userdbd"
|
||||
local active_dm=""
|
||||
for dm in sddm gdm gdm3 lightdm lxdm nodm; do
|
||||
if systemctl is-active "${dm}.service" &>/dev/null; then
|
||||
active_dm="$dm"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ -n "$active_dm" ]]; then
|
||||
echo -e " [${YELLOW}!${NC}] Skipped userdbd reload — ${active_dm} is active."
|
||||
echo -e " ${YELLOW} Do NOT lock your screen. Log out and back in (or reboot).${NC}"
|
||||
else
|
||||
systemctl try-reload-or-restart systemd-userdbd.service 2>/dev/null || true
|
||||
echo -e " [${GREEN}✓${NC}] Reloaded systemd-userdbd"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -1279,7 +1293,21 @@ revert_no_conf() {
|
||||
fi
|
||||
echo " sudo rm -rf /etc/ageless"
|
||||
if [[ -d /etc/userdb ]]; then
|
||||
echo " sudo rm -rf /etc/userdb"
|
||||
# Restore per-user backups where they exist; only remove files without one.
|
||||
# rm -rf /etc/userdb would destroy any pre-existing userdb records.
|
||||
local has_userdb_files=0
|
||||
for f in /etc/userdb/*.user; do
|
||||
[[ -f "$f" ]] || continue
|
||||
has_userdb_files=1
|
||||
if [[ -f "${f}.pre-ageless" ]]; then
|
||||
echo " sudo mv ${f}.pre-ageless ${f}"
|
||||
else
|
||||
echo " sudo rm -f ${f}"
|
||||
fi
|
||||
done
|
||||
if [[ $has_userdb_files -eq 0 ]]; then
|
||||
echo " sudo rmdir /etc/userdb 2>/dev/null || true"
|
||||
fi
|
||||
fi
|
||||
if command -v systemctl &>/dev/null; then
|
||||
if systemctl list-unit-files agelessd.timer &>/dev/null 2>&1; then
|
||||
|
||||
+17
-3
@@ -262,11 +262,25 @@ revert_userdb() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Restart userdbd to clear any cached records (safe during revert)
|
||||
# Restart userdbd to clear cached records — but NOT if a display manager
|
||||
# is active: reloading userdbd mid-session breaks the lock screen (same
|
||||
# bug that affected the install path).
|
||||
if command -v systemctl &>/dev/null; then
|
||||
if systemctl list-unit-files systemd-userdbd.service &>/dev/null 2>&1; then
|
||||
systemctl try-reload-or-restart systemd-userdbd.service 2>/dev/null || true
|
||||
echo -e " [${GREEN}✓${NC}] Reloaded systemd-userdbd"
|
||||
local active_dm=""
|
||||
for dm in sddm gdm gdm3 lightdm lxdm nodm; do
|
||||
if systemctl is-active "${dm}.service" &>/dev/null; then
|
||||
active_dm="$dm"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ -n "$active_dm" ]]; then
|
||||
echo -e " [${YELLOW}!${NC}] Skipped userdbd reload — ${active_dm} is active."
|
||||
echo -e " ${YELLOW} Do NOT lock your screen. Log out and back in (or reboot).${NC}"
|
||||
else
|
||||
systemctl try-reload-or-restart systemd-userdbd.service 2>/dev/null || true
|
||||
echo -e " [${GREEN}✓${NC}] Reloaded systemd-userdbd"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
+15
-1
@@ -414,7 +414,21 @@ revert_no_conf() {
|
||||
fi
|
||||
echo " sudo rm -rf /etc/ageless"
|
||||
if [[ -d /etc/userdb ]]; then
|
||||
echo " sudo rm -rf /etc/userdb"
|
||||
# Restore per-user backups where they exist; only remove files without one.
|
||||
# rm -rf /etc/userdb would destroy any pre-existing userdb records.
|
||||
local has_userdb_files=0
|
||||
for f in /etc/userdb/*.user; do
|
||||
[[ -f "$f" ]] || continue
|
||||
has_userdb_files=1
|
||||
if [[ -f "${f}.pre-ageless" ]]; then
|
||||
echo " sudo mv ${f}.pre-ageless ${f}"
|
||||
else
|
||||
echo " sudo rm -f ${f}"
|
||||
fi
|
||||
done
|
||||
if [[ $has_userdb_files -eq 0 ]]; then
|
||||
echo " sudo rmdir /etc/userdb 2>/dev/null || true"
|
||||
fi
|
||||
fi
|
||||
if command -v systemctl &>/dev/null; then
|
||||
if systemctl list-unit-files agelessd.timer &>/dev/null 2>&1; then
|
||||
|
||||
@@ -84,8 +84,8 @@ echo " Human users: ${HUMAN_USERS:-none}"
|
||||
section "--version"
|
||||
|
||||
version_out=$(bash "$SCRIPT" --version 2>&1)
|
||||
if [[ "$version_out" == *"0.1.0"* ]]; then
|
||||
pass "--version prints 0.1.0"
|
||||
if [[ "$version_out" == *"0.1.1"* ]]; then
|
||||
pass "--version prints 0.1.1"
|
||||
else
|
||||
fail "--version" "got: $version_out"
|
||||
fi
|
||||
@@ -273,8 +273,8 @@ if [[ -f /etc/agelesslinux.conf ]]; then
|
||||
# Verify key fields
|
||||
# shellcheck disable=SC1091
|
||||
source /etc/agelesslinux.conf
|
||||
if [[ "${AGELESS_VERSION:-}" == "0.1.0" ]]; then
|
||||
pass "conf records version 0.1.0"
|
||||
if [[ "${AGELESS_VERSION:-}" == "0.1.1" ]]; then
|
||||
pass "conf records version 0.1.1"
|
||||
else
|
||||
fail "conf version" "got: ${AGELESS_VERSION:-unset}"
|
||||
fi
|
||||
@@ -392,6 +392,98 @@ else
|
||||
skip "--persistent error test" "systemctl is available"
|
||||
fi
|
||||
|
||||
# ── Test: revert skips userdbd reload when DM is active ──────────────────────
|
||||
#
|
||||
# Regression test for issue #1: reloading systemd-userdbd mid-session breaks
|
||||
# the SDDM (and LightDM) lock screen. The fix in revert_userdb must detect
|
||||
# an active display manager and skip the reload, warning the user instead.
|
||||
|
||||
section "revert: DM lock-screen safety (issue #1 fix)"
|
||||
|
||||
bash "$SCRIPT" --accept >/dev/null 2>&1
|
||||
|
||||
mkdir -p /tmp/mock-bin
|
||||
RELOAD_FLAG=/tmp/mock-bin/userdbd-reload-called
|
||||
rm -f "$RELOAD_FLAG"
|
||||
|
||||
cat > /tmp/mock-bin/systemctl << 'MOCK_EOF'
|
||||
#!/bin/bash
|
||||
# Mock: sddm is active, userdbd is installed. Reloading userdbd must not happen.
|
||||
case "${1:-} ${2:-}" in
|
||||
"is-active sddm.service") exit 0 ;;
|
||||
"is-active "*.service) exit 1 ;;
|
||||
"list-unit-files systemd-userdbd.service") exit 0 ;;
|
||||
"try-reload-or-restart systemd-userdbd.service")
|
||||
touch /tmp/mock-bin/userdbd-reload-called ; exit 0 ;;
|
||||
*) exit 0 ;;
|
||||
esac
|
||||
MOCK_EOF
|
||||
chmod +x /tmp/mock-bin/systemctl
|
||||
|
||||
dm_revert_out=$(PATH="/tmp/mock-bin:$PATH" bash "$SCRIPT" --revert 2>&1)
|
||||
|
||||
if echo "$dm_revert_out" | grep -q "Skipped userdbd reload"; then
|
||||
pass "revert: skips userdbd reload when SDDM is active"
|
||||
else
|
||||
fail "revert DM reload check" "expected 'Skipped userdbd reload'; got: $(echo "$dm_revert_out" | grep -i 'userdbd\|reload\|sddm' | head -3)"
|
||||
fi
|
||||
|
||||
if echo "$dm_revert_out" | grep -qi "log out\|lock"; then
|
||||
pass "revert: warns about lock screen when DM active"
|
||||
else
|
||||
fail "revert DM warning" "no lock-screen warning in output"
|
||||
fi
|
||||
|
||||
if [[ ! -f "$RELOAD_FLAG" ]]; then
|
||||
pass "revert: userdbd was NOT reloaded (lock screen protected)"
|
||||
else
|
||||
fail "revert DM safety" "userdbd try-reload-or-restart was called despite active SDDM"
|
||||
fi
|
||||
|
||||
rm -rf /tmp/mock-bin
|
||||
|
||||
# ── Test: revert_no_conf prints per-file userdb instructions ─────────────────
|
||||
#
|
||||
# Regression test for issue #1 (legacy path): the old revert_no_conf printed
|
||||
# "rm -rf /etc/userdb" which destroyed any pre-existing userdb records that
|
||||
# ageless had backed up before modifying. The fix prints per-file instructions:
|
||||
# - "mv backup → original" when a .pre-ageless backup exists
|
||||
# - "rm -f file" when no backup exists (ageless created it fresh)
|
||||
|
||||
section "revert_no_conf: per-file userdb instructions (not rm -rf)"
|
||||
|
||||
cp /etc/os-release /etc/os-release.pre-ageless
|
||||
mkdir -p /etc/userdb
|
||||
printf '{"userName":"testuser","uid":1000,"birthDate":"1970-01-01"}\n' \
|
||||
> /etc/userdb/testuser.user
|
||||
printf '{"userName":"testuser","uid":1000,"birthDate":null}\n' \
|
||||
> /etc/userdb/testuser.user.pre-ageless
|
||||
printf '{"userName":"orphan","uid":1001,"birthDate":"1970-01-01"}\n' \
|
||||
> /etc/userdb/orphan.user
|
||||
|
||||
no_conf_out=$(bash "$SCRIPT" --revert 2>&1 || true)
|
||||
|
||||
if echo "$no_conf_out" | grep -q "mv.*testuser\.user\.pre-ageless.*testuser\.user"; then
|
||||
pass "revert_no_conf: prints 'mv backup → original' for backed-up user"
|
||||
else
|
||||
fail "revert_no_conf mv" "no mv instruction for testuser.user.pre-ageless"
|
||||
fi
|
||||
|
||||
if echo "$no_conf_out" | grep -q "rm -f.*orphan\.user"; then
|
||||
pass "revert_no_conf: prints 'rm -f' for un-backed-up user"
|
||||
else
|
||||
fail "revert_no_conf rm" "no rm -f instruction for orphan.user"
|
||||
fi
|
||||
|
||||
if echo "$no_conf_out" | grep -q "rm -rf /etc/userdb"; then
|
||||
fail "revert_no_conf safety" "still prints 'rm -rf /etc/userdb' (too broad)"
|
||||
else
|
||||
pass "revert_no_conf: does NOT print 'rm -rf /etc/userdb'"
|
||||
fi
|
||||
|
||||
rm -f /etc/os-release.pre-ageless
|
||||
rm -rf /etc/userdb
|
||||
|
||||
# ── Results ──────────────────────────────────────────────────────────────────
|
||||
|
||||
section "RESULTS"
|
||||
|
||||
Reference in new issue
Block a user