Мої нотатки про застосування LDAP

Вступ.

Всякий час як доводилось братися за нову для мене річ, шукав коротку зрозумілу вступну статтю про предмет, таку щоб з першой сторінки стало ясно що воно таке, а з кількох наступних - з чого треба починати, що облишити на потім. Коли я вперше брався освоювати LDAP , я , як не старався, не зміг знайти такої статті, а відтак сам почав писати свої нотатки. От з таких уривків й намагаюся скласти цей текст. Я хочу зауважити, що статей штибу "натисніть кнопку й настане вам щастя" - є чимало, але LDAP це сервіс, що потребує планування, а від так й розуміння наперед, що ж воно з нього вийде.

Стаття розрахована не те щоб зовсім на новачків, скоріше на людей, що вже є системними адмінистраторами, але раніше не зтикалися з LDAP.

Я, як і всі люди, десь можу помилятися - тож конструктивна критика й виправлення помилок будуть сприйняті з вдячністю, бо від цьго стаття має шанс покращитися.

Трохи загальних слів.

LDAP - це протокол програмного рівня (згідно моделі OSI), працює поверх TCP\IP, традиційно використовує порт 389/tcp , або 636/tcp для роботи через SSL. Призначення LDAP сервера зберігати ієрархічні (древовидні) структури даних. Структура дерева може бути якою завгодно, отже на практиці його можна пристосувати до якої завгодно структури організаії. Найпростіший приклад застосування LDAP - e-mail/телефонний довідник. Популярні e-mail клієнти "вміють" шукати інформацію в LDAP, але частіше LDAP каталог використовують для зберігання акаунтів (login/password) користувачів мережі. Як вже було сказано, сервер може працювати через SSL, отож передачу пароля можно вважати більш-менш безпечною, також може бути налаштована реплікація між LDAP серверами - так що з надійністю теж можна вважати справи не погані.

Протокол є відкритим стандартом - всі охочі можуть знайти відповідні RFC. Існує декілка реалізацій LDAP серверів, як відкритих, так і комерційних.

Я знайшов інформацію про такі:

Apache DS
Redhat Directory Server (RHDS) - Fedora Directory Server
Mandriva Directory Server
Samba4 (LDAP сервер є частиною пакету)
OpenDS
OpenLDAP
Microsoft Active Directory (починаючи з Windows 2000 server)
Sun Directory Server Enterprise Edition
IBM Tivoli DS
Oracle Internet Directory

Для роботи з данними на цих серверах було написано чимало різних інструментів, я наведу лиш ті, які сам використовував/використовую:
phpldapadmin - web інтерфейс, написаний на php (http://phpldapadmin.sourceforge.net/)
Apache Directory Studio - написана на java, в мене працює на Linux. Досить таки зручна й функціональна річ, мені сподобалася. (http://directory.apache.org/studio/)
LDAP Browser / LDAP Administrator для Windows http://www.ldapbrowser.com/ Я колись використовував LDAP Browser - теж корисна річ.

Далі по тексту окрім балачок будуть приклади, всі вони зроблені на OpenLDAP запущеному на FreeBSD, якщо буде про підключення до MS Active Directory - буде вказано окремо.

Одна важлива ремарка перед початком. Треба розрізняти два різних терміни : Аутентифікація та Авторизація. Коли обидва процеси виконуються на одному сервері - нам байдуже яка між ними різниця. Але як що ми збираємося використовувати LDAP сервер - треба чітко розуміти різницю, бо таким чином ми розділяємо ці два процеси.

Аутентифікація - це перевірка чи справді користувач є тим ким назвався (перевірка пароля).

Авторізація - це перевірка прав.

Отож LDAP сервер може добре справлятися з першою задачею, але вирішити другу - він може допомогти, а може й ні. Тут буде залежати від того, як реалізоване клієнтське ПЗ, що буде посередником між сервером, до якого користувач хоче отримати доступ, та LDAP сервером, що буде проводити Аутентифікацію. (Від системного адміністратора, казали теж щось залежить o;).

Ну тепер пора вже й починати.

Найбільш незвичним для початківців є іменування об'єктів. Унікальне ім'я об'єкта - Distinguished Name або DN складається з імен усіх об'єктів, які включаютьт в себе об'єкт (на початку я згадував про ієрархію - то це про неї). Ось кілька важливих об'єктів, що їх треба запам'ятати для початку (все решта детально описане в документації).

dc - Domain Component - зазвичай корінь каталога виглядає так dc=domain,dc=org, ну якщо Ваш домен має таку назву domain.org
ou - Org Unit - необов'язковий, але корисний об'єкт, його використовують, як контейнер для інших об'єктів.
cn - Canonical Name (атрибут об'єкта) - канонічне ім'я об'єкта. Якщо об'ект - користувач найчастіше тут буде Ім'я та Прізвище.
rdn - Relative (відносне) Distinguished Name
dn - Distinguished Name, Вже згадано вище.

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

Ось для прикладу експортований у ldif формат об'єкт - обліковий запис користувача:

dn: uid=johns,ou=Users,dc=domain,dc=org
objectClass: person
objectClass: posixAccount
objectClass: top
cn: John Smith
gidNumber: 1000
homeDirectory: /home/johns/
sn: Smith
uid: johns
uidNumber: 1000
userPassword:: e01ENX00cFdmcHkrTCtyZEZHTXlRQzVQdXZ3PT0=

Примітка: прошу не лякатися. Насправді пароль закодований не base64, як здається на перший погляд. Тут зберігається md5 хеш пароля, який потім закодований base64. Як що спробувати розкодувати base64 - вийде ось така строчка : {MD5}4pWfpy+L+rdFGMyQC5Puvw==

Можливі методи кодування пароля : ssha, md5, crypt. Також доступ до паролів (як доречі і до любого атрибуту можна обмежити за допомогою acl , але це не є матеріалом цієї статті).

Тепер розберемо що х воно написано в файлі, з розширенням ldif (це текстовий файл).
Перша строчка - це і є його Distinguished Name або DN. В даному випадку rdn: uid=johns .
З нього видно, що наш об'єкт знаходиться в контейнері Users, точніше в контейнері dn: ou=Users,dc=domain,dc=org.
Як що використовувати один з вищезгаданих інструментыв для управління даними - картинка дуже зрозуміла.
Наступні строчки - атрибути об'єкта. Як можна бачити наш об'єкт належить до трьох класів : person, posixAccount, top.

Атрибут objectClass є дуже важливим, набір значеннь цього атрибута визначає набір обов'язкових і необов'язкових атрибутів. Існує три типи класів об'єктів :
Structural - структурний - представляє об'єкт (користувача, групу, комп'ютер, структурний підрозділ, і т.ін.). Об'єкт може належати тільки до одного структурного класу. Більш того, змінити належність об'єкта до структурного класу не вийде - прийдеться створювати об'єкт заново.
Auxiliary - додатковий - слугує для доповнення структурного класу, ну як що Вам треба додати до вже існуючого об'єкта додаткові атрибути.
Abstract - абстрактний клас - не може бути використаний прямо, а тільки як нащадок батьківського класу. Про ньoго можна почитати в документації, бо це не матеріал статті.

В даному випадку
person - структурний клас
posixAccount - додатковий клас
top - абстракний клас

Декілька слів про схему каталога

От і настав час згадати про схеми каталога. Увага "схема" тут немає нічого спільно з малюванням, дерева даних.
Схема LDAP - це опис атрибутів об'єктів та класів об'єктів, які можуть бути в каталозі. В 99% випадків самому писати схему непотрібно, досить просто підключити потрібні файли схем (робиться це в slapd.conf), що є в пакеті OpenLDAP, або іншого ПЗ, що планується використовувати разом з LDAP. samba 3.* sudo, та багато іншого ПЗ мають відповідні файли схем.

Тепер знов повертаємося до прикладів. DN може бути тільки один, бо він унікальний інденифікатор, але сформівати його можна по-різномі. Існує дві моделі утворення DN :

login-based dn: uid=johns,ou=Users, dc=domain,dc=org
name-based dn: cn=John Smith, ou=Users, dc=domain,dc=org

Примітка: у деяких випадках адміністратор може в артибут cn записати login, або, як його називають в OpenLDAP uid, але це звужує можливості використання LDAP.

В цих прикладах різні rdn : uid=johns та cn=John Smith, слід зауважити, що rdn може бути тільки обов'язковий атрибут. Хоч вони обидва описують одного користувача, та можуть існувати одночасно, бо ж DN у них різні, так що адміністратору треба самому вирішувати якої моделі дотримуватися. Для прикладу, для FreeBSD є інструкція, як налаштувати аутентифікацію системних юзерів в LDAP, там використана login based модель, а MS Active Directiry - використовує name based модель. Яку модель обрати - більше буде залежати від клієнтського ПЗ, що буде підключатися до LDAP. І тут, мушу сказати, не все просто й однаково. Хоч про підтримку LDAP заявлено в багатьох продуктах, треба уважно читати документацію, що до того, як це реалізовано. Я далі наведу приклади, з чим сам зтикався.

Тепер пвернімося до схем катлога та подивимося, які об’єкти можуть бути використані для реестрації юзерів.

Ось деякі (не всі) класи, яки знадобляться при створенні облікових зписів користувачів (це уривки з файлів схем OpenLDAP, як на мене - там досить багато знайомих для IT фахівця слів, отож не бдемо витрачати час на зайві пояснення) :

core.schema

objectclass ( 2.5.6.6 NAME 'person'
    DESC 'RFC2256: a person'
    SUP top STRUCTURAL
    MUST ( sn $ cn )
    MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )


objectclass ( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject'
    DESC 'RFC1274: simple security object'
    SUP top AUXILIARY
    MUST userPassword )

cosine.schema

objectclass ( 0.9.2342.19200300.100.4.5 NAME 'account'
    SUP top STRUCTURAL
    MUST userid
    MAY ( description $ seeAlso $ localityName $
        organizationName $ organizationalUnitName $ host )
    )

Примітка: userid це псевдонім uid , як що заглянути у файл схеми, як там описаний атрибут.

inetorgperson.schema

objectclass     ( 2.16.840.1.113730.3.2.2
    NAME 'inetOrgPerson'
    DESC 'RFC2798: Internet Organizational Person'
    SUP organizationalPerson
    STRUCTURAL
    MAY (
        audio $ businessCategory $ carLicense $ departmentNumber $
        displayName $ employeeNumber $ employeeType $ givenName $
        homePhone $ homePostalAddress $ initials $ jpegPhoto $
        labeledURI $ mail $ manager $ mobile $ o $ pager $
        photo $ roomNumber $ secretary $ uid $ userCertificate $
        x500uniqueIdentifier $ preferredLanguage $
        userSMIMECertificate $ userPKCS12 )
    )

nis.schema

objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount'
    DESC 'Abstraction of an account with POSIX attributes'
    SUP top AUXILIARY
    MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
    MAY ( userPassword $ loginShell $ gecos $ description ) )

objectclass ( 1.3.6.1.1.1.2.1 NAME 'shadowAccount'
    DESC 'Additional attributes for shadow passwords'
    SUP top AUXILIARY
    MUST uid
    MAY ( userPassword $ shadowLastChange $ shadowMin $
        shadowMax $ shadowWarning $ shadowInactive $
        shadowExpire $ shadowFlag $ description ) )

Також для покращення політики безпеки можна використовувати хему ppolicy.schema

Підключення до сервера (bind).

Підключення до сервера може бути: анонімне, або з аутентифікайією, з використанням dn та пароля. До MS Active Directory можна підключатися з використанням UPN (user@domain.org ), але до OpenLDAP так підключтися не вийде. Звичайно, що набирати довгий dn не дуже зручно, ото ж LDAP клієнт, що є відповідальним за аутентифікацію виконує декілька дій, що від користувача приховані:
1. підключення до сервера: або анонімне, або з використанням спеціального юзера з правами на пошук.
2. пошук облікового запису користувача з використанням якогось атрибуту (зазвичай шукають атрибут uid на співпадіння з тим, що юзер набрав як свій login), як що знайдено ОДИН dn - повернають dn.
3. логін зі знайденим dn, та тим паролем, що набрав юзер.

Для цього в конфігові клієнта існують такі опції:

binddn cn=proxyuser,dc=domain,dc=org
bindpw  passwd
pam_login_attribute uid

Це опції з файлу ldap.conf , що я його використовував з модулем pam_ldap. Там ще багато є інших, але ці (хіба з трохи відмінними назвами) будуть зустрічатися в конфігах усіх клієнтів.

Stright Bind Це скоріше виключення з правила. Він можливий при виконанні наступних умов:
1. login based dn
2. усі користувачі розташовані в одному орг юніті, наприклад: ou=Users, dc=domain,dc=org.
Тоді можна провести аутентифікацію за одне підключення до LDAP сервера. В конфіг файлі клієнта присутня така опція :

binddn  %s=uid,ou=Users,dc=domain,dc=org

де під час аутентифікації замість %s буде підставлене те, що юзер на,рав на клавіатурі, як свій login.

Ось приклади log файла сервера при анонімному підключенні:
Це команда шукати юзера з uid=user1

$> ldapsearch -b "dc=domain,dc=org"  "(uid=user1)"

Те, що показала команда на екрані - пропускаю. А це фрагмент лог файлу:

Nov 12 16:00:15 hastname slapd[5149]: conn=61 fd=11 ACCEPT from IP=10.0.0.4:61802 (IP=10.0.0.4:389)
Nov 12 16:00:15 hastname slapd[5149]: conn=61 op=0 BIND dn="" method=128
Nov 12 16:00:15 hastname slapd[5149]: conn=61 op=0 RESULT tag=97 err=0 text=
Nov 12 16:00:15 hastname slapd[5149]: conn=61 op=1 SRCH base="dc=domain,dc=org" scope=2 deref=0 filter="(uid=user1)"
Nov 12 16:00:15 hastname slapd[5149]: conn=61 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
Nov 12 16:00:15 hastname slapd[5149]: conn=61 op=2 UNBIND
Nov 12 16:00:15 hastname slapd[5149]: conn=61 fd=11 closed

В цьому випадку анонімний доступ заблоковано, і щоб пошукати щось - підключаємося через спеціального юзера:

$> ldapsearch -D "uid=proxyuser,dc=domain,dc=org" -w 1234567 -b "dc=domain,dc=org"  "(uid=user1)"

Результат команди пропускаю. А показуємо, що залишлося в лог файлі:

Nov 12 16:10:57 hastname slapd[5491]: conn=3 fd=11 ACCEPT from IP=10.0.30.40:65231 (IP=10.0.0.4:389)
Nov 12 16:10:57 hastname slapd[5491]: conn=3 op=0 BIND dn="uid=proxyuser,dc=domain,dc=org" method=128
Nov 12 16:10:57 hastname slapd[5491]: conn=3 op=0 BIND dn="uid=proxyuser,dc=domain,dc=org" mech=SIMPLE ssf=0
Nov 12 16:10:57 hastname slapd[5491]: conn=3 op=0 RESULT tag=97 err=0 text=
Nov 12 16:10:57 hastname slapd[5491]: conn=3 op=1 SRCH base="dc=domain,dc=org" scope=2 deref=0 filter="(uid=user1)"
Nov 12 16:10:57 hastname slapd[5491]: conn=3 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
Nov 12 16:10:57 hastname slapd[5491]: conn=3 op=2 UNBIND
Nov 12 16:10:57 hastname slapd[5491]: conn=3 fd=11 closed

В обох прикладах немає запису про завершальну стадію - логін користувача зі знайденим dn, але тут я не проводив аутентифікацію, а просо шукав обліковий запис - так що все так, як й треба.

Примітка: ldapsearch - це консольна команда, частина пакету OpenLDAP.

Членство в групах.

Оскільки було згадано про авторизацію (перевірку прав користувача) - треба згадати про групи користувачів, бо це є способом задати або перевірити права користувача опираючись на певний шаблон (права групи.)

Примітка: Як що ви подумали, що аналогом групи (в звичайній системі) є орг юніт - ви помилилися. Його використовують для групування обєктів (користувачів, компьютерів, чтого завгодно) за якоюсь ознакою, наприклад територіальною, або згідно структури організації.

OpenLDAP у своїх файлах схем має такі класи:

groupOfNames - group of names(DNs) - core.schema : STRUCTURAL
Зберігає в атрибуті member dn учасників групи. Ось так виглядає експортована в ldif формат така група:

dn: cn=goup_1,ou=Groups,dc=domain,dc=org
objectClass: groupOfNames
objectClass: top
cn: goup_1
member: cn=Name1 Surname1,ou=Users,dc=domain,dc=org
member: uid=user1,ou=Users,dc=domain,dc=org
member: uid=user2,ou=Users,dc=domain,dc=org

Додати в групу користувача, що не існує - можливо.
Двічи додати одного - теж можливо.

groupOfUniqueNames - group of unique names(DN and unique identifier) - core.schema : STRUCTURAL
Зберігає в атрибуті uniqueMember DN-и учасників групи.

Ось експортована в ldif формат така група:

dn: cn=group_2,ou=Groups,dc=domain,dc=org
objectClass: groupOfUniqueNames
objectClass: top
cn: group_2
uniqueMember: uid=user1,ou=Users,dc=domain,dc=org
uniqueMember: uid=user2,ou=Users,dc=domain,dc=org
uniqueMember: cn=Name Surname,ou=Users,dc=domain,dc=org

Додати в групу користувача, що не існує - можливо.
Двічи додати одного - теж можливо.

posixGroup - group of UIDs - nis.schema : STRUCTURAL
Зберігає в memberUid, uid-и учасників групи. Аналогічна групам користувачів в POSIX системах (UNIX like). Первинна група облікового запису зберігається у ньому самому (/etc/passwd в UNIX), а дані про членство в інших (вторинних) групах - в самих групах (/etc/group в UNIX).

У зв'язку з цим важливо, як реалізований клієнт, тому що членство в первинній групі можна перевірити тим же запросом, що й логін, наприклад замість фільтра

(&(uid=%u)(objectclass=posixAccount))

написати такий:

(&(uid=%u)(objectclass=posixAccount)(gidNumber=1002))

То членство у вторинній групі можна перевірити тільки ще одним підключенням до сервера, а це повинен уміти клієнт.

Ось так виглядає експортована в ldif формат така група:

dn: cn=group_3,ou=Groups,dc=domain,dc=org
objectClass: posixGroup
objectClass: top
cn: group_3
gidNumber: 1000
memberUid: user1
memberUid: user2

Створити 2 з однаковими gidNumber - в мене вийшло (бо унікальний індентифікатор - dn, а gidNumber - один з атрибутів). Так само можна додати в групу uid користувача, що не існує.

Ось як ці групи описано в схемах LDAP

core.schema

objectclass ( 2.5.6.9 NAME 'groupOfNames'
    DESC 'RFC2256: a group of names (DNs)'
    SUP top STRUCTURAL
    MUST ( member $ cn )
    MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) )

objectclass ( 2.5.6.17 NAME 'groupOfUniqueNames'
    DESC 'RFC2256: a group of unique names (DN and Unique Identifier)'
    SUP top STRUCTURAL
    MUST ( uniqueMember $ cn )
    MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) )

nis.schema

objectclass ( 1.3.6.1.1.1.2.2 NAME 'posixGroup'
    DESC 'Abstraction of a group of accounts'
    SUP top STRUCTURAL
    MUST ( cn $ gidNumber )
    MAY ( userPassword $ memberUid $ description ) )

MS Active Directory має свої особливості.

Об'єкт user має атрибут memberOf, в якому зберігаються DN груп, до яких належить користувач, так що можна використовувати таку перевірку членства в групі:

(&(sAMaccountName=%u)(objectclass=user)(memberOf=cn=GroupName,ou=groups,dc=domain,dc=org))

Тут не робочий зразок, а тільки ідея.

Слід відзначати, що групи в MS Active Directory схожі на groupOfNames в OpenLDAP - вони так само зберігають DN учасників групи.

Слід зазначити, що є два можливих способи використання груп в LDAP, а точніше в клієнті, що проводить аутентифікацію\авторизацію:
1. користувач, що НЕ в групі - не проходить аутентифікацію.
2. користувач проходить аутентифікацію, а на основі членства в групі користувачу надаються права (авторизація)

Перший випадок я зустрічав найчастіше. Другий - в комерційному продукти MS Active Directory, та при використанні pam_ldap, nss_ldap у вищезгаданій інструкції по FreeBSD.

Приклади застосування на практиці.

LDAP + pam_ldap для аутентифікації віртуальних юзерів в vsftpd

Приклад використання LDAP + pam_ldap для аутентифікації віртуальних юзерів в vsftpd
Необхідно рдагувати 3 файли. Вірнише два редагувати, а один створити:

/usr/local/etc/vsftpd.conf
/usr/local/etc/ldap.conf
/usr/local/etc/pam.d/ldapftp

vsftpd.conf (Я не є гуру у використвнні саме цьго сервера, може щось треба підкорегувати).

local_enable=YES
write_enable=YES

anonymous_enable=NO
anon_upload_enable=YES
anon_mkdir_write_enable=NO
anon_other_write_enable=NO
anon_world_readable_only=NO
anon_umask=0022

guest_enable=YES
guest_username=vftp

user_sub_token=$USER
local_root=/var/ftp/virtual/$USER

chroot_local_user=yes
ftp_username=ftp

pam_service_name=ldapftp # перепризначаємо pam модуль, що буде використаний для аутентифікації.

ldap.conf Це мінімально необхідна конфігурація, яка перевіряє паролі, та належність до групи group_1

base dc=domain,dc=org
uri ldap://10.0.0.4/
ldap_version 3

binddn uid=proxyuser,dc=domain,dc=org
bindpw 1234567

scope sub

pam_login_attribute uid
pam_password clear

pam_groupdn cn=goup_1,ou=Groups,dc=domain,dc=org
pam_member_attribute member

В даному випадку objectClass : groupOfNames. objectClass : posixGroup працювати не буде, pam_ldap не буде шукати такий клас груп. Для роботи з таким класом груп преба використовувати модуль nss_ldap.

В ldap.conf є така опція, як pam_filter, за замовчанням фільтр такий: (&(objectClass=posixAccount)(uid=%s)) %s - ім'я, що його напечатав у полі login. В більшості випадків його не треба змінювати, але як що прийдеться це робити - треба мати на увазі, що така опція в конфіг файлі не перезапише значення за замовчанням, а лиш складе їх (логічне AND).

ldapftp

auth            required         /usr/local/lib/pam_ldap.so
account         required         /usr/local/lib/pam_ldap.so

Тут все зроблено згідно документації до vsftpd, тільки pam_userdb.so замінено на pam_ldap.so

Аутентифікація за допомогою Cyrus SASL у MS ActiveDirectory

Адмінстратори Unix like систем мабуть зустрічалися з Cyrus SASL. Багато сервісів можуть використовувати Cyrus SASL як агента для аутентифікації у Kerberos, LDAP і не тільки.

Я використовував цого (вірніше cyrus-sasl-saslauthd) щоб аутентифікувати користувачів поштової системи (Sendmail + Cyrus-imapd) в MS Active Directory.

Правда за замовчанням порт компілюється без підтримки LDAP, так що я робив це так : (на Linux треба буде робити інкше, та ця стаття, як сказано вище, не зовсім для початківців)

# cd /usr/ports/security/cyrus-sasl2-saslauthd
# make WITH_OPENSSL_BASE=yes WITH_OPENLDAP=yes
# make install

Ну й в rc.conf треба додати ще дві строчки:

saslauthd_enable="YES"
saslauthd_flags="-a ldap"

Конфіг файл (з моїми коментарями) виглядає так:

ldap_servers: ldap://172.16.0.50/ ldap://172.16.0.55/ ldap://172.16.200.5/
ldap_bind_dn: cn=proxy_user,ou=IT_ADM,ou=IT,ou=_COMPANY_STRUCTURE,dc=DOMAIN,dc=ORG
ldap_bind_pw: passwd

ldap_search_base: OU=_COMPANY STRUCTURE,DC=DOMAIN,DC=ORG
# Обидва ці фільтри працюють. Перший, я використовував без параметрів ldap_group_*
#ldap_filter: (&(sAMAccountName=%u)(memberOf=cn=IT_ADM,ou=IT_ADM,ou=IT,ou=_COMPANY_STRUCTURE,dc=DOMAIN,dc=ORG))
ldap_filter: (sAMAccountName=%u)

# Параметри ldap_group_* можна пропустити, коли є таке бажання.
# ldap_group_dn згідно документації - обов'язковий параметр, але в мене й без нього працює. 
#ldap_group_dn: cn=IT_ADM,ou=IT_ADM,ou=IT,ou=_COMPANY_STRUCTURE,dc=DOMAIN,dc=ORG
ldap_group_match_method: filter
ldap_group_search_base: OU=_COMPANY STRUCTURE,DC=DOMAIN,DC=ORG
ldap_group_filter: (&(sAMAccountName=IT_ADM)(member=%D))

Ось ця строчка портебує додаткових поясненнь.

ldap_group_filter: (&(sAMAccountName=IT_ADM)(member=%D))

IT_ADM - це назва групи. %D - це dn того юзера, що проходить аутентифікацію.

Подробиці можна почитати у файлі

/usr/local/share/doc/cyrus-sasl2/saslauthd/LDAP_SASLAUTHD

Після того, як все налаштовано й запущено - можна перевірити аутентифікацію:

# testsaslauthd –u username – p userpasswd

На додаток можу сказати, що підключатися до LDAP можуть :
Apache, lighttpd, squid, FreeRadius, OpenVPN, Samba, Sendmail, Exim, Postfix, мабуть багато інших.

Що почитати:

Сайn проекту OpenLDAP http://www.openldap.org/

Просто гарний сайт. http://www.ldapman.org/articles/intro_to_ldap.html

LDAP System Administration by Gerald Carter - гарна книжка видавництва O'Reilly

Вищезгадувана інструкція про використання FreeBSD з pam_ldap, nss_ldap
http://www.freebsd.org/doc/en_US.ISO8859-1/articles/ldap-auth/ldap.html

Короткий й акуратний опис використання LDAP з FreeBSD
http://www.boosten.org/2008/creating-my-own-ldap-directory-part-1/
http://www.boosten.org/2008/creating-my-own-ldap-directory-part-2/
http://www.boosten.org/2009/creating-my-own-ldap-directory-part-3/

Все, що знайдете в мережі, або на книжковому базарі.