Как написать запрос LDAP, чтобы проверить, является ли пользователь членом группы?

129

Я хочу написать запрос LDAP, который проверяет, является ли пользователь (sAMAccountName) членом определенной группы. Можно ли сделать так, чтобы я получил либо 0, либо 1 результативную запись?

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

Любые идеи?

Спасибо

Павел
источник
См. Также такие вопросы, как « Рекурсивный запрос членства в группе LDAP»
Франклин Пиат,

Ответы:

177

Здесь вы сможете создать запрос с этим фильтром:

(&(objectClass=user)(sAMAccountName=yourUserName)
  (memberof=CN=YourGroup,OU=Users,DC=YourDomain,DC=com))

и когда вы запускаете это на своем сервере LDAP, если вы получаете результат, ваш пользователь yourUserName действительно является членом группы CN = YourGroup, OU = Users, DC = YourDomain, DC = com

Попробуйте и посмотрите, работает ли это!

Если вы используете C # / VB.Net и System.DirectoryServices, этот фрагмент должен помочь:

DirectoryEntry rootEntry = new DirectoryEntry("LDAP://dc=yourcompany,dc=com");

DirectorySearcher srch = new DirectorySearcher(rootEntry);
srch.SearchScope = SearchScope.Subtree;

srch.Filter = "(&(objectClass=user)(sAMAccountName=yourusername)(memberOf=CN=yourgroup,OU=yourOU,DC=yourcompany,DC=com))";

SearchResultCollection res = srch.FindAll();

if(res == null || res.Count <= 0) {
    Console.WriteLine("This user is *NOT* member of that group");
} else {
    Console.WriteLine("This user is INDEED a member of that group");
}

Предупреждение: это проверяет только непосредственное членство в группах и не проверяет членство в так называемой «основной группе» (обычно «cn = Users») в вашем домене. Он не обрабатывает вложенное членство, например, пользователь A является членом группы A, которая является членом группы B - тот факт, что пользователь A действительно является членом группы B, здесь также не отражается.

Марк

marc_s
источник
1
Пытался, но у меня все еще не работает. Должно ли это быть «OU = Users» или «OU = Groups» в предложении memberOf?
Пол
3
Это мой запрос: (& (objectClass = person) (sAMAccountName = USERID) (memberof = 'CN = SPSAdmins, OU = Groups, OU = MYTOWN, OU = Germany, OU = MYCOMPANY, DC = MYTOWN, DC = MYCOMPANY, DC = com ')) DN действительно такой длинный. Я согласен, что это должно работать. Спасибо за помощь!
Пол
3
По прихоти я удалил одинарные кавычки после memberof, и теперь я получаю результат! Спасибо
пол
2
Хороший ответ. но следует отметить, что он будет работать только на серверах LDAP, которые поддерживают атрибут memberOf. Более общий метод состоит в том, чтобы получить объект группы и проверить его атрибуты uniqueMember, roleOccupant и т. Д. На предмет DN пользователя, в зависимости от того, какую схему использует объект группы.
Маркиз Лорн,
1
Имена и значения атрибутов LDAP @Gunslinger не чувствительны к регистру, как и DN, но в AD есть свои правила ...
Marquis of Lorne
35

Если вы используете OpenLDAP (например, slapd), который широко распространен на серверах Linux, вы должны включить наложение memberof, чтобы иметь возможность сопоставлять его с фильтром с помощью атрибута (memberOf = XXX).

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

Телфорд Тендис
источник
8
Думаю, будет полезна ссылка на страницу, которая объясняет, как включить наложение memberof.
Гохан Сари
5
У меня сработало руководство : schenkels.nl/2013/03/… @Telford Tendrys, чувак, ты спас мне жизнь этим уведомлением о ранее существовавших группах. Большое спасибо!
ukaszBachman
21

Я бы добавил к ответу Марка еще одну вещь: атрибут memberOf не может содержать подстановочные знаки, поэтому вы не можете сказать что-то вроде «memberof = CN = SPS *» и ожидать, что он найдет все группы, начинающиеся с «SPS».

Билл Бринкли
источник
Спасибо за информацию! Я пытался сделать то, что ты говоришь, сделать нельзя. Как я могу сделать это с помощью PHP? Можно ли получить такой же результат другим способом? чтобы найти все группы, начинающиеся с SPS, а затем с чем угодно ... Я всегда могу захватить все и зациклить свой массив, а затем предварительно сопоставить с CN, который я хочу, но я предпочитаю просто искать его, если это возможно.
ODelibalta 03
15

Вы должны установить свою базу запросов на DN соответствующего пользователя, а затем установить свой фильтр на DN группы, членом которой вы хотите знать, являются ли они. Чтобы узнать, является ли jdoe членом офисной группы, ваш запрос будет выглядеть примерно так:

ldapsearch -x -D "ldap_user" -w "user_passwd" -b "cn=jdoe,dc=example,dc=local" -h ldap_host '(memberof=cn=officegroup,dc=example,dc=local)'

Если вы хотите увидеть ВСЕ группы, членом которых он является, просто запросите в поиске только атрибут memberof, например:

ldapsearch -x -D "ldap_user" -w "user_passwd" -b "cn=jdoe,dc=example,dc=local" -h ldap_host **memberof**
gpayne_007
источник