AD通过LDAP - 如何从查询中返回所有祖先组?

时间:2009-06-24 16:44:38

标签: java php active-directory ldap

我通过LDAP(来自Java和PHP)查询Active Directory,以构建用户所属的所有组的列表。此列表必须包含所有包含用户直接成员的组的所有组(组织单位可选)。例如:

User1是GroupA,GroupB和GroupC的成员。

GroupA是GroupD的成员。

我正在寻找一种构建LDAP查询的方法,该查询将同时返回GroupA,GroupB,GroupC, GroupD。

我目前的实施情况如下,但我正在寻找一种更有效的方式来收集这些信息。

当前天真实施(伪代码)

user = ldap_search('samaccountname=johndoe', baseDN);
allGroups = array();
foreach (user.getAttribute('memberOf') as groupDN) {
    allGroups.push(groupDN);
    allGroups = allGroups.merge(getAncestorGroups(groupDN));
}

function getAncestorGroups(groupDN) {
    allGroups = array();
    group = ldap_lookup(groupDN);
    parents = group.getAttribute('memberOf');
    foreach (parents as groupDN) {
        allGroups.push(groupDN);
        allGroups = allGroups.merge(getAncestorGroups(groupDN));
    }
    return allGroups;
}

2 个答案:

答案 0 :(得分:8)

Active Directory有一个特殊的搜索过滤器选项,允许它通过链接对象(如嵌套组)进行过滤。该功能描述为here

以下是如何检索组中所有用户的示例,包括嵌套组:

(&(objectClass=user)(memberof:1.2.840.113556.1.4.1941:={0}))

其中{0}是父组的DN。

答案 1 :(得分:2)

当您浏览目录树时,您需要映射目录树,以便检查是否先前已经探索过DN,某些活动目录包含循环组包含。所以你需要防范它。

此解决方案也不需要递归。

在一些伪代码中

def getGroupsOfDN(userDN)

     groups = []
     groupsExplored = []
     groupsToExplore = []


     current = userDN
     groupsToExplore << userDN

     while(!groupsToExplore.empty?)


        ldapentry = ldap_lookup(current)

        if (!ldapentry.nil?)
           groups << current
           current_groups = ldapentry.getAttributes("memberOf")
           current_groups.each do |groupDN|
              if(groupsExplored.indexOf(groupDN) != -1)
                 groupsToExplore << groupDN
                 groupsExplored << groupDN
              end
           end
        end

        groupsToExplore.remove(current)
        if (!groupsToExplore.empty?)
           current = groupsToExplore.get(0)            
     end
     return groups
end