Externe Authentifizierung des Benutzers innerhalb einer PAM-Sitzung/einer PAM-Sitzung innerhalb einer PAM-Sitzung

Externe Authentifizierung des Benutzers innerhalb einer PAM-Sitzung/einer PAM-Sitzung innerhalb einer PAM-Sitzung

Gibt es eine Möglichkeit, einen Benutzer innerhalb einer benutzerdefinierten PAM-Sitzung ordnungsgemäß zu authentifizieren?

Ich schreibe gerade mein eigenes PAM-Authentifizierungsmodul, das es dem Benutzer ermöglicht, sich über ein externes Token anzumelden. Dieses Token muss generiert werden, bevor sich der Benutzer mit meinem Modul anmelden kann. Daher möchte ich auf die Standard-PAM-Authentifizierung zurückgreifen, wenn kein Token vorhanden ist, und mit meinem Code fortfahren, sobald der Benutzer authentifiziert ist.

Ist das irgendwie möglich? Im Pseudocode sieht mein Modul so aus:

pam_sm_authenticate() {
  if (first_login) {
    code_copied_from_pam_unix_to_authenticate_user();
    // do something else here?
  } else {
    custom_auth();
  }
}

Als schnelle Lösung habe ich den Code aus dem pam_unix-Modul von Linux in mein eigenes kopiert und es funktioniert. Dies ist jedoch nicht sehr zufriedenstellend, da es viele zusätzliche Bibliotheken erfordert und außerdem nur funktioniert, solange sich pam_unix nicht ändert. Ich würde lieber eine weitere PAM-Sitzung innerhalb meiner Sitzung öffnen, habe es aber nicht zum Laufen gebracht.

Antwort1

Überlassen Sie nicht die gesamte Logik Ihrem Code: Verwenden Sie zuerst PAM und seine Konfiguration, um sicherzustellen, dass Ihr Modul unter den besten Bedingungen ausgeführt wird (d. h. kein Kopieren pam_unixdes Codes erforderlich ist).

Lassen Sie mich zunächst einen anderen Pseudocode für Ihr Modul vorschlagen:

pam_sm_authenticate() {
    if (first_login) return PAM_CRED_INSUFFICIENT;
    else custom_auth();
}

Hier betrachte ichErster Loginein Fall von unzureichenden Anmeldeinformationen zu sein. Ich sage PAM, dass das Modul ausfällt, weil es nicht alles hat, was es braucht, um den Benutzer vollständig zu authentifizieren. Angenommen, Ihr Modul heißt my_module, wäre eine mögliche Konfiguration:

auth [cred_insufficient=ok success=done default=2] my_module.so
auth [success=ok default=1]      pam_unix.so
auth sufficient                  my_module.so
auth requisite                   pam_deny.so

Hier sind die Details:

  • Zunächst geht die Anfrage durch my_module. Hier gibt es mehrere Möglichkeiten:

    1. Erster Login: Ihr Modul hat zurückgegeben PAM_CRED_INSUFFICIENT. Dieser Fall isterwischtvon PAM (über cred_insufficient). In diesem Fall wird die Kette als erfolgreich markiert ( ok), aberweitermachen.
    2. Dies war nicht die erste Anmeldung, Sie haben sie durchgeführt custom_auth()und sie war erfolgreich (es wurde zurückgegeben PAM_SUCCESS). In diesem Fall beenden wir die Kette ( done) :Zugriff gewährt.
    3. Dies war nicht die erste Anmeldung und custom_auth()endete nicht gut ( PAM_AUTH_ERRoder andere Arten von internen Fehlern). Überspringen Sie in diesem Fall die nächsten beiden Zeilen ( default=2). Die Kette geht direkt in pam_deny, was immer fehlschlägt:Zugriff abgelehnt.
  • Im ersten Szenario geht die Kette weiter bis pam_unix. Hier gibt es zwei Möglichkeiten:

    1. Die UNIX-Authentifizierung ist erfolgreich. Dies kennzeichnet die Kette als erfolgreich ( ok) undgeht weiter zum nächsten Modul.
    2. Die UNIX-Authentifizierung schlägt fehl. Das nächste Modul wird übersprungen ( default=1) und die Kette endet mit pam_deny:Zugriff abgelehnt.
  • Wenn Sie die dritte Zeile erreichen, bedeutet dies, dass dies my_modulebeim ersten Mal beendet wurde PAM_CRED_INSUFFICIENTund pam_unixerfolgreich war. Ihr Modul wird erneut ( // do something else here?) als aufgerufen sufficient. Wieder zwei Möglichkeiten:

    1. Dieses Mal ist Ihr Modul erfolgreich:Zugriff gewährt.
    2. Das Modul schlägt erneut fehl, allerdings aus einem anderen Grund als unzureichenden Anmeldeinformationen:Zugriff abgelehnt.

Möglicherweise möchten Sie auch benutzerdefinierten Code ausführennach UNIX-Authentifizierung, auch wenn es fehlgeschlagen ist. Ändern Sie dazu die zweite Zeile wie folgt:

auth [success=ok default=bad]    pam_unix.so

my_moduleDadurch wird die Kette auf jeden Fall noch einmal durchlaufen , aber die Kette wird markiert alsfehlgeschlagenAuch wenn Ihr Modul hier erfolgreich ist, schlägt die Kette fehl.

Sie möchten Ihrem Modul vielleicht auch mitteilen, wie oft wir es in einer Kette aufgerufen haben: Unterscheiden Sie den ersten Aufruf my_modulevom zweiten. Dies lässt sich ganz einfach mit Argumenten erreichen:

auth [cred_insufficient=ok success=done default=2] my_module.so
auth [success=ok default=1]      pam_unix.so
auth sufficient                  my_module.so second_time
auth requisite                   pam_deny.so

Hier pam_sm_authenticatewird dem zweiten Aufruf von ein Argument (durch argvund argc) übergeben, das Ihnen helfen sollteLokalisierenIhr Modul in der Kette zur Laufzeit. Natürlich firstLoginsollte Ihre Bedingung ausreichen, um eine solche Unterscheidung zu treffen.

verwandte Informationen