fix(greetd): password-then-FIDO order; add ReGreet background tool

greetd's PAM stack included system-login, whose own pam_u2f line runs
before the password stack — combined with greetd's own trailing
pam_u2f line, ReGreet prompted FIDO, then password, then FIDO again.
Spell out system-login's auth phase minus that stray line so FIDO is
asked once, after the password, matching hyprlock's order.

Also add setup/tools/set-regreet-background.sh to pin a specific image
as the greeter background, independent of the wallpaper-sync unit.
main
Amir Alexander Abdelbaki 2026-07-09 00:13:19 +02:00
parent 84420733bb
commit 3da57a457a
2 changed files with 109 additions and 3 deletions

View File

@ -2,14 +2,24 @@
# PAM stack for the greetd/ReGreet greeter. # PAM stack for the greetd/ReGreet greeter.
# #
# Deployed to /etc/pam.d/greetd by greetd-regreet.sh (@HOST@ → this machine's # Deployed to /etc/pam.d/greetd by greetd-regreet.sh (@HOST@ → this machine's
# hostname at install time). Mirrors the working lightdm stack: password via # hostname at install time). Password first, then a single required FIDO/U2F
# system-login plus a required FIDO/U2F touch. `nouserok` lets users without an # touch — the same order hyprlock uses. `nouserok` lets users without an
# enrolled key log in with their password alone. # enrolled key log in with their password alone.
# #
# The `auth` phase is spelled out (pam_shells/pam_nologin/system-auth) instead
# of `include system-login`, because this host's /etc/pam.d/system-login itself
# leads with an unconditional `pam_u2f.so` line ahead of the password stack. A
# plain `include` would pull that in, then this file's own pam_u2f line would
# run again — prompting for FIDO, then password, then FIDO a second time.
# Spelling the auth phase out here reproduces system-login's auth stack minus
# that stray line, so FIDO is asked for exactly once, after the password.
#
# NOTE: intentionally simpler than a tuigreet multi-factor stack — no # NOTE: intentionally simpler than a tuigreet multi-factor stack — no
# pam_securetty / pam_oath, which a graphical greeter's single password field # pam_securetty / pam_oath, which a graphical greeter's single password field
# cannot drive cleanly. # cannot drive cleanly.
auth include system-login auth required pam_shells.so
auth requisite pam_nologin.so
auth include system-auth
auth required pam_u2f.so nouserok cue origin=pam://@HOST@ appid=pam://@HOST@ auth required pam_u2f.so nouserok cue origin=pam://@HOST@ appid=pam://@HOST@
account include system-login account include system-login
password include system-login password include system-login

View File

@ -0,0 +1,96 @@
#!/bin/bash
# =============================================================================
# set-regreet-background.sh — set a specific image as the ReGreet greeter's background
# =============================================================================
# ReGreet reads its background from the path fixed in /etc/greetd/regreet.toml
# ([background] path = /usr/share/backgrounds/lightdm-greeter-bg.png — the name
# is shared with the old lightdm greeter, both point at the same file). Normally
# that file is kept in sync with your desktop wallpaper by the
# lightdm-greeter-wallpaper.path unit (see etc-lightdm/). This tool overrides it
# with a specific image of your choosing instead.
#
# NOTE: if lightdm-greeter-wallpaper.path is enabled, it will overwrite this
# choice the next time you change your desktop wallpaper via the picker. This
# script warns you when that unit is active; disable it
# (systemctl disable --now lightdm-greeter-wallpaper.path) if you want the
# greeter background to stay pinned regardless of desktop wallpaper changes.
#
# Usage:
# set-regreet-background.sh <image> [--dry-run] [--help]
# -n, --dry-run Print what would happen; change nothing
# -h, --help Show this help and exit
# =============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SETUP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
source "$SETUP_DIR/modules/lib/logging.sh"
DEST="/usr/share/backgrounds/lightdm-greeter-bg.png"
usage() {
cat <<'EOF'
set-regreet-background.sh — set a specific image as the ReGreet greeter's background
Usage:
set-regreet-background.sh <image> [--dry-run] [--help]
-n, --dry-run Print what would happen; change nothing
-h, --help Show this help and exit
EOF
}
IMG=""
DRY_RUN=0
while [[ $# -gt 0 ]]; do
case "$1" in
-n|--dry-run) DRY_RUN=1 ;;
-h|--help) usage; exit 0 ;;
-*) err "Unknown argument: $1"; echo "Try --help." >&2; exit 2 ;;
*) IMG="$1" ;;
esac
shift
done
if [[ -z "$IMG" ]]; then
usage
exit 1
fi
[[ -f "$IMG" ]] || { err "Not found: $IMG"; exit 1; }
[[ -r "$IMG" ]] || { err "Not readable: $IMG"; exit 1; }
if command -v identify &>/dev/null && ! identify -format '%m' "$IMG" &>/dev/null; then
err "Not a readable image: $IMG"
exit 1
fi
run() {
if (( DRY_RUN )); then
printf '[dry-run] would run: %s\n' "$*"
else
"$@"
fi
}
# ReGreet loads the image by content, not by extension, but re-encode to a real
# PNG at DEST's fixed name so the file matches what it claims to be.
log "Setting ReGreet background to $IMG..."
if command -v magick &>/dev/null; then
TMP_BG="$(mktemp /tmp/regreet-bg.XXXXXX.png)"
trap 'rm -f "$TMP_BG"' EXIT
magick "$IMG" "$TMP_BG"
run sudo install -Dm644 "$TMP_BG" "$DEST"
else
warn "ImageMagick not found — copying the image as-is (extension will not match content)."
run sudo install -Dm644 "$IMG" "$DEST"
fi
if systemctl is-active --quiet lightdm-greeter-wallpaper.path 2>/dev/null; then
warn "lightdm-greeter-wallpaper.path is active — this background will be overwritten the next time your desktop wallpaper changes."
warn "To pin it permanently: sudo systemctl disable --now lightdm-greeter-wallpaper.path"
fi
if (( DRY_RUN )); then
log "Dry run complete — no changes were made."
else
log "ReGreet background set. It will show on the next greeter start (reboot, or restart greetd.service)."
fi