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.

342 lines
9.2 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. //
  4. // Copyright (C) 2002, Microsoft Corporation
  5. //
  6. // File: SiteInformation.cxx
  7. //
  8. //
  9. //--------------------------------------------------------------------------
  10. #include <nt.h>
  11. #include <ntrtl.h>
  12. #include <nturtl.h>
  13. #include <windows.h>
  14. #include <windef.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <stddef.h>
  18. #include <shellapi.h>
  19. #include "rpc.h"
  20. #include "rpcdce.h"
  21. #include <lm.h>
  22. #include <winsock2.h>
  23. #include <dsgetdc.h>
  24. #include <dsrole.h>
  25. #include <dfsutil.hxx>
  26. #include <dfsstrings.hxx>
  27. //
  28. // Flags used in DsGetDcName()
  29. //
  30. struct _DFS_PREFIX_TABLE *_pSiteTable;
  31. DWORD DcFlags[] = {
  32. DS_DIRECTORY_SERVICE_REQUIRED |
  33. DS_IP_REQUIRED,
  34. DS_DIRECTORY_SERVICE_REQUIRED |
  35. DS_IP_REQUIRED |
  36. DS_FORCE_REDISCOVERY
  37. };
  38. DfsString UseDcName;
  39. DFSSTATUS
  40. FindSiteInformation( PUNICODE_STRING pName,
  41. DfsString *pSite )
  42. {
  43. NTSTATUS NtStatus;
  44. UNICODE_STRING Suffix;
  45. DfsString *pStoredSite;
  46. DFSSTATUS Status;
  47. if (_pSiteTable == NULL)
  48. {
  49. Status = ERROR_NOT_FOUND;
  50. return Status;
  51. }
  52. Status = ERROR_NOT_FOUND;
  53. NtStatus = DfsPrefixTableAcquireReadLock( _pSiteTable );
  54. if (NtStatus == STATUS_SUCCESS)
  55. {
  56. NtStatus = DfsFindUnicodePrefixLocked( _pSiteTable,
  57. pName,
  58. &Suffix,
  59. (PVOID *)&pStoredSite,
  60. NULL );
  61. DfsPrefixTableReleaseLock( _pSiteTable );
  62. }
  63. if (NtStatus == STATUS_SUCCESS)
  64. {
  65. Status = pSite->CreateString(pStoredSite->GetString());
  66. }
  67. DebugInformation((L"Find site %wZ, status %x\n", pName, Status));
  68. return Status;
  69. }
  70. DFSSTATUS
  71. StoreSiteInformation( PUNICODE_STRING pName,
  72. DfsString *pSite )
  73. {
  74. DfsString *pStoreSite;
  75. DFSSTATUS Status;
  76. NTSTATUS NtStatus = STATUS_SUCCESS;
  77. pStoreSite = new DfsString;
  78. if (pStoreSite == NULL)
  79. {
  80. return ERROR_NOT_ENOUGH_MEMORY;
  81. }
  82. Status = pStoreSite->CreateString(pSite->GetString());
  83. if (Status != ERROR_SUCCESS)
  84. {
  85. return Status;
  86. }
  87. if (_pSiteTable == NULL)
  88. {
  89. NtStatus = DfsInitializePrefixTable( &_pSiteTable,
  90. FALSE,
  91. NULL );
  92. }
  93. if (NtStatus == STATUS_SUCCESS)
  94. {
  95. NtStatus = DfsPrefixTableAcquireWriteLock( _pSiteTable);
  96. if (NtStatus == STATUS_SUCCESS)
  97. {
  98. NtStatus = DfsInsertInPrefixTableLocked( _pSiteTable,
  99. pName,
  100. (PVOID)(pStoreSite));
  101. DfsPrefixTableReleaseLock(_pSiteTable);
  102. }
  103. }
  104. DebugInformation((L"Storing name %wZ, status %x\n", pName, NtStatus));
  105. return RtlNtStatusToDosError(NtStatus);
  106. }
  107. DWORD
  108. GetSiteNameFromIpAddress(char * IpData,
  109. ULONG IpLength,
  110. USHORT IpFamily,
  111. LPWSTR **SiteNames)
  112. {
  113. DWORD Status = ERROR_INVALID_PARAMETER;
  114. PDOMAIN_CONTROLLER_INFO pDCInfo = NULL;
  115. PSOCKET_ADDRESS pSockAddr = NULL;
  116. PSOCKADDR_IN pSockAddrIn = NULL;
  117. struct hostent* pH = NULL;
  118. DWORD cRetry = 0;
  119. SOCKET_ADDRESS SockAddr;
  120. SOCKADDR_IN SockAddrIn;
  121. //setup the socket structures in order to call DsAddressToSiteNames
  122. pSockAddr = &SockAddr;
  123. pSockAddr->iSockaddrLength = sizeof(SOCKADDR_IN);
  124. pSockAddr->lpSockaddr = (LPSOCKADDR)&SockAddrIn;
  125. pSockAddrIn = &SockAddrIn;
  126. pSockAddrIn->sin_family = IpFamily;
  127. pSockAddrIn->sin_port = 0;
  128. RtlCopyMemory(
  129. &pSockAddrIn->sin_addr,
  130. IpData,
  131. (IpLength & 0xff));
  132. //
  133. // Call DsGetDcName() with ever-increasing urgency, until either
  134. // we get a good DC or we just give up.
  135. //
  136. if (IsEmptyString(UseDcName.GetString()) == FALSE)
  137. {
  138. Status = DsAddressToSiteNames( UseDcName.GetString(),
  139. 1,
  140. pSockAddr,
  141. SiteNames);
  142. if (Status == ERROR_SUCCESS)
  143. {
  144. return Status;
  145. }
  146. }
  147. for (cRetry = 0; cRetry <= (sizeof(DcFlags) / sizeof(DcFlags[1])); cRetry++)
  148. {
  149. Status = DsGetDcName( NULL, // Computer to remote to
  150. NULL, // Domain - use local domain
  151. NULL, // Domain Guid
  152. NULL, // Site Guid
  153. DcFlags[cRetry], // Flags
  154. &pDCInfo);
  155. if (Status == ERROR_SUCCESS)
  156. {
  157. DebugInformation((L"Trying DC %ws with address %ws in domain %ws within forest %ws\n\n",
  158. pDCInfo->DomainControllerName,
  159. pDCInfo->DomainControllerAddress,
  160. pDCInfo->DomainName,
  161. pDCInfo->DnsForestName));
  162. Status = DsAddressToSiteNames( pDCInfo->DomainControllerAddress,
  163. 1,
  164. pSockAddr,
  165. SiteNames);
  166. if(Status != ERROR_SUCCESS)
  167. {
  168. DebugInformation((L"DsAddressToSiteNames failed using DC %ws with error %d\n", pDCInfo->DomainControllerAddress, Status));
  169. }
  170. if (Status == ERROR_SUCCESS)
  171. {
  172. UseDcName.CreateString(pDCInfo->DomainControllerAddress);
  173. goto Exit;
  174. }
  175. NetApiBufferFree( pDCInfo );
  176. }
  177. else
  178. {
  179. DebugInformation((L"DsGetDcName failed with error %d\n", Status));
  180. }
  181. }
  182. Exit:
  183. return Status;
  184. }
  185. DWORD
  186. GetSites(LPWSTR Target,
  187. DfsString *pSite )
  188. {
  189. DWORD Status = 0;
  190. DWORD Loop = 0;
  191. struct hostent *hp = NULL;
  192. unsigned long InetAddr = 0;
  193. char * IpAddr = NULL;
  194. WSADATA wsadata;
  195. in_addr inAddrIpServer;
  196. NTSTATUS NtStatus = STATUS_SUCCESS;
  197. ANSI_STRING DestinationString;
  198. UNICODE_STRING ServerName;
  199. LPWSTR *pSiteNamesArray = NULL;
  200. Status = DfsRtlInitUnicodeStringEx(&ServerName, Target);
  201. if (Status != ERROR_SUCCESS)
  202. {
  203. return Status;
  204. }
  205. Status = FindSiteInformation( &ServerName,
  206. pSite);
  207. if (Status == ERROR_SUCCESS)
  208. {
  209. return Status;
  210. }
  211. Status = WSAStartup( MAKEWORD( 1, 1 ), &wsadata );
  212. if (Status != ERROR_SUCCESS)
  213. {
  214. return Status;
  215. }
  216. DestinationString.Buffer = NULL;
  217. NtStatus = RtlUnicodeStringToAnsiString(&DestinationString,
  218. &ServerName,
  219. TRUE);
  220. if (NtStatus != STATUS_SUCCESS)
  221. {
  222. return RtlNtStatusToDosError(NtStatus);
  223. }
  224. //
  225. // This can be a bogus host name. So beware.
  226. //
  227. hp = gethostbyname (DestinationString.Buffer);
  228. if(hp != NULL)
  229. {
  230. for (Loop = 0; (hp->h_addr_list[Loop] != NULL); Loop++)
  231. {
  232. CopyMemory(&inAddrIpServer, hp->h_addr_list[Loop], sizeof(DWORD));
  233. DebugInformation((L"Finding site for %wZ\n", &ServerName));
  234. Status = GetSiteNameFromIpAddress( hp->h_addr_list[Loop],
  235. 4,
  236. AF_INET,
  237. &pSiteNamesArray );
  238. }
  239. }
  240. else
  241. {
  242. Status = WSAGetLastError();
  243. InetAddr = inet_addr( DestinationString.Buffer );
  244. if((InetAddr == INADDR_NONE) || (InetAddr == 0))
  245. {
  246. DebugInformation((L"gethostbyname for site for %wZ failed with error %d\n",
  247. &ServerName, Status));
  248. }
  249. else
  250. {
  251. DebugInformation((L"Finding site for %wZ\n", &ServerName));
  252. IpAddr = (char *) &InetAddr;
  253. Status = GetSiteNameFromIpAddress( IpAddr,
  254. 4,
  255. AF_INET,
  256. &pSiteNamesArray );
  257. }
  258. }
  259. if (Status == ERROR_SUCCESS)
  260. {
  261. if ((pSiteNamesArray != NULL) && (pSiteNamesArray[0] != NULL))
  262. {
  263. Status = pSite->CreateString(pSiteNamesArray[0]);
  264. }
  265. else
  266. {
  267. Status = pSite->CreateString(L"(No site association)");
  268. }
  269. if (Status == ERROR_SUCCESS)
  270. {
  271. StoreSiteInformation( &ServerName, pSite);
  272. }
  273. }
  274. if (pSiteNamesArray != NULL)
  275. {
  276. NetApiBufferFree(pSiteNamesArray);
  277. }
  278. return Status;
  279. }