From 3429ffa48fe517a9d47d7f698a17822044a33694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20unbrot=20P=C3=A4tzold?= Date: Mon, 11 May 2026 11:07:01 +0200 Subject: [PATCH 1/6] kwallet: unmount bind mount cleanly on session logout Switch kwalletd6-logon from --scope to a transient service with RemainAfterExit=yes (kwalletd6 forks to background, so the service must stay active after the main process exits). ExecStop runs 'sudo umount -l' to detach the wallet bind mount before gocryptfs unmounts ~/data (Before=gocryptfs-home.service ordering). install.sh adds a per-user sudoers drop-in so the user service can call umount as root without a password. Co-Authored-By: Claude Sonnet 4.6 --- client_software/0010_kwallet/install.sh | 8 ++++++++ client_software/0010_kwallet/user_run.sh | 7 ++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/client_software/0010_kwallet/install.sh b/client_software/0010_kwallet/install.sh index 0e6bb42..0c7f78e 100755 --- a/client_software/0010_kwallet/install.sh +++ b/client_software/0010_kwallet/install.sh @@ -125,4 +125,12 @@ if [[ $? -ne 0 ]]; then exit 1 fi echo "Done setting up kwallet from secure user folder." + +# Sudoers rule so kwalletd6-logon.service ExecStop can unmount the bind mount (needs root) +# Filename must not contain '.' or end in '~' or sudo ignores it +_SUDOUSER_SAFE=$(printf '%s' "${SUDO_USER}" | tr -dc 'a-zA-Z0-9_-') +printf '%s ALL=(root) NOPASSWD: /usr/bin/umount -l %s\n' "${SUDO_USER}" "${WALLETPATH_CFG}" \ + > "/etc/sudoers.d/kwallet-umount-${_SUDOUSER_SAFE}" +chmod 440 "/etc/sudoers.d/kwallet-umount-${_SUDOUSER_SAFE}" + exit 0 diff --git a/client_software/0010_kwallet/user_run.sh b/client_software/0010_kwallet/user_run.sh index 0cc2ede..47886f1 100755 --- a/client_software/0010_kwallet/user_run.sh +++ b/client_software/0010_kwallet/user_run.sh @@ -18,7 +18,12 @@ if [[ -z $(wmctrl -m | grep "KWin") ]]; then fi #Restart the service -systemd-run --user --scope --unit=kwalletd6-logon kwalletd6 >${TEMPDIR}/kwalletd6.log 2>&1 & +WALLETPATH_CFG="${HOME}/.local/share/kwalletd" +systemd-run --user --unit=kwalletd6-logon \ + --property=RemainAfterExit=yes \ + --property=Before=gocryptfs-home.service \ + --property="ExecStop=/usr/bin/sudo /usr/bin/umount -l ${WALLETPATH_CFG}" \ + kwalletd6 >${TEMPDIR}/kwalletd6.log 2>&1 & sleep 1 #Check if kwalletd is enabled now -- 2.52.0 From 5b13ea73720ab5e950ae04919bf105c41378336f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20unbrot=20P=C3=A4tzold?= Date: Mon, 11 May 2026 11:49:12 +0200 Subject: [PATCH 2/6] kwallet: treat exit code 1 as success in kwalletd6-logon.service kwalletd6 exits with code 1 when the Wayland compositor shuts down during logout. Without SuccessExitStatus=1, the service is marked failed and ExecStop (the bind mount umount) never runs. Treating exit code 1 as success keeps the service in active-exited state so systemd fires ExecStop cleanly on session end. Co-Authored-By: Claude Sonnet 4.6 --- client_software/0010_kwallet/user_run.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/client_software/0010_kwallet/user_run.sh b/client_software/0010_kwallet/user_run.sh index 47886f1..3d258b3 100755 --- a/client_software/0010_kwallet/user_run.sh +++ b/client_software/0010_kwallet/user_run.sh @@ -21,6 +21,7 @@ fi WALLETPATH_CFG="${HOME}/.local/share/kwalletd" systemd-run --user --unit=kwalletd6-logon \ --property=RemainAfterExit=yes \ + --property=SuccessExitStatus=1 \ --property=Before=gocryptfs-home.service \ --property="ExecStop=/usr/bin/sudo /usr/bin/umount -l ${WALLETPATH_CFG}" \ kwalletd6 >${TEMPDIR}/kwalletd6.log 2>&1 & -- 2.52.0 From b32cc96ca0e5902c9a64a6c79cc38eedf33ce80b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20unbrot=20P=C3=A4tzold?= Date: Mon, 11 May 2026 12:01:08 +0200 Subject: [PATCH 3/6] kwallet: stop kwalletd6-logon.service before remounting wallet ExecStop (umount) fires asynchronously ~26s after logout, by which time a second login's install.sh has already remounted the wallet. ExecStop then unmounts the fresh mount, leaving kwalletd6 without the wallet directory. Fix: stop kwalletd6-logon.service at the top of install.sh so its ExecStop fires and drains before the remount, eliminating the race. Co-Authored-By: Claude Sonnet 4.6 --- client_software/0010_kwallet/install.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client_software/0010_kwallet/install.sh b/client_software/0010_kwallet/install.sh index 0c7f78e..1461054 100755 --- a/client_software/0010_kwallet/install.sh +++ b/client_software/0010_kwallet/install.sh @@ -39,6 +39,12 @@ WALLETFILE="${WALLETNAME}.kwl" WALLETPATH="${DECRYPTEDDATADIR}/kwallet" WALLETPATH_CFG="$SUDO_HOME/.local/share/kwalletd" +# Stop kwalletd6-logon.service first so its ExecStop (umount) fires before we remount the wallet. +# Without this, ExecStop races with the remount below and can unmount the freshly mounted wallet. +_USER_UID=$(id -u "${SUDO_USER}") +XDG_RUNTIME_DIR="/run/user/${_USER_UID}" DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${_USER_UID}/bus" \ + sudo -u "${SUDO_USER}" systemctl --user stop kwalletd6-logon.service 2>/dev/null || true + # Stop the daemon anyway if running # kwallet and kwalletmanager are optional and only started when an app has been using them already WALLET_PID=$( pgrep -u $SUDO_USER kwalletd6 ) -- 2.52.0 From 5e0f26896239639bf905d33a8cd0935b1562b89d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20unbrot=20P=C3=A4tzold?= Date: Mon, 11 May 2026 12:29:20 +0200 Subject: [PATCH 4/6] kwallet: remove ExecStop, stop old unit in user_run.sh instead ExecStop on the user service caused an unmount race: it fired asynchronously after logout while the next login's install.sh had already remounted the wallet, then unmounted it again leaving kwalletd6 without its wallet directory. install.sh already handles umount/remount at login start, so no ExecStop is needed. On gocryptfs systems the wallet becomes inaccessible at logout naturally when ~/data is unmounted. user_run.sh now explicitly stops any leftover kwalletd6-logon unit from a previous session before creating a new one, avoiding the systemd-run unit-name-conflict failure. Co-Authored-By: Claude Sonnet 4.6 --- client_software/0010_kwallet/install.sh | 14 -------------- client_software/0010_kwallet/user_run.sh | 5 ++--- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/client_software/0010_kwallet/install.sh b/client_software/0010_kwallet/install.sh index 1461054..0e6bb42 100755 --- a/client_software/0010_kwallet/install.sh +++ b/client_software/0010_kwallet/install.sh @@ -39,12 +39,6 @@ WALLETFILE="${WALLETNAME}.kwl" WALLETPATH="${DECRYPTEDDATADIR}/kwallet" WALLETPATH_CFG="$SUDO_HOME/.local/share/kwalletd" -# Stop kwalletd6-logon.service first so its ExecStop (umount) fires before we remount the wallet. -# Without this, ExecStop races with the remount below and can unmount the freshly mounted wallet. -_USER_UID=$(id -u "${SUDO_USER}") -XDG_RUNTIME_DIR="/run/user/${_USER_UID}" DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${_USER_UID}/bus" \ - sudo -u "${SUDO_USER}" systemctl --user stop kwalletd6-logon.service 2>/dev/null || true - # Stop the daemon anyway if running # kwallet and kwalletmanager are optional and only started when an app has been using them already WALLET_PID=$( pgrep -u $SUDO_USER kwalletd6 ) @@ -131,12 +125,4 @@ if [[ $? -ne 0 ]]; then exit 1 fi echo "Done setting up kwallet from secure user folder." - -# Sudoers rule so kwalletd6-logon.service ExecStop can unmount the bind mount (needs root) -# Filename must not contain '.' or end in '~' or sudo ignores it -_SUDOUSER_SAFE=$(printf '%s' "${SUDO_USER}" | tr -dc 'a-zA-Z0-9_-') -printf '%s ALL=(root) NOPASSWD: /usr/bin/umount -l %s\n' "${SUDO_USER}" "${WALLETPATH_CFG}" \ - > "/etc/sudoers.d/kwallet-umount-${_SUDOUSER_SAFE}" -chmod 440 "/etc/sudoers.d/kwallet-umount-${_SUDOUSER_SAFE}" - exit 0 diff --git a/client_software/0010_kwallet/user_run.sh b/client_software/0010_kwallet/user_run.sh index 3d258b3..108fbe2 100755 --- a/client_software/0010_kwallet/user_run.sh +++ b/client_software/0010_kwallet/user_run.sh @@ -18,12 +18,11 @@ if [[ -z $(wmctrl -m | grep "KWin") ]]; then fi #Restart the service -WALLETPATH_CFG="${HOME}/.local/share/kwalletd" +# Stop any leftover unit from a previous session before creating a new one +systemctl --user stop kwalletd6-logon.service 2>/dev/null || true systemd-run --user --unit=kwalletd6-logon \ --property=RemainAfterExit=yes \ --property=SuccessExitStatus=1 \ - --property=Before=gocryptfs-home.service \ - --property="ExecStop=/usr/bin/sudo /usr/bin/umount -l ${WALLETPATH_CFG}" \ kwalletd6 >${TEMPDIR}/kwalletd6.log 2>&1 & sleep 1 -- 2.52.0 From 01b39e892f4e23e6a618e407fd8767b8f536101d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20unbrot=20P=C3=A4tzold?= Date: Mon, 11 May 2026 12:43:09 +0200 Subject: [PATCH 5/6] 0040_autostart_logon_script: remove executable bit from .desktop file systemd-xdg-autostart-generator warns that .desktop files with execute permissions set are invalid. .desktop files should not be executable. Co-Authored-By: Claude Sonnet 4.6 --- .../0040_autostart_logon_script/logon_script.sh.desktop | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 client_software/0040_autostart_logon_script/logon_script.sh.desktop diff --git a/client_software/0040_autostart_logon_script/logon_script.sh.desktop b/client_software/0040_autostart_logon_script/logon_script.sh.desktop old mode 100755 new mode 100644 -- 2.52.0 From ac85c665a833a2535b6036423f89193f45bc0adc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20unbrot=20P=C3=A4tzold?= Date: Mon, 11 May 2026 12:56:19 +0200 Subject: [PATCH 6/6] sync_client_software: remove unresolvable _gateway NTP entry from chrony.conf Anaconda adds 'server _gateway iburst' as a fallback NTP source when no NTP servers are specified in the kickstart. chronyd cannot resolve the special hostname '_gateway' at startup, logging an error each boot. The sourcedir /run/chrony-dhcp directive already handles DHCP-provided NTP servers, making the _gateway line redundant. Co-Authored-By: Claude Sonnet 4.6 --- system_setup/sync_client_software.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/system_setup/sync_client_software.sh b/system_setup/sync_client_software.sh index b1c4430..478f5fb 100755 --- a/system_setup/sync_client_software.sh +++ b/system_setup/sync_client_software.sh @@ -10,6 +10,16 @@ if [ "$EUID" -ne 0 ]; then echo "Press any key to continue" && read -n 1 -s -r && exit 1 fi +# Remove 'server _gateway iburst' from chrony.conf — Anaconda adds it as a fallback but +# _gateway is not resolvable by chronyd at startup; DHCP-sourced servers via sourcedir +# /run/chrony-dhcp already cover NTP discovery so this line is redundant and noisy. +_CHRONY_CONF="/etc/chrony.conf" +if [ -f "${_CHRONY_CONF}" ] && grep -q "^server _gateway" "${_CHRONY_CONF}"; then + echo "Patching chrony.conf: removing unresolvable 'server _gateway' entry" + sed -i "/^server _gateway/d" "${_CHRONY_CONF}" + systemctl restart chronyd +fi + # Ensure krb5_validate = False in sssd.conf to restore offline auth # (SSSD >= 2.10.1 skips the CAP_DAC_READ_SEARCH raise in offline mode, so validate_tgt # fails with EACCES before the cached-credential fallback is reached) -- 2.52.0