Source code of Windows XP (NT5)
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.

1145 lines
29 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1996, Microsoft Corporation
  4. //
  5. // File: dfsipc.c
  6. //
  7. // Contents: Code to communicate with the Dfs driver. The Dfs driver
  8. // sends messages to the user level to resolve a name to either a domain or
  9. // computer based Dfs name.
  10. //
  11. // Classes: None
  12. //
  13. // History: Feb 1, 1996 Milans Created
  14. //
  15. //-----------------------------------------------------------------------------
  16. #include <ntos.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. #include <dfsfsctl.h>
  20. #include <windows.h>
  21. #include <dfsstr.h>
  22. #include <nodetype.h>
  23. #include <libsup.h>
  24. #include <dfsmrshl.h>
  25. #include <upkt.h>
  26. #include <ntlsa.h>
  27. #include <dfsmsrv.h>
  28. #include <lm.h>
  29. #include <dsrole.h>
  30. #include <crypt.h>
  31. #include <samrpc.h>
  32. #include <logonmsv.h>
  33. #include <dsgetdc.h>
  34. #include <ntdsapi.h>
  35. #include <winldap.h>
  36. #include "dominfo.h"
  37. #include "dfsipc.h"
  38. #include "svcwml.h"
  39. DWORD
  40. DfsLoadSiteTableFromDs(
  41. PLDAP pLDAP,
  42. LPWSTR wszFtDfsName,
  43. ULONG Count,
  44. PUNICODE_STRING pustr);
  45. DWORD
  46. DfsCreateSpcArg(
  47. LPWSTR DomainName,
  48. ULONG Timeout,
  49. ULONG Flags,
  50. ULONG TrustDirection,
  51. ULONG TrustType,
  52. LONG NameCount,
  53. PUNICODE_STRING pustrDCNames,
  54. PDFS_CREATE_SPECIAL_INFO_ARG *ppSpcArg,
  55. PULONG pSize);
  56. DWORD
  57. DfsCreateSiteArg(
  58. LPWSTR ServerName,
  59. ULONG SiteCount,
  60. PUNICODE_STRING pustrSiteNames,
  61. PDFS_CREATE_SITE_INFO_ARG *ppSiteArg,
  62. PULONG pSize);
  63. DWORD
  64. DfsGetFtServersFromDs(
  65. PLDAP pLdap,
  66. LPWSTR wszDomainName,
  67. LPWSTR wszDfsName,
  68. LPWSTR **List);
  69. //
  70. // Event logging and debugging globals
  71. //
  72. extern ULONG DfsSvcVerbose;
  73. extern ULONG DfsEventLog;
  74. extern DFS_DOMAIN_INFO DfsDomainInfo;
  75. extern DSROLE_MACHINE_ROLE DfsMachineRole;
  76. extern WCHAR MachineName[MAX_PATH];
  77. extern WCHAR DomainName[MAX_PATH];
  78. extern WCHAR DomainNameDns[MAX_PATH];
  79. extern WCHAR LastMachineName[MAX_PATH];
  80. extern WCHAR LastDomainName[MAX_PATH];
  81. extern WCHAR SiteName[MAX_PATH];
  82. extern PLDAP pLdap;
  83. extern CRITICAL_SECTION DomListCritSection;
  84. BOOLEAN
  85. DfsGetNextDomainName(
  86. LPWSTR DomName,
  87. ULONG Size);
  88. NTSTATUS
  89. DfsInitOurDomainDCs(VOID)
  90. {
  91. DWORD dwErr;
  92. LPWSTR OurSite;
  93. NTSTATUS status;
  94. HANDLE dfsHandle = NULL;
  95. IO_STATUS_BLOCK ioStatus;
  96. ULONG cDom;
  97. PDFS_CREATE_SPECIAL_INFO_ARG pSpcArg;
  98. ULONG Size;
  99. #if DBG
  100. if (DfsSvcVerbose)
  101. DbgPrint("DfsInitOurDomainDCs()\n");
  102. #endif
  103. dwErr = DsGetSiteName(
  104. NULL,
  105. &OurSite);
  106. RtlZeroMemory(SiteName, MAX_PATH * sizeof(WCHAR));
  107. if (dwErr == NO_ERROR) {
  108. wcscpy(SiteName, OurSite);
  109. NetApiBufferFree(OurSite);
  110. }
  111. status = DfsOpen(&dfsHandle, NULL);
  112. if (NT_SUCCESS(status)) {
  113. #if DBG
  114. if (DfsSvcVerbose)
  115. DbgPrint("Domain %ws/%ws\n",
  116. DomainName,
  117. DomainNameDns);
  118. #endif
  119. status = DfsCreateSpcArg(
  120. DomainName,
  121. 0,
  122. DFS_SPECIAL_INFO_NETBIOS,
  123. TRUST_DIRECTION_BIDIRECTIONAL,
  124. TRUST_TYPE_UPLEVEL,
  125. -1,
  126. NULL,
  127. &pSpcArg,
  128. &Size);
  129. if (status == ERROR_SUCCESS) {
  130. status = NtFsControlFile(
  131. dfsHandle,
  132. NULL, // Event,
  133. NULL, // ApcRoutine,
  134. NULL, // ApcContext,
  135. &ioStatus,
  136. FSCTL_DFS_CREATE_SPECIAL_INFO,
  137. pSpcArg,
  138. Size,
  139. NULL,
  140. 0);
  141. free(pSpcArg);
  142. }
  143. status = DfsCreateSpcArg(
  144. DomainNameDns,
  145. 0,
  146. 0,
  147. TRUST_DIRECTION_BIDIRECTIONAL,
  148. TRUST_TYPE_UPLEVEL,
  149. -1,
  150. NULL,
  151. &pSpcArg,
  152. &Size);
  153. if (status == ERROR_SUCCESS) {
  154. status = NtFsControlFile(
  155. dfsHandle,
  156. NULL, // Event,
  157. NULL, // ApcRoutine,
  158. NULL, // ApcContext,
  159. &ioStatus,
  160. FSCTL_DFS_CREATE_SPECIAL_INFO,
  161. pSpcArg,
  162. Size,
  163. NULL,
  164. 0);
  165. #if DBG
  166. if (DfsSvcVerbose)
  167. DbgPrint("NtFsControlFile(FSCTL_DFS_CREATE_SPECIAL_INFO) returned 0x%x\n",
  168. status);
  169. #endif
  170. free(pSpcArg);
  171. }
  172. }
  173. if (dfsHandle != NULL) {
  174. NtClose( dfsHandle);
  175. }
  176. #if DBG
  177. if (DfsSvcVerbose)
  178. DbgPrint("DfsInitOurDomainDCs returning 0x%x\n", status);
  179. #endif
  180. DFSSVC_TRACE_LOW(DEFAULT, DfsInitOurDomainDCs_Exit, LOGSTATUS(status));
  181. return( status );
  182. }
  183. NTSTATUS
  184. DfsInitRemainingDomainDCs(VOID)
  185. {
  186. NTSTATUS status;
  187. HANDLE dfsHandle = NULL;
  188. IO_STATUS_BLOCK ioStatus;
  189. ULONG cDom;
  190. PDFS_CREATE_SPECIAL_INFO_ARG pSpcArg;
  191. ULONG Size;
  192. #if DBG
  193. if (DfsSvcVerbose)
  194. DbgPrint("DfsInitRemainingDomainDCs()\n");
  195. #endif
  196. if (DfsDomainInfo.cDomains == 0) {
  197. return STATUS_SUCCESS;
  198. }
  199. status = DfsOpen(&dfsHandle, NULL);
  200. if (NT_SUCCESS(status)) {
  201. for (cDom = 0; cDom < DfsDomainInfo.cDomains; cDom++) {
  202. #if DBG
  203. if (DfsSvcVerbose)
  204. DbgPrint("Trusted domain %ws/%ws\n",
  205. DfsDomainInfo.rgustrDomains[cDom].DnsName.Buffer,
  206. DfsDomainInfo.rgustrDomains[cDom].FlatName.Buffer);
  207. #endif
  208. status = DfsCreateSpcArg(
  209. DfsDomainInfo.rgustrDomains[cDom].FlatName.Buffer,
  210. 0,
  211. DFS_SPECIAL_INFO_NETBIOS,
  212. DfsDomainInfo.rgustrDomains[cDom].TrustDirection,
  213. DfsDomainInfo.rgustrDomains[cDom].TrustType,
  214. -1,
  215. NULL,
  216. &pSpcArg,
  217. &Size);
  218. if (status == ERROR_SUCCESS) {
  219. status = NtFsControlFile(
  220. dfsHandle,
  221. NULL, // Event,
  222. NULL, // ApcRoutine,
  223. NULL, // ApcContext,
  224. &ioStatus,
  225. FSCTL_DFS_CREATE_SPECIAL_INFO,
  226. pSpcArg,
  227. Size,
  228. NULL,
  229. 0);
  230. DFSSVC_TRACE_ERROR_HIGH(status, ALL_ERROR, DfsInitRemainingDomainDCs_Error_NtFsControlFile,
  231. LOGSTATUS(status));
  232. free(pSpcArg);
  233. }
  234. status = DfsCreateSpcArg(
  235. DfsDomainInfo.rgustrDomains[cDom].DnsName.Buffer,
  236. 0,
  237. 0,
  238. DfsDomainInfo.rgustrDomains[cDom].TrustDirection,
  239. DfsDomainInfo.rgustrDomains[cDom].TrustType,
  240. -1,
  241. NULL,
  242. &pSpcArg,
  243. &Size);
  244. if (status == ERROR_SUCCESS) {
  245. status = NtFsControlFile(
  246. dfsHandle,
  247. NULL, // Event,
  248. NULL, // ApcRoutine,
  249. NULL, // ApcContext,
  250. &ioStatus,
  251. FSCTL_DFS_CREATE_SPECIAL_INFO,
  252. pSpcArg,
  253. Size,
  254. NULL,
  255. 0);
  256. DFSSVC_TRACE_ERROR_HIGH(status, ALL_ERROR,
  257. DfsInitRemainingDomainDCs_Error_NtFsControlFile2,
  258. LOGSTATUS(status));
  259. free(pSpcArg);
  260. }
  261. }
  262. }
  263. if (dfsHandle != NULL) {
  264. NtClose( dfsHandle);
  265. }
  266. #if DBG
  267. if (DfsSvcVerbose)
  268. DbgPrint("DfsInitRemainingDomainDCs returning 0x%x\n", status);
  269. #endif
  270. return( status );
  271. }
  272. NTSTATUS
  273. _DfsGetTrustedDomainDCs(
  274. LPWSTR LpcDomainName,
  275. ULONG Flags)
  276. {
  277. NTSTATUS status;
  278. DWORD dwErr;
  279. HANDLE dfsHandle = NULL;
  280. HANDLE hDs = NULL;
  281. IO_STATUS_BLOCK ioStatus;
  282. ULONG i, j;
  283. PDFS_CREATE_SPECIAL_INFO_ARG pSpcArg;
  284. ULONG NameCount = 0;
  285. ULONG NT5Count = 0;
  286. ULONG Size;
  287. ULONG Timeout = 10 * 60;
  288. ULONG TrustDirection;
  289. ULONG TrustType;
  290. ULONG cDom;
  291. PDS_DOMAIN_CONTROLLER_INFO_1 pDsDomainControllerInfo1 = NULL;
  292. PUNICODE_STRING pustrDCNames = NULL;
  293. UNICODE_STRING ustrSiteName;
  294. PDFS_CREATE_SITE_INFO_ARG pSiteArg;
  295. LPWSTR Name = NULL;
  296. WCHAR DnsDomName[MAX_PATH];
  297. UNICODE_STRING uDomainName;
  298. UNICODE_STRING uDomainNameDns;
  299. UNICODE_STRING uLpcDomainName;
  300. #if DBG
  301. if (DfsSvcVerbose)
  302. DbgPrint("DfsGetTrustedDomainDCs(%ws)\n", LpcDomainName);
  303. #endif
  304. EnterCriticalSection(&DomListCritSection);
  305. RtlInitUnicodeString(&uDomainName, DomainName);
  306. RtlInitUnicodeString(&uDomainNameDns, DomainNameDns);
  307. RtlInitUnicodeString(&uLpcDomainName, LpcDomainName);
  308. #if DBG
  309. if (DfsSvcVerbose)
  310. DbgPrint("Comparing [%wZ/%wZ] to [%wZ]\n",
  311. &uDomainName,
  312. &uDomainNameDns,
  313. &uLpcDomainName);
  314. #endif
  315. if (RtlCompareUnicodeString(&uDomainName, &uLpcDomainName, TRUE) == 0
  316. ||
  317. RtlCompareUnicodeString(&uDomainNameDns, &uLpcDomainName, TRUE) == 0
  318. ) {
  319. if (wcslen(DomainNameDns) <= MAX_PATH) {
  320. wcscpy(DnsDomName, DomainNameDns);
  321. TrustDirection = TRUST_DIRECTION_BIDIRECTIONAL;
  322. TrustType = TRUST_TYPE_UPLEVEL;
  323. } else {
  324. status = ERROR_NOT_ENOUGH_MEMORY;
  325. LeaveCriticalSection(&DomListCritSection);
  326. goto exit_with_status;
  327. }
  328. } else {
  329. for (cDom = 0; cDom < DfsDomainInfo.cDomains; cDom++) {
  330. RtlInitUnicodeString(&uLpcDomainName, LpcDomainName);
  331. #if DBG
  332. if (DfsSvcVerbose)
  333. DbgPrint("Comparing [%wZ/%wZ] to [%wZ]\n",
  334. &DfsDomainInfo.rgustrDomains[cDom].FlatName,
  335. &DfsDomainInfo.rgustrDomains[cDom].DnsName,
  336. &uLpcDomainName);
  337. #endif
  338. if (RtlCompareUnicodeString(
  339. &DfsDomainInfo.rgustrDomains[cDom].FlatName,
  340. &uLpcDomainName,
  341. TRUE) == 0
  342. ||
  343. RtlCompareUnicodeString(
  344. &DfsDomainInfo.rgustrDomains[cDom].DnsName,
  345. &uLpcDomainName,
  346. TRUE) == 0
  347. ) {
  348. break;
  349. }
  350. }
  351. if (cDom >= DfsDomainInfo.cDomains) {
  352. status = STATUS_OBJECT_NAME_NOT_FOUND;
  353. LeaveCriticalSection(&DomListCritSection);
  354. goto exit_with_status;
  355. }
  356. if (DfsDomainInfo.rgustrDomains[cDom].DnsName.Length/sizeof(WCHAR) <= MAX_PATH) {
  357. wcscpy(DnsDomName, DfsDomainInfo.rgustrDomains[cDom].DnsName.Buffer);
  358. TrustDirection = DfsDomainInfo.rgustrDomains[cDom].TrustDirection;
  359. TrustType = DfsDomainInfo.rgustrDomains[cDom].TrustType;
  360. } else {
  361. status = ERROR_NOT_ENOUGH_MEMORY;
  362. LeaveCriticalSection(&DomListCritSection);
  363. goto exit_with_status;
  364. }
  365. }
  366. LeaveCriticalSection(&DomListCritSection);
  367. status = DfsOpen(&dfsHandle, NULL);
  368. if (NT_SUCCESS(status)) {
  369. dwErr = DsBind(NULL, DnsDomName, &hDs);
  370. if (dwErr == NO_ERROR) {
  371. //
  372. // get DC list for that domain
  373. //
  374. dwErr = DsGetDomainControllerInfo(
  375. hDs,
  376. DnsDomName,
  377. 1,
  378. &NameCount,
  379. &pDsDomainControllerInfo1);
  380. #if DBG
  381. if (DfsSvcVerbose)
  382. DbgPrint("DsGetDomainControllerInfo(%ws) returned %d\n",
  383. DnsDomName,
  384. dwErr);
  385. #endif
  386. if (dwErr == NO_ERROR && pDsDomainControllerInfo1 != NULL) {
  387. //
  388. // Load Site info
  389. //
  390. #if DBG
  391. if (DfsSvcVerbose)
  392. DbgPrint("NameCount=%d\n", NameCount);
  393. #endif
  394. for (i = 0; i < NameCount; i++) {
  395. Name = (Flags & DFS_SPECIAL_INFO_NETBIOS) != 0 ?
  396. pDsDomainControllerInfo1[i].NetbiosName :
  397. pDsDomainControllerInfo1[i].DnsHostName;
  398. if (pDsDomainControllerInfo1[i].fDsEnabled == TRUE &&
  399. Name != NULL &&
  400. pDsDomainControllerInfo1[i].SiteName != NULL) {
  401. RtlInitUnicodeString(
  402. &ustrSiteName,
  403. pDsDomainControllerInfo1[i].SiteName);
  404. #if DBG
  405. if (DfsSvcVerbose)
  406. DbgPrint("%ws is in site %ws\n",
  407. Name,
  408. pDsDomainControllerInfo1[i].SiteName);
  409. #endif
  410. dwErr = DfsCreateSiteArg(
  411. Name,
  412. 1,
  413. &ustrSiteName,
  414. &pSiteArg,
  415. &Size);
  416. if ( dwErr != NO_ERROR) {
  417. status = ERROR_NOT_ENOUGH_MEMORY;
  418. goto exit_with_status;
  419. }
  420. NtFsControlFile(
  421. dfsHandle,
  422. NULL,
  423. NULL,
  424. NULL,
  425. &ioStatus,
  426. FSCTL_DFS_CREATE_SITE_INFO,
  427. pSiteArg,
  428. Size,
  429. NULL,
  430. 0);
  431. free(pSiteArg);
  432. }
  433. }
  434. //
  435. // Convert to an array of UNICODE_STRINGS, taking only the NT5 DC's
  436. //
  437. for (i = NT5Count = 0; i < NameCount; i++) {
  438. if (pDsDomainControllerInfo1[i].fDsEnabled == TRUE) {
  439. NT5Count++;
  440. }
  441. }
  442. if (NT5Count > 0) {
  443. pustrDCNames = malloc(sizeof(UNICODE_STRING) * NT5Count);
  444. if (pustrDCNames == NULL) {
  445. status = ERROR_NOT_ENOUGH_MEMORY;
  446. goto exit_with_status;
  447. }
  448. for (i = j = 0; i < NameCount; i++) {
  449. Name = (Flags & DFS_SPECIAL_INFO_NETBIOS) != 0 ?
  450. pDsDomainControllerInfo1[i].NetbiosName :
  451. pDsDomainControllerInfo1[i].DnsHostName;
  452. if (pDsDomainControllerInfo1[i].fDsEnabled == TRUE && Name != NULL) {
  453. RtlInitUnicodeString(
  454. &pustrDCNames[j],
  455. Name);
  456. j++;
  457. }
  458. }
  459. }
  460. #if DBG
  461. if (DfsSvcVerbose) {
  462. DbgPrint("DFSINIT:%ws=", LpcDomainName);
  463. for (i = 0; i < j; i++) {
  464. DbgPrint("%wZ ", &pustrDCNames[i]);
  465. }
  466. DbgPrint("\n");
  467. DbgPrint("Our domain has %d DC's\n", j);
  468. }
  469. #endif
  470. status = DfsCreateSpcArg(
  471. LpcDomainName,
  472. Timeout,
  473. Flags,
  474. TrustDirection,
  475. TrustType,
  476. j,
  477. pustrDCNames,
  478. &pSpcArg,
  479. &Size);
  480. if (status == ERROR_SUCCESS) {
  481. status = NtFsControlFile(
  482. dfsHandle,
  483. NULL, // Event,
  484. NULL, // ApcRoutine,
  485. NULL, // ApcContext,
  486. &ioStatus,
  487. FSCTL_DFS_CREATE_SPECIAL_INFO,
  488. pSpcArg,
  489. Size,
  490. NULL,
  491. 0);
  492. free(pSpcArg);
  493. }
  494. if (pustrDCNames != NULL) {
  495. free(pustrDCNames);
  496. pustrDCNames = NULL;
  497. }
  498. }
  499. } else {
  500. status = STATUS_DS_UNAVAILABLE;
  501. }
  502. }
  503. exit_with_status:
  504. if (dfsHandle != NULL) {
  505. NtClose( dfsHandle);
  506. }
  507. if (pDsDomainControllerInfo1 != NULL) {
  508. DsFreeDomainControllerInfo(
  509. 1,
  510. NameCount,
  511. pDsDomainControllerInfo1);
  512. }
  513. if (pustrDCNames != NULL) {
  514. free(pustrDCNames);
  515. }
  516. if (hDs != NULL) {
  517. DsUnBind(&hDs);
  518. }
  519. #if DBG
  520. if (DfsSvcVerbose)
  521. DbgPrint("DfsGetTrustedDomainDCs returning 0x%x\n", status);
  522. #endif
  523. return( status );
  524. }
  525. #define MAX_SPC_LONG_NAME_SIZE 2048
  526. NTSTATUS
  527. DfsGetTrustedDomainDCs(
  528. LPWSTR LpcDomainName,
  529. ULONG Flags)
  530. {
  531. LPWSTR NewDomainName = NULL;
  532. NTSTATUS Status = STATUS_SUCCESS;
  533. if ((LpcDomainName != NULL) &&
  534. (*LpcDomainName != 0)) {
  535. return _DfsGetTrustedDomainDCs(LpcDomainName, Flags);
  536. }
  537. NewDomainName = malloc(MAX_SPC_LONG_NAME_SIZE);
  538. if (NewDomainName == NULL) {
  539. return STATUS_INSUFFICIENT_RESOURCES;
  540. }
  541. while (DfsGetNextDomainName(NewDomainName, MAX_SPC_LONG_NAME_SIZE) == TRUE) {
  542. Status = _DfsGetTrustedDomainDCs(NewDomainName, Flags);
  543. }
  544. free(NewDomainName);
  545. return Status;
  546. }
  547. DWORD
  548. DfsCreateSpcArg(
  549. LPWSTR SpecialName,
  550. ULONG Timeout,
  551. ULONG Flags,
  552. ULONG TrustDirection,
  553. ULONG TrustType,
  554. LONG NameCount,
  555. PUNICODE_STRING pustrDCNames,
  556. PDFS_CREATE_SPECIAL_INFO_ARG *ppSpcArg,
  557. PULONG pSize)
  558. {
  559. ULONG Size;
  560. PDFS_CREATE_SPECIAL_INFO_ARG pSpcArg;
  561. PUNICODE_STRING ustrp;
  562. WCHAR *wCp;
  563. LONG i;
  564. LONG j;
  565. DWORD status = STATUS_SUCCESS;
  566. UNICODE_STRING ComputerNetbiosName;
  567. UNICODE_STRING ComputerDnsName;
  568. ULONG ComputerNameSize;
  569. BOOL bStatus;
  570. WCHAR NetBIOSBuffer[MAX_COMPUTERNAME_LENGTH + 1];
  571. RtlInitUnicodeString(&ComputerNetbiosName, NULL);
  572. RtlInitUnicodeString(&ComputerDnsName, NULL);
  573. ComputerNetbiosName.Buffer = NetBIOSBuffer;
  574. ComputerNetbiosName.MaximumLength = (MAX_COMPUTERNAME_LENGTH + 1) * sizeof(WCHAR);
  575. ComputerNameSize = MAX_COMPUTERNAME_LENGTH + 1;
  576. if (GetComputerNameEx(ComputerNameNetBIOS,
  577. ComputerNetbiosName.Buffer,
  578. &ComputerNameSize)) {
  579. ComputerNetbiosName.Length = (USHORT)(ComputerNameSize - 1) * sizeof(WCHAR);
  580. }
  581. ComputerNameSize = 0;
  582. while( TRUE ) {
  583. bStatus = GetComputerNameEx( ComputerNameDnsFullyQualified,
  584. ComputerDnsName.Buffer,
  585. &ComputerNameSize );
  586. if( bStatus == TRUE ) {
  587. ComputerDnsName.Length = (USHORT)(ComputerNameSize - 1) * sizeof(WCHAR);
  588. break;
  589. }
  590. if( GetLastError() == ERROR_MORE_DATA ) {
  591. if( ComputerDnsName.Buffer != NULL ) {
  592. free( ComputerDnsName.Buffer );
  593. }
  594. ComputerDnsName.Buffer = malloc( ComputerNameSize * sizeof(WCHAR) );
  595. if( ComputerDnsName.Buffer == NULL ) {
  596. ComputerDnsName.MaximumLength = 0;
  597. break;
  598. }
  599. ComputerDnsName.MaximumLength = (USHORT)ComputerNameSize * sizeof(WCHAR);
  600. } else {
  601. break;
  602. }
  603. }
  604. #if DBG
  605. if (DfsSvcVerbose) {
  606. DbgPrint("DfsCreateSpcArg(SpecialName=%ws,Timeout=%d,Flags=0x%x,NameCount=%d)\n",
  607. SpecialName,
  608. Timeout,
  609. Flags,
  610. NameCount);
  611. for (i = 0; i < NameCount; i++) {
  612. DbgPrint(" Name[%d]:%wZ\n", i, &pustrDCNames[i]);
  613. }
  614. }
  615. #endif
  616. //
  617. // Size the buffer
  618. //
  619. if (NameCount > 0) {
  620. Size = FIELD_OFFSET(DFS_CREATE_SPECIAL_INFO_ARG,Name[NameCount]) +
  621. wcslen(SpecialName) * sizeof(WCHAR);
  622. for (i = 0; i < NameCount; i++) {
  623. Size += pustrDCNames[i].Length;
  624. }
  625. } else {
  626. Size = sizeof(DFS_CREATE_SPECIAL_INFO_ARG) +
  627. wcslen(SpecialName) * sizeof(WCHAR);
  628. }
  629. pSpcArg = malloc(Size);
  630. if (pSpcArg != NULL) {
  631. ZeroMemory(pSpcArg, Size);
  632. // Marshall the info in
  633. pSpcArg->NameCount = NameCount;
  634. pSpcArg->Flags = Flags;
  635. pSpcArg->TrustDirection = TrustDirection;
  636. pSpcArg->TrustType = TrustType;
  637. pSpcArg->Timeout = Timeout;
  638. wCp = (WCHAR *) &pSpcArg->Name[NameCount < 0 ? 0 : NameCount];
  639. ustrp = &pSpcArg->SpecialName;
  640. ustrp->Buffer = wCp;
  641. ustrp->Length = ustrp->MaximumLength = wcslen(SpecialName) * sizeof(WCHAR);
  642. RtlCopyMemory(ustrp->Buffer, SpecialName, ustrp->Length);
  643. wCp += ustrp->Length / sizeof(WCHAR);
  644. for (i = 0; i < NameCount; i++) {
  645. BOOLEAN foundDc = FALSE;
  646. ustrp = &pSpcArg->Name[i];
  647. ustrp->Buffer = wCp;
  648. ustrp->Length = ustrp->MaximumLength = pustrDCNames[i].Length;
  649. RtlCopyMemory(ustrp->Buffer, pustrDCNames[i].Buffer, ustrp->Length);
  650. wCp += ustrp->Length / sizeof(WCHAR);
  651. if (!foundDc) {
  652. if ((ComputerNetbiosName.Length != 0) &&
  653. (RtlCompareUnicodeString(&ComputerNetbiosName,
  654. &pustrDCNames[i],
  655. TRUE) == 0)) {
  656. foundDc = TRUE;
  657. }
  658. else if ((ComputerDnsName.Length != 0) &&
  659. (RtlCompareUnicodeString(&ComputerDnsName,
  660. &pustrDCNames[i],
  661. TRUE) == 0)) {
  662. foundDc = TRUE;
  663. }
  664. if ((foundDc == TRUE) && (i != 0)) {
  665. UNICODE_STRING Tmp;
  666. Tmp = *ustrp;
  667. *ustrp = pSpcArg->Name[0];
  668. pSpcArg->Name[0] = Tmp;
  669. }
  670. }
  671. }
  672. POINTER_TO_OFFSET(pSpcArg->SpecialName.Buffer, pSpcArg);
  673. for (i = 0; i < NameCount; i++) {
  674. POINTER_TO_OFFSET(pSpcArg->Name[i].Buffer, pSpcArg);
  675. }
  676. *ppSpcArg = pSpcArg;
  677. *pSize = Size;
  678. } else {
  679. status = ERROR_NOT_ENOUGH_MEMORY;
  680. }
  681. if( ComputerDnsName.Buffer != NULL ) {
  682. free( ComputerDnsName.Buffer );
  683. }
  684. return status;
  685. }
  686. DWORD
  687. DfsCreateSiteArg(
  688. LPWSTR ServerName,
  689. ULONG SiteCount,
  690. PUNICODE_STRING pustrSiteNames,
  691. PDFS_CREATE_SITE_INFO_ARG *ppSiteArg,
  692. PULONG pSize)
  693. {
  694. ULONG i;
  695. ULONG Size;
  696. WCHAR *wCp;
  697. PUNICODE_STRING ustrp;
  698. PDFS_CREATE_SITE_INFO_ARG pSiteArg;
  699. DWORD status = STATUS_SUCCESS;
  700. DFSSVC_TRACE_NORM(DEFAULT, DfsCreateSiteArg_Entry,
  701. LOGWSTR_CHK(ServerName)
  702. LOGULONG(SiteCount)
  703. LOGUSTR(*pustrSiteNames));
  704. // Size the buffer
  705. Size = FIELD_OFFSET(DFS_CREATE_SITE_INFO_ARG,SiteName[SiteCount]) +
  706. wcslen(ServerName) * sizeof(WCHAR);
  707. for (i = 0; i < SiteCount; i++)
  708. Size += pustrSiteNames[i].Length;
  709. pSiteArg = malloc(Size);
  710. if (pSiteArg != NULL) {
  711. // Marshall the info in
  712. pSiteArg->SiteCount = SiteCount;
  713. wCp = (WCHAR *) &pSiteArg->SiteName[SiteCount];
  714. ustrp = &pSiteArg->ServerName;
  715. ustrp->Buffer = wCp;
  716. ustrp->Length = ustrp->MaximumLength = wcslen(ServerName) * sizeof(WCHAR);
  717. RtlCopyMemory(ustrp->Buffer,ServerName,ustrp->Length);
  718. wCp += ustrp->Length / sizeof(WCHAR);
  719. for (i = 0; i < SiteCount; i++) {
  720. ustrp = &pSiteArg->SiteName[i];
  721. ustrp->Buffer = wCp;
  722. ustrp->Length = ustrp->MaximumLength = pustrSiteNames[i].Length;
  723. RtlCopyMemory(ustrp->Buffer,pustrSiteNames[i].Buffer,ustrp->Length);
  724. wCp += ustrp->Length / sizeof(WCHAR);
  725. }
  726. POINTER_TO_OFFSET(pSiteArg->ServerName.Buffer, pSiteArg);
  727. for (i = 0; i < SiteCount; i++) {
  728. POINTER_TO_OFFSET(pSiteArg->SiteName[i].Buffer, pSiteArg);
  729. }
  730. *ppSiteArg = pSiteArg;
  731. *pSize = Size;
  732. } else {
  733. status = ERROR_NOT_ENOUGH_MEMORY;
  734. }
  735. DFSSVC_TRACE_NORM(DEFAULT, DfsCreateSiteArg_Exit,
  736. LOGSTATUS(status)
  737. LOGWSTR_CHK(ServerName)
  738. LOGULONG(SiteCount)
  739. LOGUSTR(*pustrSiteNames));
  740. return status;
  741. }
  742. NTSTATUS
  743. DfsDomainReferral(
  744. LPWSTR wszDomain,
  745. LPWSTR wszShare)
  746. {
  747. NTSTATUS Status;
  748. DWORD dwErr;
  749. LPWSTR *List = NULL;
  750. PUNICODE_STRING pustr;
  751. HANDLE dfsHandle;
  752. IO_STATUS_BLOCK ioStatus;
  753. ULONG Count;
  754. ULONG Size;
  755. PDFS_CREATE_SPECIAL_INFO_ARG pSpcArg;
  756. ULONG i;
  757. DFSSVC_TRACE_HIGH(DEFAULT,DfsDomainReferral_Entry,
  758. LOGWSTR_CHK(wszDomain)
  759. LOGWSTR_CHK(wszShare));
  760. #if DBG
  761. if (DfsSvcVerbose) {
  762. DbgPrint("DfsDomainReferral()\n", 0);
  763. DbgPrint("\twszDomain:%ws\n", wszDomain);
  764. DbgPrint("\twszShare:%ws\n", wszShare);
  765. }
  766. #endif
  767. dwErr = DfsGetFtServersFromDs(pLdap, wszDomain, wszShare, &List);
  768. if (dwErr != NO_ERROR || List == NULL) {
  769. Status = STATUS_OBJECT_NAME_NOT_FOUND;
  770. } else {
  771. for (Count = 0; List[Count]; Count++)
  772. /* NOTHING */;
  773. pustr = malloc(sizeof(UNICODE_STRING) * Count);
  774. if (pustr != NULL) {
  775. for (i = 0; i < Count; i++) {
  776. RtlInitUnicodeString(&pustr[i], List[i]);
  777. if (pustr[i].Buffer[0] == L'\\') {
  778. pustr[i].Buffer++;
  779. pustr[i].Length -= sizeof(WCHAR);
  780. pustr[i].MaximumLength -= sizeof(WCHAR);
  781. }
  782. }
  783. Status = DfsCreateSpcArg(
  784. wszShare,
  785. 60 * 15, // 15 min
  786. DFS_SPECIAL_INFO_PRIMARY,
  787. 0,
  788. 0,
  789. Count,
  790. pustr,
  791. &pSpcArg,
  792. &Size);
  793. if (Status == ERROR_SUCCESS) {
  794. Status = DfsOpen(&dfsHandle, NULL);
  795. if (NT_SUCCESS(Status)) {
  796. NtFsControlFile(
  797. dfsHandle,
  798. NULL, // Event,
  799. NULL, // ApcRoutine,
  800. NULL, // ApcContext,
  801. &ioStatus,
  802. FSCTL_DFS_CREATE_FTDFS_INFO,
  803. pSpcArg,
  804. Size,
  805. NULL,
  806. 0);
  807. NtClose( dfsHandle);
  808. }
  809. //
  810. // Rummage through the DS, loading the site info for the
  811. // machines we found.
  812. //
  813. if (NT_SUCCESS(Status)) {
  814. DfsLoadSiteTableFromDs(
  815. pLdap,
  816. wszShare,
  817. Count,
  818. pustr);
  819. }
  820. free(pSpcArg);
  821. }
  822. free(pustr);
  823. }
  824. NetApiBufferFree(List);
  825. }
  826. #if DBG
  827. if (DfsSvcVerbose)
  828. DbgPrint("DfsDomainReferral exit 0x%x\n", Status);
  829. #endif
  830. return Status;
  831. }
  832. BOOLEAN
  833. DfsGetNextDomainName(
  834. LPWSTR DomName,
  835. ULONG Size)
  836. {
  837. HANDLE dfsHandle;
  838. IO_STATUS_BLOCK ioStatus;
  839. NTSTATUS Status;
  840. Status = DfsOpen(&dfsHandle, NULL);
  841. if (NT_SUCCESS(Status)) {
  842. Status = NtFsControlFile(
  843. dfsHandle,
  844. NULL, // Event,
  845. NULL, // ApcRoutine,
  846. NULL, // ApcContext,
  847. &ioStatus,
  848. FSCTL_DFS_GET_NEXT_LONG_DOMAIN_NAME,
  849. NULL,
  850. 0,
  851. DomName,
  852. Size);
  853. NtClose( dfsHandle);
  854. }
  855. return (Status == STATUS_SUCCESS) ? TRUE : FALSE;
  856. }