
Ich muss auf einem Ubuntu 12.04-Server ein extern anonym zugängliches LDAP-Verzeichnis einrichten und möchte die Authentifizierung und die internen Daten in einem anderen Teilbaum speichern.
Beispiel für das LDAP-Layout
dc=example.com,dc=com
organizationUnit: ou=hie_ext,dc=example,dc=com
organizationUnit: ou=group1,ou=hie_ext,dc=example,dc=com
inetOrgPerson: cn=user1,ou=group1,ou=hie_ext,dc=example,dc=com
inetOrgPerson: cn=user2,ou=group1,ou=hie_ext,dc=example,dc=com
organizationUnit: ou=group2,ou=hie_ext,dc=example,dc=com
organizationUnit: ou=group_auth,dc=example,dc=com
account: uid=group1,password=XXX,ou=group_auth,dc=example,dc=com
Die Idee ist, dass die Authentifizierung mit uid=group1 die Einträge unter ou=hie_ext,ou=group1 hinzufügen/bearbeiten (im Grunde „schreiben“) kann. Ich habe eine ACL-Regel wie diese ausprobiert:
access to dn.children="ou=hie_ext,dc=example,dc=com"
by set="this/ou & user/uid" write
by * none
Wenn ich jedoch mit slapacl auf Schreibberechtigung teste, erhalte ich "ALLOWED", wenn ich dagegen teste
"ou=group1,ou=hie_ext,dc=example,dc=com"
aber "ABGELEHNT", wenn ich teste gegen
"cn=user1,ou=group1,ou=hie_ext,dc=example,dc=com"
was mir ein bisschen verrückt vorkommt.
Ich übersehe wahrscheinlich etwas Offensichtliches (ich bin derzeit ziemlich unerfahren mit LDAP). Das Ausführen der Option „-d trace“ für slapacl hat nicht viel geholfen, da ich keine Ahnung habe, was ich mir ansehe. :)
Aktualisieren:
Während „-d trace“ ein bisschen zu umständlich war, um mir von Nutzen zu sein, bin ich auf „-d acl“ gestoßen, was wahrscheinlich viel hilfreicher sein wird.
Wenn ich also renne
slapacl -f slapd.conf -D"uid=group1,ou=servers,dc=example,dc=com" \
-b "cn=user1,ou=group1,ou=hie_ext,dc=example,dc=com" "sn/write" -d acl
Die Debug-Ausgabe ist diese.
52d544e1 => access_allowed: write access to "cn=test,ou=group1,ou=hie_ext,dc=example,dc=com" "sn" requested
52d544e1 => dn: [1]
52d544e1 => dn: [2] ou=hie_ext,dc=example,dc=com
52d544e1 => acl_get: [2] matched
52d544e1 => acl_get: [2] attr sn
52d544e1 => acl_mask: access to entry "cn=test,ou=group1,ou=hie_ext,dc=example,dc=com", attr "sn" requested
52d544e1 => acl_mask: to all values by "uid=group1,ou=servers,dc=example,dc=com", (=0)
52d544e1 <= check a_set_pat: this/ou & user/uid
52d544e1 => bdb_entry_get: found entry: "uid=group1,ou=servers,dc=example,dc=com"
52d544e1 ACL set[0]=group1
52d544e1 ACL set: empty
52d544e1 <= check a_dn_pat: *
52d544e1 <= acl_mask: [2] applying read(=rscxd) (stop)
52d544e1 <= acl_mask: [2] mask: read(=rscxd)
52d544e1 => slap_access_allowed: write access denied by read(=rscxd)
52d544e1 => access_allowed: no more rules
write access to sn: DENIED
Aber das Weglassen des datensatzspezifischen cn:
slapacl -f slapd.conf -D"uid=group1,ou=servers,dc=example,dc=com" \
-b "ou=group1,ou=hie_ext,dc=example,dc=com" "sn/write" -d 128
Und es funktioniert?
52d545ef => access_allowed: write access to "ou=group1,ou=hie_ext,dc=example,dc=com" "sn" requested
52d545ef => dn: [1]
52d545ef => dn: [2] ou=hie_ext,dc=example,dc=com
52d545ef => acl_get: [2] matched
52d545ef => acl_get: [2] attr sn
52d545ef => acl_mask: access to entry "ou=group1,ou=hie_ext,dc=example,dc=com", attr "sn" requested
52d545ef => acl_mask: to all values by "uid=group1,ou=servers,dc=example,dc=com", (=0)
52d545ef <= check a_set_pat: this/ou & user/uid
52d545ef ACL set[0]=group1
52d545ef => bdb_entry_get: found entry: "uid=group1,ou=servers,dc=example,dc=com"
52d545ef ACL set[0]=group1
52d545ef ACL set[0]=group1
52d545ef <= acl_mask: [1] applying write(=wrscxd) (stop)
52d545ef <= acl_mask: [1] mask: write(=wrscxd)
52d545ef => slap_access_allowed: write access granted by write(=wrscxd)
52d545ef => access_allowed: write access granted by write(=wrscxd)
write access to sn: ALLOWED
Ich bin nicht sicher, warum der ACL-Parser im ersten und zweiten Beispiel einen anderen Wertesatz für „this/ou“ erhält, was aber offenbar der Fall ist.
Antwort1
Offenbar habe ich die Funktionsweise von ACLs missverstanden. Anscheinend kann man nicht gegen „geerbte“ Attribute testen, was ich eigentlich versucht habe. Attribute im DN sind nicht Teil eines bestimmten Objekts: eine wertvolle Lektion für LDAP-Neulinge.
Nachdem ich herausgefunden hatte, was ich falsch gemacht hatte, war die Lösung ziemlich einfach:
Ich habe den inetorgperson-Datensätzen ein "ou"-Element hinzugefügt, das mit der UID der Autorisierungsobjekte übereinstimmte[0]. Wie durch Zauberhand funktionierte alles.
by set="this/ou & user/uid" write
[0] Das ist anscheinend kein Missbrauch des Schemas, da jedes Authentifizierungskonto an eine bestimmte Einheit gebunden ist. Versprochen!