Přidání důvěrného atributu do Active Directory
Přidání důvěrného atributu do Active Directory
Tento postup vytvoří vlastní jednohodnotový textový atribut, připojí jej ke třídě user a deleguje čtení jen určené skupině. Změna schématu je lesní a prakticky nevratná, proto ji nejprve ověříme v testovacím forestu.
⚠️ Příznak CONFIDENTIAL hodnotu nešifruje. Mění kontrolu oprávnění při čtení: vedle READ_PROPERTY je potřeba také objektově specifické CONTROL_ACCESS. Správci s širokými právy mohou hodnotu nadále přečíst.
1. Příprava
Před změnou:
- Ověříme replikaci pomocí
repadmin /replsummaryadcdiag /e /q. - Vytvoříme aktuální System State backup alespoň jednoho zapisovatelného řadiče domény.
- Přihlásíme se na Schema Master účtem dočasně přidaným do Schema Admins.
- Po přidání do Schema Admins se odhlásíme a znovu přihlásíme, aby bylo členství v přístupovém tokenu.
📌 System State záloha je součást havarijní připravenosti, ne podporované „undo“ jedné změny schématu. Přidaný objekt schématu běžně neodstraňujeme; chybný atribut lze nanejvýš deaktivovat a nahradit správně navrženým.
Schema Master zjistíme takto:
Import-Module ActiveDirectory
$SchemaMaster = (Get-ADForest).SchemaMaster
$SchemaDn = (Get-ADRootDSE -Server $SchemaMaster).schemaNamingContext
$SchemaMaster
$SchemaDn
Hodnotu registru Schema Update Allowed běžně nevytváříme. Na podporovaných verzích AD DS není pro standardní změnu schématu pomocí ldifde nutná.
2. Vygenerování jedinečného OID
⚠️ Každý attributeID musí být celosvětově jedinečný. OID z ukázkového článku nebo cizí organizace nikdy nekopírujeme.
Použijeme vlastní registrovanou OID větev nebo Microsoftem publikovaný skript z dokumentace Obtaining an Object Identifier from Microsoft. Výsledek si uložíme do evidence schématu spolu s vlastníkem a účelem atributu.
V dalším příkladu nahradíme:
<UNIQUE_OID>skutečně jedinečným OID,<SCHEMA_DN>hodnotou proměnné$SchemaDn, napříkladCN=Schema,CN=Configuration,DC=firma,DC=cz.
3. Vytvoření atributu pomocí LDIF
Vytvoříme soubor confidentialAttribute.ldf:
dn: CN=confidentialAttribute,<SCHEMA_DN>
changetype: add
objectClass: attributeSchema
lDAPDisplayName: confidentialAttribute
adminDisplayName: Confidential Attribute
adminDescription: Důvěrný údaj s řízeným přístupem
attributeID: <UNIQUE_OID>
attributeSyntax: 2.5.5.12
oMSyntax: 64
isSingleValued: TRUE
showInAdvancedViewOnly: TRUE
searchFlags: 128
dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-
dn: CN=User,<SCHEMA_DN>
changetype: modify
add: mayContain
mayContain: confidentialAttribute
-
dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-
Soubor importujeme z příkazového řádku spuštěného jako správce:
ldifde -i -f .\confidentialAttribute.ldf -s $SchemaMaster -j .
⚠️ Nepoužíváme přepínač -k, protože by mohl skrýt chybu a ponechat import jen částečně provedený. Výsledek ověříme:
$Attribute = Get-ADObject `
-Server $SchemaMaster `
-Identity "CN=confidentialAttribute,$SchemaDn" `
-Properties lDAPDisplayName, attributeID, attributeSyntax, oMSyntax, searchFlags
$UserClass = Get-ADObject `
-Server $SchemaMaster `
-Identity "CN=User,$SchemaDn" `
-Properties mayContain
$Attribute | Format-List lDAPDisplayName, attributeID, attributeSyntax, oMSyntax, searchFlags
$UserClass.mayContain -contains 'confidentialAttribute'
repadmin /replsummary
✅ searchFlags musí být 128 a poslední příkaz pro mayContain musí vrátit True. Pokud jako důvěrný označujeme již existující atribut, bit 128 přičteme k jeho současné hodnotě searchFlags; ostatní příznaky nesmíme přepsat.
4. Delegování přístupu
Pro čtení důvěrného atributu nestačí běžné Read Property. ACE musí pro konkrétní GUID atributu obsahovat ReadProperty i ExtendedRight (CONTROL_ACCESS). Příkaz dsacls neumí spolehlivě vytvořit tuto objektově specifickou kombinaci, proto použijeme rozhraní .NET.
Následující skript přidá skupině DOMENA\HR-Confidential-Readers právo číst atribut u uživatelů pod zadanou OU:
Import-Module ActiveDirectory
$TargetOuDn = 'OU=Zamestnanci,DC=firma,DC=cz'
$ReaderGroup = 'DOMENA\HR-Confidential-Readers'
$SchemaDn = (Get-ADRootDSE).schemaNamingContext
$AttributeBytes = (Get-ADObject `
-SearchBase $SchemaDn `
-LDAPFilter '(lDAPDisplayName=confidentialAttribute)' `
-Properties schemaIDGUID).schemaIDGUID
$UserClassBytes = (Get-ADObject `
-SearchBase $SchemaDn `
-LDAPFilter '(&(objectClass=classSchema)(lDAPDisplayName=user))' `
-Properties schemaIDGUID).schemaIDGUID
$AttributeGuid = [Guid]::new($AttributeBytes)
$UserClassGuid = [Guid]::new($UserClassBytes)
$Identity = [System.Security.Principal.NTAccount]::new($ReaderGroup)
$Rights = [System.DirectoryServices.ActiveDirectoryRights]::ReadProperty -bor `
[System.DirectoryServices.ActiveDirectoryRights]::ExtendedRight
$Rule = [System.DirectoryServices.ActiveDirectoryAccessRule]::new(
$Identity,
$Rights,
[System.Security.AccessControl.AccessControlType]::Allow,
$AttributeGuid,
[System.DirectoryServices.ActiveDirectorySecurityInheritance]::Descendents,
$UserClassGuid
)
$Ou = [ADSI]("LDAP://" + $TargetOuDn)
$Acl = $Ou.psbase.ObjectSecurity
$Acl.AddAccessRule($Rule)
$Ou.psbase.ObjectSecurity = $Acl
$Ou.psbase.CommitChanges()
Pro skupinu, která má atribut měnit, vytvoříme samostatnou ACE s právem WriteProperty a stejným $AttributeGuid.
❌ Skupinám nedáváme Full Control ani obecné All Extended Rights, protože by zpřístupnily i jiné citlivé operace.
📌 Delegace se dědí jen na objekty s povolenou dědičností. Na chráněné administrátorské účty spravované pomocí AdminSDHolder se oprávnění z OU zpravidla nepřenese.
5. Zápis a test oprávnění
Vlastní atribut lze zapisovat standardním modulem ActiveDirectory:
Set-ADUser -Identity testuser -Replace @{
confidentialAttribute = 'Testovací hodnota'
}
# Odstranění hodnoty
Set-ADUser -Identity testuser -Clear confidentialAttribute
Pro test hodnotu znovu nastavíme a čtení ověříme pod třemi účty: člen čtecí skupiny, běžný uživatel mimo skupinu a účet s právem zápisu.
$Credential = Get-Credential
Get-ADUser `
-Identity testuser `
-Properties confidentialAttribute `
-Credential $Credential `
-Server dc1.firma.cz |
Select-Object SamAccountName, confidentialAttribute
Člen HR-Confidential-Readers hodnotu uvidí. Běžnému uživateli se atribut nevrátí. Samostatně ověříme, že zapisovací skupina může hodnotu změnit a nemá širší práva, než bylo zamýšleno.
Po dokončení odebereme administrační účet ze Schema Admins, odhlásíme jej a uložíme LDIF, OID, výstup importu a schválení změny do dokumentace.
Shrnutí
✅ Atribut nejprve navrhneme a otestujeme v odděleném forestu.
✅ Pro attributeID použijeme vlastní jedinečný OID.
✅ Důvěrnost nastavuje bit 128 v searchFlags; nejde o šifrování hodnoty.
✅ Čtení delegujeme kombinací ReadProperty a objektově specifického ExtendedRight.
❌ Změnu schématu nepovažujeme za snadno vratnou a importní chyby neskrýváme přepínačem -k.