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.

453 lines
11 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1996, Microsoft Corporation
  4. //
  5. // File: dominfo.h
  6. //
  7. // Contents: Code to figure out domain dfs addresses
  8. //
  9. // Classes: None
  10. //
  11. // Functions:
  12. //
  13. // History: Feb 7, 1996 Milans created
  14. //
  15. //-----------------------------------------------------------------------------
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. #include <dfsfsctl.h>
  20. #include <windows.h>
  21. #include <dsgetdc.h>
  22. #include <dsrole.h>
  23. #include <wsutil.h>
  24. #include "dominfo.h"
  25. #define MUP_EVENT_NAME TEXT("wkssvc: MUP finished initializing event")
  26. HANDLE
  27. CreateMupEvent(void);
  28. NTSTATUS
  29. DfsGetDomainNameInfo(void);
  30. HANDLE hMupEvent = NULL;
  31. BOOLEAN MupEventSignaled = FALSE;
  32. BOOLEAN GotDomainNameInfo = FALSE;
  33. ULONG DfsDebug = 0;
  34. //
  35. // Commonly used strings and characters
  36. //
  37. #define UNICODE_PATH_SEP_STR L"\\"
  38. #define UNICODE_PATH_SEP L'\\'
  39. #define DNS_PATH_SEP L'.'
  40. //+----------------------------------------------------------------------------
  41. //
  42. // Function: DfsGetDCName
  43. //
  44. // Synopsis: Gets the name of a DC we can use for expanded name referrals
  45. // It will stick this into the driver.
  46. //
  47. // Arguments: [Flags] -- TBD
  48. //
  49. // Returns: [STATUS_SUCCESS] -- Successfully created domain pkt entry.
  50. //
  51. // [STATUS_INSUFFICIENT_RESOURCES] -- Out of memory condition.
  52. //
  53. // [STATUS_OBJECT_NAME_NOT_FOUND] -- wszDomain is not a trusted
  54. // domain.
  55. //
  56. // [STATUS_UNEXPECTED_NETWORK_ERROR] -- Unable to get DC for
  57. // domain.
  58. //
  59. //-----------------------------------------------------------------------------
  60. NTSTATUS
  61. DfsGetDCName(
  62. IN ULONG Flags,
  63. BOOLEAN *DcNameFailed)
  64. {
  65. NTSTATUS Status;
  66. HANDLE hDfs;
  67. ULONG cbSize;
  68. WCHAR *DCName;
  69. ULONG dwErr;
  70. ULONG Len;
  71. PDOMAIN_CONTROLLER_INFO pDomainControllerInfo;
  72. *DcNameFailed = TRUE;
  73. #if DBG
  74. if (DfsDebug)
  75. DbgPrint("DfsGetDCName(%d)\n", Flags);
  76. #endif
  77. if( WsInAWorkgroup() == TRUE ) {
  78. //
  79. // We are in a workgroup. We will never find a DC!
  80. //
  81. #if DBG
  82. if (DfsDebug)
  83. DbgPrint("DfsGetDCName exit STATUS_NO_SUCH_DOMAIN\n");
  84. #endif
  85. return STATUS_NO_SUCH_DOMAIN;
  86. }
  87. if (hMupEvent == NULL) {
  88. hMupEvent = CreateMupEvent();
  89. }
  90. dwErr = DsGetDcName(
  91. NULL, // Computername
  92. NULL, // DomainName
  93. NULL, // DomainGuid
  94. NULL, // SiteGuid
  95. Flags | DS_DIRECTORY_SERVICE_REQUIRED,
  96. &pDomainControllerInfo);
  97. //
  98. // If DsGetDcName succeeded, try to get the NetBios & Dns domain names.
  99. //
  100. if (dwErr != NO_ERROR) {
  101. if (MupEventSignaled == FALSE) {
  102. #if DBG
  103. if (DfsDebug)
  104. DbgPrint("Signaling mup event\n");
  105. #endif
  106. SetEvent(hMupEvent);
  107. MupEventSignaled = TRUE;
  108. }
  109. switch (dwErr) {
  110. case ERROR_NOT_ENOUGH_MEMORY:
  111. Status = STATUS_INSUFFICIENT_RESOURCES;
  112. break;
  113. case ERROR_NETWORK_UNREACHABLE:
  114. Status = STATUS_NETWORK_UNREACHABLE;
  115. break;
  116. default:
  117. Status = STATUS_UNEXPECTED_NETWORK_ERROR;
  118. break;
  119. }
  120. #if DBG
  121. if (DfsDebug)
  122. DbgPrint("DfsGetDCName(1) exit 0x%x\n", Status);
  123. #endif
  124. return (Status);
  125. } else {
  126. if (pDomainControllerInfo == NULL) {
  127. DbgBreakPoint();
  128. }
  129. }
  130. *DcNameFailed = FALSE;
  131. DfsGetDomainNameInfo();
  132. //
  133. // Remove leading '\'s
  134. //
  135. DCName = pDomainControllerInfo->DomainControllerName;
  136. while (*DCName == UNICODE_PATH_SEP && *DCName != UNICODE_NULL)
  137. DCName++;
  138. //
  139. // Remove trailing '.', if present
  140. //
  141. Len = wcslen(DCName);
  142. if (Len >= 1 && DCName[Len-1] == DNS_PATH_SEP) {
  143. DCName[Len-1] = UNICODE_NULL;
  144. }
  145. if (wcslen(DCName) <= 0) {
  146. NetApiBufferFree(pDomainControllerInfo);
  147. #if DBG
  148. if (DfsDebug)
  149. DbgPrint("DfsGetDCName exit STATUS_UNEXPECTED_NETWORK_ERROR\n");
  150. #endif
  151. return (STATUS_UNEXPECTED_NETWORK_ERROR);
  152. }
  153. Status = DfsOpen( &hDfs, NULL );
  154. if (!NT_SUCCESS(Status)) {
  155. NetApiBufferFree(pDomainControllerInfo);
  156. #if DBG
  157. if (DfsDebug)
  158. DbgPrint("DfsGetDCName(2) exit 0x%x\n", Status);
  159. #endif
  160. return (Status);
  161. }
  162. //
  163. // Take the name and fscontrol it down to the driver
  164. //
  165. cbSize = wcslen(DCName) * sizeof(WCHAR) + sizeof(WCHAR);
  166. Status = DfsFsctl(
  167. hDfs,
  168. FSCTL_DFS_PKT_SET_DC_NAME,
  169. DCName,
  170. cbSize,
  171. NULL,
  172. 0L);
  173. NetApiBufferFree(pDomainControllerInfo);
  174. //
  175. // Inform anyone waiting that the mup is ready.
  176. //
  177. if (MupEventSignaled == FALSE) {
  178. #if DBG
  179. if (DfsDebug)
  180. DbgPrint("Signaling mup event\n");
  181. #endif
  182. SetEvent(hMupEvent);
  183. MupEventSignaled = TRUE;
  184. }
  185. NtClose( hDfs );
  186. #if DBG
  187. if (DfsDebug)
  188. DbgPrint("DfsGetDCName(3) exit 0x%x\n", Status);
  189. #endif
  190. return (Status);
  191. }
  192. //+----------------------------------------------------------------------------
  193. //
  194. // Function: DfsGetDomainNameInfo
  195. //
  196. // Synopsis: Gets the Netbios & Dns name of the domain, then sends them
  197. // down to the drvier;
  198. //
  199. // Returns: [STATUS_SUCCESS] -- Successfully created domain pkt entry.
  200. // [other] -- return from DfsOpen or
  201. // DsRoleGetPrimaryDomainInformation
  202. //
  203. //-----------------------------------------------------------------------------
  204. NTSTATUS
  205. DfsGetDomainNameInfo(void)
  206. {
  207. NTSTATUS Status;
  208. ULONG dwErr;
  209. HANDLE hDfs;
  210. ULONG cbSize;
  211. PDSROLE_PRIMARY_DOMAIN_INFO_BASIC pPrimaryDomainInfo;
  212. Status = DfsOpen( &hDfs, NULL );
  213. if (!NT_SUCCESS(Status)) {
  214. return (Status);
  215. }
  216. //
  217. // Get our machine name and type/role.
  218. //
  219. dwErr = DsRoleGetPrimaryDomainInformation(
  220. NULL,
  221. DsRolePrimaryDomainInfoBasic,
  222. (PBYTE *)&pPrimaryDomainInfo);
  223. if (dwErr == ERROR_SUCCESS) {
  224. if (pPrimaryDomainInfo->DomainNameFlat != NULL) {
  225. cbSize = wcslen(pPrimaryDomainInfo->DomainNameFlat) * sizeof(WCHAR) + sizeof(WCHAR);
  226. Status = DfsFsctl(
  227. hDfs,
  228. FSCTL_DFS_PKT_SET_DOMAINNAMEFLAT,
  229. pPrimaryDomainInfo->DomainNameFlat,
  230. cbSize,
  231. NULL,
  232. 0L);
  233. }
  234. if (pPrimaryDomainInfo->DomainNameDns != NULL) {
  235. cbSize = wcslen(pPrimaryDomainInfo->DomainNameDns) * sizeof(WCHAR) + sizeof(WCHAR);
  236. Status = DfsFsctl(
  237. hDfs,
  238. FSCTL_DFS_PKT_SET_DOMAINNAMEDNS,
  239. pPrimaryDomainInfo->DomainNameDns,
  240. cbSize,
  241. NULL,
  242. 0L);
  243. }
  244. DsRoleFreeMemory(pPrimaryDomainInfo);
  245. GotDomainNameInfo = TRUE;
  246. }
  247. NtClose( hDfs );
  248. return (Status);
  249. }
  250. UNICODE_STRING LocalDfsName = {
  251. sizeof(DFS_DRIVER_NAME)-sizeof(UNICODE_NULL),
  252. sizeof(DFS_DRIVER_NAME)-sizeof(UNICODE_NULL),
  253. DFS_DRIVER_NAME
  254. };
  255. //+-------------------------------------------------------------------------
  256. //
  257. // Function: DfsOpen, public
  258. //
  259. // Synopsis:
  260. //
  261. // Arguments:
  262. //
  263. // Returns:
  264. //
  265. //--------------------------------------------------------------------------
  266. NTSTATUS
  267. DfsOpen(
  268. IN OUT PHANDLE DfsHandle,
  269. IN PUNICODE_STRING DfsName OPTIONAL
  270. )
  271. {
  272. NTSTATUS status;
  273. OBJECT_ATTRIBUTES objectAttributes;
  274. IO_STATUS_BLOCK ioStatus;
  275. PUNICODE_STRING name;
  276. if (ARGUMENT_PRESENT(DfsName)) {
  277. name = DfsName;
  278. } else {
  279. name = &LocalDfsName;
  280. }
  281. InitializeObjectAttributes(
  282. &objectAttributes,
  283. name,
  284. OBJ_CASE_INSENSITIVE,
  285. NULL,
  286. NULL
  287. );
  288. status = NtCreateFile(
  289. DfsHandle,
  290. SYNCHRONIZE | FILE_WRITE_DATA,
  291. &objectAttributes,
  292. &ioStatus,
  293. NULL,
  294. FILE_ATTRIBUTE_NORMAL,
  295. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  296. FILE_OPEN_IF,
  297. FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
  298. NULL,
  299. 0);
  300. if (NT_SUCCESS(status))
  301. status = ioStatus.Status;
  302. return status;
  303. }
  304. //+-------------------------------------------------------------------------
  305. //
  306. // Function: DfsFsctl, public
  307. //
  308. // Synopsis:
  309. //
  310. // Arguments:
  311. //
  312. // Returns:
  313. //
  314. //--------------------------------------------------------------------------
  315. NTSTATUS
  316. DfsFsctl(
  317. IN HANDLE DfsHandle,
  318. IN ULONG FsControlCode,
  319. IN PVOID InputBuffer OPTIONAL,
  320. IN ULONG InputBufferLength,
  321. OUT PVOID OutputBuffer OPTIONAL,
  322. IN ULONG OutputBufferLength
  323. )
  324. {
  325. NTSTATUS status;
  326. IO_STATUS_BLOCK ioStatus;
  327. status = NtFsControlFile(
  328. DfsHandle,
  329. NULL, // Event,
  330. NULL, // ApcRoutine,
  331. NULL, // ApcContext,
  332. &ioStatus,
  333. FsControlCode,
  334. InputBuffer,
  335. InputBufferLength,
  336. OutputBuffer,
  337. OutputBufferLength
  338. );
  339. if(NT_SUCCESS(status))
  340. status = ioStatus.Status;
  341. return status;
  342. }
  343. //+-------------------------------------------------------------------------
  344. //
  345. // CreateMUPEvent()
  346. //
  347. // Purpose: Creates an event so other processes can check if the
  348. // MUP is ready yet
  349. //
  350. // Parameters: none
  351. //
  352. // Note: This handle should never be closed or other processes
  353. // will fail on the call to OpenEvent().
  354. //
  355. // Return: Event handle if successful
  356. // NULL if an error occurs
  357. //
  358. //+-------------------------------------------------------------------------
  359. HANDLE
  360. CreateMupEvent(void)
  361. {
  362. HANDLE hEvent;
  363. // Use default security descriptor.
  364. hEvent = CreateEvent (NULL, TRUE, FALSE, MUP_EVENT_NAME);
  365. return hEvent;
  366. }