×
Vor einigen Jahren haben wir den Siedl-Zimbra-LDAP Connector (Projektname: sinbra) entwickelt.
Mit dem Konnektor werden Mailaccounts von Usern, Gruppen oder Verteilerlisten von einem Verzeichnisdienst wie openLDAP, Univention Corporate Server oder Active Directory AD in Zimbra synchronisiert.
Dies hat den großen Vorteil, dass
1. die Administration zentral im Verzeichnisdienst bzw. im Identity und Access Management (IAM) erfolgt und
2. die Benutzer für die Anmeldung am Zimbra Service automatisch das Kennwort vom Verzeichnisdienst verwenden bzw. die Authentifizierung über Single-Sign-on (SSO) ermöglicht
Da wir viele Migrationen von Microsoft Exchange Servern zu Zimbra durchführen, haben wir den Siedl-Zimbra-LDAP Connector um ein neues großes Feature erweitert: dynamische Expressions in der Config (Lob und Dank an unseren Developer Geri!).
Was sind die neuen Expressions?
Bei den supporteten Config Einstellungen können nun statt Attributsnamen python-like Expressions verwendet werden, die beim Mappen auf das LDAP-Objekt angewendet werden. Im Gegensatz zu den Templates bieten diese wesentlich mehr Möglichkeiten, da hier einzelne Schritte nicht mehr mit Regex aus der Eingabe geparst werden, sondern der Python eigene Code-Parser verwendet. Die möglichen, verwendeten Funktionen werden begrenzt, um die Möglichkeit, Schabernack zu treiben, zu verringern. Als "Variablen" können dabei die LDAP-Attribute verwendet werden, wobei Attribute die im Schema nicht als Single-Value gekennzeichnet sind als Liste übergeben werden (auch wenn diese nur 1 Element beinhalten).
Achtung: Viele Attribute von denen man glauben würde, dass sie Single-Value sind, sind es in Wirklichkeit nicht (z.B. uid, sn, ...). Mit der Test Funktion (siehe unten) kann das relativ einfach herausgefunden werden!
Welche Funktionen gibt es derzeit?
Typ: bytes
- base64 -> Encoded die Daten als Base64
Typ: string:
- format -> Python String Formatierungs Funktion
- html_encode -> Ersetzt non-ascii Zeichen mit HTML Escape Sequenzen
- lower -> Konvertierung zu Kleinbuchstaben
- match(pattern, flags='') -> Führt eine Regex am String aus und gibt das Match Objekt zurück, Flags ist ein String mit einer oder mehreren Regex Flags (z.B. i für Case-Insensitive)
- replace(x, y) -> Ersetzt x mit y
- split -> Teilt den String in eine Liste
- sub(pattern, replacement, count=0, flags='') -> Wie replace, aber mit Regex Matching
- upper -> Konvertierung zu Großbuchstaben
Typ: list:
- each -> Führt die angegebene Sub-Expression für alle Listenelemente aus, wobei das jeweilige Element mit _ referenziert werden kann, und ersetzt das Element mit dem Ergebnis der Sub-Expression
- join(x) -> Fügt alle Listenelemente zu einem String zusammen, mit x als Trennzeichen
- where -> wie each, aber ersetzt das Element nicht, sondern entfernt dieses, wenn das Ergebnis der Sub-Expression False~ish ist
Die Expression ist vollständig mit bestehenden Configs kompatibel (der bisherige Attributsname ist auch eine Expression, die den entsprechenden Wert zurück gibt).
Für die Kompatibilität mit bestehenden Configs wurde aber folgender Sonderfall eingebaut:
Einstellungen, die einzelne Werte erfordern (z.B. die Primäre Adresse) akzeptieren auch eine Liste mit einem einzelnen Element. Sprich, die Rückwärtskompatibilität ist nur dann nicht gegeben, falls aus irgendeinem Grund ein Multi-Value Attribut mit mehreren Werten für eine Single-Value Config Option verwendet wurde.
Unser initialer Anwendungsfall:
Microsoft Exchange speichert die Adressen eines Benutzers im Attribut "proxyAddresses", wobei die primäre Adresse mit dem Prefix "SMTP:" gekennzeichnet ist und die Alias Adressen mit "smtp:".
Das war bisher so nicht abbildbar, da der LDAP-Connector erwartet hat, dass die Primäre Adresse und Alias Adressen in 2 separaten Attributen zu finden sind, und diese als Inhalt ausschließlich die Adressen haben.
Mit den neuen Expressions lässt sich der Inhalt des Attributes nun filtern & umwandeln, und das Ergebnis wird dann schlussendlich verwendet:
email_attr = proxyAddresses.where(_.match('^SMTP:')).each(_.sub('^SMTP:',''))Dabei wird jeder Wert der proxyAddresses auf den Prefix "SMTP:" geprüft, und Dieser bei jedem entfernt.
sinbra test-expression <ldap-filter> <expression>
Bei "ldap-filter" kann auch der Name einer Config Section angegeben werden (z.B. user, group, ...), dann wird der bei "filter" hinterlegte Filter verwendet.
Wenn der Filter mehrere Objekte zurückgibt, wird die Expression für jedes davon getestet.
Beispiel einer Expression, die eine Email-Adresse aus Vor- & Nachname und der Domain-Base eines Benutzers zusammenbaut:
Wie wurde das ganze Implementiert?
Die angegebene Expression wird mit dem Python Code-Parser in einen ast (Syntax Tree) ausgewertet (aber nicht ausgeführt), und dieser dann Schritt für Schritt im Code abgearbeitet. Die Expressions sehen daher aus wie Python-Codes (und stimmen zum Großteil auch damit überein), sind es aber nicht wirklich.
Inwiefern weichen diese vom Python-Code ab?
Die Expressions sollten Null-Safe sein. Sprich: Funktionsaufrufe usw. auf Objekte, die keinen Wert besitzen, lösen keinen Fehler aus. Es gibt einige Funktionen, deren "Parameter" eine Sub-Expression ist, die dann ausgewertet wird (z.B. bei den Funktionen each & filter bei Listen). Im Bezug auf Python Code könnt ihr euch das wie eine lambda Funktion vorstellen. Da die Auswertung durch viele rekursive Funktionsaufrufe passiert, kann es sein dass der LDAP-Connector bei komplexen Expressions (vermutlich mit mehreren hundert verschachtelten Aufrufen) mit einem Stack Overflow abstürzt...
Welche Python Syntax-Features sind nicht supported?
- Alles, was nicht Teil einer Python-Expression ist (Funktionsdefinitionen, Loops, ...)
- Setzen von Variablen
- Lambda Funktionen
- Sämtliche Sequenzen außer Listen
- List-Comprehension (Lässt sich auch mit each & where umsetzen)
- Parameter Expansion (*x, **x)
Wir werden den Siedl Zimbra LDAP Connector zukünftig als Open Source Projekt online stellen. Nähere Informationen dazu folgen noch.
Bei Interesse oder Fragen schickt uns einfach eine e-Mail an support@siedl.net .
Liebe Grüße,
Robert
Für Fragen steht Ihnen
unser Team zur Verfügung
office@siedl.net
+43 2732 71545-0
Unsere Facebook-Seite
Teamviewer Support
Siedl Networks GmbH
Dr.-Franz-Wilhelm-Straße 2
3500 Krems an der Donau
+43 2732 71545-0
office@siedl.net
support@siedl.net
Unsere Bürozeiten:
Montag bis Freitag:
08:00 Uhr - 12:00 Uhr
13:00 Uhr - 16:45 Uhr