Jak napisać zapytanie LDAP, aby sprawdzić, czy użytkownik jest członkiem grupy?

129

Chcę napisać zapytanie LDAP, które sprawdza, czy użytkownik (sAMAccountName) jest członkiem określonej grupy. Czy można to zrobić, aby uzyskać 0 lub 1 rekordów wyników?

Wydaje mi się, że mogę pobrać wszystkie grupy dla użytkownika i przetestować każdą pod kątem dopasowania, ale zastanawiałem się, czy mogę spakować je do jednego wyrażenia LDAP.

Jakieś pomysły?

Dzięki

Paweł
źródło
Zobacz także pytania, takie jak Rekurencyjne zapytania o członkostwo w grupach LDAP
Franklin Piat

Odpowiedzi:

177

Tutaj powinno być możliwe utworzenie zapytania z tym filtrem:

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

a kiedy uruchomisz to na serwerze LDAP, jeśli otrzymasz wynik, Twój użytkownik „yourUserName” jest rzeczywiście członkiem grupy „CN = YourGroup, OU = Users, DC = YourDomain, DC = com

Spróbuj i zobacz, czy to działa!

Jeśli używasz C # / VB.Net i System.DirectoryServices, ten fragment powinien załatwić sprawę:

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");
}

Uwaga: to przetestuje tylko bezpośrednie członkostwo w grupach, a nie członkostwo w tak zwanej „grupie podstawowej” (zwykle „cn = Użytkownicy”) w Twojej domenie. Nie obsługuje zagnieżdżonych członkostw, np. Użytkownik A jest członkiem grupy A, która jest członkiem grupy B - fakt, że użytkownik A jest w rzeczywistości członkiem grupy B, również nie jest tu odzwierciedlany.

Marc

marc_s
źródło
1
Próbowałem, ale nadal nie działa dla mnie. Czy w klauzuli memberOf powinien znajdować się „OU = Users” czy „OU = Groups”?
paul
3
To jest moje zapytanie: (& (objectClass = person) (sAMAccountName = USERID) (memberof = 'CN = SPSAdmins, OU = Groups, OU = MYTOWN, OU = Germany, OU = MYCOMPANY, DC = MYTOWN, DC = MYCOMPANY, DC = com ')) Nazwa wyróżniająca jest naprawdę taka długa. Zgadzam się, że to powinno działać. Dzięki za pomoc!
paul
3
Dla kaprysu usunąłem pojedyncze cudzysłowy po memberof i teraz otrzymuję wynik! Dzięki
paul
2
Dobra odpowiedź. ale należy zaznaczyć, że będzie działać tylko na serwerach LDAP, które mają atrybut „memberOf”. Bardziej ogólną techniką jest pobranie obiektu grupy i sprawdzenie jego atrybutów uniqueMember, roleOccupant itp. Pod kątem nazwy wyróżniającej użytkownika, w zależności od schematu używanego przez obiekt grupy.
Markiz Lorne
1
@Gunslinger w nazwach i wartościach atrybutów LDAP nie jest rozróżniana wielkość liter, ani nazwy wyróżniające, ale AD ma swoje własne zasady ...
Marquis of Lorne,
35

Jeśli używasz OpenLDAP (tj. Slapd), który jest powszechny na serwerach Linux, musisz włączyć nakładkę memberof, aby móc dopasować ją do filtru przy użyciu atrybutu (memberOf = XXX).

Ponadto, gdy włączysz nakładkę, nie zaktualizuje ona atrybutów memberOf dla istniejących grup (będziesz musiał usunąć istniejące grupy i dodać je ponownie). Jeśli włączyłeś nakładkę na początku, gdy baza danych była pusta, powinno być OK.

Telford Tendys
źródło
8
Myślę, że przydałby się link do strony, która wyjaśnia, jak włączyć nakładkę memberof.
Gokhan Sari,
5
Samouczek, który dla mnie zadziałał : schenkels.nl/2013/03/… @Telford Tendrys, stary, uratowałeś mi życie tym powiadomieniem o wcześniej istniejących grupach. Wielkie dzięki!
Łukasz Bachman
21

Dodałbym jeszcze jedną rzecz do odpowiedzi Marca: atrybut memberOf nie może zawierać symboli wieloznacznych, więc nie można powiedzieć czegoś w rodzaju „memberof = CN = SPS *” i oczekiwać, że znajdzie wszystkie grupy zaczynające się od „SPS”.

Bill Brinkley
źródło
Dziękuję za informację. Próbowałem zrobić to, co mówisz, że nie można zrobić. Jak mogę to zrobić w PHP? Czy można uzyskać ten sam wynik w inny sposób? aby znaleźć wszystkie grupy, zacznij od SPS, a potem cokolwiek ... Zawsze mogę pobrać wszystko i zapętlić moją tablicę, a następnie dopasować preg do CN, którą chcę, ale wolę po prostu poszukać go od razu, jeśli to możliwe.
ODelibalta
15

Musisz ustawić swoją bazę zapytania na nazwę wyróżniającą danego użytkownika, a następnie ustawić filtr na nazwę wyróżniającą grupy, do której się zastanawiasz, czy jest członkiem. Aby sprawdzić, czy jdoe jest członkiem grupy biurowej, zapytanie będzie wyglądać mniej więcej tak:

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)'

Jeśli chcesz zobaczyć WSZYSTKIE grupy, do których należy, po prostu poproś o atrybut „memberof” w wyszukiwaniu, na przykład:

ldapsearch -x -D "ldap_user" -w "user_passwd" -b "cn=jdoe,dc=example,dc=local" -h ldap_host **memberof**
gpayne_007
źródło