Назад | Перейти на главную страницу

Установите ACL в OpenLDAP, чтобы пользователь мог найти свою запись в отфильтрованном поддереве

У меня есть каталог пользователей на сервере openldap под базовым DN ou=users,dc=mydomain. Записи пользователей uid=user1,ou=users,dc=mydomain

Мои текущие ACL:

{5}to * by self write by dn="cn=admin,dc=mydomain" write by * none {4}to dn.subtree="ou=users,dc=mydomain" by self read {3}to dn.exact="dc=mydomain" attrs=entry by users search by * none {2}to dn.base="" by * read {1}to dn.subtree="dc=something,dc=mydomain" by dn="uid=someone,ou=users,dc=mydomain" write by * read {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=mydomain" write by * none

Они позволяют пользователю запрашивать и находить свою собственную запись. Но если аутентифицированный пользователь user1 ищет базовое DN с фильтром (uid=user1) установлен, записи не найдены. Другими словами: ldapsearch -H ldap://myserver -b "ou=users,dc=mydomain" -D "uid=user1,ou=users,dc=mydomain" -x -W ничего не вернуть пока ldapsearch -H ldap://myserver -b "uid=user1,ou=users,dc=mydomain" -D "uid=user1,ou=users,dc=mydomain" -x -W возвращает запись для user1.

Как мне настроить ACL, чтобы пользователь мог найти свою собственную запись (и только свою) с помощью фильтрованного поиска по базовому DN?

Определить ACL OpenLDAP непросто.

В большинстве случаев проблемы ACL вызваны порядком обработки самих ACL и их предложений who (by ...), и что ACL неявно заканчиваются на by * none остановка потока управления.

Вы используете динамическую конфигурацию с cn = config и это использует ЗАКАЗАНО X расширение в схеме, чтобы сохранить порядок значений некоторых атрибутов, например olcAccess.

Итак, порядок, в котором обрабатываются ваши ACL, следующий:

{0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by  dn="cn=admin,dc=mydomain" write by * none
{1}to dn.subtree="dc=something,dc=mydomain" by dn="uid=someone,ou=users,dc=mydomain" write by * read
{2}to dn.base="" by * read
{3}to dn.exact="dc=mydomain" attrs=entry by users search by * none
{4}to dn.subtree="ou=users,dc=mydomain" by self read
{5}to * by self write by dn="cn=admin,dc=mydomain" write by * none

Итак, давайте подробно рассмотрим ваши ACL:

{0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=mydomain" write by * none

Это правило, вероятно, взято из какой-то конфигурации по умолчанию. Начать можно, но я бы посоветовал немного перефакторировать:

  1. Опустить атрибут shadowLastChange поскольку тень LDAP нарушена концепция. И если вы действительно используете карты теней, этот ACL позволит пользователю обойти срок действия теневого пароля.
  2. Измените порядок предложений who. Как правило, следуйте правилу, чтобы в первую очередь упомянуть «высшие» привилегии.
  3. Если cn = admin, dc = mydomain уже является rootdn этой базы данных вам не нужно это предложение who.
  4. Лучше предоставить группе права администратора с паролем.
  5. Не предоставлять права чтения вообще включительно write доступ, используйте привилегию только для записи =w вместо.

Лучше использовать:

{0}to attrs=userPassword by group="cn=admins,ou=groups,dc=mydomain" =w by self =w by anonymous auth by * none

{1}to dn.subtree="dc=something,dc=mydomain" by dn="uid=someone,ou=users,dc=mydomain" write by * read

Если dc=mydomain это суффикс вашей базы данных, этот ACL не имеет для меня особого смысла в контексте вашего вопроса. Может быть, остатки каких-то тестов?

{2}to dn.base="" by * read

Это неэффективно, если помещено в запись конфигурации вашей базы данных. Это должно быть добавлено в запись конфигурации внешнего интерфейса cn = config (ранее в статической конфигурации slapd.conf перед любым база данных раздел).

{3}to dn.exact="dc=mydomain" attrs=entry by users search by * none

Я бы поместил такой ACL в конец списка ACL, чтобы он не останавливал доступ к вход с этой точки зрения. И если вы хотите использовать произвольные базы поиска, например ou = пользователи, dc = mydomain вам нужно будет предоставить право этого поиска для всего поддерева.

Поместите это в конец списков управления доступом и удалите {3} или ...

{6}to dn.subtree="dc=mydomain" attrs=entry by users search by * none

... переместите это правило:

{4}to dn.subtree="ou=users,dc=mydomain" by self read

Вероятно, должен быть последний ACL и заменить {3}. См. Комментарий к {5}.

{5}to * by self write by dn="cn=admin,dc=mydomain" write by * none

Проблемы здесь:

  1. В by self write никогда не будет достигнута из-за by self read в {4}.
  2. Этот ACL вообще не достигается из-за неявного by * none в {4}.
  3. снова: предоставление доступа к rootdn не обязательно
  4. еще раз: лучше предоставить доступ администратора к группе
  5. используйте лучший порядок предложений who
  6. пересмотреть, действительно ли вы хотите предоставить доступ на запись ко всем атрибутам самому пользователю

Лучше:

{5}to * by group="cn=admins,ou=groups,dc=mydomain" write by self write by * none

Один из наиболее важных вариантов отладки - запустить пощечина с протоколированием обработки ACL:

/usr/sbin/slapd … -d config,stats,stats2,acl

Таким образом, эти подсказки должны помочь вам начать работу над своими ACL, решая ваши проблемы самостоятельно. Всегда думай дважды. Мне кажется, в ваших правилах есть немного противоречивых предположений.

Но, очевидно, нет никакого способа обойтись без глубокого погружения в документацию:

Если вы хотите подробно разобраться в ACL, вам следует обратиться к различной интерактивной документации:

это ответ Дай мне решающую улику. Единственное, что мне пришлось изменить, это предложенный поиск acl от верхнего dn (dc = mydomain) к dn пользователя (ou = users, dc = mydomain)

Изменение ACL на это помогает: {5}to * by self write by dn="cn=admin,dc=mydomain" write by * none {4}to dn.subtree="ou=users,dc=mydomain" by self read {3}to dn.exact="ou=users,dc=mydomain" attrs=entry by users search by * none {2}to dn.base="" by * read {1}to dn.subtree="dc=something,dc=mydomain" by dn="uid=someone,ou=users,dc=mydomain" write by * read {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=mydomain" write by * none