12. Наложения

Наложения - это программные компоненты, переопределяющие поведение функций, выполняемых механизмами манипуляции данными. Они располагаются "над" механизмами манипуляции, перехватывая и перенаправляя им обращения, направленные от клиента, а также перехватывая ответы механизмов манипуляции и перенаправляя их клиентам. При этом информация, передаваемая и получаемая от механизма манипуляции данными, может изменяться, изменяя тем самым поведение механизмов манипуляции.

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

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

Итак, наложения предназначены для:

При использовании slapd.conf(5), наложения, сконфигурированные до настроек какой-либо базы данных, считаются глобальными, как было описано выше. На самом деле они неявно накладываются на базу данных frontend. Их также можно наложить явно, прописав следующую конфигурацию:

        database frontend
        overlay <имя наложения>

Обычно документация к наложению помещается в отдельную man-страницу в секции 5; общепринятое именование таких страниц:

        slapo-<имя наложения>

Все основные наложения, входящие в дистрибутив, имеют man-страницы. Вы можете смело их дополнять, если считаете, что что-то упущено в описании поведения компонента или применении соответствующих директив конфигурации.

Официально-поддерживаемые наложения располагаются в директории

        servers/slapd/overlays/

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

Другие распространённые наложения расположены в

        contrib/slapd-modules/<имя наложения>/

вместе с другими типами компонентов, загружаемых во время выполнения сервера; они официально распространяются, но не поддерживаются проектом.

Все текущие наложения в OpenLDAP перечислены и подробно описаны в следующих разделах.


12.1. Ведение журнала доступа

12.1.1. Обзор

Данное наложение записывает попытки доступа к определённой базе данных в другую базу данных.

Это позволяет выполнять различные выборки пользовательских обращений к целевой базе данных из любой точки сети с помощью разнообразных LDAP-запросов, а не просто просматривать обычные локальные текстовые файлы журналов. С помощью опций конфигурации можно настроить, какие типы операций доступа попадут в журнал, и когда следует автоматически чистить базу данных журнала от устаревших записей. Записи журнала хранятся как экземпляры объектных классов набора схемы audit для обеспечения их читабельности в виде файлов LDIF либо в форме ответов на поисковые запросы.

Данное наложение используется также для дельта-syncrepl репликации

12.1.2. Настройка наложения ведения журнала доступа

Вот простой пример применения журналирования доступа:

        database bdb
        suffix dc=example,dc=com
        ...
        overlay accesslog
        logdb cn=log
        logops writes reads
        logold (objectclass=person)

        database bdb
        suffix cn=log
        ...
        index reqStart eq
        access to *
          by dn.base="cn=admin,dc=example,dc=com" read

А следующий пример используется для дельта-syncrepl репликации:

        database hdb
        suffix cn=accesslog
        directory /usr/local/var/openldap-accesslog
        rootdn cn=accesslog
        index default eq
        index entryCSN,objectClass,reqEnd,reqResult,reqStart

Установки наложения accesslog для основной базы данных:

        database bdb
        suffix dc=example,dc=com
        ...
        overlay accesslog
        logdb cn=accesslog
        logops writes
        logsuccess TRUE
        # проверять БД accesslog каждый день и удалять записи старше 7-ми дней
        logpurge 07+00:00 01+00:00

Пример данных, возвращаемых поисковым запросом к ветви cn=accesslog:

        [ghenry@suretec ghenry]# ldapsearch -x -b cn=accesslog
        # extended LDIF
        #
        # LDAPv3
        # base <cn=accesslog> with scope subtree
        # filter: (objectclass=*)
        # requesting: ALL
        #

        # accesslog
        dn: cn=accesslog
        objectClass: auditContainer
        cn: accesslog

        # 20080110163829.000004Z, accesslog
        dn: reqStart=20080110163829.000004Z,cn=accesslog
        objectClass: auditModify
        reqStart: 20080110163829.000004Z
        reqEnd: 20080110163829.000005Z
        reqType: modify
        reqSession: 196696
        reqAuthzID: cn=admin,dc=suretecsystems,dc=com
        reqDN: uid=suretec-46022f8$,ou=Users,dc=suretecsystems,dc=com
        reqResult: 0
        reqMod: sambaPwdCanChange:- ###CENSORED###
        reqMod: sambaPwdCanChange:+ ###CENSORED###
        reqMod: sambaNTPassword:- ###CENSORED###
        reqMod: sambaNTPassword:+ ###CENSORED###
        reqMod: sambaPwdLastSet:- ###CENSORED###
        reqMod: sambaPwdLastSet:+ ###CENSORED###
        reqMod: entryCSN:= 20080110163829.095157Z#000000#000#000000
        reqMod: modifiersName:= cn=admin,dc=suretecsystems,dc=com
        reqMod: modifyTimestamp:= 20080110163829Z

        # search result
        search: 2
        result: 0 Success

        # numResponses: 3
        # numEntries: 2

12.1.3. Дополнительная информация

slapo-accesslog(5) и раздел дельта-syncrepl репликаций.


12.2. Ведение журнала изменений

Данное наложение может быть использовано для складирования всех изменений, произошедших в определённой базе данных, в указанный файл журнала.

12.2.1. Обзор

Если возникает потребность журналировать изменения в виде стандартного LDIF, есть возможность применить наложение auditlog. Подробные примеры его использования можно найти в man-странице slapo-auditlog (5).

12.2.2. Настройка наложения ведения журнала изменений

Если служба каталогов настраивается через slapd.d, то можно использовать следующий LDIF, чтобы добавить наложение к списку наложений в cn=config и указать в какой файл будет записываться журнал в формате LDIF (измените путь и название файла под Ваши нужды):

       dn: olcOverlay=auditlog,olcDatabase={1}hdb,cn=config
       changetype: add
       objectClass: olcOverlayConfig
       objectClass: olcAuditLogConfig
       olcOverlay: auditlog
       olcAuditlogFile: /tmp/auditlog.ldif

В этом тестовом примере мы складываем изменения в файл /tmp/auditlog.ldif

Типичный LDIF-файл, создаваемый slapo-auditlog(5), выглядит следующим образом:

       # add 1196797576 dc=suretecsystems,dc=com cn=admin,dc=suretecsystems,dc=com
       dn: dc=suretecsystems,dc=com
       changetype: add
       objectClass: dcObject
       objectClass: organization
       dc: suretecsystems
       o: Suretec Systems Ltd.
       structuralObjectClass: organization
       entryUUID: 1606f8f8-f06e-1029-8289-f0cc9d81e81a
       creatorsName: cn=admin,dc=suretecsystems,dc=com
       modifiersName: cn=admin,dc=suretecsystems,dc=com
       createTimestamp: 20051123130912Z
       modifyTimestamp: 20051123130912Z
       entryCSN: 20051123130912.000000Z#000001#000#000000
       auditContext: cn=accesslog
       # end add 1196797576

       # add 1196797577 dc=suretecsystems,dc=com cn=admin,dc=suretecsystems,dc=com
       dn: ou=Groups,dc=suretecsystems,dc=com
       changetype: add
       objectClass: top
       objectClass: organizationalUnit
       ou: Groups
       structuralObjectClass: organizationalUnit
       entryUUID: 160aaa2a-f06e-1029-828a-f0cc9d81e81a
       creatorsName: cn=admin,dc=suretecsystems,dc=com
       modifiersName: cn=admin,dc=suretecsystems,dc=com
       createTimestamp: 20051123130912Z
       modifyTimestamp: 20051123130912Z
       entryCSN: 20051123130912.000000Z#000002#000#000000
       # end add 1196797577

12.2.3. Дополнительная информация

slapo-auditlog(5)


12.3. Сцепление

12.3.1. Обзор

Это наложение обеспечивает возможность простого сцепления между серверами, обслуживающими базу данных LDAP.

Что такое сцепление? Оно представляет собою возможность DSA следовать по отсылкам LDAP от имени клиентов, которые сами "перейти" по этим отсылкам не могут. Таким образом, с точки зрения клиента, распределённая система представляется как единственный виртуальный DSA.

Наложение сцепления накладывается поверх механизма манипуляции данными ldap; оно компилируется автоматически, если при запуске configure была указана опция --enable-ldap.

12.3.2. Настройка наложения сцепления

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

На каждой реплике в начале файла slapd.conf(5) (глобальные настройки, до определения какой-либо базы данных) добавляются следующие строки:

        overlay                    chain
        chain-uri                  "ldap://ldapmaster.example.com"
        chain-idassert-bind        bindmethod="simple"
                                   binddn="cn=Manager,dc=example,dc=com"
                                   credentials="<secret>"
                                   mode="self"
        chain-tls                  start
        chain-return-error         TRUE

В настройках syncrepl добавляется:

        updateref                  "ldap://ldapmaster.example.com/"

Директива chain-tls включает TLS между подчинённым и основным ldap-сервером. Поскольку на всех серверах одинаковые DIT, DN пользователя, подключающегося к подчинённому серверу, существует и на основном сервере. Если на основном сервере у этого DN нет прав на обновление, операция будет просто проигнорирована и ничего не произойдёт.

После внесения изменений в slapd.conf требуется перезапустить демоны на подчинённых серверах (при использовании cn=config перезапуск не требуется). После этого, если Вы используете уровень журналирования stats (256), Вы можете отследить изменения, вносимые, например, с помощью ldapmodify, на подчинённых и основном серверах.

Итак, запустим ldapmodify на подчинённом сервере и посмотрим записи журнала. Там будет что-то вроде:

        Sep  6 09:27:25 slave1 slapd[29274]: conn=11 fd=31 ACCEPT from IP=143.199.102.216:45181 (IP=143.199.102.216:389)
        Sep  6 09:27:25 slave1 slapd[29274]: conn=11 op=0 STARTTLS
        Sep  6 09:27:25 slave1 slapd[29274]: conn=11 op=0 RESULT oid= err=0 text=
        Sep  6 09:27:25 slave1 slapd[29274]: conn=11 fd=31 TLS established tls_ssf=256 ssf=256
        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=1 BIND dn="uid=user1,ou=people,dc=example,dc=com" method=128
        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=1 BIND dn="uid=user1,ou=People,dc=example,dc=com" mech=SIMPLE ssf=0
        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=1 RESULT tag=97 err=0 text=
        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=2 MOD dn="uid=user1,ou=People,dc=example,dc=com"
        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=2 MOD attr=mail
        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=2 RESULT tag=103 err=0 text=
        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=3 UNBIND
        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 fd=31 closed
        Sep  6 09:27:28 slave1 slapd[29274]: syncrepl_entry: LDAP_RES_SEARCH_ENTRY(LDAP_SYNC_MODIFY)
        Sep  6 09:27:28 slave1 slapd[29274]: syncrepl_entry: be_search (0)
        Sep  6 09:27:28 slave1 slapd[29274]: syncrepl_entry: uid=user1,ou=People,dc=example,dc=com
        Sep  6 09:27:28 slave1 slapd[29274]: syncrepl_entry: be_modify (0)

А на основном сервере будет такое:

        Sep  6 09:23:57 ldapmaster slapd[2961]: conn=55902 op=3 PROXYAUTHZ dn="uid=user1,ou=people,dc=example,dc=com"
        Sep  6 09:23:57 ldapmaster slapd[2961]: conn=55902 op=3 MOD dn="uid=user1,ou=People,dc=example,dc=com"
        Sep  6 09:23:57 ldapmaster slapd[2961]: conn=55902 op=3 MOD attr=mail
        Sep  6 09:23:57 ldapmaster slapd[2961]: conn=55902 op=3 RESULT tag=103 err=0 text=


Замечание: Обратите внимание на строку PROXYAUTHZ в записях журнала основного сервера, она говорит о использовании верных идентификационных данных при выполнении операции обновления на основном сервере. Также имейте ввиду, что подчинённые сервера немедленно получают Syncrepl-обновления с основного сервера.

12.3.3. Обработка ошибок сцепления

По умолчанию, если операция обновления при сцеплении окончилось неудачей, клиенту возвращается оригинальная отсылка для того, чтобы он мог сам попробовать перейти по этой отсылке.

Однако, при использовании следующей директивы, если операция обновления при сцеплении окончилось неудачей на стороне сервера, клиенту возвращается актуальная ошибка.

        chain-return-error TRUE

12.3.4. Чтение изменений, внесенных с использованием сцепления

Иногда приложениям требуется заново прочитать данные, которые они только что записали. Если запрос на изменение данных на подчиненном сервере был перенаправлен на основной сервер, немедленный запрос данных с подчиненного сервера может привести к тому, что будут получены данные, которые еще не были синхронизированы. В подобных случаях клиентам нужно использовать элемент управления dontusecopy для получения актуальных данных напрямую с основного сервера.

Обычно, при получении элемента управления dontusecopy, клиенту возвращается отсылка на актуальный источник данных. Однако, при использовании наложения slapo-chain(5), оно перехватывает такие отсылки и пытается самостоятельно получить запрашиваемые данные.

12.3.5. Дополнительная информация

slapo-chain(5)


12.4. Ограничения на значения

12.4.1. Обзор

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

12.4.2. Настройка наложения ограничений

Пример конфигурации через slapd.conf(5):

        overlay constraint
        constraint_attribute mail regex ^[[:alnum:]]+@mydomain.com$
        constraint_attribute title uri ldap:///dc=catalog,dc=example,dc=com?title?sub?(objectClass=titleCatalog)

С подобными настройками будет отклоняться любой атрубут mail, содержимое которого не соответствует <буквенно-цифровая строка>@mydomain.com.

Также будет отклоняться любой атрибут title, значения которого не встречаются в атрибутах title любых записей titleCatalog в указанной области поиска.

Тот же пример с использованием cn=config:

       dn: olcOverlay=constraint,olcDatabase={1}hdb,cn=config
       changetype: add
       objectClass: olcOverlayConfig
       objectClass: olcConstraintConfig
       olcOverlay: constraint
       olcConstraintAttribute: mail regex ^[[:alnum:]]+@mydomain.com$
       olcConstraintAttribute: title uri ldap:///dc=catalog,dc=example,dc=com?title?sub?(objectClass=titleCatalog)

12.4.3. Дополнительная информация

slapo-constraint(5)


12.5. Динамические службы каталогов (Dynamic Directory Services)

12.5.1. Обзор

Наложение dds реализует в slapd(8) динамические объекты в соответствии с RFC2589. Название dds - акроним от Dynamic Directory Services (динамические службы каталогов). Данное наложение позволяет определить динамические объекты, описываемые объектным классом dynamicObject.

Время жизни динамических объектов ограничено и определяется так называемым time-to-live (TTL, время жизни), которое может быть обновлено с помощью специальной операции расширенного обновления. Эта операция позволяет задать Client Refresh Period (CRP, клиентский период обновления), а именно промежуток времени между обновлениями, необходимый для предохранения динамического объекта от истечения срока его действия. Срок действия вычисляется путём добавления запрашиваемого TTL к текущему времени. Если объект достигает конца срока жизни и этот срок не был дополнительно обновлён, то такой объект автоматически удаляется. Однако нет гарантии, что объект будет удалён немедленно, поэтому клиенты не должны на это рассчитывать.

12.5.2. Настройка наложения динамических служб каталогов

Рассмотрим использование динамических объектов на примере реализации проведения динамических собраний. Для определённости установим, что участники собрания могут обновлять объект собрания, но только создатель данного объекта собрания может его удалить (либо он удалится по истечении TTL).

Применяя данное наложение к базе данных нашего примера, установим максимальное время жизни объекта в 1 день, минимальное - 10 секунд, а время жизни по умолчанию - 1 час. Мы также установим интервал проверок устаревания объекта в 120 секунд (менее 60-ти будет слишком мало), и срок толерантности в 5 секунд (фактическое время жизни объекта таким образом будет entryTtl + срок толерантности).

       overlay dds
       dds-max-ttl     1d
       dds-min-ttl     10s
       dds-default-ttl 1h
       dds-interval    120s
       dds-tolerance   5s

и добавим индекс:

       entryExpireTimestamp

Создадим собрание следующей записью:

       dn: cn=OpenLDAP Documentation Meeting,ou=Meetings,dc=example,dc=com
       objectClass: groupOfNames
       objectClass: dynamicObject
       cn: OpenLDAP Documentation Meeting
       member: uid=ghenry,ou=People,dc=example,dc=com
       member: uid=hyc,ou=People,dc=example,dc=com

12.5.2.1. Контроль доступа к динамическим службам каталога

Разрешим пользователям создавать новое собрание и присоединяться к существующим; операции обновления TTL разрешим только пользователям, перечисленным в атрибутах member; создателю разрешим удаление объекта:

       access to attrs=userPassword
          by self write
          by * read

       access to dn.base="ou=Meetings,dc=example,dc=com"
                 attrs=children
            by users write

       access to dn.onelevel="ou=Meetings,dc=example,dc=com"
                 attrs=entry
            by dnattr=creatorsName write
            by * read

       access to dn.onelevel="ou=Meetings,dc=example,dc=com"
                 attrs=participant
            by dnattr=creatorsName write
            by users selfwrite
            by * read

       access to dn.onelevel="ou=Meetings,dc=example,dc=com"
                 attrs=entryTtl
            by dnattr=member manage
            by * read

Проще говоря, пользователь, создавший OpenLDAP Documentation Meeting, может добавлять новых участников, обновлять время жизни собрания (практически, полный контроль):

       ldapexop -x -H ldap://ldaphost "refresh" "cn=OpenLDAP Documentation Meeting,ou=Meetings,dc=example,dc=com" "120" -D "uid=ghenry,ou=People,dc=example,dc=com" -W

Любой пользователь может присоединиться к собранию, но не может добавить другого участника; кроме того, участники могут обновлять время жизни собрания. Приведенные выше ACL достаточно прямолинейны и понятны, чтобы в этом разобраться.

12.5.3. Дополнительная информация

slapo-dds(5)


12.6. Динамические группы

12.6.1. Обзор

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


12.7. Динамические списки

12.7.1. Обзор

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

12.7.2. Настройка наложения динамических списков

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

       overlay dynlist
       dynlist-attrset <group-oc> <URL-ad> [member-ad]

Параметры директивы dynlist-attrset имеют следующие значения:

Следующий пример создаёт почтовый псевдоним, ссылающийся автоматически на адреса электронной почты всех пользователей из диапазона, заданного фильтрами нашего поискового LDAP-запроса:

В файле slapd.conf(5) укажем следующее:

       overlay dynlist
       dynlist-attrset nisMailAlias labeledURI

Это значит, что при извлечении записи, содержащей объектный класс nisMailAlias, будет выполняться поисковый запрос по URI, указанному в атрибуте labeledURI.

Допустим, в нашем каталоге есть такая запись:

       cn=all,ou=aliases,dc=example,dc=com
       cn: all
       objectClass: nisMailAlias
       labeledURI: ldap:///ou=People,dc=example,dc=com?mail?one?(objectClass=inetOrgPerson)

При её извлечении будет выполнен поисковый запрос согласно значению labeledURI, и его результаты будут подставлены к записи, как будто они всегда тут и были. В данном случае поисковый фильтр выбирает все записи на один уровень ниже ou=People, имеющие объектный класс inetOrgPerson, и извлекает из них атрибут mail, если таковой имеется.

Вот что добавится к нашей записи, если в ветви ou=People нашлись две записи о пользователях, удовлетворяющие фильтру:

Рисунок 12.1: Динамический список всех адресов электронной почты

Конфигурация для динамической группы аналогична. Рассмотрим пример, автоматически заполняющий группу allusers group всеми учетными записями пользователей из определённой ветви каталога.

В файле slapd.conf(5) укажем следующее:

       include /path/to/dyngroup.schema
       ...
       overlay dynlist
       dynlist-attrset groupOfURLs labeledURI member


Замечание: Для нашего примера нужно подключить файл dyngroup.schema, в котором определяется объектный класс groupOfURLs.

Попробуем применить наши настройки к следующей записи:

       cn=allusers,ou=group,dc=example,dc=com
       cn: all
       objectClass: groupOfURLs
       labeledURI: ldap:///ou=people,dc=example,dc=com??one?(objectClass=inetOrgPerson)

В данном случае всё происходит аналогично предыдущему примеру с динамическими списками: при извлечении записи с объектным классом groupOfURLs, выполняется поисковый запрос, определённый в атрибуте labeledURI. Но на этот раз получаются только DN найденных записей, и они добавляются к нашей исходной записи как значения атрибута member.

Вот что мы получим:

Рисунок 12.2: Динамическая группа всех пользователей

Заметьте, что побочным эффектом этой схемы динамических групп является то, что члены группы должны быть указаны своими полными DN. Так что если Вы планируете использовать данную схему для записей с объектным классом posixGroup, убедитесь, что Вы используете RFC2307bis и такие типы атрибутов, которые могут содержать DN. Например атрибут memberUid объектного класса posixGroup может содержать только имена, а не DN, поэтому для динамических групп он не подходит.

12.7.3. Дополнительная информация

slapo-dynlist(5)


12.8. Обратное обслуживание членства в группах

12.8.1. Обзор

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

Наложение memberof обновляет атрибут (по умолчанию memberOf) записи-члена всякий раз при изменении атрибута членства (по умолчанию member) записей-групп с теми объектными классами, которые определены для отслеживания подобных обновлений (по умолчанию groupOfNames).

Таким образом, наложение обеспечивает обслуживание списка групп, членом которых является данная запись, если обслуживание групп осуществляется изменением атрибутов членства записи-группы.

12.8.2. Настройка наложения членства в группах

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

        include /usr/share/openldap/schema/core.schema
        include /usr/share/openldap/schema/cosine.schema

        authz-regexp "gidNumber=0\\\+uidNumber=0,cn=peercred,cn=external,cn=auth"
                "cn=Manager,dc=example,dc=com"
        database        bdb
        suffix          "dc=example,dc=com"
        rootdn          "cn=Manager,dc=example,dc=com"
        rootpw          secret
        directory       /var/lib/ldap2.4
        checkpoint 256 5
        index   objectClass   eq
        index   uid           eq,sub

        overlay memberof

добавим в каталог следующий ldif:

        cat memberof.ldif
        dn: dc=example,dc=com
        objectclass: domain
        dc: example

        dn: ou=Group,dc=example,dc=com
        objectclass: organizationalUnit
        ou: Group

        dn: ou=People,dc=example,dc=com
        objectclass: organizationalUnit
        ou: People

        dn: uid=test1,ou=People,dc=example,dc=com
        objectclass: account
        uid: test1

        dn: cn=testgroup,ou=Group,dc=example,dc=com
        objectclass: groupOfNames
        cn: testgroup
        member: uid=test1,ou=People,dc=example,dc=com

Результат поискового запроса для пользователя test1:

 # ldapsearch -LL -Y EXTERNAL -H ldapi:/// "(uid=test1)" -b dc=example,dc=com memberOf
 SASL/EXTERNAL authentication started
 SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
 SASL SSF: 0
 version: 1

 dn: uid=test1,ou=People,dc=example,dc=com
 memberOf: cn=testgroup,ou=Group,dc=example,dc=com

Обратите внимание, что атрибут memberOf - это операционный атрибут, поэтому он должен быть запрошен явно.

12.8.3. Дополнительная информация

slapo-memberof(5)


12.9. Кэширующий прокси-сервер

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

12.9.1. Обзор

Расширение slapd кэширующий прокси-сервер предназначено для улучшения быстродействия механизмов манипуляции данными ldap и meta. Оно обрабатывает поисковые запросы и сначала определяет, соответствуют ли его поисковые фильтры тем, записи по которым уже закэшированы. Если записи по запросу содержатся в локальной базе данных прокси-кэша, они извлекаются оттуда и возвращаются в ответ на запрос. Остальные запросы пропускаются дальше в нужный механизм манипуляции данными ldap или meta, где обрабатываются обычным способом.

Например, записи по запросу (shoesize>=9) уже содержатся в записях по запросу (shoesize>=8), а записи по запросу (sn=Richardson) уже содержатся в записях по запросу (sn=Richards*)

При сравнении утверждений, для принятия решения о сохранении результата запроса в кэше, используются установленные правила соответствия и синтаксисы. Для упрощения проблемы сохранения информации в кэше, во время конфигурации определяется список "шаблонов" запросов, которые могут быть закэшированы (смотрите описание ниже). Результаты запроса помещаются в кэш и извлекаются оттуда только если запрос соответствует одному из таких шаблонов. Записи, связанные с закэшированными запросами, хранятся в локальной базе данных прокси-кэша, а ассоциированная с ними мета-информация (база и диапазон поиска, фильтры, атрибуты) содержится непосредственно в оперативной памяти.

Шаблон - это прототип для образования поискового запроса LDAP. Шаблоны задаются прототипом поискового фильтра и списком атрибутов, которые потребуются в запросах, образовываемых из шаблона. Представление прототипа поискового фильтра аналогично RFC4515, за исключением того, что конкретно заданные значения атрибутов опускаются. Примеры прототипов поисковых фильтров: (sn=),(&(sn=)(givenname=)), соответствующие им экземпляры поисковых фильтров: (sn=Doe) и (&(sn=Doe)(givenname=John)).

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

На странице Кэширующего Прокси-сервера (http://www.openldap.org/pub/kapurva/proxycaching.pdf) представлены детали проектирования и реализации данной технологии.

12.9.2. Настройка наложения кэширующего прокси-сервера

Описанные ниже директивы, специфичные для кэширующего прокси, должны указываться после директивы overlay pcache в разделе database meta или database ldap файла slapd.conf(5).

12.9.2.1. Задание параметров кэша

 pcache <DB> <maxentries> <nattrsets> <entrylimit> <period>

Данная директива активирует прокси-кэширование и задаёт основные параметры кэша. Параметр <DB> указывает тип базы данных, которая будет использоваться для хранения кэшированных записей. Можно задать либо bdb, либо hdb. Параметр <maxentries> указывает общее количество записей, которые могут содержаться в кэше. Параметр The <nattrsets> указывает общее количество наборов атрибутов (задаваемых директивой pcacheAttrSet), которые можно определить. Параметр <entrylimit> указывает максимальное количество записей в запросе, который может быть закэширован. Наконец, параметр <period> указывает период проверки целостности (в секундах). Всякий раз по истечении этого периода, запросы с устарешими TTL удаляются.

12.9.2.2. Определение наборов атрибутов

 pcacheAttrset <index> <attrs...>

Данная директива нужна для ассоциации наборов атрибутов с индексами. Каждый набор атрибутов ассоциируется с числовым индексом от 0 до <numattrsets>-1. Эти индексы используются директивой proxyTemplate для определения шаблонов запросов, которые могут быть закэшированы.

12.9.2.3. Определение шаблонов запросов, которые могут быть закэшированы

 pcacheTemplate <prototype_string> <attrset_index> <TTL>

Данная директива задаёт шаблон запросов, которые могут быть закэшированы и "время жизни" в секундах (параметр <TTL>) тех запросов, которые попадают под этот шаблон. Шаблон описывается строкой прототипа поискового фильтра и набором запрашиваемых атрибутов, определяемым индексом в параметре <attrset_index>.

12.9.2.4. Пример с использованием slapd.conf

Вот пример раздела database файла slapd.conf(5) для организации кэширующего прокси-сервера для поддерева "dc=example,dc=com", содержащегося на сервере ldap.example.com.

        database        ldap
        suffix          "dc=example,dc=com"
        rootdn          "dc=example,dc=com"
        uri             ldap://ldap.example.com/
        overlay pcache
        pcache         hdb 100000 1 1000 100
        pcacheAttrset  0 mail postaladdress telephonenumber
        pcacheTemplate (sn=) 0 3600
        pcacheTemplate (&(sn=)(givenName=)) 0 3600
        pcacheTemplate (&(departmentNumber=)(secretary=*)) 0 3600

        cachesize 20
        directory ./testrun/db.2.a
        index       objectClass eq
        index       cn,sn,uid,mail  pres,eq,sub

12.9.2.5. Пример с использованием slapd-config

Пример аналогичного LDIF-файла для back-config, настраивающий кэширующий прокси сервер для поддерева "dc=example,dc=com", хранящегося на сервере ldap.example.com.

   dn: olcDatabase={2}ldap,cn=config
   objectClass: olcDatabaseConfig
   objectClass: olcLDAPConfig
   olcDatabase: {2}ldap
   olcSuffix: dc=example,dc=com
   olcRootDN: dc=example,dc=com
   olcDbURI: "ldap://ldap.example.com"

   dn: olcOverlay={0}pcache,olcDatabase={2}ldap,cn=config
   objectClass: olcOverlayConfig
   objectClass: olcPcacheConfig
   olcOverlay: {0}pcache
   olcPcache: hdb 100000 1 1000 100
   olcPcacheAttrset: 0 mail postalAddress telephoneNumber
   olcPcacheTemplate: "(sn=)" 0 3600 0 0 0
   olcPcacheTemplate: "(&(sn=)(givenName=))" 0 3600 0 0 0
   olcPcacheTemplate: "(&(departmentNumber=)(secretary=))" 0 3600

   dn: olcDatabase={0}hdb,olcOverlay={0}pcache,olcDatabase={2}ldap,cn=config
   objectClass: olcHdbConfig
   objectClass: olcPcacheDatabase
   olcDatabase: {0}hdb
   olcDbDirectory: ./testrun/db.2.a
   olcDbCacheSize: 20
   olcDbIndex: objectClass eq
   olcDbIndex: cn,sn,uid,mail  pres,eq,sub
12.9.2.4.1. Запросы, которые могут быть закэшированы

Поисковый запрос LDAP может быть закэширован, если его фильтр соответствует одному из шаблонов, определённых директивами pcacheTemplate, и если запрашиваемые в нём атрибуты указаны в соответствующем наборе атрибутов. В приведённом выше примере набор атрибутов номер 0 определяет, что только атрибуты mail postaladdress telephonenumber могут быть закэшированы в идущих следом pcacheTemplate.

12.9.2.4.2. Примеры:
        Filter: (&(sn=Richard*)(givenName=jack))
        Attrs: mail telephoneNumber

может быть закэширован, поскольку он соответствует шаблону (&(sn=)(givenName=)) и его атрибуты содержатся в pcacheAttrset 0.

        Filter: (&(sn=Richard*)(telephoneNumber))
        Attrs: givenName

не может быть закэширован, поскольку фильтр не соответствует шаблону, и атрибут givenName не задан для хранения в кэше.

        Filter: (|(sn=Richard*)(givenName=jack))
        Attrs: mail telephoneNumber

не может быть закэширован, поскольку фильтр не соответствует шаблону (условие логического ИЛИ "|" вместо логического И "&").

12.9.3. Дополнительная информация

slapo-pcache(5)


12.10. Политики паролей

12.10.1. Обзор

Цель данного наложения - исполнение требований проектного RFC под названием draft-behera-ldap-password-policy-09. Несмотря на то, что данный проект не получил официального статуса, он был реализован в нескольких серверах службы каталогов, в том числе и в slapd. Тем не менее, важно отметить, что это всего-лишь проектный RFC, работы по нему еще ведутся и, возможно, будут внесены какие-либо изменения.

Ключевые возможности наложения политик паролей следующие:

12.10.2. Настройка наложения политик паролей

Перед подключением наложения к той базе данных, где оно будет использоваться, нужно добавить новый набор схемы ppolicy и загрузить модуль ppolicy. В следующем примере демонстрируется подключение наложения ppolicy к базе данных, обслуживающей пространство имён "dc=example,dc=com". В этом примере мы также указываем DN объекта политики по умолчанию, которая применяется, если для объекта учётной записи пользователя не была определена никакая другая политика.

       database bdb
       suffix "dc=example,dc=com"
       [... здесь указываются другие директивы конфигурации базы данных ...]

       overlay ppolicy
       ppolicy_default "cn=default,ou=policies,dc=example,dc=com"

Теперь мы должны создать контейнер для объектов политик. В нашем примере объекты политик паролей будут размещаться в ветви, называемой "ou=policies,dc=example,dc=com":

       dn: ou=policies,dc=example,dc=com
       objectClass: organizationalUnit
       objectClass: top
       ou: policies

Создадим объект политики по умолчанию и определим в нём следующие политики:

Итак, наш объект политики получился такой:

       dn: cn=default,ou=policies,dc=example,dc=com
       cn: default
       objectClass: pwdPolicy
       objectClass: person
       objectClass: top
       pwdAllowUserChange: TRUE
       pwdAttribute: userPassword
       pwdCheckQuality: 2
       pwdExpireWarning: 600
       pwdFailureCountInterval: 30
       pwdGraceAuthNLimit: 5
       pwdInHistory: 5
       pwdLockout: TRUE
       pwdLockoutDuration: 0
       pwdMaxAge: 0
       pwdMaxFailure: 5
       pwdMinAge: 0
       pwdMinLength: 5
       pwdMustChange: FALSE
       pwdSafeModify: FALSE
       sn: dummy value

При необходимости можно создать и другие объекты политик.

Есть 2 пути применения политик паролей к индивидуальным объектам:

1. Атрибут pwdPolicySubentry в объекте учётной записи пользователя. Если этот атрибут присутствует и в нём указан DN объекта политики, то данная политика применяется к целевому объекту учётной записи.

2. Политика паролей по умолчанию. Если в учётной записи не задан атрибут pwdPolicySubentry, и наложение политик паролей было сконфигурировано с указанием DN объекта политики по умолчанию, а также если такой объект присутствует, тогда указанная в этом объекте политика применяется к учетной записи пользователя.

Полностью возможности данного наложения описаны в slapo-ppolicy(5). Также посмотрите дискуссию "Вопросы управления паролями" по адресу http://www.symas.com/blog/?page_id=66

12.10.3. Дополнительная информация

slapo-ppolicy(5)


12.11. Обеспечение целостности ссылок

12.11.1. Обзор

Данное наложение может использоваться поверх механизмов манипуляции данными, таких как slapd-bdb(5), для поддержания целостности схемы данных, использующей атрибуты-ссылки.

При выполнении операций modrdn или delete, то есть при переименовании DN записи или удалении записи, сервер будет искать ссылки на данный DN в записях каталога (в указанных атрибутах, смотрите описание ниже) и обновлять их соответственно. Если выполнялась операция delete, ссылка будет удалена. Если выполнялась операция modrdn, то в ссылочный атрибут будет записан новый DN.

Примером может служить очень распространённая административная задача ведения списка членов группы во время манипуляций с учётными записями пользователей. Когда учётная запись пользователя удаляется или переименовывается, все записи групп, где этот пользователь состоит членом, должны быть обновлены соответственно. Для решения этой задачи администраторы LDAP обычно пишут свои скрипты. Но мы можем использовать наложение refint для автоматизации этой задачи. В этом примере, если пользователь удаляется из каталога, наложение позаботится об удалении пользователя из группы, где он состоял. И не надо никаких скриптов.

12.11.2. Настройка наложения обеспечения целостности ссылок

Настройки этого наложения следующие:

       overlay refint
       refint_attributes <attribute [attribute ...]>
       refint_nothing <string>

Проиллюстрируем работу наложения описанным выше сценарием обеспечения целостности членства в группах.

В файле slapd.conf укажем:

       overlay refint
       refint_attributes member
       refint_nothing "cn=admin,dc=example,dc=com"

Данная конфигурация указывает наложению поддерживать целостность ссылок в атрибуте member. Этот атрибут используется в объектном классе groupOfNames, требующем наличия хотя бы одного члена, поэтому мы добавляем директиву refint_nothing, чтобы дополнить группу стандартным членом, если все её члены будут удалены.

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

Рисунок 12.3: Поддержание целостности ссылок в группах

Обратите внимание, что если мы переименуем (modrdn) запись john в, скажем, jsmith, наложение refint также переименует ссылку в атрибуте member, таким образом членство в группе останется верным.

При удалении всех пользователей-членов данной группы из каталога, в конечном итоге в группе останется один член: cn=admin,dc=example,dc=com. Он будет принудительно помещён туда из параметра refint_nothing для обеспечения требований корректности набора схемы.

Для базы данных должен быть задан rootdn, поскольку refint работает от имени rootdn, чтобы получить соответствующие права для выполнения требуемых обновлений. Задавать rootpw не обязательно.

12.11.3. Дополнительная информация

slapo-refint(5)


12.12. Настраиваемые коды возврата

12.12.1. Обзор

Данное наложение полезно для тестирования поведения клиентов при получении от сервера ошибочных или необычных ответов, например кодов ошибок, отсылок, превышение времени отклика и т.п.

Его можно квалифицировать как инструмент отладки в процессе разработки клиентских программ или дополнительных наложений.

Для получения детальной информации обращайтесь к man-странице slapo-retcode(5).

12.12.2. Настройка кодов возврата

Наложение retcode использует набор схемы "return code", описанный в man-странице. Этот набор схемы специально разработан для использования с данным наложением и не предназначен для использования в иных случаях.


Замечание: Необходимый набор схемы загружается наложением автоматически.

Примерная конфигурация может быть такой:

       overlay         retcode
       retcode-parent  "ou=RetCodes,dc=example,dc=com"
       include         ./retcode.conf

       retcode-item    "cn=Unsolicited"                0x00 unsolicited="0"
       retcode-item    "cn=Notice of Disconnect"       0x00 unsolicited="1.3.6.1.4.1.1466.20036"
       retcode-item    "cn=Pre-disconnect"             0x34 flags="pre-disconnect"
       retcode-item    "cn=Post-disconnect"            0x34 flags="post-disconnect"


Замечание: retcode.conf можно найти в исходных кодах openldap в: tests/data/retcode.conf

Вот отрывок из retcode.conf:

       retcode-item    "cn=success"                            0x00

       retcode-item    "cn=success w/ delay"                   0x00    sleeptime=2

       retcode-item    "cn=operationsError"                    0x01
       retcode-item    "cn=protocolError"                      0x02
       retcode-item    "cn=timeLimitExceeded"                  0x03    op=search
       retcode-item    "cn=sizeLimitExceeded"                  0x04    op=search
       retcode-item    "cn=compareFalse"                       0x05    op=compare
       retcode-item    "cn=compareTrue"                        0x06    op=compare
       retcode-item    "cn=authMethodNotSupported"             0x07
       retcode-item    "cn=strongAuthNotSupported"             0x07    text="same as authMethodNotSupported"
       retcode-item    "cn=strongAuthRequired"                 0x08
       retcode-item    "cn=strongerAuthRequired"               0x08    text="same as strongAuthRequired"

Посмотреть полный retcode.conf можно в tests/data/retcode.conf.

12.12.3. Дополнительная информация

slapo-retcode(5)


12.13. Перезапись/Переназначение (Rewrite/Remap)

12.13.1. Обзор

Наложение выполняет простую перезапись DN/данных и переназначение одних объектных классов/типов атрибутов другими. В основном его используют для виртуального представления существующей информации, причём как удалённой, в сочетании с механизмом манипуляции данными ldap, описанном в slapd-ldap(5), так и локальной, в сочетании с механизмом манипуляции данными relay, описанном в slapd-relay(5).

Это наложение чрезвычайно настраиваемое и продвинутое, поэтому рекомендуем обратиться к man-странице slapo-rwm(5).

12.13.2. Настройка наложения перезаписи/переназначения

12.13.3. Дополнительная информация

slapo-rwm(5)


12.14. Сервер-поставщик синхронизации

12.14.1. Обзор

Данное наложение реализует поддержку syncrepl-репликации, то есть репликации с помощью LDAP Content Synchronization (RFC4533 (рус.) (RFC4533 (ориг.)), синхронизация содержимого LDAP), на стороне поставщика, включая связанные с ней функции поиска.

12.14.2. Настройка наложения сервера-поставщика синхронизации

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

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

       overlay syncprov
       syncprov-checkpoint 100 10

Итак, после выполнения каждых 100 операций или по прошествии 10 минут (в зависимости от того, что произойдёт раньше), contextCSN будет сохранён в базу данных.

Всего доступны четыре директивы конфигурации: syncprov-checkpoint, syncprov-sessionlog, syncprov-nopresent и syncprov-reloadhint, все они рассмотрены в man-странице, где обсуждаются несколько разных сценариев применения этого наложения.

12.14.3. Дополнительная информация

Man-страница slapo-syncprov(5) и раздел Настройка различных типов репликации.


12.15. Прозрачный прокси (Translucent Proxy)

12.15.1. Обзор

Данное наложение используется совместно с базой данных одного из механизмов манипуляции данными, таких как slapd-bdb(5) для создания "прозрачного прокси".

Перед передачей клиенту записей, получаемых с удалённого LDAP-сервера, у них могут быть подменены некоторые или все атрибуты, или добавлены новые с помощью соответствующих записей, хранящихся в локальной базе данных.

При операции поиска сначала извлекаются записи с удалённого сервера, затем их атрибуты подменяются атрибутами из локальной базы данных (если таковые имеются). В локальных переопределениях могут применяться операции add, modify, и modrdn, если их использование разрешено root-пользователю локальной базы данных прозрачного прокси.

При операциях сравнения сначала происходит сравнение с атрибутами записи из локальной базы данных (если таковые имеются), а затем с данными из удалённой базы данных.

12.15.2. Настройка наложения прозрачного прокси

Для этого наложения существуют различные варианты настройки, но в нашем примере мы продемонстрируем добавление новых атрибутов к удалённой записи, а также поиск по этим новым добавленным локальным атрибутам. Чтобы узнать больше о переопределении удалённых записей и настройке поисковых операций, посмотрите slapo-translucent(5)


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

Сначала настроим наложение в нормальной манере:

       include     /usr/local/etc/openldap/schema/core.schema
       include     /usr/local/etc/openldap/schema/cosine.schema
       include     /usr/local/etc/openldap/schema/nis.schema
       include     /usr/local/etc/openldap/schema/inetorgperson.schema

       pidfile     ./slapd.pid
       argsfile    ./slapd.args

       database    bdb
       suffix      "dc=suretecsystems,dc=com"
       rootdn      "cn=trans,dc=suretecsystems,dc=com"
       rootpw      secret
       directory   ./openldap-data

       index       objectClass eq

       overlay     translucent
       translucent_local carLicense

       uri         ldap://192.168.X.X:389
       lastmod     off
       acl-bind    binddn="cn=admin,dc=suretecsystems,dc=com" credentials="blahblah"

Обратите внимание на директиву overlay и следующую за ней директиву, определяющую, по каким атрибутам мы хотим осуществлять поиск в локальной базе данных. Для обращения к удалённому серверу каталогов мы должны также подключить механизм манипуляции данными ldap.

Ну, а теперь возьмём для примера группу LDAP на удалённом сервере:

       # itsupport, Groups, suretecsystems.com
       dn: cn=itsupport,ou=Groups,dc=suretecsystems,dc=com
       objectClass: posixGroup
       objectClass: sambaGroupMapping
       cn: itsupport
       gidNumber: 1000
       sambaSID: S-1-5-21-XXX
       sambaGroupType: 2
       displayName: itsupport
       memberUid: ghenry
       memberUid: joebloggs

и создадим файл LDIF, чтобы добавить в локальную базу данных запись с несколько странным набором новых атрибутов (в целях демонстрации):

       [ghenry@suretec test_configs]$ cat test-translucent-add.ldif
       dn: cn=itsupport,ou=Groups,dc=suretecsystems,dc=com
       businessCategory: frontend-override
       carLicense: LIVID
       employeeType: special
       departmentNumber: 9999999
       roomNumber: 41L-535

Поиск по нашему прокси выдаёт следующий результат:

       [ghenry@suretec test_configs]$ ldapsearch -x -H ldap://127.0.0.1:9001 "(cn=itsupport)"
       # itsupport, Groups, OxObjects, suretecsystems.com
       dn: cn=itsupport,ou=Groups,ou=OxObjects,dc=suretecsystems,dc=com
       objectClass: posixGroup
       objectClass: sambaGroupMapping
       cn: itsupport
       gidNumber: 1003
       SAMBASID: S-1-5-21-XXX
       SAMBAGROUPTYPE: 2
       displayName: itsupport
       memberUid: ghenry
       memberUid: joebloggs
       roomNumber: 41L-535
       departmentNumber: 9999999
       employeeType: special
       carLicense: LIVID
       businessCategory: frontend-override

Мы видим 5 новых атрибутов, добавленных к удалённой записи перед тем, как выдать её нашему клиенту.

Поскольку мы определили поиск по локальному атрибуту:

       overlay     translucent
       translucent_local carLicense

мы можем осуществлять поиск по нему в уже полностью сформированной записи:

       ldapsearch -x -H ldap://127.0.0.1:9001 (carLicense=LIVID)

Это весьма интересная функция, поскольку мы не только можем локально "расширить" удалённый сервер каталогов, но и осуществлять поиск по локальным записям.


Замечание: Поскольку наложение translucent не выполняет никаких переписываний DN, записи в локальной и удалённой базах данных должны иметь одинаковый суффикс. В противном случае сервер может аварийно завершить работу с ошибками типа No Such Object (нет такого объекта) или другими.

12.15.3. Дополнительная информация

slapo-translucent(5)


12.16. Проверка уникальности атрибутов

12.16.1. Обзор

Данное наложение может использоваться поверх механизмов манипуляции данными, таких как slapd-bdb(5), для принудительного поддержания уникальности одного или нескольких атрибутов в пределах поддерева.

12.16.2. Настройка наложения проверки уникальности атрибутов

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

В следующем примере, при установке проверки уникальности для атрибута mail, в ходе выполнения операций add, modify или modrdn поддерево будет сканировано (в указанном при настройке диапазоне поиска) на наличие записей с тем же значением атрибута mail, что и присутствует в запросе. Если найдётся хотя бы одна такая запись, запрос будет отвергнут.

Для проверки уникальности атрибута mail с поиском по всему поддереву, начиная от базового DN текущей базы данных, просто добавим следующие строки конфигурации:

       overlay unique
       unique_uri ldap:///?mail?sub?


Замечание: Если в URI не было указано никаких атрибутов, например ldap:///??sub?, проверка уникальности будет распространена на все неоперационные атрибуты. Можно, однако, исключить некоторые из неоперационных атрибутов с помощью ключевого слова ignore.

Итак, в нашем каталоге имеется запись:

       dn: cn=gavin,dc=suretecsystems,dc=com
       objectClass: top
       objectClass: inetorgperson
       cn: gavin
       sn: henry
       mail: ghenry@suretecsystems.com

При добавлении такой записи:

       dn: cn=robert,dc=suretecsystems,dc=com
       objectClass: top
       objectClass: inetorgperson
       cn: robert
       sn: jones
       mail: ghenry@suretecsystems.com

мы получим следующую ошибку:

       adding new entry "cn=robert,dc=example,dc=com"
       ldap_add: Constraint violation (19)
               additional info: some attributes not unique

Чтобы осуществлять более комплексный отбор записей, в наложении можно указать несколько URI для одного домена. Также можно указать несколько директив unique_uri или атрибутов olcUniqueURI для поддержки независимых доменов.

За дополнительной информацией и подробностями использования ключевых слов strict и ignore, обращайтесь к man-странице slapo-unique(5).

12.16.3. Дополнительная информация

slapo-unique(5)


12.17. Сортировка значений атрибутов

12.17.1. Обзор

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

12.17.2. Настройка наложения сортировки значений атрибутов

Сортировка может быть определена как в порядке убывания, так и возрастания, с использованием числового или символьного метода сортировки. Кроме того, может быть определена сортировка "по весу" с использованием числового значения веса, ассоциированного со значением атрибута.

Сортировка по весу всегда производится в порядке возрастания, но она может быть скомбинирована с другими методами для значений, имеющих одинаковый вес. Вес указывается подстановкой целочисленного значения {<вес>} перед собственно значением атрибута, с которым этот вес ассоциируется. При поисковых запросах данное значение веса отбрасывается и клиенту передаётся "чистое" значение атрибута.

Приведём несколько примеров. Для сортировки по возрастанию:

       loglevel    sync stats

       database    hdb
       suffix      "dc=suretecsystems,dc=com"
       directory   /usr/local/var/openldap-data

       ......

       overlay valsort
       valsort-attr memberUid ou=Groups,dc=suretecsystems,dc=com alpha-ascend

Получаем:

       # sharedemail, Groups, suretecsystems.com
       dn: cn=sharedemail,ou=Groups,dc=suretecsystems,dc=com
       objectClass: posixGroup
       objectClass: top
       cn: sharedemail
       gidNumber: 517
       memberUid: admin
       memberUid: dovecot
       memberUid: laura
       memberUid: suretec

Для сортировки по весу внесём изменения в нашу запись:

       # sharedemail, Groups, suretecsystems.com
       dn: cn=sharedemail,ou=Groups,dc=suretecsystems,dc=com
       objectClass: posixGroup
       objectClass: top
       cn: sharedemail
       gidNumber: 517
       memberUid: {4}admin
       memberUid: {2}dovecot
       memberUid: {1}laura
       memberUid: {3}suretec

и поменяем конфигурацию:

       overlay valsort
       valsort-attr memberUid ou=Groups,dc=suretecsystems,dc=com weighted

В этом случае получаем:

       # sharedemail, Groups, OxObjects, suretecsystems.com
       dn: cn=sharedemail,ou=Groups,ou=OxObjects,dc=suretecsystems,dc=com
       objectClass: posixGroup
       objectClass: top
       cn: sharedemail
       gidNumber: 517
       memberUid: laura
       memberUid: dovecot
       memberUid: suretec
       memberUid: admin

12.17.3. Дополнительная информация

slapo-valsort(5)


12.18. Объединение наложений в стек

12.18.1. Обзор

Наложения могут быть объединены в стек. Это означает, что более одного наложения сразу может быть применено к той или иной базе данных или на глобальном уровне frontend. При последовательном вызове наложений исполняется каждая из функций работающего в данный момент наложения (если настроено её исполнение). Несколько наложений исполняются в обратном порядке (как и положено стеку) по отношению к их определению в slapd.conf (5), или по отношению к установленному для них порядку в конфигурационной базе данных (назначение порядка сортировки описано в slapd-config (5)).

12.18.2. Возможные сценарии применения

12.18.2.1. Samba