From 95ecbe72c70facd434fb844ad863eac2a51a5898 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 27 Apr 2026 20:00:52 +0000 Subject: [PATCH] fix: sysmaint login fails without autologin due to empty password When autologin is disabled for the sysmaint account, the display manager greeter requires manual authentication. However, the sysmaint account is created with an empty password, which PAM rejects (pam_unix does not allow empty passwords without nullok). This causes immediate login failure before the password prompt even appears. Fix by detecting when autologin is off and the sysmaint account has no password during sysmaint boot, then setting a temporary password ('changeme') that is cleared on shutdown. https://claude.ai/code/session_013aeZmbWvCMJxAPDcHYiBqS --- usr/libexec/user-sysmaint-split/sysmaint-boot | 35 +++++++++++++++++++ .../user-sysmaint-split/sysmaint-boot-cleanup | 9 +++++ 2 files changed, 44 insertions(+) diff --git a/usr/libexec/user-sysmaint-split/sysmaint-boot b/usr/libexec/user-sysmaint-split/sysmaint-boot index 584e043..6db6437 100755 --- a/usr/libexec/user-sysmaint-split/sysmaint-boot +++ b/usr/libexec/user-sysmaint-split/sysmaint-boot @@ -87,6 +87,7 @@ old_sysmaint_conf_file_list=( '/etc/sddm.conf.d/z-sysmaint-boot.conf' ) sudo_to_sysmaint="sudo --non-interactive -u sysmaint" +sysmaint_temp_password_flag='/run/user-sysmaint-split/temp-password-set' bail_if_read_only() { if test -w /etc; then @@ -100,7 +101,39 @@ bail_if_read_only() { exit 1 } +ensure_sysmaint_has_password() { + ## When autologin is disabled, the display manager greeter requires manual + ## authentication. If the sysmaint account has an empty password, PAM will + ## reject login attempts because pam_unix does not allow empty passwords + ## without the nullok option (which security-hardened systems remove). + ## Detect this and set a temporary password so manual login works. + if [ "${sysmaint_autologin}" = "yes" ]; then + return + fi + local pass_status + pass_status="$(passwd -S sysmaint 2>/dev/null)" || true + if printf '%s\n' "${pass_status}" | grep -qw 'NP'; then + printf '%s\n' "WARNING: sysmaint account has no password and autologin is disabled." >&2 + printf '%s\n' "WARNING: Setting temporary password 'changeme' for sysmaint account." >&2 + printf '%s\n' "WARNING: Please change it after login using the 'passwd' command." >&2 + printf '%s\n' 'sysmaint:changeme' | chpasswd + mkdir --parents -- "$(dirname -- "${sysmaint_temp_password_flag}")" + touch -- "${sysmaint_temp_password_flag}" + fi +} + +restore_sysmaint_empty_password() { + ## If we set a temporary password during boot, restore the empty password + ## state on shutdown so the system returns to its original configuration. + if [ -f "${sysmaint_temp_password_flag}" ]; then + printf '%s\n' "INFO: Restoring empty password for sysmaint account." >&2 + passwd -d sysmaint >/dev/null 2>&1 || true + safe-rm -f -- "${sysmaint_temp_password_flag}" + fi +} + restore_pre_sysmaint_autologin_config() { + restore_sysmaint_empty_password safe-rm -f -- "${sysmaint_lightdm_conf_file}" safe-rm -f -- "${sysmaint_sddm_conf_file}" safe-rm -f -- "${old_sysmaint_conf_file_list[@]}" @@ -354,6 +387,8 @@ handle_boot() { rebuild_greetd_config fi + ensure_sysmaint_has_password + ## Qubes handling. if [ ! -f /usr/share/qubes/marker-vm ]; then return diff --git a/usr/libexec/user-sysmaint-split/sysmaint-boot-cleanup b/usr/libexec/user-sysmaint-split/sysmaint-boot-cleanup index 96c97a0..8539c46 100755 --- a/usr/libexec/user-sysmaint-split/sysmaint-boot-cleanup +++ b/usr/libexec/user-sysmaint-split/sysmaint-boot-cleanup @@ -24,8 +24,17 @@ old_sysmaint_conf_file_list=( '/etc/lightdm/lightdm.conf.d/60_sysmaint-boot.conf' '/etc/sddm.conf.d/z-sysmaint-boot.conf' ) +sysmaint_temp_password_flag='/run/user-sysmaint-split/temp-password-set' exit_code=0 +## Restore empty password for sysmaint if a temporary password was set +## during boot (when autologin was disabled and the account had no password). +if [ -f "${sysmaint_temp_password_flag}" ]; then + echo "INFO: Restoring empty password for sysmaint account." >&2 + passwd -d sysmaint >/dev/null 2>&1 || true + rm -f -- "${sysmaint_temp_password_flag}" +fi + echo "INFO: Removing sysmaint autologin files because system is shutting down." >&2 safe-rm -f --verbose -- "${sysmaint_lightdm_conf_file}" safe-rm -f --verbose -- "${sysmaint_sddm_conf_file}"