Leaked source code of windows server 2003
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

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 2001, Microsoft Corporation
  4. //
  5. // File: DfsDomainInformation.cxx
  6. //
  7. // Contents: the Dfs domain info class
  8. //
  9. // Classes: DfsDomainInformation
  10. //
  11. // History: apr. 8 2001, Author: udayh
  12. //
  13. //-----------------------------------------------------------------------------
  14. #include "DfsGeneric.hxx"
  15. #include "Align.h"
  16. #include "dsgetdc.h"
  17. #include "DfsTrustedDomain.hxx"
  18. #include "DfsReferralData.h"
  19. #include "dfsdomainInformation.hxx"
  20. #include "dfsxforest.hxx"
  21. #include "dfsdomainInformation.tmh"
  22. DfsDomainInformation::DfsDomainInformation(
  23. DFSSTATUS *pStatus,
  24. DFSSTATUS *pXforestStatus)
  25. : DfsGeneric( DFS_OBJECT_TYPE_DOMAIN_INFO)
  26. {
  27. ULONG DsDomainCount = 0;
  28. PDS_DOMAIN_TRUSTS pDsDomainTrusts = NULL;
  29. DFSSTATUS Status = ERROR_SUCCESS;
  30. DFSSTATUS XforestInitStatus = ERROR_SUCCESS;
  31. LPWSTR ServerName = NULL;
  32. ULONG Index = 0;
  33. DfsXForest XForestInfo;
  34. _pTrustedDomains = NULL;
  35. _DomainCount = 0;
  36. _fCritInit = FALSE;
  37. _DomainReferralLength = 0;
  38. _pLock = new CRITICAL_SECTION;
  39. if ( _pLock == NULL )
  40. {
  41. Status = ERROR_NOT_ENOUGH_MEMORY;
  42. }
  43. else
  44. {
  45. _fCritInit = InitializeCriticalSectionAndSpinCount( _pLock, DFS_CRIT_SPIN_COUNT );
  46. if(!_fCritInit)
  47. {
  48. Status = GetLastError();
  49. DFS_TRACE_ERROR_HIGH(Status, REFERRAL_SERVER, "DfsDomainInformation::DfsDomainInformation InitializeCriticalSectionAndSpinCount Status %d\n",
  50. Status);
  51. }
  52. }
  53. if (Status == ERROR_SUCCESS)
  54. {
  55. ULONG ValidDomainCount = 0;
  56. DfsTrustedDomain *pUseDomain = NULL;
  57. //
  58. // We ignore Xforest initialization errors temporarily
  59. // but propagate them back to the DcLoop thread so
  60. // it can retry.
  61. //
  62. Status = XForestInfo.Initialize( pXforestStatus );
  63. if (Status == ERROR_SUCCESS)
  64. {
  65. ValidDomainCount = XForestInfo.GetCount();
  66. }
  67. if ( (Status == ERROR_SUCCESS) &&
  68. (ValidDomainCount > 0) )
  69. {
  70. _DomainCount = ValidDomainCount;
  71. _pTrustedDomains = new DfsTrustedDomain[ _DomainCount ];
  72. if (_pTrustedDomains == NULL)
  73. {
  74. Status = ERROR_NOT_ENOUGH_MEMORY;
  75. DFS_TRACE_ERROR_HIGH(Status, REFERRAL_SERVER, "DfsDomainInformation - _pTrustedDomains is NULL Status %d\n",
  76. Status);
  77. }
  78. ValidDomainCount = 0;
  79. if (Status == ERROR_SUCCESS)
  80. {
  81. PDFS_DOMAIN_NAME_INFO pDomainInfo;
  82. do
  83. {
  84. pDomainInfo = XForestInfo.GetNextDomainInfo();
  85. if (pDomainInfo != NULL)
  86. {
  87. pUseDomain = &_pTrustedDomains[ValidDomainCount];
  88. pUseDomain->Initialize(_pLock );
  89. if (pDomainInfo->UseBindDomain)
  90. {
  91. Status = pUseDomain->SetBindDomainName( &pDomainInfo->BindDomainName);
  92. }
  93. if (Status == ERROR_SUCCESS)
  94. {
  95. Status = pUseDomain->SetDomainName( &pDomainInfo->DomainName,
  96. pDomainInfo->Netbios);
  97. }
  98. if (Status == ERROR_SUCCESS)
  99. {
  100. _DomainReferralLength += (pUseDomain->GetDomainName())->Length;
  101. }
  102. else
  103. {
  104. break;
  105. }
  106. ValidDomainCount++;
  107. }
  108. } while ( pDomainInfo != NULL );
  109. }
  110. if (Status == ERROR_SUCCESS)
  111. {
  112. _SkippedDomainCount = XForestInfo.GetSkippedDomainCount();
  113. DFS_TRACE_LOW(REFERRAL_SERVER, "DfsDomainInformation, with %d domains, (%d domains skipped)\n",
  114. ValidDomainCount,
  115. _SkippedDomainCount);
  116. }
  117. }
  118. }
  119. *pStatus = Status;
  120. //
  121. // XForestInfo goes out of scope and is destroyed
  122. //
  123. }
  124. DFSSTATUS
  125. DfsDomainInformation::GenerateDomainReferral(
  126. REFERRAL_HEADER ** ppReferralHeader)
  127. {
  128. DFSSTATUS Status = ERROR_SUCCESS;
  129. ULONG TotalSize = 0;
  130. ULONG NextEntry = 0;
  131. ULONG LastEntry = 0;
  132. ULONG CurrentEntryLength = 0;
  133. ULONG LastEntryLength = 0;
  134. ULONG BaseLength = 0;
  135. ULONG HeaderBaseLength = 0;
  136. ULONG CurrentNameLength =0;
  137. PUCHAR Buffer = NULL;
  138. PUCHAR pDomainBuffer = NULL;
  139. PWCHAR ReturnedName = NULL;
  140. PREFERRAL_HEADER pHeader = NULL;
  141. HeaderBaseLength = FIELD_OFFSET( REFERRAL_HEADER, LinkName[0] );
  142. //calculate size of base replica structure
  143. BaseLength = FIELD_OFFSET( REPLICA_INFORMATION, ReplicaName[0] );
  144. TotalSize = ROUND_UP_COUNT(HeaderBaseLength, ALIGN_LONG);
  145. for (ULONG Index = 0; Index < _DomainCount; Index++)
  146. {
  147. PUNICODE_STRING pDomainName = (&_pTrustedDomains[Index])->GetDomainName();
  148. TotalSize += ROUND_UP_COUNT(pDomainName->Length + BaseLength, ALIGN_LONG);
  149. }
  150. //allocate the buffer
  151. Buffer = new BYTE[TotalSize];
  152. if(Buffer == NULL)
  153. {
  154. Status = ERROR_NOT_ENOUGH_MEMORY;
  155. DFS_TRACE_ERROR_HIGH(Status, REFERRAL_SERVER, "DfsDomainInformation:GenerateDomainReferral allocation failure Status %d\n",
  156. Status);
  157. return Status;
  158. }
  159. RtlZeroMemory( Buffer, TotalSize );
  160. //setup the header
  161. pHeader = (PREFERRAL_HEADER) Buffer;
  162. pHeader->VersionNumber = CURRENT_DFS_REPLICA_HEADER_VERSION;
  163. pHeader->ReplicaCount = 0;
  164. pHeader->OffsetToReplicas = ROUND_UP_COUNT((HeaderBaseLength), ALIGN_LONG);
  165. pHeader->LinkNameLength = 0;
  166. pHeader->TotalSize = TotalSize;
  167. pHeader->ReferralFlags = DFS_REFERRAL_DATA_DOMAIN_REFERRAL;
  168. pDomainBuffer = Buffer + pHeader->OffsetToReplicas;
  169. for (ULONG Index = 0; Index < _DomainCount; Index++)
  170. {
  171. PUNICODE_STRING pDomainName = (&_pTrustedDomains[Index])->GetDomainName();
  172. if (pDomainName->Length == 0)
  173. {
  174. continue;
  175. }
  176. pHeader->ReplicaCount++;
  177. NextEntry += (ULONG)( CurrentEntryLength );
  178. ReturnedName = (PWCHAR) &pDomainBuffer[NextEntry + BaseLength];
  179. CurrentNameLength = 0;
  180. #if 0
  181. //
  182. // Start with the leading path seperator
  183. //
  184. ReturnedName[ CurrentNameLength / sizeof(WCHAR) ] = UNICODE_PATH_SEP;
  185. CurrentNameLength += sizeof(UNICODE_PATH_SEP);
  186. #endif
  187. //
  188. // next copy the server name.
  189. //
  190. RtlMoveMemory( &ReturnedName[ CurrentNameLength / sizeof(WCHAR) ],
  191. pDomainName->Buffer,
  192. pDomainName->Length);
  193. CurrentNameLength += pDomainName->Length;
  194. ((PREPLICA_INFORMATION)&pDomainBuffer[NextEntry])->ReplicaFlags = 0;
  195. ((PREPLICA_INFORMATION)&pDomainBuffer[NextEntry])->ReplicaCost = 0;
  196. ((PREPLICA_INFORMATION)&pDomainBuffer[NextEntry])->ReplicaNameLength = CurrentNameLength;
  197. CurrentEntryLength = ROUND_UP_COUNT((CurrentNameLength + BaseLength), ALIGN_LONG);
  198. //setup the offset to the next entry
  199. *((PULONG)(&pDomainBuffer[NextEntry])) = pHeader->OffsetToReplicas + NextEntry + CurrentEntryLength;
  200. }
  201. *((PULONG)(&pDomainBuffer[NextEntry])) = 0;
  202. *ppReferralHeader = pHeader;
  203. return Status;
  204. }
  205. VOID
  206. DfsDomainInformation::PurgeDCReferrals()
  207. {
  208. ULONG Index;
  209. for (Index = 0; Index < _DomainCount; Index++)
  210. {
  211. DFSSTATUS DiscardStatus;
  212. DiscardStatus = _pTrustedDomains[Index].RemoveDcReferralData( NULL, NULL);
  213. }
  214. return NOTHING;
  215. }