turns out calling getpw{nam,uid} recursively is not such a great idea… we need a fixed path (solution 1) or global state (solution 2, although we cannot do away with a fixed path by numeric uid totally) after all /var/ - lib/ - nss-pam-oidc/ - by-uid/ - 0 inode 555 - FFF inode 556 - 1000 inode 557 - by-name/ - root inode 555 root:root 0600 - foo inode 556 foo:root 0600 - bar inode 557 bar:root 0600 1. Loginversuch 2. PAM-Modul wird geladen 3. PAM-Modul macht HTTP-Request, bekommt erfolgreiche Antwort 4. PAM-Modul legt /var/lib/nss-pam-oidc/by-name/%s an… open(path, O_RDWR|O_CREAT|O_TRUNC, 0600) … schreibt das Token rein. 5. PAM-Modul macht setenv("NSS_PAM_OIDC_OVERRIDE", "/var/lib/nss-pam-oidc/by-name/%s"); 6. PAM-Modul macht getpwnam() 7a. NSS-Modul ist nicht im Einsatz, UID wird zurückgegeben 7b. NSS-Modul ist im Einsatz .1. NSS-Modul wird im PAM-Kontext aufgerufen, läuft also als root .2. Die Variable NSS_PAM_OIDC_OVERRIDE ist gesetzt, also nimmt er das Token aus jener Datei (die zu dem Zeitpunkt noch root gehört) (falls sie existiert, ansonsten das Systemtoken) .3. NSS-Modul macht Request/Auflösung/usw. mit dem Token aus 7b.2 .4. NSS-Modul gibt UID (bzw. struct passwd) zurück 8. PAM-Modul macht link("/var/lib/nss-pam-oidc/by-name/%s", "/var/lib/nss-pam-oidc/by-uid/%X") 9. PAM-Modul macht chown("/var/lib/nss-pam-oidc/by-name/%s", numerische uid) 10. User ist eingeloggt, System läuft jetzt als User 11. User macht NSS-Aufruf (wir ignorieren mal Fall Modul wird nicht verwendet) 12. NSS-Modul läuft also als User 13. NSS_PAM_OIDC_OVERRIDE ist nicht gesetzt, also wir das Token von "/var/lib/nss-pam-oidc/by-uid/%X" geladen (oder halt System) 14. usw. etc. usf. pp. Experiment (muß man sehen, ob der State vom NSS-Teil gelesen werden kann): 1. Loginversuch 2. PAM-Modul wird geladen 3. pam_authenticate startet 4. PAM-Modul macht HTTP-Request, bekommt erfolgreiche Antwort 5. Token wird in globalen State der Library gelegt und dort ein Flag auf 1 gesetzt 6. PAM-Modul macht getpwnam() 7a. NSS-Modul ist nicht im Einsatz, UID wird zurückgegeben 7b. NSS-Modul ist im Einsatz .1. NSS-Modul wird im PAM-Kontext aufgerufen, läuft also als root .2. Das Flag ist gesetzt, also wird das Token aus dem globalen State gelesen .3. NSS-Modul macht Request/Auflösung/usw. mit dem Token aus 7b.2 .4. NSS-Modul gibt UID (bzw. struct passwd) zurück 8. PAM-Modul merkt sich UID aus Schritt 7 im globalen State 9. pam_authenticate zuende 10. pam_session startet (hier ist z.B. ecryptfs bereits geladen und ~ verfügbar) 11. PAM-Modul droppt temporär die Privilegien 12. PAM-Modul legt Token ins Homeverzeichnis 13. PAM-Modul wird wieder root 14. PAM-Modul legt "/var/lib/nss-pam-oidc/%X" als Symlink auf die Datei im User-Home an 15. pam_session endet 16. User ist eingeloggt, System läuft jetzt als User 17. User macht NSS-Aufruf (wir ignorieren mal Fall Modul wird nicht verwendet) 18. NSS-Modul läuft also als User 19. NSS-Modul lädt Token von "/var/lib/nss-pam-oidc/%X" 20. usw. etc. usf. pp. Berechtigungen: /var/lib/nss-pam-oidc (dir) user=root group=root mode=0711 /var/lib/nss-pam-oidc/* (file) user=* group=root mode=0600 Stücke an globalem State, die vorzuhalten sind: • Tokenpuffer, uninitialisiert ‣ gesetzt durch pam_authenticate ‣ genutzt durch NSS gdw Flag=1 (zum Holen der UID) ‣ genutzt durch pam_session (zum Schreiben ins Home) • Flag „Tokenpuffer gültig?“, auf 0 initialisiert ‣ gesetzt durch PAM auf 1, nachdem Tokenpuffer gesetzt wurde ‣ genutzt durch NSS (siehe oben) • struct passwd-Inhalt für den User, uninitialisiert ‣ gesetzt durch pam_authenticate ‣ genutzt durch pam_session (zum Schreiben ins Home und nach /var/lib/…)