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.

505 lines
9.3 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. w3stub.c
  5. Abstract:
  6. Client stubs of the W3 Daemon APIs.
  7. Author:
  8. Dan Hinsley (DanHi) 23-Mar-1993
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. --*/
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include "w3svci_c.h" // W3_USER_ENUM_STRUCT
  17. #include "w3svc.h"
  18. #include <winsock2.h>
  19. #include <ntsam.h>
  20. #include <ntlsa.h>
  21. DWORD
  22. GetSecret(
  23. IN LPWSTR Server,
  24. IN LPWSTR SecretName,
  25. OUT LPWSTR * ppSecret
  26. );
  27. DWORD
  28. SetSecret(
  29. IN LPWSTR Server,
  30. IN LPWSTR SecretName,
  31. IN LPWSTR pSecret,
  32. IN DWORD cbSecret
  33. );
  34. NET_API_STATUS
  35. NET_API_FUNCTION
  36. W3GetAdminInformation(
  37. IN LPWSTR Server OPTIONAL,
  38. OUT LPW3_CONFIG_INFO * ppConfig
  39. )
  40. {
  41. NET_API_STATUS status;
  42. LPWSTR pSecret;
  43. RpcTryExcept {
  44. //
  45. // Try RPC (local or remote) version of API.
  46. //
  47. status = W3rGetAdminInformation(
  48. Server,
  49. ppConfig
  50. );
  51. }
  52. RpcExcept (1) {
  53. status = RpcExceptionCode();
  54. }
  55. RpcEndExcept
  56. if ( status )
  57. return status;
  58. memset( (*ppConfig)->szCatapultUserPwd,
  59. 0,
  60. sizeof( (*ppConfig)->szCatapultUserPwd ));
  61. return (status);
  62. }
  63. NET_API_STATUS
  64. NET_API_FUNCTION
  65. W3SetAdminInformation(
  66. IN LPWSTR Server OPTIONAL,
  67. IN LPW3_CONFIG_INFO pConfig
  68. )
  69. {
  70. NET_API_STATUS status;
  71. RpcTryExcept {
  72. //
  73. // Try RPC (local or remote) version of API.
  74. //
  75. status = W3rSetAdminInformation(
  76. Server,
  77. pConfig
  78. );
  79. }
  80. RpcExcept (1) {
  81. status = RpcExceptionCode();
  82. }
  83. RpcEndExcept
  84. if ( status )
  85. return status;
  86. return (status);
  87. }
  88. NET_API_STATUS
  89. NET_API_FUNCTION
  90. W3EnumerateUsers(
  91. IN LPWSTR Server OPTIONAL,
  92. OUT LPDWORD EntriesRead,
  93. OUT LPW3_USER_INFO * Buffer
  94. )
  95. {
  96. NET_API_STATUS status;
  97. W3_USER_ENUM_STRUCT EnumStruct;
  98. RpcTryExcept {
  99. //
  100. // Try RPC (local or remote) version of API.
  101. //
  102. status = W3rEnumerateUsers(
  103. Server,
  104. &EnumStruct
  105. );
  106. *EntriesRead = EnumStruct.EntriesRead;
  107. *Buffer = EnumStruct.Buffer;
  108. }
  109. RpcExcept (1) {
  110. status = RpcExceptionCode();
  111. }
  112. RpcEndExcept
  113. return (status);
  114. }
  115. NET_API_STATUS
  116. NET_API_FUNCTION
  117. W3DisconnectUser(
  118. IN LPWSTR Server OPTIONAL,
  119. IN DWORD User
  120. )
  121. {
  122. NET_API_STATUS status;
  123. RpcTryExcept {
  124. //
  125. // Try RPC (local or remote) version of API.
  126. //
  127. status = W3rDisconnectUser(
  128. Server,
  129. User
  130. );
  131. }
  132. RpcExcept (1) {
  133. status = RpcExceptionCode();
  134. }
  135. RpcEndExcept
  136. return (status);
  137. }
  138. NET_API_STATUS
  139. NET_API_FUNCTION
  140. W3QueryStatistics(
  141. IN LPWSTR Server OPTIONAL,
  142. IN DWORD Level,
  143. OUT LPBYTE * Buffer
  144. )
  145. {
  146. NET_API_STATUS status;
  147. *Buffer = NULL;
  148. RpcTryExcept {
  149. //
  150. // Try RPC (local or remote) version of API.
  151. //
  152. status = W3rQueryStatistics(
  153. Server,
  154. Level,
  155. (LPSTATISTICS_INFO)Buffer
  156. );
  157. }
  158. RpcExcept (1) {
  159. status = RpcExceptionCode();
  160. }
  161. RpcEndExcept
  162. return (status);
  163. }
  164. NET_API_STATUS
  165. NET_API_FUNCTION
  166. W3ClearStatistics(
  167. IN LPWSTR Server OPTIONAL
  168. )
  169. {
  170. NET_API_STATUS status;
  171. RpcTryExcept {
  172. //
  173. // Try RPC (local or remote) version of API.
  174. //
  175. status = W3rClearStatistics(
  176. Server
  177. );
  178. }
  179. RpcExcept (1) {
  180. status = RpcExceptionCode();
  181. }
  182. RpcEndExcept
  183. return (status);
  184. }
  185. DWORD
  186. GetSecret(
  187. IN LPWSTR Server,
  188. IN LPWSTR SecretName,
  189. OUT LPWSTR * ppSecret
  190. )
  191. /*++
  192. Description
  193. Gets the specified LSA secret
  194. Arguments:
  195. Server - Server name (or NULL) secret lives on
  196. SecretName - Name of the LSA secret
  197. ppSecret - Receives an allocated block of memory containing the secret.
  198. Must be freed with LocalFree.
  199. Note:
  200. --*/
  201. {
  202. LSA_HANDLE hPolicy;
  203. UNICODE_STRING * punicodePassword;
  204. UNICODE_STRING unicodeServer;
  205. NTSTATUS ntStatus;
  206. OBJECT_ATTRIBUTES ObjectAttributes;
  207. LSA_HANDLE hSecret;
  208. UNICODE_STRING unicodeSecret;
  209. RtlInitUnicodeString( &unicodeServer,
  210. Server );
  211. //
  212. // Open a policy to the remote LSA
  213. //
  214. InitializeObjectAttributes( &ObjectAttributes,
  215. NULL,
  216. 0L,
  217. NULL,
  218. NULL );
  219. ntStatus = LsaOpenPolicy( &unicodeServer,
  220. &ObjectAttributes,
  221. POLICY_ALL_ACCESS,
  222. &hPolicy );
  223. if ( !NT_SUCCESS( ntStatus ) )
  224. return RtlNtStatusToDosError( ntStatus );
  225. //
  226. // Open the LSA secret
  227. //
  228. RtlInitUnicodeString( &unicodeSecret,
  229. SecretName );
  230. ntStatus = LsaOpenSecret( hPolicy,
  231. &unicodeSecret,
  232. SECRET_ALL_ACCESS,
  233. &hSecret );
  234. LsaClose( hPolicy );
  235. if ( !NT_SUCCESS( ntStatus ))
  236. return RtlNtStatusToDosError( ntStatus );
  237. //
  238. // Query the secret value
  239. //
  240. ntStatus = LsaQuerySecret( hSecret,
  241. &punicodePassword,
  242. NULL,
  243. NULL,
  244. NULL );
  245. LsaClose( hSecret );
  246. if ( !NT_SUCCESS( ntStatus ))
  247. return RtlNtStatusToDosError( ntStatus );
  248. *ppSecret = LocalAlloc( LPTR, punicodePassword->Length + sizeof(WCHAR) );
  249. if ( !*ppSecret )
  250. {
  251. RtlZeroMemory( punicodePassword->Buffer,
  252. punicodePassword->MaximumLength );
  253. LsaFreeMemory( (PVOID) punicodePassword );
  254. return ERROR_NOT_ENOUGH_MEMORY;
  255. }
  256. //
  257. // Copy it into the buffer, Length is count of bytes
  258. //
  259. memcpy( *ppSecret,
  260. punicodePassword->Buffer,
  261. punicodePassword->Length );
  262. (*ppSecret)[punicodePassword->Length/sizeof(WCHAR)] = L'\0';
  263. RtlZeroMemory( punicodePassword->Buffer,
  264. punicodePassword->MaximumLength );
  265. LsaFreeMemory( (PVOID) punicodePassword );
  266. return NO_ERROR;
  267. }
  268. DWORD
  269. SetSecret(
  270. IN LPWSTR Server,
  271. IN LPWSTR SecretName,
  272. IN LPWSTR pSecret,
  273. IN DWORD cbSecret
  274. )
  275. /*++
  276. Description
  277. Sets the specified LSA secret
  278. Arguments:
  279. Server - Server name (or NULL) secret lives on
  280. SecretName - Name of the LSA secret
  281. pSecret - Pointer to secret memory
  282. cbSecret - Size of pSecret memory block
  283. Note:
  284. --*/
  285. {
  286. LSA_HANDLE hPolicy;
  287. UNICODE_STRING unicodePassword;
  288. UNICODE_STRING unicodeServer;
  289. NTSTATUS ntStatus;
  290. OBJECT_ATTRIBUTES ObjectAttributes;
  291. LSA_HANDLE hSecret;
  292. UNICODE_STRING unicodeSecret;
  293. RtlInitUnicodeString( &unicodeServer,
  294. Server );
  295. //
  296. // Initialize the unicode string by hand so we can handle '\0' in the
  297. // string
  298. //
  299. unicodePassword.Buffer = pSecret;
  300. unicodePassword.Length = (USHORT) cbSecret;
  301. unicodePassword.MaximumLength = (USHORT) cbSecret;
  302. //
  303. // Open a policy to the remote LSA
  304. //
  305. InitializeObjectAttributes( &ObjectAttributes,
  306. NULL,
  307. 0L,
  308. NULL,
  309. NULL );
  310. ntStatus = LsaOpenPolicy( &unicodeServer,
  311. &ObjectAttributes,
  312. POLICY_ALL_ACCESS,
  313. &hPolicy );
  314. if ( !NT_SUCCESS( ntStatus ) )
  315. return RtlNtStatusToDosError( ntStatus );
  316. //
  317. // Create or open the LSA secret
  318. //
  319. RtlInitUnicodeString( &unicodeSecret,
  320. SecretName );
  321. ntStatus = LsaCreateSecret( hPolicy,
  322. &unicodeSecret,
  323. SECRET_ALL_ACCESS,
  324. &hSecret );
  325. if ( !NT_SUCCESS( ntStatus ))
  326. {
  327. //
  328. // If the secret already exists, then we just need to open it
  329. //
  330. if ( ntStatus == STATUS_OBJECT_NAME_COLLISION )
  331. {
  332. ntStatus = LsaOpenSecret( hPolicy,
  333. &unicodeSecret,
  334. SECRET_ALL_ACCESS,
  335. &hSecret );
  336. }
  337. if ( !NT_SUCCESS( ntStatus ))
  338. {
  339. LsaClose( hPolicy );
  340. return RtlNtStatusToDosError( ntStatus );
  341. }
  342. }
  343. //
  344. // Set the secret value
  345. //
  346. ntStatus = LsaSetSecret( hSecret,
  347. &unicodePassword,
  348. &unicodePassword );
  349. LsaClose( hSecret );
  350. LsaClose( hPolicy );
  351. if ( !NT_SUCCESS( ntStatus ))
  352. {
  353. return RtlNtStatusToDosError( ntStatus );
  354. }
  355. return NO_ERROR;
  356. }
  357.