LDAP-Passwörter mit PHP ändern

Wie kann ich denn mein Passwort ändern? Diese Frage kennen wohl die meisten Linux-Admins zur Genüge. Oft haben sie aber keine Antwort parat, mit der auch unerfahrene Benutzer etwas anfangen können – SSH und Kommandozeile sind nunmal nicht jedermanns Sache. Ich möchte deshalb ein paar Tipps geben, die helfen sollen, ein Webinterface zum Ändern des Passwortes zu bauen.

Leider gibt es keine fertige Lösung, die man nur noch mit eigenem CSS anpassen muss und auch dieser Blogeintrag liefert so etwas nicht. Die erste Suche bei Google führt zu logout.sh: Hier werden aber leider nur die grundlegenden Schritte skizziert. Aber wie schön ein paar mal erwähnt: Geht nicht, gibts bei uns nicht. Notfalls muss man das halt selbst programmieren…

LDAP

Zuerst muss sichergestellt werden, dass die LDAP-Zugriffsberechtigungen für die Attribute richtig gesetzt sind. Damit es fürs Blog nicht zu breit wird, habe ich es in zwei Teile geteilt.

access to attrs=userPassword,sambaNTPassword,sambaLMPassword
        by self write
        by anonymous auth
        by * none

und

access to attrs=sambaPwdMustChange,sambaPwdLastSet
        by self write
        by anonymous auth
        by * none

Zusätzlich sollten die Parameter, die zur Passwort-Alterung nötig sind, mit passenden Zugriffsrechten ausgestattet sein. Das sollte per Default passen, hier nur nochmal zur Sicherheit:

access to attrs=shadowLastChange,shadowMax
        by self write
        by * read

Unix Passwort ändern

Prinzipiell funktioniert dann das Ändern des Unix-Passworts so:

function change_posix_pwd($conn, $uid, $pwd) {
   $hash_pass = "{MD5}" . base64_encode(pack( "H*", md5($pwd)));
   $last_change = (int)(time()/86400);
   return ldap_mod_replace(
      $conn, 
      "uid=" . $uid . ",ou=people,dc=xxx,dc=xxx", 
      array("userPassword" => $hash_pass, "shadowLastChange" => $last_change)
   );
}

Die Details, wie man mit PHP auf einen LDAP-Server zugreift, lasse ich hier mal aus. Die API-Funktionen sind auf der PHP-Webseite beschrieben. Ein gutes Tutorial gibt es auch bei wikibooks.

Nur eines: baut man eine Verbindung zu einem OpenLDAP-Server auf, wird das immer klappen – auch wenn man den falschen Hostnamen verwendet hat. Ob es wirklich geklappt hat, sieht man an einem anonymen Bind:

ldap_set_option ($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);		
if (!@ldap_bind($ldapconn)) {
   die("Kein Zugriff auf den LDAP-Server");
}

Im Codeschnipsel sieht man auch gleich, wie man die LDAP-Version für die Verbindung passend setzen kann. Die gewünschte Version ist letztendlich abhängig von der Konfiguration.

Kommen weitergehende Features, wie z.B. Passwörter mit Ablaufdatum ins Spiel, kann ich nur die Lektüre von/usr/sbin/smbldap-passwd und dem zugehörigen Perl Modul (/usr/share/perl5/smbldap_tools.pm) empfehlen. Nachdem ich diese Funktionen momentan nicht verwende, kann meine Lösung damit im Moment auch nicht umgehen. Auch mit anderen Hashfunktionen als MD5 für die Passwörter kann meine momentane Lösung nicht umgehen.

Windows Passwörter ändern

Windows kocht bei der Hashfunktion für die Passwörter ein vollkommen eigenes Süppchen. Es gibt in der PHP API auch keine passende Hashfunktion. Auch das von den smbldap-tools verwendete Perl-Paket Crypt::SmbHash gibt es nicht für PHP. Glücklicherweise gibt es aber bereits einen Port von Roland Gruber, so dass einem diese unangenehme Aufgabe erspart bleibt.

Damit kann man auch die entsprechenden Felder im LDAP ändern:

include_once("class.smbhash.inc.php");

function change_samba_pwd($conn, $uid, $pwd) {
   $clazz = new smbHash();
   $lmhash = $clazz->lmhash($pwd);
   $nthash = $clazz->nthash($pwd);
   $time = time();
		
   return ldap_mod_replace(
      $conn, 
      "uid=" . $uid . ",ou=people,dc=xxx,dc=xxx", 
      array(
         "sambaLMPassword" => $lmhash, 
         "sambaNTPassword" => $nthash, 
         "sambaPwdLastSet" => $time
      )
   );
}

Auch hier verwende ich die erweiterten Features, wie Passwörter, die vom Benutzer beim ersten Einloggen geändert werden müssen, nicht. Der Quellcode von smbldap-passwd hilft auch bei diesem Problem weiter.

Fazit

Eine Seite zum Ändern der Passwörter ist in PHP mit 300 Zeilen Code leicht erstellt. Meine PHP-Kenntnisse haben leider nur zu grausamen aussehenden Code gereicht, daher gibt es das hier auch nicht zum Download. Aber selbst als Laie konnte ich das mit der nötigen Recherche an einem Vormittag realisieren.

Meine Lösung verwendet das gleiche Rapidweaver-Template wie meine Intranet-Seite. Das Ergebnis sieht nicht nur schick aus, sondern funktioniert auch bei weniger erfahrenen Benutzern problemlos.

2 Gedanken zu „LDAP-Passwörter mit PHP ändern“

  1. Wäre es nicht fast besser, das Passwort-ändern von PAM erledigen zu lassen? Dann muss man nur ein System pflegen – falls mal ein Kerberos dazu kommt o.ä.. Ausserdem kann man so problemlos (und Administrator-freundlich ;-)) sowohl über die Webseite als auch über SSH das Passwort ändern.

  2. Gute Frage. PAM ist für mich immer noch ein Buch mit sieben Siegeln. Vermutlich würde es sich lohnen, sich mal ausführlich damit zu beschäftigen.

    Über SSH ändere ich das Passwort mit smbldap-passwd.

Kommentare sind geschlossen.