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

Вступ.

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

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

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

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

LDAP — це протокол програмного рівня (згідно моделі OSI), працює поверх TCP/IP, традиційно використовує порт 389/tcp (або 636/tcp для роботи через SSL). Призначення сервера LDAP — зберігати ієрархічні (деревовидні) структури даних. Структура дерева може бути якою завгодно, отже на практиці його можна пристосувати до якої завгодно структури організації. Найпростіший приклад застосування LDAP — довідник e-mail/телефонів. Популярні клієнти електронної пошти вміють шукати інформацію в LDAP, але частіше каталог LDAP використовують для зберігання акаунтів (логін/пароль) користувачів мережі. Як вже було сказано, сервер може працювати через 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. Я колись використовував LDAP Browser - теж корисна річ. (http://www.ldapbrowser.com/)

Далі по тексту, окрім балачок будуть приклади, всі вони зроблені на 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:

  • dn за логіном: uid=johns,ou=Users, dc=domain,dc=org
  • 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, там використана модель з логінами, а MS Active Directiry використовує модель з іменами. Яку модель обрати — більше буде залежати від клієнтського ПЗ, що буде підключатися до 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 на співпадіння з тим, що користувач вказав як свій логін), якщо знайдено один dn — повертають його.
  3. логін зі знайденим dn, та тим паролем, що вказав користувач.

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

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

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

Staright Bind

Це скоріше виключення з правила. Він можливий при виконанні наступних умов:

  1. dn за логіном
  2. усі користувачі розташовані в одному орг-юніті, наприклад: ou=Users, dc=domain,dc=org.

Тоді можна провести аутентифікацію за одне підключення до сервера LDAP. В конфіг-файлі клієнта присутня така опція:

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

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

Ось приклади журналу сервера при анонімному підключенні:

Це команда шукати користувача з 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

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

groupOfUniqueName - 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

Створити дві групи з однаковими 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 файли. Вірніше два відредагувати, а один створити:

  • 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

Адмінстратори Юнікс-подібних систем мабуть зустрічалися з 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"

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

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 та, мабуть, багато інших.

Що почитати: