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.

535 lines
11 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. rpcstub.c
  5. Abstract:
  6. License Logging Service client stubs.
  7. Author:
  8. Arthur Hanson (arth) 06-Dec-1994
  9. Environment: User mode only.
  10. Revision History:
  11. --*/
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <string.h>
  17. #include <zwapi.h>
  18. #include <llsconst.h>
  19. #include <debug.h>
  20. #include "lsapi_c.h"
  21. #include <strsafe.h>
  22. // #define API_TRACE 1
  23. BOOLEAN LLSUp = FALSE;
  24. //swi, code review, why we hard code the length here, where is 72 from? winnt.h has a define already, SECURITY_MAX_SID_SIZE
  25. #define MAX_EXPECTED_SID_LENGTH 72
  26. LPTSTR pszStringBinding = NULL;
  27. RTL_CRITICAL_SECTION LPCInitLock;
  28. static HANDLE LpcPortHandle = NULL;
  29. /////////////////////////////////////////////////////////////////////////
  30. NTSTATUS
  31. LLSReInitLPC( )
  32. /*++
  33. Routine Description:
  34. This service connects to the LLS server and initializes the LPC port.
  35. Arguments:
  36. Return Value:
  37. STATUS_SUCCESS - The call completed successfully.
  38. --*/
  39. {
  40. RPC_STATUS Status = STATUS_SUCCESS;
  41. LPTSTR pszUuid = NULL;
  42. LPTSTR pszProtocolSequence = NULL;
  43. LPTSTR pszNetworkAddress = NULL;
  44. LPTSTR pszEndpoint = NULL;
  45. LPTSTR pszOptions = NULL;
  46. pszProtocolSequence = TEXT("ncalrpc");
  47. pszEndpoint = TEXT(LLS_LPC_ENDPOINT);
  48. pszNetworkAddress = NULL;
  49. if (LLSUp) {
  50. LLSUp = FALSE;
  51. if (pszStringBinding != NULL) {
  52. Status = RpcStringFree(&pszStringBinding);
  53. pszStringBinding = NULL;
  54. }
  55. if (Status == STATUS_SUCCESS) {
  56. if (lsapirpc_handle != NULL) {
  57. Status = RpcBindingFree(&lsapirpc_handle);
  58. }
  59. lsapirpc_handle = NULL;
  60. }
  61. }
  62. try {
  63. // Compose a string binding
  64. Status = RpcStringBindingComposeW(pszUuid,
  65. pszProtocolSequence,
  66. pszNetworkAddress,
  67. pszEndpoint,
  68. pszOptions,
  69. &pszStringBinding);
  70. }
  71. except (TRUE) {
  72. Status = RpcExceptionCode();
  73. }
  74. if(Status) {
  75. #if DBG
  76. dprintf(TEXT("NTLSAPI RpcStringBindingComposeW Failed: 0x%lX\n"), Status);
  77. #endif
  78. if (pszStringBinding != NULL) {
  79. RpcStringFree(&pszStringBinding);
  80. pszStringBinding = NULL;
  81. }
  82. return I_RpcMapWin32Status(Status);
  83. }
  84. // Bind using the created string binding...
  85. try {
  86. Status = RpcBindingFromStringBindingW(pszStringBinding, &lsapirpc_handle);
  87. }
  88. except (TRUE) {
  89. Status = RpcExceptionCode();
  90. }
  91. if(Status) {
  92. #if DBG
  93. dprintf(TEXT("NTLSAPI RpcBindingFromStringBindingW Failed: 0x%lX\n"), Status);
  94. #endif
  95. // lsapirpc_handle = NULL;
  96. if (pszStringBinding != NULL) {
  97. RpcStringFree(&pszStringBinding);
  98. pszStringBinding = NULL;
  99. }
  100. return I_RpcMapWin32Status(Status);
  101. }
  102. LLSUp = TRUE;
  103. return I_RpcMapWin32Status(Status);
  104. } // LLSReInitLPC
  105. /////////////////////////////////////////////////////////////////////////
  106. NTSTATUS
  107. LLSInitLPC( )
  108. /*++
  109. Routine Description:
  110. This service connects to the LLS server and initializes the LPC port.
  111. Arguments:
  112. Return Value:
  113. STATUS_SUCCESS - The call completed successfully.
  114. --*/
  115. {
  116. NTSTATUS status;
  117. status = RtlInitializeCriticalSection(&LPCInitLock);
  118. lsapirpc_handle = NULL;
  119. return status;
  120. } // LLSInitLPC
  121. /////////////////////////////////////////////////////////////////////////
  122. NTSTATUS
  123. LLSCloseLPC( )
  124. /*++
  125. Routine Description:
  126. This closes the LPC port connection to the service.
  127. Arguments:
  128. Return Value:
  129. STATUS_SUCCESS - The call completed successfully.
  130. --*/
  131. {
  132. RPC_STATUS Status = STATUS_SUCCESS, Status2 = STATUS_SUCCESS;
  133. RtlEnterCriticalSection(&LPCInitLock);
  134. LLSUp = FALSE;
  135. if (pszStringBinding != NULL) {
  136. Status = RpcStringFree(&pszStringBinding);
  137. pszStringBinding = NULL;
  138. }
  139. if (lsapirpc_handle != NULL) {
  140. Status2 = RpcBindingFree(&lsapirpc_handle);
  141. }
  142. if (Status == STATUS_SUCCESS)
  143. Status = Status2;
  144. lsapirpc_handle = NULL;
  145. RtlLeaveCriticalSection(&LPCInitLock);
  146. return Status;
  147. } // LLSCloseLPC
  148. /////////////////////////////////////////////////////////////////////////
  149. NTSTATUS
  150. LLSLicenseRequest2 (
  151. IN LPWSTR ProductName,
  152. IN LPWSTR Version,
  153. IN ULONG DataType,
  154. IN BOOLEAN IsAdmin,
  155. IN PVOID Data,
  156. OUT PHANDLE LicenseHandle
  157. )
  158. /*++
  159. Arguments:
  160. ProductName -
  161. Version -
  162. DataType -
  163. IsAdmin -
  164. Data -
  165. LicenseHandle -
  166. Return Status:
  167. STATUS_SUCCESS - Indicates the service completed successfully.
  168. Routine Description:
  169. --*/
  170. {
  171. WCHAR ProductID[MAX_PRODUCT_NAME_LENGTH + MAX_VERSION_LENGTH + 2];
  172. NTSTATUS Status = STATUS_SUCCESS;
  173. BOOL Close = FALSE;
  174. ULONG VersionIndex;
  175. ULONG Size = 0;
  176. ULONG i;
  177. LICENSE_HANDLE RpcLicenseHandle;
  178. BOOL bActuallyConnect = TRUE;
  179. HRESULT hr;
  180. size_t cb;
  181. ZeroMemory(&RpcLicenseHandle, sizeof(RpcLicenseHandle));
  182. //
  183. // Get this out of the way in-case anything goes wrong
  184. //
  185. *LicenseHandle = NULL;
  186. //
  187. // If LicenseService isn't running (no LPC port) then just return
  188. // dummy info - and let the user on.
  189. //
  190. RtlEnterCriticalSection(&LPCInitLock);
  191. if (!LLSUp)
  192. Status = LLSReInitLPC();
  193. RtlLeaveCriticalSection(&LPCInitLock);
  194. if (!NT_SUCCESS(Status))
  195. return STATUS_SUCCESS;
  196. if (((i = lstrlen(ProductName)) > MAX_PRODUCT_NAME_LENGTH) || (lstrlen(Version) > MAX_VERSION_LENGTH))
  197. return STATUS_SUCCESS;
  198. //
  199. // Create productID - product name + version string.
  200. //
  201. cb = sizeof(ProductID);
  202. hr = StringCbCopy(ProductID, cb, ProductName);
  203. ASSERT(SUCCEEDED(hr));
  204. hr = StringCbCat(ProductID, cb, TEXT(" "));
  205. ASSERT(SUCCEEDED(hr));
  206. hr = StringCbCat(ProductID, cb, Version);
  207. ASSERT(SUCCEEDED(hr));
  208. VersionIndex = i;
  209. //
  210. // Based on DataType figure out if we are doing a name or a SID
  211. // and copy the data appropriatly
  212. //
  213. if (DataType == NT_LS_USER_NAME) {
  214. Size = lstrlen((LPWSTR) Data);
  215. //swi, code review, MAX_USER_NAME_LENGTH is defined in inc\llsconst.h as 37 where did 37 come from?
  216. if (Size > MAX_USER_NAME_LENGTH)
  217. return STATUS_SUCCESS;
  218. Size = (Size + 1) * sizeof(TCHAR);
  219. }
  220. if (DataType == NT_LS_USER_SID) {
  221. //
  222. // Friggin SID, so need to copy it manually.
  223. // WARNING: This makes it dependent on the structure of the
  224. // SID!!!
  225. //
  226. Size = RtlLengthSid( (PSID) Data);
  227. if (Size > MAX_EXPECTED_SID_LENGTH)
  228. return STATUS_SUCCESS;
  229. }
  230. //swi, code review, what happen if DataType is not NT_LS_USER_NAME or NT_LS_USER_SID?
  231. //- it at least pass the call with invalid data to rpc. we should block from here.
  232. //- check with the server side code, it doesn't validate DataType either and it actually goes through the loop to check it against all users in cached list. mostly performance hit.
  233. //
  234. // Call the Server.
  235. //
  236. try {
  237. Status = LlsrLicenseRequestW(
  238. &RpcLicenseHandle,
  239. ProductID,
  240. VersionIndex,
  241. IsAdmin,
  242. DataType,
  243. Size,
  244. (PBYTE) Data );
  245. }
  246. except (TRUE) {
  247. #if DBG
  248. Status = I_RpcMapWin32Status(RpcExceptionCode());
  249. if (Status != RPC_NT_SERVER_UNAVAILABLE) {
  250. dprintf(TEXT("ERROR NTLSAPI.DLL: RPC Exception: 0x%lX\n"), Status);
  251. // ASSERT(FALSE);
  252. }
  253. #endif
  254. *LicenseHandle = NULL;
  255. Status = STATUS_SUCCESS;
  256. bActuallyConnect = FALSE;
  257. }
  258. if (Close)
  259. LLSCloseLPC();
  260. // This is really a ULONG, we just treated it as a PVOID so
  261. // RPC would treat is as a context handle
  262. if(bActuallyConnect == TRUE)
  263. *LicenseHandle = RpcLicenseHandle;
  264. return Status;
  265. } // LLSLicenseRequest
  266. /////////////////////////////////////////////////////////////////////////
  267. NTSTATUS
  268. LLSLicenseRequest (
  269. IN LPWSTR ProductName,
  270. IN LPWSTR Version,
  271. IN ULONG DataType,
  272. IN BOOLEAN IsAdmin,
  273. IN PVOID Data,
  274. OUT PULONG LicenseHandle
  275. )
  276. /*++
  277. Arguments:
  278. ProductName -
  279. Version -
  280. DataType -
  281. IsAdmin -
  282. Data -
  283. LicenseHandle -
  284. Return Status:
  285. STATUS_SUCCESS - Indicates the service completed successfully.
  286. Routine Description:
  287. --*/
  288. {
  289. HANDLE RealLicenseHandle;
  290. NTSTATUS status;
  291. #pragma warning (push)
  292. #pragma warning (disable : 4127) //conditional expression is constant
  293. if (sizeof(ULONG) == sizeof(HANDLE))
  294. #pragma warning (pop)
  295. {
  296. // Should still work on Win32
  297. status = LLSLicenseRequest2(ProductName,Version,DataType,IsAdmin,Data,&RealLicenseHandle);
  298. if (NULL != LicenseHandle)
  299. *LicenseHandle = PtrToUlong(RealLicenseHandle);
  300. }
  301. else
  302. {
  303. status = STATUS_NOT_IMPLEMENTED;
  304. if (NULL != LicenseHandle)
  305. *LicenseHandle = (ULONG) 0xFFFFFFFF;
  306. }
  307. return status;
  308. }
  309. /////////////////////////////////////////////////////////////////////////
  310. NTSTATUS
  311. LLSLicenseFree2 (
  312. IN HANDLE LicenseHandle
  313. )
  314. /*++
  315. Arguments:
  316. LicenseHandle -
  317. Return Status:
  318. STATUS_SUCCESS - Indicates the service completed successfully.
  319. --*/
  320. {
  321. BOOL Close = FALSE;
  322. NTSTATUS Status;
  323. LICENSE_HANDLE RpcLicenseHandle = (LICENSE_HANDLE) LicenseHandle;
  324. //
  325. // If LicenseService isn't running (no LPC port) then just return
  326. // dummy info - and let the user on.
  327. //
  328. if (!LLSUp)
  329. {
  330. return STATUS_SUCCESS;
  331. }
  332. //
  333. // Call the Server.
  334. //
  335. try {
  336. Status = LlsrLicenseFree( &RpcLicenseHandle );
  337. }
  338. except (TRUE) {
  339. #if DBG
  340. Status = I_RpcMapWin32Status(RpcExceptionCode());
  341. if (Status != RPC_NT_SERVER_UNAVAILABLE) {
  342. dprintf(TEXT("ERROR NTLSAPI.DLL: RPC Exception: 0x%lX\n"), Status);
  343. // ASSERT(FALSE);
  344. }
  345. #endif
  346. Status = STATUS_SUCCESS;
  347. }
  348. if (Close)
  349. LLSCloseLPC();
  350. return Status;
  351. } // LLSLicenseFree
  352. /////////////////////////////////////////////////////////////////////////
  353. NTSTATUS
  354. LLSLicenseFree (
  355. IN ULONG LicenseHandle
  356. )
  357. /*++
  358. Arguments:
  359. LicenseHandle -
  360. Return Status:
  361. STATUS_SUCCESS - Indicates the service completed successfully.
  362. --*/
  363. {
  364. #pragma warning (push)
  365. #pragma warning (disable : 4127) //conditional expression is constant
  366. if (sizeof(ULONG) == sizeof(HANDLE))
  367. #pragma warning (pop)
  368. {
  369. // Should still work on Win32
  370. return LLSLicenseFree2(ULongToPtr(LicenseHandle));
  371. }
  372. else
  373. {
  374. return STATUS_NOT_IMPLEMENTED;
  375. }
  376. }