如何编写LDAP查询以测试用户是否是组的成员?

151

我想编写一个LDAP查询,测试用户(sAMAccountName)是否是特定组的成员。是否可以这样做,以便我只获得0或1个结果记录?

我想我可以获取用户的所有组,并测试每个组是否匹配,但我想知道是否可以将其打包到一个LDAP表达式中。

有任何想法吗?

谢谢


请参阅类似问题:递归查询LDAP组成员资格 - Franklin Piat
4个回答

211
你应该能够使用此筛选器创建一个查询:
(&(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的成员,组A又是组B的成员 - 这个事实并没有在此处反映出用户A实际上也是组B的成员。

Marc


2
尝试过了,但对我仍然不起作用。在memberOf子句中应该是“OU=Users”还是“OU=Groups”? - paul
4
这是我的查询: (&(objectClass=person)(sAMAccountName=USERID)(memberof='CN=SPSAdmins,OU=Groups,OU=MYTOWN,OU=Germany,OU=MYCOMPANY,DC=MYTOWN,DC=MYCOMPANY,DC=com')) 这个DN确实很长。我同意它“应该”能够工作。谢谢你的帮助! - paul
4
我突发奇想删掉了memberof后面的单引号,结果我终于得到了结果!谢谢。 - paul
3
好的回答。但需要指出的是,这仅适用于维护“memberOf”属性的LDAP服务器。更通用的技术是获取对象,并检查其uniqueMember、roleOccupant等属性,以便根据组对象使用的模式获取用户的DN。 - user207421
1
这在AIX 7.1上完美运行:ldapsearch -h dc1.example.com -D user@example.com -w \? -b DC=example,DC=com -v "(&(objectClass=user)(memberof=CN=AIX-users,OU=AIX,DC=example,DC=com))" - Wally
显示剩余5条评论

44
如果您使用在Linux服务器上常见的OpenLDAP(即slapd),则必须启用memberof叠加层才能使用(memberOf=XXX)属性来匹配过滤器。此外,一旦启用了这个叠加层,对于现有组,它不会更新memberOf属性(您需要删除现有组并将它们重新添加)。如果您在数据库为空的情况下启用了该叠加层,则应该没问题。

8
提供一个说明如何启用memberof覆盖的页面链接可能会很有用。 - Gokhan Sari
6
适合我的教程:http://www.schenkels.nl/2013/03/how-to-setup-openldap-with-memberof-overlay-ubuntu-12-04/@Telford Tendrys,老兄,你提醒我关于预先存在的组,真是救了我的一命。非常感谢! - ŁukaszBachman
谢谢,浪费了很多时间在尝试在OpenLDAP中使其工作,不知道这个memberOf不是开箱即用的。 - Codigo Morsa

27

我想在Marc的回答中再补充一点:memberOf属性不能包含通配符,因此您不能像"memberof=CN=SPS*"这样说,并期望它找到所有以"SPS"开头的组。


谢谢你提供的信息。我一直在尝试做你说不可能完成的事情。我该如何使用PHP实现它?有没有其他方法可以得到相同的结果?比如查找所有以SPS开头的组...我可以先抓取所有内容,然后循环我的数组并使用preg_match来获取我想要的CN,但如果可能的话,我更愿意直接搜索。 - ODelibalta

20

你需要将查询基础设置为所询问用户的DN,然后将筛选器设置为你想知道他们是否是成员的组的DN。要查看 jdoe 是否是 office 组的成员,则查询将类似于以下内容:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接