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.

1325 lines
38 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <stddef.h>
  8. #include <lm.h>
  9. #include <lmdfs.h>
  10. #include <netdfs.h>
  11. #include <DfsServerLibrary.hxx>
  12. #include <validc.h>
  13. #include "ReferralServerLog.hxx"
  14. //
  15. // logging specific includes
  16. //
  17. #include "apisupport.tmh"
  18. extern ULONG Flags;
  19. CRITICAL_SECTION DfsApiLock;
  20. BOOL DfsLockInitialized = FALSE;
  21. BOOL ServerListen = FALSE;
  22. #define DFS_API_START() \
  23. EnterCriticalSection( &DfsApiLock ); \
  24. _try \
  25. {
  26. #define DFS_API_END() \
  27. } _finally { \
  28. LeaveCriticalSection( &DfsApiLock); \
  29. }
  30. extern
  31. DFSSTATUS
  32. DfsEnum(
  33. IN LPWSTR DfsName,
  34. IN DWORD Level,
  35. IN DWORD PrefMaxLen,
  36. OUT LPBYTE *pBuffer,
  37. OUT LPDWORD pEntriesRead,
  38. IN OUT LPDWORD pResumeHandle);
  39. NET_API_STATUS
  40. DfsEnumEx(
  41. IN LPWSTR DfsName,
  42. IN DWORD Level,
  43. IN DWORD PrefMaxLen,
  44. IN OUT LPDFS_INFO_ENUM_STRUCT pDfsEnum,
  45. IN OUT LPDWORD pResumeHandle);
  46. //+----------------------------------------------------------------------------
  47. //
  48. // Function: NetrDfsManagerGetVersion
  49. //
  50. // Synopsis: Returns the version of this server side implementation.
  51. //
  52. // Arguments: None.
  53. //
  54. // Returns: The version number.
  55. //
  56. //-----------------------------------------------------------------------------
  57. DWORD
  58. NetrDfsManagerGetVersion()
  59. {
  60. DWORD Version = 4;
  61. return( Version );
  62. }
  63. //+----------------------------------------------------------------------------
  64. //
  65. // Function: NetrDfsAdd
  66. // Synopsis:
  67. //
  68. // Arguments: [DfsEntryPath] -- Entry Path of volume/link to be created, or
  69. // to which a replica should be added.
  70. // [ServerName] -- Name of server backing the volume.
  71. // [ShareName] -- Name of share on ServerName backing the volume.
  72. // [Comment] -- Comment associated with this volume, only used
  73. // when DFS_ADD_VOLUME is specified.
  74. // [Flags] -- If DFS_ADD_VOLUME, a new volume will be created.
  75. // If DFS_ADD_LINK, a new link to another Dfs will be
  76. // create. If 0, a replica will be added.
  77. //
  78. // Returns: [NERR_Success] -- Operation succeeded.
  79. //
  80. // Error other wise.
  81. //
  82. //-----------------------------------------------------------------------------
  83. extern "C" NET_API_STATUS
  84. NetrDfsAdd(
  85. IN LPWSTR DfsEntryPath,
  86. IN LPWSTR ServerName,
  87. IN LPWSTR ShareName,
  88. IN LPWSTR Comment,
  89. IN DWORD Flags)
  90. {
  91. NET_API_STATUS Status = ERROR_SUCCESS;
  92. DFS_TRACE_HIGH( API, "Net Dfs Add %ws %ws %ws\n", DfsEntryPath, ServerName, ShareName);
  93. DFS_API_START();
  94. Status = AccessImpersonateCheckRpcClient();
  95. if (Status == ERROR_SUCCESS)
  96. {
  97. Status = DfsAdd( DfsEntryPath,
  98. ServerName,
  99. ShareName,
  100. Comment,
  101. Flags );
  102. }
  103. DFS_API_END();
  104. DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Add %ws, Status 0x%x\n", DfsEntryPath, Status);
  105. return Status;
  106. }
  107. //+----------------------------------------------------------------------------
  108. //
  109. // Function: NetrDfsAdd2
  110. //
  111. // Synopsis: Adds a volume/replica/link to this Dfs.
  112. //
  113. // Arguments: [DfsEntryPath] -- Entry Path of volume/link to be created, or
  114. // to which a replica should be added.
  115. // [DcName] -- Name of Dc to use
  116. // [ServerName] -- Name of server backing the volume.
  117. // [ShareName] -- Name of share on ServerName backing the volume.
  118. // [Comment] -- Comment associated with this volume, only used
  119. // when DFS_ADD_VOLUME is specified.
  120. // [Flags] -- If DFS_ADD_VOLUME, a new volume will be created.
  121. // If DFS_ADD_LINK, a new link to another Dfs will be
  122. // create. If 0, a replica will be added.
  123. // [ppRootList] -- On success, returns a list of roots that need to be
  124. // informed of the change in the DS object
  125. //
  126. // Returns: [NERR_Success] -- Operation succeeded.
  127. //
  128. // Erroroce otherwise.
  129. //
  130. //-----------------------------------------------------------------------------
  131. extern "C" NET_API_STATUS
  132. NetrDfsAdd2(
  133. IN LPWSTR DfsEntryPath,
  134. IN LPWSTR DcName,
  135. IN LPWSTR ServerName,
  136. IN LPWSTR ShareName,
  137. IN LPWSTR Comment,
  138. IN DWORD Flags,
  139. IN PDFSM_ROOT_LIST *ppRootList)
  140. {
  141. NET_API_STATUS Status = ERROR_SUCCESS;
  142. DFS_TRACE_HIGH( API, "Net Dfs Add2 %ws DC:%ws Server:%ws Share:%ws\n", DfsEntryPath, DcName, ServerName, ShareName);
  143. DFS_API_START();
  144. //
  145. // For now, we dont use DC name or pprootlist. We will use
  146. // this once we implement domain dfs.
  147. //
  148. UNREFERENCED_PARAMETER( DcName );
  149. UNREFERENCED_PARAMETER( ppRootList );
  150. Status = AccessImpersonateCheckRpcClient();
  151. if (Status == ERROR_SUCCESS)
  152. {
  153. Status = DfsAdd( DfsEntryPath,
  154. ServerName,
  155. ShareName,
  156. Comment,
  157. Flags );
  158. }
  159. DFS_API_END();
  160. DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Add2 %ws, Status 0x%x\n", DfsEntryPath, Status);
  161. return Status;
  162. }
  163. //+----------------------------------------------------------------------------
  164. //
  165. // Function: NetrDfsGetDcAddress
  166. //
  167. // Synopsis: Gets the DC to go to so that we can create an FtDfs object for
  168. // this server.
  169. //
  170. // Arguments: [ServerName] -- Name of server backing the volume.
  171. // [DcName] -- Dc to use
  172. // [IsRoot] -- TRUE if this server is a Dfs root, FALSE otherwise
  173. // [Timeout] -- Timeout, in sec, that the server will stay with this DC
  174. //
  175. // Returns: [NERR_Success] -- Operation succeeded.
  176. //
  177. //
  178. //-----------------------------------------------------------------------------
  179. extern "C" NET_API_STATUS
  180. NetrDfsGetDcAddress(
  181. IN LPWSTR ServerName,
  182. IN OUT LPWSTR *DcName,
  183. IN OUT BOOLEAN *IsRoot,
  184. IN OUT ULONG *Timeout)
  185. {
  186. NET_API_STATUS Status = ERROR_SUCCESS;
  187. UNREFERENCED_PARAMETER(ServerName);
  188. //
  189. // Currently, not supported
  190. //
  191. if(DcName == NULL)
  192. {
  193. Status = ERROR_INVALID_PARAMETER;
  194. return Status;
  195. }
  196. *DcName = (LPWSTR)MIDL_user_allocate(4);
  197. if (*DcName == NULL)
  198. {
  199. Status = ERROR_NOT_ENOUGH_MEMORY;
  200. }
  201. else
  202. {
  203. (*DcName)[0] = L' ';
  204. (*DcName)[1] = 0;
  205. }
  206. if(IsRoot)
  207. {
  208. *IsRoot = FALSE;
  209. }
  210. if(Timeout)
  211. {
  212. *Timeout = 1000;
  213. }
  214. return Status;
  215. }
  216. //+----------------------------------------------------------------------------
  217. //
  218. // Function: NetrDfsSetDcAddress
  219. //
  220. // Synopsis: Sets the DC to go to for the dfs blob
  221. //
  222. // Arguments: [ServerName] -- Name of server backing the volume.
  223. // [DcName] -- Dc to use
  224. // [Timeout] -- Time, in sec, to stay with that DC
  225. //
  226. // Returns: [NERR_Success] -- Operation succeeded.
  227. //
  228. //
  229. //-----------------------------------------------------------------------------
  230. extern "C" NET_API_STATUS
  231. NetrDfsSetDcAddress(
  232. IN LPWSTR ServerName,
  233. IN LPWSTR DcName,
  234. IN ULONG Timeout,
  235. IN DWORD Flags)
  236. {
  237. UNREFERENCED_PARAMETER(ServerName);
  238. UNREFERENCED_PARAMETER(DcName);
  239. UNREFERENCED_PARAMETER(Timeout);
  240. UNREFERENCED_PARAMETER(Flags);
  241. //
  242. // Currently, not supported
  243. //
  244. return ERROR_SUCCESS;
  245. }
  246. //+----------------------------------------------------------------------------
  247. //
  248. // Function: NetrDfsFlushFtTable
  249. //
  250. // Synopsis: Flushes an FtDfs entry from the FtDfs cache
  251. //
  252. // Arguments: [DcName] -- Dc to use
  253. // [FtDfsName] -- Name of FtDfs
  254. //
  255. // Returns: [NERR_Success] -- Operation succeeded.
  256. //
  257. //
  258. //-----------------------------------------------------------------------------
  259. extern "C" NET_API_STATUS
  260. NetrDfsFlushFtTable(
  261. IN LPWSTR DcName,
  262. IN LPWSTR FtDfsName)
  263. {
  264. UNREFERENCED_PARAMETER(DcName);
  265. UNREFERENCED_PARAMETER(FtDfsName);
  266. //
  267. // This will NEVER be supported.
  268. //
  269. return ERROR_NOT_SUPPORTED;
  270. }
  271. //+----------------------------------------------------------------------------
  272. //
  273. // Function: NetrDfsAddStdRoot
  274. //
  275. // Synopsis: Creates a new Std Dfs
  276. //
  277. // Arguments: [ServerName] -- Name of server backing the volume.
  278. // [RootShare] -- Name of share on ServerName backing the volume.
  279. // [Comment] -- Comment associated with this root.
  280. // [Flags] -- Flags for the operation
  281. //
  282. // Returns: [NERR_Success] -- Operation succeeded.
  283. //
  284. // [NERR_DfsInternalCorruption] -- An internal database
  285. // corruption was encountered while executing this
  286. // operation.
  287. //
  288. // [ERROR_OUTOFMEMORY] -- Out of memory condition.
  289. //
  290. //-----------------------------------------------------------------------------
  291. extern "C" NET_API_STATUS
  292. NetrDfsAddStdRoot(
  293. IN LPWSTR ServerName,
  294. IN LPWSTR RootShare,
  295. IN LPWSTR Comment,
  296. IN DWORD ApiFlags)
  297. {
  298. NET_API_STATUS Status = ERROR_SUCCESS;
  299. DFS_TRACE_HIGH( API, "Net Dfs Add Std Root Server:%ws, Share:%ws\n", ServerName, RootShare);
  300. DFS_API_START();
  301. if (Flags & DFS_LOCAL_NAMESPACE)
  302. {
  303. ServerName = NULL;
  304. }
  305. //
  306. // Add a standalone root.
  307. //
  308. Status = AccessImpersonateCheckRpcClient();
  309. if (Status == ERROR_SUCCESS)
  310. {
  311. Status = DfsAddStandaloneRoot( ServerName,
  312. RootShare,
  313. Comment,
  314. ApiFlags );
  315. }
  316. DFS_API_END();
  317. DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Add Std Root %ws\n", RootShare);
  318. return Status;
  319. }
  320. //+----------------------------------------------------------------------------
  321. //
  322. // Function: NetrDfsAddStdRootForced
  323. //
  324. // Synopsis: Creates a new Std Dfs
  325. //
  326. // Arguments: [ServerName] -- Name of server backing the volume.
  327. // [RootShare] -- Name of share on ServerName backing the volume.
  328. // [Comment] -- Comment associated with this root.
  329. // [Share] -- drive:\dir behind the share
  330. //
  331. // Returns: [NERR_Success] -- Operation succeeded.
  332. //
  333. // [ERROR_OUTOFMEMORY] -- Out of memory condition.
  334. //
  335. //-----------------------------------------------------------------------------
  336. extern "C" NET_API_STATUS
  337. NetrDfsAddStdRootForced(
  338. IN LPWSTR ServerName,
  339. IN LPWSTR RootShare,
  340. IN LPWSTR Comment,
  341. IN LPWSTR Share)
  342. {
  343. UNREFERENCED_PARAMETER(ServerName);
  344. UNREFERENCED_PARAMETER(RootShare);
  345. UNREFERENCED_PARAMETER(Comment);
  346. UNREFERENCED_PARAMETER(Share);
  347. //
  348. // This will probably be never supported.
  349. //
  350. return ERROR_NOT_SUPPORTED;
  351. }
  352. //+----------------------------------------------------------------------------
  353. //
  354. // Function: NetrDfsRemove (Obsolete)
  355. //
  356. // Synopsis: Deletes a volume/replica/link from the Dfs.
  357. //
  358. // Arguments: [DfsEntryPath] -- Entry path of the volume to operate on.
  359. // [ServerName] -- If specified, indicates the replica of the
  360. // volume to operate on.
  361. // [ShareName] -- If specified, indicates the share on the
  362. // server to operate on.
  363. // [Flags] -- Flags for the operation
  364. //
  365. // Returns: [NERR_Success] -- Operation successful.
  366. //
  367. //-----------------------------------------------------------------------------
  368. extern "C" NET_API_STATUS
  369. NetrDfsRemove(
  370. IN LPWSTR DfsEntryPath,
  371. IN LPWSTR ServerName,
  372. IN LPWSTR ShareName)
  373. {
  374. NET_API_STATUS Status = ERROR_SUCCESS;
  375. DFS_TRACE_HIGH( API, "Net Dfs remove %ws\n", DfsEntryPath);
  376. //
  377. // call DfsRemove to do this operation.
  378. //
  379. DFS_API_START();
  380. Status = AccessImpersonateCheckRpcClient();
  381. if (Status == ERROR_SUCCESS)
  382. {
  383. Status = DfsRemove( DfsEntryPath,
  384. ServerName,
  385. ShareName );
  386. }
  387. DFS_API_END( );
  388. DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs remove %ws, Status %x\n", DfsEntryPath, Status);
  389. return Status;
  390. }
  391. //+----------------------------------------------------------------------------
  392. //
  393. // Function: NetrDfsRemove2
  394. //
  395. // Synopsis: Deletes a volume/replica/link from the Dfs.
  396. //
  397. // Arguments: [DfsEntryPath] -- Entry path of the volume to operate on.
  398. // [DcName] -- Name of Dc to use
  399. // [ServerName] -- If specified, indicates the replica of the
  400. // volume to operate on.
  401. // [ShareName] -- If specified, indicates the share on the
  402. // server to operate on.
  403. // [Flags] -- Flags for the operation
  404. // [ppRootList] -- On success, returns a list of roots that need to be
  405. // informed of the change in the DS object
  406. //
  407. // Returns: [NERR_Success] -- Operation successful.
  408. //
  409. //-----------------------------------------------------------------------------
  410. extern "C" NET_API_STATUS
  411. NetrDfsRemove2(
  412. IN LPWSTR DfsEntryPath,
  413. IN LPWSTR DcName,
  414. IN LPWSTR ServerName,
  415. IN LPWSTR ShareName,
  416. IN PDFSM_ROOT_LIST *ppRootList)
  417. {
  418. UNREFERENCED_PARAMETER(DcName);
  419. UNREFERENCED_PARAMETER(ppRootList);
  420. NET_API_STATUS Status = ERROR_SUCCESS;
  421. //
  422. // For now we ignore the DcName and rootlist, these are needed
  423. // when we implement dom dfs.
  424. //
  425. DFS_TRACE_HIGH( API, "Net Dfs remove2 %ws\n", DfsEntryPath);
  426. DFS_API_START( );
  427. Status = AccessImpersonateCheckRpcClient();
  428. if (Status == ERROR_SUCCESS)
  429. {
  430. Status = DfsRemove( DfsEntryPath,
  431. ServerName,
  432. ShareName );
  433. }
  434. DFS_API_END( );
  435. DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs remove2 %ws, Status %x\n", DfsEntryPath, Status);
  436. return Status;
  437. }
  438. //+----------------------------------------------------------------------------
  439. //
  440. // Function: NetrDfsRemoveStdRoot
  441. //
  442. // Synopsis: Deletes a Dfs root
  443. //
  444. // Arguments: [ServerName] -- The server to remove.
  445. // [RootShare] -- The Root share hosting the Dfs/FtDfs
  446. // [Flags] -- Flags for the operation
  447. //
  448. // Returns: [NERR_Success] -- Operation successful.
  449. //
  450. //-----------------------------------------------------------------------------
  451. extern "C" NET_API_STATUS
  452. NetrDfsRemoveStdRoot(
  453. IN LPWSTR ServerName,
  454. IN LPWSTR RootShare,
  455. IN DWORD Flags)
  456. {
  457. UNREFERENCED_PARAMETER(ServerName);
  458. UNREFERENCED_PARAMETER(Flags);
  459. NET_API_STATUS Status = ERROR_SUCCESS;
  460. DFS_TRACE_HIGH( API, "Net Dfs remove std root %ws\n", RootShare);
  461. DFS_API_START( );
  462. Status = AccessImpersonateCheckRpcClient();
  463. if (Status == ERROR_SUCCESS)
  464. {
  465. Status = DfsDeleteStandaloneRoot( ServerName, RootShare );
  466. }
  467. DFS_API_END( );
  468. DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs remove std root %ws, Status %x\n", RootShare, Status);
  469. return Status;
  470. }
  471. //+----------------------------------------------------------------------------
  472. //
  473. // Function: NetrDfsSetInfo (Obsolete)
  474. //
  475. // Synopsis: Sets the comment, volume state, or replica state.
  476. //
  477. // Arguments: [DfsEntryPath] -- Entry Path of the volume for which info is
  478. // to be set.
  479. // [ServerName] -- If specified, the name of the server whose
  480. // state is to be set.
  481. // [ShareName] -- If specified, the name of the share on
  482. // ServerName whose state is to be set.
  483. // [Level] -- Level of DfsInfo
  484. // [DfsInfo] -- The actual Dfs info.
  485. //
  486. // Returns: [NERR_Success] -- Operation completed successfully.
  487. //
  488. //-----------------------------------------------------------------------------
  489. extern "C" NET_API_STATUS
  490. NetrDfsSetInfo(
  491. IN LPWSTR DfsEntryPath,
  492. IN LPWSTR ServerName,
  493. IN LPWSTR ShareName,
  494. IN DWORD Level,
  495. IN LPDFS_INFO_STRUCT pDfsInfo)
  496. {
  497. NET_API_STATUS Status = ERROR_SUCCESS;
  498. NET_API_STATUS AccessStatus;
  499. DFS_TRACE_HIGH( API, "Net Dfs set info %ws\n", DfsEntryPath);
  500. DFS_API_START( );
  501. //
  502. // we have to allow resynchronize events from every one.
  503. // So do the access check for all calls except the resychronize.
  504. //
  505. AccessStatus = AccessImpersonateCheckRpcClient();
  506. Status = DfsSetInfoCheckAccess( DfsEntryPath,
  507. ServerName,
  508. ShareName,
  509. Level,
  510. (LPBYTE)pDfsInfo,
  511. AccessStatus );
  512. DFS_API_END( );
  513. DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs set info %ws, Status %x\n", DfsEntryPath, Status);
  514. return Status;
  515. }
  516. //+----------------------------------------------------------------------------
  517. //
  518. // Function: NetrDfsSetInfo2
  519. //
  520. // Synopsis: Sets the comment, volume state, or replica state.
  521. //
  522. // Arguments: [DfsEntryPath] -- Entry Path of the volume for which info is
  523. // to be set.
  524. // [ServerName] -- If specified, the name of the server whose
  525. // state is to be set.
  526. // [ShareName] -- If specified, the name of the share on
  527. // ServerName whose state is to be set.
  528. // [Level] -- Level of DfsInfo
  529. // [DfsInfo] -- The actual Dfs info.
  530. //
  531. // Returns: [NERR_Success] -- Operation completed successfully.
  532. //
  533. // [ERROR_INVALID_LEVEL] -- Level != 100 , 101, or 102
  534. //
  535. // [ERROR_INVALID_PARAMETER] -- DfsEntryPath invalid, or
  536. // ShareName specified without ServerName.
  537. //
  538. // [NERR_DfsNoSuchVolume] -- DfsEntryPath does not correspond to
  539. // a valid Dfs volume.
  540. //
  541. // [NERR_DfsNoSuchShare] -- The indicated ServerName/ShareName do
  542. // not support this Dfs volume.
  543. //
  544. // [NERR_DfsInternalCorruption] -- Internal database corruption
  545. // encountered while executing operation.
  546. //
  547. //-----------------------------------------------------------------------------
  548. extern "C" NET_API_STATUS
  549. NetrDfsSetInfo2(
  550. IN LPWSTR DfsEntryPath,
  551. IN LPWSTR DcName,
  552. IN LPWSTR ServerName,
  553. IN LPWSTR ShareName,
  554. IN DWORD Level,
  555. IN LPDFS_INFO_STRUCT pDfsInfo,
  556. IN PDFSM_ROOT_LIST *ppRootList)
  557. {
  558. NET_API_STATUS Status = ERROR_SUCCESS;
  559. UNREFERENCED_PARAMETER(ppRootList);
  560. UNREFERENCED_PARAMETER(DcName);
  561. DFS_TRACE_HIGH( API, "Net Dfs set info2 %ws\n", DfsEntryPath);
  562. //
  563. // DcName and rootlist not supported, for now.
  564. //
  565. DFS_API_START( );
  566. Status = AccessImpersonateCheckRpcClient();
  567. if (Status == ERROR_SUCCESS)
  568. {
  569. Status = DfsSetInfo( DfsEntryPath,
  570. ServerName,
  571. ShareName,
  572. Level,
  573. (LPBYTE)pDfsInfo );
  574. }
  575. DFS_API_END( );
  576. DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs set info %ws, Status %x\n", DfsEntryPath, Status);
  577. return Status;
  578. }
  579. //+----------------------------------------------------------------------------
  580. //
  581. // Function: NetrDfsGetInfo
  582. //
  583. // Synopsis: Server side implementation of the NetDfsGetInfo.
  584. //
  585. // Arguments: [DfsEntryPath] -- Entry Path of volume for which info is
  586. // requested.
  587. //
  588. // [ServerName] -- Name of server which supports this volume
  589. // and for which info is requested.
  590. //
  591. // [ShareName] -- Name of share on ServerName which supports this
  592. // volume.
  593. //
  594. // [Level] -- Level of Info requested.
  595. //
  596. // [DfsInfo] -- On successful return, contains a pointer to the
  597. // requested DFS_INFO_x struct.
  598. //
  599. // Returns: [NERR_Success] -- If successfully returned requested info.
  600. //
  601. //-----------------------------------------------------------------------------
  602. extern "C" NET_API_STATUS
  603. NetrDfsGetInfo(
  604. IN LPWSTR DfsEntryPath,
  605. IN LPWSTR ServerName,
  606. IN LPWSTR ShareName,
  607. IN DWORD Level,
  608. OUT LPDFS_INFO_STRUCT pDfsInfo)
  609. {
  610. LONG BufferSize = 0;
  611. LONG SizeRequired = 0;
  612. ULONG MaxRetry = 0;
  613. NET_API_STATUS Status = ERROR_SUCCESS;
  614. PDFS_INFO_1 pInfo1 = NULL;
  615. UNREFERENCED_PARAMETER(ServerName);
  616. UNREFERENCED_PARAMETER(ShareName);
  617. DFS_TRACE_HIGH( API, "Net Dfs get info %ws\n", DfsEntryPath);
  618. MaxRetry = 5;
  619. BufferSize = sizeof(DFS_INFO_STRUCT);
  620. DFS_API_START( );
  621. do
  622. {
  623. pInfo1 = (PDFS_INFO_1)MIDL_user_allocate(BufferSize);
  624. if (pInfo1 == NULL)
  625. {
  626. Status = ERROR_NOT_ENOUGH_MEMORY;
  627. }
  628. else
  629. {
  630. Status = DfsGetInfo( DfsEntryPath,
  631. Level,
  632. (LPBYTE)pInfo1,
  633. BufferSize,
  634. &SizeRequired );
  635. if (Status != ERROR_SUCCESS)
  636. {
  637. MIDL_user_free( pInfo1 );
  638. }
  639. if (Status == ERROR_BUFFER_OVERFLOW)
  640. {
  641. BufferSize = SizeRequired;
  642. }
  643. }
  644. } while ( (Status == ERROR_BUFFER_OVERFLOW) && (MaxRetry--) );
  645. if (Status == ERROR_SUCCESS)
  646. {
  647. pDfsInfo->DfsInfo1 = pInfo1;
  648. }
  649. DFS_API_END( );
  650. DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs get info %ws, Status %x\n", DfsEntryPath, Status);
  651. return Status;
  652. }
  653. //+----------------------------------------------------------------------------
  654. //
  655. // Function: NetrDfsEnum
  656. //
  657. // Synopsis: The server side implementation of the NetDfsEnum public API
  658. //
  659. // Arguments: [Level] -- The level of info struct desired.
  660. // [PrefMaxLen] -- Preferred maximum length of output buffer.
  661. // 0xffffffff means no limit.
  662. // [DfsEnum] -- DFS_INFO_ENUM_STRUCT pointer where the info
  663. // structs will be returned.
  664. // [ResumeHandle] -- If 0, the enumeration will begin from the
  665. // start. On return, the resume handle will be an opaque
  666. // cookie that can be passed in on subsequent calls to
  667. // resume the enumeration.
  668. //
  669. // Returns: [NERR_Success] -- Successfully retrieved info.
  670. //
  671. //-----------------------------------------------------------------------------
  672. extern "C" NET_API_STATUS
  673. NetrDfsEnum(
  674. IN DWORD Level,
  675. IN DWORD PrefMaxLen,
  676. IN OUT LPDFS_INFO_ENUM_STRUCT pDfsEnum,
  677. IN OUT LPDWORD pResumeHandle)
  678. {
  679. NET_API_STATUS Status = ERROR_SUCCESS;
  680. DFS_TRACE_HIGH( API, "Net Dfs enum %d\n", Level);
  681. DFS_API_START();
  682. //
  683. // We just call NetRDfsEnumEx with a null pathname.
  684. //
  685. Status = DfsEnumEx( NULL,
  686. Level,
  687. PrefMaxLen,
  688. pDfsEnum,
  689. pResumeHandle );
  690. DFS_API_END( );
  691. DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs enum %d, Status %x\n", Level, Status);
  692. return Status;
  693. }
  694. //+----------------------------------------------------------------------------
  695. //
  696. // Function: NetrDfsEnumEx
  697. //
  698. // Synopsis: The DC implementation of the NetDfsEnum public API
  699. //
  700. // Arguments: [DfsName] -- The Dfs to enumerate (\\domainname\ftdfsname)
  701. // [Level] -- The level of info struct desired.
  702. // [PrefMaxLen] -- Preferred maximum length of output buffer.
  703. // 0xffffffff means no limit.
  704. // [DfsEnum] -- DFS_INFO_ENUM_STRUCT pointer where the info
  705. // structs will be returned.
  706. // [ResumeHandle] -- If 0, the enumeration will begin from the
  707. // start. On return, the resume handle will be an opaque
  708. // cookie that can be passed in on subsequent calls to
  709. // resume the enumeration.
  710. //
  711. // Returns: [NERR_Success] -- Successfully retrieved info.
  712. //-----------------------------------------------------------------------------
  713. extern "C" NET_API_STATUS
  714. NetrDfsEnumEx(
  715. IN LPWSTR DfsName,
  716. IN DWORD Level,
  717. IN DWORD PrefMaxLen,
  718. IN OUT LPDFS_INFO_ENUM_STRUCT pDfsEnum,
  719. IN OUT LPDWORD pResumeHandle)
  720. {
  721. NET_API_STATUS Status = ERROR_SUCCESS;
  722. DFS_TRACE_HIGH( API, "Net Dfs enum ex %ws\n", DfsName);
  723. DFS_API_START ();
  724. Status = DfsEnumEx( DfsName,
  725. Level,
  726. PrefMaxLen,
  727. pDfsEnum,
  728. pResumeHandle);
  729. DFS_API_END( );
  730. DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs enum ex %ws, Status %x\n", DfsName, Status);
  731. return Status;
  732. }
  733. NET_API_STATUS
  734. DfsEnumEx(
  735. IN LPWSTR DfsName,
  736. IN DWORD Level,
  737. IN DWORD PrefMaxLen,
  738. IN OUT LPDFS_INFO_ENUM_STRUCT pDfsEnum,
  739. IN OUT LPDWORD pResumeHandle)
  740. {
  741. DWORD EntriesRead = 0;
  742. NET_API_STATUS Status = 0;
  743. LPDFS_INFO_1 pInfo1 = NULL;
  744. if ((pDfsEnum == NULL) ||
  745. (pDfsEnum->DfsInfoContainer.DfsInfo1Container == NULL)) {
  746. return ERROR_INVALID_PARAMETER;
  747. }
  748. Status = DfsEnum(DfsName, Level, PrefMaxLen,
  749. (LPBYTE *) &pInfo1, &EntriesRead,
  750. pResumeHandle);
  751. if (Status == ERROR_SUCCESS)
  752. {
  753. pDfsEnum->DfsInfoContainer.DfsInfo1Container->Buffer = (LPDFS_INFO_1) pInfo1;
  754. pDfsEnum->DfsInfoContainer.DfsInfo1Container->EntriesRead = EntriesRead,
  755. pDfsEnum->Level = Level;
  756. }
  757. return Status;
  758. }
  759. //+----------------------------------------------------------------------------
  760. //
  761. // Function: NetrDfsManagerGetConfigInfo
  762. //
  763. // Synopsis: RPC Interface method that returns the config info for a
  764. // Dfs volume for a given server
  765. //
  766. // Arguments: [wszServer] -- Name of server requesting the info. This
  767. // server is assumed to be requesting the info for
  768. // verification of its local volume knowledge.
  769. // [wszLocalVolumeEntryPath] -- Entry path of local volume.
  770. // [idLocalVolume] -- The guid of the local volume.
  771. // [ppRelationInfo] -- The relation info is allocated and
  772. // returned here.
  773. //
  774. // Returns: STATUS_NOT_SUPPORTED
  775. //
  776. //-----------------------------------------------------------------------------
  777. extern "C" DWORD
  778. NetrDfsManagerGetConfigInfo(
  779. IN LPWSTR wszServer,
  780. IN LPWSTR wszLocalVolumeEntryPath,
  781. IN GUID idLocalVolume,
  782. OUT LPDFSM_RELATION_INFO *ppRelationInfo)
  783. {
  784. UNREFERENCED_PARAMETER( wszServer);
  785. UNREFERENCED_PARAMETER( wszLocalVolumeEntryPath);
  786. UNREFERENCED_PARAMETER( idLocalVolume);
  787. UNREFERENCED_PARAMETER( ppRelationInfo);
  788. //
  789. // This will probably be never supported.
  790. //
  791. return ERROR_NOT_SUPPORTED;
  792. }
  793. //+----------------------------------------------------------------------------
  794. //
  795. // Function: NetrDfsManagerSendSiteInfo
  796. //
  797. // Synopsis: RPC Interface method that reports the site information for a
  798. // Dfs storage server.
  799. //
  800. // Arguments: [wszServer] -- Name of server sending the info.
  801. // [pSiteInfo] -- The site info is here.
  802. //
  803. // Returns: STATUS_NOT_SUPPORTED
  804. //
  805. //-----------------------------------------------------------------------------
  806. extern "C" DWORD
  807. NetrDfsManagerSendSiteInfo(
  808. IN LPWSTR wszServer,
  809. IN LPDFS_SITELIST_INFO pSiteInfo)
  810. {
  811. UNREFERENCED_PARAMETER( wszServer);
  812. UNREFERENCED_PARAMETER( pSiteInfo);
  813. //
  814. // This will probably be never supported.
  815. //
  816. return ERROR_NOT_SUPPORTED;
  817. }
  818. //+----------------------------------------------------------------------------
  819. //
  820. // Function: NetrDfsManagerInitialize
  821. //
  822. // Synopsis: Reinitializes the service
  823. //
  824. // Arguments: [ServerName] -- Name of server
  825. // [Flags] -- Flags for the operation
  826. //
  827. // Returns: STATUS_NOT_SUPPORTED
  828. //
  829. //-----------------------------------------------------------------------------
  830. extern "C" NET_API_STATUS
  831. NetrDfsManagerInitialize(
  832. IN LPWSTR ServerName,
  833. IN DWORD Flags)
  834. {
  835. UNREFERENCED_PARAMETER( ServerName);
  836. UNREFERENCED_PARAMETER( Flags);
  837. //
  838. // This will probably be never supported.
  839. //
  840. return ERROR_NOT_SUPPORTED;
  841. }
  842. //+----------------------------------------------------------------------------
  843. //
  844. // Function: NetrDfsMove
  845. //
  846. // Synopsis: Moves a leaf volume to a different parent.
  847. //
  848. // Arguments: [DfsEntryPath] -- Current entry path of Dfs volume.
  849. //
  850. // [NewEntryPath] -- New entry path of Dfs volume.
  851. //
  852. // Returns: STATUS_NOT_SUPPORTED
  853. //
  854. //-----------------------------------------------------------------------------
  855. extern "C" NET_API_STATUS
  856. NetrDfsMove(
  857. IN LPWSTR DfsEntryPath,
  858. IN LPWSTR NewDfsEntryPath)
  859. {
  860. UNREFERENCED_PARAMETER( DfsEntryPath);
  861. UNREFERENCED_PARAMETER( NewDfsEntryPath);
  862. //
  863. // This will definitely be never supported.
  864. //
  865. return ERROR_NOT_SUPPORTED;
  866. }
  867. //+----------------------------------------------------------------------------
  868. //
  869. // Function: NetrDfsRename
  870. //
  871. // Synopsis: Moves a leaf volume to a different parent.
  872. //
  873. // Arguments: [Path] -- Current path along the entry path of a Dfs volume.
  874. //
  875. // [NewPath] -- New path for current path.
  876. //
  877. // Returns: STATUS_NOT_SUPPORTED
  878. //
  879. //-----------------------------------------------------------------------------
  880. extern "C" NET_API_STATUS
  881. NetrDfsRename(
  882. IN LPWSTR Path,
  883. IN LPWSTR NewPath)
  884. {
  885. UNREFERENCED_PARAMETER( Path);
  886. UNREFERENCED_PARAMETER( NewPath);
  887. //
  888. // This will definitely be never supported.
  889. //
  890. return ERROR_NOT_SUPPORTED;
  891. }
  892. // ====================================================================
  893. // MIDL allocate and free
  894. //
  895. // These routines are used by the RPC layer to call back into our
  896. // code to allocate or free memory.
  897. //
  898. // ====================================================================
  899. PVOID
  900. MIDL_user_allocate(size_t len)
  901. {
  902. return malloc(len);
  903. }
  904. VOID
  905. MIDL_user_free(void * ptr)
  906. {
  907. free(ptr);
  908. }
  909. //+-------------------------------------------------------------------------
  910. //
  911. // Function: RpcInit - Initialize the RPC for this server.
  912. //
  913. // Arguments: NONE
  914. //
  915. // Returns: Status
  916. // ERROR_SUCCESS if we initialized without errors
  917. //
  918. // Description: This routine sets up the RPC server to listen to the
  919. // api requests originating from the clients.
  920. //
  921. //--------------------------------------------------------------------------
  922. DWORD
  923. DfsApiInit()
  924. {
  925. RPC_STATUS Status = 0;
  926. LPWSTR ProtocolSequence = L"ncacn_np";
  927. PVOID Security = NULL; /* let the security subsystem assign appropriate SD */
  928. LPWSTR Endpoint = L"\\pipe\\netdfs";
  929. unsigned int cMinCalls = 1;
  930. unsigned int cMaxCalls = RPC_C_LISTEN_MAX_CALLS_DEFAULT;
  931. unsigned int fDontWait = TRUE;
  932. DfsLockInitialized = InitializeCriticalSectionAndSpinCount( &DfsApiLock, 0 );
  933. if(DfsLockInitialized == FALSE)
  934. {
  935. Status = GetLastError();
  936. return Status;
  937. }
  938. //
  939. // We register our protocol, and startup a server to listen to RPC
  940. // requests. A new server thread is started, so that our thread
  941. // can return back to the caller.
  942. //
  943. Status = RpcServerUseProtseqEpW((USHORT *)ProtocolSequence,
  944. cMaxCalls,
  945. (USHORT *)Endpoint,
  946. Security);
  947. if (Status == ERROR_SUCCESS)
  948. {
  949. Status = RpcServerRegisterIf(netdfs_ServerIfHandle,
  950. NULL,
  951. NULL);
  952. if (Status == ERROR_SUCCESS)
  953. {
  954. Status = RpcServerListen(cMinCalls,
  955. cMaxCalls,
  956. fDontWait);
  957. if (Status == RPC_S_OK )
  958. {
  959. ServerListen = TRUE;
  960. }
  961. }
  962. }
  963. return Status;
  964. }
  965. void
  966. DfsApiShutDown(void)
  967. {
  968. RPC_STATUS Status = RPC_S_OK;
  969. //
  970. // stop server listen.
  971. //
  972. if(ServerListen)
  973. {
  974. Status = RpcMgmtStopServerListening(0);
  975. //
  976. // wait for all RPC threads to go away.
  977. //
  978. if( Status == RPC_S_OK)
  979. {
  980. Status = RpcMgmtWaitServerListen();
  981. }
  982. ServerListen = FALSE;
  983. }
  984. Status = RpcServerUnregisterIf(netdfs_ServerIfHandle,
  985. NULL,
  986. TRUE); // wait for calls to complete
  987. if(DfsLockInitialized)
  988. {
  989. DeleteCriticalSection(&DfsApiLock);
  990. }
  991. }
  992. //+----------------------------------------------------------------------------
  993. //
  994. // Function: NetrDfsAddFtRoot
  995. //
  996. // Synopsis: Creates a new FtDfs, or joins a Server into an FtDfs
  997. //
  998. // Arguments: [ServerName] -- Name of server backing the volume.
  999. // [DcName] -- DC to use
  1000. // [RootShare] -- Name of share on ServerName backing the volume.
  1001. // [FtDfsName] -- The Name of the FtDfs to create/join
  1002. // [Comment] -- Comment associated with this root.
  1003. // [Flags] -- Flags for the operation
  1004. // [ppRootList] -- On success, returns a list of roots that need to be
  1005. // informed of the change in the DS object
  1006. //
  1007. // Returns: [NERR_Success] -- Operation succeeded.
  1008. //
  1009. //
  1010. //-----------------------------------------------------------------------------
  1011. extern "C" NET_API_STATUS
  1012. NetrDfsAddFtRoot(
  1013. IN LPWSTR ServerName,
  1014. IN LPWSTR DcName,
  1015. IN LPWSTR RootShare,
  1016. IN LPWSTR FtDfsName,
  1017. IN LPWSTR Comment,
  1018. IN LPWSTR ConfigDN,
  1019. IN BOOLEAN NewFtDfs,
  1020. IN DWORD ApiFlags,
  1021. IN PDFSM_ROOT_LIST *ppRootList)
  1022. {
  1023. NET_API_STATUS Status = ERROR_SUCCESS;
  1024. UNREFERENCED_PARAMETER( ConfigDN);
  1025. if ( (DcName == NULL) || (DcName[0] == UNICODE_NULL) ||
  1026. (RootShare == NULL) || (RootShare[0] == UNICODE_NULL) ||
  1027. (FtDfsName == NULL) || (FtDfsName[0] == UNICODE_NULL) ||
  1028. (ServerName == NULL) || (ServerName[0] == UNICODE_NULL) )
  1029. {
  1030. return ERROR_INVALID_PARAMETER;
  1031. }
  1032. DFS_TRACE_HIGH( API, "Net Dfs Add FT Root %ws\n", RootShare);
  1033. DFS_API_START( );
  1034. Status = AccessImpersonateCheckRpcClient();
  1035. if (Status == ERROR_SUCCESS)
  1036. {
  1037. Status = DfsAddADBlobRoot( ServerName,
  1038. DcName,
  1039. RootShare,
  1040. FtDfsName,
  1041. Comment,
  1042. NewFtDfs,
  1043. ApiFlags,
  1044. (PVOID)ppRootList );
  1045. }
  1046. DFS_API_END( );
  1047. DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Add AD blob Root %ws\n", RootShare);
  1048. return Status;
  1049. }
  1050. //+----------------------------------------------------------------------------
  1051. //
  1052. // Function: NetrDfsRemoveFtRoot
  1053. //
  1054. // Synopsis: Deletes a root from an FtDfs.
  1055. //
  1056. // Arguments: [ServerName] -- The server to remove.
  1057. // [DcName] -- DC to use
  1058. // [RootShare] -- The Root share hosting the Dfs/FtDfs
  1059. // [FtDfsName] -- The FtDfs to remove the root from.
  1060. // [Flags] -- Flags for the operation
  1061. // [ppRootList] -- On success, returns a list of roots that need to be
  1062. // informed of the change in the DS object
  1063. //
  1064. // Returns: [NERR_Success] -- Operation successful.
  1065. //
  1066. //
  1067. //-----------------------------------------------------------------------------
  1068. extern "C" NET_API_STATUS
  1069. NetrDfsRemoveFtRoot(
  1070. IN LPWSTR ServerName,
  1071. IN LPWSTR DcName,
  1072. IN LPWSTR RootShare,
  1073. IN LPWSTR FtDfsName,
  1074. IN DWORD ApiFlags,
  1075. IN PDFSM_ROOT_LIST *ppRootList)
  1076. {
  1077. NET_API_STATUS Status = ERROR_SUCCESS;
  1078. if ( (DcName == NULL) || (DcName[0] == UNICODE_NULL) ||
  1079. (RootShare == NULL) || (RootShare[0] == UNICODE_NULL) ||
  1080. (FtDfsName == NULL) || (FtDfsName[0] == UNICODE_NULL) ||
  1081. (ServerName == NULL) || (ServerName[0] == UNICODE_NULL) )
  1082. {
  1083. return ERROR_INVALID_PARAMETER;
  1084. }
  1085. DFS_TRACE_HIGH( API, "Net Dfs Remove FT Root %ws\n", RootShare);
  1086. DFS_API_START( );
  1087. Status = AccessImpersonateCheckRpcClient();
  1088. if (Status == ERROR_SUCCESS)
  1089. {
  1090. Status = DfsDeleteADBlobRoot( ServerName,
  1091. DcName,
  1092. RootShare,
  1093. FtDfsName,
  1094. ApiFlags,
  1095. (PVOID)ppRootList );
  1096. }
  1097. DFS_API_END( );
  1098. DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Remove AD blob Root %ws\n", RootShare);
  1099. return Status;
  1100. }