https://linux.die.net/man/5/slapd.access
Da LDAP quasi jede Struktur auf jede andere fĂŒr Zugriffsrechte abbilden kann ist oft schwer zu verstehen, welche Regeln letztendlich angewandt werden. Gerade wenn regex ins Spiel kommt oder ein Zweig mehrere Regeln benötigt.
Was hilft? Debugging!
In cn=config olcLogLevel ACL
hinzufĂŒgen, hier lĂ€uft sonst stats und stats2, also fĂŒrs Testen immer gut: stats stats2 ACL
dn. (default) == dn.exact == dn.base => exakt dieser DN
dn.one = Eine Ebene darunter, aber NICHT der DN selbst und auch nur 1 Ebene, nicht alle! (aliase: dn.onelevel)
dn.subtree = Alle EintrÀge unter dem Eintrag, inkl. des Eintrags selbst. (aliase: dn.sub)
dn.children = Alle EintrÀge unter dem Eintrag, aber NICHT der DN selbst.
Hier 2 Beispiele, einmal fĂŒr ou=Gruppen (1) und ou=Kundendienst,ou=Mitarbeiter,ou=Gruppen
dn base one subtree children
ou=Gruppen 1 1
âââ ou=Mitarbeiter 1 1 1
â âââ ou=Manager 1 1
â â âââ cn=Inhaber 1 1
â â âââ cn=Partner 1 1
â â âââ cn=GeschĂ€ftsfĂŒhrer 1 1
â âââ ou=Kundendienst 2 1 2 1
â â âââ cn=HomeOffice 2 1 2 1 2
â â âââ cn=Kundendienstleitung 2 1 2 1 2
â âââ cn=Aussendienst 1 1
âââ cn=Lieferanten 1 1 1
âââ cn=GĂ€ste 1 1 1
Eine olcAccess-Regel setzt immer:
Kann ein DN sein (z.B. ein Abzweig), ein Fiter (nutzen wir nie) oder eine Liste von Attributen - es geht natĂŒrlich auch die Kombination, also Attribute eines bestimmten DNs.
gibt den Match an auf wen die Regel zutrifft. Wichtig ist zu verstehen, dass IMMER ein by * none
hinten angehĂ€ngt wird den wir u.U. abfangen mĂŒssen wenn wir das "Was" spĂ€ter nochmal prĂŒfen wollen.
FĂŒr leserliche Rechte-Listen ist das eigentlich der wichtigste Aspekt und wenn man das einmal verstanden hat schreiben sich die Regeln fast wie von selbst!
Hier ist stop
Standard wenn nichts angeben ist und bedeutet, dass sobald ein "Was" zutrifft die Regelauswertung nach dieser Regel beendet wird. Das ist wichtig zu verstehen, denn das implizierte by * none
mit stop
schliesst so jede Regel ab.
Möglich ist zudem break
- dann geht die Auswertung weiter.
Nie benutzt, aber auch machbar ist continue
was sehr verwirrend klingt, aber nur bedeutet, dass bei einem Match auch die nÀchste Regel noch beachtet wird. Damit lÀsst sich also mehrfach eingrenzen, zunÀchst z.B. ein Abzweig und dann einzelne Attribute in der nÀchsten Regel, aber diese addieren sich auf.
Da es in olcAccess keine Möglichkeit zum Kommentieren gibt (warum auch immer, super nervig) hier eine sehr restriktive olcAccess-Liste mit ErklÀrungen:
GewÀhre auf das userPassword nur dem gleichen DN schreibzugriff, anonym darf dagegen authentifizieren und der users-Dienst darf (den Hash) lesen. Ansonsten darf keiner irgendwas und mit by * none stop
werden alle anderen Regeln ignoriert.
{0}to attrs=userPassword by self write by anonymous auth by dn="cn=users,ou=Dienste,dc=domain,dc=tld" read by * none stop
GewÀhre auf das Attribut shadowLastChange nur dem gleichen DN Schreibzugriff. ABER setze mit by * break
die Regelauswertung fort. Das sorgt dafĂŒr, dass Dienste wie lookup oder users in Regel 6 und 7 dieses Attribut lesen dĂŒrfen
{1}to attrs=shadowLastChange by self write by * break
Das gleiche hier mit Attributen zu Wohnort, Handy, StraĂe, PLZ: Der gleiche DN darf diese Attribute Ă€ndern (lassen Sie NIE einen User seine Mail-Adresse selbststĂ€ndig Ă€ndern!!), aber die Regelauswertung wird fĂŒr alle anderen fortgesetzt. Denn Leserechte hat wieder auch ein Dienst-DN ab Regel 6.
{2}to attrs=l,mobile,street,postalCode by self write by * break
Das sind Kerberos-Passwörter, Ă€hnlich wie Attribut User-Passwort. Die darf nur der gleiche DN schreiben (das ist i.d.R. der Principal im Kerberos-Container, kann aber auch ein erweiterter User-DN woanders sein). Der KDC muss das lesen dĂŒrfen und Kadmin darf es ĂŒberschreiben. Alle anderen dĂŒrfen nix und wir beenden daher die Regelauswertung an dieser Stelle wieder mit by * none stop
{3}to attrs=krbPrincipalKey by self write by anonymous auth by dn.exact="uid=kdc,ou=Dienste,dc=domain,dc=tld" read by dn.exact="uid=kadmin,ou=Dienste,dc=domain,dc=tld" write by * none stop
Das ist der Container fĂŒr Kerberos, hier setzen wir Rechte fĂŒr den kompletten Sub-Baum. Den darf KDC lesen, Kadmin schreiben.
{4}to dn.subtree="cn=krbContainer,ou=Dienste,dc=domain,dc=tld" by dn.exact="uid=kdc,ou=Dienste,dc=domain,dc=tld" read by dn.exact="uid=kadmin,ou=Dienste,dc=domain,dc=tld" write by * none stop
Checks die es bis hierher geschafft haben sind meist Attribute die wir nicht gesondert behandeln mĂŒssen. Diese darf jeder DN fĂŒr sich selbst lesen. Danach geht die Regelauswertung weiter
{5}to * by self read by * break
Auch der Lookup-Dienst darf lesen was noch ĂŒbrig ist.
{6}to * by dn="cn=lookup,ou=Dienste,dc=domain,dc=tld" read by * break
Ebenso der Users-Dienst. Die könnte man in einer Regel zusammenfassen, so ist es aber leserlicher.
{7}to * by dn="cn=users,ou=Dienste,dc=domain,dc=tld" read by * break
đ·đ·đ· Das ist eine leider notwendige ganz gemeine Extra-Regel weil Kerberos derzeit noch im ganzen Baum nach Sachen sucht - das lassen wir hier zu, denn die sehen ohnehin nur noch Daten die unkritisch sind.
{8}to * by dn.exact="uid=kdc,ou=Dienste,dc=domain,dc=tld" search by dn.exact="uid=kadmin,ou=Dienste,dc=domain,dc=tld" read by * break
Die letzte Regel sperrt alle anderen Anfragen aus. Das ist hier so, wir lassen generell keine anonymen Suchen, etc. zu, auch nicht von jedem authentifizierten Nutzer.
{9}to * by * none stop
Alle Regeln:
{0}to attrs=userPassword by self write by anonymous auth by dn="cn=users,ou=Dienste,dc=domain,dc=tld" read by * none stop
{1}to attrs=shadowLastChange by self write by * break
{2}to attrs=l,mobile,street,postalCode by self write by * break
{3}to attrs=krbPrincipalKey by self write by anonymous auth by dn.exact="uid=kdc,ou=Dienste,dc=domain,dc=tld" read by dn.exact="uid=kadmin,ou=Dienste,dc=domain,dc=tld" write by * none stop
{4}to dn.subtree="cn=krbContainer,ou=Dienste,dc=domain,dc=tld" by dn.exact="uid=kdc,ou=Dienste,dc=domain,dc=tld" read by dn.exact="uid=kadmin,ou=Dienste,dc=domain,dc=tld" write by * none stop
{5}to * by self read by * break
{6}to * by dn="cn=lookup,ou=Dienste,dc=domain,dc=tld" read by * break
{7}to * by dn="cn=users,ou=Dienste,dc=domain,dc=tld" read by * break
{8}to * by dn.exact="uid=kdc,ou=Dienste,dc=domain,dc=tld" search by dn.exact="uid=kadmin,ou=Dienste,dc=domain,dc=tld" read by * break
{9}to * by * none stop