Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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