LINUX.ORG.RU
решено ФорумAdmin

Зачем нужны группы в LDAP?

 ,


0

1

Пусть мы используем ldap. Пусть мы завели в нём несколько пользователей. Пусть также мы завели несколько групп, пусть они будут например posixGroup. И пусть теперь мы хотим авторизовывать пользователей в зависимости от принадлежности к той или иной группе.

Естественно мы пытаемся сделать запрос вроде такого:

(&(cn=TestGroup)(memberUid=user1))

Но оказывается что dma_k здесь: http://www.opennet.ru/base/net/ldap_search_filter.txt.html всё таки ошибся.

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

Во первых это наложение (Overlay), то есть этот функционал не входит в базовую поставку. Но даже если мы установим этот оверлей, окажется что к posixGroup он неприменим. И нужно либо пересаживать пользователей в другую группу, либо искать как скрестить memberOf и posixGroup (встречается описание и для этого).

И вот тут у меня возник вопрос. А для чего вообще нужны эти группы? Если их нельзя использовать по своему прямому назначению. Ну, по крайней мере мне кажется что это их прямое назначение: группировать пользователей. Потому что если звёзды зажигают^W^W эти группы существуют, то может быть всё таки существует какой нибудь естественный механизм их использования?

★★★★★

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

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

openldap-servers-2.4.23-34.el6_5.1.x86_64

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

Вот моя страничка про memberOf с GSoC2010 - http://moinmo.in/LDAP2010/memberOf.

Если кратко - в openldap нет memberOf, и вообще изначально afaik это фича ActiveDirectory (могу, конечно, ошибаться), вместо него в openldap есть hasMember.

Попробуй вместо openldap взять 389 Directory Server, он гораздо приятнее в использовании по моему опыту.

ei-grad ★★★★★
()
Ответ на: комментарий от sin_a

А вообще, опять же afair - изначально группы в LDAP (в частности в Novell DS) были на основе нахождения ссылки на пользователя в определенном OU. Собственно OU и являлись группами. С такой схемой вроде все совсем просто становится.

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

Да, вероятно и придётся включать memberOf. И оно похоже действительно пришло из AD. Но мне действительно интересно: группы существуют для того что бы группировать, зачем они нужны здесь, если они не делают то, зачем нужны...

389 Directory Server

А сервисы умеют с ним работать? Джаббер, почта, апач, веб приложения?

sin_a ★★★★★
() автор топика
Ответ на: комментарий от ei-grad

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

sin_a ★★★★★
() автор топика
Ответ на: комментарий от ei-grad

Да, тоже уже прочёл что он просто поддерживает простокол ldap. Спасибо, возможно это действительно лучшая идея. Потому что я о других DS думал, но не думал что они совместимы.

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

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

sin_a ★★★★★
() автор топика
Ответ на: комментарий от ei-grad

А ты с ним имел дело? А то про него пишут божественные вещи:

Если будешь это делать, в процессе поиска наткнёшься на bash скрипт, написанный разрабами, который должен тебе помочь. Не запускай его. Он испаганит всё, включая желание заного всё настраивать

2013 Не стартует 389 Directory Server (комментарий)

Однако... Мой опыт эксплуатации 389-DS показал, что он, ну, скажем так, «хрустальный». И пару раз он, по непонятным мне причинам отказывался загружаться. А именно - он работает не с файлами схемы, не с ldif, а переносит их содержание в свою отдельную базу данных. Ну и если там что порушится, то восстанавливать - нужны особые умственные усилия

2011 http://linuxforum.ru/viewtopic.php?pid=199852#p199852

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

Правильно ли я понимаю, что это отрицательный результат?

 $ ldapsearch -H ldap://testldap/ -x -b "dc=Grp" "(&(cn=Test2)(member=cn=test.user,ou=People,dc=Grp))"   
# extended LDIF
#
# LDAPv3
# base <dc=Grp> with scope subtree
# filter: (&(cn=Test2)(member=cn=test.user,ou=People,dc=Grp))
# requesting: ALL
#

# search result
search: 2
result: 0 Success

# numResponses: 1

Пользователь там определённо присутствует:

 $ ldapsearch -H ldap://testldap/ -x -b "dc=Grp" "(cn=Test2)"                                          
# extended LDIF
#
# LDAPv3
# base <dc=Grp> with scope subtree
# filter: (cn=Test2)
# requesting: ALL
#

# Test2, Test1, Grp
dn: cn=Test2,ou=Test1,dc=Grp
cn: Test2
gidNumber: 505
memberUid: test.user
memberUid: a.test.607
memberUid: a.test.956
memberUid: a.test.737
objectClass: posixGroup
objectClass: top

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1
sin_a ★★★★★
() автор топика
Ответ на: комментарий от sin_a

Хочешь кнопку или быть тру?

Сложный путь прочитать все здесь http://zytrax.com/books/ldap/

Мне нужно groupOfNames вместо posixGroup?

Легкий путь. Объясняю на пальцах: objectClass является ссылкой на класс. Класс определяет аттрибуты. Поиск (концепция, технология) по аттрибутам везде одинаковый. Запихни оба. Из класса groupOfNames тебе нужен аттрибут member, который ссылается на любой DN (даже несуществующий). Из класса posixGroup заполняй gidNumber.

Итого:

dn: cn=myGroup,ou=Groups,dc=example,dc=com
objectClass: posixGroup
objectClass: groupOfNames
gidNumber: 1000
member: cn=user1,ou=Users,dc=example,dc=com
member: cn=user2,ou=Users,dc=example,dc=com
...

gh0stwizard ★★★★★
()
Последнее исправление: gh0stwizard (всего исправлений: 1)
Ответ на: Хочешь кнопку или быть тру? от gh0stwizard

Не хочу быть тру...

Я мальчик и я хочу кнопку... :( И я её уже нашёл: http://button.dekel.ru/

А «LDAP для учёных-ракетчиков» даже в переводе есть. Приходится читать...

У меня phpldapadmin и если я при попытке добавить значение в objectClass в выпадающем списке не нахожу «groupOfNames», то мне нужно искать схему в которой он есть, что бы подключить её?

sin_a ★★★★★
() автор топика

мы пытаемся сделать запрос вроде такого:

(&(cn=TestGroup)(memberUid=user1))
… оказывается что такого рода запрос невозможен.

Вполне возможен! Но его возможность довольно слабо относится к возможностям и ограничениям именно сервера LDAP (любого, включая AD).

Дело в том, что принадлежность к группе может определяться двумя способами:

  • у пользователя перечислить группы, к которым он принадлежит (memberOf)
  • в группе перечислить её членов (member/memberUid)

Аттрибуты для обоих вариантов есть в стандартных классах как для групп, так и для пользователей (сейчас нет под рукой «настоящего» LDAP-сервера, только AD поэтому классы не назову).

Так вот, где хранить членство в группах определяет ПО, записывающее информацию в LDAP. Не сервер LDAP, а клиент или админка, назовите как хотите!

И поэтому во всём ПО, работающим с LDAP, есть выбор варианта поиска членства в группах: «в пользователях» или «в группах». Ну или вообще врукопашную…

наложение (Overlay), то есть этот функционал не входит в базовую поставку

А вот overlay — это вовсе не механизм хранения принадлежности к группам «в группах» или «в пользователях», а механизм синхронизации обоих вариантов. Т.е. при записи пользователю группы в memberOf, этот пользователь overlay'ем прописывается в member(Uid) соответствующей группы. И наоборот — при добавлении в группу memberUid, этому пользователю добавляется атрибут memberOf с новой группой.

MumiyTroll ★★★
()

Нашёл подробности про упомянутый overlay (см. п. «12.8. Reverse Group Membership Maintenance»):

http://www.openldap.org/doc/admin24/overlays.html

adding the following ldif:
…
        cn: testgroup
        member: uid=test1,ou=People,dc=example,dc=com

Results in the following output from a search on the test1 user:
…
 dn: uid=test1,ou=People,dc=example,dc=com
 memberOf: cn=testgroup,ou=Group,dc=example,dc=com

Ну т.е. я приврал, синхронизирует оно только в одну сторону из групп (member) в пользователей (memberOf).

MumiyTroll ★★★
()

Одним запросом без memberOf, по всей видимости, не обойдёшься. Но можно делать несколько запросов. Например, у тебя есть несколько групп, которым разрешён доступ к аутентификации. Ты делаешь ldapsearch по каждой из этих групп с фильтром (memberuid=user1). Если есть положительные результаты, то делаешь поиск по своим контекстам с учётками в поисках dn (uid=user1). Далее по dn проводишь аутентификацию.

Но позиксгруппы неудобны. ИМХО лучше пользоваться groupOfNames. А нужны они для совместимости. Ну и иногда их вполне достаточно, наверное.

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

Если у пользователя можно принудительно указать принадлежность к нескольким группам, то это тоже в принципе решение. Спасибо, завтра буду проверять.

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

sin_a

Что-то в духе (&(cn=TestGroup)(member=cn=user1,ou=people,dc=example,dc=com)).

cn=TestGroup

Вы что вообще пытаетесь найти таким фильтром. А то я по-моему чего-то не понимаю.

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

В следующем посте есть результат двух поисков. Существует группа cn=Test2 и существует пользователь cn=test.user,ou=People,dc=Grp, который в неё входит. Соответственно хотелось бы найти запрос, который позволяет это определить.

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

Если у пользователя можно принудительно указать принадлежность к нескольким группам, то это тоже в принципе решение.

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

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

Вот результат:

ldapsearch -H ldap://127.0.0.1/ -x -b "dc=Grp" "(&(cn=Test2)(memberUid=cn=test.user))"
# extended LDIF
#
# LDAPv3
# base <dc=Grp> with scope subtree
# filter: (&(cn=Test2)(memberUid=cn=test.user))
# requesting: ALL
#

# search result
search: 2
result: 0 Success

# numResponses: 1

Если я правильно понимаю, то result: 0 означает что пользователя не авторизуют. Завтра попробую пользователю групп добавить. Без пыхадмина тяжело... :(

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

Если я правильно понимаю, то result: 0 означает что пользователя не авторизуют.

ldapsearch - это поиск по каталогу, а не авторизация. Этот поиск должен возвращать записи, которые подходят под фильтр. В данном случае он должен вернуть группу cn=test2.

Покажи вывод

ldapsearch -H ldap://127.0.0.1/ -x -b "dc=Grp" "(memberUid=cn=test.user)"

И ещё

ldapsearch -H ldap://127.0.0.1/ -x -b "dc=Grp" "(memberUid=cn=*test*)"

Ivan_qrt ★★★★★
()
Последнее исправление: Ivan_qrt (всего исправлений: 1)
Ответ на: комментарий от Ivan_qrt

ldapsearch - это поиск по каталогу

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

вывод

Одинаковый, различается только строка «фильтр»:

ldapsearch -H ldap://127.0.0.1/ -x -b "dc=Grp" "(memberUid=cn=*test*)"# extended LDIF
#
# LDAPv3
# base <dc=Grp> with scope subtree
# filter: (memberUid=cn=*test*)
# requesting: ALL
#

# search result
search: 2
result: 0 Success

# numResponses: 1
sin_a ★★★★★
() автор топика
Ответ на: комментарий от sin_a

Да, запрос без «memberUid=» возвращает всю информацию о пользователе.

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

Впрочем, видимо так и должно быть:

ldapsearch -H ldap://127.0.0.1/ -x -b "dc=Grp" "(cn=test.user)" | grep member

Пусто

Завтра буду смотреть что можно добавить пользователю.

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

Это плохо. Судя по всему у тебя сломан memberuid, либо что-то сделано не так.

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

PS покажи

ldapsearch -H ldap://127.0.0.1/ -x -b "dc=Grp" "(uid=test.user)"

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

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

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

ldapsearch -H ldap://127.0.0.1/ -x -b "dc=Grp" "(cn=test.user)"
# extended LDIF
#
# LDAPv3
# base <dc=Grp> with scope subtree
# filter: (cn=test.user)
# requesting: ALL
#

# test.user, People, Grp
dn: uid=test.user,ou=People,dc=Grp
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: test.user
sn: test.user
givenName: test.user
uid: test.user
uidNumber: 1065
gidNumber: 513
homeDirectory: /home/test.user
loginShell: /bin/bash
gecos: System User
shadowLastChange: 14471
shadowMax: 45
userPassword:: e01ENX00UXJjT1VtNldhdStWdUJYOGcrSVBnPT0=
mail: test.user@test.example.org
mail: test.user@test2.example.org

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

Поэтому и 389 DS заинтересовал. В принципе есть возможность сменить DS. Правда приведённые выше цитаты охлаждают интерес.

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

Скорее не сломан а не сделан.

Да там по идее нечего делать. Должно работать из коробки.

Могу пованговать, что дело в точке в uid'е. Попробуй без неё. Ну и раз такая пьянка, пробуй переползать на groupofnames.

389ds я пока не тыкал, но всё собираюсь. Они оба вылезли из netscape directory server и во многом похожи. Насколько я понимаю, эта часть у них практически одинаковая. Единственное что, у 389 дефолтная схема отличается по мелочам.

Короче, принцип организации всего ты можешь прорабатывать и на openldap'е. Потом перелезть на 389 не должно составить проблем. По-крайней мере я у себя надеюсь перелезть.

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

Блин, у меня же апач уже обучен, надо иногда оглядываться на уже сделанное. И в логе лдап отражается что он это запрашивает. Вот значимая часть лога slapd:

fd=17 ACCEPT from IP=10.10.10.4:41642 (IP=0.0.0.0:389)
op=0 BIND dn="" method=128
op=0 RESULT tag=97 err=0 text=
op=1 SRCH base="ou=People,dc=Grp" scope=2 deref=3 filter="(&(objectClass=*)(uid=test.user))"
op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
op=2 BIND dn="uid=test.user,ou=People,dc=Grp" method=128
op=2 BIND dn="uid=test.user,ou=People,dc=Grp" mech=SIMPLE ssf=0
op=2 RESULT tag=97 err=0 text=
op=3 BIND anonymous mech=implicit ssf=0
op=3 BIND dn="" method=128
op=3 RESULT tag=97 err=0 text=

op=4 CMP dn="cn=Test2,ou=Test1,dc=Grp" attr="memberUid"

op=4 RESULT tag=111 err=6 text=

Остаётся понять чем вызывается выделенная строка.

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

Он просто считывает сначала пользователя, а потом - группу. И сравнивает DN юзера с DN из атрибута группы memberUid.

То бишь это два запроса идут, а не один.

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

Проверил у себя. Создал тестовый dc=grp, набил его posixgroup'ами.

% ldapsearch -xw "secret" -D "cn=admin,dc=grp" -b "dc=grp" "(&(cn=admins)(memberuid=ivan))"
# extended LDIF
#
# LDAPv3
# base <dc=grp> with scope subtree
# filter: (&(cn=admins)(memberuid=ivan))
# requesting: ALL
#

# admins, groups, grp
dn: cn=admins,ou=groups,dc=grp
objectClass: posixGroup
gidNumber: 1002
cn: admins
description:: 0JDQtNC80LjQvdGLLg==
memberUid: ivan
memberUid: syncuser

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

Так что у тебя что-то сделано не так.

Схемы подключены core.ldif, cosine.ldif и nis.ldif. Всё на дефолтах.

А в логе у тебя нечто странное (имхо). Какой запрос был у этого лога.

Ivan_qrt ★★★★★
()
Последнее исправление: Ivan_qrt (всего исправлений: 1)
Ответ на: комментарий от Ivan_qrt

Это уже не ldapsearch а апач. До того я его настроил, и он определяет по группе. Но скорее всего он действительно отправляет два запроса. Собственно уже пробую groupOfNames.

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

Да, лог лдап сервера, но запросов всё таки видимо два. Апач проверяет наличие пользователя, получает список членов и смотрит попадает пользователь или нет.

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

Ну да, я это и имел в виду. У меня немного по-другому, апач авторизует через керберос прозрачно, а потом проверяет в группе:

        AuthLDAPUrl "ldap://10.1.16.10/OU=Users,DC=domain,DC=ru?sAMAccountName?sub?(&(objectclass=user)(!(UserAccountControl=66050)))" NONE
        AuthLDAPBindDN CN=service_ldap_ro,CN=Users,DC=domain,DC=ru
        AuthLDAPBindPassword xxx
        AuthLDAPGroupAttribute member
        AuthLDAPGroupAttributeIsDN On
        Require ldap-group CN=IT_Department,OU=Groups,DC=domain,DC=ru

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

Ну тогда апач работает правильно. Он находит dn test.user, биндится под его учёткой, после чего из-под анонимуса сравнивает memberuid группы cn=test2 с каким-то значением, на что получает ldap_compare_true (op=4 RESULT tag=111 err=6 text=).

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

"(&(cn=admins)(memberuid=ivan))"

Спасибо, всё таки это действительно работает. В приложениях я уже запутался, а у ldapsearch в таком выводе «result: 0» понял как пустой результат...

sin_a ★★★★★
() автор топика
Ответ на: комментарий от sin_a
# search result
search: 2
result: 0 Success - 0 это код возврата. Успех, операция прошла нормально.

# numResponses:
# numEntries: 1 - кол-во найденных записей. - вот это тебе и нужно.
Ivan_qrt ★★★★★
()
Ответ на: комментарий от Ivan_qrt

Спасибо. Вообще я сам себе заморочил голову. Очень хотелось авторизовать если пользователь включён в подгруппу примерно так: cn=*,ou=Test1,dc=Grp, и вместо того что бы идти постепенно сразу начал такого рода запросы ставить. А потом уже просто запутался в примерах.

sin_a ★★★★★
() автор топика
Ответ на: Не хочу быть тру... от sin_a

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

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

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

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

Нужность определяется задачами. У разработчика ПО (если я правильно понял), у администратора большой организации и разветвлённой сети и у администратора маленькой организации с несложными требованиями будут существенно разные критерии.

И если документация, даже переводная, даёт достаточно полное представление для решения текущих задач, то дальнейшее изучение вопроса имеет смысл только если тема представляет некий специальный интерес. Но ldap на специальный интерес не всегда тянет. По сути, нишевая вещь, хотя и достаточно важная.

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