Форум проекта Pro-LDAP.ru
Администрирование OpenLDAP => Вопросы безопасности => Access Control List (ACL) => Тема начата: Pilot от 02 Октябрь 2017, 07:28:46
-
Здравствуйте.
структура такая
+--> dc=mycompany,dc=lan (3)
---> ou=addressbook
---> ou=adrbookprivate
+--> ou=adrbookusers (2)
| ---> cn=adrbook <<<--- этому пользователю разрешить запись и просмотр - addressbook
| ---> cn=userspriv <<<--- этому пользователю разрешить запись и просмотр adrbookprivate
| ---> Создать новый
---> Создать новый
# cat slapd.conf | grep -v ^# | grep -v ^$
include /usr/local/etc/openldap/schema/core.schema
include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/inetorgperson.schema
include /usr/local/etc/openldap/schema/misc.schema
include /usr/local/etc/openldap/schema/nis.schema
include /usr/local/etc/openldap/schema/openldap.schema
pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args
modulepath /usr/local/libexec/openldap
moduleload back_mdb
access to * by * read
access to attrs=userPassword
by self write
by anonymous auth
by * none
access to dn.base="dc=mycompany,dc=lan"
by * read
access to dn.one="dc=mycompany,dc=lan"
by * read
access to dn.base=""
by * read
access to dn.base="cn=Subschema"
by * read
access to *
by * none
access to dn.regex="^.*cn=([^,]+),ou=adrbookusers,dc=mycompany,dc=lan$"
by dn.exact,expand="cn=$1,ou=adrbookprivate,dc=mycompany,dc=lan" write
access to dn.regex="^.*cn=([^,]+),ou=adrbookusers,dc=mycompany,dc=lan$"
by dn.exact,expand="cn=$1,ou=addressbook,dc=mycompany,dc=lan" write
database mdb
maxsize 1073741824
overlay sssvlv
suffix "dc=mycompany,dc=lan"
rootdn "cn=root,dc=mycompany,dc=lan"
rootpw {SSHA}7SDjZYyn3vcMXJ2dg5/H+oWWeFJmnI03
directory /var/db/openldap-data
index objectClass eq
# cat mycompany.local.ldif
dn: dc=mycompany,dc=lan
objectClass: top
objectClass: dcObject
objectClass: organization
dc: mycompany
o: mycompany-RU
# Public AdressBook
dn: ou=addressbook,dc=mycompany,dc=lan
objectClass: organizationalUnit
ou: addressbook
# Private AdressBook
dn: ou=adrbookprivate,dc=mycompany,dc=lan
objectClass: organizationalUnit
ou: adrbookprivate
# Users adressbooks Public and Private
dn: ou=adrbookusers,dc=mycompany,dc=lan
objectClass: organizationalUnit
ou: adrbookusers
dn: cn=adrbook,ou=adrbookusers,dc=mycompany,dc=lan
cn: adrbook
userPassword: 111
objectClass: organizationalRole
objectClass: simpleSecurityObject
dn: cn=userspriv,ou=adrbookusers,dc=mycompany,dc=lan
cn: userspriv
userPassword: 222
objectClass: organizationalRole
objectClass: simpleSecurityObject
Где ошибаюсь ?
Как разрешить запись и чтение общей и приватной разным пользователям адресных книг, подскажите пожалуйста ?
-
Здравствуйте! Задача сформулирована неоднозначно, поэтому могут быть разные варианты решения. Будет ли к Вашему каталогу анонимный доступ на чтение, например, адресных книг? Будет ли в каталоге что-то кроме адресных книг?
Я исходил из того, что анонимного доступа не планируется, а каждый из двух пользователей имеет доступ только к своей адресной книге. Кроме этих двух адресных книг в каталоге ничего нет. Тогда можно сделать ACL так:
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/misc.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/openldap.schema
#pidfile /var/run/openldap/slapd.pid
#argsfile /var/run/openldap/slapd.args
modulepath /usr/lib/ldap
moduleload back_mdb
access to dn.base=""
by * read
access to dn.base="cn=Subschema"
by * read
access to *
by * none
database mdb
maxsize 1073741824
suffix "dc=mycompany,dc=lan"
rootdn "cn=root,dc=mycompany,dc=lan"
rootpw rootPassword
directory /data/openldap-experiments/2017-10-02-acl_concat/db/
index objectClass eq
access to dn.subtree="ou=adrbookusers,dc=mycompany,dc=lan" attrs=userPassword
by anonymous auth
by * none
access to dn.subtree="ou=addressbook,dc=mycompany,dc=lan"
by dn.base="cn=adrbook,ou=adrbookusers,dc=mycompany,dc=lan" write
by * none
access to dn.subtree="ou=adrbookprivate,dc=mycompany,dc=lan"
by dn.base="cn=userspriv,ou=adrbookusers,dc=mycompany,dc=lan" write
by * none
access to dn.subtree="dc=mycompany,dc=lan"
by * search
При составлении ACL нужно помнить следующее:
1. Глобальные ACL (до определения первой базы данных) добавляются в конец ACL базы данных.
2. ALC рассматриваются последовательно один за другим до первого совпадения условия to, оставшиеся ACL не рассматриваются. Поэтому сначала задаются более конкретные ACL, а затем более общие.
Егор
-
Егор, благодарю за ответ.
Да, согласен по поводу вопроса, момент важный, поэтому уточню.
ou=addressbook,dc=mycompany,dc=lan
Авторизированный доступ, если человеку разрешена правка общей адресной книги и анонимный для всех остальных сотрудников
клиенты Outlook 2013, Outlook 2016 и Вебинтерфейс Rouncubemail
ou=adrbookprivate,dc=mycompany,dc=lan
Только авторизированный под конкретного пользователя
Создание, редактирование и запись контактов адресной книги.
клиенты Outlook 2013, Outlook 2016 и Вебинтерфейс Rouncubemail
Характеристики сервера.
ОС FreeBSD 11.1-Release
openldap-client-2.4.45 Open source LDAP client implementation
openldap-server-2.4.45 Open source LDAP server implementation
php56-ldap-5.6.31 The ldap shared extension for php
phpldapadmin-1.2.3_7,1 PHP application to administer LDAP over the web
Теперь что касается написанного Вами решения вопроса.
Попробовал, аккуратно скопировав и проверив всё, но не работает к сожалению...
Опишу что происходит.
1. Копирую написанную конфигурацию.
2. Рестартую slapd
# service slapd restart
3. Открываю в браузере phpLDAPadmin, пробую логиниться через имя пользователя
cn=adrbook,ou=adrbookusers,dc=mycompany,dc=lan
и пароль 12345
Ответ в окне браузера
Невозможно соединиться с сервером LDAP My LDAP Server
Ошибка: Invalid credentials (49) for user
error Ошибка авторизации
Неверное имя пользователя или пароль.
Зайдя через root, проверил совпадение пароля - совпадение есть, в пароле ошибки нет точно!
В логах в момент ошибки
# tail -n33 -Ff /var/log/debug.log
Oct 2 20:16:04 srv slapd[54696]: conn=1000 fd=9 ACCEPT from IP=127.0.0.1:10341 (IP=127.0.0.1:389)
Oct 2 20:16:04 srv slapd[54696]: conn=1000 op=0 BIND dn="cn=adrbook,ou=adrbookusers,dc=mycompany,dc=lan" method=128
Oct 2 20:16:04 srv slapd[54696]: conn=1000 op=0 RESULT tag=97 err=49 text=
Oct 2 20:16:04 srv slapd[54696]: conn=1000 op=1 UNBIND
Oct 2 20:16:04 srv slapd[54696]: conn=1000 fd=9 closed
Oct 2 20:16:18 srv slapd[54696]: conn=1001 fd=9 ACCEPT from IP=127.0.0.1:54724 (IP=127.0.0.1:389)
Oct 2 20:16:18 srv slapd[54696]: conn=1001 op=0 BIND dn="cn=adrbook,ou=adrbookusers,dc=mycompany,dc=lan" method=128
Oct 2 20:16:18 srv slapd[54696]: conn=1001 op=0 RESULT tag=97 err=49 text=
Oct 2 20:16:18 srv slapd[54696]: conn=1001 op=1 UNBIND
Oct 2 20:16:18 srv slapd[54696]: conn=1001 fd=9 closed
Конфиг выглядит сейчас так
# cat slapd.conf | grep -v ^# | grep -v ^$
include /usr/local/etc/openldap/schema/core.schema
include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/inetorgperson.schema
include /usr/local/etc/openldap/schema/misc.schema
include /usr/local/etc/openldap/schema/nis.schema
include /usr/local/etc/openldap/schema/openldap.schema
pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args
modulepath /usr/local/libexec/openldap
moduleload back_mdb
access to dn.base=""
by * read
access to dn.base="cn=Subschema"
by * read
access to *
by * none
access to dn.subtree="ou=adrbookusers,dc=mycompany,dc=lan" attrs=userPassword
by anonymous auth
by * none
access to dn.subtree="ou=addressbook,dc=mycompany,dc=lan"
by dn.base="cn=adrbook,ou=adrbookusers,dc=mycompany,dc=lan" write
by * none
access to dn.subtree="ou=adrbookprivate,dc=mycompany,dc=lan"
by dn.base="cn=userspriv,ou=adrbookusers,dc=mycompany,dc=lan" write
by * none
access to dn.subtree="dc=mycompany,dc=lan"
by * search
access to * by * read
database mdb
maxsize 1073741824
overlay sssvlv
suffix "dc=mycompany,dc=lan"
rootdn "cn=root,dc=mycompany,dc=lan"
rootpw passwd_root
directory /var/db/openldap-data
index objectClass eq
Если добавляю строчки после moduleload back_mdb
Такого вида
access to * by * read
То авторизация по логину cn=adrbook,ou=adrbookusers,dc=mycompany,dc=lan
проходит успешно, но право добавлять записи в ou=addressbook,dc=mycompany,dc=lan отсутствует и выводится такая ошибка
Не удалось добавить объект на LDAP-сервер.
Сообщение LDAP: Insufficient access
Номер ошибки: 0x32 (LDAP_INSUFFICIENT_ACCESS)
Описание: You do not have sufficient permissions to perform that operation.
Тестовое создание контакта в phpLDAPadmin делаю так
- выбираю ou=addressbook
- далее "Создать потомка"
- далее Выбираю шаблон Общее: Запись в адресной книге(Generic: Address Book Entry (inetOrgPerson))
*** обязательные поля Фамилия и Общее имя
* в логе это фигурирует как Oct 2 20:41:49 srv slapd[54747]: conn=1009 op=2 ADD dn="cn=First_name Second_name,ou=addressbook,dc=mycompany,dc=lan"
Тут полный лог с момента выбора опций и до момента добавления и возникновения ошибки.
Ввиду объёмности, предоставил лог по ссылке http://www.heypasteit.com/clip/0IIUKJ
Егор,
какие можете дать рекомендации, может в целом подход другой нужен для той задачи что требуется ?
Кратко, то что требуется.
ou=adrbookusers,dc=mycompany,dc=lan
Создание, редактирование(через outlook или roundcubemail) и запись в адресную книгу некоторым пользователям, анонимное чтение любому пользователю.
ou=adrbookprivate,dc=mycompany,dc=lan
Редактирования(через outlook или roundcubemail), чтение и запись только через авторизацию.
-
Здравствуйте ещё раз. Чтобы внести ясность, придётся начать со структуры конфигурационного файла. Хоть это и не очевидно, но он разбит на разделы =) . Всё, что находится ПЕРЕД первой директивой database (или первой директивой backend) -- это глобальный раздел. То есть в Вашем случае к глобальному разделу относятся подключения файлов наборов схемы данных (include), местоположения фалов параметров (pidfile и argsfile), подгрузки динамических модулей (modulepath и moduleload) и настройки ACL (access). ПОСЛЕ директивы database (и до следующей директивы database или до конца файла) идут настройки конкретной БД, в Вашем случае это mdb с суффиксом dc=mycompany,dc=lan. Настройки глобального раздела либо относятся к самому slapd, либо распространяются на все базы данных (как в случае директив access). Именно об этом я писал в конце прошлого поста. Потому в приведённом мною примере slapd.conf итоговый набор ACL для БД будет выглядеть так:
access to dn.subtree="ou=adrbookusers,dc=mycompany,dc=lan" attrs=userPassword
by anonymous auth
by * none
access to dn.subtree="ou=addressbook,dc=mycompany,dc=lan"
by dn.base="cn=adrbook,ou=adrbookusers,dc=mycompany,dc=lan" write
by * none
access to dn.subtree="ou=adrbookprivate,dc=mycompany,dc=lan"
by dn.base="cn=userspriv,ou=adrbookusers,dc=mycompany,dc=lan" write
by * none
access to dn.subtree="dc=mycompany,dc=lan"
by * search
# это унаследовано из глобального раздела
access to dn.base=""
by * read
access to dn.base="cn=Subschema"
by * read
access to *
by * none
В Вашем же случае набор ACL выглядит так:
access to dn.base=""
by * read
access to dn.base="cn=Subschema"
by * read
access to * # <-- на этом этапе оценка ACL заканчивается
by * none
access to dn.subtree="ou=adrbookusers,dc=mycompany,dc=lan" attrs=userPassword
by anonymous auth
by * none
access to dn.subtree="ou=addressbook,dc=mycompany,dc=lan"
by dn.base="cn=adrbook,ou=adrbookusers,dc=mycompany,dc=lan" write
by * none
access to dn.subtree="ou=adrbookprivate,dc=mycompany,dc=lan"
by dn.base="cn=userspriv,ou=adrbookusers,dc=mycompany,dc=lan" write
by * none
access to dn.subtree="dc=mycompany,dc=lan"
by * search
access to * by * read
Как я опять же писал в предыдущем посте, ACL оцениваются один за другим до нахождения первого совпадения. 3-й ACL совпадает с любым объектом из БД и запрещает доступ всем, поэтому к Вашему каталогу доступа в принципе нет и быть не может. Если добавить в начало списка
access to * by * read
то у всех сразу появляется доступ на чтение и каталог становится виден. Всё просто, никакой мистики.
Теперь по Вашей задаче. Я бы на Вашем месте вообще не определял никаких глобальных ACL. Те ACL, которые я оставил в глобальном разделе в прошлый раз, не играют никакой роли -- так каталог будет работать и по умолчанию, я их оставил в качестве примера глобальных ACL (и, видимо, зря, только Вас запутал). Определите только НУЖНЫЕ Вам ACL в правильной последовательности (от более конкретных к более общим) в разделе БД:
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/misc.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/openldap.schema
#pidfile /var/run/openldap/slapd.pid
#argsfile /var/run/openldap/slapd.args
modulepath /usr/lib/ldap
moduleload back_mdb
database mdb
maxsize 1073741824
suffix "dc=mycompany,dc=lan"
rootdn "cn=root,dc=mycompany,dc=lan"
rootpw rootPassword
directory /data/openldap-experiments/2017-10-02-acl_concat/db/
index objectClass eq
access to dn.subtree="ou=adrbookusers,dc=mycompany,dc=lan" attrs=userPassword
by anonymous auth
by * none
access to dn.subtree="ou=addressbook,dc=mycompany,dc=lan"
by dn.base="cn=adrbook,ou=adrbookusers,dc=mycompany,dc=lan" write
by * read
access to dn.subtree="ou=adrbookprivate,dc=mycompany,dc=lan"
by dn.base="cn=userspriv,ou=adrbookusers,dc=mycompany,dc=lan" write
by * none
access to dn.subtree="dc=mycompany,dc=lan"
by * search
Во 2-м ACL я смягчил условие с by * none на by * read чтобы анонимные пользователи могли читать эту адресную книгу.
Егор
-
Егор, спасибо что уделяете время.
Теперь яснее стало, пробую дальше...
slapd.conf такой сделал
include /usr/local/etc/openldap/schema/core.schema
include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/inetorgperson.schema
include /usr/local/etc/openldap/schema/misc.schema
include /usr/local/etc/openldap/schema/nis.schema
include /usr/local/etc/openldap/schema/openldap.schema
pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args
modulepath /usr/local/libexec/openldap
moduleload back_mdb
database mdb
maxsize 1073741824
overlay sssvlv
suffix "dc=mycompany,dc=lan"
rootdn "cn=root,dc=mycompany,dc=lan"
rootpw passwd_root
directory /var/db/openldap-data
index objectClass eq
access to dn.subtree="ou=adrbookusers,dc=mycompany,dc=lan" attrs=userPassword
by anonymous auth
by * none
access to dn.subtree="ou=addressbook,dc=mycompany,dc=lan"
by dn.base="cn=adrbook,ou=adrbookusers,dc=mycompany,dc=lan" write
by * read
access to dn.subtree="ou=adrbookprivate,dc=mycompany,dc=lan"
by dn.base="cn=userspriv,ou=adrbookusers,dc=mycompany,dc=lan" write
by * none
access to dn.subtree="dc=mycompany,dc=lan"
by * search
Авторизация, поиск работает и записи внести можно через phpLDAPadmin.
Но только при авторизации пользователем cn=adrbook,ou=adrbookusers,dc=mycompany,dc=lan и cn=userspriv,ou=adrbookusers,dc=mycompany,dc=lan
Нету слева иерархии каталога, как это при логине через root.
B cлева надпись
dc=mycompany,dc=lan
This base cannot be created with PLA.
OutLook не соединяется.
Ошибка 81. Невозможно соединиться с сервером каталогов LDAP.
Логин использую - cn=adrbook,ou=adrbookusers,dc=mycompany,dc=lan
Пароль там простой пока - 1111
Вопрос собственно, требуется ещё донастройка ACL ?
-
Я поэтому и спрашивал, будет ли в каталоге что-то ещё? Если только адресные книги, то пользователю не нужно показывать лишнего. В общем, тут 2 пути:
1. В клиентах с анонимным подключением указать в качестве базовой записи не dc=mycompany,dc=lan а ou=addressbook,dc=mycompany,dc=lan , тогда они увидят всё что им нужно.
2. В последнем ACL вместо by * search указать by * read, тогда пользователи увидят весь каталог (кроме ветки ou=adrbookprivate,dc=mycompany,dc=lan, поскольку там by * none).
Егор
-
Работает как и требовалось, теперь буду пробовать дальше разные настройки!
Большое спасибо Егор за помощь в решении вопроса и подробное объяснение.