2009-06-24 72 views
7

我通过LDAP(来自Java和PHP)查询Active Directory以构建用户所属的所有组的列表。该列表必须包含所有至少包含用户直接参与的组的所有组(组织单位可选)。例如:AD via LDAP - 如何返回查询中的所有祖先组?

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

您需要映射的目录树,你通过它移动,这样你就可以检查,看看是否您以前探索出了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 
7

Active Directory中有一个特殊的搜索过滤选项,允许其通过连锁目标筛选,像嵌套组。该能力被描述为here

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

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

其中{0}是父组的DN。