You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
8.0 KiB
265 lines
8.0 KiB
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 2001, Microsoft Corporation
|
|
//
|
|
// File: DfsDomainInformation.cxx
|
|
//
|
|
// Contents: the Dfs domain info class
|
|
//
|
|
// Classes: DfsDomainInformation
|
|
//
|
|
// History: apr. 8 2001, Author: udayh
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "DfsGeneric.hxx"
|
|
#include "Align.h"
|
|
#include "dsgetdc.h"
|
|
#include "DfsTrustedDomain.hxx"
|
|
#include "DfsReferralData.h"
|
|
|
|
#include "dfsdomainInformation.hxx"
|
|
|
|
#include "dfsxforest.hxx"
|
|
|
|
#include "dfsdomainInformation.tmh"
|
|
|
|
DfsDomainInformation::DfsDomainInformation(
|
|
DFSSTATUS *pStatus,
|
|
DFSSTATUS *pXforestStatus)
|
|
: DfsGeneric( DFS_OBJECT_TYPE_DOMAIN_INFO)
|
|
{
|
|
|
|
ULONG DsDomainCount = 0;
|
|
PDS_DOMAIN_TRUSTS pDsDomainTrusts = NULL;
|
|
DFSSTATUS Status = ERROR_SUCCESS;
|
|
DFSSTATUS XforestInitStatus = ERROR_SUCCESS;
|
|
LPWSTR ServerName = NULL;
|
|
ULONG Index = 0;
|
|
|
|
DfsXForest XForestInfo;
|
|
|
|
_pTrustedDomains = NULL;
|
|
_DomainCount = 0;
|
|
_fCritInit = FALSE;
|
|
_DomainReferralLength = 0;
|
|
|
|
_pLock = new CRITICAL_SECTION;
|
|
if ( _pLock == NULL )
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
_fCritInit = InitializeCriticalSectionAndSpinCount( _pLock, DFS_CRIT_SPIN_COUNT );
|
|
if(!_fCritInit)
|
|
{
|
|
Status = GetLastError();
|
|
DFS_TRACE_ERROR_HIGH(Status, REFERRAL_SERVER, "DfsDomainInformation::DfsDomainInformation InitializeCriticalSectionAndSpinCount Status %d\n",
|
|
Status);
|
|
}
|
|
}
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
ULONG ValidDomainCount = 0;
|
|
DfsTrustedDomain *pUseDomain = NULL;
|
|
|
|
//
|
|
// We ignore Xforest initialization errors temporarily
|
|
// but propagate them back to the DcLoop thread so
|
|
// it can retry.
|
|
//
|
|
Status = XForestInfo.Initialize( pXforestStatus );
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
ValidDomainCount = XForestInfo.GetCount();
|
|
}
|
|
|
|
if ( (Status == ERROR_SUCCESS) &&
|
|
(ValidDomainCount > 0) )
|
|
{
|
|
_DomainCount = ValidDomainCount;
|
|
_pTrustedDomains = new DfsTrustedDomain[ _DomainCount ];
|
|
|
|
if (_pTrustedDomains == NULL)
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
DFS_TRACE_ERROR_HIGH(Status, REFERRAL_SERVER, "DfsDomainInformation - _pTrustedDomains is NULL Status %d\n",
|
|
Status);
|
|
}
|
|
|
|
ValidDomainCount = 0;
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
PDFS_DOMAIN_NAME_INFO pDomainInfo;
|
|
do
|
|
{
|
|
|
|
|
|
pDomainInfo = XForestInfo.GetNextDomainInfo();
|
|
if (pDomainInfo != NULL)
|
|
{
|
|
pUseDomain = &_pTrustedDomains[ValidDomainCount];
|
|
pUseDomain->Initialize(_pLock );
|
|
|
|
if (pDomainInfo->UseBindDomain)
|
|
{
|
|
Status = pUseDomain->SetBindDomainName( &pDomainInfo->BindDomainName);
|
|
}
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
Status = pUseDomain->SetDomainName( &pDomainInfo->DomainName,
|
|
pDomainInfo->Netbios);
|
|
}
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
_DomainReferralLength += (pUseDomain->GetDomainName())->Length;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
ValidDomainCount++;
|
|
}
|
|
} while ( pDomainInfo != NULL );
|
|
|
|
}
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
_SkippedDomainCount = XForestInfo.GetSkippedDomainCount();
|
|
DFS_TRACE_LOW(REFERRAL_SERVER, "DfsDomainInformation, with %d domains, (%d domains skipped)\n",
|
|
ValidDomainCount,
|
|
_SkippedDomainCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
*pStatus = Status;
|
|
|
|
//
|
|
// XForestInfo goes out of scope and is destroyed
|
|
//
|
|
}
|
|
|
|
|
|
DFSSTATUS
|
|
DfsDomainInformation::GenerateDomainReferral(
|
|
REFERRAL_HEADER ** ppReferralHeader)
|
|
{
|
|
DFSSTATUS Status = ERROR_SUCCESS;
|
|
ULONG TotalSize = 0;
|
|
ULONG NextEntry = 0;
|
|
ULONG LastEntry = 0;
|
|
ULONG CurrentEntryLength = 0;
|
|
ULONG LastEntryLength = 0;
|
|
ULONG BaseLength = 0;
|
|
ULONG HeaderBaseLength = 0;
|
|
ULONG CurrentNameLength =0;
|
|
PUCHAR Buffer = NULL;
|
|
PUCHAR pDomainBuffer = NULL;
|
|
PWCHAR ReturnedName = NULL;
|
|
PREFERRAL_HEADER pHeader = NULL;
|
|
|
|
|
|
HeaderBaseLength = FIELD_OFFSET( REFERRAL_HEADER, LinkName[0] );
|
|
|
|
//calculate size of base replica structure
|
|
BaseLength = FIELD_OFFSET( REPLICA_INFORMATION, ReplicaName[0] );
|
|
|
|
TotalSize = ROUND_UP_COUNT(HeaderBaseLength, ALIGN_LONG);
|
|
|
|
for (ULONG Index = 0; Index < _DomainCount; Index++)
|
|
{
|
|
PUNICODE_STRING pDomainName = (&_pTrustedDomains[Index])->GetDomainName();
|
|
TotalSize += ROUND_UP_COUNT(pDomainName->Length + BaseLength, ALIGN_LONG);
|
|
}
|
|
|
|
//allocate the buffer
|
|
Buffer = new BYTE[TotalSize];
|
|
if(Buffer == NULL)
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
DFS_TRACE_ERROR_HIGH(Status, REFERRAL_SERVER, "DfsDomainInformation:GenerateDomainReferral allocation failure Status %d\n",
|
|
Status);
|
|
return Status;
|
|
}
|
|
|
|
RtlZeroMemory( Buffer, TotalSize );
|
|
//setup the header
|
|
|
|
pHeader = (PREFERRAL_HEADER) Buffer;
|
|
pHeader->VersionNumber = CURRENT_DFS_REPLICA_HEADER_VERSION;
|
|
pHeader->ReplicaCount = 0;
|
|
pHeader->OffsetToReplicas = ROUND_UP_COUNT((HeaderBaseLength), ALIGN_LONG);
|
|
pHeader->LinkNameLength = 0;
|
|
pHeader->TotalSize = TotalSize;
|
|
pHeader->ReferralFlags = DFS_REFERRAL_DATA_DOMAIN_REFERRAL;
|
|
|
|
pDomainBuffer = Buffer + pHeader->OffsetToReplicas;
|
|
|
|
for (ULONG Index = 0; Index < _DomainCount; Index++)
|
|
{
|
|
PUNICODE_STRING pDomainName = (&_pTrustedDomains[Index])->GetDomainName();
|
|
if (pDomainName->Length == 0)
|
|
{
|
|
continue;
|
|
}
|
|
pHeader->ReplicaCount++;
|
|
NextEntry += (ULONG)( CurrentEntryLength );
|
|
|
|
ReturnedName = (PWCHAR) &pDomainBuffer[NextEntry + BaseLength];
|
|
CurrentNameLength = 0;
|
|
|
|
#if 0
|
|
//
|
|
// Start with the leading path seperator
|
|
//
|
|
ReturnedName[ CurrentNameLength / sizeof(WCHAR) ] = UNICODE_PATH_SEP;
|
|
CurrentNameLength += sizeof(UNICODE_PATH_SEP);
|
|
#endif
|
|
//
|
|
// next copy the server name.
|
|
//
|
|
RtlMoveMemory( &ReturnedName[ CurrentNameLength / sizeof(WCHAR) ],
|
|
pDomainName->Buffer,
|
|
pDomainName->Length);
|
|
CurrentNameLength += pDomainName->Length;
|
|
((PREPLICA_INFORMATION)&pDomainBuffer[NextEntry])->ReplicaFlags = 0;
|
|
((PREPLICA_INFORMATION)&pDomainBuffer[NextEntry])->ReplicaCost = 0;
|
|
((PREPLICA_INFORMATION)&pDomainBuffer[NextEntry])->ReplicaNameLength = CurrentNameLength;
|
|
|
|
CurrentEntryLength = ROUND_UP_COUNT((CurrentNameLength + BaseLength), ALIGN_LONG);
|
|
|
|
//setup the offset to the next entry
|
|
*((PULONG)(&pDomainBuffer[NextEntry])) = pHeader->OffsetToReplicas + NextEntry + CurrentEntryLength;
|
|
}
|
|
|
|
*((PULONG)(&pDomainBuffer[NextEntry])) = 0;
|
|
*ppReferralHeader = pHeader;
|
|
|
|
return Status;
|
|
}
|
|
|
|
VOID
|
|
DfsDomainInformation::PurgeDCReferrals()
|
|
{
|
|
ULONG Index;
|
|
|
|
for (Index = 0; Index < _DomainCount; Index++)
|
|
{
|
|
DFSSTATUS DiscardStatus;
|
|
|
|
DiscardStatus = _pTrustedDomains[Index].RemoveDcReferralData( NULL, NULL);
|
|
}
|
|
return NOTHING;
|
|
|
|
}
|