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.

5410 lines
134 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1991 - 1992
  6. //
  7. // File: KLPCSTUB.CXX
  8. //
  9. // Contents: LPC Support for the KSEC device driver
  10. // API Dispatcher
  11. // (Un)Marshalling code
  12. //
  13. //
  14. // Functions: GetClientString
  15. // LpcAcquireCreds
  16. // LpcInitContext
  17. // LpcAcceptContext
  18. //
  19. // DispatchAPI
  20. //
  21. // History: 20 May 92 RichardW Created
  22. // 11 Mar 94 MikeSw Renamed from klpc2.c
  23. //
  24. //------------------------------------------------------------------------
  25. #include <lsapch.hxx>
  26. extern "C"
  27. {
  28. #include "klpcstub.h"
  29. #include <efsstruc.h>
  30. #include "efssrv.hxx"
  31. #include "sphelp.h"
  32. }
  33. ULONG LsapPageSize ;
  34. LONG InternalMessageId ;
  35. PLSAP_API_LOG InternalApiLog ;
  36. //
  37. // Maximum size of a string. This is the max size of
  38. // a short, less the null terminator
  39. //
  40. #define LSAP_MAX_STRING_LENGTH (0xfffc)
  41. //#define LSAP_CATCH_BAD_VM
  42. static EfsSessionKeySent = FALSE;
  43. extern "C" BOOLEAN EfsPersonalVer;
  44. extern "C" BOOLEAN EfsDisabled;
  45. #if DBG
  46. char * SessionStatLabels[] = { "<Disconnect>",
  47. "<Connect>",
  48. "LsaLookupPackage",
  49. "LsaLogonUser",
  50. "LsaCallPackage",
  51. "LsaDeregisterLogonProcess",
  52. "<empty>",
  53. "(I) GetBinding",
  54. "(I) SetSession",
  55. "(I) FindPackage",
  56. "EnumeratePackages",
  57. "AcquireCredentialHandle",
  58. "EstablishCredentials",
  59. "FreeCredentialHandle",
  60. "InitializeSecurityContext",
  61. "AcceptSecurityContext",
  62. "ApplyControlToken",
  63. "DeleteSecurityContext",
  64. "QueryPackage",
  65. "GetUserInfo",
  66. "GetCredentials",
  67. "SaveCredentials",
  68. "DeleteCredentials",
  69. "QueryCredAttributes",
  70. "AddPackage",
  71. "DeletePackage",
  72. "GenerateKey",
  73. "GenerateDirEfs",
  74. "DecryptFek",
  75. "GenerateSessionKey",
  76. "Callback",
  77. "QueryContextAttributes",
  78. "PolicyChangeNotify",
  79. "GetUserName",
  80. "AddCredentials",
  81. "EnumLogonSessions",
  82. "GetLogonSessionData",
  83. "SetContextAttribute",
  84. "LookupAccountName",
  85. "LookupAccountSid",
  86. "<empty>" };
  87. #define ApiLabel(x) (((x+2) < sizeof(SessionStatLabels) / sizeof(char *)) ? \
  88. SessionStatLabels[(x+2)] : "[Illegal API Number!]")
  89. #endif
  90. PLSA_DISPATCH_FN DllCallbackHandler ;
  91. //
  92. // Function orders after LsapAuMaxApiNumber must match SPM_API and
  93. // SPM_API_NUMBER defined in ..\h\spmlpc.h
  94. //
  95. PLSA_DISPATCH_FN LpcDispatchTable[ SPMAPI_MaxApiNumber ] =
  96. {
  97. LpcLsaLookupPackage,
  98. LpcLsaLogonUser,
  99. LpcLsaCallPackage,
  100. LpcLsaDeregisterLogonProcess,
  101. NULL, // LsapAuMaxApiNumber
  102. LpcGetBinding,
  103. LpcSetSession,
  104. LpcFindPackage,
  105. LpcEnumPackages,
  106. LpcAcquireCreds,
  107. LpcEstablishCreds,
  108. LpcFreeCredHandle,
  109. LpcInitContext,
  110. LpcAcceptContext,
  111. LpcApplyToken,
  112. LpcDeleteContext,
  113. LpcQueryPackage,
  114. LpcGetUserInfo,
  115. LpcGetCreds,
  116. LpcSaveCreds,
  117. LpcDeleteCreds,
  118. LpcQueryCredAttributes,
  119. LpcAddPackage,
  120. LpcDeletePackage,
  121. LpcEfsGenerateKey,
  122. LpcEfsGenerateDirEfs,
  123. LpcEfsDecryptFek,
  124. LpcEfsGenerateSessionKey,
  125. LpcCallback,
  126. LpcQueryContextAttributes,
  127. LpcLsaPolicyChangeNotify,
  128. LpcGetUserName,
  129. LpcAddCredentials,
  130. LpcEnumLogonSessions,
  131. LpcGetLogonSessionData,
  132. LpcSetContextAttributes,
  133. LpcLookupAccountName,
  134. LpcLookupAccountSid
  135. };
  136. NTSTATUS
  137. MapTokenBuffer(
  138. PSecBufferDesc pInput,
  139. BOOLEAN fDoClientCopy
  140. );
  141. #define KLPC_FLAG_RESET (~(SPMAPI_FLAG_ERROR_RET | \
  142. SPMAPI_FLAG_MEMORY | SPMAPI_FLAG_PREPACK | \
  143. SPMAPI_FLAG_EXEC_NOW ) )
  144. //+---------------------------------------------------------------------------
  145. //
  146. // Function: AbortLpcContext
  147. //
  148. // Synopsis: Aborts a security context if something goes wrong.
  149. //
  150. // Effects: Calls a DeleteContext() on the context.
  151. //
  152. // Arguments: [phContext] -- Context to abort
  153. //
  154. // History: 6-29-93 RichardW Created
  155. //
  156. // Notes:
  157. //
  158. //----------------------------------------------------------------------------
  159. void
  160. AbortLpcContext(
  161. PCtxtHandle phContext
  162. )
  163. {
  164. PSession pSession ;
  165. NTSTATUS scRet;
  166. PLSA_CALL_INFO CallInfo ;
  167. pSession = GetCurrentSession();
  168. CallInfo = LsapGetCurrentCall();
  169. CallInfo->Flags |= CALL_FLAG_NO_HANDLE_CHK ;
  170. DebugLog((DEB_WARN, "[%x] Aborting context %p:%p\n",
  171. pSession->dwProcessID, phContext->dwUpper,
  172. phContext->dwLower));
  173. scRet = WLsaDeleteContext( phContext );
  174. if (FAILED(scRet))
  175. {
  176. DebugLog((DEB_WARN, "[%x] DeleteContext failed (%x) on context %p:%p\n",
  177. pSession->dwProcessID, scRet, phContext->dwUpper,
  178. phContext->dwLower));
  179. }
  180. CallInfo->Flags &= (~(CALL_FLAG_NO_HANDLE_CHK));
  181. }
  182. //+-------------------------------------------------------------------------
  183. //
  184. // Function: GetClientString
  185. //
  186. // Synopsis: Get a string from client memory
  187. //
  188. // Effects:
  189. //
  190. // Arguments:
  191. //
  192. // Requires:
  193. //
  194. // Returns:
  195. //
  196. // Notes:
  197. //
  198. //--------------------------------------------------------------------------
  199. NTSTATUS
  200. GetClientString(
  201. PUNICODE_STRING pssSource,
  202. PUNICODE_STRING pssDest,
  203. PSPM_LPC_MESSAGE pMessage,
  204. PUCHAR * Where
  205. )
  206. {
  207. NTSTATUS scRet = S_OK;
  208. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  209. *pssDest = *pssSource;
  210. if ( pssDest->Length > LSAP_MAX_STRING_LENGTH )
  211. {
  212. return STATUS_INVALID_PARAMETER ;
  213. }
  214. if ( CallInfo->Flags & CALL_FLAG_KERNEL_POOL )
  215. {
  216. if ((ULONG_PTR) pssSource->Buffer >= (ULONG_PTR) sizeof( SPM_LPC_MESSAGE ) )
  217. {
  218. *pssDest = *pssSource ;
  219. if ( pssDest->Length < pssDest->MaximumLength )
  220. {
  221. pssDest->Buffer[ pssDest->Length / sizeof( WCHAR )] = L'\0';
  222. }
  223. return STATUS_SUCCESS ;
  224. }
  225. }
  226. pssDest->Buffer = (LPWSTR) LsapAllocatePrivateHeap(pssDest->Length+sizeof(WCHAR));
  227. if (pssDest->Buffer)
  228. {
  229. pssDest->MaximumLength = pssDest->Length+sizeof(WCHAR);
  230. if (pssSource->Length != 0)
  231. {
  232. if ((ULONG_PTR) pssSource->Buffer >= (ULONG_PTR) sizeof( SPM_LPC_MESSAGE ) )
  233. {
  234. scRet = LsapCopyFromClient( pssSource->Buffer,
  235. pssDest->Buffer,
  236. pssDest->Length);
  237. if (FAILED(scRet))
  238. {
  239. LsapFreePrivateHeap(pssDest->Buffer);
  240. pssDest->Buffer = NULL;
  241. }
  242. }
  243. else
  244. {
  245. //
  246. // prepacked buffers
  247. //
  248. if ( pssSource->Length > CBPREPACK )
  249. {
  250. LsapFreePrivateHeap( pssDest->Buffer );
  251. pssDest->Buffer = NULL ;
  252. return STATUS_INVALID_PARAMETER ;
  253. }
  254. *Where = (PUCHAR) (pMessage) + (ULONG_PTR) pssSource->Buffer ;
  255. if (*Where == NULL)
  256. {
  257. *Where = pMessage->ApiMessage.bData;
  258. }
  259. RtlCopyMemory(
  260. pssDest->Buffer,
  261. *Where,
  262. pssDest->Length);
  263. *Where += pssDest->Length;
  264. }
  265. }
  266. return(scRet);
  267. }
  268. return(SEC_E_INSUFFICIENT_MEMORY);
  269. }
  270. //+-------------------------------------------------------------------------
  271. //
  272. // Function: PutClientString
  273. //
  274. // Synopsis: Get a string from client memory
  275. //
  276. // Effects:
  277. //
  278. // Arguments:
  279. //
  280. // Requires:
  281. //
  282. // Returns:
  283. //
  284. // Notes:
  285. //
  286. //--------------------------------------------------------------------------
  287. NTSTATUS
  288. PutClientString(
  289. PUNICODE_STRING pssSource,
  290. PUNICODE_STRING pssDest
  291. )
  292. {
  293. NTSTATUS scRet;
  294. pssDest->Length = pssSource->Length;
  295. //
  296. // If the destination buffer isn't allocated yet, allocate it.
  297. //
  298. if (!pssDest->Buffer)
  299. {
  300. pssDest->Buffer = (LPWSTR) LsapClientAllocate(pssDest->Length+sizeof(WCHAR));
  301. pssDest->MaximumLength = pssDest->Length+sizeof(WCHAR);
  302. }
  303. if (pssDest->Buffer)
  304. {
  305. scRet = LsapCopyToClient( pssSource->Buffer,
  306. pssDest->Buffer,
  307. pssDest->Length);
  308. if (FAILED(scRet))
  309. {
  310. LsapClientFree(pssDest->Buffer);
  311. pssDest->Buffer = NULL;
  312. }
  313. return(scRet);
  314. }
  315. return(SEC_E_INSUFFICIENT_MEMORY);
  316. }
  317. //+-------------------------------------------------------------------------
  318. //
  319. // Function: MapTokenBuffer
  320. //
  321. // Synopsis: Maps the security token buffer into local memory
  322. //
  323. // Effects:
  324. //
  325. // Arguments:
  326. //
  327. // Requires:
  328. //
  329. // Returns:
  330. //
  331. // Notes:
  332. //
  333. //
  334. //--------------------------------------------------------------------------
  335. NTSTATUS
  336. MapTokenBuffer(
  337. PSecBufferDesc pInput,
  338. BOOLEAN fDoClientCopy
  339. )
  340. {
  341. ULONG i;
  342. NTSTATUS scRet = STATUS_SUCCESS;
  343. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  344. //
  345. // Mark all buffers as unmapped in case of failure
  346. //
  347. for (i = 0; i < pInput->cBuffers ; i++ )
  348. {
  349. pInput->pBuffers[i].BufferType |= SECBUFFER_UNMAPPED;
  350. }
  351. for (i = 0; i < pInput->cBuffers ; i++ )
  352. {
  353. //
  354. // Always map the security token - it is assumed that this
  355. // is always wanted by all packages
  356. //
  357. if ((pInput->pBuffers[i].BufferType & ~SECBUFFER_ATTRMASK) == SECBUFFER_TOKEN)
  358. {
  359. if (fDoClientCopy)
  360. {
  361. scRet = LsapMapClientBuffer( &pInput->pBuffers[i],
  362. &pInput->pBuffers[i] );
  363. }
  364. else
  365. {
  366. pInput->pBuffers[i].pvBuffer = LsapAllocateLsaHeap(pInput->pBuffers[i].cbBuffer);
  367. if (!pInput->pBuffers[i].pvBuffer)
  368. {
  369. scRet = SEC_E_INSUFFICIENT_MEMORY;
  370. }
  371. pInput->pBuffers[i].BufferType &= ~SECBUFFER_UNMAPPED;
  372. }
  373. if (FAILED(scRet))
  374. {
  375. return(scRet);
  376. }
  377. }
  378. else
  379. {
  380. NOTHING ;
  381. }
  382. }
  383. return(S_OK);
  384. }
  385. //+---------------------------------------------------------------------------
  386. //
  387. // Function: AllocateClientBuffers
  388. //
  389. // Synopsis: Allocate space in the client process for TOKEN type buffers
  390. //
  391. // Arguments: [pOutput] --
  392. // [pClientOutput] --
  393. // [pFlags] --
  394. //
  395. // History: 8-14-98 RichardW Created
  396. //
  397. // Notes:
  398. //
  399. //----------------------------------------------------------------------------
  400. NTSTATUS
  401. AllocateClientBuffers(
  402. PSecBufferDesc pOutput,
  403. PSecBufferDesc pClientOutput,
  404. PUSHORT pFlags)
  405. {
  406. ULONG i;
  407. DsysAssert(pOutput->cBuffers <= MAX_SECBUFFERS);
  408. if (pOutput->cBuffers > MAX_SECBUFFERS)
  409. {
  410. return(SEC_E_INVALID_TOKEN);
  411. }
  412. for (i = 0; i < pOutput->cBuffers ; i++ )
  413. {
  414. pClientOutput->pBuffers[i] = pOutput->pBuffers[i];
  415. if (((pOutput->pBuffers[i].BufferType & ~SECBUFFER_ATTRMASK) == SECBUFFER_TOKEN)
  416. && (pOutput->pBuffers[i].cbBuffer))
  417. {
  418. pClientOutput->pBuffers[i].pvBuffer =
  419. LsapClientAllocate(pOutput->pBuffers[i].cbBuffer);
  420. if (!pClientOutput->pBuffers[i].pvBuffer)
  421. {
  422. return( SEC_E_INSUFFICIENT_MEMORY );
  423. }
  424. *pFlags |= SPMAPI_FLAG_MEMORY;
  425. }
  426. }
  427. return(S_OK);
  428. }
  429. //+-------------------------------------------------------------------------
  430. //
  431. // Function: CopyClientBuffers
  432. //
  433. // Synopsis: Copies any mapped buffers over to the client's address
  434. // space. The length is also copies for those buffers.
  435. //
  436. // Effects:
  437. //
  438. // Arguments:
  439. //
  440. // Requires:
  441. //
  442. // Returns:
  443. //
  444. // Notes:
  445. //
  446. //
  447. //--------------------------------------------------------------------------
  448. NTSTATUS
  449. CopyClientBuffers(
  450. PSecBufferDesc pSource,
  451. PSecBufferDesc pDest)
  452. {
  453. ULONG i;
  454. NTSTATUS scRet;
  455. for (i = 0; i < pSource->cBuffers ; i++ )
  456. {
  457. //
  458. // Only copy it if the buffer exists and is unmapped -
  459. // otherwise nothing changed or there is nothing and it is
  460. // a waste of time.
  461. //
  462. if (pSource->pBuffers[i].pvBuffer &&
  463. !(pSource->pBuffers[i].BufferType & SECBUFFER_UNMAPPED))
  464. {
  465. DsysAssert(pSource->pBuffers[i].cbBuffer <= pDest->pBuffers[i].cbBuffer);
  466. scRet = LsapCopyToClient( pSource->pBuffers[i].pvBuffer,
  467. pDest->pBuffers[i].pvBuffer,
  468. pSource->pBuffers[i].cbBuffer );
  469. if (FAILED(scRet))
  470. {
  471. //
  472. // Again, we have a real problem when this fails. We
  473. // abort the context and return an error.
  474. //
  475. return(SEC_E_INSUFFICIENT_MEMORY);
  476. }
  477. //
  478. // Copy the length over also
  479. //
  480. pDest->pBuffers[i].cbBuffer = pSource->pBuffers[i].cbBuffer;
  481. pDest->pBuffers[i].BufferType = pSource->pBuffers[i].BufferType &
  482. (~SECBUFFER_ATTRMASK) ;
  483. }
  484. }
  485. return(S_OK);
  486. }
  487. //+-------------------------------------------------------------------------
  488. //
  489. // Function: GetClientBuffer
  490. //
  491. // Synopsis: Maps a client's SecBuffer into the caller's address space or
  492. // from prepacked area
  493. //
  494. // Effects: Clears the SECBUFFER_UNMAPPED field of the BufferType of
  495. // the return SecBuffer
  496. //
  497. // Arguments:
  498. //
  499. // Requires:
  500. //
  501. // Returns:
  502. //
  503. // Notes: Doesn't modify pOutput until the end, so it is o.k. to pass
  504. // the same thing for pInput and pOutput.
  505. //
  506. //
  507. //--------------------------------------------------------------------------
  508. NTSTATUS
  509. GetClientBuffer(
  510. IN PSecBuffer pInput,
  511. OUT PSecBuffer pOutput,
  512. IN PSPM_LPC_MESSAGE pMessage,
  513. IN OUT PUCHAR * Where
  514. )
  515. {
  516. NTSTATUS hrRet = STATUS_SUCCESS;
  517. SecBuffer Output;
  518. Output = *pInput;
  519. //
  520. // If the buffer is already mapped or it doesn't exist (is NULL) we
  521. // are done.
  522. //
  523. if (!(pInput->BufferType & SECBUFFER_UNMAPPED) ||
  524. !pInput->pvBuffer)
  525. {
  526. return(S_OK);
  527. }
  528. Output.BufferType &= ~SECBUFFER_UNMAPPED;
  529. Output.pvBuffer = LsapAllocateLsaHeap(pInput->cbBuffer);
  530. if (!(Output.pvBuffer))
  531. {
  532. return(SEC_E_INSUFFICIENT_MEMORY);
  533. }
  534. if (pInput->pvBuffer != (PVOID) SEC_PACKED_BUFFER_VALUE)
  535. {
  536. hrRet = LsapCopyFromClient( pInput->pvBuffer,
  537. Output.pvBuffer,
  538. Output.cbBuffer );
  539. }
  540. else
  541. {
  542. if (*Where == NULL)
  543. {
  544. *Where = pMessage->ApiMessage.bData;
  545. }
  546. RtlCopyMemory( Output.pvBuffer, *Where, Output.cbBuffer);
  547. *Where += Output.cbBuffer;
  548. }
  549. if (FAILED(hrRet))
  550. {
  551. LsapFreeLsaHeap(Output.pvBuffer);
  552. }
  553. else
  554. {
  555. *pOutput = Output;
  556. }
  557. return(hrRet);
  558. }
  559. //+---------------------------------------------------------------------------
  560. //
  561. // Function: LsapWriteClientBuffer
  562. //
  563. // Synopsis: Allocates and copies a buffer out to the client
  564. //
  565. // Arguments: [LsaBuffer] --
  566. // [ClientBuffer] --
  567. //
  568. // History: 4-11-97 RichardW Created
  569. //
  570. // Notes:
  571. //
  572. //----------------------------------------------------------------------------
  573. NTSTATUS
  574. LsapWriteClientBuffer(
  575. IN PSecBuffer LsaBuffer,
  576. OUT PSecBuffer ClientBuffer
  577. )
  578. {
  579. NTSTATUS Status ;
  580. PVOID Client ;
  581. Status = LsapAllocateClientBuffer( NULL,
  582. LsaBuffer->cbBuffer,
  583. &Client );
  584. if ( NT_SUCCESS( Status ) )
  585. {
  586. Status = LsapCopyToClientBuffer( NULL,
  587. LsaBuffer->cbBuffer,
  588. Client,
  589. LsaBuffer->pvBuffer );
  590. if ( NT_SUCCESS( Status ) )
  591. {
  592. ClientBuffer->BufferType = LsaBuffer->BufferType ;
  593. ClientBuffer->cbBuffer = LsaBuffer->cbBuffer ;
  594. ClientBuffer->pvBuffer = Client ;
  595. }
  596. else
  597. {
  598. LsapFreeClientBuffer( NULL, Client );
  599. }
  600. }
  601. return Status ;
  602. }
  603. //+---------------------------------------------------------------------------
  604. //
  605. // Function: LsapChangeHandle
  606. //
  607. // Synopsis: Changes a handle, based on the current API, session
  608. //
  609. // Arguments: [HandleOp] --
  610. // [OldHandle] --
  611. // [NewHandle] --
  612. //
  613. // History: 9-20-96 RichardW Created
  614. //
  615. // Notes:
  616. //
  617. //----------------------------------------------------------------------------
  618. BOOL
  619. LsapChangeHandle(
  620. SECHANDLE_OPS HandleOp,
  621. PSecHandle OldHandle,
  622. PSecHandle NewHandle
  623. )
  624. {
  625. PLSA_CALL_INFO CallInfo ;
  626. PSPM_LPC_MESSAGE pMessage;
  627. SPMAcquireCredsAPI *pAcquireCreds;
  628. SPMInitContextAPI * pInitContext;
  629. SPMAcceptContextAPI *pAcceptContext;
  630. BOOL ContextHandle ;
  631. PSession pSession ;
  632. SecHandle RemoveHandle = { 0 };
  633. PVOID Key ;
  634. CallInfo = LsapGetCurrentCall();
  635. if ( !CallInfo )
  636. {
  637. return FALSE ;
  638. }
  639. pMessage = CallInfo->Message ;
  640. pSession = CallInfo->Session ;
  641. ContextHandle = TRUE ;
  642. if ( HandleOp == HandleRemoveReplace )
  643. {
  644. RemoveHandle = *OldHandle ;
  645. }
  646. switch ( pMessage->ApiMessage.dwAPI )
  647. {
  648. case SPMAPI_AcquireCreds:
  649. pAcquireCreds = LPC_MESSAGE_ARGSP( pMessage, AcquireCreds );
  650. if ( HandleOp == HandleReplace )
  651. {
  652. RemoveHandle = pAcquireCreds->hCredential ;
  653. }
  654. DebugLog((DEB_TRACE, "[%x] Changing Handle %p : %p to %p : %p\n",
  655. pSession->dwProcessID,
  656. pAcquireCreds->hCredential.dwUpper, pAcquireCreds->hCredential.dwLower,
  657. NewHandle->dwUpper, NewHandle->dwLower ));
  658. pAcquireCreds->hCredential = *NewHandle ;
  659. ContextHandle = FALSE ;
  660. break;
  661. case SPMAPI_InitContext:
  662. pInitContext = LPC_MESSAGE_ARGSP( pMessage, InitContext );
  663. if ( HandleOp == HandleReplace )
  664. {
  665. RemoveHandle = pInitContext->hContext ;
  666. }
  667. DebugLog((DEB_TRACE, "[%x] Changing Handle %p : %p to %p : %p\n",
  668. pSession->dwProcessID,
  669. pInitContext->hContext.dwUpper, pInitContext->hContext.dwLower,
  670. NewHandle->dwUpper, NewHandle->dwLower ));
  671. pInitContext->hNewContext = *NewHandle ;
  672. break;
  673. case SPMAPI_AcceptContext:
  674. pAcceptContext = LPC_MESSAGE_ARGSP( pMessage, AcceptContext );
  675. if ( HandleOp == HandleReplace )
  676. {
  677. RemoveHandle = pAcceptContext->hContext ;
  678. }
  679. DebugLog((DEB_TRACE, "[%x] Changing Handle %p : %p to %p : %p\n",
  680. pSession->dwProcessID,
  681. pAcceptContext->hNewContext.dwUpper, pAcceptContext->hNewContext.dwLower,
  682. NewHandle->dwUpper, NewHandle->dwLower ));
  683. pAcceptContext->hNewContext = *NewHandle ;
  684. break;
  685. default:
  686. return( FALSE );
  687. }
  688. pMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_HANDLE_CHG ;
  689. //
  690. // Clean up the handle references. The old handle is dereferenced,
  691. // the new handle is referenced once (to make up for it).
  692. //
  693. if ( ContextHandle )
  694. {
  695. if ( HandleOp != HandleSet )
  696. {
  697. DebugLog(( DEB_TRACE, "[%x] Deleting old context handle %p : %p\n",
  698. pSession->dwProcessID,
  699. RemoveHandle.dwUpper, RemoveHandle.dwLower ));
  700. ValidateAndDerefContextHandle( pSession, &RemoveHandle );
  701. // ValidateContextHandle( pSession, NewHandle, &Key );
  702. }
  703. }
  704. else
  705. {
  706. if ( HandleOp != HandleSet )
  707. {
  708. DebugLog(( DEB_TRACE, "[%x] Deleting old credential handle %p : %p\n",
  709. pSession->dwProcessID,
  710. RemoveHandle.dwUpper, RemoveHandle.dwLower ));
  711. ValidateAndDerefCredHandle( pSession, &RemoveHandle );
  712. // ValidateCredHandle( pSession, NewHandle, &Key );
  713. }
  714. }
  715. return( TRUE );
  716. }
  717. NTSTATUS
  718. LsapFixupAuthIdentity(
  719. PKSEC_LSA_MEMORY_HEADER KMap,
  720. PVOID AuthIdentity
  721. )
  722. {
  723. PSEC_WINNT_AUTH_IDENTITY_EX AuthEx ;
  724. NTSTATUS Status = STATUS_SUCCESS ;
  725. ULONG_PTR PoolBase = (ULONG_PTR) -1 ;
  726. USHORT i ;
  727. AuthEx = (PSEC_WINNT_AUTH_IDENTITY_EX) AuthIdentity ;
  728. DsysAssert( AuthEx->Version == SEC_WINNT_AUTH_IDENTITY_VERSION );
  729. for ( i = 0 ; i < KMap->MapCount ; i++ )
  730. {
  731. if ( (PUCHAR) KMap + KMap->PoolMap[ i ].Offset == (PUCHAR) AuthIdentity )
  732. {
  733. PoolBase = (ULONG_PTR) KMap->PoolMap[ i ].Pool ;
  734. break;
  735. }
  736. }
  737. if ( AuthEx->User )
  738. {
  739. if ( (ULONG_PTR) AuthEx->User > PoolBase)
  740. {
  741. AuthEx->User = (PWSTR) ( (ULONG_PTR) AuthEx->User - PoolBase );
  742. }
  743. if ( (ULONG_PTR) AuthEx->User < 0x10000 )
  744. {
  745. AuthEx->User = (PWSTR) ((ULONG_PTR)AuthEx->User + (PUCHAR) AuthIdentity);
  746. }
  747. else
  748. {
  749. if ( !LsapIsBlockInKMap( KMap, AuthEx->User ) )
  750. {
  751. Status = STATUS_ACCESS_VIOLATION ;
  752. }
  753. }
  754. }
  755. if ( AuthEx->Domain )
  756. {
  757. if ( (ULONG_PTR) AuthEx->Domain > PoolBase)
  758. {
  759. AuthEx->Domain = (PWSTR) ( (ULONG_PTR) AuthEx->Domain - PoolBase );
  760. }
  761. if ( (ULONG_PTR) AuthEx->Domain < 0x10000 )
  762. {
  763. AuthEx->Domain = (PWSTR) ((ULONG_PTR)AuthEx->Domain + (PUCHAR) AuthIdentity);
  764. }
  765. else
  766. {
  767. if ( !LsapIsBlockInKMap( KMap, AuthEx->Domain ) )
  768. {
  769. Status = STATUS_ACCESS_VIOLATION ;
  770. }
  771. }
  772. }
  773. if ( AuthEx->Password )
  774. {
  775. if ( (ULONG_PTR) AuthEx->Password > PoolBase)
  776. {
  777. AuthEx->Password = (PWSTR) ( (ULONG_PTR) AuthEx->Password - PoolBase );
  778. }
  779. if ( (ULONG_PTR) AuthEx->Password < 0x10000 )
  780. {
  781. AuthEx->Password = (PWSTR) ((ULONG_PTR)AuthEx->Password + (PUCHAR) AuthIdentity);
  782. }
  783. else
  784. {
  785. if ( !LsapIsBlockInKMap( KMap, AuthEx->Password ) )
  786. {
  787. Status = STATUS_ACCESS_VIOLATION ;
  788. }
  789. }
  790. }
  791. if ( AuthEx->PackageList )
  792. {
  793. if ( (ULONG_PTR) AuthEx->PackageList > PoolBase)
  794. {
  795. AuthEx->PackageList = (PWSTR) ( (ULONG_PTR) AuthEx->PackageList - PoolBase );
  796. }
  797. if ( (ULONG_PTR) AuthEx->PackageList < 0x10000 )
  798. {
  799. AuthEx->PackageList = (PWSTR) ((ULONG_PTR)AuthEx->PackageList + (PUCHAR) AuthIdentity);
  800. }
  801. else
  802. {
  803. if ( !LsapIsBlockInKMap( KMap, AuthEx->PackageList ) )
  804. {
  805. Status = STATUS_ACCESS_VIOLATION ;
  806. }
  807. }
  808. }
  809. return Status ;
  810. }
  811. //+-------------------------------------------------------------------------
  812. //
  813. // Function: LpcAcquireCreds()
  814. //
  815. // Synopsis: Lpc stub for AcquireCredHandle
  816. //
  817. // Effects: Calls the WLsaAcquire function
  818. //
  819. // Arguments: pApiMessage - Input message
  820. // pApiMessage - Output message
  821. //
  822. // Requires:
  823. //
  824. // Returns:
  825. //
  826. // Notes:
  827. //
  828. //--------------------------------------------------------------------------
  829. NTSTATUS
  830. LpcAcquireCreds(
  831. PSPM_LPC_MESSAGE pApiMessage
  832. )
  833. {
  834. UNICODE_STRING ssPrincipalName;
  835. UNICODE_STRING ssPackageName;
  836. NTSTATUS scApiRet;
  837. NTSTATUS scRet;
  838. SPMAcquireCredsAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.AcquireCreds;
  839. PSession pSession ;
  840. PLSA_CALL_INFO CallInfo ;
  841. PUCHAR Where = NULL;
  842. pSession = GetCurrentSession();
  843. CallInfo = LsapGetCurrentCall();
  844. DebugLog((DEB_TRACE, "[%x] LpcAcquireCreds()\n", pSession->dwProcessID));
  845. ssPrincipalName.Buffer = NULL;
  846. ssPackageName.Buffer = NULL;
  847. if (pArgs->ssPrincipal.Buffer )
  848. {
  849. scRet = GetClientString(&pArgs->ssPrincipal,
  850. &ssPrincipalName,
  851. pApiMessage,
  852. &Where);
  853. if (FAILED(scRet))
  854. {
  855. DebugLog((DEB_ERROR, "GetClientString failed to get principal name 0x%08x\n", scRet));
  856. pApiMessage->ApiMessage.scRet = scRet;
  857. return(scRet);
  858. }
  859. } else {
  860. ssPrincipalName.MaximumLength = 0;
  861. ssPrincipalName.Length = 0;
  862. ssPrincipalName.Buffer = NULL;
  863. }
  864. scRet = GetClientString(&pArgs->ssSecPackage,
  865. &ssPackageName,
  866. pApiMessage,
  867. &Where);
  868. if (FAILED(scRet))
  869. {
  870. LsapFreePrivateHeap(ssPrincipalName.Buffer);
  871. DebugLog((DEB_ERROR, "GetClientString failed to get package name 0x%08x\n", scRet));
  872. pApiMessage->ApiMessage.scRet = scRet;
  873. return(scRet);
  874. }
  875. if ( CallInfo->Flags & CALL_FLAG_KERNEL_POOL )
  876. {
  877. scRet = LsapFixupAuthIdentity( CallInfo->KMap, pArgs->pvAuthData );
  878. if ( !NT_SUCCESS( scRet ) )
  879. {
  880. LsapFreePrivateHeap(ssPrincipalName.Buffer);
  881. LsapFreePrivateHeap(ssPackageName.Buffer);
  882. DebugLog((DEB_ERROR, "AuthData in KMap not formatted correctly\n" ));
  883. pApiMessage->ApiMessage.scRet = scRet;
  884. return(scRet);
  885. }
  886. }
  887. scApiRet = WLsaAcquireCredHandle( (PSECURITY_STRING) &ssPrincipalName,
  888. (PSECURITY_STRING) &ssPackageName,
  889. pArgs->fCredentialUse,
  890. &pArgs->LogonID,
  891. (PVOID) pArgs->pvAuthData,
  892. (PVOID) pArgs->pvGetKeyFn,
  893. (PVOID) pArgs->ulGetKeyArgument,
  894. &pArgs->hCredential,
  895. &pArgs->tsExpiry);
  896. //
  897. // Reset the reply flags:
  898. //
  899. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  900. DebugLog((DEB_TRACE_VERB, "[%x] WLsaAcquire returned %x\n", pSession->dwProcessID, scRet));
  901. LsapFreePrivateHeap(ssPackageName.Buffer);
  902. LsapFreePrivateHeap(ssPrincipalName.Buffer);
  903. pApiMessage->ApiMessage.scRet = scApiRet;
  904. if (FAILED(pApiMessage->ApiMessage.scRet))
  905. {
  906. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  907. }
  908. return(S_OK);
  909. }
  910. //+---------------------------------------------------------------------------
  911. //
  912. // Function: LpcFreeCredHandle
  913. //
  914. // Synopsis: Free a credential handle
  915. //
  916. // Arguments: [pApiMessage] --
  917. //
  918. // History: 8-14-98 RichardW Created
  919. //
  920. // Notes:
  921. //
  922. //----------------------------------------------------------------------------
  923. NTSTATUS
  924. LpcFreeCredHandle(
  925. PSPM_LPC_MESSAGE pApiMessage
  926. )
  927. {
  928. NTSTATUS hrApiRet;
  929. PSession pSession ;
  930. pSession = GetCurrentSession();
  931. DebugLog((DEB_TRACE, "[%x] LpcFreeCreds\n", pSession->dwProcessID));
  932. hrApiRet = WLsaFreeCredHandle(&pApiMessage->ApiMessage.Args.SpmArguments.API.FreeCredHandle.hCredential);
  933. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  934. pApiMessage->ApiMessage.scRet = hrApiRet;
  935. if (FAILED(hrApiRet))
  936. {
  937. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  938. }
  939. return(S_OK);
  940. }
  941. //+---------------------------------------------------------------------------
  942. //
  943. // Function: LsapCaptureBuffers
  944. //
  945. // Synopsis: Capture client buffers and counts to local memory, validating
  946. // as we go.
  947. //
  948. // Arguments: [InputBuffers] --
  949. // [MappedBuffers] --
  950. // [MapTokenBuffer] --
  951. //
  952. // History: 8-14-98 RichardW Created
  953. //
  954. // Notes:
  955. //
  956. //----------------------------------------------------------------------------
  957. NTSTATUS
  958. LsapCaptureBuffers(
  959. IN PUCHAR Base,
  960. IN PSecBufferDesc InputBuffers,
  961. OUT PSecBufferDesc MappedBuffers,
  962. OUT PVOID * CapturedBuffers,
  963. IN BOOLEAN MapTokenBuffers
  964. )
  965. {
  966. NTSTATUS Status = STATUS_SUCCESS ;
  967. PSecBuffer LocalCopy ;
  968. PSecBufferDesc Capture ;
  969. ULONG i ;
  970. //
  971. // Initialize them first:
  972. //
  973. *CapturedBuffers = NULL ;
  974. RtlZeroMemory(
  975. MappedBuffers->pBuffers,
  976. MappedBuffers->cBuffers * sizeof( SecBuffer ) );
  977. for (i = 0 ; i < MappedBuffers->cBuffers ; i++ )
  978. {
  979. MappedBuffers->pBuffers[ i ].BufferType = SECBUFFER_UNMAPPED ;
  980. }
  981. if ( InputBuffers->cBuffers > MappedBuffers->cBuffers )
  982. {
  983. return STATUS_INVALID_PARAMETER ;
  984. }
  985. //
  986. // Sizewise, we're safe to copy now:
  987. //
  988. if ( (ULONG_PTR) InputBuffers->pBuffers < PORT_MAXIMUM_MESSAGE_LENGTH )
  989. {
  990. if ( InputBuffers->cBuffers * sizeof( SecBuffer ) > CBPREPACK )
  991. {
  992. return STATUS_INVALID_PARAMETER ;
  993. }
  994. LocalCopy = (PSecBuffer) (Base +
  995. (ULONG_PTR) InputBuffers->pBuffers );
  996. RtlCopyMemory(
  997. MappedBuffers->pBuffers,
  998. LocalCopy,
  999. InputBuffers->cBuffers * sizeof( SecBuffer ) );
  1000. }
  1001. else
  1002. {
  1003. //
  1004. // They were too big to fit. Copy them directly from the client
  1005. // process:
  1006. //
  1007. Capture = (PSecBufferDesc) LsapAllocatePrivateHeap( sizeof( SecBufferDesc ) +
  1008. sizeof( SecBuffer ) * InputBuffers->cBuffers );
  1009. if ( Capture == NULL )
  1010. {
  1011. Status = SEC_E_INSUFFICIENT_MEMORY ;
  1012. }
  1013. else
  1014. {
  1015. Capture->pBuffers = (PSecBuffer) (Capture + 1);
  1016. Capture->cBuffers = InputBuffers->cBuffers ;
  1017. Capture->ulVersion = SECBUFFER_VERSION ;
  1018. Status = LsapCopyFromClient(
  1019. InputBuffers->pBuffers,
  1020. MappedBuffers->pBuffers,
  1021. InputBuffers->cBuffers * sizeof( SecBuffer ) );
  1022. if ( NT_SUCCESS( Status ) )
  1023. {
  1024. RtlCopyMemory(
  1025. Capture->pBuffers,
  1026. MappedBuffers->pBuffers,
  1027. InputBuffers->cBuffers * sizeof( SecBuffer ) );
  1028. *CapturedBuffers = Capture ;
  1029. }
  1030. else
  1031. {
  1032. LsapFreePrivateHeap( Capture );
  1033. }
  1034. }
  1035. }
  1036. if ( !NT_SUCCESS( Status ) )
  1037. {
  1038. for ( i = 0 ; i < MappedBuffers->cBuffers ; i++ )
  1039. {
  1040. MappedBuffers->pBuffers[ i ].BufferType = SECBUFFER_UNMAPPED ;
  1041. }
  1042. return Status ;
  1043. }
  1044. //
  1045. // Touch up the mapped buffers so that the count is correct
  1046. //
  1047. MappedBuffers->cBuffers = InputBuffers->cBuffers ;
  1048. //
  1049. // try to map the security blob one:
  1050. //
  1051. if ( MapTokenBuffers )
  1052. {
  1053. Status = MapTokenBuffer(
  1054. MappedBuffers,
  1055. TRUE );
  1056. }
  1057. else
  1058. {
  1059. Status = STATUS_SUCCESS ;
  1060. }
  1061. return Status ;
  1062. }
  1063. VOID
  1064. LsapResetKsecBuffer(
  1065. PKSEC_LSA_MEMORY_HEADER Header
  1066. )
  1067. {
  1068. Header->Consumed = Header->Preserve ;
  1069. Header->MapCount = 0 ;
  1070. RtlZeroMemory( Header->PoolMap, sizeof( KSEC_LSA_POOL_MAP ) * KSEC_LSA_MAX_MAPS );
  1071. }
  1072. //+---------------------------------------------------------------------------
  1073. //
  1074. // Function: LsapCreateKsecBuffer
  1075. //
  1076. // Synopsis: Creates a kmap buffer to return to ksecdd
  1077. //
  1078. // Arguments: [InitialSize] -- Minimum size of the buffer
  1079. //
  1080. // History: 2-9-01 RichardW Created
  1081. //
  1082. // Notes:
  1083. //
  1084. //----------------------------------------------------------------------------
  1085. PKSEC_LSA_MEMORY_HEADER
  1086. LsapCreateKsecBuffer(
  1087. SIZE_T InitialSize
  1088. )
  1089. {
  1090. PKSEC_LSA_MEMORY_HEADER Header = NULL ;
  1091. NTSTATUS Status ;
  1092. SIZE_T Size = LSA_MAX_KMAP_SIZE ;
  1093. InitialSize += sizeof( KSEC_LSA_MEMORY_HEADER );
  1094. DsysAssert( InitialSize < Size );
  1095. Status = NtAllocateVirtualMemory(
  1096. NtCurrentProcess(),
  1097. (PVOID *) &Header,
  1098. 0,
  1099. &Size,
  1100. MEM_RESERVE,
  1101. PAGE_READWRITE );
  1102. if ( NT_SUCCESS( Status ) )
  1103. {
  1104. Status = NtAllocateVirtualMemory(
  1105. NtCurrentProcess(),
  1106. (PVOID *) &Header,
  1107. 0,
  1108. &InitialSize,
  1109. MEM_COMMIT,
  1110. PAGE_READWRITE );
  1111. if ( NT_SUCCESS( Status ) )
  1112. {
  1113. Header->Size = LSA_MAX_KMAP_SIZE ;
  1114. Header->Commit = (ULONG) InitialSize ;
  1115. Header->Preserve = sizeof( KSEC_LSA_MEMORY_HEADER );
  1116. LsapResetKsecBuffer( Header );
  1117. }
  1118. else
  1119. {
  1120. NtFreeVirtualMemory(
  1121. NtCurrentProcess(),
  1122. (PVOID *) &Header,
  1123. 0,
  1124. MEM_RELEASE );
  1125. Header = NULL ;
  1126. }
  1127. }
  1128. return Header ;
  1129. }
  1130. PVOID
  1131. LsapAllocateFromKsecBuffer(
  1132. PKSEC_LSA_MEMORY_HEADER Header,
  1133. ULONG Size
  1134. )
  1135. {
  1136. SIZE_T DesiredSize ;
  1137. NTSTATUS Status ;
  1138. PVOID Block ;
  1139. PVOID Page ;
  1140. Size = ROUND_UP_COUNT( Size, ALIGN_LPVOID );
  1141. if ( Header->Consumed + Size > Header->Commit )
  1142. {
  1143. DesiredSize = Header->Commit - Header->Consumed + Size ;
  1144. DesiredSize = ROUND_UP_COUNT( DesiredSize, LsapPageSize );
  1145. Page = (PUCHAR) Header + Header->Commit ;
  1146. Status = NtAllocateVirtualMemory(
  1147. NtCurrentProcess(),
  1148. &Page,
  1149. 0,
  1150. &DesiredSize,
  1151. MEM_COMMIT,
  1152. PAGE_READWRITE );
  1153. if ( NT_SUCCESS( Status ) )
  1154. {
  1155. Header->Commit += (ULONG) DesiredSize ;
  1156. }
  1157. }
  1158. if ( Header->Consumed + Size <= Header->Commit )
  1159. {
  1160. Block = (PVOID) ((PUCHAR) Header + Header->Consumed) ;
  1161. Header->Consumed += Size ;
  1162. }
  1163. else
  1164. {
  1165. Block = NULL ;
  1166. }
  1167. return Block ;
  1168. }
  1169. //+---------------------------------------------------------------------------
  1170. //
  1171. // Function: LsapUncaptureBuffers
  1172. //
  1173. // Synopsis: Return all the buffers to the client process.
  1174. //
  1175. // Arguments: [Base] -- Base address of message
  1176. // [CapturedBuffers]-- Captured buffer descriptions
  1177. // [InputBuffers] -- Buffers supplied by the client
  1178. // [MappedBuffers] -- Mapped buffers
  1179. // [AllocateMemory] -- Allocate memory for
  1180. //
  1181. // History: 8-14-98 RichardW Created
  1182. //
  1183. // Notes:
  1184. //
  1185. //----------------------------------------------------------------------------
  1186. NTSTATUS
  1187. LsapUncaptureBuffers(
  1188. IN PUCHAR Base,
  1189. IN OUT PVOID * CapturedBuffers,
  1190. IN OUT PSecBufferDesc InputBuffers,
  1191. IN OUT PSecBufferDesc MappedBuffers,
  1192. IN BOOL AllocateMemory,
  1193. IN BOOL CopyBack,
  1194. OUT PULONG pFlags
  1195. )
  1196. {
  1197. NTSTATUS Status = STATUS_SUCCESS ;
  1198. PSecBuffer Buffers ;
  1199. PSecBufferDesc Capture ;
  1200. ULONG i ;
  1201. PVOID Scratch ;
  1202. PVOID ScratchBuffers[ MAX_SECBUFFERS ];
  1203. PSecBufferDesc Input;
  1204. SecBufferDesc InputFixup ;
  1205. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  1206. DebugLog(( DEB_TRACE_SPECIAL, "LsapUncaptureBuffers:\n" ));
  1207. RtlZeroMemory( ScratchBuffers, sizeof( ScratchBuffers ) );
  1208. Capture = (PSecBufferDesc) *CapturedBuffers ;
  1209. if ( InputBuffers )
  1210. {
  1211. if ( Capture )
  1212. {
  1213. DebugLog(( DEB_TRACE_SPECIAL, " using captured buffers\n" ));
  1214. Input = Capture ;
  1215. }
  1216. else
  1217. {
  1218. if ( (ULONG_PTR) InputBuffers->pBuffers < PORT_MAXIMUM_MESSAGE_LENGTH )
  1219. {
  1220. //
  1221. // Time to fix up:
  1222. //
  1223. InputFixup.pBuffers = (PSecBuffer) (Base + (ULONG_PTR) InputBuffers->pBuffers );
  1224. InputFixup.cBuffers = InputBuffers->cBuffers ;
  1225. InputFixup.ulVersion = SECBUFFER_VERSION ;
  1226. Input = &InputFixup ;
  1227. DebugLog(( DEB_TRACE_SPECIAL, " using buffers in message\n" ));
  1228. }
  1229. else
  1230. {
  1231. Input = InputBuffers ;
  1232. DebugLog(( DEB_TRACE_SPECIAL, " using buffers from caller\n" ));
  1233. }
  1234. }
  1235. //
  1236. // First, handle the map back to the client process
  1237. //
  1238. for ( i = 0 ; i < MappedBuffers->cBuffers ; i++ )
  1239. {
  1240. //
  1241. // If this is a read only buffer, or it was not mapped across,
  1242. // skip it. There is no change that will go back to the client.
  1243. //
  1244. DebugLog(( DEB_TRACE_SPECIAL, " Processing buffer %d, <t=%x [%c%c%c],cb=%x,pv=%p>\n",
  1245. i,
  1246. MappedBuffers->pBuffers[ i ].BufferType & ~SECBUFFER_ATTRMASK,
  1247. (MappedBuffers->pBuffers[ i ].BufferType & SECBUFFER_READONLY ? 'R' : ' '),
  1248. (MappedBuffers->pBuffers[ i ].BufferType & SECBUFFER_UNMAPPED ? 'U' : ' '),
  1249. (MappedBuffers->pBuffers[ i ].BufferType & SECBUFFER_KERNEL_MAP ? 'K' : ' '),
  1250. MappedBuffers->pBuffers[ i ].cbBuffer,
  1251. MappedBuffers->pBuffers[ i ].pvBuffer ));
  1252. //
  1253. // For readonly or untouched buffers, skip them.
  1254. //
  1255. if ( ( MappedBuffers->pBuffers[ i ].BufferType & SECBUFFER_ATTRMASK ) ==
  1256. ( SECBUFFER_READONLY | SECBUFFER_UNMAPPED ) )
  1257. {
  1258. DebugLog(( DEB_TRACE_SPECIAL, " Buffer %d: skipped\n", i ));
  1259. continue;
  1260. }
  1261. //
  1262. // If this is a SSPI security blob (aka a token), decide what
  1263. // needs to be done:
  1264. //
  1265. if ( ( MappedBuffers->pBuffers[ i ].BufferType & (~SECBUFFER_ATTRMASK) )
  1266. == SECBUFFER_TOKEN )
  1267. {
  1268. if ( ( MappedBuffers->pBuffers[ i ].cbBuffer > 0 ) &&
  1269. ( CopyBack ) )
  1270. {
  1271. DebugLog(( DEB_TRACE_SPECIAL, " Copying back buffer %d\n", i ));
  1272. if ( CallInfo->Flags & CALL_FLAG_KMAP_USED )
  1273. {
  1274. //
  1275. // KMap case:
  1276. //
  1277. Scratch = LsapAllocateFromKsecBuffer(
  1278. CallInfo->KMap,
  1279. MappedBuffers->pBuffers[ i ].cbBuffer
  1280. );
  1281. if ( !Scratch )
  1282. {
  1283. Status = SEC_E_INSUFFICIENT_MEMORY ;
  1284. break;
  1285. }
  1286. *pFlags |= SPMAPI_FLAG_KMAP_MEM ;
  1287. }
  1288. else if ( AllocateMemory )
  1289. {
  1290. Scratch = LsapClientAllocate(
  1291. MappedBuffers->pBuffers[ i ].cbBuffer
  1292. );
  1293. //
  1294. // Allocation failed, break out of the loop with a failure
  1295. // status code, and handle the failure there:
  1296. //
  1297. if ( !Scratch )
  1298. {
  1299. Status = SEC_E_INSUFFICIENT_MEMORY ;
  1300. break;
  1301. }
  1302. *pFlags |= SPMAPI_FLAG_MEMORY;
  1303. }
  1304. else
  1305. {
  1306. Scratch = Input->pBuffers[ i ].pvBuffer ;
  1307. if ( Input->pBuffers[ i ].cbBuffer <
  1308. MappedBuffers->pBuffers[ i ].cbBuffer )
  1309. {
  1310. //
  1311. // Buffer too small. Break out and return the failure
  1312. //
  1313. Status = STATUS_BUFFER_TOO_SMALL ;
  1314. break;
  1315. }
  1316. }
  1317. //
  1318. // Copy the buffer back to the client address space
  1319. //
  1320. ScratchBuffers[ i ] = Scratch ;
  1321. if ( CallInfo->Flags & CALL_FLAG_KMAP_USED )
  1322. {
  1323. DebugLog(( DEB_TRACE_SPECIAL, " Copying %x bytes from %p to %p [KMap]\n",
  1324. MappedBuffers->pBuffers[ i ].cbBuffer,
  1325. MappedBuffers->pBuffers[ i ].pvBuffer,
  1326. Scratch ));
  1327. RtlCopyMemory(
  1328. Scratch,
  1329. MappedBuffers->pBuffers[ i ].pvBuffer,
  1330. MappedBuffers->pBuffers[ i ].cbBuffer );
  1331. Status = STATUS_SUCCESS ;
  1332. }
  1333. else
  1334. {
  1335. DebugLog(( DEB_TRACE_SPECIAL, " Copying %x bytes from %p to %p\n",
  1336. MappedBuffers->pBuffers[ i ].cbBuffer,
  1337. MappedBuffers->pBuffers[ i ].pvBuffer,
  1338. Scratch ));
  1339. Status = LsapCopyToClient(
  1340. MappedBuffers->pBuffers[ i ].pvBuffer,
  1341. Scratch,
  1342. MappedBuffers->pBuffers[ i ].cbBuffer
  1343. );
  1344. }
  1345. if ( !NT_SUCCESS( Status ) )
  1346. {
  1347. break;
  1348. }
  1349. }
  1350. else
  1351. {
  1352. //
  1353. // For zero length buffers that appear to be mapped, set scratch
  1354. // equal to the original input value.
  1355. //
  1356. DebugLog(( DEB_TRACE_SPECIAL, " Zero length buffer\n" ));
  1357. ScratchBuffers[ i ] = Input->pBuffers[ i ].pvBuffer ;
  1358. }
  1359. }
  1360. else
  1361. {
  1362. //
  1363. // This is not a token buffer, it is a EXTRA, or PADDING, or
  1364. // one of those. Turn off the mapping bit, and copy out
  1365. // the buffer value.
  1366. //
  1367. DebugLog(( DEB_TRACE_SPECIAL, " Special buffer [%p] passed back\n",
  1368. Input->pBuffers[ i ].pvBuffer ));
  1369. ScratchBuffers[ i ] = Input->pBuffers[ i ].pvBuffer ;
  1370. }
  1371. }
  1372. }
  1373. else
  1374. {
  1375. DebugLog(( DEB_TRACE_SPECIAL, "InputBuffers is NULL, just walking and freeing\n" ));
  1376. }
  1377. //
  1378. // Now go through and free any allocated memory
  1379. //
  1380. for ( i = 0 ; i < MappedBuffers->cBuffers ; i++ )
  1381. {
  1382. if ( (MappedBuffers->pBuffers[ i ].BufferType & SECBUFFER_UNMAPPED) == 0 )
  1383. {
  1384. //
  1385. // This buffer was mapped in. Free it.
  1386. //
  1387. if ( !LsapIsBlockInKMap( CallInfo->KMap, MappedBuffers->pBuffers[ i ].pvBuffer ) )
  1388. {
  1389. LsapFreeLsaHeap( MappedBuffers->pBuffers[ i ].pvBuffer );
  1390. }
  1391. else
  1392. {
  1393. DebugLog(( DEB_TRACE_SPECIAL, "Buffer at %p is in KMap\n", MappedBuffers->pBuffers[ i ].pvBuffer ));
  1394. }
  1395. }
  1396. //
  1397. // Turn off our bit
  1398. //
  1399. MappedBuffers->pBuffers[ i ].BufferType &= ~(SECBUFFER_UNMAPPED);
  1400. //
  1401. // If we allocated a new buffer (here or in the client), it's
  1402. // been stored away in the scratch array, and we copy it in
  1403. //
  1404. if ( ScratchBuffers[ i ] )
  1405. {
  1406. MappedBuffers->pBuffers[ i ].pvBuffer = ScratchBuffers[ i ];
  1407. }
  1408. }
  1409. if ( InputBuffers )
  1410. {
  1411. if ( NT_SUCCESS( Status ) )
  1412. {
  1413. //
  1414. // Now, copy back the buffer descriptors. Note that in the normal (optimal)
  1415. // case, this will fit into the LPC message. Otherwise, we have to copy
  1416. if ( (ULONG_PTR) InputBuffers->pBuffers < PORT_MAXIMUM_MESSAGE_LENGTH )
  1417. {
  1418. Buffers = (PSecBuffer) (Base + (ULONG_PTR) InputBuffers->pBuffers );
  1419. RtlCopyMemory(
  1420. Buffers,
  1421. MappedBuffers->pBuffers,
  1422. MappedBuffers->cBuffers * sizeof( SecBuffer ) );
  1423. }
  1424. else
  1425. {
  1426. Status = LsapCopyToClient(
  1427. MappedBuffers->pBuffers,
  1428. InputBuffers->pBuffers,
  1429. MappedBuffers->cBuffers * sizeof( SecBuffer ) );
  1430. }
  1431. InputBuffers->cBuffers = MappedBuffers->cBuffers ;
  1432. }
  1433. }
  1434. if ( Capture )
  1435. {
  1436. LsapFreePrivateHeap( Capture );
  1437. *CapturedBuffers = NULL ;
  1438. }
  1439. return Status ;
  1440. }
  1441. //+---------------------------------------------------------------------------
  1442. //
  1443. // Function: LsapChangeBuffer
  1444. //
  1445. // Synopsis: Switches a buffer around. If the old one needs to be freed,
  1446. // it is cleaned up.
  1447. //
  1448. // Arguments: [Old] --
  1449. // [New] --
  1450. //
  1451. // Returns:
  1452. //
  1453. // Notes:
  1454. //
  1455. //----------------------------------------------------------------------------
  1456. NTSTATUS
  1457. LsapChangeBuffer(
  1458. PSecBuffer Old,
  1459. PSecBuffer New
  1460. )
  1461. {
  1462. if ( ( Old->BufferType & SECBUFFER_KERNEL_MAP ) == 0 )
  1463. {
  1464. if ( ( Old->BufferType & SECBUFFER_UNMAPPED ) == 0 )
  1465. {
  1466. LsapFreeLsaHeap( Old->pvBuffer );
  1467. }
  1468. }
  1469. *Old = *New ;
  1470. return STATUS_SUCCESS ;
  1471. }
  1472. NTSTATUS
  1473. LsapCheckMarshalledTargetInfo(
  1474. IN PUNICODE_STRING TargetServerName
  1475. )
  1476. {
  1477. PWSTR Candidate;
  1478. ULONG CandidateSize;
  1479. NTSTATUS Status = STATUS_SUCCESS;
  1480. //
  1481. // if target info wasn't supplied, or the length doesn't look like it
  1482. // includes the marshalled version, do nothing.
  1483. //
  1484. if( (TargetServerName == NULL) ||
  1485. (TargetServerName->Buffer == NULL) ||
  1486. (TargetServerName->Length < (sizeof( CREDENTIAL_TARGET_INFORMATIONW ) / (sizeof(ULONG_PTR)/2)) )
  1487. )
  1488. {
  1489. return STATUS_SUCCESS;
  1490. }
  1491. RtlCopyMemory(
  1492. &CandidateSize,
  1493. (PBYTE)TargetServerName->Buffer + TargetServerName->Length - sizeof(ULONG),
  1494. sizeof( CandidateSize )
  1495. );
  1496. if( TargetServerName->Length <= CandidateSize )
  1497. {
  1498. return STATUS_SUCCESS;
  1499. }
  1500. Candidate = (PWSTR)(
  1501. (PBYTE)TargetServerName->Buffer + TargetServerName->Length - CandidateSize
  1502. );
  1503. Status = CredUnmarshalTargetInfo (
  1504. Candidate,
  1505. CandidateSize,
  1506. NULL
  1507. );
  1508. if( !NT_SUCCESS(Status) )
  1509. {
  1510. if( Status == STATUS_INVALID_PARAMETER )
  1511. {
  1512. Status = STATUS_SUCCESS;
  1513. }
  1514. } else {
  1515. //
  1516. // marshalled information was found. adjust the Length to
  1517. // represent the non-marshalled content, and MaximumLength to
  1518. // include non-marshalled+marshalled content. This allows legacy
  1519. // packages to continue to handle the TargetServerName string properly.
  1520. //
  1521. TargetServerName->MaximumLength = TargetServerName->Length;
  1522. TargetServerName->Length -= (USHORT)CandidateSize;
  1523. }
  1524. return Status ;
  1525. }
  1526. //+-------------------------------------------------------------------------
  1527. //
  1528. // Function: LpcInitContext()
  1529. //
  1530. // Synopsis: LPC Serverside InitializeSecurityContext
  1531. //
  1532. // Notes: OutputBuffers and LocalOutput are the local copy of the
  1533. // output buffers. The secbuffers in the ApiMessage point
  1534. // to client addresses.
  1535. //
  1536. //--------------------------------------------------------------------------
  1537. NTSTATUS
  1538. LpcInitContext(
  1539. PSPM_LPC_MESSAGE pApiMessage
  1540. )
  1541. {
  1542. UNICODE_STRING ssTarget = {0,0,NULL};
  1543. NTSTATUS scApiRet;
  1544. NTSTATUS scRet;
  1545. ULONG i;
  1546. PSecBufferDesc pOutput = NULL;
  1547. PSecBufferDesc pInput = NULL;
  1548. PVOID CapturedInput = NULL ;
  1549. PVOID CapturedOutput = NULL ;
  1550. SecBufferDesc LocalOutput;
  1551. SecBufferDesc LocalInput ;
  1552. SPMInitContextAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.InitContext;
  1553. PUCHAR Where = NULL;
  1554. SecBuffer ContextData = {0,0,NULL};
  1555. SecBuffer OutputBuffers[MAX_SECBUFFERS];
  1556. SecBuffer InputBuffers[MAX_SECBUFFERS];
  1557. PSession pSession ;
  1558. BOOLEAN MappedOutput = FALSE;
  1559. BOOLEAN FirstCall ;
  1560. DWORD Flags ;
  1561. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  1562. pSession = GetCurrentSession();
  1563. DebugLog((DEB_TRACE, "[%x] LpcInitContext()\n", pSession->dwProcessID));
  1564. DebugLog((DEB_TRACE_VERB, " hCredentials = %d:%d\n",
  1565. pArgs->hCredential.dwUpper,
  1566. pArgs->hCredential.dwLower));
  1567. //
  1568. // Copy target string to local space:
  1569. //
  1570. scRet = GetClientString(&pArgs->ssTarget,
  1571. &ssTarget,
  1572. pApiMessage,
  1573. &Where);
  1574. if (FAILED(scRet))
  1575. {
  1576. pApiMessage->ApiMessage.scRet = scRet;
  1577. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  1578. DebugLog((DEB_ERROR, "LpcInitContext, no target, error %x\n", scRet));
  1579. return(scRet);
  1580. }
  1581. //
  1582. // check if the caller supplied marshalled target info.
  1583. // this will update the Length and MaximumLength fields
  1584. // if marshalled info was present.
  1585. //
  1586. LsapCheckMarshalledTargetInfo( &ssTarget );
  1587. //
  1588. // Set all the SecBuffer's to be unmapped, but map the Security token
  1589. //
  1590. LocalInput.pBuffers = InputBuffers ;
  1591. LocalInput.ulVersion = SECBUFFER_VERSION ;
  1592. if (pArgs->sbdInput.cBuffers)
  1593. {
  1594. pInput = &pArgs->sbdInput;
  1595. //
  1596. // If there is a buffer, reset the pointer and
  1597. // map it
  1598. //
  1599. LocalInput.cBuffers = MAX_SECBUFFERS ;
  1600. scRet = LsapCaptureBuffers(
  1601. (PUCHAR) pArgs,
  1602. pInput,
  1603. &LocalInput,
  1604. &CapturedInput,
  1605. TRUE );
  1606. if ( !NT_SUCCESS( scRet ) )
  1607. {
  1608. pInput = NULL ;
  1609. scApiRet = scRet ;
  1610. goto InitCleanExit ;
  1611. }
  1612. }
  1613. else
  1614. {
  1615. LocalInput.pBuffers = InputBuffers ;
  1616. LocalInput.cBuffers = 0 ;
  1617. LocalInput.ulVersion = SECBUFFER_VERSION ;
  1618. }
  1619. //
  1620. // Copy the output SecBuffer's so that if they get mapped we can
  1621. // still copy back the data
  1622. //
  1623. pOutput = &pArgs->sbdOutput;
  1624. if (pOutput->cBuffers)
  1625. {
  1626. LocalOutput.cBuffers = MAX_SECBUFFERS ;
  1627. LocalOutput.pBuffers = OutputBuffers;
  1628. LocalOutput.ulVersion = SECBUFFER_VERSION ;
  1629. scRet = LsapCaptureBuffers(
  1630. (PUCHAR) pArgs,
  1631. pOutput,
  1632. &LocalOutput,
  1633. &CapturedOutput,
  1634. FALSE );
  1635. if ( !NT_SUCCESS( scRet ) )
  1636. {
  1637. scApiRet = scRet ;
  1638. goto Init_FreeStringAndExit ;
  1639. }
  1640. MappedOutput = TRUE;
  1641. }
  1642. else
  1643. {
  1644. LocalOutput.cBuffers = 0 ;
  1645. LocalOutput.pBuffers = OutputBuffers ;
  1646. LocalOutput.ulVersion = SECBUFFER_VERSION ;
  1647. }
  1648. if (pArgs->sbdOutput.cBuffers &&
  1649. !(pArgs->fContextReq & ISC_REQ_ALLOCATE_MEMORY))
  1650. {
  1651. if (FAILED(scRet = MapTokenBuffer(&LocalOutput, FALSE)))
  1652. {
  1653. scApiRet = scRet;
  1654. goto InitCleanExit;
  1655. }
  1656. }
  1657. //
  1658. // Call the worker for relay to the package:
  1659. //
  1660. if ( ( pArgs->hContext.dwUpper == 0 ) &&
  1661. ( pArgs->hContext.dwLower == 0 ) )
  1662. {
  1663. FirstCall = TRUE ;
  1664. }
  1665. else
  1666. {
  1667. FirstCall = FALSE ;
  1668. }
  1669. scApiRet = WLsaInitContext( &pArgs->hCredential,
  1670. &pArgs->hContext,
  1671. (PSECURITY_STRING) &ssTarget,
  1672. pArgs->fContextReq,
  1673. pArgs->dwReserved1,
  1674. pArgs->TargetDataRep,
  1675. &LocalInput, // &pArgs->sbdInput,
  1676. pArgs->dwReserved2,
  1677. &pArgs->hNewContext,
  1678. &LocalOutput,
  1679. &pArgs->fContextAttr,
  1680. &pArgs->tsExpiry,
  1681. &pArgs->MappedContext,
  1682. &ContextData );
  1683. // DsysAssert( scApiRet != SEC_E_INVALID_HANDLE );
  1684. if( scApiRet == SEC_E_INVALID_HANDLE ||
  1685. scApiRet == STATUS_INVALID_HANDLE )
  1686. {
  1687. DebugLog((DEB_ERROR, "[%x] LpcInitContext() returning invalid handle\n", pSession->dwProcessID));
  1688. DebugLog((DEB_ERROR, " hCredentials = %p:%p\n",
  1689. pArgs->hCredential.dwUpper,
  1690. pArgs->hCredential.dwLower));
  1691. DebugLog((DEB_ERROR, " hContext = %p:%p\n",
  1692. pArgs->hContext.dwUpper,
  1693. pArgs->hContext.dwLower));
  1694. DsysAssert( scApiRet == STATUS_SUCCESS );
  1695. }
  1696. //
  1697. // Reset the reply flags:
  1698. //
  1699. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  1700. //
  1701. // If this is the failure case, don't bother copying everything down.
  1702. //
  1703. if (FAILED(scApiRet))
  1704. {
  1705. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  1706. //
  1707. // Unmap any output buffers
  1708. //
  1709. Flags = 0 ;
  1710. scRet = LsapUncaptureBuffers(
  1711. (PUCHAR) pArgs,
  1712. &CapturedOutput,
  1713. &pArgs->sbdOutput,
  1714. &LocalOutput,
  1715. FALSE,
  1716. FALSE,
  1717. &Flags );
  1718. }
  1719. else
  1720. {
  1721. //
  1722. // Now we have to look at the output and copy all the mapped
  1723. // buffers back.
  1724. //
  1725. Flags = pApiMessage->ApiMessage.Args.SpmArguments.fAPI ;
  1726. //
  1727. // if a KMap is present, use it.
  1728. //
  1729. if ( CallInfo->KMap )
  1730. {
  1731. CallInfo->Flags |= CALL_FLAG_KMAP_USED ;
  1732. }
  1733. scRet = LsapUncaptureBuffers(
  1734. (PUCHAR) pArgs,
  1735. &CapturedOutput,
  1736. &pArgs->sbdOutput,
  1737. &LocalOutput,
  1738. (pArgs->fContextReq & ISC_REQ_ALLOCATE_MEMORY) ? TRUE : FALSE,
  1739. TRUE,
  1740. &Flags );
  1741. pApiMessage->ApiMessage.Args.SpmArguments.fAPI = (USHORT) Flags ;
  1742. if (NT_SUCCESS(scRet) && (ContextData.cbBuffer != 0))
  1743. {
  1744. pArgs->ContextData = ContextData;
  1745. pArgs->ContextData.pvBuffer = LsapClientAllocate(ContextData.cbBuffer);
  1746. if ( pArgs->ContextData.pvBuffer )
  1747. {
  1748. scRet = LsapCopyToClient(
  1749. ContextData.pvBuffer,
  1750. pArgs->ContextData.pvBuffer,
  1751. ContextData.cbBuffer
  1752. );
  1753. }
  1754. else
  1755. {
  1756. scRet = SEC_E_INSUFFICIENT_MEMORY ;
  1757. }
  1758. }
  1759. if (FAILED(scRet))
  1760. {
  1761. //
  1762. // Again, we have a real problem when this fails. We
  1763. // abort the context and return an error.
  1764. //
  1765. if ( FirstCall )
  1766. {
  1767. AbortLpcContext(&pArgs->hContext);
  1768. }
  1769. scApiRet = scRet;
  1770. goto InitCleanExit;
  1771. }
  1772. }
  1773. InitCleanExit:
  1774. pApiMessage->ApiMessage.scRet = scApiRet;
  1775. //
  1776. // Unmap the input buffers
  1777. //
  1778. scRet = LsapUncaptureBuffers(
  1779. (PUCHAR) pArgs,
  1780. &CapturedInput,
  1781. &pArgs->sbdInput,
  1782. &LocalInput,
  1783. FALSE,
  1784. FALSE,
  1785. NULL );
  1786. if (ContextData.pvBuffer != NULL)
  1787. {
  1788. LsapFreeLsaHeap(ContextData.pvBuffer);
  1789. }
  1790. if (FAILED(scRet) && (pArgs->ContextData.pvBuffer != NULL))
  1791. {
  1792. LsapClientFree(pArgs->ContextData.pvBuffer);
  1793. pArgs->ContextData.pvBuffer;
  1794. }
  1795. Init_FreeStringAndExit:
  1796. //
  1797. // Test the string pointer. If it is within the KMap, do
  1798. // not free it. If there is no KMap, or it was separately
  1799. // allocated, free it:
  1800. //
  1801. if ( !LsapIsBlockInKMap( CallInfo->KMap, ssTarget.Buffer ) )
  1802. {
  1803. LsapFreePrivateHeap( ssTarget.Buffer );
  1804. }
  1805. return(scRet);
  1806. }
  1807. //+-------------------------------------------------------------------------
  1808. //
  1809. // Function: LpcAcceptContext()
  1810. //
  1811. // Synopsis:
  1812. //
  1813. // Effects:
  1814. //
  1815. // Arguments:
  1816. //
  1817. // Requires:
  1818. //
  1819. // Returns:
  1820. //
  1821. // Notes: The memory management is kind of weird. The input buffers
  1822. // are mapped into the SPMgr's memory and can be freed. Easy.
  1823. // The output buffers are more complex. The original buffer
  1824. // pointers are kep in the arguments structure, while the
  1825. // local copies are kept in LocalOutput.
  1826. //
  1827. //--------------------------------------------------------------------------
  1828. NTSTATUS
  1829. LpcAcceptContext(
  1830. PSPM_LPC_MESSAGE pApiMessage
  1831. )
  1832. {
  1833. NTSTATUS scRet = S_OK;
  1834. NTSTATUS scApiRet;
  1835. PSession pSession ;
  1836. ULONG i;
  1837. SecBufferDesc LocalOutput;
  1838. SecBufferDesc LocalInput ;
  1839. PSecBufferDesc pInput = NULL;
  1840. PSecBufferDesc pOutput = NULL ;
  1841. SPMAcceptContextAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.AcceptContext;
  1842. BOOLEAN MappedOutput = FALSE;
  1843. BOOLEAN FirstCall ;
  1844. BOOL CopyBack = FALSE ;
  1845. DWORD Flags ;
  1846. PVOID CapturedInput = NULL ;
  1847. PVOID CapturedOutput = NULL ;
  1848. SecBuffer OutputBuffers[MAX_SECBUFFERS];
  1849. SecBuffer InputBuffers[MAX_SECBUFFERS];
  1850. SecBuffer ContextData = {0,0,NULL};
  1851. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  1852. pSession = GetCurrentSession();
  1853. DebugLog((DEB_TRACE, "[%x] LpcAcceptContext\n", pSession->dwProcessID));
  1854. // Copy input token to local space:
  1855. //
  1856. // Set all the SecBuffer's to be unmapped, but map the Security token
  1857. //
  1858. pInput = &pArgs->sbdInput;
  1859. LocalInput.pBuffers = InputBuffers ;
  1860. LocalInput.cBuffers = MAX_SECBUFFERS ;
  1861. LocalInput.ulVersion = SECBUFFER_VERSION ;
  1862. if (pInput->cBuffers)
  1863. {
  1864. scRet = LsapCaptureBuffers(
  1865. (PUCHAR) pArgs,
  1866. pInput,
  1867. &LocalInput,
  1868. &CapturedInput,
  1869. TRUE );
  1870. if ( !NT_SUCCESS( scRet ) )
  1871. {
  1872. scApiRet = scRet;
  1873. goto AcceptCleanExit;
  1874. }
  1875. }
  1876. else
  1877. {
  1878. LocalInput.cBuffers = 0 ;
  1879. }
  1880. //
  1881. // Copy the output SecBuffer's so that if they get mapped we can
  1882. // still copy back the data
  1883. //
  1884. LocalOutput.cBuffers = MAX_SECBUFFERS ;
  1885. LocalOutput.pBuffers = OutputBuffers ;
  1886. LocalOutput.ulVersion = SECBUFFER_VERSION ;
  1887. pOutput = &pArgs->sbdOutput ;
  1888. if ( pOutput->cBuffers )
  1889. {
  1890. scRet = LsapCaptureBuffers(
  1891. (PUCHAR) pArgs,
  1892. pOutput,
  1893. &LocalOutput,
  1894. &CapturedOutput,
  1895. FALSE );
  1896. if ( !NT_SUCCESS( scRet ) )
  1897. {
  1898. scApiRet = scRet ;
  1899. goto AcceptCleanExit ;
  1900. }
  1901. #if DBG
  1902. if ( (pArgs->fContextReq & ASC_REQ_ALLOCATE_MEMORY ) == 0 )
  1903. {
  1904. for ( i = 0 ; i < LocalOutput.cBuffers ; i++ )
  1905. {
  1906. if ( (LocalOutput.pBuffers[ i ].BufferType & (~SECBUFFER_ATTRMASK)) == SECBUFFER_TOKEN )
  1907. {
  1908. DsysAssert( LocalOutput.pBuffers[ i ].cbBuffer > 0 );
  1909. }
  1910. }
  1911. }
  1912. #endif
  1913. }
  1914. else
  1915. {
  1916. LocalOutput.cBuffers = 0 ;
  1917. }
  1918. MappedOutput = TRUE;
  1919. if (LocalOutput.cBuffers &&
  1920. !(pArgs->fContextReq & ASC_REQ_ALLOCATE_MEMORY))
  1921. {
  1922. if (FAILED(scRet = MapTokenBuffer(&LocalOutput,FALSE)))
  1923. {
  1924. scApiRet = scRet;
  1925. goto AcceptCleanExit;
  1926. }
  1927. }
  1928. else
  1929. {
  1930. //
  1931. // Since they asked us to allocate memory, ensure the output
  1932. // buffers are NULL.
  1933. //
  1934. for (i = 0; i < LocalOutput.cBuffers ; i++ )
  1935. {
  1936. LocalOutput.pBuffers[i].pvBuffer = NULL;
  1937. }
  1938. }
  1939. if ( ( pArgs->hContext.dwUpper == 0 ) &&
  1940. ( pArgs->hContext.dwLower == 0 ) )
  1941. {
  1942. FirstCall = TRUE ;
  1943. }
  1944. else
  1945. {
  1946. FirstCall = FALSE ;
  1947. }
  1948. scApiRet = WLsaAcceptContext( &pArgs->hCredential,
  1949. &pArgs->hContext,
  1950. &LocalInput,
  1951. pArgs->fContextReq,
  1952. pArgs->TargetDataRep,
  1953. &pArgs->hNewContext,
  1954. &LocalOutput,
  1955. &pArgs->fContextAttr,
  1956. &pArgs->tsExpiry,
  1957. &pArgs->MappedContext,
  1958. &ContextData );
  1959. //
  1960. // Reset the reply flags:
  1961. //
  1962. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET;
  1963. if (FAILED(scApiRet))
  1964. {
  1965. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  1966. //
  1967. // Copy the sizes from the output security buffers in case they
  1968. // are used to indicate how much space is required
  1969. //
  1970. if ((pArgs->fContextAttr & ASC_RET_EXTENDED_ERROR) == 0)
  1971. {
  1972. CopyBack = FALSE ;
  1973. }
  1974. else
  1975. {
  1976. CopyBack = TRUE ;
  1977. }
  1978. }
  1979. else
  1980. {
  1981. CopyBack = TRUE ;
  1982. }
  1983. //
  1984. // Turn on this flag on return, so that all allocations will come
  1985. // out of the map. This is safe because KMap would only be set
  1986. // for the right callers.
  1987. //
  1988. if ( CallInfo->KMap )
  1989. {
  1990. CallInfo->Flags |= CALL_FLAG_KMAP_USED ;
  1991. }
  1992. if (NT_SUCCESS(scRet) && (ContextData.cbBuffer != 0))
  1993. {
  1994. pArgs->ContextData = ContextData;
  1995. pArgs->ContextData.pvBuffer = LsapClientAllocate(ContextData.cbBuffer);
  1996. if (pArgs->ContextData.pvBuffer == NULL)
  1997. {
  1998. scRet = SEC_E_INSUFFICIENT_MEMORY;
  1999. }
  2000. else
  2001. {
  2002. scRet = LsapCopyToClient(
  2003. ContextData.pvBuffer,
  2004. pArgs->ContextData.pvBuffer,
  2005. ContextData.cbBuffer
  2006. );
  2007. if ( !NT_SUCCESS( scRet ) )
  2008. {
  2009. DebugLog(( DEB_ERROR, "Copy to Client failed, %x. Client addr %p, size %#x\n",
  2010. scRet, pArgs->ContextData.pvBuffer, ContextData.cbBuffer ));
  2011. }
  2012. }
  2013. }
  2014. if ( NT_SUCCESS( scRet ) )
  2015. {
  2016. Flags = pApiMessage->ApiMessage.Args.SpmArguments.fAPI ;
  2017. #if DBG
  2018. if ( ( scRet == SEC_I_CONTINUE_NEEDED ) &&
  2019. ( LocalInput.pBuffers[0].cbBuffer < 2048 ) )
  2020. {
  2021. ULONG t ;
  2022. for ( t = 0 ; t < LocalOutput.cBuffers ; t++ )
  2023. {
  2024. if ( ( LocalOutput.pBuffers[ t ].BufferType & 0xFFFF ) == SECBUFFER_TOKEN )
  2025. {
  2026. DsysAssert( LocalOutput.pBuffers[ t ].cbBuffer > 0 );
  2027. }
  2028. }
  2029. }
  2030. #endif
  2031. scRet = LsapUncaptureBuffers(
  2032. (PUCHAR) pArgs,
  2033. &CapturedOutput,
  2034. &pArgs->sbdOutput,
  2035. &LocalOutput,
  2036. (pArgs->fContextReq & ASC_REQ_ALLOCATE_MEMORY ) ? TRUE : FALSE,
  2037. CopyBack,
  2038. &Flags );
  2039. pApiMessage->ApiMessage.Args.SpmArguments.fAPI = (USHORT) Flags ;
  2040. }
  2041. if (FAILED(scRet))
  2042. {
  2043. if ( FirstCall )
  2044. {
  2045. AbortLpcContext(&pArgs->hNewContext);
  2046. }
  2047. if( scRet == SEC_E_INSUFFICIENT_MEMORY )
  2048. {
  2049. DebugLog((DEB_ERROR,"[%x] Accept Failed, low memory handle passed: %p:%p\n",
  2050. pSession->dwProcessID,
  2051. pArgs->hNewContext.dwUpper,
  2052. pArgs->hNewContext.dwLower
  2053. ));
  2054. }
  2055. //
  2056. // Turn off any flags that would cause the client to try and send
  2057. // an invalid blob:
  2058. //
  2059. pArgs->fContextAttr &= ~ ( ASC_RET_EXTENDED_ERROR );
  2060. scApiRet = scRet;
  2061. goto AcceptCleanExit;
  2062. }
  2063. AcceptCleanExit:
  2064. pApiMessage->ApiMessage.scRet = scApiRet;
  2065. //
  2066. // This is cool. Either I allocated the buffer, and I can free it this
  2067. // way, or the package allocated it. If the package allocated, then the
  2068. // address is in this buffer, and I free it. So cool.
  2069. //
  2070. scRet = LsapUncaptureBuffers(
  2071. (PUCHAR) pArgs,
  2072. &CapturedInput,
  2073. &pArgs->sbdInput,
  2074. &LocalInput,
  2075. FALSE,
  2076. FALSE,
  2077. NULL );
  2078. if (ContextData.pvBuffer != NULL)
  2079. {
  2080. LsapFreeLsaHeap(ContextData.pvBuffer);
  2081. }
  2082. if (FAILED(scRet) && (pArgs->ContextData.pvBuffer != NULL))
  2083. {
  2084. LsapClientFree(pArgs->ContextData.pvBuffer);
  2085. pArgs->ContextData.pvBuffer = NULL;
  2086. }
  2087. return(scRet);
  2088. }
  2089. //+-------------------------------------------------------------------------
  2090. //
  2091. // Function: LpcEstablishCreds
  2092. //
  2093. // Synopsis: Lpc stub for WLsaEstablishCreds()
  2094. //
  2095. // Notes: obsolete
  2096. //
  2097. //--------------------------------------------------------------------------
  2098. NTSTATUS
  2099. LpcEstablishCreds(
  2100. PSPM_LPC_MESSAGE pApiMessage
  2101. )
  2102. {
  2103. pApiMessage->ApiMessage.scRet = STATUS_NOT_SUPPORTED ;
  2104. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  2105. return STATUS_SUCCESS ;
  2106. }
  2107. //+-------------------------------------------------------------------------
  2108. //
  2109. // Function: LpcDeleteContext
  2110. //
  2111. // Synopsis: Delete context
  2112. //
  2113. // Effects:
  2114. //
  2115. // Arguments:
  2116. //
  2117. // Requires:
  2118. //
  2119. // Returns:
  2120. //
  2121. // Notes:
  2122. //
  2123. //--------------------------------------------------------------------------
  2124. NTSTATUS
  2125. LpcDeleteContext(
  2126. PSPM_LPC_MESSAGE pApiMessage
  2127. )
  2128. {
  2129. NTSTATUS scRet;
  2130. SPMDeleteContextAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.DeleteContext;
  2131. scRet = WLsaDeleteContext( &pArgs->hContext );
  2132. //
  2133. // Reset the reply flags:
  2134. //
  2135. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  2136. pApiMessage->ApiMessage.scRet = scRet;
  2137. return(S_OK);
  2138. }
  2139. //+---------------------------------------------------------------------------
  2140. //
  2141. // Function: LpcGetBinding
  2142. //
  2143. // Synopsis: Get the DLL binding info for a package
  2144. //
  2145. // Arguments: [pApiMessage] --
  2146. //
  2147. // History: 8-14-98 RichardW Created
  2148. //
  2149. // Notes:
  2150. //
  2151. //----------------------------------------------------------------------------
  2152. NTSTATUS
  2153. LpcGetBinding(
  2154. PSPM_LPC_MESSAGE pApiMessage
  2155. )
  2156. {
  2157. SPMGetBindingAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.GetBinding;
  2158. NTSTATUS scRet;
  2159. ULONG Size;
  2160. PWSTR Base;
  2161. PWSTR Remote;
  2162. pArgs->BindingInfo.PackageName.Buffer = NULL ;
  2163. pArgs->BindingInfo.Comment.Buffer = NULL ;
  2164. scRet = WLsaGetBinding( pArgs->ulPackageId,
  2165. &pArgs->BindingInfo,
  2166. &Size,
  2167. &Base );
  2168. if (SUCCEEDED(scRet))
  2169. {
  2170. //
  2171. // We succeeded so now we have to copy the two strings
  2172. //
  2173. Remote = (PWSTR) LsapClientAllocate( Size );
  2174. if (Remote != NULL)
  2175. {
  2176. LsapCopyToClient( Base, Remote, Size );
  2177. pArgs->BindingInfo.PackageName.Buffer = Remote ;
  2178. pArgs->BindingInfo.Comment.Buffer = Remote +
  2179. pArgs->BindingInfo.PackageName.MaximumLength / 2;
  2180. pArgs->BindingInfo.ModuleName.Buffer = pArgs->BindingInfo.Comment.Buffer +
  2181. pArgs->BindingInfo.Comment.MaximumLength / 2;
  2182. }
  2183. else
  2184. {
  2185. scRet = SEC_E_INSUFFICIENT_MEMORY;
  2186. }
  2187. LsapFreeLsaHeap( Base );
  2188. }
  2189. pApiMessage->ApiMessage.scRet = scRet;
  2190. return(scRet);
  2191. }
  2192. //+---------------------------------------------------------------------------
  2193. //
  2194. // Function: LpcSetSession
  2195. //
  2196. // Synopsis: Internal function to set session options, including the
  2197. // hook to do direct calls while in-process.
  2198. //
  2199. // Arguments: [pApiMessage] --
  2200. //
  2201. // History: 8-14-98 RichardW Created
  2202. //
  2203. // Notes:
  2204. //
  2205. //----------------------------------------------------------------------------
  2206. NTSTATUS
  2207. LpcSetSession(
  2208. PSPM_LPC_MESSAGE pApiMessage
  2209. )
  2210. {
  2211. NTSTATUS scRet;
  2212. SPMSetSessionAPI * Args = &pApiMessage->ApiMessage.Args.SpmArguments.API.SetSession ;
  2213. DebugLog((DEB_TRACE_VERB,"SetSession\n"));
  2214. scRet = LsapSetSessionOptions( Args->Request,
  2215. Args->Argument,
  2216. &Args->Response );
  2217. pApiMessage->ApiMessage.scRet = STATUS_SUCCESS;
  2218. return(scRet);
  2219. }
  2220. //+---------------------------------------------------------------------------
  2221. //
  2222. // Function: LpcFindPackage
  2223. //
  2224. // Synopsis: Locates a package by id
  2225. //
  2226. // Arguments: [pApiMessage] --
  2227. //
  2228. // History: 8-14-98 RichardW Created
  2229. //
  2230. // Notes:
  2231. //
  2232. //----------------------------------------------------------------------------
  2233. NTSTATUS
  2234. LpcFindPackage(
  2235. PSPM_LPC_MESSAGE pApiMessage
  2236. )
  2237. {
  2238. NTSTATUS scRet;
  2239. SECURITY_STRING ssPackageName;
  2240. SPMFindPackageAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.FindPackage;
  2241. PUCHAR Where = NULL;
  2242. scRet = GetClientString(&pArgs->ssPackageName,&ssPackageName, pApiMessage, &Where);
  2243. if (FAILED(scRet))
  2244. {
  2245. pApiMessage->ApiMessage.scRet = scRet;
  2246. return(scRet);
  2247. }
  2248. DebugLog((DEB_TRACE_VERB,"Find Package called for %wZ\n",&ssPackageName));
  2249. scRet = WLsaFindPackage(&ssPackageName,&pArgs->ulPackageId);
  2250. LsapFreePrivateHeap(ssPackageName.Buffer);
  2251. pApiMessage->ApiMessage.scRet = scRet;
  2252. return(scRet);
  2253. }
  2254. //+---------------------------------------------------------------------------
  2255. //
  2256. // Function: LpcEnumPackages
  2257. //
  2258. // Synopsis: Enumerate available packages
  2259. //
  2260. // Arguments: [pApiMessage] --
  2261. //
  2262. // History: 8-14-98 RichardW Created
  2263. //
  2264. // Notes:
  2265. //
  2266. //----------------------------------------------------------------------------
  2267. NTSTATUS
  2268. LpcEnumPackages(
  2269. PSPM_LPC_MESSAGE pApiMessage
  2270. )
  2271. {
  2272. NTSTATUS scRet;
  2273. SPMEnumPackagesAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.EnumPackages;
  2274. scRet = WLsaEnumeratePackages(&pArgs->cPackages,&pArgs->pPackages);
  2275. pApiMessage->ApiMessage.scRet = scRet;
  2276. return(scRet);
  2277. }
  2278. //+-------------------------------------------------------------------------
  2279. //
  2280. // Function: LpcApplyToken
  2281. //
  2282. // Synopsis:
  2283. //
  2284. // Effects:
  2285. //
  2286. // Arguments:
  2287. //
  2288. // Requires:
  2289. //
  2290. // Returns:
  2291. //
  2292. // Notes:
  2293. //
  2294. //
  2295. //--------------------------------------------------------------------------
  2296. NTSTATUS
  2297. LpcApplyToken(
  2298. PSPM_LPC_MESSAGE pApiMessage
  2299. )
  2300. {
  2301. NTSTATUS scRet;
  2302. SPMApplyTokenAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.ApplyToken;
  2303. ULONG i;
  2304. pArgs->sbdInput.pBuffers = pArgs->sbInputBuffer;
  2305. scRet = MapTokenBuffer(&pArgs->sbdInput, TRUE);
  2306. if (FAILED(scRet))
  2307. {
  2308. return(SEC_E_INSUFFICIENT_MEMORY);
  2309. }
  2310. scRet = WLsaApplyControlToken( &pArgs->hContext,
  2311. &pArgs->sbdInput);
  2312. //
  2313. // Reset the reply flags:
  2314. //
  2315. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  2316. pApiMessage->ApiMessage.scRet = scRet;
  2317. for (i = 0; i < pArgs->sbdInput.cBuffers; i++ )
  2318. {
  2319. if (!(pArgs->sbdInput.pBuffers[i].BufferType & SECBUFFER_UNMAPPED))
  2320. {
  2321. LsapFreeLsaHeap(pArgs->sbdInput.pBuffers[i].pvBuffer);
  2322. }
  2323. }
  2324. return(scRet);
  2325. }
  2326. //+-------------------------------------------------------------------------
  2327. //
  2328. // Function: LpcQueryPackage
  2329. //
  2330. // Synopsis:
  2331. //
  2332. // Effects:
  2333. //
  2334. // Arguments:
  2335. //
  2336. // Requires:
  2337. //
  2338. // Returns:
  2339. //
  2340. // Notes:
  2341. //
  2342. //
  2343. //--------------------------------------------------------------------------
  2344. NTSTATUS
  2345. LpcQueryPackage(
  2346. PSPM_LPC_MESSAGE pApiMessage
  2347. )
  2348. {
  2349. NTSTATUS scRet;
  2350. SPMQueryPackageAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.QueryPackage;
  2351. SECURITY_STRING ssPackageName;
  2352. BOOLEAN fNameAlloc = FALSE;
  2353. BOOLEAN fCommentAlloc = FALSE;
  2354. LPWSTR pszNameString = NULL;
  2355. LPWSTR pszCommentString = NULL;
  2356. ULONG cbLength;
  2357. PUCHAR Where = NULL;
  2358. scRet = GetClientString(&pArgs->ssPackageName,&ssPackageName, pApiMessage, &Where);
  2359. if (FAILED(scRet))
  2360. {
  2361. pApiMessage->ApiMessage.scRet = scRet;
  2362. return(scRet);
  2363. }
  2364. DebugLog((DEB_TRACE_VERB,"Querying package %wZ\n",&ssPackageName));
  2365. scRet = WLsaQueryPackageInfo( &ssPackageName,
  2366. &pArgs->pPackageInfo);
  2367. //
  2368. // Reset the reply flags:
  2369. //
  2370. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  2371. DebugLog((DEB_TRACE_VERB,"Querying package returned %x\n",scRet));
  2372. LsapFreePrivateHeap(ssPackageName.Buffer);
  2373. pApiMessage->ApiMessage.scRet = scRet;
  2374. return(scRet);
  2375. }
  2376. //+-------------------------------------------------------------------------
  2377. //
  2378. // Function: LpcGetUserInfo
  2379. //
  2380. // Synopsis:
  2381. //
  2382. // Effects:
  2383. //
  2384. // Arguments:
  2385. //
  2386. // Requires:
  2387. //
  2388. // Returns:
  2389. //
  2390. // Notes:
  2391. //
  2392. //
  2393. //--------------------------------------------------------------------------
  2394. NTSTATUS
  2395. LpcGetUserInfo(
  2396. PSPM_LPC_MESSAGE pApiMessage
  2397. )
  2398. {
  2399. NTSTATUS scRet;
  2400. static LUID lFake = {0,0};
  2401. SPMGetUserInfoAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.GetUserInfo;
  2402. PLUID pLogonId;
  2403. if ((pArgs->LogonId.LowPart == 0) &&
  2404. (pArgs->LogonId.HighPart == 0))
  2405. {
  2406. pLogonId = NULL;
  2407. }
  2408. else pLogonId = &pArgs->LogonId;
  2409. scRet = WLsaGetSecurityUserInfo(
  2410. pLogonId,
  2411. pArgs->fFlags,
  2412. &pArgs->pUserInfo
  2413. );
  2414. pApiMessage->ApiMessage.scRet = scRet;
  2415. return(scRet);
  2416. }
  2417. //+-------------------------------------------------------------------------
  2418. //
  2419. // Function: LpcGetCreds
  2420. //
  2421. // Synopsis:
  2422. //
  2423. // Effects:
  2424. //
  2425. // Arguments:
  2426. //
  2427. // Requires:
  2428. //
  2429. // Returns:
  2430. //
  2431. // Notes:
  2432. //
  2433. //
  2434. //--------------------------------------------------------------------------
  2435. NTSTATUS
  2436. LpcGetCreds(
  2437. PSPM_LPC_MESSAGE pApiMessage
  2438. )
  2439. {
  2440. NTSTATUS scRet;
  2441. SPMGetCredsAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.GetCreds;
  2442. scRet = SEC_E_UNSUPPORTED_FUNCTION;
  2443. pApiMessage->ApiMessage.scRet = scRet;
  2444. //
  2445. // It is up to the package to do the right thing with the
  2446. // buffer (for now).
  2447. //
  2448. return(scRet);
  2449. }
  2450. //+-------------------------------------------------------------------------
  2451. //
  2452. // Function: LpcSaveCreds
  2453. //
  2454. // Synopsis:
  2455. //
  2456. // Effects:
  2457. //
  2458. // Arguments:
  2459. //
  2460. // Requires:
  2461. //
  2462. // Returns:
  2463. //
  2464. // Notes:
  2465. //
  2466. //
  2467. //--------------------------------------------------------------------------
  2468. NTSTATUS
  2469. LpcSaveCreds(PSPM_LPC_MESSAGE pApiMessage)
  2470. {
  2471. NTSTATUS scRet;
  2472. SPMSaveCredsAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.SaveCreds;
  2473. scRet = SEC_E_UNSUPPORTED_FUNCTION;
  2474. pApiMessage->ApiMessage.scRet = scRet;
  2475. return(scRet);
  2476. }
  2477. //+-------------------------------------------------------------------------
  2478. //
  2479. // Function: LpcDeleteCreds
  2480. //
  2481. // Synopsis:
  2482. //
  2483. // Effects:
  2484. //
  2485. // Arguments:
  2486. //
  2487. // Requires:
  2488. //
  2489. // Returns:
  2490. //
  2491. // Notes:
  2492. //
  2493. //
  2494. //--------------------------------------------------------------------------
  2495. NTSTATUS
  2496. LpcDeleteCreds(PSPM_LPC_MESSAGE pApiMessage)
  2497. {
  2498. NTSTATUS scRet;
  2499. SPMDeleteCredsAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.DeleteCreds;
  2500. scRet = SEC_E_UNSUPPORTED_FUNCTION;
  2501. pApiMessage->ApiMessage.scRet = scRet;
  2502. return(scRet);
  2503. }
  2504. //+-------------------------------------------------------------------------
  2505. //
  2506. // Function: LpcLsaLookupPackage
  2507. //
  2508. // Synopsis:
  2509. //
  2510. // Effects:
  2511. //
  2512. // Arguments:
  2513. //
  2514. // Requires:
  2515. //
  2516. // Returns:
  2517. //
  2518. // Notes:
  2519. //
  2520. //
  2521. //--------------------------------------------------------------------------
  2522. NTSTATUS
  2523. LpcLsaLookupPackage(
  2524. PSPM_LPC_MESSAGE pApiMessage
  2525. )
  2526. {
  2527. PLSAP_AU_API_MESSAGE pLsaMessage = (PLSAP_AU_API_MESSAGE) pApiMessage;
  2528. UNICODE_STRING sPackageName;
  2529. ANSI_STRING sAnsiName;
  2530. PLSAP_SECURITY_PACKAGE pspPackage;
  2531. NTSTATUS Status;
  2532. //
  2533. // First, convert ANSI name to UNICODE
  2534. //
  2535. if ( pLsaMessage->Arguments.LookupPackage.PackageNameLength >
  2536. LSAP_MAX_PACKAGE_NAME_LENGTH )
  2537. {
  2538. return STATUS_INVALID_PARAMETER ;
  2539. }
  2540. sAnsiName.Length = (USHORT) pLsaMessage->Arguments.LookupPackage.PackageNameLength;
  2541. sAnsiName.MaximumLength = LSAP_MAX_PACKAGE_NAME_LENGTH+1;
  2542. sAnsiName.Buffer = pLsaMessage->Arguments.LookupPackage.PackageName;
  2543. Status = RtlAnsiStringToUnicodeString(&sPackageName, &sAnsiName, TRUE);
  2544. if ( !NT_SUCCESS(Status) )
  2545. {
  2546. pLsaMessage->Arguments.LookupPackage.AuthenticationPackage = (ULONG) -1;
  2547. pLsaMessage->ReturnedStatus = Status;
  2548. }
  2549. else
  2550. {
  2551. //
  2552. // Now, look up the package.
  2553. //
  2554. pspPackage = SpmpLookupPackage(&sPackageName);
  2555. if (pspPackage)
  2556. {
  2557. pLsaMessage->Arguments.LookupPackage.AuthenticationPackage = (DWORD) pspPackage->dwPackageID;
  2558. pLsaMessage->ReturnedStatus = STATUS_SUCCESS;
  2559. }
  2560. else
  2561. {
  2562. pLsaMessage->Arguments.LookupPackage.AuthenticationPackage = (ULONG) -1;
  2563. pLsaMessage->ReturnedStatus = STATUS_NO_SUCH_PACKAGE;
  2564. }
  2565. RtlFreeUnicodeString(&sPackageName);
  2566. }
  2567. return(S_OK);
  2568. }
  2569. //+-------------------------------------------------------------------------
  2570. //
  2571. // Function: LpcLsaDeregisterLogonProcess
  2572. //
  2573. // Synopsis:
  2574. //
  2575. // Effects:
  2576. //
  2577. // Arguments:
  2578. //
  2579. // Requires:
  2580. //
  2581. // Returns:
  2582. //
  2583. // Notes:
  2584. //
  2585. //
  2586. //--------------------------------------------------------------------------
  2587. NTSTATUS
  2588. LpcLsaDeregisterLogonProcess(
  2589. PSPM_LPC_MESSAGE pApiMessage
  2590. )
  2591. {
  2592. PLSAP_AU_API_MESSAGE pLsaMessage = (PLSAP_AU_API_MESSAGE) pApiMessage;
  2593. //
  2594. // The client side will close the handle (or not, not a big deal), and
  2595. // we will run down the session at that time. Safer that way, as well.
  2596. //
  2597. pLsaMessage->ReturnedStatus = STATUS_SUCCESS;
  2598. return(S_OK);
  2599. }
  2600. //+---------------------------------------------------------------------------
  2601. //
  2602. // Function: LpcLsaLogonUser
  2603. //
  2604. // Synopsis: Unmarshalls everything for a call to WLsaLogonUserWhoopee
  2605. //
  2606. // Arguments: [pApiMessage] --
  2607. //
  2608. // History: 6-14-94 RichardW Created
  2609. //
  2610. // Notes:
  2611. //
  2612. //----------------------------------------------------------------------------
  2613. NTSTATUS
  2614. LpcLsaLogonUser(
  2615. PSPM_LPC_MESSAGE pApiMessage
  2616. )
  2617. {
  2618. NTSTATUS Status;
  2619. LSAP_CLIENT_REQUEST ClientRequest;
  2620. PLSAP_AU_API_MESSAGE pLsaMessage = (PLSAP_AU_API_MESSAGE) pApiMessage;
  2621. PSession Session = GetCurrentSession();
  2622. ClientRequest.Request = (PLSAP_AU_API_MESSAGE) pApiMessage;
  2623. pLsaMessage->ReturnedStatus = LsapAuApiDispatchLogonUser(&ClientRequest);
  2624. if ( NT_SUCCESS( pLsaMessage->ReturnedStatus ) )
  2625. {
  2626. if ( ( pLsaMessage->Arguments.LogonUser.LogonType == Interactive ) &&
  2627. ( pLsaMessage->Arguments.LogonUser.ProfileBuffer == NULL ) )
  2628. {
  2629. DsysAssertMsg( pLsaMessage->Arguments.LogonUser.ProfileBuffer,
  2630. "Successful logon, but profile is NULL. w\n" );
  2631. }
  2632. }
  2633. return(STATUS_SUCCESS);
  2634. }
  2635. //+-------------------------------------------------------------------------
  2636. //
  2637. // Function: LpcLsaCallPackage
  2638. //
  2639. // Synopsis:
  2640. //
  2641. // Effects:
  2642. //
  2643. // Arguments:
  2644. //
  2645. // Requires:
  2646. //
  2647. // Returns:
  2648. //
  2649. // Notes:
  2650. //
  2651. //
  2652. //--------------------------------------------------------------------------
  2653. NTSTATUS
  2654. LpcLsaCallPackage(
  2655. PSPM_LPC_MESSAGE pApiMessage
  2656. )
  2657. {
  2658. LSAP_CLIENT_REQUEST ClientRequest;
  2659. PLSAP_AU_API_MESSAGE pLsaMessage = (PLSAP_AU_API_MESSAGE) pApiMessage;
  2660. PSession Session = GetCurrentSession();
  2661. ClientRequest.Request = (PLSAP_AU_API_MESSAGE) pApiMessage;
  2662. pLsaMessage->ReturnedStatus = LsapAuApiDispatchCallPackage(&ClientRequest);
  2663. return(STATUS_SUCCESS);
  2664. }
  2665. //+-------------------------------------------------------------------------
  2666. //
  2667. // Function: LpcQueryCredAttributes
  2668. //
  2669. //
  2670. //
  2671. //--------------------------------------------------------------------------
  2672. NTSTATUS
  2673. LpcQueryCredAttributes(
  2674. PSPM_LPC_MESSAGE pApiMessage
  2675. )
  2676. {
  2677. NTSTATUS hrApiRet;
  2678. SPMQueryCredAttributesAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.QueryCredAttributes;
  2679. PLSA_CALL_INFO CallInfo ;
  2680. CallInfo = LsapGetCurrentCall();
  2681. hrApiRet = WLsaQueryCredAttributes(
  2682. &pArgs->hCredentials,
  2683. pArgs->ulAttribute,
  2684. pArgs->pBuffer
  2685. );
  2686. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  2687. if ( CallInfo->Allocs )
  2688. {
  2689. ULONG i ;
  2690. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ALLOCS ;
  2691. pArgs->Allocs = CallInfo->Allocs ;
  2692. for ( i = 0 ; i < CallInfo->Allocs ; i++ )
  2693. {
  2694. pArgs->Buffers[i] = CallInfo->Buffers[i] ;
  2695. }
  2696. }
  2697. pApiMessage->ApiMessage.scRet = hrApiRet;
  2698. if (FAILED(hrApiRet))
  2699. {
  2700. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  2701. }
  2702. return(S_OK);
  2703. }
  2704. //+---------------------------------------------------------------------------
  2705. //
  2706. // Function: LpcAddPackage
  2707. //
  2708. // Algorithm:
  2709. //
  2710. // History: 3-05-97 RichardW Created
  2711. //
  2712. // Notes:
  2713. //
  2714. //----------------------------------------------------------------------------
  2715. SECURITY_STATUS
  2716. LpcAddPackage(
  2717. PSPM_LPC_MESSAGE pApiMessage
  2718. )
  2719. {
  2720. SPMAddPackageAPI * pArgs;
  2721. SECURITY_STRING PackageName;
  2722. SECURITY_STATUS scRet ;
  2723. PUCHAR Where = NULL;
  2724. SECURITY_PACKAGE_OPTIONS Options;
  2725. pArgs = LPC_MESSAGE_ARGSP( pApiMessage, AddPackage );
  2726. scRet = GetClientString( &pArgs->Package,
  2727. &PackageName,
  2728. pApiMessage,
  2729. &Where);
  2730. if (FAILED(scRet))
  2731. {
  2732. pApiMessage->ApiMessage.scRet = scRet;
  2733. return(scRet);
  2734. }
  2735. DebugLog((DEB_TRACE_VERB,"Add Package called for %ws\n",
  2736. PackageName.Buffer ));
  2737. Options.Flags = pArgs->OptionsFlags ;
  2738. Options.Size = sizeof( SECURITY_PACKAGE_OPTIONS );
  2739. scRet = WLsaAddPackage( &PackageName,
  2740. &Options );
  2741. LsapFreePrivateHeap( PackageName.Buffer );
  2742. pApiMessage->ApiMessage.scRet = scRet;
  2743. return( scRet );
  2744. }
  2745. //+---------------------------------------------------------------------------
  2746. //
  2747. // Function: LpcDeletePackage
  2748. //
  2749. // History: 3-05-97 RichardW Created
  2750. //
  2751. // Notes:
  2752. //
  2753. //----------------------------------------------------------------------------
  2754. SECURITY_STATUS
  2755. LpcDeletePackage(
  2756. PSPM_LPC_MESSAGE pApiMessage)
  2757. {
  2758. pApiMessage->ApiMessage.scRet = SEC_E_UNSUPPORTED_FUNCTION ;
  2759. return( SEC_E_OK );
  2760. }
  2761. //+---------------------------------------------------------------------------
  2762. //
  2763. // Function: LpcQueryContextAttributes
  2764. //
  2765. // History: 3-05-97 RichardW Created
  2766. //
  2767. // Notes:
  2768. //
  2769. //----------------------------------------------------------------------------
  2770. NTSTATUS
  2771. LpcQueryContextAttributes(
  2772. PSPM_LPC_MESSAGE pApiMessage
  2773. )
  2774. {
  2775. NTSTATUS hrApiRet;
  2776. SPMQueryContextAttrAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.QueryContextAttr;
  2777. PLSA_CALL_INFO CallInfo ;
  2778. CallInfo = LsapGetCurrentCall();
  2779. hrApiRet = WLsaQueryContextAttributes(
  2780. &pArgs->hContext,
  2781. pArgs->ulAttribute,
  2782. pArgs->pBuffer
  2783. );
  2784. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  2785. pApiMessage->ApiMessage.scRet = hrApiRet;
  2786. if ( CallInfo->Allocs )
  2787. {
  2788. ULONG i ;
  2789. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ALLOCS ;
  2790. pArgs->Allocs = CallInfo->Allocs ;
  2791. for ( i = 0 ; i < CallInfo->Allocs ; i++ )
  2792. {
  2793. pArgs->Buffers[i] = CallInfo->Buffers[i] ;
  2794. }
  2795. pApiMessage->pmMessage.u1.s1.DataLength = LPC_DATA_LENGTH( CallInfo->Allocs * sizeof( PVOID ) );
  2796. pApiMessage->pmMessage.u1.s1.TotalLength = LPC_TOTAL_LENGTH( CallInfo->Allocs * sizeof( PVOID ) );
  2797. }
  2798. if (FAILED(hrApiRet))
  2799. {
  2800. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  2801. }
  2802. return(S_OK);
  2803. }
  2804. //+---------------------------------------------------------------------------
  2805. //
  2806. // Function: LpcSetContextAttributes
  2807. //
  2808. // History: 4-20-00 CliffV Created
  2809. //
  2810. // Notes:
  2811. //
  2812. //----------------------------------------------------------------------------
  2813. NTSTATUS
  2814. LpcSetContextAttributes(
  2815. PSPM_LPC_MESSAGE pApiMessage
  2816. )
  2817. {
  2818. NTSTATUS hrApiRet;
  2819. SPMSetContextAttrAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.SetContextAttr;
  2820. PLSA_CALL_INFO CallInfo ;
  2821. CallInfo = LsapGetCurrentCall();
  2822. hrApiRet = WLsaSetContextAttributes(
  2823. &pArgs->hContext,
  2824. pArgs->ulAttribute,
  2825. pArgs->pBuffer,
  2826. pArgs->cbBuffer
  2827. );
  2828. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  2829. pApiMessage->ApiMessage.scRet = hrApiRet;
  2830. if (FAILED(hrApiRet))
  2831. {
  2832. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  2833. }
  2834. return(S_OK);
  2835. }
  2836. //+---------------------------------------------------------------------------
  2837. //
  2838. // Function: LpcCallback
  2839. //
  2840. // Synopsis: Callback handler. Should never be hit.
  2841. //
  2842. // Arguments: [pApiMessage] --
  2843. //
  2844. // History: 3-05-97 RichardW Created
  2845. //
  2846. // Notes:
  2847. //
  2848. //----------------------------------------------------------------------------
  2849. NTSTATUS
  2850. LpcCallback(
  2851. PSPM_LPC_MESSAGE pApiMessage
  2852. )
  2853. {
  2854. pApiMessage->ApiMessage.scRet = SEC_E_UNSUPPORTED_FUNCTION ;
  2855. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  2856. return S_OK ;
  2857. }
  2858. NTSTATUS
  2859. WLsaGenerateKey(
  2860. PEFS_DATA_STREAM_HEADER DirectoryEfsStream,
  2861. PEFS_DATA_STREAM_HEADER * EfsStream,
  2862. PULONG EfsLength,
  2863. PEFS_KEY * Fek
  2864. )
  2865. {
  2866. NTSTATUS Status;
  2867. DWORD HResult;
  2868. HANDLE hToken = NULL;
  2869. HANDLE hProfile = NULL;
  2870. PEFS_DATA_STREAM_HEADER EfsStreamHeader;
  2871. //
  2872. // Impersonate the client
  2873. //
  2874. Status = LsapImpersonateClient( );
  2875. if (!NT_SUCCESS(Status)) {
  2876. return( Status );
  2877. }
  2878. EFS_USER_INFO EfsUserInfo;
  2879. if (EfspGetUserInfo( &EfsUserInfo )) {
  2880. BOOL b = EfspLoadUserProfile( &EfsUserInfo, &hToken, &hProfile );
  2881. if (!b) {
  2882. HResult = GetLastError();
  2883. if (!EfsErrorToNtStatus(HResult, &Status)) {
  2884. Status = STATUS_UNSUCCESSFUL;
  2885. }
  2886. } else {
  2887. //
  2888. // Generate the Fek. This routine will fill in the
  2889. // EFS_KEY structure with key data.
  2890. //
  2891. if (GenerateFEK( Fek )) {
  2892. if (!ConstructEFS( &EfsUserInfo, *Fek, DirectoryEfsStream, &EfsStreamHeader )) {
  2893. HResult = GetLastError();
  2894. ASSERT( HResult != ERROR_SUCCESS );
  2895. DebugLog((DEB_ERROR, "ConstructEFS failed, error = (%x)\n" ,HResult ));
  2896. LsapFreeLsaHeap( *Fek );
  2897. *Fek = NULL;
  2898. if (!EfsErrorToNtStatus(HResult, &Status)) {
  2899. Status = STATUS_UNSUCCESSFUL;
  2900. }
  2901. } else {
  2902. *EfsStream = EfsStreamHeader;
  2903. *EfsLength = EfsStreamHeader->Length;
  2904. }
  2905. } else {
  2906. HResult = GetLastError();
  2907. if (!EfsErrorToNtStatus(HResult, &Status)) {
  2908. Status = STATUS_UNSUCCESSFUL;
  2909. }
  2910. }
  2911. EfspUnloadUserProfile( hToken, hProfile );
  2912. }
  2913. EfspFreeUserInfo( &EfsUserInfo );
  2914. } else {
  2915. HResult = GetLastError();
  2916. if (!EfsErrorToNtStatus(HResult, &Status)) {
  2917. Status = STATUS_UNSUCCESSFUL;
  2918. }
  2919. }
  2920. RevertToSelf();
  2921. return Status;
  2922. }
  2923. NTSTATUS
  2924. WLsaGenerateDirEfs(
  2925. PEFS_DATA_STREAM_HEADER DirectoryEfsStream,
  2926. PEFS_DATA_STREAM_HEADER * EfsStream
  2927. )
  2928. {
  2929. NTSTATUS Status;
  2930. DWORD HResult;
  2931. HANDLE hToken = NULL;
  2932. HANDLE hProfile = NULL;
  2933. PEFS_KEY Fek = NULL;
  2934. Status = LsapImpersonateClient( );
  2935. if (!NT_SUCCESS(Status)) {
  2936. return( Status );
  2937. }
  2938. EFS_USER_INFO EfsUserInfo;
  2939. if (EfspGetUserInfo( &EfsUserInfo )) {
  2940. if (!EfspLoadUserProfile( &EfsUserInfo, &hToken, &hProfile )) {
  2941. HResult = GetLastError();
  2942. if (!EfsErrorToNtStatus(HResult, &Status)) {
  2943. Status = STATUS_UNSUCCESSFUL;
  2944. }
  2945. } else {
  2946. if (GenerateFEK( &Fek )) {
  2947. if (!ConstructDirectoryEFS(
  2948. &EfsUserInfo,
  2949. Fek,
  2950. EfsStream
  2951. )) {
  2952. HResult = GetLastError();
  2953. ASSERT( HResult != ERROR_SUCCESS );
  2954. DebugLog((DEB_ERROR, "ConstructDirectoryEFS failed, error = (%x)\n" ,HResult ));
  2955. if (!EfsErrorToNtStatus(HResult, &Status)) {
  2956. Status = STATUS_UNSUCCESSFUL;
  2957. }
  2958. }
  2959. LsapFreeLsaHeap( Fek );
  2960. } else {
  2961. HResult = GetLastError();
  2962. if (!EfsErrorToNtStatus(HResult, &Status)) {
  2963. Status = STATUS_UNSUCCESSFUL;
  2964. }
  2965. }
  2966. EfspUnloadUserProfile( hToken, hProfile );
  2967. }
  2968. EfspFreeUserInfo( &EfsUserInfo );
  2969. } else {
  2970. HResult = GetLastError();
  2971. if (!EfsErrorToNtStatus(HResult, &Status)) {
  2972. Status = STATUS_UNSUCCESSFUL;
  2973. }
  2974. }
  2975. RevertToSelf();
  2976. return Status;
  2977. }
  2978. NTSTATUS
  2979. LpcEfsGenerateKey( PSPM_LPC_MESSAGE pApiMessage)
  2980. /*++
  2981. Routine Description:
  2982. This routine generates an FEK and an EFS stream for the file
  2983. being encrypted.
  2984. Arguments:
  2985. pApiMessage - Supplies the LPC message from the driver.
  2986. Return Value:
  2987. return-value - Description of conditions needed to return value. - or -
  2988. None.
  2989. --*/
  2990. {
  2991. NTSTATUS scRet;
  2992. SPMEfsGenerateKeyAPI * Args = &pApiMessage->ApiMessage.Args.SpmArguments.API.EfsGenerateKey ;
  2993. ULONG EfsLength = 0;
  2994. PEFS_KEY Fek = NULL;
  2995. PEFS_DATA_STREAM_HEADER EfsStream;
  2996. SIZE_T BufferLength;
  2997. DebugLog((DEB_TRACE_EFS,"LpcEfsGenerateKey, Args is at %x\n",Args));
  2998. if ((pApiMessage->pmMessage.u2.s2.Type & LPC_KERNELMODE_MESSAGE) == 0){
  2999. DebugLog((DEB_ERROR,"Caller is not from kernelmode \n"));
  3000. pApiMessage->ApiMessage.scRet = STATUS_ACCESS_DENIED ;
  3001. return STATUS_ACCESS_DENIED;
  3002. }
  3003. if (EfsPersonalVer || EfsDisabled) {
  3004. pApiMessage->ApiMessage.scRet = STATUS_NOT_SUPPORTED;
  3005. return STATUS_NOT_SUPPORTED;
  3006. }
  3007. scRet = WLsaGenerateKey(
  3008. (PEFS_DATA_STREAM_HEADER)Args->DirectoryEfsStream,
  3009. &EfsStream,
  3010. &EfsLength,
  3011. &Fek
  3012. );
  3013. if (NT_SUCCESS( scRet )) {
  3014. //
  3015. // Copy the FEK to the client's address space
  3016. //
  3017. PVOID Target = NULL;
  3018. BufferLength = EFS_KEY_SIZE( Fek ) + EfsLength;
  3019. #ifdef LSAP_CATCH_BAD_VM
  3020. if ( BufferLength > 0x2000000 )
  3021. {
  3022. DbgPrint("Allocation too large\n" );
  3023. DbgBreakPoint();
  3024. }
  3025. #endif
  3026. scRet = NtAllocateVirtualMemory(
  3027. GetCurrentProcess(),
  3028. &Target,
  3029. 0,
  3030. &BufferLength,
  3031. MEM_COMMIT,
  3032. PAGE_READWRITE
  3033. );
  3034. Args->BufferLength = (ULONG) BufferLength;
  3035. if (NT_SUCCESS( scRet )) {
  3036. //
  3037. // Save away the base of the allocation so that the driver may free it
  3038. // when it's finished with it.
  3039. //
  3040. Args->BufferBase = Target;
  3041. Args->Fek = Target;
  3042. RtlCopyMemory(
  3043. Target,
  3044. (PVOID)Fek,
  3045. EFS_KEY_SIZE( Fek )
  3046. );
  3047. Target = (PVOID)((ULONG_PTR)Target + EFS_KEY_SIZE( Fek ));
  3048. Args->EfsStream = Target;
  3049. RtlCopyMemory(
  3050. Target,
  3051. (PVOID)EfsStream,
  3052. EfsLength
  3053. );
  3054. } else {
  3055. Args->BufferBase = NULL;
  3056. Args->BufferLength = 0;
  3057. Args->Fek = NULL;
  3058. Args->EfsStream = NULL;
  3059. }
  3060. if ( Fek ){
  3061. LsapFreeLsaHeap( Fek );
  3062. }
  3063. if ( EfsStream ){
  3064. LsapFreeLsaHeap( EfsStream );
  3065. }
  3066. }
  3067. pApiMessage->ApiMessage.scRet = scRet;
  3068. return( scRet );
  3069. }
  3070. NTSTATUS
  3071. LpcEfsGenerateDirEfs(
  3072. PSPM_LPC_MESSAGE pApiMessage
  3073. )
  3074. /*++
  3075. Routine Description:
  3076. Lpc stub for GenerateDirEfs
  3077. Arguments:
  3078. pApiMessage - LPC Message
  3079. Return Value:
  3080. NtStatus
  3081. --*/
  3082. {
  3083. SPMEfsGenerateDirEfsAPI * Args = &pApiMessage->ApiMessage.Args.SpmArguments.API.EfsGenerateDirEfs ;
  3084. PEFS_DATA_STREAM_HEADER EfsStream;
  3085. NTSTATUS scRet;
  3086. ULONG EfsLength = 0;
  3087. if ((pApiMessage->pmMessage.u2.s2.Type & LPC_KERNELMODE_MESSAGE) == 0){
  3088. DebugLog((DEB_ERROR,"Caller is not from kernelmode \n"));
  3089. pApiMessage->ApiMessage.scRet = STATUS_ACCESS_DENIED ;
  3090. return STATUS_ACCESS_DENIED;
  3091. }
  3092. if (EfsPersonalVer || EfsDisabled) {
  3093. pApiMessage->ApiMessage.scRet = STATUS_NOT_SUPPORTED;
  3094. return STATUS_NOT_SUPPORTED;
  3095. }
  3096. scRet = WLsaGenerateDirEfs(
  3097. (PEFS_DATA_STREAM_HEADER)Args->DirectoryEfsStream,
  3098. &EfsStream
  3099. );
  3100. if (NT_SUCCESS( scRet )) {
  3101. PVOID Target = NULL;
  3102. SIZE_T EfsLength = EfsStream->Length;
  3103. #ifdef LSAP_CATCH_BAD_VM
  3104. if ( EfsLength > 0x2000000 )
  3105. {
  3106. DbgPrint("Allocation too large\n" );
  3107. DbgBreakPoint();
  3108. }
  3109. #endif
  3110. scRet = NtAllocateVirtualMemory(
  3111. GetCurrentProcess(),
  3112. &Target,
  3113. 0,
  3114. &EfsLength,
  3115. MEM_COMMIT,
  3116. PAGE_READWRITE
  3117. );
  3118. if (NT_SUCCESS( scRet )) {
  3119. Args->BufferBase = Target;
  3120. Args->BufferLength = EfsStream->Length;
  3121. Args->EfsStream = Target;
  3122. RtlCopyMemory(
  3123. Target,
  3124. (PVOID)EfsStream,
  3125. EfsStream->Length
  3126. );
  3127. } else {
  3128. Args->BufferBase = NULL;
  3129. Args->BufferLength = 0;
  3130. Args->EfsStream = NULL;
  3131. }
  3132. if (EfsStream){
  3133. LsapFreeLsaHeap( EfsStream );
  3134. }
  3135. }
  3136. pApiMessage->ApiMessage.scRet = scRet;
  3137. return( scRet );
  3138. }
  3139. NTSTATUS
  3140. WLsaDecryptFek(
  3141. PEFS_DATA_STREAM_HEADER EfsStream,
  3142. PEFS_KEY * Fek,
  3143. PEFS_DATA_STREAM_HEADER * NewEfs,
  3144. ULONG OpenType
  3145. )
  3146. /*++
  3147. Routine Description:
  3148. Worker function for DecryptFek
  3149. Arguments:
  3150. EfsStream - The $EFS attribute for the file being decrypted.
  3151. Fek - Returns the FEK for the file being decrypted. This structure
  3152. is allocated out of heap and must be freed by the caller.
  3153. NewEfs - Optionally returns a new $EFS stream to be applied to
  3154. the file.
  3155. OpenType - Whether this is a decrypt or recovery operation.
  3156. Return Value:
  3157. NtStatus
  3158. --*/
  3159. {
  3160. NTSTATUS Status;
  3161. DWORD HResult;
  3162. DWORD rc;
  3163. HANDLE hToken = NULL;
  3164. HANDLE hProfile = NULL;
  3165. Status = LsapImpersonateClient( );
  3166. if (!NT_SUCCESS(Status)) {
  3167. return( Status );
  3168. }
  3169. EFS_USER_INFO EfsUserInfo;
  3170. if (EfspGetUserInfo( &EfsUserInfo ) ) {
  3171. if (EfspLoadUserProfile( &EfsUserInfo, &hToken, &hProfile )) {
  3172. HResult = DecryptFek( &EfsUserInfo, EfsStream, Fek, NewEfs, OpenType );
  3173. if (HResult != ERROR_SUCCESS) {
  3174. DebugLog((DEB_ERROR, "WLsaDecryptFek: DecryptFek failed, error = %x\n" ,HResult ));
  3175. if (!EfsErrorToNtStatus(HResult, &Status)) {
  3176. Status = STATUS_UNSUCCESSFUL;
  3177. }
  3178. }
  3179. EfspUnloadUserProfile( hToken, hProfile );
  3180. } else {
  3181. HResult = GetLastError();
  3182. if (!EfsErrorToNtStatus(HResult, &Status)) {
  3183. Status = STATUS_UNSUCCESSFUL;
  3184. }
  3185. }
  3186. EfspFreeUserInfo( &EfsUserInfo );
  3187. } else {
  3188. HResult = GetLastError();
  3189. if (!EfsErrorToNtStatus(HResult, &Status)) {
  3190. Status = STATUS_UNSUCCESSFUL;
  3191. }
  3192. }
  3193. RevertToSelf();
  3194. return Status;
  3195. }
  3196. NTSTATUS
  3197. LpcEfsDecryptFek( PSPM_LPC_MESSAGE pApiMessage)
  3198. {
  3199. SPMEfsDecryptFekAPI * Args = &pApiMessage->ApiMessage.Args.SpmArguments.API.EfsDecryptFek ;
  3200. PEFS_DATA_STREAM_HEADER NewEfs;
  3201. NTSTATUS Status;
  3202. ULONG EfsLength = 0;
  3203. PEFS_KEY Fek;
  3204. SIZE_T BufferLength;
  3205. Args->BufferBase = NULL;
  3206. Args->BufferLength = 0;
  3207. Args->Fek = NULL;
  3208. Args->NewEfs = NULL;
  3209. if ((pApiMessage->pmMessage.u2.s2.Type & LPC_KERNELMODE_MESSAGE) == 0){
  3210. DebugLog((DEB_ERROR,"Caller is not from kernelmode \n"));
  3211. pApiMessage->ApiMessage.scRet = STATUS_ACCESS_DENIED ;
  3212. return STATUS_ACCESS_DENIED;
  3213. }
  3214. if (EfsPersonalVer || EfsDisabled) {
  3215. pApiMessage->ApiMessage.scRet = STATUS_NOT_SUPPORTED;
  3216. return STATUS_NOT_SUPPORTED;
  3217. }
  3218. Status = WLsaDecryptFek( (PEFS_DATA_STREAM_HEADER)Args->EfsStream, &Fek, &NewEfs, Args->OpenType );
  3219. if (NT_SUCCESS( Status )) {
  3220. BufferLength = EFS_KEY_SIZE( Fek );
  3221. if (NewEfs != NULL) {
  3222. BufferLength += NewEfs->Length;
  3223. }
  3224. PVOID Target = NULL;
  3225. #ifdef LSAP_CATCH_BAD_VM
  3226. if ( BufferLength > 0x2000000 )
  3227. {
  3228. DbgPrint("Allocation too large\n" );
  3229. DbgBreakPoint();
  3230. }
  3231. #endif
  3232. Status = NtAllocateVirtualMemory(
  3233. GetCurrentProcess(),
  3234. &Target,
  3235. 0,
  3236. &BufferLength,
  3237. MEM_COMMIT,
  3238. PAGE_READWRITE
  3239. );
  3240. Args->BufferLength = (ULONG) BufferLength;
  3241. if (NT_SUCCESS( Status )) {
  3242. Args->BufferBase = Target;
  3243. Args->Fek = Target;
  3244. RtlCopyMemory(
  3245. Target,
  3246. (PVOID)Fek,
  3247. EFS_KEY_SIZE( Fek )
  3248. );
  3249. if (NewEfs != NULL) {
  3250. Target = (PVOID)((DWORD_PTR)Target + EFS_KEY_SIZE( Fek ));
  3251. Args->NewEfs = Target;
  3252. RtlCopyMemory(
  3253. Target,
  3254. (PVOID)NewEfs,
  3255. NewEfs->Length
  3256. );
  3257. }
  3258. } else {
  3259. Args->BufferBase = NULL;
  3260. Args->BufferLength = 0;
  3261. Args->Fek = NULL;
  3262. }
  3263. if ( Fek){
  3264. LsapFreeLsaHeap( Fek );
  3265. }
  3266. if ( NewEfs ){
  3267. LsapFreeLsaHeap( NewEfs );
  3268. }
  3269. }
  3270. pApiMessage->ApiMessage.scRet = Status;
  3271. return( Status );
  3272. }
  3273. NTSTATUS
  3274. LpcEfsGenerateSessionKey(
  3275. PSPM_LPC_MESSAGE pApiMessage
  3276. )
  3277. {
  3278. SPMEfsGenerateSessionKeyAPI * Args = &pApiMessage->ApiMessage.Args.SpmArguments.API.EfsGenerateSessionKey ;
  3279. NTSTATUS scRet;
  3280. EFS_INIT_DATAEXG InitDataExg;
  3281. if ((pApiMessage->pmMessage.u2.s2.Type & LPC_KERNELMODE_MESSAGE) == 0){
  3282. DebugLog((DEB_ERROR,"Caller is not from kernelmode \n"));
  3283. pApiMessage->ApiMessage.scRet = STATUS_ACCESS_DENIED ;
  3284. return STATUS_ACCESS_DENIED;
  3285. }
  3286. if ( EfsSessionKeySent ){
  3287. pApiMessage->ApiMessage.scRet = STATUS_ACCESS_DENIED ;
  3288. return STATUS_ACCESS_DENIED;
  3289. }
  3290. scRet = GenerateDriverSessionKey( &InitDataExg );
  3291. if (NT_SUCCESS( scRet )) {
  3292. //
  3293. // Copy the returned session key into the argument buffer
  3294. //
  3295. RtlCopyMemory( &Args->InitDataExg, &InitDataExg, sizeof( EFS_INIT_DATAEXG ));
  3296. pApiMessage->pmMessage.u1.s1.DataLength = LPC_DATA_LENGTH( sizeof( EFS_INIT_DATAEXG ) );
  3297. pApiMessage->pmMessage.u1.s1.TotalLength = LPC_TOTAL_LENGTH( sizeof( EFS_INIT_DATAEXG ) );
  3298. EfsSessionKeySent = TRUE;
  3299. }
  3300. pApiMessage->ApiMessage.scRet = scRet;
  3301. return( scRet );
  3302. }
  3303. NTSTATUS
  3304. LpcGetUserName(
  3305. PSPM_LPC_MESSAGE pApiMessage
  3306. )
  3307. {
  3308. LUID LogonId ;
  3309. PLSAP_LOGON_SESSION LogonSession ;
  3310. NTSTATUS Status ;
  3311. SECPKG_CLIENT_INFO ClientInfo ;
  3312. SPMGetUserNameXAPI * Args = &pApiMessage->ApiMessage.Args.SpmArguments.API.GetUserNameX ;
  3313. PLSAP_DS_NAME_MAP Map ;
  3314. PLSAP_DS_NAME_MAP SamMap = NULL ;
  3315. UNICODE_STRING String ;
  3316. PWSTR Scan ;
  3317. PWSTR DnsDomainName = NULL;
  3318. Status = LsapGetClientInfo( &ClientInfo );
  3319. if ( NT_SUCCESS( Status ) )
  3320. {
  3321. LogonSession = LsapLocateLogonSession( &ClientInfo.LogonId );
  3322. if ( LogonSession )
  3323. {
  3324. if ( RtlEqualLuid( &ClientInfo.LogonId,
  3325. &LsapSystemLogonId ) &&
  3326. (Args->Options & SPM_NAME_OPTION_NT4_ONLY) )
  3327. {
  3328. Map = LsapGetNameForLocalSystem();
  3329. Status = STATUS_SUCCESS ;
  3330. }
  3331. else
  3332. {
  3333. Status = LsapGetNameForLogonSession(
  3334. LogonSession,
  3335. Args->Options,
  3336. &Map,
  3337. FALSE );
  3338. if (NT_SUCCESS(Status)
  3339. &&
  3340. (Args->Options & (~SPM_NAME_OPTION_MASK)) == NameDnsDomain)
  3341. {
  3342. //
  3343. // To cruft up the NameDnsDomain format, we need
  3344. // the SAM username.
  3345. //
  3346. Status = LsapGetNameForLogonSession(
  3347. LogonSession,
  3348. NameSamCompatible,
  3349. &SamMap,
  3350. FALSE);
  3351. if (!NT_SUCCESS(Status))
  3352. {
  3353. LsapDerefDsNameMap(Map);
  3354. }
  3355. }
  3356. }
  3357. LsapReleaseLogonSession( LogonSession );
  3358. if ( NT_SUCCESS( Status ) )
  3359. {
  3360. //
  3361. // See what we can do.
  3362. //
  3363. if ( (Args->Options & SPM_NAME_OPTION_NT4_ONLY) == 0)
  3364. {
  3365. if ((Args->Options & (~SPM_NAME_OPTION_MASK )) != NameDnsDomain)
  3366. {
  3367. String = Map->Name ;
  3368. }
  3369. else
  3370. {
  3371. //
  3372. // Build up the DnsDomainName format
  3373. //
  3374. Scan = wcschr( SamMap->Name.Buffer, L'\\' );
  3375. if ( Scan )
  3376. {
  3377. Scan++;
  3378. }
  3379. else
  3380. {
  3381. Scan = SamMap->Name.Buffer;
  3382. }
  3383. //
  3384. // SAM name is always NULL-terminated
  3385. //
  3386. DnsDomainName = (LPWSTR) LsapAllocatePrivateHeap(
  3387. Map->Name.Length + (wcslen(Scan) + 2) * sizeof(WCHAR));
  3388. if (DnsDomainName != NULL)
  3389. {
  3390. ULONG Index = Map->Name.Length / sizeof(WCHAR);
  3391. wcsncpy(DnsDomainName, Map->Name.Buffer, Index);
  3392. DnsDomainName[Index++] = L'\\';
  3393. wcscpy(DnsDomainName + Index, Scan);
  3394. RtlInitUnicodeString(&String, DnsDomainName);
  3395. }
  3396. else
  3397. {
  3398. String.Length = String.MaximumLength = 0;
  3399. String.Buffer = NULL;
  3400. Status = STATUS_NO_MEMORY;
  3401. }
  3402. LsapDerefDsNameMap(SamMap);
  3403. }
  3404. }
  3405. else
  3406. {
  3407. Scan = wcschr( Map->Name.Buffer, L'\\' );
  3408. if ( Scan )
  3409. {
  3410. Scan++;
  3411. RtlInitUnicodeString( &String, Scan );
  3412. }
  3413. else
  3414. {
  3415. String = Map->Name ;
  3416. }
  3417. }
  3418. if (NT_SUCCESS(Status))
  3419. {
  3420. if ( String.Length <= Args->Name.MaximumLength )
  3421. {
  3422. Args->Name.Length = String.Length ;
  3423. if ( String.Length < CBPREPACK )
  3424. {
  3425. Args->Name.Buffer = (PWSTR) ((LONG_PTR) pApiMessage->ApiMessage.bData
  3426. - (LONG_PTR) Args);
  3427. RtlCopyMemory(
  3428. pApiMessage->ApiMessage.bData,
  3429. String.Buffer,
  3430. String.Length );
  3431. pApiMessage->pmMessage.u1.s1.DataLength = LPC_DATA_LENGTH( String.Length );
  3432. pApiMessage->pmMessage.u1.s1.TotalLength = LPC_TOTAL_LENGTH( String.Length );
  3433. }
  3434. else
  3435. {
  3436. Status = LsapCopyToClient(
  3437. String.Buffer,
  3438. Args->Name.Buffer,
  3439. String.Length );
  3440. }
  3441. }
  3442. else
  3443. {
  3444. Args->Name.Length = String.Length ;
  3445. Args->Name.Buffer = NULL ;
  3446. Status = STATUS_BUFFER_OVERFLOW ;
  3447. }
  3448. }
  3449. LsapDerefDsNameMap( Map );
  3450. }
  3451. else
  3452. {
  3453. if ( Status == STATUS_UNSUCCESSFUL )
  3454. {
  3455. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_WIN32_ERROR ;
  3456. Status = GetLastError();
  3457. }
  3458. }
  3459. }
  3460. else
  3461. {
  3462. DebugLog(( DEB_ERROR, "No logon session found for impersonated client!\n" ));
  3463. Status = STATUS_NO_SUCH_LOGON_SESSION ;
  3464. }
  3465. }
  3466. if (DnsDomainName != NULL)
  3467. {
  3468. LsapFreePrivateHeap(DnsDomainName);
  3469. }
  3470. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  3471. pApiMessage->ApiMessage.scRet = Status ;
  3472. return STATUS_SUCCESS ;
  3473. }
  3474. NTSTATUS
  3475. LpcAddCredentials(
  3476. PSPM_LPC_MESSAGE pApiMessage
  3477. )
  3478. {
  3479. UNICODE_STRING ssPrincipalName;
  3480. UNICODE_STRING ssPackageName;
  3481. NTSTATUS scApiRet;
  3482. NTSTATUS scRet;
  3483. SPMAddCredentialAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.AddCredential;
  3484. PSession pSession ;
  3485. PUCHAR Where = NULL;
  3486. pSession = GetCurrentSession();
  3487. DebugLog((DEB_TRACE, "[%x] LpcAddCredentials()\n", pSession->dwProcessID));
  3488. ssPrincipalName.Buffer = NULL;
  3489. ssPackageName.Buffer = NULL;
  3490. if (pArgs->ssPrincipal.Buffer )
  3491. {
  3492. scRet = GetClientString(&pArgs->ssPrincipal,
  3493. &ssPrincipalName,
  3494. pApiMessage,
  3495. &Where);
  3496. if (FAILED(scRet))
  3497. {
  3498. DebugLog((DEB_ERROR, "GetClientString failed to get principal name 0x%08x\n", scRet));
  3499. pApiMessage->ApiMessage.scRet = scRet;
  3500. return(scRet);
  3501. }
  3502. } else {
  3503. ssPrincipalName.MaximumLength = 0;
  3504. ssPrincipalName.Length = 0;
  3505. ssPrincipalName.Buffer = NULL;
  3506. }
  3507. scRet = GetClientString(&pArgs->ssSecPackage,
  3508. &ssPackageName,
  3509. pApiMessage,
  3510. &Where);
  3511. if (FAILED(scRet))
  3512. {
  3513. LsapFreePrivateHeap(ssPrincipalName.Buffer);
  3514. DebugLog((DEB_ERROR, "GetClientString failed to get package name 0x%08x\n", scRet));
  3515. pApiMessage->ApiMessage.scRet = scRet;
  3516. return(scRet);
  3517. }
  3518. scApiRet = WLsaAddCredentials(
  3519. &pArgs->hCredentials,
  3520. &ssPrincipalName,
  3521. &ssPackageName,
  3522. pArgs->fCredentialUse,
  3523. (PVOID) pArgs->pvAuthData,
  3524. (PVOID) pArgs->pvGetKeyFn,
  3525. (PVOID) pArgs->ulGetKeyArgument,
  3526. &pArgs->tsExpiry );
  3527. //
  3528. // Reset the reply flags:
  3529. //
  3530. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  3531. LsapFreePrivateHeap(ssPackageName.Buffer);
  3532. LsapFreePrivateHeap(ssPrincipalName.Buffer);
  3533. pApiMessage->ApiMessage.scRet = scApiRet;
  3534. if (FAILED(pApiMessage->ApiMessage.scRet))
  3535. {
  3536. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  3537. }
  3538. return(S_OK);
  3539. }
  3540. NTSTATUS
  3541. LpcEnumLogonSessions(
  3542. PSPM_LPC_MESSAGE pApiMessage
  3543. )
  3544. {
  3545. NTSTATUS scApiRet;
  3546. NTSTATUS scRet;
  3547. SPMEnumLogonSessionAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.EnumLogonSession ;
  3548. PSession pSession ;
  3549. pSession = GetCurrentSession();
  3550. DebugLog((DEB_TRACE, "[%x] LpcEnumLogonSessions()\n", pSession->dwProcessID));
  3551. scApiRet = WLsaEnumerateLogonSession(
  3552. &pArgs->LogonSessionCount,
  3553. (PLUID *) &pArgs->LogonSessionList );
  3554. //
  3555. // Reset the reply flags:
  3556. //
  3557. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  3558. pApiMessage->ApiMessage.scRet = scApiRet;
  3559. if (FAILED(pApiMessage->ApiMessage.scRet))
  3560. {
  3561. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  3562. }
  3563. return(S_OK);
  3564. }
  3565. NTSTATUS
  3566. LpcGetLogonSessionData(
  3567. PSPM_LPC_MESSAGE pApiMessage
  3568. )
  3569. {
  3570. NTSTATUS scApiRet;
  3571. NTSTATUS scRet;
  3572. SPMGetLogonSessionDataAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.GetLogonSessionData ;
  3573. PSession pSession ;
  3574. pSession = GetCurrentSession();
  3575. DebugLog((DEB_TRACE, "[%x] LpcGetLogonSessionData()\n", pSession->dwProcessID));
  3576. scApiRet = WLsaGetLogonSessionData(
  3577. &pArgs->LogonId,
  3578. &pArgs->LogonSessionInfo );
  3579. //
  3580. // Reset the reply flags:
  3581. //
  3582. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  3583. pApiMessage->ApiMessage.scRet = scApiRet;
  3584. if (FAILED(pApiMessage->ApiMessage.scRet))
  3585. {
  3586. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  3587. }
  3588. return(S_OK);
  3589. }
  3590. NTSTATUS
  3591. LpcLookupAccountName(
  3592. PSPM_LPC_MESSAGE pApiMessage
  3593. )
  3594. {
  3595. NTSTATUS scApiRet;
  3596. NTSTATUS scRet;
  3597. SPMLookupAccountNameXAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.LookupAccountNameX ;
  3598. PSession pSession ;
  3599. UNICODE_STRING Name ;
  3600. PUCHAR Where = NULL ;
  3601. LSAPR_TRANSLATED_SIDS_EX2 Sids ;
  3602. PLSAPR_REFERENCED_DOMAIN_LIST DomList ;
  3603. LSAPR_UNICODE_STRING String ;
  3604. ULONG MappedCount ;
  3605. ULONG Available ;
  3606. ULONG Size ;
  3607. pSession = GetCurrentSession();
  3608. DebugLog((DEB_TRACE, "[%x] LpcLookupAccountName()\n", pSession->dwProcessID));
  3609. scApiRet = GetClientString(
  3610. &pArgs->Name,
  3611. &Name,
  3612. pApiMessage,
  3613. &Where );
  3614. if ( NT_SUCCESS( scApiRet ) )
  3615. {
  3616. MappedCount = 0 ;
  3617. String.Length = Name.Length ;
  3618. String.MaximumLength = Name.MaximumLength ;
  3619. String.Buffer = Name.Buffer ;
  3620. scApiRet = LsarLookupNames3(
  3621. LsapPolicyHandle,
  3622. 1,
  3623. &String,
  3624. &DomList,
  3625. &Sids,
  3626. LsapLookupWksta,
  3627. &MappedCount,
  3628. 0,
  3629. LSA_CLIENT_LATEST );
  3630. if ( NT_SUCCESS( scApiRet ) )
  3631. {
  3632. Where = pApiMessage->ApiMessage.bData ;
  3633. pArgs->NameUse = Sids.Sids[0].Use ;
  3634. Size = RtlLengthSid( (PSID) Sids.Sids[0].Sid );
  3635. pArgs->Sid = (PVOID) (Where - (PUCHAR) pApiMessage) ;
  3636. RtlCopyMemory(
  3637. Where,
  3638. Sids.Sids[0].Sid,
  3639. Size );
  3640. Available = CBPREPACK - Size ;
  3641. Where += Size ;
  3642. Size = DomList->Domains[0].Name.Length ;
  3643. if ( Available >= Size )
  3644. {
  3645. RtlCopyMemory(
  3646. Where,
  3647. DomList->Domains[0].Name.Buffer,
  3648. Size );
  3649. pArgs->Domain.Buffer = (PWSTR) (Where - (PUCHAR) pApiMessage ) ;
  3650. pArgs->Domain.Length = (USHORT) Size ;
  3651. pArgs->Domain.MaximumLength = (USHORT) Size ;
  3652. }
  3653. else
  3654. {
  3655. pArgs->Domain.Buffer = NULL ;
  3656. pArgs->Domain.Length = 0 ;
  3657. pArgs->Domain.MaximumLength = 0 ;
  3658. }
  3659. MIDL_user_free( DomList );
  3660. MIDL_user_free( Sids.Sids );
  3661. }
  3662. }
  3663. //
  3664. // Reset the reply flags:
  3665. //
  3666. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  3667. pApiMessage->ApiMessage.scRet = scApiRet;
  3668. if (FAILED(pApiMessage->ApiMessage.scRet))
  3669. {
  3670. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  3671. }
  3672. return(S_OK);
  3673. }
  3674. NTSTATUS
  3675. LpcLookupAccountSid(
  3676. PSPM_LPC_MESSAGE pApiMessage
  3677. )
  3678. {
  3679. NTSTATUS scApiRet = STATUS_SUCCESS ;
  3680. NTSTATUS scRet;
  3681. SPMLookupAccountSidXAPI * pArgs = &pApiMessage->ApiMessage.Args.SpmArguments.API.LookupAccountSidX ;
  3682. PSession pSession ;
  3683. PUCHAR Where = NULL ;
  3684. PLSAPR_REFERENCED_DOMAIN_LIST DomList ;
  3685. LSAPR_SID_ENUM_BUFFER SidBuffer ;
  3686. LSAPR_SID_INFORMATION SidInfo ;
  3687. LSAPR_TRANSLATED_NAMES_EX Names ;
  3688. ULONG MappedCount ;
  3689. SIZE_T Available ;
  3690. ULONG Size ;
  3691. PSID Sid = NULL ;
  3692. pSession = GetCurrentSession();
  3693. DebugLog((DEB_TRACE, "[%x] LpcLookupAccountSid()\n", pSession->dwProcessID));
  3694. Where = (ULONG_PTR) pArgs->Sid + (PUCHAR) pApiMessage ;
  3695. Available = sizeof( SPM_LPC_MESSAGE ) - (ULONG_PTR) pArgs->Sid ;
  3696. //
  3697. // Verify that the passed SID is at least large enough for the SID header
  3698. //
  3699. if ( Available < sizeof( SID ) )
  3700. {
  3701. scApiRet = STATUS_INVALID_PARAMETER ;
  3702. }
  3703. if ( NT_SUCCESS( scApiRet ) )
  3704. {
  3705. Sid = (PSID) ( Where );
  3706. Size = RtlLengthSid( Sid );
  3707. if ( Size > Available )
  3708. {
  3709. scApiRet = STATUS_INVALID_PARAMETER ;
  3710. }
  3711. }
  3712. if ( NT_SUCCESS( scApiRet ) )
  3713. {
  3714. PSID DomainSid = NULL;
  3715. MappedCount = 0 ;
  3716. SidInfo.Sid = (PLSAPR_SID) Sid ;
  3717. SidBuffer.Entries = 1 ;
  3718. SidBuffer.SidInfo = &SidInfo ;
  3719. if( LsapAccountDomainMemberSid )
  3720. {
  3721. ULONG SidLength = RtlLengthSid( LsapAccountDomainMemberSid );
  3722. DomainSid = LsapAllocatePrivateHeap(
  3723. SidLength
  3724. );
  3725. if( DomainSid != NULL )
  3726. {
  3727. RtlCopyMemory(DomainSid, LsapAccountDomainMemberSid, SidLength);
  3728. *(RtlSubAuthoritySid(
  3729. DomainSid,
  3730. (*GetSidSubAuthorityCount(DomainSid) - 1)
  3731. )) = DOMAIN_USER_RID_GUEST;
  3732. SidInfo.Sid = (PLSAPR_SID)DomainSid;
  3733. }
  3734. }
  3735. scApiRet = LsarLookupSids2(
  3736. LsapPolicyHandle,
  3737. &SidBuffer,
  3738. &DomList,
  3739. &Names,
  3740. LsapLookupWksta,
  3741. &MappedCount,
  3742. 0,
  3743. LSA_CLIENT_LATEST );
  3744. if ( NT_SUCCESS( scApiRet ) &&
  3745. ( MappedCount == 1 ) )
  3746. {
  3747. Where = pApiMessage->ApiMessage.bData ;
  3748. pArgs->NameUse = Names.Names[0].Use ;
  3749. Size = Names.Names[0].Name.Length ;
  3750. pArgs->Name.Buffer = (PWSTR) (Where - (PUCHAR) pApiMessage );
  3751. pArgs->Name.Length = (USHORT) Size ;
  3752. pArgs->Name.MaximumLength = pArgs->Name.Length ;
  3753. RtlCopyMemory(
  3754. Where,
  3755. Names.Names[0].Name.Buffer,
  3756. Size );
  3757. Available = CBPREPACK - Size ;
  3758. Where += Size ;
  3759. Size = DomList->Domains[0].Name.Length ;
  3760. if ( Available >= Size )
  3761. {
  3762. RtlCopyMemory(
  3763. Where,
  3764. DomList->Domains[0].Name.Buffer,
  3765. Size );
  3766. pArgs->Domain.Buffer = (PWSTR) Where ;
  3767. pArgs->Domain.Length = (USHORT) Size ;
  3768. pArgs->Domain.MaximumLength = (USHORT) Size ;
  3769. }
  3770. else
  3771. {
  3772. pArgs->Domain.Buffer = NULL ;
  3773. pArgs->Domain.Length = 0 ;
  3774. pArgs->Domain.MaximumLength = 0 ;
  3775. }
  3776. MIDL_user_free( DomList );
  3777. MIDL_user_free( Names.Names );
  3778. }
  3779. if( DomainSid )
  3780. {
  3781. LsapFreePrivateHeap( DomainSid );
  3782. }
  3783. }
  3784. //
  3785. // Reset the reply flags:
  3786. //
  3787. pApiMessage->ApiMessage.Args.SpmArguments.fAPI &= KLPC_FLAG_RESET ;
  3788. pApiMessage->ApiMessage.scRet = scApiRet;
  3789. if (FAILED(pApiMessage->ApiMessage.scRet))
  3790. {
  3791. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  3792. }
  3793. return(S_OK);
  3794. }
  3795. //+---------------------------------------------------------------------------
  3796. //
  3797. // Function: LsapClientCallback
  3798. //
  3799. // Synopsis: Client Callback.
  3800. //
  3801. // Arguments: [Session] --
  3802. // [Type] --
  3803. // [Function] --
  3804. // [Argument1] --
  3805. // [Argument2] --
  3806. // [Input] --
  3807. // [Output] --
  3808. //
  3809. // History: 12-09-97 RichardW Created
  3810. //
  3811. // Notes:
  3812. //
  3813. //----------------------------------------------------------------------------
  3814. NTSTATUS
  3815. LsapClientCallback(
  3816. PSession Session,
  3817. ULONG Type,
  3818. PVOID Function,
  3819. PVOID Argument1,
  3820. PVOID Argument2,
  3821. PSecBuffer Input,
  3822. PSecBuffer Output
  3823. )
  3824. {
  3825. PSPM_LPC_MESSAGE Message ;
  3826. NTSTATUS Status ;
  3827. SPMCallbackAPI * Args ;
  3828. PSPM_LPC_MESSAGE ReplyTo ;
  3829. PVOID ClientBuffer ;
  3830. PLSA_CALL_INFO CallInfo ;
  3831. CallInfo = LsapGetCurrentCall();
  3832. if ( !CallInfo )
  3833. {
  3834. return STATUS_INVALID_PARAMETER ;
  3835. }
  3836. ReplyTo = CallInfo->Message ;
  3837. if ( !ReplyTo )
  3838. {
  3839. return STATUS_INVALID_PARAMETER ;
  3840. }
  3841. Message = (PSPM_LPC_MESSAGE) LsapAllocatePrivateHeap(
  3842. sizeof( SPM_LPC_MESSAGE ) );
  3843. if ( !Message )
  3844. {
  3845. return SEC_E_INSUFFICIENT_MEMORY ;
  3846. }
  3847. // DebugLog(( DEB_TRACE_LPC, "Calling back on LPC message %x\n",
  3848. // ReplyTo->pmMessage.MessageId ));
  3849. PREPARE_MESSAGE_EX( (*Message), Callback, SPMAPI_FLAG_CALLBACK, 0 );
  3850. Message->pmMessage = ReplyTo->pmMessage ;
  3851. Message->pmMessage.u1.s1.DataLength = LPC_DATA_LENGTH( 0 );
  3852. Message->pmMessage.u1.s1.TotalLength = LPC_TOTAL_LENGTH( 0 );
  3853. Args = LPC_MESSAGE_ARGS( (*Message), Callback );
  3854. Args->Type = Type ;
  3855. Args->CallbackFunction = Function ;
  3856. Args->Argument1 = Argument1 ;
  3857. Args->Argument2 = Argument2 ;
  3858. if ( Input->pvBuffer )
  3859. {
  3860. Status = LsapWriteClientBuffer( Input, &Args->Input );
  3861. if ( !NT_SUCCESS( Status ) )
  3862. {
  3863. LsapFreePrivateHeap( Message );
  3864. return Status ;
  3865. }
  3866. }
  3867. else
  3868. {
  3869. Args->Input.BufferType = SECBUFFER_EMPTY ;
  3870. Args->Input.cbBuffer = 0 ;
  3871. Args->Input.pvBuffer = NULL ;
  3872. }
  3873. ClientBuffer = Args->Input.pvBuffer ;
  3874. if ( CallInfo->InProcCall )
  3875. {
  3876. //
  3877. // Inproc Callback!
  3878. //
  3879. Status = DllCallbackHandler( Message );
  3880. }
  3881. else
  3882. {
  3883. DsysAssert( Session->hPort );
  3884. Status = NtRequestWaitReplyPort( Session->hPort,
  3885. (PPORT_MESSAGE) Message,
  3886. (PPORT_MESSAGE) Message );
  3887. }
  3888. if ( !NT_SUCCESS( Status ) )
  3889. {
  3890. LsapFreePrivateHeap( Message );
  3891. return Status ;
  3892. }
  3893. if ( ClientBuffer )
  3894. {
  3895. LsapFreeClientBuffer( NULL, ClientBuffer );
  3896. }
  3897. *Output = Args->Output ;
  3898. Status = Message->ApiMessage.scRet ;
  3899. LsapFreePrivateHeap( Message );
  3900. return Status ;
  3901. }
  3902. //+---------------------------------------------------------------------------
  3903. //
  3904. // Function: LsapShutdownInprocDll
  3905. //
  3906. // Synopsis: Shuts down the inproc secur32 DLL
  3907. //
  3908. // History: 11-04-98 RichardW Created
  3909. //
  3910. // Notes:
  3911. //
  3912. //----------------------------------------------------------------------------
  3913. VOID
  3914. LsapShutdownInprocDll(
  3915. VOID
  3916. )
  3917. {
  3918. SPM_LPC_MESSAGE LocalMessage ;
  3919. PSPM_LPC_MESSAGE Message ;
  3920. SPMCallbackAPI * Args ;
  3921. Message = &LocalMessage;
  3922. PREPARE_MESSAGE_EX( (*Message), Callback, SPMAPI_FLAG_CALLBACK, 0 );
  3923. Args = LPC_MESSAGE_ARGS( (*Message), Callback );
  3924. Args->Type = SPM_CALLBACK_INTERNAL ;
  3925. Args->CallbackFunction = NULL ;
  3926. Args->Argument1 = (PVOID) SPM_CALLBACK_SHUTDOWN ;
  3927. Args->Argument2 = 0 ;
  3928. if ( DllCallbackHandler )
  3929. {
  3930. (void) DllCallbackHandler( Message );
  3931. }
  3932. }
  3933. //+-------------------------------------------------------------------------
  3934. //
  3935. // Function: DispatchAPI()
  3936. //
  3937. // Synopsis: Dispatches API requests
  3938. //
  3939. // Effects:
  3940. //
  3941. // Arguments: pApiMessage - Input message
  3942. // pApiMessage - Output message
  3943. //
  3944. // Requires:
  3945. //
  3946. // Returns:
  3947. //
  3948. // Notes:
  3949. //
  3950. //--------------------------------------------------------------------------
  3951. extern "C"
  3952. NTSTATUS
  3953. DispatchAPI(PSPM_LPC_MESSAGE pApiMessage)
  3954. {
  3955. NTSTATUS scRet;
  3956. PSession pSession ;
  3957. pSession = GetCurrentSession();
  3958. DebugLog((DEB_TRACE,"[%x] LpcDispatch: dispatching %s (%x)\n",
  3959. pSession->dwProcessID, ApiLabel(pApiMessage->ApiMessage.dwAPI),
  3960. pApiMessage->ApiMessage.dwAPI));
  3961. scRet = 0;
  3962. if ((pApiMessage->ApiMessage.dwAPI >= LsapAuLookupPackageApi) &&
  3963. (pApiMessage->ApiMessage.dwAPI < SPMAPI_MaxApiNumber) &&
  3964. (LpcDispatchTable[pApiMessage->ApiMessage.dwAPI] != NULL) )
  3965. {
  3966. if ( !ShutdownBegun )
  3967. {
  3968. scRet = LpcDispatchTable[pApiMessage->ApiMessage.dwAPI](pApiMessage);
  3969. //
  3970. // BUGBUG: If scRet is not STATUS_SUCCESS, the error code gets dropped
  3971. //
  3972. }
  3973. else
  3974. {
  3975. pApiMessage->ApiMessage.scRet = STATUS_SHUTDOWN_IN_PROGRESS;
  3976. }
  3977. //
  3978. // Shutdown may have been initiated prior or during a call in progress.
  3979. // If the call failed, we always return an error code indicating that
  3980. // shutdown was invoked. This avoids returning random error codes
  3981. // that can result from calls failing due to async shutdown activities.
  3982. //
  3983. if( ShutdownBegun && !NT_SUCCESS(pApiMessage->ApiMessage.scRet) )
  3984. {
  3985. scRet = STATUS_SHUTDOWN_IN_PROGRESS;
  3986. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  3987. pApiMessage->ApiMessage.scRet = scRet ;
  3988. }
  3989. //
  3990. // Do some checking to see if we're getting pounded by an agressive
  3991. // app. NOTE: This is not MT safe (counters are not interlocked,
  3992. // resets are not protected). This is merely an optimization to try
  3993. // and service clients with dedicated threads. The counter may not
  3994. // be precise - them's the breaks.
  3995. //
  3996. pSession->CallCount++ ;
  3997. if ( pSession->Tick + 5000 < GetTickCount() )
  3998. {
  3999. //
  4000. // Ok, in a minimum five second interval, did more than, say, 50
  4001. // requests come in. If so, set a flag indicating that the client
  4002. // should request a workqueue.
  4003. //
  4004. if ( pSession->CallCount > 50 )
  4005. {
  4006. if (pApiMessage->ApiMessage.dwAPI > LsapAuMaxApiNumber )
  4007. {
  4008. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_GETSTATE ;
  4009. }
  4010. }
  4011. pSession->CallCount = 0;
  4012. pSession->Tick = GetTickCount();
  4013. }
  4014. }
  4015. else
  4016. {
  4017. DebugLog((DEB_ERROR, "[%x] Dispatch: Unknown API code %d\n",
  4018. pSession->dwProcessID, pApiMessage->ApiMessage.dwAPI));
  4019. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  4020. pApiMessage->ApiMessage.scRet = SEC_E_UNSUPPORTED_FUNCTION;
  4021. }
  4022. DebugLog((DEB_TRACE, "[%x] LpcDispatch: retcode = %x\n", pSession->dwProcessID, pApiMessage->ApiMessage.scRet));
  4023. return(S_OK);
  4024. }
  4025. VOID
  4026. LsapInitializeCallInfo(
  4027. PLSA_CALL_INFO CallInfo,
  4028. BOOL InProcess
  4029. )
  4030. {
  4031. PLSA_CALL_INFO OriginalCall ;
  4032. OriginalCall = LsapGetCurrentCall() ;
  4033. ZeroMemory( CallInfo, sizeof( LSA_CALL_INFO ) );
  4034. CallInfo->PreviousCall = OriginalCall ;
  4035. CallInfo->InProcCall = InProcess ;
  4036. CallInfo->CallInfo.ProcessId = HandleToUlong(NtCurrentTeb()->ClientId.UniqueProcess) ;
  4037. CallInfo->CallInfo.ThreadId = HandleToUlong(NtCurrentTeb()->ClientId.UniqueThread) ;
  4038. CallInfo->CallInfo.Attributes = 0 ;
  4039. CallInfo->Allocs = 0 ;
  4040. CallInfo->LogContext = NULL ;
  4041. }
  4042. NTSTATUS
  4043. LsapBuildCallInfo(
  4044. PSPM_LPC_MESSAGE pApiMessage,
  4045. PLSA_CALL_INFO CallInfo,
  4046. PHANDLE Impersonated,
  4047. PSession * NewSession,
  4048. PSession * OldSession
  4049. )
  4050. {
  4051. NTSTATUS scRet ;
  4052. BOOL Recurse = FALSE ;
  4053. HANDLE ImpersonatedToken ;
  4054. PSession pOldSession ;
  4055. PSession pSession ;
  4056. PLSA_CALL_INFO OriginalCall ;
  4057. OriginalCall = LsapGetCurrentCall() ;
  4058. LsapInitializeCallInfo( CallInfo,
  4059. TRUE );
  4060. //
  4061. // Save away who we were impersonating
  4062. //
  4063. scRet = NtOpenThreadToken(
  4064. NtCurrentThread(),
  4065. TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE,
  4066. TRUE,
  4067. &ImpersonatedToken
  4068. );
  4069. if (!NT_SUCCESS(scRet))
  4070. {
  4071. if (scRet != STATUS_NO_TOKEN)
  4072. {
  4073. return(scRet);
  4074. }
  4075. ImpersonatedToken = NULL ;
  4076. scRet = STATUS_SUCCESS ;
  4077. }
  4078. *Impersonated = ImpersonatedToken ;
  4079. CallInfo->InProcToken = ImpersonatedToken ;
  4080. CallInfo->Message = pApiMessage ;
  4081. //
  4082. // Check to see if we're recursing:
  4083. //
  4084. if ( OriginalCall &&
  4085. OriginalCall->InProcCall &&
  4086. pApiMessage &&
  4087. OriginalCall->Message )
  4088. {
  4089. if ( OriginalCall->Message->ApiMessage.dwAPI ==
  4090. pApiMessage->ApiMessage.dwAPI )
  4091. {
  4092. //
  4093. // Same call. Since they're both inproc, the pointers
  4094. // are valid. Compare the target strings
  4095. //
  4096. if ( pApiMessage->ApiMessage.dwAPI == SPMAPI_InitContext )
  4097. {
  4098. Recurse = (RtlCompareUnicodeString(
  4099. &pApiMessage->ApiMessage.Args.SpmArguments.API.InitContext.ssTarget,
  4100. &OriginalCall->Message->ApiMessage.Args.SpmArguments.API.InitContext.ssTarget,
  4101. TRUE ) == 0) ;
  4102. }
  4103. }
  4104. }
  4105. if ( Recurse )
  4106. {
  4107. DebugLog(( DEB_ERROR, "Recursive call\n" ));
  4108. CallInfo->CallInfo.Attributes |= SECPKG_CALL_RECURSIVE ;
  4109. }
  4110. pOldSession = GetCurrentSession();
  4111. pSession = pDefaultSession ;
  4112. CallInfo->Session = pSession ;
  4113. SpmpReferenceSession( pSession );
  4114. *NewSession = pSession ;
  4115. *OldSession = pOldSession ;
  4116. return scRet ;
  4117. }
  4118. extern "C"
  4119. NTSTATUS
  4120. InitializeDirectDispatcher(
  4121. VOID
  4122. )
  4123. {
  4124. InternalApiLog = ApiLogCreate( 0 );
  4125. if ( InternalApiLog )
  4126. {
  4127. return STATUS_SUCCESS ;
  4128. }
  4129. return STATUS_UNSUCCESSFUL ;
  4130. }
  4131. //+---------------------------------------------------------------------------
  4132. //
  4133. // Function: DispatchAPIDirect
  4134. //
  4135. // Synopsis: Dispatcher to be called from security.dll when in process.
  4136. //
  4137. // Arguments: [pApiMessage] --
  4138. //
  4139. // History: 9-13-96 RichardW Created
  4140. //
  4141. // Notes:
  4142. //
  4143. //----------------------------------------------------------------------------
  4144. NTSTATUS
  4145. SEC_ENTRY
  4146. DispatchAPIDirect(
  4147. PSPM_LPC_MESSAGE pApiMessage)
  4148. {
  4149. NTSTATUS scRet;
  4150. PSession pOldSession;
  4151. PSession pSession;
  4152. PVOID DsaState ;
  4153. HANDLE ImpersonatedToken = NULL;
  4154. ULONG TokenSize = sizeof(HANDLE);
  4155. LSA_CALL_INFO CallInfo ;
  4156. PLSA_CALL_INFO OriginalCall ;
  4157. ULONG_PTR OriginalPackageId;
  4158. PLSAP_API_LOG_ENTRY Entry ;
  4159. //
  4160. // save off the current package hints to allow recursion in process.
  4161. //
  4162. OriginalCall = LsapGetCurrentCall() ;
  4163. OriginalPackageId = GetCurrentPackageId();
  4164. pApiMessage->pmMessage.MessageId = InterlockedIncrement( &InternalMessageId );
  4165. Entry = ApiLogAlloc( InternalApiLog );
  4166. scRet = LsapBuildCallInfo(
  4167. pApiMessage,
  4168. &CallInfo,
  4169. &ImpersonatedToken,
  4170. &pSession,
  4171. &pOldSession );
  4172. if ( !NT_SUCCESS( scRet ) )
  4173. {
  4174. return scRet ;
  4175. }
  4176. DBG_DISPATCH_PROLOGUE_EX( Entry, pApiMessage, CallInfo );
  4177. LsapSetCurrentCall( &CallInfo );
  4178. SetCurrentSession( pSession );
  4179. if ( GetDsaThreadState )
  4180. {
  4181. DsaState = GetDsaThreadState();
  4182. }
  4183. else
  4184. {
  4185. DsaState = NULL ;
  4186. }
  4187. DebugLog((DEB_TRACE,"[%x] DispatchAPIDirect: dispatching %s (%d)\n",
  4188. pSession->dwProcessID, ApiLabel(pApiMessage->ApiMessage.dwAPI),
  4189. pApiMessage->ApiMessage.dwAPI));
  4190. scRet = 0;
  4191. if ((pApiMessage->ApiMessage.dwAPI >= LsapAuLookupPackageApi) &&
  4192. (pApiMessage->ApiMessage.dwAPI < SPMAPI_MaxApiNumber) &&
  4193. (LpcDispatchTable[pApiMessage->ApiMessage.dwAPI] != NULL) )
  4194. {
  4195. scRet = LpcDispatchTable[pApiMessage->ApiMessage.dwAPI](pApiMessage);
  4196. }
  4197. else
  4198. {
  4199. DebugLog((DEB_ERROR, "[%x] Dispatch: Unknown API code %x\n", pSession->dwProcessID, pApiMessage->ApiMessage.dwAPI));
  4200. pApiMessage->ApiMessage.Args.SpmArguments.fAPI |= SPMAPI_FLAG_ERROR_RET;
  4201. pApiMessage->ApiMessage.scRet = SEC_E_UNSUPPORTED_FUNCTION;
  4202. }
  4203. DebugLog((DEB_TRACE, "[%x] DispatchAPIDirect: retcode = %x\n", pSession->dwProcessID, pApiMessage->ApiMessage.scRet));
  4204. if ( DsaState )
  4205. {
  4206. RestoreDsaThreadState( DsaState );
  4207. }
  4208. if ( pOldSession != pSession )
  4209. {
  4210. SetCurrentSession( pOldSession );
  4211. }
  4212. DBG_DISPATCH_POSTLOGUE( ULongToPtr( pApiMessage->ApiMessage.scRet ),
  4213. pApiMessage->ApiMessage.dwAPI );
  4214. SpmpDereferenceSession( pSession );
  4215. SetCurrentPackageId( OriginalPackageId );
  4216. LsapSetCurrentCall( OriginalCall );
  4217. (void) NtSetInformationThread(
  4218. NtCurrentThread(),
  4219. ThreadImpersonationToken,
  4220. (PVOID) &ImpersonatedToken,
  4221. sizeof(HANDLE)
  4222. );
  4223. if ( ImpersonatedToken )
  4224. {
  4225. NtClose( ImpersonatedToken );
  4226. }
  4227. return( SEC_E_OK );
  4228. }
  4229. //+---------------------------------------------------------------------------
  4230. //
  4231. // Function: LpcLsaPolicyChangeNotify
  4232. //
  4233. // Synopsis: Lpc stub for LsaPolicyChangeNotify
  4234. //
  4235. // Arguments: [pApiMessage] --
  4236. //
  4237. // History: 06-05-98 MacM Created
  4238. //
  4239. // Notes:
  4240. //
  4241. //----------------------------------------------------------------------------
  4242. NTSTATUS
  4243. LpcLsaPolicyChangeNotify(
  4244. PSPM_LPC_MESSAGE pApiMessage
  4245. )
  4246. {
  4247. SPMLsaPolicyChangeNotifyAPI * Args = &pApiMessage->ApiMessage.Args.SpmArguments.API.LsaPolicyChangeNotify;
  4248. NTSTATUS Status = STATUS_SUCCESS;
  4249. HANDLE LocalHandle = NULL;
  4250. PSession Session;
  4251. Session = GetCurrentSession();
  4252. Status = CheckCaller( Session );
  4253. if ( !NT_SUCCESS( Status ) ) {
  4254. DebugLog(( DEB_ERROR, "CheckCaller returned 0x%lx\n", Status ));
  4255. return( Status );
  4256. }
  4257. //
  4258. // Duplicate the handle
  4259. //
  4260. Status = NtDuplicateObject( Session->hProcess,
  4261. Args->EventHandle,
  4262. NtCurrentProcess(),
  4263. &LocalHandle,
  4264. 0,
  4265. 0,
  4266. DUPLICATE_SAME_ACCESS );
  4267. //
  4268. // Now, the notify
  4269. //
  4270. if (NT_SUCCESS( Status )) {
  4271. Status = LsapNotifyProcessNotificationEvent( Args->NotifyInfoClass,
  4272. LocalHandle,
  4273. Session->dwProcessID,
  4274. Args->EventHandle,
  4275. Args->Register );
  4276. if ( NT_SUCCESS( Status )) {
  4277. // Indicate that we've successfully registered the handle
  4278. LocalHandle = NULL;
  4279. }
  4280. //
  4281. // Since we duplicated the handle in our namespace, if we fail to register it,
  4282. // make sure we close it
  4283. //
  4284. if ( LocalHandle != NULL ) {
  4285. NtClose( LocalHandle );
  4286. }
  4287. }
  4288. pApiMessage->ApiMessage.scRet = Status;
  4289. return( Status );
  4290. }