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.

1215 lines
28 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. infostub.c
  5. Abstract:
  6. Client stubs of the Internet Info Server Admin APIs.
  7. Author:
  8. Madan Appiah (madana) 10-Oct-1993
  9. Environment:
  10. User Mode - Win32
  11. --*/
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include "info_cli.h"
  16. #include <ntsam.h>
  17. #include <ntlsa.h>
  18. #include <ftpd.h>
  19. #include <w3svc.h>
  20. #include <rpcutil.h>
  21. #include <winsock2.h>
  22. #include <rpcasync.h>
  23. //
  24. // Quick macro to initialize a unicode string
  25. //
  26. WCHAR g_wchUnicodeNull[] = L"";
  27. #define _InitUnicodeString( pUnicode, pwch ) \
  28. { \
  29. (pUnicode)->Buffer = pwch; \
  30. (pUnicode)->Length = wcslen( pwch ) * sizeof(WCHAR); \
  31. (pUnicode)->MaximumLength = (pUnicode)->Length + sizeof(WCHAR); \
  32. }
  33. # define InitUnicodeString( pUnicode, pwch) \
  34. if (pwch == NULL) { _InitUnicodeString( pUnicode, g_wchUnicodeNull); } \
  35. else { _InitUnicodeString( pUnicode, pwch); } \
  36. //
  37. // Returns a unicode empty string if the string is NULL
  38. //
  39. #define EMPTY_IF_NULL(str) (str ? str : L"")
  40. struct SRV_SECRET_NAMES
  41. {
  42. DWORD dwID;
  43. LPWSTR SecretName;
  44. LPWSTR RootSecretName;
  45. }
  46. aSrvSecrets[] =
  47. {
  48. INET_FTP, FTPD_ANONYMOUS_SECRET_W, FTPD_ROOT_SECRET_W,
  49. INET_HTTP, W3_ANONYMOUS_SECRET_W, W3_ROOT_SECRET_W,
  50. INET_GOPHER, GOPHERD_ANONYMOUS_SECRET_W , GOPHERD_ROOT_SECRET_W,
  51. //INET_CHAT, CHAT_ANONYMOUS_SECRET_W, CHAT_ROOT_SECRET_W,
  52. //INET_NNTP, NNTP_ANONYMOUS_SECRET_W, NNTP_ROOT_SECRET_W,
  53. //INET_SMTP, SMTP_ANONYMOUS_SECRET_W, SMTP_ROOT_SECRET_W,
  54. //INET_POP3, POP3_ANONYMOUS_SECRET_W, POP3_ROOT_SECRET_W,
  55. //INET_LDAP, LDAP_ANONYMOUS_SECRET_W, LDAP_ROOT_SECRET_W,
  56. //INET_IMAP, IMAP_ANONYMOUS_SECRET_W, IMAP_ROOT_SECRET_W,
  57. 0, NULL, NULL
  58. };
  59. DWORD
  60. GetSecret(
  61. IN LPWSTR Server,
  62. IN LPWSTR SecretName,
  63. OUT LPWSTR * ppSecret
  64. );
  65. DWORD
  66. SetSecret(
  67. IN LPWSTR Server,
  68. IN LPWSTR SecretName,
  69. IN LPWSTR pSecret,
  70. IN DWORD cbSecret
  71. );
  72. NET_API_STATUS
  73. NET_API_FUNCTION
  74. InetInfoGetVersion(
  75. IN LPWSTR Server OPTIONAL,
  76. IN DWORD dwReserved,
  77. OUT DWORD * pdwVersion
  78. )
  79. {
  80. NET_API_STATUS status;
  81. RpcTryExcept
  82. {
  83. //
  84. // Try RPC (local or remote) version of API.
  85. //
  86. status = R_InetInfoGetVersion(
  87. Server,
  88. dwReserved,
  89. pdwVersion
  90. );
  91. }
  92. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  93. {
  94. status = RpcExceptionCode();
  95. }
  96. RpcEndExcept
  97. return (status);
  98. } // InetInfoGetVersion()
  99. NET_API_STATUS
  100. NET_API_FUNCTION
  101. InetInfoGetServerCapabilities(
  102. IN LPWSTR Server OPTIONAL,
  103. IN DWORD dwReserved,
  104. OUT LPINET_INFO_CAPABILITIES * ppCap
  105. )
  106. {
  107. NET_API_STATUS status;
  108. *ppCap = NULL;
  109. RpcTryExcept
  110. {
  111. //
  112. // Try RPC (local or remote) version of API.
  113. //
  114. status = R_InetInfoGetServerCapabilities(
  115. Server,
  116. dwReserved,
  117. (LPINET_INFO_CAPABILITIES_STRUCT *)ppCap
  118. );
  119. }
  120. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  121. {
  122. status = RpcExceptionCode();
  123. }
  124. RpcEndExcept
  125. return (status);
  126. } // InetInfoServerCapabilities()
  127. NET_API_STATUS
  128. NET_API_FUNCTION
  129. InetInfoQueryStatistics(
  130. IN LPWSTR pszServer OPTIONAL,
  131. IN DWORD Level,
  132. IN DWORD dwServerMask,
  133. OUT LPBYTE * Buffer
  134. )
  135. {
  136. NET_API_STATUS status;
  137. *Buffer = NULL;
  138. RpcTryExcept
  139. {
  140. //
  141. // Try RPC (local or remote) version of API.
  142. //
  143. status = R_InetInfoQueryStatistics(
  144. pszServer,
  145. Level,
  146. dwServerMask,
  147. (LPINET_INFO_STATISTICS_INFO) Buffer
  148. );
  149. }
  150. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  151. {
  152. status = RpcExceptionCode();
  153. }
  154. RpcEndExcept
  155. return (status);
  156. } // InetInfoQueryStatistics()
  157. NET_API_STATUS
  158. NET_API_FUNCTION
  159. InetInfoClearStatistics(
  160. IN LPWSTR pszServer OPTIONAL,
  161. IN DWORD dwServerMask
  162. )
  163. {
  164. NET_API_STATUS status;
  165. RpcTryExcept
  166. {
  167. //
  168. // Try RPC (local or remote) version of API.
  169. //
  170. status = R_InetInfoClearStatistics(
  171. pszServer,
  172. dwServerMask
  173. );
  174. }
  175. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  176. {
  177. status = RpcExceptionCode();
  178. }
  179. RpcEndExcept
  180. return (status);
  181. } // InetInfoClearStatistics()
  182. NET_API_STATUS
  183. NET_API_FUNCTION
  184. InetInfoFlushMemoryCache(
  185. IN LPWSTR pszServer OPTIONAL,
  186. IN DWORD dwServerMask
  187. )
  188. {
  189. NET_API_STATUS status;
  190. RpcTryExcept
  191. {
  192. //
  193. // Try RPC (local or remote) version of API.
  194. //
  195. status = R_InetInfoFlushMemoryCache(
  196. pszServer,
  197. dwServerMask
  198. );
  199. }
  200. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  201. {
  202. status = RpcExceptionCode();
  203. }
  204. RpcEndExcept
  205. return (status);
  206. } // InetInfoFlushMemoryCache()
  207. NET_API_STATUS
  208. NET_API_FUNCTION
  209. InetInfoGetGlobalAdminInformation(
  210. IN LPWSTR Server OPTIONAL,
  211. IN DWORD dwReserved,
  212. OUT LPINET_INFO_GLOBAL_CONFIG_INFO * ppConfig
  213. )
  214. {
  215. NET_API_STATUS status;
  216. RpcTryExcept
  217. {
  218. status = R_InetInfoGetGlobalAdminInformation(
  219. Server,
  220. dwReserved,
  221. ppConfig
  222. );
  223. }
  224. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  225. {
  226. status = RpcExceptionCode();
  227. }
  228. RpcEndExcept
  229. return status;
  230. } // InetInfoGetGlobalAdminInformation()
  231. NET_API_STATUS
  232. NET_API_FUNCTION
  233. InetInfoGetSites(
  234. IN LPWSTR pszServer OPTIONAL,
  235. IN DWORD dwServerMask,
  236. OUT LPINET_INFO_SITE_LIST * ppSites
  237. )
  238. {
  239. NET_API_STATUS status;
  240. RpcTryExcept
  241. {
  242. status = R_InetInfoGetSites(
  243. pszServer,
  244. dwServerMask,
  245. ppSites
  246. );
  247. }
  248. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  249. {
  250. status = RpcExceptionCode();
  251. }
  252. RpcEndExcept
  253. return status;
  254. } // InetInfoGetSites()
  255. NET_API_STATUS
  256. NET_API_FUNCTION
  257. InetInfoSetGlobalAdminInformation(
  258. IN LPWSTR Server OPTIONAL,
  259. IN DWORD dwReserved,
  260. IN INET_INFO_GLOBAL_CONFIG_INFO * pConfig
  261. )
  262. {
  263. NET_API_STATUS status;
  264. RpcTryExcept
  265. {
  266. status = R_InetInfoSetGlobalAdminInformation(
  267. Server,
  268. dwReserved,
  269. pConfig
  270. );
  271. }
  272. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  273. {
  274. status = RpcExceptionCode();
  275. }
  276. RpcEndExcept
  277. return status;
  278. } // InetInfoSetGlobalAdminInformation()
  279. NET_API_STATUS
  280. NET_API_FUNCTION
  281. InetInfoGetAdminInformation(
  282. IN LPWSTR Server OPTIONAL,
  283. IN DWORD dwServerMask,
  284. OUT LPINET_INFO_CONFIG_INFO * ppConfig
  285. )
  286. {
  287. NET_API_STATUS status;
  288. BOOL fGetPassword = TRUE;
  289. LPWSTR pSecret;
  290. DWORD i = 0;
  291. DWORD j;
  292. LPWSTR pszCurrent;
  293. INET_INFO_VIRTUAL_ROOT_ENTRY * pVirtRoot;
  294. RpcTryExcept
  295. {
  296. status = R_InetInfoGetAdminInformation(
  297. Server,
  298. dwServerMask,
  299. ppConfig
  300. );
  301. }
  302. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  303. {
  304. status = RpcExceptionCode();
  305. }
  306. RpcEndExcept
  307. if ( status )
  308. return status;
  309. #ifndef CHICAGO
  310. //
  311. // Get the anonymous account password
  312. //
  313. while ( aSrvSecrets[i].dwID &&
  314. !(aSrvSecrets[i].dwID & dwServerMask ) )
  315. {
  316. i++;
  317. }
  318. // Note: Only the service corresponding to first mask is chosen.
  319. if ( !aSrvSecrets[i].dwID )
  320. return ERROR_INVALID_PARAMETER;
  321. status = GetSecret( Server,
  322. aSrvSecrets[i].SecretName,
  323. &pSecret );
  324. if ( status )
  325. return status;
  326. memcpy( (*ppConfig)->szAnonPassword,
  327. pSecret,
  328. sizeof(WCHAR) * min( wcslen( pSecret ), PWLEN ));
  329. (*ppConfig)->szAnonPassword[PWLEN] = L'\0';
  330. LocalFree( pSecret );
  331. //
  332. // Zero terminate all of the passwords in case there is no associated
  333. // secret
  334. //
  335. for ( j = 0; j < (*ppConfig)->VirtualRoots->cEntries; j++ )
  336. {
  337. *(*ppConfig)->VirtualRoots->aVirtRootEntry[j].AccountPassword = L'\0';
  338. }
  339. status = GetSecret( Server,
  340. aSrvSecrets[i].RootSecretName,
  341. &pSecret );
  342. if ( status )
  343. return status;
  344. pszCurrent = pSecret;
  345. while ( *pszCurrent )
  346. {
  347. LPWSTR pszRoot;
  348. LPWSTR pszPassword;
  349. LPWSTR pszAddress;
  350. LPWSTR pszNextLine = pszCurrent + wcslen(pszCurrent) + 1;
  351. //
  352. // The list is in the form:
  353. //
  354. // <Root>,<Addresss>=<Password>\0
  355. // <Root>,<Addresss>=<Password>\0
  356. // \0
  357. //
  358. pszRoot = pszCurrent;
  359. pszPassword = wcschr( pszCurrent, L'=' );
  360. if ( !pszPassword )
  361. {
  362. //
  363. // Bad list format, skip this one
  364. //
  365. goto NextLine;
  366. }
  367. *pszPassword = L'\0';
  368. pszPassword++;
  369. pszAddress = wcschr( pszRoot, L',');
  370. if ( !pszAddress )
  371. {
  372. goto NextLine;
  373. }
  374. *pszAddress = L'\0';
  375. pszAddress++;
  376. //
  377. // Now look for this root and address in the virtual root list
  378. // so we can set the password
  379. //
  380. for ( i = 0; i < (*ppConfig)->VirtualRoots->cEntries; i++ )
  381. {
  382. pVirtRoot = &(*ppConfig)->VirtualRoots->aVirtRootEntry[i];
  383. if ( !_wcsicmp( pszRoot, pVirtRoot->pszRoot ) &&
  384. (!pszAddress || !_wcsicmp( pszAddress, pVirtRoot->pszAddress)))
  385. {
  386. //
  387. // If the password length is invalid, we just ignore it.
  388. // This shouldn't happen because we check before setting the
  389. // password
  390. //
  391. if ( wcslen( pszPassword ) <= PWLEN )
  392. {
  393. wcscpy( pVirtRoot->AccountPassword,
  394. pszPassword );
  395. break;
  396. }
  397. }
  398. }
  399. NextLine:
  400. pszCurrent = pszNextLine;
  401. }
  402. LocalFree( pSecret );
  403. #else // CHICAGO
  404. //
  405. // Zero terminate all of the passwords in case there is no associated
  406. // secret
  407. //
  408. for ( j = 0; j < (*ppConfig)->VirtualRoots->cEntries; j++ )
  409. {
  410. *(*ppConfig)->VirtualRoots->aVirtRootEntry[j].AccountPassword = L'\0';
  411. }
  412. #endif // CHICAGO
  413. return status;
  414. } // InetInfoGetAdminInformation()
  415. NET_API_STATUS
  416. NET_API_FUNCTION
  417. InetInfoSetAdminInformation(
  418. IN LPWSTR Server OPTIONAL,
  419. IN DWORD dwServerMask,
  420. IN INET_INFO_CONFIG_INFO * pConfig
  421. )
  422. {
  423. NET_API_STATUS status;
  424. WCHAR szAnonPassword[PWLEN+1];
  425. LPWSTR pszRootPasswords = NULL;
  426. LPWSTR pszPassword;
  427. DWORD i, j;
  428. #ifndef CHICAGO
  429. //
  430. // Enumerate the LSA secret names for the specified servers. We set the
  431. // secrets first so the anonymous user name password can be refreshed
  432. // in the server side InetInfoSetAdminInformation
  433. //
  434. i = 0;
  435. while ( aSrvSecrets[i].dwID )
  436. {
  437. if ( !(aSrvSecrets[i].dwID & dwServerMask ))
  438. {
  439. i++;
  440. continue;
  441. }
  442. if ( IsFieldSet( pConfig->FieldControl, FC_INET_INFO_ANON_PASSWORD ))
  443. {
  444. status = SetSecret( Server,
  445. aSrvSecrets[i].SecretName,
  446. pConfig->szAnonPassword,
  447. (wcslen( pConfig->szAnonPassword ) + 1)
  448. * sizeof(WCHAR));
  449. if ( status )
  450. return status;
  451. }
  452. if ( IsFieldSet( pConfig->FieldControl, FC_INET_INFO_VIRTUAL_ROOTS ))
  453. {
  454. DWORD cbNeeded = sizeof(WCHAR);
  455. INET_INFO_VIRTUAL_ROOT_ENTRY * pVirtRoot;
  456. LPWSTR psz;
  457. LPWSTR pszSecret;
  458. //
  459. // Build a string that looks like:
  460. //
  461. // <Root>,<Addresss>=<Password>\0
  462. // <Root>,<Addresss>=<Password>\0
  463. // \0
  464. //
  465. //
  466. // Do a first pass to figure the buffer size we need to build
  467. //
  468. for ( j = 0; j < pConfig->VirtualRoots->cEntries; j++ )
  469. {
  470. pVirtRoot = &pConfig->VirtualRoots->aVirtRootEntry[j];
  471. cbNeeded += (wcslen( pVirtRoot->pszRoot ) +
  472. wcslen( EMPTY_IF_NULL(pVirtRoot->pszAddress)) +
  473. wcslen( pVirtRoot->AccountPassword ) +
  474. (PWLEN + 3)) * sizeof(WCHAR);
  475. }
  476. //
  477. // We always allocate at least enough room for a '\0'
  478. //
  479. pszSecret = LocalAlloc( LPTR, cbNeeded + sizeof(WCHAR) );
  480. if ( !pszSecret )
  481. return ERROR_NOT_ENOUGH_MEMORY;
  482. psz = pszSecret;
  483. //
  484. // Now build the string
  485. //
  486. for ( j = 0; j < pConfig->VirtualRoots->cEntries; j++ )
  487. {
  488. pVirtRoot = &pConfig->VirtualRoots->aVirtRootEntry[j];
  489. psz += wsprintfW( psz,
  490. L"%ls,%ls=%ls",
  491. pVirtRoot->pszRoot,
  492. EMPTY_IF_NULL(pVirtRoot->pszAddress),
  493. pVirtRoot->AccountPassword );
  494. psz++;
  495. }
  496. //
  497. // Add the list terminating NULL
  498. //
  499. *psz = L'\0';
  500. status = SetSecret( Server,
  501. aSrvSecrets[i].RootSecretName,
  502. pszSecret,
  503. cbNeeded );
  504. LocalFree( pszSecret );
  505. if ( status )
  506. return status;
  507. }
  508. i++;
  509. }
  510. #endif // CHICAGO
  511. //
  512. // Set the passwords to NULL so it doesn't go out on the
  513. // wire. We set them as a secrets above
  514. //
  515. if ( IsFieldSet( pConfig->FieldControl, FC_INET_INFO_VIRTUAL_ROOTS ))
  516. {
  517. pszRootPasswords = LocalAlloc( LPTR,
  518. pConfig->VirtualRoots->cEntries *
  519. (PWLEN + 1) * sizeof(WCHAR) );
  520. if ( !pszRootPasswords )
  521. return ERROR_NOT_ENOUGH_MEMORY;
  522. for ( i = 0; i < pConfig->VirtualRoots->cEntries; i++ )
  523. {
  524. pszPassword = pConfig->VirtualRoots->aVirtRootEntry[i].AccountPassword;
  525. if ( wcslen( pszPassword ) > PWLEN )
  526. {
  527. LocalFree( pszRootPasswords );
  528. return ERROR_INVALID_PARAMETER;
  529. }
  530. wcscpy( pszRootPasswords + i * (PWLEN + 1),
  531. pszPassword );
  532. SecureZeroMemory( pszPassword,
  533. sizeof( pConfig->VirtualRoots->aVirtRootEntry[i].AccountPassword ));
  534. }
  535. }
  536. if ( IsFieldSet( pConfig->FieldControl, FC_INET_INFO_ANON_PASSWORD ))
  537. {
  538. memcpy( szAnonPassword,
  539. pConfig->szAnonPassword,
  540. sizeof(pConfig->szAnonPassword) );
  541. SecureZeroMemory( pConfig->szAnonPassword,
  542. sizeof(pConfig->szAnonPassword) );
  543. }
  544. RpcTryExcept
  545. {
  546. status = R_InetInfoSetAdminInformation(
  547. Server,
  548. dwServerMask,
  549. pConfig
  550. );
  551. }
  552. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  553. {
  554. status = RpcExceptionCode();
  555. }
  556. RpcEndExcept
  557. //
  558. // Restore the structure we just mucked with
  559. //
  560. if ( IsFieldSet( pConfig->FieldControl, FC_INET_INFO_ANON_PASSWORD ))
  561. {
  562. memcpy( pConfig->szAnonPassword,
  563. szAnonPassword,
  564. sizeof(pConfig->szAnonPassword) );
  565. SecureZeroMemory( szAnonPassword, sizeof( szAnonPassword ));
  566. }
  567. if ( IsFieldSet( pConfig->FieldControl, FC_INET_INFO_VIRTUAL_ROOTS ))
  568. {
  569. for ( i = 0; i < pConfig->VirtualRoots->cEntries; i++ )
  570. {
  571. pszPassword = pConfig->VirtualRoots->aVirtRootEntry[i].AccountPassword;
  572. wcscpy( pszPassword,
  573. pszRootPasswords + i * (PWLEN + 1) );
  574. }
  575. SecureZeroMemory( pszRootPasswords,
  576. pConfig->VirtualRoots->cEntries * (PWLEN + 1) * sizeof(WCHAR));
  577. LocalFree( pszRootPasswords );
  578. pszRootPasswords = NULL;
  579. }
  580. return status;
  581. } // InetInfoSetAdminInformation()
  582. NET_API_STATUS
  583. NET_API_FUNCTION
  584. IISEnumerateUsers(
  585. IN LPWSTR Server OPTIONAL,
  586. IN DWORD dwLevel,
  587. IN DWORD dwServiceId,
  588. IN DWORD dwInstance,
  589. OUT PDWORD nRead,
  590. OUT LPBYTE *pBuffer
  591. )
  592. {
  593. NET_API_STATUS status;
  594. GENERIC_INFO_CONTAINER genInfo;
  595. GENERIC_ENUM_STRUCT genStruct;
  596. genInfo.Buffer = NULL;
  597. genInfo.EntriesRead = 0;
  598. genStruct.Container = &genInfo;
  599. genStruct.Level = dwLevel;
  600. RpcTryExcept
  601. {
  602. status = R_IISEnumerateUsers(
  603. Server,
  604. dwServiceId,
  605. dwInstance,
  606. (LPIIS_USER_ENUM_STRUCT)&genStruct
  607. );
  608. if ( genInfo.Buffer != NULL ) {
  609. *pBuffer = (LPBYTE)genInfo.Buffer;
  610. *nRead = genInfo.EntriesRead;
  611. } else {
  612. *pBuffer = NULL;
  613. *nRead = 0;
  614. }
  615. }
  616. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  617. {
  618. status = RpcExceptionCode();
  619. }
  620. RpcEndExcept
  621. return status;
  622. } // IISEnumerateUsers
  623. NET_API_STATUS
  624. NET_API_FUNCTION
  625. IISDisconnectUser(
  626. IN LPWSTR Server OPTIONAL,
  627. IN DWORD dwServiceId,
  628. IN DWORD dwInstance,
  629. IN DWORD dwIdUser
  630. )
  631. {
  632. NET_API_STATUS status;
  633. RpcTryExcept
  634. {
  635. status = R_IISDisconnectUser(
  636. Server,
  637. dwServiceId,
  638. dwInstance,
  639. dwIdUser
  640. );
  641. }
  642. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  643. {
  644. status = RpcExceptionCode();
  645. }
  646. RpcEndExcept
  647. return status;
  648. } // IISDisconnectUser
  649. NET_API_STATUS
  650. NET_API_FUNCTION
  651. InitW3CounterStructure(
  652. IN LPWSTR Server OPTIONAL,
  653. OUT LPDWORD lpcbTotalRequired
  654. )
  655. {
  656. NET_API_STATUS status;
  657. RpcTryExcept
  658. {
  659. status = R_InitW3CounterStructure(Server, lpcbTotalRequired);
  660. }
  661. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  662. {
  663. status = RpcExceptionCode();
  664. }
  665. RpcEndExcept
  666. return status;
  667. } //InitW3CounterStructure
  668. NET_API_STATUS
  669. NET_API_FUNCTION
  670. CollectW3PerfData(
  671. IN LPWSTR Server OPTIONAL,
  672. IN LPWSTR lpValueName,
  673. OUT LPBYTE lppData,
  674. IN OUT LPDWORD lpcbTotalBytes,
  675. OUT LPDWORD lpNumObjectTypes
  676. )
  677. {
  678. NET_API_STATUS status;
  679. RpcTryExcept
  680. {
  681. status = R_CollectW3PerfData(
  682. Server,
  683. lpValueName,
  684. lppData,
  685. lpcbTotalBytes,
  686. lpNumObjectTypes
  687. );
  688. }
  689. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  690. {
  691. status = RpcExceptionCode();
  692. }
  693. RpcEndExcept
  694. return status;
  695. } //CollectW3PerfData
  696. NET_API_STATUS
  697. NET_API_FUNCTION
  698. W3QueryStatistics2(
  699. IN LPWSTR Server OPTIONAL,
  700. IN DWORD dwLevel,
  701. IN DWORD dwInstance,
  702. IN DWORD dwReserved,
  703. OUT LPBYTE * pBuffer
  704. )
  705. {
  706. NET_API_STATUS status;
  707. *pBuffer = NULL;
  708. RpcTryExcept
  709. {
  710. status = R_W3QueryStatistics2(
  711. Server,
  712. dwLevel,
  713. dwInstance,
  714. dwReserved,
  715. (LPW3_STATISTICS_STRUCT)pBuffer
  716. );
  717. }
  718. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  719. {
  720. status = RpcExceptionCode();
  721. }
  722. RpcEndExcept
  723. return status;
  724. } // W3QueryStatistics2
  725. NET_API_STATUS
  726. NET_API_FUNCTION
  727. W3ClearStatistics2(
  728. IN LPWSTR Server OPTIONAL,
  729. IN DWORD dwInstance
  730. )
  731. {
  732. NET_API_STATUS status;
  733. RpcTryExcept
  734. {
  735. status = R_W3ClearStatistics2(
  736. Server,
  737. dwInstance
  738. );
  739. }
  740. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  741. {
  742. status = RpcExceptionCode();
  743. }
  744. RpcEndExcept
  745. return status;
  746. } // W3ClearStatistics2
  747. NET_API_STATUS
  748. NET_API_FUNCTION
  749. FtpQueryStatistics2(
  750. IN LPWSTR Server OPTIONAL,
  751. IN DWORD dwLevel,
  752. IN DWORD dwInstance,
  753. IN DWORD dwReserved,
  754. OUT LPBYTE * pBuffer
  755. )
  756. {
  757. NET_API_STATUS status;
  758. *pBuffer = NULL;
  759. RpcTryExcept
  760. {
  761. status = R_FtpQueryStatistics2(
  762. Server,
  763. dwLevel,
  764. dwInstance,
  765. dwReserved,
  766. (LPFTP_STATISTICS_STRUCT)pBuffer
  767. );
  768. }
  769. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  770. {
  771. status = RpcExceptionCode();
  772. }
  773. RpcEndExcept
  774. return status;
  775. } // FtpQueryStatistics2
  776. NET_API_STATUS
  777. NET_API_FUNCTION
  778. FtpClearStatistics2(
  779. IN LPWSTR Server OPTIONAL,
  780. IN DWORD dwInstance
  781. )
  782. {
  783. NET_API_STATUS status;
  784. RpcTryExcept
  785. {
  786. status = R_FtpClearStatistics2(
  787. Server,
  788. dwInstance
  789. );
  790. }
  791. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  792. {
  793. status = RpcExceptionCode();
  794. }
  795. RpcEndExcept
  796. return status;
  797. } // FtpClearStatistics2
  798. #ifndef CHICAGO
  799. DWORD
  800. GetSecret(
  801. IN LPWSTR Server,
  802. IN LPWSTR SecretName,
  803. OUT LPWSTR * ppSecret
  804. )
  805. /*++
  806. Description
  807. Gets the specified LSA secret
  808. Arguments:
  809. Server - Server name (or NULL) secret lives on
  810. SecretName - Name of the LSA secret
  811. ppSecret - Receives an allocated block of memory containing the secret.
  812. Must be freed with LocalFree.
  813. Note:
  814. --*/
  815. {
  816. LSA_HANDLE hPolicy;
  817. UNICODE_STRING * punicodePassword;
  818. UNICODE_STRING unicodeServer;
  819. NTSTATUS ntStatus;
  820. OBJECT_ATTRIBUTES ObjectAttributes;
  821. UNICODE_STRING unicodeSecret;
  822. InitUnicodeString( &unicodeServer,
  823. Server );
  824. //
  825. // Open a policy to the remote LSA
  826. //
  827. InitializeObjectAttributes( &ObjectAttributes,
  828. NULL,
  829. 0L,
  830. NULL,
  831. NULL );
  832. ntStatus = LsaOpenPolicy( &unicodeServer,
  833. &ObjectAttributes,
  834. POLICY_ALL_ACCESS,
  835. &hPolicy );
  836. if ( !NT_SUCCESS( ntStatus ) )
  837. return LsaNtStatusToWinError( ntStatus );
  838. InitUnicodeString( &unicodeSecret,
  839. SecretName );
  840. //
  841. // Query the secret value
  842. //
  843. ntStatus = LsaRetrievePrivateData( hPolicy,
  844. &unicodeSecret,
  845. &punicodePassword );
  846. LsaClose( hPolicy );
  847. if ( !NT_SUCCESS( ntStatus ))
  848. return LsaNtStatusToWinError( ntStatus );
  849. *ppSecret = LocalAlloc( LPTR, punicodePassword->Length + sizeof(WCHAR) );
  850. if ( !*ppSecret )
  851. {
  852. RtlZeroMemory( punicodePassword->Buffer,
  853. punicodePassword->MaximumLength );
  854. LsaFreeMemory( (PVOID) punicodePassword );
  855. return ERROR_NOT_ENOUGH_MEMORY;
  856. }
  857. //
  858. // Copy it into the buffer, Length is count of bytes
  859. //
  860. memcpy( *ppSecret,
  861. punicodePassword->Buffer,
  862. punicodePassword->Length );
  863. (*ppSecret)[punicodePassword->Length/sizeof(WCHAR)] = L'\0';
  864. RtlZeroMemory( punicodePassword->Buffer,
  865. punicodePassword->MaximumLength );
  866. LsaFreeMemory( (PVOID) punicodePassword );
  867. return NO_ERROR;
  868. } // GetSecret()
  869. DWORD
  870. SetSecret(
  871. IN LPWSTR Server,
  872. IN LPWSTR SecretName,
  873. IN LPWSTR pSecret,
  874. IN DWORD cbSecret
  875. )
  876. /*++
  877. Description
  878. Sets the specified LSA secret
  879. Arguments:
  880. Server - Server name (or NULL) secret lives on
  881. SecretName - Name of the LSA secret
  882. pSecret - Pointer to secret memory
  883. cbSecret - Size of pSecret memory block
  884. Note:
  885. --*/
  886. {
  887. LSA_HANDLE hPolicy;
  888. UNICODE_STRING unicodePassword;
  889. UNICODE_STRING unicodeServer;
  890. NTSTATUS ntStatus;
  891. OBJECT_ATTRIBUTES ObjectAttributes;
  892. UNICODE_STRING unicodeSecret;
  893. InitUnicodeString( &unicodeServer,
  894. Server );
  895. //
  896. // Initialize the unicode string by hand so we can handle '\0' in the
  897. // string
  898. //
  899. unicodePassword.Buffer = pSecret;
  900. unicodePassword.Length = (USHORT) cbSecret;
  901. unicodePassword.MaximumLength = (USHORT) cbSecret;
  902. //
  903. // Open a policy to the remote LSA
  904. //
  905. InitializeObjectAttributes( &ObjectAttributes,
  906. NULL,
  907. 0L,
  908. NULL,
  909. NULL );
  910. ntStatus = LsaOpenPolicy( &unicodeServer,
  911. &ObjectAttributes,
  912. POLICY_ALL_ACCESS,
  913. &hPolicy );
  914. if ( !NT_SUCCESS( ntStatus ) )
  915. return LsaNtStatusToWinError( ntStatus );
  916. //
  917. // Create or open the LSA secret
  918. //
  919. InitUnicodeString( &unicodeSecret,
  920. SecretName );
  921. ntStatus = LsaStorePrivateData( hPolicy,
  922. &unicodeSecret,
  923. &unicodePassword );
  924. LsaClose( hPolicy );
  925. if ( !NT_SUCCESS( ntStatus ))
  926. {
  927. return LsaNtStatusToWinError( ntStatus );
  928. }
  929. return NO_ERROR;
  930. } // SetSecret()
  931. #else // CHICAGO
  932. DWORD
  933. GetSecret(
  934. IN LPWSTR Server,
  935. IN LPWSTR SecretName,
  936. OUT LPWSTR * ppSecret
  937. )
  938. {
  939. return(NO_ERROR);
  940. }
  941. DWORD
  942. SetSecret(
  943. IN LPWSTR Server,
  944. IN LPWSTR SecretName,
  945. IN LPWSTR pSecret,
  946. IN DWORD cbSecret
  947. )
  948. {
  949. return(NO_ERROR);
  950. }
  951. #endif // CHICAGO
  952.