Здравствуйте! Я тут поэкспериментировал немного с ACL, вышло что-то в таком духе (slapd.conf):
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/inetorgperson.schema
database mdb
suffix "dc=example,dc=ru"
directory ./mdb
rootdn "cn=admin,dc=example,dc=ru"
rootpw admin
maxsize 1073741824
# Разрешаем аутентификацию по userPassword
access to attrs=userPassword
by anonymous auth
by * none
# Разрешаем ab_admin ДОБАВЛЯТЬ записи в addressbook
# (но не саму запись addressbook)
access to dn.base="ou=addressbook,dc=example,dc=ru" attrs=children
by dn="cn=ab_admin,dc=example,dc=ru" write
by * none
# Разрешаем ab_admin ИЗМЕНЯТЬ записи в addressbook
# а ab_reader ЧИТАТЬ записи в addressbook
# (но не саму запись addressbook)
access to dn.children="ou=addressbook,dc=example,dc=ru"
by dn="cn=ab_admin,dc=example,dc=ru" write
by dn="cn=ab_reader,dc=example,dc=ru" read
by * none
# Остальные записи просматривать запрещено
access to *
by users search
by * none
LDIF, с которого я инициализировал каталог (init.ldif):
dn: dc=example,dc=ru
objectClass: organization
objectClass: dcObject
dc: example
o: example
dn: cn=ab_admin,dc=example,dc=ru
objectClass: inetOrgPerson
cn: ab_admin
sn: ab_admin
userPassword: ab_admin
dn: cn=ab_reader,dc=example,dc=ru
objectClass: inetOrgPerson
cn: ab_reader
sn: ab_reader
userPassword: ab_reader
dn: ou=addressbook,dc=example,dc=ru
objectClass: organizationalUnit
ou: addressbook
dn: cn=client1,ou=addressbook,dc=example,dc=ru
objectClass: inetOrgPerson
cn: client1
sn: client1
mail: boss@some.org
Запускаю slapd, инициализирую каталог от имени rootDN:
# /usr/lib/openldap/slapd -h 'ldap://127.0.0.1:9000' -f ./slapd.conf
# ldapadd -H 'ldap://127.0.0.1:9000' -f ./init.ldif -x -D 'cn=admin,dc=example,dc=ru' -w admin
adding new entry "dc=example,dc=ru"
adding new entry "cn=ab_admin,dc=example,dc=ru"
adding new entry "cn=ab_reader,dc=example,dc=ru"
adding new entry "ou=addressbook,dc=example,dc=ru"
adding new entry "cn=client1,ou=addressbook,dc=example,dc=ru"
Поиск от анонима, ab_reader, ab_admin:
# ldapsearch -x -LLL -H 'ldap://127.0.0.1:9000' -b 'dc=example,dc=ru'
No such object (32)
# ldapsearch -x -LLL -H 'ldap://127.0.0.1:9000' -b 'dc=example,dc=ru' -D 'cn=ab_reader,dc=example,dc=ru' -w ab_reader
dn: cn=client1,ou=addressbook,dc=example,dc=ru
objectClass: inetOrgPerson
cn: client1
sn: client1
mail: boss@some.org
# ldapsearch -x -LLL -H 'ldap://127.0.0.1:9000' -b 'dc=example,dc=ru' -D 'cn=ab_admin,dc=example,dc=ru' -w ab_admin
dn: cn=client1,ou=addressbook,dc=example,dc=ru
objectClass: inetOrgPerson
cn: client1
sn: client1
mail: boss@some.org
Всё штатно. Попромуем добавить/изменить записи в адресной книге, для этого создадим modify.ldif:
dn: cn=client2,ou=addressbook,dc=example,dc=ru
changetype: add
objectClass: inetOrgPerson
cn: client2
sn: client2
mail: dima@some.org
dn: cn=client1,ou=addressbook,dc=example,dc=ru
changetype: modify
replace: mail
mail: manager@some.org
Попробуем применить его от анонима ab_reader, ab_admin:
# ldapmodify -x -H 'ldap://127.0.0.1:9000' -f ./modify.ldif
modifying entry "ou=addressbook,dc=example,dc=ru"
ldap_modify: Strong(er) authentication required (8)
additional info: modifications require authentication
# ldapmodify -x -H 'ldap://127.0.0.1:9000' -f ./modify.ldif -D 'cn=ab_reader,dc=example,dc=ru' -w ab_reader
adding new entry "cn=client2,ou=addressbook,dc=example,dc=ru"
ldap_add: Insufficient access (50)
additional info: no write access to parent
# ldapmodify -x -H 'ldap://127.0.0.1:9000' -f ./modify.ldif -D 'cn=ab_admin,dc=example,dc=ru' -w ab_admin
adding new entry "cn=client2,ou=addressbook,dc=example,dc=ru"
modifying entry "cn=client1,ou=addressbook,dc=example,dc=ru"
Всё как положено. Последний тест -- пробуем изменить саму запись addressbook. Создадим modify2.ldif:
dn: ou=addressbook,dc=example,dc=ru
changetype: modify
add: description
description: Address Book
Попробуем применить его от имени ab_admin:
# ldapmodify -x -H 'ldap://127.0.0.1:9000' -f ./modify2.ldif -D 'cn=ab_admin,dc=example,dc=ru' -w ab_admin
modifying entry "ou=addressbook,dc=example,dc=ru"
ldap_modify: Insufficient access (50)
Все тесты прошли успешно.
Егор