Skip Ribbon Commands
Skip to main content

Ondrej Sevecek's Blog

:

Engineering and troubleshooting by Directory Master!
Ondrej Sevecek's Blog > Posts > Archiv: Pokročilé vyhledávání v Active Directory
listopad 17
Archiv: Pokročilé vyhledávání v Active Directory

Disclaimer: Měl jsem moooc článků na svém dřívějším blogu, hostovaném na placeném www.pipni.cz. Akorát mi ho bez varování zrušili. Teďka makám na obnově článků, speciálně na to používám www.archive.org, kde se dají přecejenom alespoň nějaké zbytky ještě najít. Takže tu je jeden obnovený článeček. Upozorňuju, že odkazy nejspíš nebudou fungovat a obrázky tam také nejsou.

6. June 2007, 09:01 by Ondřej Ševeček

Je obvyklé, že potřebujete v Active Directory něco vyhledat. Každý nejspíš zná onen vyhledávací dialog z konzole Active Directory Users and Computers. Nejspíš není také probém vyhledat účet podle jeho jména, nebo loginu. My se ale podíváme na některé pokročilé techniky vyhledávání v Active Directory.

Využijete je jistě v oné konzoli. Mnohdy se vám však budou hodit při skriptování. Například ve skriptu pro PowerShell. A nebo, když třeba vytváříte filtr pro address list do Microsoft Exchange.

Co tedy budeme vyhledávat? Vyhledat jde prakticky cokoliv, až byste se divili:

  • zakázané účty
  • účty, které si nemusí měnit heslo
  • účty, které si již nějakou dobu heslo nezměnily
  • členství uživatele ve skupinách
  • emailové adresy
  • zamčené účty
  • bezpečnostní a distribuční skupiny
  • nově vytvořené účty
  • uživatele a skupiny podle SID
  • uživatele, kteří se již nějakou dobu nepřihlásili
  • a cokoliv dalšího vás napadne

 

Co budeme hledat
Při hledání budeme potřebovat znát jména atributů, které obsahují námi hledané hodnoty. Atribut je vlastně pojmenovaná položka u objektu v Active Directory. Pokud si stáhnete program ADSIEDIT.MSC (je to součást Support Tools od Microsoftu), můžete se na všechny přesně podívat. Některé, pro nás důležité atributy jsou v následující tabulce:

Objekt Atribut Hodnota
Libovolný objekt objectCategory Obsahuje právě jméno typu objektu, kterým daný objek je. Například tedy user, computer, nebo group
whenChanged Datum a čas poslední změny jakéhokoliv parametru příslušného objektu
User givenName Křestní jméno
sn Příjmení (surname)
displayName Zobrazované jméno
email Primární email adresa, kterou najdete hned na první záložce uživatelského účtu
proxyAddresses Všechny emailové adresy, na kterých Exchange přijímá poštu pro daný účet
department Oddělení. Mnohdy se hodí pro hledání v adres listech
sAMAccountName Starý login uživatele
userPrincipalName Nový login uživatele. Ten se objeví třeba v certifikátech
userAccountControl Parametry účtu jako je Uživatel si musí změnit heslo, nebo Účet je zakázán
memberOf Seznam skupin, jichž je uživatel členem. Tedy přímo. Zřetězené členství se zjišťuje jinak
objectSid Uživatelův SID
pwdLastSet Datum a čas poslední změny hesla
lastLogon Datum a čas posledního přihlášení uživatele
Group sAMAccountName Jméno skupiny
groupType Typ skupiny (jako je Domain Local, Global, Universal)
member Seznam členů dané skupiny. Opět pouze přímé členství, zřetězené se zjistí jinak (viz. dále)
memberOf Seznam skupin, jichž je tato skupina členem
Computer dNSHostName DNS jméno počítače
lastLogon Datum a čas posledního spuštění (v doméně) počítače
operatingSystem Jméno operačního systému, například Windows Server 2003
operatingSystemVersion Verze operačního systému, například 5.2 pro Windows Server 2003
operatingSystemServicePack Verze záplaty Service Pack daného systému

Jak to budeme vyhledávat
Nebo lépe se zeptat kde? Tedy pomocí konzole Uživatelé služby Active Directory (anglicky Active Directory Users and Computer). Pomocí okénka Hledat. Musíte si ale zvolit Vlastní vyhledávání (anglicky Custom search). Tak jak je na obrázku:

LDAP vyhledávací řetězce
První věc, kterou si musíme říct je, jak vlastně Active Directory vyhledává. Používá se k tomu vždy takzvaný LDAP vyhledávácí řetězec (anglicky LDAP search string). Ten je konstruován za pomoci logických operací AND (a současně), OR (nebo), NOT (negace). Logickými operacemi se spojují jednotlivé vyhledávací podmínky typu rovnost, nerovnost a podobnost pomocí hvězdičkové konence. Příkladem by mohlo být třeba:

(givenName=o*) AND (sn=s*)
(givenName=o*) OR (givenName=*a)
(NOT givenName=o*)

Tedy snaha o vyhledání všech objektů, jejichž křestní jméno začíná na o a přijmení na s (viz. ona horní tabulka). Nebo ve druhém případě objektů s křestním jménem začínajícím na o nebo končící na k. Třetí případ chce hledat všechny účty, jejichž křestní jméno nezačíná na o. Takto to ale zadat nelze! Musíte to přepsat do formy srozumitelné pro LDAP:

(& (givenName=o*) (sn=s*) )
(| (givenName=o*) (givenName=*a) )
(!givenName=o*)

Myslím, že onen zápis LDAP řetězce by mohl být docela srozumitelný, pokud ho porovnáte s předchozím uvažovaným zadáním, ne? Následující tabulka operátory pěkně shrnuje:

LDAP Operátor Vysvětlení
& (amprsand) Logický operátor součinu, tedy AND
pipe Logický operátor nebo, tedy OR
! (vykřičník) Logická negace, tedy NOT
= (rovnítko) Porovnání na rovnost
>= Větší nebo rovno
<= Menší nebo rovno

Obvykle budeme ještě k vyhledávání přidávat specifikaci typu hledaných položek pomocí atributu objectCategory. Také nebudu vynechávat mezery, protože by to mohlo dělat potíže. Takže předchozí příklady by měly správně vypadat asi takto:

(&(objectCategory=user)(givenName=o*)(sn=s*))
(&(objectCategory=user)(|(givenName=o*)(givenName=*a)))
(&(objectCategory=user)(!givenName=o*))

Takže tohle si již můžete konečně zadat do vašeho vyhledávacího okna a vyzkoušet, jestli vám to něco v adresáři najde.

Hledáme příjemce pošty Microsoft Exchagne
První příklad vyhledá všechny uživatele, kteří mají emailovou adresu začínající písmenem O. Druhý příklad vyhledá úplně všechny objekty, které jsou Exchange příjemci (tedy Exchange recepient jako jsou uživatelé, kontakty a skupiny). Třetí příklad vyhledá jen skupiny s emailem.

(&(objectCategory=user)(proxyAddresses=smtp:o*))
(proxyAddresses=*)
(&(objectCategory=group)(proxyAddresses=*))

Někdy naopak chcete všechny uživatele, kteří email nemají vůbec (všimněte si onoho vykřičníku, tedy negace):

(&(objectCategory=user)(!proxyAddresses=*))

Vyhledání zakázaných účtů
Hledat zakázané účty (ang. disabled accounts) není tak jednoduché. Chce to vědět další detaily. Tak zaprvé, který atribut nese informaci, že účet je zakázaný? Je to userAccountControl. Problém je v tom, že se jedná o bitovou masku s více informacemi dohromady. Tento atribut může mít hodnotu například 66048, 512, nebo 262656. Ani jedna z těhto hodnot neznamená zakázaný účet. Naopak 262658, nebo 514 znamená zakázaný účet.

Jak to tedy je? Přeložte si ona čísla pomocí kalkulačky na jejich binární zápis. Zjistíte, že jednotlivé bity znamenají různé vlastnosti účtu:

Jednotlivé bity v atributu userAccountControl znamenají to, co najdete v následující tabulce (pro ostatní googlujte ADS_USER_FLAG_ENUM):

Nastavení Hodnota desítkově Hodnota binárně
Zakázaný účet 2 00000000 00000000 00000010
Účet zamknut 16 00000000 00000000 00010000
Nesmí si měnit heslo 64 00000000 00000000 01000000
Nemusí si měnit heslo 65536 00000001 00000000 00000000
Vyžaduje se čipová karta 262144 00000100 00000000 00000000
Musí změnit heslo při přihlášení 8388608 10000000 00000000 00000000

Jednoduchým příkladem může být třeba zakázaný účet, který si nemusí měnit heslo, který je současně zamčen kvůli jeho špatnému zadávání. Binární hodnota bude 10000000000010010, což se převede na desítkovou hodnotu 65554.

Nemůžete vyhledávat konkrétní hodnotu, protože v ní mohou být obsaženy různé bity. Musíte vyhledat konkrétní bit. A na to je LDAP speciálně zařízen. Musíte použít speciální číslo (je to OID), určující, že se má hledat jenom jeden bit a nikoliv konkrétní hodnota. Tedy takto vyhledáte zakázané účty:

(&(objectCategory=user)(userAccountControl:1.2.840.113556.1.4.803:=2))

A takto účty, které si nemusí pravidelně měnit heslo:

(&(objectCategory=user)(userAccountControl:1.2.840.113556.1.4.803:=65536))

Uživatelské skupiny
U skupin se jedná o stejný případ. Zde je atribut groupType, který obsahuje bity podle následující tabulky (pro ostatní googlujte ADS_GROUP_TYPE_ENUM):

Nastavení Hodnota desítkově
Bezpečnostní (angl. security group) 2147483648
Doménová lokální (angl. domain local group) 4
Globální (angl. global group) 2
Universální (angl. universal group) 8

Chceteli potom vyhledat nějaké zkupiny, zadejte následující. První příklad hledá bezpečnostní skupiny, druhý distribuční skupiny (všiměte si vykřičníku). Třetí hledá universální skupiny. Ve čtvrtém případě hledáme všechny bezpečnostní globální skupiny (hodnoty musíte sečíst).

(&(objectCategory=group)
(groupType:1.2.840.113556.1.4.803:=2147483648))
(&(objectCategory=group)
(!groupType:1.2.840.113556.1.4.803:=2147483648))
(&(objectCategory=group)
(groupType:1.2.840.113556.1.4.803:=2147483648))
(&(objectCategory=group)
(groupType:1.2.840.113556.1.4.803:=2147483650))

Od Windows Server 2003 SP2 máte skvělou možnost vyhledat všechny skupiny, ve kterých je nějaký uživatel členem! A tím se myslí i nepřímo, pokud jsou skupiny vnořené. Použije se jiný OID a distinguishedName uživatele:

(&(objectCategory=group)
(member:1.2.840.113556.1.4.1941:=CN=ondra,OU=Uzivatele,DC=podnik,DC=cz))

Hledání podle času
Časové údaje jsou kódovány několika způsoby. Vždy je potřeba vědět jak. Ukážeme si tři nejběžnější příklady. První z nich vyhledá všechny uživatele, kteří byli vytvořeni před nějakým datem v minulosti (konkrétně před 5:45 hod. dne 17.6.2005 UTC):

(&(objectCategory=user)(whenCreated<=20050617054500.0Z)

Myslím, že formát data by měl být jasný. Takže jen pro jistotu. Formát je následující. Dokonce můžete specifikovat i posun vůči UTC, neboli greenwichskému času (v našich končinách +1 hod.):

RRRRMMDDhhmmss.0Z
RRRRMMDDhhmmss.0+0100

Některé časy jsou ale v jiném formátu. Je to konkrétně počet 100ns (sto nanosekundových) intervalů od 1.1.1601. To je hodně komplikovaný výpočet. Pro převod takových údajů jsem si udělal skriptík v PowerShellu.

Chcete třeba najít uživatele, kteří si už nějakou dobu nezměnili heslo? Řekněme od 1.5.2007? Pomocí onoho skriptu si převedete to datum na hodnotu:

Get-100NS-Since-1601( ( new-object DateTime(2007,5,1) ) )
>> 128224512000000000

A vyhledáte všechny objekty, kde je hodnota pwdLastSet menší než zjistěné megačíslo. Tedy všechny objekty, u kterých se heslo naposledy změnilo před oním datem:

(&(objectCategory=user)(pwdLastSet<=128224512000000000))

Stejně tak funguje atribut lastLogon. Jeho jméno už samo napovídá, že nás zajímají čas vůbec posledního přihlášení. Použijeme datum z předchozího příkladu. A vyhledáme uživatele, kteří se už od 1.5.2007 nepřihlásili. Na co tam takové účty vůbec jsou?

(&(objectCategory=user)(lastLogon<=128224512000000000))

Hledání podle SID
Chcete hledat uživatele podle jejich SID? No, né uplně často, ale někdy přece. Takže zkusme. Najdeme si uživatele, jehož SID je následující. Druhá hodnota je jeho šetnáctkový zápis (hexadecimální). Můžete zase použít kalkulačku:

S-1-5-21-911941294-13226589-850011906-1697
S-01-05-15-365B1EAE-C9D25D-32AA2702-000006A1

Potom vyhledáte uživatelský účet s tímto SIDem následovně. Je to trošku komplikovanější pochopit. Prostě to z části zapíšete odzadu:

(objectSID=\01\05\00\00\00\00\00\05\15\00\00\00\
AE\1E\5B\36\5D\D2\C9\00\02\27\AA\32\A1\06\00\00)

A to je vše. Dobře se bavte!

Comments

Vyžaduje se čipová karta - opak

Dobrý den,
prosím nemáte LDAP dotaz do AD - uživatelé mají odškrtnuto "Interaktivní přihlašování čipovou kartou"

- Vyžaduje se čipová karta 262144
Opak
- Karta není vyžadována do přihlášení do operačního systému

Děkuji
David on 23.2.2013 11:14

Re: Archiv: Pokročilé vyhledávání v Active Directory

použijte vykřičník, jako negaci:

(!userAccountControl:1.2.840.113556.1.4.803:=262144)

ondass on 23.2.2013 11:18

Re: Archiv: Pokročilé vyhledávání v Active Directory

Moc děkuji, tahle možnost mne vůbec nenapadla. Děkuji Vám a přeji krásný den.
David on 23.2.2013 11:54

Add Comment

Title


Pole Title nemusíte vyplňovat, doplní se to samo na stejnou hodnotu jako je nadpis článku.

Author *


Pole Author nesmí být stejné jako pole Title! Mám to tu jako ochranu proti spamu. Roboti to nevyplní dobře :-)

Body *


Type number two as digit *


Semhle vyplňte číslici dvě. Předchozí antispemové pole nefunguje úplně dokonale, zdá se, že jsou i spamery, které pochopily, že je občas potřeba vyplnit autora :-)

Email


Emailová adresa, pokud na ni chcete ode mě dostat odpověď. Nikdo jiný než já vaši emailovou adresu neuvidí.

Attachments