LDAP-Server
DirectoryHub stellt das zusammengeführte Meta-Verzeichnis als eingebetteten, ausschließlich lesenden LDAP-Server (LDAPv3, optional LDAPv2) bereit. Konsumenten sind Tischtelefone mit LDAP-Telefonbuch, Fachanwendungen mit Verzeichnisanbindung, eine zweite STARFACE-Anlage — und jeder LDAP-Client, der bislang ein estos MetaDirectory abgefragt hat: Baumsemantik, Bind-Verfahren und Suchverhalten sind auf diese Ablösung ausgelegt.
Diese Schnittstelle ist für die Nutzung durch Drittsysteme freigegeben. Änderungen und Erweiterungen werden je Version in den Release Notes dokumentiert.
Grundlagen
- Typ: LDAP (RFC 4511) über TCP — zwei getrennt aktivierbare Zugänge: unverschlüsselt mit StartTLS-Unterstützung sowie durchgehend verschlüsselt (LDAPS). Nach der Installation sind beide Zugänge deaktiviert.
- Endpunkte: Port 389 (Standard, unverschlüsselt/StartTLS) und Port 636 (Standard, LDAPS); beide Ports sind in der Modulkonfiguration änderbar (Tab , siehe Konfiguration).
- Protokollversionen: LDAPv3; LDAPv2 zusätzlich, sofern die Option LDAPv2 erlauben aktiv ist (Standard: aktiv).
- Authentifizierung: Simple Bind gegen lokale Konten, Active Directory oder STARFACE-Benutzer; anonymer Bind zulässig (Sichtbarkeit dann nur auf öffentliche Baumknoten). SASL-Mechanismen werden nicht unterstützt.
- Betriebsart: strikt read-only — Add, Modify, Delete und ModifyDN werden mit
Result-Code
53(unwillingToPerform, „read-only directory") abgelehnt. Die Datenpflege bleibt in den Quellsystemen. - Absicherung: STARFACE-Firewall-Freigaben je Quellnetz (ohne Freigabe nur Localhost-Zugriff), zusätzlich Zugriffsprofile und IP-Regeln je Baumknoten (siehe unten).
- Editionen: In der Small Business Edition steht der LDAP-Server ausschließlich der Anlage selbst zur Verfügung (Firewall-Freigaben werden abgelehnt); externe Konsumenten, Zugriffsprofile und der frei gestaltbare Baum sind ab Professional verfügbar.
Ports unterhalb 1024 kann der Moduldienst nicht direkt binden. Bei konfigurierten Standardports lauscht der Server intern auf dem konfigurierten Port + 1000 (389 → 1389, 636 → 1636); das Modul richtet automatisch eine NAT-Weiterleitung für die freigegebenen Quellnetze ein. Externe Clients verwenden den konfigurierten Port. Lokale Verbindungen auf der Anlage selbst (z. B. das STARFACE-Adressbuch) sprechen den internen Bind-Port direkt an; die Statusanzeige des Tabs nennt beide Ports.
Verbindung & TLS
| Zugang | Standard-Port | Verschlüsselung |
|---|---|---|
| LDAP | 389 | optional per StartTLS (Extended Operation 1.3.6.1.4.1.1466.20037) |
| LDAPS | 636 | TLS ab Verbindungsaufbau |
Das TLS-Schlüsselmaterial bezieht DirectoryHub direkt aus dem Zertifikatsspeicher der
STARFACE (Webserver-Zertifikat, KeyStore-Alias tomcat) — es gilt also dasselbe
Zertifikat wie für die STARFACE-Weboberfläche, ein separates Zertifikatsmanagement
entfällt. Steht für StartTLS kein Schlüsselmaterial bereit, startet der unverschlüsselte
Zugang trotzdem, nur ohne StartTLS-Angebot.
Anmeldung (Bind)
Der Server akzeptiert ausschließlich Simple Binds. Ein Bind mit leerem DN und leerem
Passwort ist ein anonymer Bind (RFC 4513); er wird angenommen, die Verbindung sieht danach
nur öffentliche Knoten. Andere Authentisierungsmethoden beantwortet der Server mit
Result-Code 7 (authMethodNotSupported).
Der Bind-DN bestimmt, gegen welche Identitätsquellen geprüft wird. Lokale Konten werden immer zuerst geprüft (schnell, ohne Netzzugriff); danach das aus der DN-Form abgeleitete Backend, zuletzt die übrigen:
| Backend | Bind-Identität | Prüfung | Zugriffsprofile |
|---|---|---|---|
| Lokale Konten | uid=<benutzername> oder nur <benutzername> (auch cn=<benutzername>) | PBKDF2-Passwort-Hash im Modul, zeitkonstanter Vergleich | direkt am Konto hinterlegt |
| Active Directory | sAMAccountName, userPrincipalName oder vollständiger DN (Formen mit dc=…/cn=… werden bevorzugt gegen AD geprüft) | Suche über das in der STARFACE konfigurierte AD-Servicekonto, danach zweiter Simple Bind mit dem gefundenen Benutzer-DN | über Gruppen-Zuordnungen (AD-Gruppen-DN aus memberOf) |
| STARFACE-Benutzer | Login-ID des Anlagenbenutzers | Verifikation gegen die interne STARFACE-Benutzerverwaltung (OAuth-Passwort-Grant, Realm pbx, Client pbx-gui) | über Gruppen-Zuordnungen (STARFACE-Gruppen-ID) sowie die dem automatisch angelegten Benutzerkonto zugewiesenen Profile |
Für die AD-Anmeldung nutzt DirectoryHub die vorhandene Active-Directory-Konfiguration der
STARFACE; ist dort kein AD aktiv, schlägt dieser Pfad fehl. Alle Backends sind
fail-closed und nicht enumerierbar: „Benutzer unbekannt" und „falsches Passwort" liefern
identisch Result-Code 49 (invalidCredentials).
In der Professional Edition sind nur Konten mit zugewiesenem Lizenzplatz aktiv — der Bind
eines nicht lizenzierten STARFACE-Benutzers wird mit 49 abgelehnt.
Benutzerindividuelle Auslieferung (estos-Impersonation)
Für das STARFACE-Adressbuch bindet die Anlage mit dem systemverwalteten Servicekonto
uid=starface und übermittelt je Suche das estos-kompatible SearchUserId-Control
(OID 1.3.6.1.4.1.10924.233.12) mit der Account-ID des anfragenden Anlagenbenutzers.
DirectoryHub löst daraus dessen persönliche Sicht auf (zugewiesene Zugriffsprofile des
delegierten Benutzerkontos). Von allen anderen Binds wird das Control ignoriert —
Fremdsysteme können darüber keine fremden Sichten anfordern. Nicht auflösbare Account-IDs
führen fail-closed zur anonymen Sicht.
Baumstruktur & Basis-DN
Der Server veröffentlicht drei Naming-Contexts:
| Naming-Context | Inhalt | Änderbar |
|---|---|---|
dc=directory (Standard; per Basis-DN konfigurierbar) | Wurzel der frei modellierten Baumknoten; Quellen werden je Knoten eingehängt | Struktur frei gestaltbar (ab Professional) |
dc=meta | Fixknoten: hier werden automatisch alle lokal laufenden Importquellen eingehängt | nein (fest) |
dc=configuration | Fixknoten: LDAP-spezifische Konfiguration und Server-Metadaten, reserviert | nein (fest, read-only) |
Die beiden Fixknoten sind eigenständige Naming-Contexts mit den bloßen DNs dc=meta und
dc=configuration; sie hängen nicht unter dem Basis-DN. Ein maschinenlesbares
LDAP-Subschema (attributeTypes/objectClasses) wird unter dc=configuration derzeit
nicht veröffentlicht.
Strukturknoten erscheinen abhängig vom RDN-Attribut:
dc=…—objectClass: top, dcObject, organizationmit den Attributendcundo,- alle übrigen (typisch
ou=…) —objectClass: top, organizationalUnitmitouund optionaldescription(Anzeigename des Knotens).
Kontakteinträge liegen direkt unter ihrem Baumknoten:
uid=<Kontakt-ID>,<Knoten-DN> z. B. uid=src-9f3a21c7::1042,dc=meta
Die Kontakt-ID ist deterministisch aus Quelle und Quell-Primärschlüssel gebildet
(<Quellen-ID>::<Primärschlüssel>, RFC-4514-konform escaped) und bleibt über Importläufe
stabil. Derselbe Kontakt kann unter mehreren Knoten erscheinen, wenn seine Quelle mehrfach
eingehängt ist.
Root DSE
Eine Base-Suche mit leerem Basis-DN liefert die Root DSE mit folgenden Attributen:
| Attribut | Wert |
|---|---|
namingContexts | Basis-DN, dc=meta, dc=configuration |
supportedLDAPVersion | 3 (zusätzlich 2, wenn LDAPv2 erlaubt ist) |
supportedExtension | 1.3.6.1.4.1.1466.20037 (StartTLS) |
supportedControl | 1.2.840.113556.1.4.473 (Server-Side Sort, RFC 2891), 2.16.840.1.113730.3.4.9 / 2.16.840.1.113730.3.4.10 (Virtual List View Request/Response) |
subschemaSubentry | dc=configuration |
vendorName | Fluxpunkt GmbH |
vendorVersion | UnboundID DirectoryHub (Fluxpunkt) |
metaVersion | installierte Modulversion (estos-MetaDirectory-Kompatibilitätskennung) |
vendorVersion beginnt bewusst mit „UnboundID": Die STARFACE erkennt daran den
Servertyp und verwendet den modernen VLV-Suchpfad. metaVersion signalisiert
estos-kompatiblen Clients die Unterstützung der benutzerindividuellen Auslieferung.
Attribut-Schema
Kontakteinträge tragen die Objektklassen top, person, organizationalPerson,
inetOrgPerson. Alle Werte werden als String-Attribute ausgeliefert; mehrere Quellfelder
mit demselben Zielattribut werden mehrwertig zusammengeführt (Duplikate entfernt).
Rufnummern liegen normalisiert im E.164-Format vor (+49…, Standardregion DE); wo kein
normalisierter Wert existiert, wird der Rohwert der Quelle ausgeliefert.
Die Attributnamen ergeben sich aus den Feldzuordnungen der Importquellen. Der mitgelieferte Zielfeld-Katalog:
| Attribut | Alias (gleicher Wert) | Feldtyp | Attributgruppe | Bedeutung |
|---|---|---|---|---|
objectClass | — | — | strukturell | top, person, organizationalPerson, inetOrgPerson |
uid | — | — | strukturell | stabile Kontakt-ID (<Quellen-ID>::<Primärschlüssel>) |
cn | — | Name | strukturell | Anzeigename des Kontakts |
givenName | gn | Name | public | Vorname |
sn | surname | Name | public | Nachname |
o | company | Sonstiges | public | Organisation/Firma |
title | — | Sonstiges | internal | Position/Titel |
mail | email | Sonstiges | public | E-Mail-Adresse |
street | streetAddress | Adresse | internal | Straße |
postalCode | — | Adresse | internal | Postleitzahl |
l | city | Adresse | internal | Ort |
st | — | Adresse | internal | Bundesland |
c | — | Adresse | internal | Land |
ou | — | Sonstiges | internal | Abteilung |
description | — | Sonstiges | internal | Beschreibung |
telephoneNumber | — | Rufnummer | public | Telefon geschäftlich (E.164) |
mobile | — | Rufnummer | public | Mobiltelefon (E.164) |
homePhone | — | Rufnummer | internal | Telefon privat (E.164) |
facsimileTelephoneNumber | — | Rufnummer | public | Fax (E.164) |
jpegPhoto | — | Sonstiges | internal | Kontaktbild, Base64-kodiert als Textattribut |
employeeNumber | — | Sonstiges | internal | Personalnummer |
Hinweise:
- Aliase: Derselbe Wert wird unter allen Schreibweisen seiner Alias-Gruppe ausgegeben
(
oundcompany,streetundstreetAddress,lundcity,snundsurname,givenNameundgn,mailundemail) — RFC-konforme wie AD-/STARFACE-übliche Client-Vorlagen finden die Daten ohne Anpassung. Attributnamen sind ohnehin case-insensitiv. - Eigene Zielfelder: Der Katalog ist eine Vorbelegung. Administratoren können in den
Feldzuordnungen beliebige weitere LDAP-Attributnamen als Zielfelder definieren; diese
erscheinen zusätzlich am Eintrag (Attributgruppe
internal). - Attributgruppen: Zugriffsprofile können die Sicht auf die Gruppe
public(Kern-Kontaktattribute, siehe Tabelle) beschränken;internalumfasst alle übrigen Attribute. Die strukturellen AttributeobjectClass,uidundcnbleiben immer sichtbar, damit Einträge referenzierbar sind. Ein Profil ohne Attributgruppen-Einschränkung liefert alle sichtbaren Attribute. - Feld-Herkunft: Jedes Feld kennt seine Quelle. Bei quellenübergreifend zusammengeführten Kontakten werden Felder aus Quellen, die der Bind nicht sehen darf, nicht ausgeliefert — und sind auch per Suchfilter nicht matchbar.
Suchoperationen & Filter
| Operation | Unterstützung |
|---|---|
| Bind | Simple Bind, anonymer Bind |
| Search | Scopes base, one, sub; Filter nach RFC 4515; Attributlisten-Projektion inkl. *, 1.1 und typesOnly |
| Compare | ja (Wertvergleich case-insensitiv) |
| StartTLS | ja (auf dem unverschlüsselten Port) |
| Add / Modify / Delete / ModifyDN | nein — Result-Code 53, „read-only directory" |
| sonstige Extended Operations | nein — Result-Code 53 |
| Controls | Server-Side Sort (RFC 2891), Virtual List View, estos SearchUserId |
Filterauswertung: strikt und fehlertolerant
DirectoryHub wertet Suchfilter zweistufig aus: Eine indexgestützte Kandidatensuche
(Namens-, Rufnummern- und uid-Terme) zieht die Treffermenge, anschließend wird jeder
Kandidat gegen den vollständigen Filter verifiziert (AND/OR/NOT, objectClass,
>=/<=, Substrings). Daraus ergeben sich zwei Verhaltensweisen:
- Exakte Filter (Equality/Presence, z. B.
(sn=Maier)oder(telephoneNumber=+49721556677)) sind strikt RFC-konform: Es wird nur geliefert, was den Filter wörtlich erfüllt. Rufnummern müssen dabei in der gespeicherten E.164-Form angegeben werden. - Wildcard-Filter (mindestens ein Substring-Anteil, z. B.
(sn=*Maier*)— die Form, die das STARFACE-Adressbuch erzeugt) liefern die Kandidaten der Suchmaschine direkt aus: zusätzlich fehlertolerante (Fuzzy), phonetische (Kölner Phonetik, „Meyer" trifft „Maier") und formatunabhängige Rufnummern-Treffer (*0721556677*findet+49721556677) — die estos-artige Suchsemantik. Zugriffsrechte gelten dabei unverändert.
Rufnummern-Terme werden für die Kandidatensuche in mehrere Varianten übersetzt (E.164,
nationale Rufnummer, reine Ziffernfolge). Als Rufnummern-Attribute gelten u. a.
telephoneNumber, mobile, facsimileTelephoneNumber, homePhone, pager, ipPhone,
otherTelephone; als Namens-/Textattribute u. a. cn, sn, givenName,
displayName, mail, o, ou, description. (uid=…)-Gleichheit ist ein direkter
Schlüsselzugriff. Syntaktisch ungültige Filter werden wie (objectClass=*) behandelt.
Paging und Sortierung
Ohne Größenangabe des Clients liefert der Server höchstens 500 Einträge je Suche; ein
niedrigeres Client-sizeLimit gilt unverändert. Wird das Limit überschritten, endet die
Suche mit Result-Code 4 (sizeLimitExceeded). Für große Bestände unterstützt der Server
Server-Side Sort + Virtual List View: Das Ergebnisfenster wird datenbankseitig
paginiert (100.000+ Einträge), das VLV-Response-Control meldet die Gesamtanzahl.
Indexgestützte Sortierschlüssel sind sn/surname, givenName/gn und o/company;
andere Sortierattribute fallen auf den Anzeigenamen zurück. Reine Strukturfilter
(z. B. (|(objectClass=organizationalUnit)(objectClass=container))) liefern nur
Baumknoten und lösen keinen Kontakt-Scan aus.
Beispiele
Root DSE abfragen (anonym):
ldapsearch -H ldap://pbx.example.de:389 -x -s base -b "" "(objectClass=*)"
dn:
objectClass: top
namingContexts: dc=directory
namingContexts: dc=meta
namingContexts: dc=configuration
supportedLDAPVersion: 2
supportedLDAPVersion: 3
supportedExtension: 1.3.6.1.4.1.1466.20037
supportedControl: 1.2.840.113556.1.4.473
supportedControl: 2.16.840.1.113730.3.4.9
supportedControl: 2.16.840.1.113730.3.4.10
subschemaSubentry: dc=configuration
vendorName: Fluxpunkt GmbH
vendorVersion: UnboundID DirectoryHub (Fluxpunkt)
metaVersion: <Modulversion>
Angemeldete Suche über StartTLS mit einem lokalen Servicekonto — exakter Filter, projiziert auf vier Attribute:
ldapsearch -H ldap://pbx.example.de:389 -ZZ -x \
-D "uid=telefonbuch-service" -w 'IhrPasswort' \
-b "dc=meta" "(sn=Maier)" cn sn telephoneNumber mail
dn: uid=src-9f3a21c7::1042,dc=meta
cn: Petra Maier
sn: Maier
telephoneNumber: +49721556677
mail: p.maier@example.de
Dieselbe Suche als Wildcard-Filter — jetzt mit phonetischen und formatunabhängigen Treffern:
ldapsearch -H ldap://pbx.example.de:389 -ZZ -x \
-D "uid=telefonbuch-service" -w 'IhrPasswort' \
-b "dc=meta" "(|(sn=*Maier*)(telephoneNumber=*0721556677*))" cn sn telephoneNumber
dn: uid=src-9f3a21c7::1042,dc=meta
cn: Petra Maier
sn: Maier
telephoneNumber: +49721556677
dn: uid=src-9f3a21c7::2210,dc=meta
cn: Thomas Meyer
sn: Meyer
telephoneNumber: +49721448899
Anonymes Lesen eines öffentlichen Telefonbuch-Knotens über LDAPS — vollständiger Eintrag mit Alias-Attributen:
ldapsearch -H ldaps://pbx.example.de:636 -x \
-b "ou=telefonbuch,dc=directory" -s one "(objectClass=inetOrgPerson)"
dn: uid=src-4c11e0b2::2001,ou=telefonbuch,dc=directory
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
uid: src-4c11e0b2::2001
cn: Max Beispiel
givenName: Max
gn: Max
sn: Beispiel
surname: Beispiel
o: Beispiel GmbH
company: Beispiel GmbH
telephoneNumber: +49721998877
mobile: +491701234567
mail: m.beispiel@example.de
email: m.beispiel@example.de
Ein Systemhaus löst ein estos MetaDirectory ab: Die vorhandenen Tischtelefone behalten ihre LDAP-Telefonbuch-Vorlage (Server, Port 389, anonymer Bind auf den Telefonbuch-Knoten) und zeigen nach dem Umschwenken auf die STARFACE-Adresse unverändert Namen und Rufnummern — jetzt gespeist aus CRM, Microsoft 365 und Odoo statt aus einem eigenen Verzeichnis-Server.
Zugriffsprofile & IP-Regeln
Die Sichtbarkeit jeder Antwort berechnet sich aus vier Achsen — Bind-Identität, Zugriffsprofile, Feld-Herkunft (Quelle) und Client-IP:
- Zugriffsprofile sind benannte Rechtebündel mit drei Dimensionen: freigegebene
Teilbäume (DNs), Attributgruppen (
public/internal, leer = alle) und Quellen (Provenance-Filter, leer = alle Quellen). Profile erhalten lokale Konten direkt, STARFACE-/AD-Identitäten über Gruppen-Zuordnungen (additiv: Vereinigung aller Gruppen-Profile). Das eingebaute Preset Voller Lesezugriff (preset:fullReader, Teilbaumdc=meta) wird automatisch angelegten STARFACE-Benutzerkonten standardmäßig zugewiesen. - Öffentliche Knoten: Ein Baumknoten ohne zugewiesene Zugriffsprofile ist
öffentlich — jeder Bind (auch anonym) darf die dort eingehängten Quellen lesen. Ein
Knoten mit Profilen verlangt einen authentifizierten Bind mit mindestens einem
passenden Profil. Der Fixknoten
dc=metaist stets öffentlich; sein Schutz gegenüber fremden Netzen erfolgt über die Firewall-Freigaben. - IP-Regeln je Knoten gelten unabhängig vom Bind: CIDR-Regeln (IPv4 und IPv6) mit Erlauben/Verbieten. Ausgewertet wird nach Longest-Prefix-Match — die spezifischste passende Regel gewinnt, bei gleicher Präfixlänge gewinnt Verbieten. Passt keine Regel, gilt: Existiert mindestens eine Erlauben-Regel, ist der Zugriff verboten (Allowlist-Semantik); existieren nur Verbieten-Regeln, ist er erlaubt (Blocklist). Eine leere Regelliste beschränkt nicht; eine nicht bestimmbare Client-IP wird abgewiesen.
- Firewall-Freigaben (Tab ) öffnen die STARFACE-Firewall für die eingetragenen Quellnetze (IPv4/CIDR). Ohne Eintrag sind die LDAP-Ports nur lokal erreichbar.
Fehlerbehandlung
| Result-Code | Situation |
|---|---|
0 success | Erfolg — auch bei leerer Treffermenge; ebenso, wenn ein Benutzer der Professional Edition ohne Lizenzplatz sucht (bewusst leeres Ergebnis statt Fehler). |
2 protocolError | LDAPv2-Bind bei deaktivierter Option LDAPv2 erlauben („LDAPv2 is disabled"). |
4 sizeLimitExceeded | Treffermenge übersteigt das sizeLimit des Clients bzw. das Server-Maximum von 500. |
7 authMethodNotSupported | Bind-Methode ist nicht Simple Bind („Only simple bind is supported"). |
32 noSuchObject | Base-Suche/Compare auf einen unbekannten oder für den Bind nicht sichtbaren DN. |
49 invalidCredentials | Bind fehlgeschlagen — einheitlich für unbekannten Benutzer, falsches Passwort, deaktiviertes Konto oder (unter Professional) fehlenden Lizenzplatz. |
53 unwillingToPerform | Schreiboperation („read-only directory") oder nicht unterstützte Extended Operation. |
1 operationsError | Interner Fehler bei Suche/Compare; Details im Modul-Log. |
Nicht sichtbare Einträge und Knoten verhalten sich für den Client wie nicht existent — Zugriffsverweigerungen erzeugen keinen eigenen Fehlercode (kein Informationsleck).
Versionierung & Kompatibilität
Basis-DN-Semantik, Fixknoten (dc=meta, dc=configuration), Objektklassen, die
Attributnamen des Zielfeld-Katalogs samt Alias-Gruppen sowie das Bind-/Suchverhalten sind
stabile Verträge dieser Schnittstelle; Erweiterungen erfolgen additiv (neue Attribute,
neue Controls). Die Kontakt-IDs (uid) sind über Importläufe stabil, solange Quelle und
Quell-Primärschlüssel unverändert bleiben; nach dem Löschen und Neuanlegen einer Quelle
entstehen neue IDs. Änderungen dokumentieren die
Release Notes der jeweiligen Modulversion.