3.5.4.7.5 DsrGetForestTrustInformation (Opnum 43)

The DsrGetForestTrustInformation method SHOULD<231> retrieve the trust information for the forest of the specified domain controller (DC), or for a forest trusted by the forest of the specified DC.

 NET_API_STATUS DsrGetForestTrustInformation(
   [in, unique, string] LOGONSRV_HANDLE ServerName,
   [in, unique, string] wchar_t* TrustedDomainName,
   [in] DWORD Flags,
   [out] PLSA_FOREST_TRUST_INFORMATION* ForestTrustInfo
 );

ServerName: The custom binding handle, as defined in section 3.5.4.1.

TrustedDomainName: The optional null-terminated Unicode string that contains the DNS or NetBIOS name of the trusted domain for which the forest trust information is to be gathered.

Flags: A set of bit flags that specify additional applications for the forest trust information. A flag is TRUE (or set) if its value is equal to 1.


0


1


2


3


4


5


6


7


8


9

1
0


1


2


3


4


5


6


7


8


9

2
0


1


2


3


4


5


6


7


8


9

3
0


1

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

A

Where the bits are defined as:

Value

Description

A

Update a trusted domain object (TDO) with the information returned in ForestTrustInfo.

All other bits MUST be set to zero.

ForestTrustInfo: A pointer to an LSA_FOREST_TRUST_INFORMATION structure, as specified in [MS-LSAD] section 2.2.7.25, that contains data for each forest trust.

Return Values: The method returns 0x00000000 on success; otherwise, it SHOULD return the following error code.

Return Value/Code

Description

0x00000001

ERROR_INVALID_FUNCTION

Incorrect function.

On receiving this call, the server MUST perform the following validation steps:

  • Apply Common Error Processing Rule A, specified in section 3.

  • Apply Common Error Processing Rule B, specified in section 3.

  • Verify that the client has sufficient privileges. The server determines if the client has sufficient privileges (as specified in section 3.5.4.1) with the Access Request mask set to match the NETLOGON_FTINFO_ACCESS mask; otherwise, the server MUST return ERROR_ACCESS_DENIED.

  • Verify that if the Flags parameter has bit A enabled, the server is a PDC; otherwise, the server MUST return NERR_NotPrimary ([MS-ERREF] section 2.2).

  • The Flags parameter MUST be checked for invalid bit flags. The server MUST return ERROR_INVALID_FLAGS if any bit other than A is set.

If the TrustedDomainName parameter is specified, the server calls the DsrGetForestTrustInformation method on a DC in the trusted domain specified by the TrustedDomainName parameter.

Additionally, if the TrustedDomainName is not NULL, the server MUST perform the additional following validation steps:

  • Verify that the server has established a secure channel with the domain specified in the TrustedDomainName parameter, and apply Common Error Processing Rule E, specified in section 3. If the server has not established a secure channel with the domain specified in the TrustedDomainName parameter, then the server MUST return the error code ERROR_NO_SUCH_DOMAIN.

  • Apply Common Error Processing Rule C, specified in section 3.

  • The forest trust information for the domain specified by the TrustedDomainName parameter MUST be returned.

  • The server MUST verify that the TrustedDomainName refers to a cross-forest trust by performing external behavior consistent with locally invoking LsarQueryTrustedDomainInfoByName ([MS-LSAD] section 3.1.4.7.5), using the following parameters (a policy handle is not needed locally):

    • Domain is set to the value of the TrustedDomainName parameter.

    • InformationClass is set to the value of TrustedDomainInformationEx.

      If the call returns STATUS_OBJECT_NAME_NOT_FOUND the server MUST return ERROR_NO_SUCH_DOMAIN. Additionally, the server MUST verify that:

    • The securityIdentifier (Sid) field ([MS-ADTS] section 6.1.6.7.8) is not NULL.

    • The trustType field ([MS-ADTS] section 6.1.6.7.15) is 1 or 2.

    • The trustAttributes field ([MS-ADTS] section 6.1.6.7.9) does not contain TRUST_ATTRIBUTE_UPLEVEL_ONLY.

    • The trustAttributes field ([MS-ADTS] section 6.1.6.7.9) contains TRUST_ATTRIBUTE_FOREST_TRANSITIVE.

      If the server fails to verify any of the preceding conditions, the server MUST return ERROR_NO_SUCH_DOMAIN.

      Otherwise, if the TrustedDomainName is NULL, the server MUST check to see if Flags bit A is set. If Flags bit A is set, the server MUST return ERROR_INVALID_FLAGS, and no further processing occurs.

The server MUST retrieve the forest trust information for the domain specified by the TrustedDomainName parameter:

  • If the TrustedDomainName is NULL the server performs external behavior equivalent to locally invoking NetrGetForestTrustInformation with the parameters specified in the previous paragraph, return the forest trust information, and stop further processing.

  • Otherwise, the server calls NetrGetForestTrustInformation with the following parameters (in addition to those specified in section 3.4.5.5.4) to a PDC, in the domain specified by the TrustedDomainName Parameter, in order to retrieve the Trusted Forest's version of the LSA_FOREST_TRUST_INFORMATION, referred to in the rest of this section as NewTrustInfo:

    • ServerName is set to NULL, indicating the current server's domain.

    • ComputerName is set to the NetBIOS computer name of the server.

    • Flags is set to 0.

Otherwise, if the TrustedDomainName is not NULL and Flags bit A is set, the server updates the server's forest information for the domain specified by the TrustedDomainName parameter as follows:

  • The server MUST retrieve its version of the forest trust information, referred to in the rest of this section as OldTrustInfo, by performing external behavior equivalent to locally invoking LsarQueryForestTrustInformation with the following parameters (a policy handle is not required locally):

    • TrustedDomainName is set to the TrustedDomainName parameter that was passed by the caller of DsrGetForestTrustInformation.

    • HighestRecordType is set to ForestTrustRecordTypeLast ([MS-LSAD] section 2.2.7.22).

  • If the call returns STATUS_NOT_FOUND, the server ignores this error and continue processing. If any other error is returned, the server passes the error through and stops processing.

  • The server merges the OldTrustInfo LSA_FOREST_TRUST_INFORMATION with the Trusted Forest's version of the NewTrustInfo LSA_FOREST_TRUST_INFORMATION. The server creates an LSA_FOREST_TRUST_INFORMATION structure. After the merge, the new version of the LSA_FOREST_TRUST_INFORMATION will result in the merged result, referred to in this section as MergedTrustInfo. The server performs the merge using the following rules:

    • The server iterates through the LSA_FOREST_TRUST_RECORD ([MS-LSAD] section 2.2.7.21) entries in the NewTrustInfo version of the LSA_FOREST_TRUST_INFORMATION according to the following rules. The index for the current entry in NewTrustInfo.Entries is denoted as "i":

      • If the NewTrustInfo.Entries[i].ForestTrustType is not ForestTrustTopLevelName, then ignore further rules for NewTrustInfo.Entries[i], and continue iterating through NewTrustInfo.Entries.

      • If the NewTrustInfo.Entries[i].ForestTrustData.TopLevelName is equal to the DNS domain name of the TDO, copy NewTrustInfo.Entries[i] into MergedTrustInfo.Entries, ignore further rules for NewTrustInfo.Entries[i] and continue iterating through NewTrustInfo.Entries.

      • Iterate through the LSA_FOREST_TRUST_RECORD entries in the MergedTrustInfo version of the LSA_FOREST_TRUST_INFORMATION according to the following rules. The index for the current entry in MergedTrustInfo.Entries is denoted as "m":

        • If the NewTrustInfo.Entries[i].ForestTrustData.TopLevelName is subordinate to the MergedTrustInfo.Entries[m].ForestTrustData.TopLevelName, stop iterating through MergedTrustInfo.Entries, ignore further rules for NewTrustInfo.Entries[i], and continue iterating through NewTrustInfo.Entries.

      • Copy the NewTrustInfo.Entries[i] to MergedTrustInfo.Entries. The new entry in MergedTrustInfo.Entries is referred to as MergedEntry.

        • Iterate through the LSA_FOREST_TRUST_RECORD entries in the OldTrustInfo version of the LSA_FOREST_TRUST_INFORMATION according to the following rules. The index for the current entry in OldTrustInfo.Entries is denoted as "k":

          • If the OldTrustInfo.Entries[k].ForestTrustType is equal to ForestTrustTopLevelName, and the NewTrustInfo.Entries[i].ForestTrustData.TopLevelName is equal to OldTrustInfo.Entries[k].ForestTrustData.TopLevelName, copy OldTrustInfo.Entries[k].Flags to MergedEntry.Flags and copy OldTrustInfo.Entries[k].Time to MergedEntry.Time.

          • Otherwise, MergedEntry.Flags is set to LSA_TLN_DISABLED_NEW (0x00000001) ([MS-LSAD] section 2.2.1.5) and MergedEntry.Time is set to 0.

    • The server iterates through the LSA_FOREST_TRUST_RECORD ([MS-LSAD] section 2.2.7.21) entries in the NewTrustInfo version of the LSA_FOREST_TRUST_INFORMATION ([MS-LSAD] section 2.2.7.25) according to the following rules. The index for the current entry in NewTrustInfo.Entries is denoted as "i":

      • If the NewTrustInfo.Entries[i].ForestTrustType is a ForestTrustDomainInfo, create a new LSA_FOREST_TRUST_RECORD, referred to in this section as TempEntry, and copy NewTrustInfo.Entries[i] into TempEntry. TempEntry.Flags is set to 0 and TempEntry.Time is set to 0.

      • Iterate through the LSA_FOREST_TRUST_RECORD entries in the MergedTrustInfo version of the LSA_FOREST_TRUST_INFORMATION according to the following rules. The index for the current entry in MergedTrustInfo.Entries is denoted as "m":

        • If MergedTrustInfo.Entries[m].ForestTrustType is a ForestTrustDomainInfo and TempEntry.ForestTrustData.DomainInfo.Sid is equal to MergedTrustInfo.Entries[m].ForestTrustData.DomainInfo.Sid, delete TempEntry, stop iterating through MergedTrustInfo.Entries, ignore further rules for NewTrustInfo.Entries[i], and continue iterating through NewTrustInfo.Entries.

        • Iterate through the LSA_FOREST_TRUST_RECORD Entries in the OldTrustInfo version of the LSA_FOREST_TRUST_INFORMATION according to the following rules. The index for the current entry in OldTrustInfo.Entries is denoted as "n":

          • If OldTrustInfo.Entries[n].ForestTrustType is a ForestTrustDomainInfo and TempEntry.ForestTrustData.DomainInfo.NetbiosName is equal to OldTrustInfo.Entries[n].ForestTrustData.DomainInfo.NetbiosName, copy OldTrustInfo.Entries[n].Flags into TempEntry.Flags and also copy OldTrustInfo.Entries[n].Time into TempEntry.Time.

      • Copy TempEntry into MergedTrustedInfo.Entries.

    • The server iterates through the LSA_FOREST_TRUST_RECORD ([MS-LSAD] section 2.2.7.21) entries in the OldTrustInfo version of the LSA_FOREST_TRUST_INFORMATION according to the following rules. The index for the current entry in OldTrustInfo.Entries is denoted as "i":

      • If OldTrustInfo.Entries[i].ForestTrustType is not ForestTrustDomainInfo, then ignore further rules for OldTrustInfo.Entries[i] and continue iterating through OldTrustInfo.Entries.

      • Iterate through the LSA_FOREST_TRUST_RECORD entries in the MergedTrustInfo version of the LSA_FOREST_TRUST_INFORMATION according to the following rules. The index for the current entry in MergedTrustInfo.Entries is denoted as "m":

        • If MergedTrustInfo.Entries[m].ForestTrustType is a ForestTrustDomainInfo and OldTrustInfo.Entries[m].ForestTrustData.DomainInfo.NetbiosName equals MergedTrustInfo.Entries[m].ForestTrustData.DomainInfo.NetbiosName, stop iterating through the MergedTrustInfo.Entries, ignore further rules for OldTrustInfo.Entries[i] and continue iterating through OldTrustInfo.Entries.

      • If OldTrustInfo.Entries[i].Flags has either the LSA_SID_DISABLED_ADMIN (0x00000001) flag set or the LSA_NB_DISABLED_ADMIN (0x00000004) flag set ([MS-LSAD] section 2.2.1.5), copy OldTrustInfo.Entries[i] into MergedTrustInfo.Entries.

    • The server iterates through the LSA_FOREST_TRUST_RECORD ([MS-LSAD] section 2.2.7.21) entries in the OldTrustInfo version of the LSA_FOREST_TRUST_INFORMATION according to the following rules. The index for the current entry in OldTrustInfo.Entries is denoted as "i":

      • If OldTrustInfo.Entries[i].ForestTrustType is not equal to ForestTrustTopLevelNameEx, then ignore further rules for OldTrustInfo.Entries[i] and continue iterating through OldTrustInfo.Entries.

      • Iterate through the LSA_FOREST_TRUST_RECORD entries in the MergedTrustInfo version of the LSA_FOREST_TRUST_INFORMATION according to the following rules. The index for the current entry in MergedTrustInfo.Entries is denoted as "m":

        • If MergedTrustInfo.Entries[m].ForestTrustType is a ForestTrustTopLevelName and OldTrustInfo.Entries[i].ForestTrustData.TopLevelName is equal to or subordinate to MergedTrustInfo.Entries[m].ForestTrustData.TopLevelName, copy OldTrustInfo.Entries[i] into MergedTrustInfo.Entries. Stop iterating through MergedTrustInfo.Entries but continue iterating through OldTrustInfo.Entries.

The server MUST update its version of the forest trust information for the domain specified by the TrustedDomainName parameter by performing external behavior equivalent to locally invoking LsarSetForestTrustInformation, with the following parameters (a policy handle is not needed locally):

  • TrustedDomainName is set to the TrustedDomainName parameter that was passed by the caller of DsrGetForestTrustInformation.

  • HighestRecordType is set to ForestTrustRecordTypeLast.

  • ForestTrustInfo is set to the merged forest trust information, MergedTrustInfo.

If the TrustedDomainName is NULL:

  • The forest trust information for the domain hosted by ServerName MUST be returned if Flags bit A is not set.

  • The server MUST return ERROR_INVALID_FLAGS if Flags bit A is set.