kurze Einführung in LDAP

Bearbeiten

LDAP ist eine Abkürzung für   Lightweight Directory Access Protocol, was soviel heisst wie "Leichtgewicht Verzeichnis-Zugriffs-Protokol". Also ist LDAP eigentlich nur das Protokol um auf das "Leichtgewicht Verzeichnis" zuzugreiffen.

Ein Verzeichnisdienst ähnelt in seiner Funktionsweise zwar einer Datenbank, unterscheidet sich aber von traditionellen relationalen Datenbanken in folgenden Punkten:

  • Ein Directory ist mehr auf das Finden und Auslesen von Informationen spezialisiert als auf das Schreiben immer neuer Informationen.

Suchfilter

Bearbeiten

Eine LDAP-DB arbeitet nicht wie eine relationale Datenbank anhand von SQL-Statements sondern anhand von Suchfiltern.

Das Format ist allgemein im RFC 1960 definiert. Hier führen wir dich aber kurz in die wichtigsten Ausdrücke.

Hier die Grundsätzlichen Filter:

Exakter Wert Format Beispiel Resultate
Exakter Wert (<attr>=<wert>) (sn=Muster) Alle Personen mit dem Nachnamen Muster
ungefährer Wert (<attr>~=<wert>) (givenname~=Pascal) Alle Person mit einem Vornamen,
welcher einen ähnlichen Ton hat wie Pascal
(Achtung: Dies ist Server Abhängig)
Teilzeichenkette (<attr>=[<begin>]*[<text>]*[<ende>]) (sn=*ust*) Alle Personen, welche im Nachnamen die Sequenz ust enthält.
Grösser gleich (<attr>>=<wert>) (sn>=Muster) Alle Nachname welche im Lexikon an derselben Stelle wie Muster und nach Muster auftritt.
Kleiner gleich (<attr><=<wert>) (sn<=Muster) Alle Nachname welche im Lexikon an derselben Stelle wie Muster und vor Muster auftritt.
Vorhanden (<attr>=*) (sn=*) Alle Einträge mit Nachnamen.

Die Basic-Filter können in jeder beliebigen Form kombiniert werden, wie man in der folgenden Tabelle sehen kann:

Exakter Wert Format Beispiel Resultate
UND (&(<filter1>)(<filter2>)...) (&(givenname=Hans)(sn=Muster)) Einträge mit dem Vornamen Hans UND dem Nachnamen Muster
ODER (|(<filter1>)(<filter2>)...) (|(givenname=Hans)(sn=Muster)) Einträge mit dem Vornamen Hans ODER dem Nachnamen Muster
NICHT (!(<filter1>)) (!(mail=*)) Einträge ohne eine Mail-Attribut

So nun kennst du alle Grundlagen um deine eigenen Suchfilter zu schreiben, bedenke aber, dass du nur Attribute, welche der Server kennt nutzts, denn ansonsten kann dies die Suche erheblich verlangsamen.

OpenLDAP installieren

Bearbeiten

Um OpenLDAP auf einem Linux Computer zu installieren siehe Linux-Kompendium: Lightweight Directory Access Protocol

Siehe http://lucas.bergmans.us/hacks/openldap/

LDAP mit PHP

Bearbeiten

Es gibt eine vielzahl an Funktion, um auf eine LDAP-Datenbank zu kommunizieren. Hier werden nur die meistgebräuchlisten erklärt:

  • ldap_connect ([string hostname[, int port]]) - Stellt die Verbindung zu einem LDAP-DB-Server her.
  • ldap_bind(resource link_identifier[, string bind_rdn[, string bind_password]]) - Logged sich beim Server ein, wobei die eigentlichen Userdaten optional sind. Standardmässig wird man als anonymous eingelogged.
  • ldap_search(resource link_identifier, string base_dn, string filter[, array attributes[, int attrsonly[, int sizelimit[, int timelimit[, int deref]]]]]) - Started eine Suche in dem vorgegebenen Namespace und mit dem angegebenen Suchfilter.
  • ldap_get_entries(resource link_identifier, resource result_identifier) - Wandelt die Suchresultate in ein Array um.
  • ldap_error(resource link_identifier) - Hollt eine Fehlerbeschreibung, des zuletzt aufgetrettenen Fehlers.
  • ldap_delete(resource link_identifier, string dn) - Löscht einen Eintrag des Verzeichnises.
  • ldap_rename(resource link_identifier, string dn, string newrdn, string newparent, bool deleteoldrdn) - Ändert den Namen eines Eintrages.
  • ldap_add(resource link_identifier, string dn, array entry) - Fügt einen Eintrag hinzu.
  • ldap_modify(resource link_identifier, string dn, array entry) - Ändert Werte eines Eintrages.
  • ldap_unbind(resource link_identifier) oder ldap_close(resource link_identifier) - Schliesst die Verbindung mit dem LDAP-Server.

DB Zugriffe

Bearbeiten

Verzeichnislein, Verzeichislein an der Wand wo wohnt cn=Hans Muster;ou=contacts,o=master,c=ch im kleinen Land ?!?

Nun diese Frage kann ein kleiner LDAP-Zugriff beantworten und dies sogar sehr schnell, auch wenn es mehrere 10000 Einträge gibt.

Mit Server Verbinden

Bearbeiten

Aber zuerst müssen wir auf die Datenbank verbinden (und falls nötig uns authentisieren, damit wir aus der DB lesen können):

 //''ldap.master.org'' ist der DNS-Name des LDAP-Servers
 $ldapconn = $ldap_connect("ldap.master.org") or die("Could not connect to $ldaphost");
 //''username'' und ''passwort'' sind optional, default ist anonymous-login
 if (ldap_bind($ldapconn, "username", "passwort")) {
   echo "Die Verbindung zu ldap.master.org war erfolgreich";
 }

Der Verbindungsaufbau wird in den weiteren Beispielen nicht weiter geschrieben, um Platz zu sparen,

Nun da wir mit dem Server verbunden sind, können wir den Server unsere Frage stellen:

/*
 * $ldapconn ist die Verbindung zum LDAP-Server vom ersten Beispiel
 */

$results = ldap_search($ldapconn, "ou=contacts,o=master,c=ch", "cn=Hans Muster");
/* Wie der Filter (letztes Argument) aufgebaut ist, siehe hier
 * 
 * Die optionalen Argument sind:
 * attributes - Nur diese Attribute sollen zurückgegeben werden z.B. array("cn", "givenname", "sn")
 * attrsonly - 1 für nur die Attributtypen, 0 (default) 
 * sizelimit - Die maximale Anzahl an Einträge, welche zurückgegeben werden sollen.
 * timelimit - Die maximale Zeit, welch für die suche genutzt werden darf.
 * deref - bestimmt wie aliase behandelt werden sollen, bei dieser Suche
 *  -LDAP_DEREF_NEVER - (default) Aliase werden nie aufgelöst. Mögliche Werte:
 *  -LDAP_DEREF_SEARCHING - Aliase sollen während der Suche aufgelöst werden, aber nicht dann, wenn das Basisobjekt der Suche ermittelt wird.
 *  -LDAP_DEREF_FINDING - Aliase sollen aufgelöst werden, wenn das Basisobjekt ermiitelt wird, aber nicht während der Suche.
 *  -LDAP_DEREF_ALWAYS - Aliase sollen immer aufgelöst werden. 
 */

// und nun die gefundenen Einträge verarbeiten
$entries = ldap_get_entries($ldapconn, $results);
echo "Es wurden ".$entries["count"]." Einträge gefunden";
if ($res != false) {
  foreach($entries as $entry) {
    //Gibt den Eindeutigen Bezeichner (CommonName) des Eintrags aus.
    echo $entry["cn"][0]." (".$entry["cn"]["count"].")<br>\n";
  }
}

Neuer Eintrag

Bearbeiten

Du hast einen hübschen Typen/eine schöne Frau kennen gelernt und möchstes diese Person (Axel Muster) nun auch in deiner Datenbank speichern. Nach dem Verbinden zur Datenbank aufgebaut hast, muss nur eine einzelne Methode aufgerufen werden:

 ldap_add($ldapconn, "cn=Axel Muster,ou=contacts,o=master,c=ch", 
   array(
     "cn" => array("Axel Muster"), //CommonName
     "givenname" => array("Axel"), //Vorname
     "sn" => array("Muster"), //Nachname (SurName)
     "objectclass" => array("pabPerson", "inetOrgPerson", "organizationalPerson", "person", "top"), //Eintrag typen
     "telephonenumber" => array("784'351'92'34"), //Telefonnummer
     "mobile" => array())); //Handy-Nummer

Umbenennen

Bearbeiten

Eine gute Kollegin (Nadine Schindel) hat nun geheirate und übernimmt den Namen ihres Ehemannes (Fabian Wickihalder), nun möchtest du diesen Eintrag auch in deiner Datenbank aktualisieren:

 ldap_rename($ldapconn, 
   "cn=Nadine Schindel,ou=contacts,o=master,c=ch", //Der alte Eintrag, welche gemoved/umbenannt werden soll.
   "cn=Nadine Wickihalder,ou=contacts,o=master,c=ch", //Der neue Name des alten Eintrags
   "ou=contacts,o=master,c=ch", //Daher wir diesen Eintrag nicht in einen anderen Namespace verschieben, bleibt dies gleich
   true); //Der alte Eintrag soll gelöscht werden (false, wäre beibehalten)

Aktualisieren

Bearbeiten

Jemand (Hans Muster) hat seine Natel-Nummer geändert und nun werden wir diese kleine Information nachtragen

 ldap_modify($ldapconn, "cn=Hans Muster;ou=contacts,o=master,c=ch", array("mobile" => array("435'245'45'56")))

Löschen

Bearbeiten

Ein schlimmer Streit ist zwischen dir und einem Kollegen vorgekommen und du willst nichts mehr von dieser Person wissen, also löschst du seinen Eintrag (cn=Hans Muster;ou=contacts,o=master,c=ch)

 ldap_delete($ldapconn, "cn=Hans Muster;ou=contacts,o=master,c=ch")

Specials

Bearbeiten

phpLDAPAdmin

Bearbeiten

phpLDAPAdmin ist das LDAP-Equivalent zu phpMyAdmin, welches aber für Mysql-Datenbanken geschrieben wurde. Die Benuzter oberfläche ist gut organisiert, sodass keine weiter Ausführung nötig ist.

Installation

  1. Die php-sources von sourceforge herunger laden (http://phpldapadmin.sourceforge.net/download.php)
  2. .tar.gz bzw. .zip File entpacken
  3. Das Entpackte in einen Ordner verschieben, welcher durch den Webserver zugreifbar ist (Oft htdocs oder bei MacOSX Sites)
  4. LDAP-Server-Zugriff konfigurieren
  5. FERTIG

Konfiguration

Hier eine kleine Hilfestellung wie man das LDAP-Tool phpLDAPAdmin konfiguriert.

TODO: Konfiguration beschreiben

Bilder in der LDAP-DB

Bearbeiten

In diesem kleinen Special behandeln wir, welche Bedingungen erfüllt werden müssen um ein Bild in der Datenbank speichern zu können und wie man solch ein Bild wieder ausliest.

Da du denkst eine LDAP-DB ist genau das was du brauchst, um die Mitglieder deines Vereins zu verwalten, hast du eine Directory erstellt. Hier hast du die Möglichkeit, um die Daten in deiner Datenbank noch zu erweitern: Speichere ein Bild z.B. von den wichtigsten Personen deines Vereins in die DB. Dies ist ganz einfach:

Die Bedingungen

Die Attribute, in welchen man ein Bild speichern könnte, muss mit der ldapSyntax Binary (1.3.6.1.4.1.1466.115.121.1.5) bezeichnet sein.

Das einfachste ist aber, wenn man das Attribut jpegPhoto von einen der Objekt-Klassen document, inetOrgPerson, pabPerson, pilotObject benutzt.

Bild speichern

/*
 * $dn repräsentiert die DN worin das Bild gespeichert werden kann.
 * $data repräsentieren die JPG-Daten, welche z.B. mit fread aus einem File gelesen wurden.
 */

 $ldapconn = $ldap_connect("ldap.master.org");
 if ($ldapconn && $ldap_bind($ldapconn, "username", "passwort")) { //username und passwort sind optional
  $res = ldap_modify($ldapconn, $dn, array("jpegPhoto" => $data));
  if (!$res) {
   echo "Fehler beim speichern des Bildes: ".ldap_error();
  } else {
   echo "Bild erfolgreich in $dn gespeichert.";
  }
 }

Bild auslesen

/*
 * Zur DB Verbinden...
 * $dn repräsentiert die DN des Eintrages
 */

$ldapconn = ldap_connect("ldap.master.org");
if ($ldapconn && ldap_bind($ldapconn, "username", "passwort")) { //username und passwort sind optional
 $search_result = ldap_read($ldapconn, $dn, 'objectClass=*');
 $entry = ldap_first_entry($ldapconn, $search_result);
 $entry = ldap_get_values_len($ldapconn, $entry, "jpegPhoto");
 $jpeg_data = $entry[0];
}