LINUX.ORG.RU
ФорумAdmin

openldap и ACL по objectClass

 ,


0

1

Здравствуйте.

Есть вот такая структура:

dn: o=z
objectclass: organization
objectclass: top
o: z

dn: domainName=example.org,o=z
objectclass: mailDomain
objectclass: top
domainname: example.org

dn: uid=user,domainName=example.org,o=z
objectclass: account
objectclass: mailUser
objectclass: top
mail: user@example.org
uid: user

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

Первый вариант (некрасивый):

Добавляем подветку

dn: ou=Admins,domainName=example.org,o=z
objectclass: organizationalUnit
objectclass: top
ou: Admins

dn: uid=postmaster,ou=Admins,domainName=example.org,o=z
objectclass: account
objectclass: mailAdmin
objectclass: top
mail: postmaster@example.org
uid: postmaster

Пишем ACL:

{0}to attrs=userPassword
	by self write
	by anonymous auth
	by * none
{1}to dn.regex="^(.+,)?(domainName=[^,]+,o=z)$"
	by dn.onelevel,expand="ou=Admins,$2" write
{2}to *
	by self write

В результате, только те, кто находится в поддереве ou=Admin каждого domainName, имеют права на изменения только в в пределах собственной песочницы domainName=[^,]+,o=z .

Второй вариант (как хочется):

Добавляем только аккаунты такого вида:

dn: uid=admin,domainName=example.org,o=z
objectclass: account
objectclass: mailAdmin
objectclass: top
mail: admin@example.org
uid: admin

(см. objectClass) и переписываем этот ACL

{1}to dn.regex="^(.+,)?(domainName=[^,]+,o=z)$"
	by dn.onelevel,expand="ou=Admins,$2" write

к такому виду, который понимает что в ветку dn.regex может писать только такая запись из subtree/onelevel/etc текущего domainName, которая имеет objectClass=mailAdmin.

Итак, вопрос: как это объяснить openldap'у?


2 раза перечитал - ничего не понял, простая конструкция

access to dn=«dc=domainName=example.org,o=z»
by dn.children=«domainName=example.org,o=z» write

Не устраивает, там разные классы (много) пользователей добавлены?

zgen ★★★★★
()
Ответ на: комментарий от zgen

Нет, не устраивает, потому что

  • Этих domainName разных очень много;
  • Доступ к их содержимому конкретного domainName должен быть только у подзаписей этого domainName. Чтение можно организовать с помощью ACL с regex, аналогичной вышеприведённой, естественно, адаптированной;
  • Доступ на запись в domainName должен быть только у подзапиcей этого domainName, которые имеют objectClass=mailAdmin. Опять таки, этих mailAdmin'ов в пределах domainName может быть много.

Так что, либо подстраиваемся под возможности ACL'ей у openldap, создавая внутри domainName ou или группу memberOf, а потом применяя магию с regex уже знакомым способом или делаем что-то такое, чтобы ACL в разделе by понимала не только dn.xxx, но и фильтровала их по objectClass.

HolyBoy
() автор топика
Ответ на: комментарий от HolyBoy

К сож. пока нет времени попробовать, но задача интересная!

zgen ★★★★★
()
Ответ на: комментарий от bass

О!

Используя запрос:

ldapsearch -D "uid=adm,domainName=example.org,o=z" -b "o=z" -w 123 -s subtree "(objectClass=*)"

и аккаунт

dn: uid=adm,domainName=example.org,o=z
objectclass: inetOrgPerson
objectclass: mailAdmin
objectclass: organizationalPerson
objectclass: person
objectclass: top
cn: adm
sn: adm
uid: adm
mail: ps@example.org
userpassword: pass

проверяем как это всё работает.

Я поначалу написал такой ACL:

{0}to attr=userPassword
	by self write
	by anonymous auth
	by * none
{1}to attrs=entry
	by users read
	by * none
{2}to dn.regex=".+,domainName=([^,]+),o=z$"
	by self write
	by * none

Таким способом мы даём изменять и читать только свои собственные аккаунты. Затем, добавляем в последний ACL

{2}to dn.regex=".+,domainName=([^,]+),o=z$"
	by self write
	by dn.one,expand="domainName=$1,o=z" read
	by * none

и стало показывать всё содержимое domainName только для той записи, которая находится внутри domainName на 1-м уровне.

снова меняем последнюю ACL:

{2}to dn.regex=".+,domainName=([^,]+),o=z$"
	by self write
	by dn.one,expand="domainName=$1,o=z/objectClass:mailAdmin" read
	by * none

и всё… ломается.

Работает только строка by self write, т.е. показываются только свои аккаунты.

Смотрю логи (кусок лога о запросе одной из записей внутри example.org)

=> access_allowed: search access to "uid=rest,domainName=example.org,o=z" "objectClass" requested
=> dnpat: [3] .+,domainName=([^,]+),o=z$ nsub: 1
=> acl_get: [3] matched
=> acl_get: [3] attr objectClass
=> match[dn0]: 0 34
…
=> match[dn1]: 12 19
…
=> acl_mask: access to entry "uid=rest,domainName=example.org,o=z", attr "objectClass" requested
=> acl_mask: to all values by "uid=adm,domainName=example.org,o=z", (=0)
<= check a_dn_pat: self
<= check a_dn_pat: dc=$1,o=z/objectclass:mailAdmin
=> acl_string_expand: pattern:  dc=$1,o=z/objectclass:mailAdmin
=> acl_string_expand: expanded: domainName=example.org,o=z/objectclass:mailAdmin
<= check a_dn_pat: *
<= acl_mask: [3] applying none(=0) (stop)
<= acl_mask: [3] mask: none(=0)
=> slap_access_allowed: search access denied by none(=0)
=> access_allowed: no more rules

поменял ACL:

{1}to attrs=entry,objectClass
	by users read
	by * none

Стало выводить всем пользователям objectClass'ы всей базы (что понятно и не страшно), но того, что надо, всё равно не выводится.

HolyBoy
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.