AD через LDAP - Как я могу вернуть все группы предков из запроса? - PullRequest
7 голосов
/ 24 июня 2009

Я запрашиваю Active Directory через LDAP (из Java и PHP), чтобы создать список всех групп, членом которых является пользователь. Этот список должен содержать все наименьшие все группы (необязательные организационные единицы), которые содержат группы, членом которых пользователь является непосредственно. Например:

Пользователь1 является членом 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 ]

8 голосов
/ 21 сентября 2011

Active Directory имеет специальную опцию фильтра поиска, которая позволяет фильтровать связанные объекты, например, вложенные группы. Возможность описана здесь .

Вот пример того, как получить всех пользователей в группе, включая вложенные группы:

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

где {0} - DN родительской группы.

2 голосов
/ 24 июня 2009

При отображении дерева каталогов вам необходимо отобразить дерево, чтобы вы могли проверить, исследовали ли вы ранее 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
...