Windows NT 4.0 source code leak
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.

432 lines
9.2 KiB

4 years ago
  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1992 - 1994
  6. //
  7. // File: support.cxx
  8. //
  9. // Contents: support routines for ksecdd.sys
  10. //
  11. //
  12. // History: 3-7-94 Created MikeSw
  13. //
  14. //------------------------------------------------------------------------
  15. #include <sspdrv.h>
  16. //
  17. // Global Variables:
  18. //
  19. BOOLEAN fInitialized = FALSE;
  20. SecurityFunctionTable SecTable = {SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION,
  21. EnumerateSecurityPackages,
  22. NULL, // LogonUser,
  23. AcquireCredentialsHandle,
  24. FreeCredentialsHandle,
  25. NULL, // QueryCredentialAttributes,
  26. InitializeSecurityContext,
  27. AcceptSecurityContext,
  28. CompleteAuthToken,
  29. DeleteSecurityContext,
  30. ApplyControlToken,
  31. QueryContextAttributes,
  32. ImpersonateSecurityContext,
  33. RevertSecurityContext,
  34. MakeSignature,
  35. VerifySignature,
  36. FreeContextBuffer,
  37. NULL, // QuerySecurityPackageInfo
  38. SealMessage,
  39. UnsealMessage
  40. };
  41. #pragma alloc_text(PAGE, SecAllocate)
  42. #pragma alloc_text(PAGE, SecFree)
  43. #pragma alloc_text(PAGE, IsOkayToExec)
  44. #pragma alloc_text(PAGE, InitSecurityInterfaceW)
  45. #pragma alloc_text(PAGE, MapSecurityError)
  46. #pragma alloc_text(PAGE, GetTokenBuffer)
  47. #pragma alloc_text(PAGE, GetSecurityToken)
  48. //+-------------------------------------------------------------------------
  49. //
  50. // Function: SecAllocate
  51. //
  52. // Synopsis:
  53. //
  54. // Effects:
  55. //
  56. // Arguments:
  57. //
  58. // Requires:
  59. //
  60. // Returns:
  61. //
  62. // Notes:
  63. //
  64. //
  65. //--------------------------------------------------------------------------
  66. VOID * SEC_ENTRY
  67. SecAllocate(ULONG cbMemory)
  68. {
  69. PAGED_CODE();
  70. return(ExAllocatePool(PagedPool, cbMemory));
  71. }
  72. //+-------------------------------------------------------------------------
  73. //
  74. // Function: SecFree
  75. //
  76. // Synopsis:
  77. //
  78. // Effects:
  79. //
  80. // Arguments:
  81. //
  82. // Requires:
  83. //
  84. // Returns:
  85. //
  86. // Notes:
  87. //
  88. //
  89. //--------------------------------------------------------------------------
  90. void SEC_ENTRY
  91. SecFree(PVOID pvMemory)
  92. {
  93. PAGED_CODE();
  94. ExFreePool(pvMemory);
  95. }
  96. //+-------------------------------------------------------------------------
  97. //
  98. // Function: IsOkayToExec
  99. //
  100. // Synopsis: Determines if it is okay to make a call to the SPM
  101. //
  102. // Effects: Binds if necessary to the SPM
  103. //
  104. // Arguments:
  105. //
  106. // Requires:
  107. //
  108. // Returns:
  109. //
  110. // Notes: uses IsSPMgrReady and InitState
  111. //
  112. //--------------------------------------------------------------------------
  113. SECURITY_STATUS
  114. IsOkayToExec(PClient * ppClient)
  115. {
  116. SECURITY_STATUS scRet;
  117. PClient pClient;
  118. PAGED_CODE();
  119. if (NT_SUCCESS(LocateClient(&pClient)))
  120. {
  121. if (ppClient)
  122. *ppClient = pClient;
  123. return(STATUS_SUCCESS);
  124. }
  125. scRet = CreateClient(&pClient);
  126. if (!NT_SUCCESS(scRet))
  127. {
  128. return(scRet);
  129. }
  130. if (ppClient)
  131. *ppClient = pClient;
  132. return(STATUS_SUCCESS);
  133. }
  134. //+-------------------------------------------------------------------------
  135. //
  136. // Function: InitSecurityInterfaceW
  137. //
  138. // Synopsis: returns function table of all the security function and,
  139. // more importantly, create a client session.
  140. //
  141. // Effects:
  142. //
  143. // Arguments:
  144. //
  145. // Requires:
  146. //
  147. // Returns:
  148. //
  149. // Notes:
  150. //
  151. //--------------------------------------------------------------------------
  152. PSecurityFunctionTableW SEC_ENTRY
  153. InitSecurityInterfaceW(void)
  154. {
  155. SECURITY_STATUS scRet;
  156. PAGED_CODE();
  157. scRet = IsOkayToExec(NULL);
  158. if (!NT_SUCCESS(scRet))
  159. {
  160. DebugLog((DEB_ERROR, "Failed to init security interface: 0x%x\n",scRet));
  161. return(NULL);
  162. }
  163. return(&SecTable);
  164. }
  165. //+-------------------------------------------------------------------------
  166. //
  167. // Function: MapSecurityError
  168. //
  169. // Synopsis: maps a HRESULT from the security interface to a NTSTATUS
  170. //
  171. // Effects:
  172. //
  173. // Arguments:
  174. //
  175. // Requires:
  176. //
  177. // Returns:
  178. //
  179. // Notes:
  180. //
  181. //
  182. //--------------------------------------------------------------------------
  183. NTSTATUS SEC_ENTRY
  184. MapSecurityError(HRESULT Error)
  185. {
  186. PAGED_CODE();
  187. return((NTSTATUS) Error);
  188. }
  189. //+-------------------------------------------------------------------------
  190. //
  191. // Function: GetTokenBuffer
  192. //
  193. // Synopsis:
  194. //
  195. // This routine parses a Token Descriptor and pulls out the useful
  196. // information.
  197. //
  198. // Effects:
  199. //
  200. // Arguments:
  201. //
  202. // TokenDescriptor - Descriptor of the buffer containing (or to contain) the
  203. // token. If not specified, TokenBuffer and TokenSize will be returned
  204. // as NULL.
  205. //
  206. // BufferIndex - Index of the token buffer to find (0 for first, 1 for
  207. // second).
  208. //
  209. // TokenBuffer - Returns a pointer to the buffer for the token.
  210. //
  211. // TokenSize - Returns a pointer to the location of the size of the buffer.
  212. //
  213. // ReadonlyOK - TRUE if the token buffer may be readonly.
  214. //
  215. // Requires:
  216. //
  217. // Returns:
  218. //
  219. // TRUE - If token buffer was properly found.
  220. //
  221. // Notes:
  222. //
  223. //
  224. //--------------------------------------------------------------------------
  225. BOOLEAN
  226. GetTokenBuffer(
  227. IN PSecBufferDesc TokenDescriptor OPTIONAL,
  228. IN ULONG BufferIndex,
  229. OUT PVOID * TokenBuffer,
  230. OUT PULONG TokenSize,
  231. IN BOOLEAN ReadonlyOK
  232. )
  233. {
  234. ULONG i, Index = 0;
  235. PAGED_CODE();
  236. //
  237. // If there is no TokenDescriptor passed in,
  238. // just pass out NULL to our caller.
  239. //
  240. if ( !ARGUMENT_PRESENT( TokenDescriptor) ) {
  241. *TokenBuffer = NULL;
  242. *TokenSize = 0;
  243. return TRUE;
  244. }
  245. //
  246. // Check the version of the descriptor.
  247. //
  248. if ( TokenDescriptor->ulVersion != SECBUFFER_VERSION ) {
  249. return FALSE;
  250. }
  251. //
  252. // Loop through each described buffer.
  253. //
  254. for ( i=0; i<TokenDescriptor->cBuffers ; i++ ) {
  255. PSecBuffer Buffer = &TokenDescriptor->pBuffers[i];
  256. if ( (Buffer->BufferType & (~SECBUFFER_READONLY)) == SECBUFFER_TOKEN ) {
  257. //
  258. // If the buffer is readonly and readonly isn't OK,
  259. // reject the buffer.
  260. //
  261. if ( !ReadonlyOK && (Buffer->BufferType & SECBUFFER_READONLY) ) {
  262. return FALSE;
  263. }
  264. if (Index != BufferIndex)
  265. {
  266. Index++;
  267. continue;
  268. }
  269. //
  270. // Return the requested information
  271. //
  272. *TokenBuffer = Buffer->pvBuffer;
  273. *TokenSize = Buffer->cbBuffer;
  274. return TRUE;
  275. }
  276. }
  277. return FALSE;
  278. }
  279. //+-------------------------------------------------------------------------
  280. //
  281. // Function: GetSecurityToken
  282. //
  283. // Synopsis:
  284. // This routine parses a Token Descriptor and pulls out the useful
  285. // information.
  286. //
  287. // Effects:
  288. //
  289. // Arguments:
  290. // TokenDescriptor - Descriptor of the buffer containing (or to contain) the
  291. // token. If not specified, TokenBuffer and TokenSize will be returned
  292. // as NULL.
  293. //
  294. // BufferIndex - Index of the token buffer to find (0 for first, 1 for
  295. // second).
  296. //
  297. // TokenBuffer - Returns a pointer to the buffer for the token.
  298. //
  299. // Requires:
  300. //
  301. // Returns:
  302. //
  303. // TRUE - If token buffer was properly found.
  304. //
  305. // Notes:
  306. //
  307. //
  308. //--------------------------------------------------------------------------
  309. BOOLEAN
  310. GetSecurityToken(
  311. IN PSecBufferDesc TokenDescriptor OPTIONAL,
  312. IN ULONG BufferIndex,
  313. OUT PSecBuffer * TokenBuffer
  314. )
  315. {
  316. ULONG i;
  317. ULONG Index = 0;
  318. PAGED_CODE();
  319. //
  320. // If there is no TokenDescriptor passed in,
  321. // just pass out NULL to our caller.
  322. //
  323. if ( !ARGUMENT_PRESENT( TokenDescriptor) ) {
  324. *TokenBuffer = NULL;
  325. return TRUE;
  326. }
  327. //
  328. // Check the version of the descriptor.
  329. //
  330. if ( TokenDescriptor->ulVersion != SECBUFFER_VERSION ) {
  331. return FALSE;
  332. }
  333. //
  334. // Loop through each described buffer.
  335. //
  336. for ( i=0; i<TokenDescriptor->cBuffers ; i++ ) {
  337. PSecBuffer Buffer = &TokenDescriptor->pBuffers[i];
  338. if ( (Buffer->BufferType & (~SECBUFFER_READONLY)) == SECBUFFER_TOKEN ) {
  339. //
  340. // If the buffer is readonly and readonly isn't OK,
  341. // reject the buffer.
  342. //
  343. if ( Buffer->BufferType & SECBUFFER_READONLY ) {
  344. return FALSE;
  345. }
  346. if (Index != BufferIndex)
  347. {
  348. Index++;
  349. continue;
  350. }
  351. //
  352. // Return the requested information
  353. //
  354. *TokenBuffer = Buffer;
  355. return TRUE;
  356. }
  357. }
  358. return FALSE;
  359. }