diff --git a/roles/personalisierung/files/personalisierung-anmeldung b/roles/personalisierung/files/personalisierung-anmeldung new file mode 100755 index 0000000..0ae64f9 --- /dev/null +++ b/roles/personalisierung/files/personalisierung-anmeldung @@ -0,0 +1,62 @@ +#!/bin/sh +# Verwaltet von Tuxflotte (Rolle personalisierung) +# +# Gibt die Anmeldung am Konto "Personalisierung" frei oder nimmt sie weg +# (ADR-0041, Ergänzung 18.10.2026). Frei nur, wenn beides gilt: +# - die Verwaltung bietet sie an (Merkerdatei, von der Rolle gesetzt: kein +# persönliches Konto auf dem Gerät oder ein neuer Code läuft), und +# - das laufende LightDM nutzt schon den Kiosk-Wrapper. LightDM liest +# seine Konfiguration nur beim Start; vorher bekäme das passwortlose +# Konto den vollen Desktop. +# Sonst: keine passwortlose PAM-Freigabe und Shell nologin, damit blendet +# AccountsService das Konto im Anmeldebildschirm aus. +# +# Aufruf: "start" aus ExecStartPre von lightdm.service (LightDM startet +# gleich mit der aktuellen Konfiguration), ohne Argument von der Rolle. +# Ausgabe: "frei" oder "gesperrt", bei einer Änderung mit " geaendert". +set -eu + +KONF=/etc/lightdm/lightdm.conf.d/85-tuxflotte-personalisierung.conf +MERKER=/etc/tuxflotte/personalisierung-anbieten +PAM=/etc/pam.d/lightdm +ZEILE='auth sufficient pam_succeed_if.so user = personalisierung' +MUSTER='^auth[[:space:]]+sufficient[[:space:]]+pam_succeed_if\.so[[:space:]]+user[[:space:]]+=[[:space:]]+personalisierung[[:space:]]*$' + +wrapper_aktiv() { + [ -f "$KONF" ] || return 1 + [ "${1:-}" = start ] && return 0 + pid=$(systemctl show -p MainPID --value lightdm.service 2>/dev/null || true) + [ "${pid:-0}" -gt 0 ] 2>/dev/null || return 1 + laufzeit=$(ps -o etimes= -p "$pid" | tr -d ' ') + [ -n "$laufzeit" ] || return 1 + [ $(( $(date +%s) - laufzeit )) -gt "$(stat -c %Y "$KONF")" ] +} + +soll=gesperrt +if [ -f "$MERKER" ] && wrapper_aktiv "${1:-}"; then + soll=frei +fi + +geaendert="" +if [ "$soll" = frei ]; then + if [ -f "$PAM" ] && ! grep -Eq "$MUSTER" "$PAM"; then + sed -i "1i $ZEILE" "$PAM" + geaendert=" geaendert" + fi + shell=/bin/bash +else + if [ -f "$PAM" ] && grep -Eq "$MUSTER" "$PAM"; then + sed -i -E "/$MUSTER/d" "$PAM" + geaendert=" geaendert" + fi + shell=/usr/sbin/nologin +fi + +if getent passwd personalisierung >/dev/null; then + if [ "$(getent passwd personalisierung | cut -d: -f7)" != "$shell" ]; then + usermod -s "$shell" personalisierung + geaendert=" geaendert" + fi +fi + +echo "$soll$geaendert" diff --git a/roles/personalisierung/tasks/main.yml b/roles/personalisierung/tasks/main.yml index d580468..3a37d94 100644 --- a/roles/personalisierung/tasks/main.yml +++ b/roles/personalisierung/tasks/main.yml @@ -74,15 +74,15 @@ state: present when: tuxflotte_pers_aktiv | bool -# Kein Passwort (gesperrt), Anmeldung nur über die PAM-Freigabe unten und nur -# am Anmeldebildschirm. Shell bleibt bash: AccountsService blendet Konten mit -# nologin aus, dann stünde es nicht in der Benutzerliste. Der Kommentar ist -# der Anzeigename im Greeter und kennzeichnet das Konto als unseres. +# Kein Passwort (gesperrt), Anmeldung nur über die PAM-Freigabe von +# personalisierung-anmeldung und nur am Anmeldebildschirm. Die Shell setzt +# ebenfalls das Skript: bash, wenn das Konto angeboten wird, sonst nologin +# (AccountsService blendet es dann im Greeter aus). Der Kommentar ist der +# Anzeigename im Greeter und kennzeichnet das Konto als unseres. - name: Ensure personalisierung account exists ansible.builtin.user: name: personalisierung comment: "Personalisierung" - shell: /bin/bash create_home: true password_lock: true when: tuxflotte_pers_aktiv | bool @@ -134,15 +134,69 @@ mode: "0644" when: tuxflotte_pers_aktiv | bool -# Eigene Freigabe nur für dieses Konto, nicht über die Gruppe nopasswdlogin: -# guest-session entfernt deren Regel beim Abwählen vollständig. -- name: Allow passwordless login for the personalisierung account - ansible.builtin.lineinfile: - path: /etc/pam.d/lightdm - regexp: '^auth\s+sufficient\s+pam_succeed_if\.so\s+user\s+=\s+personalisierung\s*$' - line: "auth sufficient pam_succeed_if.so user = personalisierung" - insertbefore: BOF - state: present +# Passwortlose Anmeldung: eigene PAM-Freigabe nur für dieses Konto, nicht über +# die Gruppe nopasswdlogin (guest-session entfernt deren Regel beim Abwählen +# vollständig). Gesetzt und entfernt von personalisierung-anmeldung, nicht +# hier: frei nur, solange die Verwaltung das Konto anbietet (Check-in-Option +# anmeldung_anbieten, ADR-0041 Ergänzung 18.10.2026) und LightDM schon mit +# dem Kiosk-Wrapper läuft. Beim ersten Einrichten also erst nach dem +# nächsten Start von LightDM, vorher bekäme das Konto den vollen Desktop. +- name: Ensure Tuxflotte config directory exists + ansible.builtin.file: + path: /etc/tuxflotte + state: directory + mode: "0755" + when: tuxflotte_pers_aktiv | bool + +- name: Record whether the account is offered (Verwaltung) + ansible.builtin.copy: + dest: /etc/tuxflotte/personalisierung-anbieten + content: "# Verwaltet von Tuxflotte (Rolle personalisierung)\n" + mode: "0644" + when: (tuxflotte_pers_aktiv | bool) and (tuxflotte_optionen.anmeldung_anbieten | default(true) | bool) + +- name: Record that the account is not offered (Verwaltung) + ansible.builtin.file: + path: /etc/tuxflotte/personalisierung-anbieten + state: absent + when: (tuxflotte_pers_aktiv | bool) and not (tuxflotte_optionen.anmeldung_anbieten | default(true) | bool) + +- name: Install login switch + ansible.builtin.copy: + src: personalisierung-anmeldung + dest: /usr/local/lib/tuxflotte/personalisierung-anmeldung + mode: "0755" + when: tuxflotte_pers_aktiv | bool + +- name: Ensure lightdm.service drop-in directory exists + ansible.builtin.file: + path: /etc/systemd/system/lightdm.service.d + state: directory + mode: "0755" + when: tuxflotte_pers_aktiv | bool + +# Beim Start von LightDM (Neustart des Geräts) gilt die neue Konfiguration +# sofort; "-": ein fehlendes Skript hält LightDM nicht auf. +- name: Apply the login switch when LightDM starts + ansible.builtin.copy: + dest: /etc/systemd/system/lightdm.service.d/85-tuxflotte-personalisierung.conf + content: | + # Verwaltet von Tuxflotte (Rolle personalisierung) + [Service] + ExecStartPre=-/usr/local/lib/tuxflotte/personalisierung-anmeldung start + mode: "0644" + register: tuxflotte_pers_dropin + when: tuxflotte_pers_aktiv | bool + +- name: Reload systemd for the lightdm.service drop-in + ansible.builtin.systemd: + daemon_reload: true + when: (tuxflotte_pers_aktiv | bool) and tuxflotte_pers_dropin is changed + +- name: Apply the login switch now + ansible.builtin.command: /usr/local/lib/tuxflotte/personalisierung-anmeldung + register: tuxflotte_pers_anmeldung + changed_when: "'geaendert' in tuxflotte_pers_anmeldung.stdout" when: tuxflotte_pers_aktiv | bool # Kein Prozess des Kiosk-Kontos überlebt das Abmelden. Eigene Datei, nicht @@ -195,8 +249,17 @@ - /etc/systemd/logind.conf.d/50-tuxflotte-personalisierung.conf - /usr/local/lib/tuxflotte/personalisierung-sitzung - /usr/local/lib/tuxflotte/tuxflotte-kiosk.py + - /usr/local/lib/tuxflotte/personalisierung-anmeldung + - /etc/tuxflotte/personalisierung-anbieten + - /etc/systemd/system/lightdm.service.d/85-tuxflotte-personalisierung.conf + register: tuxflotte_pers_entfernt when: tuxflotte_state == "absent" +- name: Reload systemd after removing the drop-in (Auftrag abgewählt) + ansible.builtin.systemd: + daemon_reload: true + when: tuxflotte_state == "absent" and tuxflotte_pers_entfernt is changed + - name: Read the personalisierung account (Auftrag abgewählt) ansible.builtin.getent: database: passwd