Nedávno jsem tu vydával ukázkový soubor na rozšíření schematu. A rovnou se mi to hodí, protože v pátek mi známý ukazoval další problém, tentokrát s atributy typu link a backlink. Tak se rovnou podívejme, co to je, a jak se založí tyto atributy do schematu.
Co jsou atributy typu link a backlink?
Objekty mohou odkazovat na jiné objekty. Tak jako třeba skupiny odkazují na svoje členy (pomocí member atributu). Nebo jak objekty serverů (sever class) v Sites and Services odkazují (atribut serverReference) na objekty účtů DC v domain partition. A speciálně u Exchange je takových příkladů milión. Takový atribut se nazývá link.
Když někdo na něco odkazuje, tak proč nezobrazovat na i opačný odkaz. Na odkazovaných objektech je možné vidět obvykle zpětný odkaz - backlink. Třeba na členech skupin jsou atributy memberOf. Nebo právě počítačové účty DC mají zpětnou referenci v podobě atributu serverReferenceBL.
Pokud chcete modifikovat nějaký odkaz, lze to udělat jen na atributu link. Atribut typu backlink je jenom pro čtení. Backlink existuje jenom proto, aby byla navigace jednodušší a nebylo potřeba prohledávat všechno "dopředné" odkazy.
Dokud nemáte ještě forest functional level (FFL) na úrovni Windows 2003 nebo novější, tak dokonce backlink vůbec neuchovává data v databázi. Hodnota odkazu je uložena jen v atributu typu link, tam to žere místo. Zatímco hodnota backlink se prostě jen dynamicky generuje v okamžiku, kdy ji nějaký LDAP klient potřebuje.
Pokud máte FFL na úrovni alespoň Windows 2003, link a backlink jsou ve skutečnosti uloženy současně v jedné tabulce (linktable) a není v nich tedy ve skutečnosti rozdíl z pohledu ukládání dat. Ale LDAP rozhraní pořád bere link jako zapisovatelný, zatímco backlink je jen pro čtení.
Co je linkID?
Když budeme zakládat nový link a k němu backlink, budeme to dělat zase pomocí LDF souboru. To znamená, dvě samostatné operace, založení dvou různých atributů. Aby systém věděl, co je link a co je k němu backlink, musí to nějak poznat. Obě definice atributů musí mít tedy atribut linkId. Je to číslo. Na atributech typu link musí být sudá hodnota, zatímco na backlink musí být o jedničku vyšší lichá hodnota.
Navíc máme ale problém v tom, že tyto hodnoty musí být v celém schema unikátní. To je celkem logické, aby se dva atributy typu backlink náhodou neokazovaly na společný link.
A sakra. Další unikátnost, která nám bude při rozšiřování schematu dělat potíže. Jak vygenerovat unikátní linkID? Pokud je váš schema master FSMO stále ještě na verzi operačního systému Windows 2000, nemáte jinou možnost, než si unikátní linkID vyžádat přímo od Microsoftu. Jinak se vystavujete budoucím problémům s kolizí linkID.
To jsou hlášky LDIFDE ve stylu:
There was an error while running 'ldifde.exe' to import the schema file
The server side error is: 0x2114 Schema update failed: An attribute with the same link identifier already exists.
00002114: SvcErr: DSID-032603BC, problem 5003 (WILL_NOT_PERFORM), data 8468
An error has occurred in the program
V našem případě se jednalo konkrétně o rozšiřování schema pro Exchange. Kolize byla na těchto dvou Exchange atributech:
Organization Preparation Failed
Error: The following error was generated when
"$error.Clear();
install-ExchangeSchema -LdapFileName ($roleInstallPath + "Setup\Data\"+$RoleSchemaPrefix + "schema5.ldf") "
install-ExchangeSchema -LdapFileName ($roleInstallPath + "Setup\Data\"+$RoleSchemaPrefix + "schema2.ldf") "
was run:
"There was an error while running 'ldifde.exe' to import the schema file 'C:\Windows\Temp\ExchangeSetup\Setup\Data\PostExchange2000_schema5.ldf'. The error code is: 8245. More details can be found in the error file: 'C:\Users\domain-admin\AppData\Local\Temp\2\ldif.err'".
"There was an error while running 'ldifde.exe' to import the schema file 'C:\Windows\Temp\ExchangeSetup\Setup\Data\PostExchange2003_schema2.ldf'. The error code is: 8245. More details can be found in the error file: 'C:\Users\domain-admin\AppData\Local\Temp\2\ldif.err'".
"Add error on entry: Unwilling To Perform"
CN=ms-Exch-ELC-Folder-Link, linkID: 2054
CN=ms-Exch-ELC-Folder-BL, linkID: 2055
CN=ms-Exch-Mailbox-Template-Link, linkID: 2056
CN=ms-Exch-Mailbox-Template-BL, linkID: 2057
Pokud máte schema master FSMO s operačním systémem alespoň Windows 2003, tak to už není takový problém. Stačí použít místo konkrétní hodnoty linkId náhradní OID, který linkId vygeneruje automaticky. OID je popsán v článku Obtaining a Link ID a má hodnotu 1.2.840.113556.1.2.50 (viz. také definice http://msdn.microsoft.com/en-us/library/cc223203.aspx)
V pátek jsme se to snažili pokořit, právě kvůli problému s kolizí. Jednalo se o rozšíření schematu na Exchange 2007. A on nějaký lumpík už dříve přidal svůj vlastní link a backlink s kolizními hodnotami linkId, takže nešlo schema rozšířit.
Takže jsme zkusili použít tento OID, ale pořád to hlásilo, nějaké chyby. Tak jsem si dneska znovu přečetl poctivě dokumentaci, proč by to člověk dělal hned na poprvé, že? A ono to tam je ve skutečnosti napsáno :-) "The schema cache must be reloaded after creating the forward link and before creating the back link". Takže tak.
Příklad rozšíření schematu o link a k němu odpovídající backlink, bez použití konkrétních linkId
Takže příklad následuje. Podstatné je mezi jednotlivými atributy vložit aktualizaci schema cache. Bez toho se neví v okamžiku importu backlinku, že ten link už vlastně existuje. To podstatné je zápis atributu schemaUpdateNow = 1 před přidáním atributu typu backlink.
dn: CN=sevecekLink,
changetype: ntdsSchemaAdd
adminDescription: sevecekLink
adminDisplayName: sevecekLink
attributeID: 1.3.6.1.4.1.25005.102.1.33.3.1
attributeSyntax: 2.5.5.1
isMemberOfPartialAttributeSet: FALSE
isSingleValued: FALSE
lDAPDisplayName: sevecekLink
name: sevecekLink
oMSyntax: 127
oMObjectClass:: KwwCh3McAIVK
objectCategory: CN=Attribute-Schema,
objectClass: attributeSchema
linkID: 1.2.840.113556.1.2.50
searchFlags: 0
dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-
dn: CN=sevecekBL,
changetype: ntdsSchemaAdd
adminDescription: sevecekBL
adminDisplayName: sevecekBL
attributeID: 1.3.6.1.4.1.25005.102.1.33.3.2
attributeSyntax: 2.5.5.1
isMemberOfPartialAttributeSet: FALSE
isSingleValued: FALSE
lDAPDisplayName: sevecekBL
name: sevecekBL
oMSyntax: 127
oMObjectClass:: KwwCh3McAIVK
objectCategory: CN=Attribute-Schema,
objectClass: attributeSchema
linkID: sevecekLink
searchFlags: 0
A co vlastně způsobovalo tu kolizi?
Jednalo se o dřívější rozšíření schema firmou Aladdin - tedy výrobcem přihlašovacích tokenů eToken. Oni si sami už někdy dříve přidali svoje vlastní atributy typu link a backlink. Přidávali to v roce 2007, takže by se ten problém ani nevyskytl, kdyby tam už tehdy bylo schéma Exchange 2007. Tedy vyskytl by se naopak :-)
CN=aks-tms-tokens
lDAPDisplayName: AksTmsTokens
linkID: 2054
CN=aks-tms-users
lDAPDisplayName: AksTmsUsers
linkID: 2055
CN=aks-tms-creator
lDAPDisplayName: AksTmsCreator
linkID: 2056
CN=aks-tms-paramsets
linkID: 2057
lDAPDisplayName: AksTmsParamSets
Takže ani Israelci nejsou zase až tak linkId savvy :-) Ale to nevadí. Hlavní je, že Iránci dostávají svoji vlastní, kustomizovanou verzi těch tokenů :-)