ACL OpenLDAP не взаимодействуют

У меня был простой ACL на моем сервере, который работал нормально. Я решил настроить SSSD для аутентификации пользователей при входе в систему через LDAP, поэтому мне нужно предоставить больше доступа к учетной записи привязки SSSD. В процессе я каким-то образом заблокировал весь доступ за пределами первого ACL; несмотря на break в конце ACL {0}, каждый поиск, который не выполняется пользователем уровня root, возвращает ошибку 32 (объект не найден).

Структура базы данных выглядит примерно так:

organization: dc=r1,dc=internal
    organizationalUnit: ou=users,dc=r1,dc=internal
        inetOrgPerson: uid=mike,ou=users,dc=r1,dc=internal
    organizationalUnit: ou=groups,dc=r1,dc=internal
        groupOfUniqueNames: cn=root,ou=groups,dc=r1,dc=internal
        posixGroup: cn=mike,ou=groups,dc=r1,dc=internal
    organizationalUnit: ou=system,dc=r1,dc=internal
        inetOrgPerson: uid=sssd,ou=system,dc=r1,dc=internal

Вот мой ACL:

version: 1

dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcAccess
# admin users can write anything in this subtree
# also the root SASL user (eg ldapmodify -QY EXTERNAL -H ldapi:/// ...)
# nobody else has access, but continue searching for matches below
olcAccess: {0}to dn.subtree="dc=r1,dc=internal"
  by anonymous break
  by group/groupOfUniqueNames/uniqueMember="cn=root,ou=groups,dc=r1,dc=internal" write
  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
  by * break
# sssd user can read all user/group attributes
# other users keep looking
olcAccess: {1}to dn.onelevel="ou=users,dc=r1,dc=internal"
  by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
  by * break
olcAccess: {2}to dn.onelevel="ou=groups,dc=r1,dc=internal"
  by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
  by * break
# you can update your own password
# anonymous users can authenticate against it
# nobody else sees it
olcAccess: {3}to dn.subtree="dc=r1,dc=internal"
  attrs=userPassword
    by self write
    by anonymous auth
    by * none
# anonymous users can read select user/group attributes
olcAccess: {4}to dn.onelevel="ou=users,dc=r1,dc=internal"
  attrs=entry,cn,uid,sn,givenName,mail,telephoneNumber,mobile,memberOf
    by anonymous read
    by * break
olcAccess: {5}to dn.onelevel="ou=groups,dc=r1,dc=internal"
  attrs=entry,cn,description,uniqueMember,memberUid
    by anonymous read
    by * break
# all users can update their own records
# and see all other users' attributes
# everyone (including anonymous) can search
olcAccess: {6}to dn.onelevel="ou=users,dc=r1,dc=internal"
  by self write
  by users read
  by * search

Вот выдержка из журнала с дополнительным ведением журнала ACL:

Aug 26 13:04:10 lemongrab slapd[3991]: => access_allowed: search access to "ou=users,dc=r1,dc=internal" "entry" requested
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [1] dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_get: [1] matched
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_get: [1] attr entry
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_mask: access to entry "ou=users,dc=r1,dc=internal", attr "entry" requested
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_mask: to all values by "uid=sssd,ou=system,dc=r1,dc=internal", (=0)
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_dn_pat: anonymous
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_dn_pat: cn=admin,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_group_pat: cn=root,ou=groups,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => mdb_entry_get: found entry: "cn=root,ou=groups,dc=r1,dc=internal"
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_dn_pat: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_dn_pat: *
Aug 26 13:04:10 lemongrab slapd[3991]: <= acl_mask: [5] applying +0 (break)
Aug 26 13:04:10 lemongrab slapd[3991]: <= acl_mask: [5] mask: =0
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [2] ou=users,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [3] ou=groups,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [4] dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_get: [4] matched
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [5] ou=users,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [6] ou=groups,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [7] ou=users,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: <= acl_get: done.
Aug 26 13:04:10 lemongrab slapd[3991]: => slap_access_allowed: no more rules
Aug 26 13:04:10 lemongrab slapd[3991]: => access_allowed: no more rules

Записи в журнале подтверждают мое подозрение, что после первого правила ничего особенного не делается. Почему, например, он перескакивает с правила 1 на правило 4? Насколько я понимаю, следующим следует рассмотреть правило 2.

я пробовал оба onelevel а также children области в ACL с тем же эффектом. Если я изменю ACL на olcAccess: {1}to dn.subtree="dc=r1,dc=internal" вроде работает, но есть и другие OU помимо пользователей и групп, которым я не хочу предоставлять доступ. Я неправильно понимаю, как работает прицел?

openldap-список-управления-доступом

микен32

1 ответ
1

Обновлять Я понял! Основная проблема заключается в том, что документация неуловима. Это описание квалификаторов dnstyle в slapd.access(5):

<dnstyle> является необязательным; однако рекомендуется указать его, чтобы избежать двусмысленностей. База (синоним baseObject), значение по умолчанию или exact (псевдоним base) указывает запись, DN которой равно <dnpattern>; one (синоним onelevel) указывает на все записи непосредственно под <dnpattern>, sub (синоним subtree) указывает на все записи в поддереве на
<dnpattern>, children указывает все записи ниже (подчиненные) <dnpattern>.

Ключевым моментом является то, что dn.one предоставляет доступ к Только записи сразу под <dnpattern>. Если вы пишете (как у вас):

olcAccess: {1}to dn.onelevel="ou=users,dc=r1,dc=internal"
  by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
  by * break
olcAccess: {2}to dn.onelevel="ou=groups,dc=r1,dc=internal"
  by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
  by * break

Это будет потерпеть неудачупотому что dn.onelevel="ou=users,dc=r1,dc=internal"
не предоставляет sssd доступ пользователя к дн
ou=users,dc=r1,dc=internal сам. Если вы посмотрите на журналы ACL при выполнении запроса, вы увидите что-то вроде:

=> access_allowed: search access to "ou=users,dc=r1,dc=internal" "entry" requested

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

olcAccess: to dn.onelevel="ou=users,dc=r1,dc=internal"
  by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
  by * break

С этим:

# grant access to ou=users
olcAccess: to dn.base="ou=users,dc=r1,dc=internal"
  by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
  by * break
# grant access to entries immediately below ou=users
olcAccess: to dn.onelevel="ou=users,dc=r1,dc=internal"
  by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
  by * break

(Вы можете заменить read с search в первом ACL, если вы не хотите sssd читать атрибуты самого ou.)

Вот полный набор ACL, которые я настроил в своей тестовой среде:

dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: mdb
olcSuffix: dc=r1,dc=internal
olcDbDirectory: /var/lib/openldap/r1.internal
# root has access to everything always
olcAccess: to *
  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
  by * break
# root and members of cn=root group can access everything
olcAccess: to dn.subtree="dc=r1,dc=internal"
  by anonymous break
  by group/groupOfUniqueNames/uniqueMember="cn=root,ou=groups,dc=r1,dc=internal" write
  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
  by * break
# sssd user can read all users
olcAccess: to dn.base="ou=users,dc=r1,dc=internal"
  by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
  by * break
olcAccess: to dn.one="ou=users,dc=r1,dc=internal"
  by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
  by * break
# sssd user can read all groups
olcAccess: to dn.base="ou=groups,dc=r1,dc=internal"
  by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
  by * break
olcAccess: to dn.one="ou=groups,dc=r1,dc=internal"
  by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
  by * break
# self can modify password, anon can authenticate
olcAccess: to dn.subtree="dc=r1,dc=internal"
  attrs=userPassword
    by self write
    by anonymous auth
    by * none
# anonymous can read selected user attributes
olcAccess: to dn.base="ou=users,dc=r1,dc=internal"
    by anonymous search
    by * break
olcAccess: to dn.one="ou=users,dc=r1,dc=internal"
  attrs=entry,cn,uid,sn
    by anonymous read
    by * break
# anonymous can read selected group attributes
olcAccess: to dn.base="ou=groups,dc=r1,dc=internal"
    by anonymous search
    by * break
olcAccess: to dn.subtree="ou=groups,dc=r1,dc=internal"
  attrs=entry,cn,uniqueMember,objectClass
    by anonymous read
    by * break
# self can modify own entry, authenticated users can
# read all entries
olcAccess: to dn.base="ou=users,dc=r1,dc=internal"
  by * search
olcAccess: to dn.one="ou=users,dc=r1,dc=internal"
  by self write
  by users read
  by * search

Это работает! С такой структурой каталогов:

dn: ou=users,dc=r1,dc=internal
  dn: cn=user1,ou=users,dc=r1,dc=internal
  dn: cn=user2,ou=users,dc=r1,dc=internal
  dn: ou=nested,ou=users,dc=r1,dc=internal
    dn: cn=user3,ou=nested,ou=users,dc=r1,dc=internal

Затем работает:

ldapsearch -LLL -H ldap://localhost:3890 -x \
  -D uid=sssd,ou=system,dc=r1,dc=internal -w secret \
  -b ou=users,dc=r1,dc=internal dn

Производит:

dn: ou=users,dc=r1,dc=internal

dn: cn=user1,ou=users,dc=r1,dc=internal

dn: cn=user2,ou=users,dc=r1,dc=internal

dn: ou=nested,ou=users,dc=r1,dc=internal

… это именно то, что мы хотим: sssd может видеть только один уровень и не видит пользователей ниже ou=nested. Если мы выполним тот же поиск в качестве члена root группа, теперь мы видим user3 под
ou=nested:

dn: ou=users,dc=r1,dc=internal

dn: cn=user1,ou=users,dc=r1,dc=internal

dn: cn=user2,ou=users,dc=r1,dc=internal

dn: ou=nested,ou=users,dc=r1,dc=internal

dn: cn=user3,ou=nested,ou=users,dc=r1,dc=internal

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *