2. Динамические списки с перезаписью типов атрибутов: построение динамических POSIX-групп

Содержание

Постановка задачи

Предпосылки: В организации, сведения о которой ведутся в нашем каталоге, два отдела: Developers и Designers. Информация о принадлежности пользователя отделу фиксируется как значение атрибута ou в учётной записи каждого пользователя. Разграничение доступа на сервере VPN-подключений организации решено выполнить на основании принадлежности пользователей POSIX-группам соответствующих отделов.

Задача: Требуется создать POSIX-группы, постоянно отражающие актуальную структуру организации.

Решение

Как мы помним, POSIX-группы представляют собой записи-списки, в которых в значениях атрибута memberUid перечислены текстовые имена учётных записей пользователей UNIX, соответствующие тем, которые указываются в значении атрибута uid записей пользователей в каталоге. Как видно, имена атрибутов, содержащих нужную нам информацию, в записях пользователей и записях-списках не совпадают, и напрямую построить динамический список нужного формата не получится. Но наложение dynlist позволяет при построении динамических списков выполнять перезапись имён атрибутов, чем мы и воспользуемся.

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

Шаг 1. Настройка наложения dynlist

Первым делом нужно подгрузить модуль нашего наложения в работающий сервер slapd. Для этого требуется внести изменения в запись cn=module{0},cn=config:

dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: dynlist.la

Подгрузим наш модуль и убедимся, что он загружен:

$ ldapmodify -x -D cn=config -W -f ./101-add_dynlist_module.ldif
Enter LDAP Password: 
modifying entry "cn=module{0},cn=config"

$ ldapsearch -xLLL -D cn=config -W -b cn=module{0},cn=config olcModuleLoad
Enter LDAP Password: 
dn: cn=module{0},cn=config
olcModuleLoad: {0}back_mdb.la
olcModuleLoad: {1}dynlist.la

Переходим к настройкам наложения. Для данного примера мы сформируем такую запись наложения с объектным классом olcDynamicList (дочернюю по отношению к рабочей базе данных):

dn: olcOverlay=dynlist,olcDatabase={1}mdb,cn=config
objectClass: olcDynamicList
olcOverlay: dynlist
olcDLattrSet: posixGroup labeledURI memberUid:uid

Параметры работы наложения задаются значением атрибута olcDLattrSet (строка 4). В данном случае у нас три разделённых пробелами параметра: имя объектного класса (posixGroup), имя типа атрибута (labeledURI), а также определение правила перезаписи имени атрибута (memberUid:uid). Назначение первых двух параметров мы подробно разбирали в предыдущем примере: это объектный класс и тип атрибута, по которым наложение dynlist отбирает среди результирующего набора операции поиска LDAP те записи, которые требуется дополнить динамическим содержимым. Обратите внимание, что для данного примера мы выбрали "нетипичные" для наложения dynlist класс и тип атрибута. Отчасти это сделано для того, чтобы продемонстрировать, что с наложением dynlist можно использовать любые известные серверу slapd классы и типы атрибутов. Другая же причина в том, что многие приложения, проверяющие права пользователей на основе сведений из каталога, понимают класс posixGroup как "стандартный", к тому же на нём как раз и строятся POSIX-группы.

Наиболее интересен для нас третий параметр настройки наложения. В данном примере он представляет собой два имени атрибута, разделённых символом двоеточия. Такой синтаксис говорит о том, что наложению задаётся правило перезаписи имён атрибутов, которое формулируется так: если среди атрибутов, возвращаемых в результате вторичного поискового запроса, выполняемого с целью сбора динамического содержимого записи, будут возвращены атрибуты типа uid, то в них имя атрибута будет заменено на memberUid. Значение же атрибута останется неизменным. Простое действие, которое позволит сформировать запись-список, полностью отвечающий условию нашей задачи.

Следует отметить, что в настройках наложения dynlist можно задавать несколько таких правил перезаписи, отделяя их друг от друга пробелом. Но для нашей задачи это не требуется.

Итак, добавим нашу запись с настройками наложения и убедимся в её наличии:

$ ldapadd -x -D cn=config -W -f ./102-add_dynlist_overlay.ldif
Enter LDAP Password:
adding new entry "olcOverlay=dynlist,olcDatabase={1}mdb,cn=config"

$ ldapsearch -xLLL -D cn=config -W -b olcDatabase={1}mdb,cn=config -s one
Enter LDAP Password:
dn: olcOverlay={0}dynlist,olcDatabase={1}mdb,cn=config
objectClass: olcDynamicList
olcOverlay: {0}dynlist
olcDlAttrSet: {0}posixGroup labeledURI memberUid:uid

Наложение стало первым (индекс 0) для нашей рабочей базы данных. Пора переходить к следующему этапу.

Шаг 2. Добавление записей динамических POSIX-групп

По условиям задачи составим определения динамических списков (POSIX-групп) для наших отделов Developers и Designers, поместив их в отдельный контейнер с именем PosixGroups:

dn: ou=PosixGroups,dc=mycompany,dc=ru
objectClass: organizationalUnit
ou: PosixGroups

dn: cn=Developers,ou=PosixGroups,dc=mycompany,dc=ru
objectClass: posixGroup
objectClass: labeledURIObject
cn: Developers
gidNumber: 10001
labeledURI: ldap:///ou=People,dc=mycompany,dc=ru?uid?one?(&(objectClass=inetOrgPerson)(ou=Developers))

dn: cn=Designers,ou=PosixGroups,dc=mycompany,dc=ru
objectClass: posixGroup
objectClass: labeledURIObject
cn: Designers
gidNumber: 10002
labeledURI: ldap:///ou=People,dc=mycompany,dc=ru?uid?one?(&(objectClass=inetOrgPerson)(ou=Designers))

Записи POSIX-групп строятся на структурном объектном классе posixGroup, его обязательные атрибуты cn (который мы использовали для формирования RDN) и gidNumber (наследие NIS для хранения числового идентификатора группы в UNIX). Условия для поиска динамического содержимого оформлены в виде LDAP URI в значениях атрибутов labeledURI динамических записей (строки 10 и 17). Поскольку тип атрибута labeledURI не входит в число обязательных или допустимых атрибутов класса posixGroup, для включения таких атрибутов в наши записи мы воспользовались вспомогательным объектным классом labeledURIObject, содержащим этот тип атрибута и позволяющим включить его в запись.

Сами LDAP URI мало чем отличаются от подробно разобранных нами в предыдущем примере URI: согласно указанных в них критериев поиска, среди записей пользователей будут отобраны те, у которых есть признак принадлежности к конкретному отделу. Отличается только список возвращаемых атрибутов (4-й компонент URI): в данном случае из найденных записей будут извлекаться только атрибуты uid.

Добавим наши записи в каталог:

$ ldapadd -D cn=manager,ou=System,dc=mycompany,dc=ru -W -f ./002-add_posix_groups.ldif
Enter LDAP Password:
adding new entry "ou=PosixGroups,dc=mycompany,dc=ru"

adding new entry "cn=Developers,ou=PosixGroups,dc=mycompany,dc=ru"

adding new entry "cn=Designers,ou=PosixGroups,dc=mycompany,dc=ru"

Посмотрим, что получилось:

$ ldapsearch -xLLL -b dc=mycompany,dc=ru -o ldif-wrap=no '(objectClass=posixGroup)'
dn: cn=Developers,ou=PosixGroups,dc=mycompany,dc=ru
objectClass: posixGroup
objectClass: labeledURIObject
cn: Developers
gidNumber: 10001
labeledURI: ldap:///ou=People,dc=mycompany,dc=ru?uid?one?(&(objectClass=inetOrgPerson)(ou=Developers))

dn: cn=Designers,ou=PosixGroups,dc=mycompany,dc=ru
objectClass: posixGroup
objectClass: labeledURIObject
cn: Designers
gidNumber: 10002
labeledURI: ldap:///ou=People,dc=mycompany,dc=ru?uid?one?(&(objectClass=inetOrgPerson)(ou=Designers))

А где же, собственно, атрибуты принадлежности списку memberUid, то есть динамическое содержимое записей? Что-то пошло не так и наложение dynlist не сработало? Да нет, всё так, просто в наших записях пользователей ещё нет признака принадлежности отделу.

Шаг 3. Модификация учётных записей пользователей

Дополним записи пользователей признаком принадлежности к отделам. Для этого сформируем такой LDIF-файл:

dn: uid=antonova,ou=People,dc=mycompany,dc=ru
changetype: modify
add: ou
ou: Designers

dn: uid=ivanov,ou=People,dc=mycompany,dc=ru
changetype: modify
add: ou
ou: Developers

dn: uid=petrov,ou=People,dc=mycompany,dc=ru
changetype: modify
add: ou
ou: Developers

dn: uid=sidorov,ou=People,dc=mycompany,dc=ru
changetype: modify
add: ou
ou: Designers

Применим его к нашему каталогу и посмотрим, в каком состоянии будут наши учётки после модификации:

$ ldapmodify -x -D cn=manager,ou=System,dc=mycompany,dc=ru -W -f ./003-add_users_attributes.ldif
Enter LDAP Password:
modifying entry "uid=antonova,ou=People,dc=mycompany,dc=ru"

modifying entry "uid=ivanov,ou=People,dc=mycompany,dc=ru"

modifying entry "uid=petrov,ou=People,dc=mycompany,dc=ru"

modifying entry "uid=sidorov,ou=People,dc=mycompany,dc=ru"

$ ldapsearch -xLLL -b ou=People,dc=mycompany,dc=ru -s one
dn: uid=ivanov,ou=People,dc=mycompany,dc=ru
objectClass: inetOrgPerson
uid: ivanov
cn: Ivan Ivanov
sn: Ivanov
ou: Developers

dn: uid=petrov,ou=People,dc=mycompany,dc=ru
objectClass: inetOrgPerson
uid: petrov
cn: Petr Petrov
sn: Petrov
ou: Developers

dn: uid=sidorov,ou=People,dc=mycompany,dc=ru
objectClass: inetOrgPerson
uid: sidorov
cn: Sidor Sidorov
sn: Sidorov
ou: Designers

dn: uid=antonova,ou=People,dc=mycompany,dc=ru
objectClass: inetOrgPerson
uid: antonova
cn: Antonina Antonova
sn: Antonova
ou: Designers

Всё в порядке. А теперь ещё раз запросим наши POSIX-группы:

$ ldapsearch -xLLL -b dc=mycompany,dc=ru -o ldif-wrap=no '(objectClass=posixGroup)'
dn: cn=Developers,ou=PosixGroups,dc=mycompany,dc=ru
objectClass: posixGroup
objectClass: labeledURIObject
cn: Developers
gidNumber: 10001
labeledURI: ldap:///ou=People,dc=mycompany,dc=ru?uid?one?(&(objectClass=inetOrgPerson)(ou=Developers))
memberUid: ivanov
memberUid: petrov

dn: cn=Designers,ou=PosixGroups,dc=mycompany,dc=ru
objectClass: posixGroup
objectClass: labeledURIObject
cn: Designers
gidNumber: 10002
labeledURI: ldap:///ou=People,dc=mycompany,dc=ru?uid?one?(&(objectClass=inetOrgPerson)(ou=Designers))
memberUid: antonova
memberUid: sidorov

Как видно, наше наложение успешно справилось и с задачей наполнения записей динамическим содержимым, и с перезаписью имён атрибутов: у нас получились корректные POSIX-группы с нужными атрибутами членства в них.

Что ещё можно сделать

У наложения dynlist есть ещё один параметр настройки, с помощью которого можно ограничить область действия наложения. Чтобы не нарушать очерёдность перечисления параметров наложения, мы будем называть его промежуточным параметром, поскольку, при необходимости, его можно указать между первым (имя объектного класса, на который срабатывает наложение) и вторым параметром (имя атрибута, в котором указаны критерии вторичного поиска). То есть, если вслед за первым параметром в настройках наложения вместо имени атрибута указан LDAP URI, то наложение будет воспринимать его как тот самый промежуточный параметр.

Итак, промежуточный параметр представляет собой LDAP URI, с помощью компонентов которого (базовой записи, поискового диапазона и фильтра отбора) задаётся область действия наложения. При указании промежуточного параметра наложение будет применяться не ко всем записям, попавшим в результирующий набор первоначальной операции поиска, а только к подмножеству этих записей, удовлетворяющих условиям, заданным в URI этого параметра.

Разберём применение промежуточного параметра на примере. Допустим, в ветку ou=Groups,dc=mycompany,dc=ru также добавляются записи, на которые будет реагировать наложение dynlist с указанными нами настройками:

dn: cn=Developers2,ou=Groups,dc=mycompany,dc=ru
objectClass: posixGroup
objectClass: labeledURIObject
cn: Developers2
gidNumber: 10011
labeledURI: ldap:///ou=People,dc=mycompany,dc=ru?uid?one?(&(objectClass=inetOrgPerson)(ou=Developers))

dn: cn=Designers2,ou=Groups,dc=mycompany,dc=ru
objectClass: posixGroup
objectClass: labeledURIObject
cn: Designers2
gidNumber: 10012
labeledURI: ldap:///ou=People,dc=mycompany,dc=ru?uid?one?(&(objectClass=inetOrgPerson)(ou=Designers))

Добавим эти записи в каталог:

$ ldapadd -D cn=manager,ou=System,dc=mycompany,dc=ru -W -f ./004-add_posix_groups2.ldif
Enter LDAP Password:
adding new entry "cn=Developers2,ou=Groups,dc=mycompany,dc=ru"

adding new entry "cn=Designers2,ou=Groups,dc=mycompany,dc=ru"

Проверим работу наложения dynlist:

$ ldapsearch -xLLL -b dc=mycompany,dc=ru -o ldif-wrap=no '(objectClass=posixGroup)' memberUid
dn: cn=Developers,ou=PosixGroups,dc=mycompany,dc=ru
memberUid: ivanov
memberUid: petrov

dn: cn=Designers,ou=PosixGroups,dc=mycompany,dc=ru
memberUid: antonova
memberUid: sidorov

dn: cn=Developers2,ou=Groups,dc=mycompany,dc=ru
memberUid: ivanov
memberUid: petrov

dn: cn=Designers2,ou=Groups,dc=mycompany,dc=ru
memberUid: antonova
memberUid: sidorov

Наложение отработало великолепно: все четыре наших POSIX-группы дополнились динамическим содержимым.

А теперь попытаемся ограничить область действия наложения так, чтобы динамическим содержимым дополнялись только записи в ветке ou=PosixGroups,dc=mycompany,dc=ru. Дополним настройки наложения промежуточным параметром:

dn: olcOverlay={0}dynlist,olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcDLattrSet
olcDLattrSet: posixGroup ldap:///ou=PosixGroups,dc=mycompany,dc=ru??one? labeledURI memberUid:uid

Интересующие нас изменения представлены в строке 4. В параметрах наложения между именем объектного класса (posixGroup) и именем типа атрибута (labeledURI) мы поместили LDAP URI — тот самый промежуточный параметр. Согласно критериям, заданным компонентами этого URI, наложение будет обрабатывать только записи, непосредственно дочерние (диапазон one) записи ou=PosixGroups,dc=mycompany,dc=ru. Поисковый фильтр не задан, поэтому будут рассматриваться все записи, отвечающие первым двум критериям.

Применим наши изменения и проверим:

$ ldapmodify -x -D cn=config -W -f ./103-modify_dynlist_overlay.ldif
Enter LDAP Password: 
modifying entry "olcOverlay={0}dynlist,olcDatabase={1}mdb,cn=config"

$ ldapsearch -xLLL -D cn=config -W -b olcDatabase={1}mdb,cn=config -s one -o ldif-wrap=no
Enter LDAP Password:
dn: olcOverlay={0}dynlist,olcDatabase={1}mdb,cn=config
objectClass: olcDynamicList
olcOverlay: {0}dynlist
olcDlAttrSet: {0}posixGroup ldap:///ou=PosixGroups,dc=mycompany,dc=ru??one? labeledURI memberUid:uid

Теперь посмотрим, как это повлияло на работу нашего наложения:

$ ldapsearch -xLLL -b dc=mycompany,dc=ru -o ldif-wrap=no '(objectClass=posixGroup)' memberUid
dn: cn=Developers,ou=PosixGroups,dc=mycompany,dc=ru
memberUid: ivanov
memberUid: petrov

dn: cn=Designers,ou=PosixGroups,dc=mycompany,dc=ru
memberUid: antonova
memberUid: sidorov

dn: cn=Developers2,ou=Groups,dc=mycompany,dc=ru

dn: cn=Designers2,ou=Groups,dc=mycompany,dc=ru

Как видно, записи в ветке ou=Groups,dc=mycompany,dc=ru не получили динамического содержимого, следовательно, наши ограничения работают.

Итоговые настройки

В ходе этого урока мы познакомились с одним из вариантов третьего параметра настроек наложения dynlist, отвечающим за перезапись имён атрибутов при построении динамического содержимого. Кроме того, была рассмотрена возможность установки ограничений на область действия наложения с помощью промежуточного параметра в настройках. Итоговые настройки каталога dc=mycompany,dc=ru выглядят так:

$ ldapsearch -xLLL -o ldif-wrap=no -D cn=config -W -b olcDatabase={1}mdb,cn=config
Enter LDAP Password:
dn: olcDatabase={1}mdb,cn=config
objectClass: olcMdbConfig
olcDatabase: {1}mdb
olcDbDirectory: /var/lib/ldap/dc=mycompany,dc=ru
olcSuffix: dc=mycompany,dc=ru
olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {1}to * by self write by * read
olcRootDN: cn=manager,ou=System,dc=mycompany,dc=ru
olcRootPW: {SSHA}PKFrwbIL/zLd3gabPPLxn1vNq2jQHj4g
olcDbIndex: objectClass eq
olcDbIndex: cn eq,sub,subinitial

dn: olcOverlay={0}dynlist,olcDatabase={1}mdb,cn=config
objectClass: olcDynamicList
olcOverlay: {0}dynlist
olcDlAttrSet: {0}posixGroup ldap:///ou=PosixGroups,dc=mycompany,dc=ru??one? labeledURI memberUid:uid
Pro-LDAP.ru 2013-2019 г. Последнее изменение страницы — 28 декабря 2018 г. Вопросы и предложения принимаются на форуме проекта.