Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2636 lines
62 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1991 - 1992
  6. //
  7. // File: sphelp.c
  8. //
  9. // Contents: Security Package Helper functions (see isecpkg.doc)
  10. //
  11. // Functions LsapUnloadPackage
  12. // LsapAllocate
  13. // LsapFree
  14. // LsapClientAllocate
  15. // LsapCopyToClient
  16. // LsapCopyFromClient
  17. // LsapClientFree
  18. // LsapOpenClientProcess
  19. // LsapOpenClientThread
  20. // LsapDuplicateHandle
  21. // LsapSaveSupplementalCredentials
  22. // LsapGetWindow
  23. // LsapCreateThread
  24. // LsapMapClientBuffer
  25. //
  26. //
  27. // Notes: By defining TRACK_MEM, we will track all use of memory
  28. // allocated through the LsapAllocate. DBG_MEM will track
  29. // memory leaks.
  30. //
  31. // History: 20 May 92 RichardW Created
  32. //
  33. //------------------------------------------------------------------------
  34. #include <lsapch.hxx>
  35. extern "C"
  36. {
  37. #include "sesmgr.h"
  38. #include "spdebug.h"
  39. #include "klpcstub.h"
  40. }
  41. typedef struct _LSAP_THREAD_START {
  42. LPTHREAD_START_ROUTINE lpStart;
  43. LPVOID lpParm;
  44. ULONG_PTR dwPackageID;
  45. } LSAP_THREAD_START, *PLSAP_THREAD_START;
  46. extern LSA_CALL_INFO LsapDefaultCallInfo ;
  47. ULONG_PTR LsapUserModeLimit ;
  48. //
  49. // private heaps defines.
  50. //
  51. // HEAP_HEADER should always be size even multiple of heap allocation granularity
  52. //
  53. typedef struct {
  54. HANDLE hHeap;
  55. SIZE_T Magic;
  56. } HEAP_HEADER_LSA, *PHEAP_HEADER_LSA;
  57. #define HEAP_COUNT_MAX 32
  58. #define HEAP_MAGIC_TAG 0x66677766
  59. HANDLE gHeaps[ HEAP_COUNT_MAX ];
  60. DWORD gcHeaps;
  61. #if DBG
  62. //
  63. // Failure simulation parameters
  64. //
  65. ULONG TotalAllocations;
  66. ULONG_PTR PackageToFail = SPMGR_ID;
  67. SpmDbg_MemoryFailure MemFail;
  68. #endif // DBG
  69. void
  70. CacheMachineInReg(GUID *);
  71. #define MEM_MAGIC 0x0feedbed
  72. #define MEM_FREED 0x0b00b00b
  73. #define MEM_MASK 0x0FFFFFFF
  74. #define MEM_NEVER 0x10000000
  75. LSA_SECPKG_FUNCTION_TABLE LsapSecpkgFunctionTable = {
  76. LsapCreateLogonSession,
  77. LsapDeleteLogonSession,
  78. LsapAddCredential,
  79. LsapGetCredentials,
  80. LsapDeleteCredential,
  81. LsapAllocateLsaHeap,
  82. LsapFreeLsaHeap,
  83. LsapAllocateClientBuffer,
  84. LsapFreeClientBuffer,
  85. LsapCopyToClientBuffer,
  86. LsapCopyFromClientBuffer,
  87. LsapImpersonateClient,
  88. LsapUnloadPackage,
  89. LsapDuplicateHandle,
  90. NULL, // LsapSaveSupplementalCredentials,
  91. LsapCreateThread,
  92. LsapGetClientInfo,
  93. LsaIRegisterNotification,
  94. LsaICancelNotification,
  95. LsapMapClientBuffer,
  96. LsapCreateToken,
  97. LsapAuditLogon,
  98. LsaICallPackage,
  99. LsaIFreeReturnBuffer,
  100. LsapGetCallInfo,
  101. LsaICallPackageEx,
  102. LsaCreateSharedMemory,
  103. LsaAllocateSharedMemory,
  104. LsaFreeSharedMemory,
  105. LsaDeleteSharedMemory,
  106. LsaOpenSamUser,
  107. LsaGetUserCredentials,
  108. LsaGetUserAuthData,
  109. LsaCloseSamUser,
  110. LsaConvertAuthDataToToken,
  111. LsaClientCallback,
  112. LsapUpdateCredentials,
  113. LsaGetAuthDataForUser,
  114. LsaCrackSingleName,
  115. LsaIAuditAccountLogon,
  116. LsaICallPackagePassthrough,
  117. CrediRead,
  118. CrediReadDomainCredentials,
  119. CrediFreeCredentials,
  120. LsaProtectMemory,
  121. LsaUnprotectMemory,
  122. LsapOpenTokenByLogonId,
  123. LsaExpandAuthDataForDomain,
  124. LsapAllocatePrivateHeap,
  125. LsapFreePrivateHeap,
  126. LsapCreateTokenEx
  127. };
  128. //+-------------------------------------------------------------------------
  129. //
  130. // Function: LsapOpenCaller
  131. //
  132. // Synopsis: Opens the calling process
  133. //
  134. // Effects:
  135. //
  136. // Arguments: phProcess -- receives handle to process
  137. //
  138. // Requires:
  139. //
  140. // Returns:
  141. //
  142. // Notes:
  143. //
  144. //--------------------------------------------------------------------------
  145. NTSTATUS
  146. LsapOpenCaller(
  147. IN OUT PSession pSession
  148. )
  149. {
  150. HANDLE hProcess;
  151. NTSTATUS Status;
  152. OBJECT_ATTRIBUTES ObjectAttributes;
  153. CLIENT_ID ClientId;
  154. PVOID Ignored ;
  155. ClientId.UniqueThread = NULL;
  156. ClientId.UniqueProcess = (HANDLE) LongToHandle(pSession->dwProcessID);
  157. InitializeObjectAttributes(
  158. &ObjectAttributes,
  159. NULL,
  160. 0,
  161. NULL,
  162. NULL
  163. );
  164. Status = NtOpenProcess(
  165. &hProcess,
  166. PROCESS_DUP_HANDLE | // Duplicate Handles
  167. PROCESS_QUERY_INFORMATION | // Get token
  168. PROCESS_VM_OPERATION | // Allocate
  169. PROCESS_VM_READ | // Read memory
  170. PROCESS_VM_WRITE, // Write memory
  171. &ObjectAttributes,
  172. &ClientId
  173. );
  174. if (!NT_SUCCESS(Status))
  175. {
  176. DebugLog((DEB_ERROR, "Did not open process %08x, error %08x\n",
  177. pSession->dwProcessID, Status));
  178. return( Status );
  179. }
  180. pSession->hProcess = hProcess;
  181. Status = NtQueryInformationProcess(
  182. hProcess,
  183. ProcessSessionInformation,
  184. &pSession->SessionId,
  185. sizeof( ULONG ),
  186. NULL );
  187. #if _WIN64
  188. Status = NtQueryInformationProcess(
  189. hProcess,
  190. ProcessWow64Information,
  191. &Ignored,
  192. sizeof( Ignored ),
  193. NULL );
  194. if ( NT_SUCCESS( Status ) )
  195. {
  196. if ( Ignored != 0 )
  197. {
  198. pSession->fSession |= SESFLAG_WOW_PROCESS ;
  199. }
  200. }
  201. #endif
  202. return( STATUS_SUCCESS );
  203. }
  204. //+-------------------------------------------------------------------------
  205. //
  206. // Function: CheckCaller
  207. //
  208. // Synopsis: Checks if calling process has been opened, opens if it
  209. // hasn't.
  210. //
  211. // Effects:
  212. //
  213. // Arguments: pSession - Current session
  214. //
  215. // Requires:
  216. //
  217. // Returns:
  218. //
  219. // Notes:
  220. //
  221. //--------------------------------------------------------------------------
  222. NTSTATUS
  223. CheckCaller(
  224. IN PSession pSession
  225. )
  226. {
  227. NTSTATUS Status;
  228. if (!pSession->hProcess)
  229. {
  230. Status = LsapOpenCaller(pSession);
  231. if (FAILED(Status))
  232. {
  233. DebugLog((DEB_ERROR, "Could not open client (%x)\n", Status));
  234. return(Status);
  235. }
  236. }
  237. return(STATUS_SUCCESS);
  238. }
  239. //+-------------------------------------------------------------------------
  240. //
  241. // Function: LsapUnloadPackage
  242. //
  243. // Synopsis: Unloads the calling package in case of catastrophic problems
  244. //
  245. // Effects: Unloads the DLL that generated this call.
  246. //
  247. // Arguments:
  248. //
  249. // Requires:
  250. //
  251. // Returns:
  252. //
  253. // Notes: Calling thread is terminated through a special exception.
  254. //
  255. //--------------------------------------------------------------------------
  256. NTSTATUS NTAPI
  257. LsapUnloadPackage(
  258. VOID
  259. )
  260. {
  261. ULONG_PTR PackageId;
  262. PSession pSession = GetCurrentSession();
  263. PackageId = GetCurrentPackageId();
  264. //
  265. // If this is an autonomous thread, we should interrupt any other threads
  266. // that are currently executing in the DLL. At this time, I do not know
  267. // what will happen if the virtual address space of a thread suddenly
  268. // becomes invalid, or even if that will happen. We'll find out...
  269. //
  270. if (pSession->fSession & SESFLAG_AUTONOMOUS)
  271. {
  272. DebugLog((DEB_WARN, "Autonomous thread executed LsapUnloadPackage\n"));
  273. }
  274. pSession->fSession |= SESFLAG_UNLOADING;
  275. RaiseException((ULONG) SEC_E_BAD_PKGID, 0, 0, NULL);
  276. return(STATUS_SUCCESS);
  277. }
  278. BOOLEAN
  279. LsapHeapInitialize(
  280. IN BOOLEAN Server
  281. )
  282. {
  283. if( !Server )
  284. {
  285. NT_PRODUCT_TYPE ProductType;
  286. if ( RtlGetNtProductType( &ProductType ) &&
  287. (ProductType == NtProductServer || ProductType == NtProductLanManNt)
  288. )
  289. {
  290. Server = TRUE;
  291. }
  292. }
  293. if ( Server )
  294. {
  295. SYSTEM_INFO si;
  296. DWORD Heaps;
  297. DWORD i, cHeapsCreated;
  298. RTL_HEAP_PARAMETERS HeapParameters;
  299. GetSystemInfo( &si );
  300. if( si.dwNumberOfProcessors == 0 ) {
  301. Heaps = 1;
  302. } else if( si.dwNumberOfProcessors > HEAP_COUNT_MAX )
  303. {
  304. Heaps = HEAP_COUNT_MAX;
  305. } else {
  306. Heaps = si.dwNumberOfProcessors;
  307. }
  308. ZeroMemory( &HeapParameters, sizeof(HeapParameters) );
  309. HeapParameters.Length = sizeof(HeapParameters);
  310. HeapParameters.DeCommitTotalFreeThreshold = 8 * LsapPageSize ;
  311. cHeapsCreated = 0;
  312. for( i = 0 ; i < Heaps ; i++ )
  313. {
  314. gHeaps[ cHeapsCreated ] = RtlCreateHeap(
  315. HEAP_GROWABLE,
  316. NULL,
  317. 0,
  318. 0,
  319. NULL,
  320. &HeapParameters
  321. );
  322. if( gHeaps[ cHeapsCreated ] != NULL )
  323. {
  324. cHeapsCreated++;
  325. }
  326. }
  327. gcHeaps = cHeapsCreated;
  328. }
  329. if( gHeaps[ 0 ] == NULL )
  330. {
  331. gHeaps[ 0 ] = RtlProcessHeap();
  332. gcHeaps = 1;
  333. }
  334. return TRUE;
  335. }
  336. //+-------------------------------------------------------------------------
  337. //
  338. // Function: LsapAllocateLsaHeap
  339. //
  340. // Synopsis: Allocates memory on process heap
  341. //
  342. // Effects:
  343. //
  344. // Arguments: cbMemory -- Size of block needed
  345. //
  346. // Requires:
  347. //
  348. // Returns: ptr to memory
  349. //
  350. // Notes: if DBGMEM or TRACK_MEM defined, extra work is done for
  351. // tracking purposes.
  352. //
  353. // Can raise the exception STATUS_NO_MEMORY
  354. //
  355. // Per object reuse rules of C2 and above, we zero any memory
  356. // allocated through this function
  357. //
  358. //--------------------------------------------------------------------------
  359. PVOID NTAPI
  360. LsapAllocateLsaHeap(
  361. IN ULONG cbMemory
  362. )
  363. {
  364. #if DBG
  365. if (MemFail.fSimulateFailure)
  366. {
  367. TotalAllocations++;
  368. if ((TotalAllocations > MemFail.FailureDelay) &&
  369. (TotalAllocations < MemFail.FailureLength + MemFail.FailureDelay))
  370. {
  371. if ((TotalAllocations % MemFail.FailureInterval) == 0)
  372. {
  373. if ((PackageToFail == SPMGR_ID) ||
  374. (GetCurrentPackageId() == PackageToFail))
  375. {
  376. DebugLog((DEB_TRACE,"LsapAllocateLsaHeap: Simulating failure\n"));
  377. return(NULL);
  378. }
  379. }
  380. }
  381. }
  382. #endif // DBG
  383. return(RtlAllocateHeap(
  384. RtlProcessHeap(),
  385. HEAP_ZERO_MEMORY,
  386. cbMemory
  387. ));
  388. }
  389. //+-------------------------------------------------------------------------
  390. //
  391. // Function: LsapFreeLsaHeap
  392. //
  393. // Synopsis: Frees memory allocated by LsapAllocateLsaHeap
  394. //
  395. // Effects:
  396. //
  397. // Arguments: pvMemory
  398. //
  399. // Requires:
  400. //
  401. // Returns:
  402. //
  403. // Notes:
  404. //
  405. //--------------------------------------------------------------------------
  406. void NTAPI
  407. LsapFreeLsaHeap(
  408. IN PVOID pvMemory
  409. )
  410. {
  411. RtlFreeHeap(
  412. RtlProcessHeap(),
  413. 0,
  414. pvMemory
  415. );
  416. }
  417. //+-------------------------------------------------------------------------
  418. //
  419. // Function: LsapAllocatePrivateHeap
  420. //
  421. // Synopsis: Allocates memory on private heap(s)
  422. //
  423. // Effects:
  424. //
  425. // Arguments: cbMemory -- Size of block needed
  426. //
  427. // Requires:
  428. //
  429. // Returns: ptr to memory
  430. //
  431. // Per object reuse rules of C2 and above, we zero any memory
  432. // allocated through this function
  433. //
  434. //--------------------------------------------------------------------------
  435. PVOID
  436. NTAPI
  437. LsapAllocatePrivateHeap(
  438. IN SIZE_T cbMemory
  439. )
  440. {
  441. HANDLE hHeap;
  442. PHEAP_HEADER_LSA memory;
  443. hHeap = LsapGetCurrentHeap();
  444. if( hHeap == NULL )
  445. {
  446. static ULONG heapindex;
  447. ULONG LocalHeapIndex;
  448. LocalHeapIndex = (ULONG)InterlockedIncrement( (PLONG)&heapindex );
  449. LocalHeapIndex %= gcHeaps;
  450. hHeap = gHeaps[ LocalHeapIndex ];
  451. LsapSetCurrentHeap( hHeap );
  452. }
  453. memory = (PHEAP_HEADER_LSA)RtlAllocateHeap(
  454. hHeap,
  455. HEAP_ZERO_MEMORY,
  456. cbMemory+sizeof(HEAP_HEADER_LSA)
  457. );
  458. if( memory != NULL )
  459. {
  460. memory->hHeap = hHeap;
  461. memory->Magic = (unsigned char*)HEAP_MAGIC_TAG-(unsigned char*)hHeap;
  462. return ( (unsigned char*)memory+sizeof(HEAP_HEADER_LSA) );
  463. }
  464. DebugLog((DEB_ERROR,"LsapAllocatePrivateHeap: %p failed allocate %lu bytes\n", hHeap, cbMemory));
  465. return NULL;
  466. }
  467. PVOID
  468. NTAPI
  469. LsapAllocatePrivateHeapNoZero(
  470. IN SIZE_T cbMemory
  471. )
  472. {
  473. HANDLE hHeap;
  474. PHEAP_HEADER_LSA memory;
  475. hHeap = LsapGetCurrentHeap();
  476. if( hHeap == NULL )
  477. {
  478. static ULONG heapindex;
  479. ULONG LocalHeapIndex;
  480. LocalHeapIndex = (ULONG)InterlockedIncrement( (PLONG)&heapindex );
  481. LocalHeapIndex %= gcHeaps;
  482. hHeap = gHeaps[ LocalHeapIndex ];
  483. LsapSetCurrentHeap( hHeap );
  484. }
  485. memory = (PHEAP_HEADER_LSA)RtlAllocateHeap(
  486. hHeap,
  487. 0,
  488. cbMemory+sizeof(HEAP_HEADER_LSA)
  489. );
  490. if( memory != NULL )
  491. {
  492. memory->hHeap = hHeap;
  493. memory->Magic = (unsigned char*)HEAP_MAGIC_TAG-(unsigned char*)hHeap;
  494. return ( (unsigned char*)memory+sizeof(HEAP_HEADER_LSA) );
  495. }
  496. DebugLog((DEB_ERROR,"LsapAllocatePrivateHeapNoZero: %p failed allocate %lu bytes\n", hHeap, cbMemory));
  497. return NULL;
  498. }
  499. //+-------------------------------------------------------------------------
  500. //
  501. // Function: LsapFreePrivateHeap
  502. //
  503. // Synopsis: Frees memory allocated by LsapAllocatePrivateHeap
  504. //
  505. // Effects:
  506. //
  507. // Arguments: pvMemory
  508. //
  509. // Requires:
  510. //
  511. // Returns:
  512. //
  513. // Notes:
  514. //
  515. //--------------------------------------------------------------------------
  516. void
  517. NTAPI
  518. LsapFreePrivateHeap(
  519. IN PVOID pvMemory
  520. )
  521. {
  522. PHEAP_HEADER_LSA HeapEntry;
  523. if( pvMemory == NULL )
  524. {
  525. return ;
  526. }
  527. HeapEntry = (PHEAP_HEADER_LSA)((unsigned char*)pvMemory-sizeof(HEAP_HEADER_LSA));
  528. if( HeapEntry->Magic + ((unsigned char*)HeapEntry->hHeap) != (unsigned char*)HEAP_MAGIC_TAG )
  529. {
  530. DebugLog((DEB_ERROR, "LsapFreePrivateHeap tried to free %p from wrong heap\n",
  531. pvMemory));
  532. DsysAssert( pvMemory == NULL );
  533. return;
  534. }
  535. RtlFreeHeap(
  536. HeapEntry->hHeap,
  537. 0,
  538. HeapEntry
  539. );
  540. }
  541. //+-------------------------------------------------------------------------
  542. //
  543. // Function: LsapClientAllocate
  544. //
  545. // Synopsis: Allocates memory in client process
  546. //
  547. // Effects:
  548. //
  549. // Arguments: cbMemory -- Size of block to allocate
  550. //
  551. // Requires:
  552. //
  553. // Returns: pointer to memory in client address space
  554. //
  555. // Notes: pointer is not valid in this process, only in client
  556. //
  557. //--------------------------------------------------------------------------
  558. PVOID NTAPI
  559. LsapClientAllocate(
  560. IN ULONG cbMemory
  561. )
  562. {
  563. NTSTATUS Status;
  564. PSession pSession;
  565. void * pClientMemory = NULL;
  566. SIZE_T cbMem = cbMemory;
  567. PLSA_CALL_INFO CallInfo ;
  568. CallInfo = LsapGetCurrentCall();
  569. pSession = GetCurrentSession() ;
  570. if ( pSession == NULL )
  571. {
  572. pSession = pDefaultSession ;
  573. }
  574. if ( CallInfo == NULL )
  575. {
  576. CallInfo = &LsapDefaultCallInfo ;
  577. }
  578. if (FAILED(CheckCaller(pSession)))
  579. {
  580. return(NULL);
  581. }
  582. //
  583. // If the INPROC flag is set, allocate out of the heap. The copy functions
  584. // will also honor this.
  585. //
  586. if ( pSession->fSession & SESFLAG_INPROC )
  587. {
  588. pClientMemory = LsapAllocateLsaHeap( (ULONG) cbMem );
  589. return( pClientMemory );
  590. }
  591. if ( CallInfo->Flags & CALL_FLAG_KERNEL_POOL )
  592. {
  593. if ( ( CallInfo->Flags & CALL_FLAG_KMAP_USED ) != 0 )
  594. {
  595. pClientMemory = LsapAllocateFromKsecBuffer(
  596. CallInfo->KMap,
  597. (ULONG) cbMem );
  598. DebugLog((DEB_TRACE_HELPERS, "[%x] LsapClientAllocate(%d) = %p in KMap %p\n",
  599. pSession->dwProcessID, cbMem,
  600. pClientMemory, CallInfo->KMap ));
  601. return pClientMemory ;
  602. }
  603. }
  604. Status = NtAllocateVirtualMemory(pSession->hProcess,
  605. &pClientMemory,
  606. 0,
  607. &cbMem,
  608. MEM_COMMIT,
  609. PAGE_READWRITE);
  610. if (!NT_SUCCESS(Status))
  611. {
  612. DebugLog((DEB_ERROR, "[%x] Could not allocate client memory (%x)\n",
  613. pSession->dwProcessID, Status));
  614. pClientMemory = NULL;
  615. }
  616. DebugLog((DEB_TRACE_HELPERS, "[%x] LsapClientAllocate(%d) = %p\n",
  617. pSession->dwProcessID, cbMemory, pClientMemory));
  618. if ( pClientMemory )
  619. {
  620. // Save pointer so that FreeContextBuffer will use
  621. // correct 'free' function.
  622. if(CallInfo->Allocs < MAX_BUFFERS_IN_CALL)
  623. {
  624. CallInfo->Buffers[ CallInfo->Allocs++ ] = pClientMemory ;
  625. }
  626. }
  627. return(pClientMemory);
  628. }
  629. //+-------------------------------------------------------------------------
  630. //
  631. // Function: LsapCopyToClient
  632. //
  633. // Synopsis: Copies data into client process
  634. //
  635. // Effects:
  636. //
  637. // Arguments: pLocalMemory -- pointer to data in this process
  638. // pClientMemory -- pointer to destination in client process
  639. // cbMemory -- how much to copy
  640. //
  641. // Requires:
  642. //
  643. // Returns:
  644. //
  645. // Notes:
  646. //
  647. //--------------------------------------------------------------------------
  648. NTSTATUS NTAPI
  649. LsapCopyToClient(
  650. IN PVOID pLocalMemory,
  651. OUT PVOID pClientMemory,
  652. IN ULONG cbMemory
  653. )
  654. {
  655. NTSTATUS Status;
  656. PSession pSession;
  657. PLSA_CALL_INFO CallInfo;
  658. PKSEC_LSA_MEMORY_HEADER Header ;
  659. ULONG i ;
  660. ULONG_PTR Basis ;
  661. ULONG_PTR Limit ;
  662. BOOL Tried = FALSE ;
  663. if (cbMemory == 0)
  664. {
  665. return(STATUS_SUCCESS);
  666. }
  667. pSession = GetCurrentSession();
  668. if ( !pSession )
  669. {
  670. pSession = pDefaultSession ;
  671. }
  672. CallInfo = LsapGetCurrentCall();
  673. if ( ( pLocalMemory == NULL ) ||
  674. ( pClientMemory == NULL ) )
  675. {
  676. return STATUS_ACCESS_VIOLATION ;
  677. }
  678. if (FAILED(Status = CheckCaller(pSession)))
  679. {
  680. return(Status);
  681. }
  682. //
  683. // Cases for a direct copy:
  684. //
  685. // - The current session is the default session
  686. // - This is an inproc call
  687. // - We're using a KMap buffer
  688. //
  689. if (CallInfo &&
  690. CallInfo->Flags & CALL_FLAG_KERNEL_POOL )
  691. {
  692. Header = CallInfo->KMap ;
  693. if ( (ULONG_PTR) pClientMemory > LsapUserModeLimit )
  694. {
  695. //
  696. // Someone is trying to deal with a pool address directly.
  697. // we can handle this if it was copied into the KMap already
  698. //
  699. for ( i = 0 ; i < Header->MapCount ; i++ )
  700. {
  701. Limit = (ULONG_PTR) Header->PoolMap[ i ].Pool + Header->PoolMap[ i ].Size ;
  702. if ( ((ULONG_PTR) pClientMemory >= (ULONG_PTR) Header->PoolMap[ i ].Pool ) &&
  703. ( (ULONG_PTR) pClientMemory < Limit ) )
  704. {
  705. //
  706. // Found an overlap, this is promising. Check the bounds:
  707. //
  708. Basis = (ULONG_PTR) pClientMemory -
  709. (ULONG_PTR) Header->PoolMap[ i ].Pool ;
  710. if ( Basis + cbMemory <= Header->PoolMap[ i ].Size )
  711. {
  712. //
  713. // Found it!
  714. //
  715. __try
  716. {
  717. RtlCopyMemory(
  718. (PUCHAR) Header +
  719. (Header->PoolMap[ i ].Offset +
  720. Basis),
  721. pLocalMemory,
  722. cbMemory );
  723. Status = STATUS_SUCCESS ;
  724. }
  725. __except (EXCEPTION_EXECUTE_HANDLER)
  726. {
  727. Status = GetExceptionCode();
  728. }
  729. }
  730. Tried = TRUE ;
  731. break;
  732. }
  733. }
  734. if ( !Tried )
  735. {
  736. Status = STATUS_ACCESS_VIOLATION ;
  737. }
  738. }
  739. else if ( LsapIsBlockInKMap( CallInfo->KMap, pClientMemory ) )
  740. {
  741. __try
  742. {
  743. RtlCopyMemory( pClientMemory, pLocalMemory, cbMemory );
  744. Status = STATUS_SUCCESS ;
  745. }
  746. __except (EXCEPTION_EXECUTE_HANDLER)
  747. {
  748. Status = GetExceptionCode();
  749. }
  750. }
  751. else
  752. {
  753. Status = NtWriteVirtualMemory(pSession->hProcess,
  754. pClientMemory,
  755. pLocalMemory,
  756. cbMemory,
  757. NULL);
  758. }
  759. } else if ( (pSession->dwProcessID == pDefaultSession->dwProcessID) ||
  760. (pSession->fSession & SESFLAG_INPROC) ||
  761. (CallInfo->Flags & CALL_FLAG_KMAP_USED ) )
  762. {
  763. __try
  764. {
  765. RtlCopyMemory( pClientMemory, pLocalMemory, cbMemory );
  766. Status = STATUS_SUCCESS ;
  767. }
  768. __except ( EXCEPTION_EXECUTE_HANDLER )
  769. {
  770. Status = GetExceptionCode();
  771. }
  772. }
  773. else
  774. {
  775. Status = NtWriteVirtualMemory( pSession->hProcess,
  776. pClientMemory,
  777. pLocalMemory,
  778. cbMemory,
  779. NULL);
  780. }
  781. DebugLog((DEB_TRACE_HELPERS, "[%x] LsapCopyToClient(%p, %p, %d) = %x\n",
  782. pSession->dwProcessID, pLocalMemory, pClientMemory, cbMemory,
  783. Status ));
  784. return(Status);
  785. }
  786. //+-------------------------------------------------------------------------
  787. //
  788. // Function: LsapCopyFromClient
  789. //
  790. // Synopsis: Copies memory from client to this process
  791. //
  792. // Effects:
  793. //
  794. // Arguments: pClientMemory -- Pointer to data in client space
  795. // pLocalMemory -- Pointer to destination in this process
  796. // cbMemory -- How much
  797. //
  798. // Requires:
  799. //
  800. // Returns:
  801. //
  802. // Notes:
  803. //
  804. //--------------------------------------------------------------------------
  805. NTSTATUS NTAPI
  806. LsapCopyFromClient(
  807. IN PVOID pClientMemory,
  808. OUT PVOID pLocalMemory,
  809. IN ULONG cbMemory
  810. )
  811. {
  812. NTSTATUS Status;
  813. PSession pSession;
  814. PLSA_CALL_INFO CallInfo ;
  815. PKSEC_LSA_MEMORY_HEADER Header ;
  816. ULONG i ;
  817. ULONG_PTR Basis ;
  818. ULONG_PTR Limit ;
  819. BOOL Tried = FALSE ;
  820. if (cbMemory == 0)
  821. {
  822. return(STATUS_SUCCESS);
  823. }
  824. if ( ( pClientMemory == NULL ) ||
  825. ( pLocalMemory == NULL ) )
  826. {
  827. return STATUS_ACCESS_VIOLATION ;
  828. }
  829. pSession = GetCurrentSession();
  830. if ( pSession == NULL )
  831. {
  832. pSession = pDefaultSession ;
  833. }
  834. CallInfo = LsapGetCurrentCall();
  835. if (FAILED(Status = CheckCaller(pSession)))
  836. {
  837. return(Status);
  838. }
  839. if (CallInfo &&
  840. CallInfo->Flags & CALL_FLAG_KERNEL_POOL )
  841. {
  842. Header = CallInfo->KMap ;
  843. if ( (ULONG_PTR) pClientMemory > LsapUserModeLimit )
  844. {
  845. //
  846. // Someone is trying to deal with a pool address directly.
  847. // we can handle this if it was copied into the KMap already
  848. //
  849. for ( i = 0 ; i < Header->MapCount ; i++ )
  850. {
  851. Limit = (ULONG_PTR) Header->PoolMap[ i ].Pool + Header->PoolMap[ i ].Size ;
  852. if ( ((ULONG_PTR) pClientMemory >= (ULONG_PTR) Header->PoolMap[ i ].Pool ) &&
  853. ( (ULONG_PTR) pClientMemory < Limit ) )
  854. {
  855. //
  856. // Found an overlap, this is promising. Check the bounds:
  857. //
  858. Basis = (ULONG_PTR) pClientMemory -
  859. (ULONG_PTR) Header->PoolMap[ i ].Pool ;
  860. if ( Basis + cbMemory <= Header->PoolMap[ i ].Size )
  861. {
  862. //
  863. // Found it!
  864. //
  865. __try
  866. {
  867. RtlCopyMemory(
  868. pLocalMemory,
  869. (PUCHAR) Header +
  870. (Header->PoolMap[ i ].Offset +
  871. Basis),
  872. cbMemory );
  873. Status = STATUS_SUCCESS ;
  874. }
  875. __except (EXCEPTION_EXECUTE_HANDLER)
  876. {
  877. Status = GetExceptionCode();
  878. }
  879. }
  880. Tried = TRUE ;
  881. break;
  882. }
  883. }
  884. if ( !Tried )
  885. {
  886. Status = STATUS_ACCESS_VIOLATION ;
  887. }
  888. }
  889. else if ( LsapIsBlockInKMap( CallInfo->KMap, pClientMemory ) )
  890. {
  891. __try
  892. {
  893. RtlCopyMemory( pLocalMemory, pClientMemory, cbMemory );
  894. Status = STATUS_SUCCESS ;
  895. }
  896. __except (EXCEPTION_EXECUTE_HANDLER)
  897. {
  898. Status = GetExceptionCode();
  899. }
  900. }
  901. else
  902. {
  903. Status = NtReadVirtualMemory(pSession->hProcess,
  904. pClientMemory,
  905. pLocalMemory,
  906. cbMemory,
  907. NULL);
  908. }
  909. }
  910. else if ( (pSession->dwProcessID == pDefaultSession->dwProcessID) ||
  911. (pSession->fSession & SESFLAG_INPROC ) )
  912. {
  913. __try
  914. {
  915. RtlCopyMemory( pLocalMemory, pClientMemory, cbMemory );
  916. Status = STATUS_SUCCESS ;
  917. }
  918. __except (EXCEPTION_EXECUTE_HANDLER)
  919. {
  920. Status = GetExceptionCode();
  921. }
  922. }
  923. else
  924. {
  925. Status = NtReadVirtualMemory(pSession->hProcess,
  926. pClientMemory,
  927. pLocalMemory,
  928. cbMemory,
  929. NULL);
  930. }
  931. DebugLog((DEB_TRACE_HELPERS, "[%x] LsapCopyFromClient(%p, %p, %d) = %x\n",
  932. pSession->dwProcessID, pClientMemory, pLocalMemory, cbMemory,
  933. Status));
  934. return(Status);
  935. }
  936. //+-------------------------------------------------------------------------
  937. //
  938. // Function: LsapClientFree
  939. //
  940. // Synopsis: Frees memory allocated in client space
  941. //
  942. // Effects:
  943. //
  944. // Arguments: pClientMemory -- pointer to memory to free
  945. //
  946. // Requires:
  947. //
  948. // Returns:
  949. //
  950. // Notes:
  951. //
  952. //--------------------------------------------------------------------------
  953. NTSTATUS NTAPI
  954. LsapClientFree(
  955. IN PVOID pClientMemory
  956. )
  957. {
  958. NTSTATUS Status;
  959. SIZE_T cbMem = 0;
  960. PSession pSession;
  961. PLSA_CALL_INFO CallInfo ;
  962. CallInfo = LsapGetCurrentCall();
  963. if ( CallInfo == NULL )
  964. {
  965. CallInfo = &LsapDefaultCallInfo ;
  966. }
  967. if (!pClientMemory)
  968. {
  969. return(STATUS_SUCCESS);
  970. }
  971. pSession = GetCurrentSession();
  972. if ( pSession == NULL )
  973. {
  974. pSession = pDefaultSession ;
  975. }
  976. if (FAILED(Status = CheckCaller(pSession)))
  977. {
  978. return(Status);
  979. }
  980. if ( pSession->fSession & SESFLAG_INPROC )
  981. {
  982. LsapFreeLsaHeap( pClientMemory );
  983. return( STATUS_SUCCESS );
  984. }
  985. #if DBG
  986. if ( pSession->dwProcessID == pDefaultSession->dwProcessID )
  987. {
  988. DebugLog(( DEB_ERROR, "Freeing VM in LSA: %x\n", pClientMemory ));
  989. }
  990. #endif
  991. Status = NtFreeVirtualMemory(pSession->hProcess,
  992. &pClientMemory,
  993. &cbMem,
  994. MEM_RELEASE);
  995. if ( pClientMemory )
  996. {
  997. ULONG i;
  998. // Remove this pointer from our list.
  999. for(i = 0; i < CallInfo->Allocs; i++)
  1000. {
  1001. if(CallInfo->Buffers[i] == pClientMemory)
  1002. {
  1003. if(i < CallInfo->Allocs - 1)
  1004. {
  1005. memcpy(&CallInfo->Buffers[i],
  1006. &CallInfo->Buffers[i+1],
  1007. sizeof(PVOID) * (CallInfo->Allocs - i - 1));
  1008. }
  1009. CallInfo->Allocs--;
  1010. break;
  1011. }
  1012. }
  1013. }
  1014. DebugLog((DEB_TRACE_HELPERS, "[%x] LsapClientFree(%x) == %x\n",
  1015. pSession->dwProcessID, pClientMemory, Status));
  1016. return(Status);
  1017. }
  1018. //+-------------------------------------------------------------------------
  1019. //
  1020. // Function: LsapDuplicateHandle
  1021. //
  1022. // Synopsis: Duplicates a handle to an NT object into the calling process
  1023. //
  1024. // Effects: A new handle is generated, referencing the object
  1025. //
  1026. // Arguments: hObject -- handle to the object
  1027. // hNewObject -- New handle valid in calling process
  1028. //
  1029. // Requires:
  1030. //
  1031. // Returns:
  1032. //
  1033. // Notes:
  1034. //
  1035. //--------------------------------------------------------------------------
  1036. NTSTATUS NTAPI
  1037. LsapDuplicateHandle(
  1038. IN HANDLE hObject,
  1039. OUT PHANDLE phNewObject
  1040. )
  1041. {
  1042. NTSTATUS Status;
  1043. PSession pSession;
  1044. pSession = GetCurrentSession();
  1045. if ( pSession == NULL )
  1046. {
  1047. pSession = pDefaultSession ;
  1048. }
  1049. if (Status = CheckCaller(pSession))
  1050. {
  1051. DebugLog((DEB_ERROR, "CheckCaller returned %d\n", Status));
  1052. return(Status);
  1053. }
  1054. Status = NtDuplicateObject( NtCurrentProcess(),
  1055. hObject,
  1056. pSession->hProcess,
  1057. phNewObject,
  1058. 0,
  1059. 0,
  1060. DUPLICATE_SAME_ACCESS);
  1061. DebugLog((DEB_TRACE_HELPERS, "[%x] LsapDupHandle(%x, %x (@%x)) = %x\n",
  1062. pSession->dwProcessID, hObject, *phNewObject, phNewObject, Status));
  1063. return(Status);
  1064. }
  1065. //+---------------------------------------------------------------------------
  1066. //
  1067. // Function: LsapImpersonateClient
  1068. //
  1069. // Synopsis: Impersonate the client of the API call.
  1070. //
  1071. // Arguments: (none)
  1072. //
  1073. // History: 6-05-95 RichardW Created
  1074. //
  1075. // Notes: Threads should call RevertToSelf() when done.
  1076. //
  1077. //----------------------------------------------------------------------------
  1078. NTSTATUS NTAPI
  1079. LsapImpersonateClient(
  1080. VOID
  1081. )
  1082. {
  1083. PSession pSession;
  1084. PLSA_CALL_INFO CallInfo ;
  1085. PSPM_LPC_MESSAGE pApiMessage;
  1086. NTSTATUS Status;
  1087. CallInfo = LsapGetCurrentCall() ;
  1088. if ( CallInfo->InProcCall )
  1089. {
  1090. if ( CallInfo->InProcToken )
  1091. {
  1092. Status = NtSetInformationThread(
  1093. NtCurrentThread(),
  1094. ThreadImpersonationToken,
  1095. (PVOID) &CallInfo->InProcToken,
  1096. sizeof(HANDLE)
  1097. );
  1098. }
  1099. else
  1100. {
  1101. Status = RtlImpersonateSelf(SecurityImpersonation);
  1102. }
  1103. }
  1104. else
  1105. {
  1106. pSession = GetCurrentSession() ;
  1107. if ( !pSession )
  1108. {
  1109. pSession = pDefaultSession ;
  1110. }
  1111. Status = NtImpersonateClientOfPort(
  1112. pSession->hPort,
  1113. (PPORT_MESSAGE) CallInfo->Message);
  1114. }
  1115. return(Status);
  1116. }
  1117. //+-------------------------------------------------------------------------
  1118. //
  1119. // Function: LsapDuplicateString
  1120. //
  1121. // Synopsis:
  1122. //
  1123. // Effects:
  1124. //
  1125. // Arguments:
  1126. //
  1127. // Requires:
  1128. //
  1129. // Returns:
  1130. //
  1131. // Notes:
  1132. //
  1133. //--------------------------------------------------------------------------
  1134. NTSTATUS
  1135. LsapDuplicateString(
  1136. OUT PUNICODE_STRING pDest,
  1137. IN PUNICODE_STRING pSrc
  1138. )
  1139. {
  1140. pDest->Length = 0;
  1141. if (pSrc == NULL)
  1142. {
  1143. pDest->Buffer = NULL;
  1144. pDest->MaximumLength = 0;
  1145. return(STATUS_SUCCESS);
  1146. }
  1147. pDest->Buffer = (LPWSTR) LsapAllocateLsaHeap(pSrc->Length + sizeof(WCHAR));
  1148. if (pDest->Buffer)
  1149. {
  1150. pDest->MaximumLength = pSrc->Length + sizeof(WCHAR);
  1151. RtlCopyMemory(
  1152. pDest->Buffer,
  1153. pSrc->Buffer,
  1154. pSrc->Length
  1155. );
  1156. pDest->Buffer[pSrc->Length/sizeof(WCHAR)] = L'\0';
  1157. pDest->Length = pSrc->Length;
  1158. return(STATUS_SUCCESS);
  1159. } else
  1160. {
  1161. pDest->MaximumLength = 0;
  1162. return(STATUS_INSUFFICIENT_RESOURCES);
  1163. }
  1164. }
  1165. NTSTATUS
  1166. LsapDuplicateString2(
  1167. OUT PUNICODE_STRING pDest,
  1168. IN PUNICODE_STRING pSrc
  1169. )
  1170. /*++
  1171. Same as LsapDuplicateString(), but uses LsapPrivateHeap routines.
  1172. --*/
  1173. {
  1174. pDest->Length = 0;
  1175. if (pSrc == NULL)
  1176. {
  1177. pDest->Buffer = NULL;
  1178. pDest->MaximumLength = 0;
  1179. return(STATUS_SUCCESS);
  1180. }
  1181. pDest->Buffer = (LPWSTR) LsapAllocatePrivateHeap(pSrc->Length + sizeof(WCHAR));
  1182. if (pDest->Buffer)
  1183. {
  1184. pDest->MaximumLength = pSrc->Length + sizeof(WCHAR);
  1185. RtlCopyMemory(
  1186. pDest->Buffer,
  1187. pSrc->Buffer,
  1188. pSrc->Length
  1189. );
  1190. pDest->Buffer[pSrc->Length/sizeof(WCHAR)] = L'\0';
  1191. pDest->Length = pSrc->Length;
  1192. return(STATUS_SUCCESS);
  1193. } else
  1194. {
  1195. pDest->MaximumLength = 0;
  1196. return(STATUS_INSUFFICIENT_RESOURCES);
  1197. }
  1198. }
  1199. //+-------------------------------------------------------------------------
  1200. //
  1201. // Function: LsapFreeString
  1202. //
  1203. // Synopsis: Frees a string allocated by LsapDuplicateString
  1204. //
  1205. // Effects:
  1206. //
  1207. // Arguments: String - Optionally points to a UNICODE_STRING
  1208. //
  1209. // Requires:
  1210. //
  1211. // Returns:
  1212. //
  1213. // Notes:
  1214. //
  1215. //
  1216. //--------------------------------------------------------------------------
  1217. VOID
  1218. LsapFreeString(
  1219. IN OPTIONAL PUNICODE_STRING String
  1220. )
  1221. {
  1222. if (ARGUMENT_PRESENT(String) && String->Buffer != NULL)
  1223. {
  1224. LsapFreeLsaHeap(String->Buffer);
  1225. String->Buffer = NULL;
  1226. }
  1227. }
  1228. //+-------------------------------------------------------------------------
  1229. //
  1230. // Function: LsapThreadBase
  1231. //
  1232. // Synopsis: Thread start routine
  1233. //
  1234. // Effects: Sets up all the TLS data for a thread, then executes
  1235. // the "real" base function.
  1236. //
  1237. // Arguments:
  1238. //
  1239. // Requires:
  1240. //
  1241. // Returns:
  1242. //
  1243. // Notes:
  1244. //
  1245. //--------------------------------------------------------------------------
  1246. void
  1247. LsapThreadBase(
  1248. PLSAP_THREAD_START pThread)
  1249. {
  1250. NTSTATUS Status;
  1251. PSession pSession;
  1252. LSAP_THREAD_START tStart = *pThread;
  1253. LsapFreePrivateHeap(pThread);
  1254. SetCurrentSession( pDefaultSession );
  1255. SpmpReferenceSession( pDefaultSession );
  1256. // Initialize Session information:
  1257. SetCurrentPackageId(tStart.dwPackageID);
  1258. DebugLog((DEB_TRACE, "Thread start @%x\n", tStart.lpStart));
  1259. // If this is a debug build, all threads are started in a protective
  1260. // try-except block. For retail, only threads started by packages
  1261. // will be run this way. Retail builds, we assume that the SPM is
  1262. // debugged and running correctly, and threads started this way can
  1263. // be trusted.
  1264. #if DBG == 0
  1265. if (tStart.dwPackageID != SPMGR_ID)
  1266. #endif
  1267. {
  1268. __try
  1269. {
  1270. tStart.lpStart(tStart.lpParm);
  1271. }
  1272. __except (SP_EXCEPTION)
  1273. {
  1274. Status = GetExceptionCode();
  1275. Status = SPException(Status, tStart.dwPackageID);
  1276. }
  1277. }
  1278. #if DBG == 0
  1279. else
  1280. {
  1281. tStart.lpStart(tStart.lpParm);
  1282. }
  1283. #endif
  1284. pSession = GetCurrentSession();
  1285. SpmpDereferenceSession( pSession );
  1286. if ( pSession != pDefaultSession )
  1287. {
  1288. DebugLog(( DEB_ERROR, "Thread completing in session other than default!\n" ));
  1289. }
  1290. DebugLog((DEB_TRACE, "Thread exit\n" ));
  1291. }
  1292. //+-------------------------------------------------------------------------
  1293. //
  1294. // Function: LsapCreateThread
  1295. //
  1296. // Synopsis: Creates a thread with all the proper Tls stuff
  1297. //
  1298. // Effects:
  1299. //
  1300. // Arguments: same as CreateThread
  1301. //
  1302. // Requires:
  1303. //
  1304. // Returns:
  1305. //
  1306. // Notes:
  1307. //
  1308. //--------------------------------------------------------------------------
  1309. HANDLE NTAPI
  1310. LsapCreateThread(
  1311. IN LPSECURITY_ATTRIBUTES lpSA,
  1312. IN ULONG cbStack,
  1313. IN LPTHREAD_START_ROUTINE lpStart,
  1314. IN LPVOID lpvThreadParm,
  1315. IN ULONG fCreate,
  1316. OUT PULONG lpTID
  1317. )
  1318. {
  1319. PLSAP_THREAD_START pThread;
  1320. HANDLE hThread;
  1321. pThread = (PLSAP_THREAD_START) LsapAllocatePrivateHeap(sizeof(LSAP_THREAD_START));
  1322. if (pThread == NULL)
  1323. {
  1324. DebugLog((DEB_ERROR, "LsapCreateThread, memory allocation failed.\n"));
  1325. SetLastError(ERROR_OUTOFMEMORY);
  1326. return(NULL);
  1327. }
  1328. pThread->lpStart = lpStart;
  1329. pThread->lpParm = lpvThreadParm;
  1330. pThread->dwPackageID = GetCurrentPackageId();
  1331. hThread = CreateThread(
  1332. lpSA,
  1333. cbStack,
  1334. (LPTHREAD_START_ROUTINE) LsapThreadBase,
  1335. pThread,
  1336. fCreate,
  1337. lpTID
  1338. );
  1339. if( hThread == NULL )
  1340. {
  1341. DebugLog((DEB_ERROR, "LsapCreateThread, failed thread creation (%lu)\n", GetLastError()));
  1342. LsapFreePrivateHeap( pThread );
  1343. }
  1344. return hThread;
  1345. }
  1346. //+-------------------------------------------------------------------------
  1347. //
  1348. // Function: LsapGetClientInfo
  1349. //
  1350. // Synopsis:
  1351. //
  1352. // Effects:
  1353. //
  1354. // Arguments:
  1355. //
  1356. // Requires:
  1357. //
  1358. // Returns:
  1359. //
  1360. // Notes:
  1361. //
  1362. //--------------------------------------------------------------------------
  1363. NTSTATUS NTAPI
  1364. LsapGetClientInfo(
  1365. OUT PSECPKG_CLIENT_INFO ClientInfo
  1366. )
  1367. {
  1368. PSession pSession = GetCurrentSession();
  1369. PPORT_MESSAGE pMessage;
  1370. HANDLE ClientToken;
  1371. NTSTATUS Status;
  1372. NTSTATUS ExtraStatus ;
  1373. TOKEN_STATISTICS TokenStats;
  1374. ULONG TokenStatsSize = sizeof(TOKEN_STATISTICS);
  1375. PLSA_CALL_INFO CallInfo ;
  1376. HANDLE Thread = NULL ;
  1377. OBJECT_ATTRIBUTES NullAttributes = { 0 };
  1378. KERNEL_USER_TIMES Times ;
  1379. RtlZeroMemory(
  1380. ClientInfo,
  1381. sizeof(SECPKG_CLIENT_INFO)
  1382. );
  1383. if ( !pSession )
  1384. {
  1385. pSession = pDefaultSession ;
  1386. }
  1387. //
  1388. // First, fill in the easy stuff from the session record. If we are
  1389. // running with the LSA session then we want to ignore the LPC message
  1390. // because it may be referring to somebody elses message (we may be
  1391. // being called on behalf of someone doing authenticated RPC in response
  1392. // to an LPC request)
  1393. //
  1394. CallInfo = LsapGetCurrentCall();
  1395. if ( CallInfo )
  1396. {
  1397. ClientInfo->ProcessID = CallInfo->CallInfo.ProcessId ;
  1398. ClientInfo->ThreadID = CallInfo->CallInfo.ThreadId ;
  1399. if (((pSession->fSession & SESFLAG_TCB_PRIV) != 0) ||
  1400. ((pSession->fSession & SESFLAG_KERNEL) != 0))
  1401. {
  1402. ClientInfo->HasTcbPrivilege = TRUE;
  1403. }
  1404. else
  1405. {
  1406. ClientInfo->HasTcbPrivilege = FALSE;
  1407. }
  1408. if(CallInfo->CachedTokenInfo)
  1409. {
  1410. ClientInfo->LogonId = CallInfo->LogonId;
  1411. ClientInfo->Restricted = CallInfo->Restricted;
  1412. ClientInfo->Impersonating = CallInfo->Impersonating;
  1413. ClientInfo->ImpersonationLevel = CallInfo->ImpersonationLevel;
  1414. return STATUS_SUCCESS;
  1415. }
  1416. Status = LsapImpersonateClient();
  1417. if ( !NT_SUCCESS( Status ) )
  1418. {
  1419. if ( Status == STATUS_BAD_IMPERSONATION_LEVEL )
  1420. {
  1421. Status = NtOpenThread(
  1422. &Thread,
  1423. THREAD_QUERY_INFORMATION,
  1424. &NullAttributes,
  1425. &CallInfo->Message->pmMessage.ClientId );
  1426. }
  1427. else if ( ( Status == STATUS_REPLY_MESSAGE_MISMATCH ) ||
  1428. ( Status == STATUS_INVALID_CID ) ||
  1429. ( Status == STATUS_PORT_DISCONNECTED ) )
  1430. {
  1431. //
  1432. // This is a special status returned by the LPC layer to indicate
  1433. // that the client thread has disappeared, or the process is
  1434. // terminating. Set a flag to indicate this:
  1435. //
  1436. ClientInfo->ClientFlags |= SECPKG_CLIENT_THREAD_TERMINATED ;
  1437. CallInfo->CallInfo.Attributes |= SECPKG_CALL_THREAD_TERM ;
  1438. //
  1439. // Check the process. If the process has started to exit, set that
  1440. // flag as well.
  1441. //
  1442. ExtraStatus = NtQueryInformationProcess(
  1443. pSession->hProcess,
  1444. ProcessTimes,
  1445. &Times,
  1446. sizeof( Times ),
  1447. NULL );
  1448. if ( NT_SUCCESS( ExtraStatus ) )
  1449. {
  1450. if ( Times.ExitTime.QuadPart != 0 )
  1451. {
  1452. ClientInfo->ClientFlags |= SECPKG_CLIENT_PROCESS_TERMINATED ;
  1453. CallInfo->CallInfo.Attributes |= SECPKG_CALL_PROCESS_TERM ;
  1454. }
  1455. }
  1456. DebugLog(( DEB_TRACE, "Client %x.%x has terminated\n",
  1457. ClientInfo->ProcessID, ClientInfo->ThreadID ));
  1458. return STATUS_SUCCESS ;
  1459. }
  1460. }
  1461. else
  1462. {
  1463. Thread = NtCurrentThread();
  1464. }
  1465. if (!NT_SUCCESS(Status))
  1466. {
  1467. DebugLog((DEB_WARN,"Failed to impersonate client: 0x%x\n",Status));
  1468. return(Status);
  1469. }
  1470. Status = NtOpenThreadToken(
  1471. Thread,
  1472. TOKEN_QUERY,
  1473. TRUE, // use LSA security context
  1474. &ClientToken
  1475. );
  1476. if (NT_SUCCESS(Status))
  1477. {
  1478. ClientInfo->Restricted = ( IsTokenRestricted(ClientToken) != 0 );
  1479. Status = NtQueryInformationToken(
  1480. ClientToken,
  1481. TokenStatistics,
  1482. (PVOID) &TokenStats,
  1483. TokenStatsSize,
  1484. &TokenStatsSize
  1485. );
  1486. NtClose(ClientToken);
  1487. if (NT_SUCCESS(Status))
  1488. {
  1489. ClientInfo->LogonId = TokenStats.AuthenticationId;
  1490. ClientInfo->Impersonating = (TokenStats.TokenType == TokenPrimary) ? FALSE : TRUE;
  1491. if( ClientInfo->Impersonating )
  1492. {
  1493. ClientInfo->ImpersonationLevel = TokenStats.ImpersonationLevel;
  1494. } else {
  1495. ClientInfo->ImpersonationLevel = SecurityImpersonation;
  1496. }
  1497. }
  1498. }
  1499. RevertToSelf();
  1500. if ( Thread != NtCurrentThread() )
  1501. {
  1502. NtClose( Thread );
  1503. }
  1504. if(NT_SUCCESS(Status))
  1505. {
  1506. CallInfo->LogonId = ClientInfo->LogonId;
  1507. CallInfo->Restricted = ClientInfo->Restricted;
  1508. CallInfo->Impersonating = ClientInfo->Impersonating;
  1509. CallInfo->ImpersonationLevel = ClientInfo->ImpersonationLevel;
  1510. CallInfo->CachedTokenInfo = TRUE;
  1511. }
  1512. return(Status);
  1513. }
  1514. else
  1515. {
  1516. ClientInfo->ProcessID = GetCurrentProcessId();
  1517. ClientInfo->ThreadID = GetCurrentThreadId();
  1518. ClientInfo->HasTcbPrivilege = TRUE;
  1519. ClientInfo->Impersonating = FALSE;
  1520. ClientInfo->ImpersonationLevel = SecurityImpersonation;
  1521. ClientInfo->LogonId = SystemLogonId;
  1522. return(STATUS_SUCCESS);
  1523. }
  1524. }
  1525. //+---------------------------------------------------------------------------
  1526. //
  1527. // Function: LsapGetCallInfo
  1528. //
  1529. // Synopsis: Gets call information
  1530. //
  1531. // Arguments: [Info] --
  1532. //
  1533. // History: 10-06-96 RichardW Created
  1534. //
  1535. // Notes:
  1536. //
  1537. //----------------------------------------------------------------------------
  1538. BOOLEAN
  1539. LsapGetCallInfo(
  1540. PSECPKG_CALL_INFO Info
  1541. )
  1542. {
  1543. PLSA_CALL_INFO CallInfo ;
  1544. CallInfo = LsapGetCurrentCall() ;
  1545. if ( CallInfo )
  1546. {
  1547. *Info = CallInfo->CallInfo ;
  1548. if ( CallInfo->InProcCall )
  1549. {
  1550. Info->Attributes |= SECPKG_CALL_IN_PROC ;
  1551. }
  1552. return TRUE ;
  1553. } else {
  1554. Info->ProcessId = GetCurrentProcessId();
  1555. Info->ThreadId = GetCurrentThreadId();
  1556. Info->Attributes = SECPKG_CALL_IN_PROC |
  1557. SECPKG_CALL_IS_TCB ;
  1558. Info->CallCount = 0;
  1559. return TRUE;
  1560. }
  1561. }
  1562. //+-------------------------------------------------------------------------
  1563. //
  1564. // Function: LsapMapClientBuffer
  1565. //
  1566. // Synopsis: Maps a client's SecBuffer into the caller's address space
  1567. //
  1568. // Effects: Clears the SECBUFFER_UNMAPPED field of the BufferType of
  1569. // the return SecBuffer
  1570. //
  1571. // Arguments:
  1572. //
  1573. // Requires:
  1574. //
  1575. // Returns:
  1576. //
  1577. // Notes: Doesn't modify pOutput until the end, so it is o.k. to pass
  1578. // the same thing for pInput and pOutput.
  1579. //
  1580. //
  1581. //--------------------------------------------------------------------------
  1582. NTSTATUS
  1583. LsapMapClientBuffer(
  1584. IN PSecBuffer pInput,
  1585. OUT PSecBuffer pOutput
  1586. )
  1587. {
  1588. NTSTATUS Status = STATUS_SUCCESS ;
  1589. SecBuffer Output ;
  1590. Output = *pInput ;
  1591. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  1592. //
  1593. // If the buffer is already mapped or it doesn't exist (is NULL) we
  1594. // are done.
  1595. //
  1596. if (!(pInput->BufferType & SECBUFFER_UNMAPPED) ||
  1597. !pInput->pvBuffer)
  1598. {
  1599. return( STATUS_SUCCESS );
  1600. }
  1601. else
  1602. {
  1603. Output.BufferType &= ~SECBUFFER_UNMAPPED;
  1604. }
  1605. if ( pInput->BufferType & SECBUFFER_KERNEL_MAP )
  1606. {
  1607. //
  1608. // This one is already in process space
  1609. //
  1610. if ( ( CallInfo->CallInfo.Attributes & SECPKG_CALL_KERNEL_MODE ) == 0 )
  1611. {
  1612. //
  1613. // If this call did not come from kernel mode with
  1614. // the kernel-pool flag set, then this is an attempted
  1615. // hack on the LSA. Reject it.
  1616. //
  1617. Status = STATUS_ACCESS_VIOLATION ;
  1618. }
  1619. else
  1620. {
  1621. //
  1622. // The buffer is already in memory. Mark the call as
  1623. // using kernel-pool memory, so we allocate correctly
  1624. // on the return.
  1625. //
  1626. CallInfo->Flags |= CALL_FLAG_KERNEL_POOL ;
  1627. DebugLog((DEB_TRACE_SPECIAL, "Kernel Pool Map at %p [%x,%x]\n",
  1628. Output.pvBuffer, Output.BufferType, Output.cbBuffer ));
  1629. }
  1630. }
  1631. else
  1632. {
  1633. Output.pvBuffer = LsapAllocateLsaHeap( Output.cbBuffer );
  1634. if ( Output.pvBuffer != NULL )
  1635. {
  1636. Status = LsapCopyFromClient(
  1637. pInput->pvBuffer,
  1638. Output.pvBuffer,
  1639. Output.cbBuffer );
  1640. if ( !NT_SUCCESS( Status ) )
  1641. {
  1642. LsapFreeLsaHeap(Output.pvBuffer);
  1643. }
  1644. }
  1645. else
  1646. {
  1647. Status = STATUS_NO_MEMORY ;
  1648. }
  1649. }
  1650. if ( NT_SUCCESS( Status ) )
  1651. {
  1652. *pOutput = Output ;
  1653. }
  1654. return( Status );
  1655. }
  1656. //+-------------------------------------------------------------------------
  1657. //
  1658. // Function: LsaICallPackage
  1659. //
  1660. // Synopsis: Function to call another security package
  1661. //
  1662. // Effects:
  1663. //
  1664. // Arguments:
  1665. //
  1666. // Requires:
  1667. //
  1668. // Returns:
  1669. //
  1670. // Notes:
  1671. //
  1672. //
  1673. //--------------------------------------------------------------------------
  1674. extern "C"
  1675. NTSTATUS
  1676. LsaICallPackage(
  1677. IN PUNICODE_STRING AuthenticationPackage,
  1678. IN PVOID ProtocolSubmitBuffer,
  1679. IN ULONG SubmitBufferLength,
  1680. OUT PVOID *ProtocolReturnBuffer,
  1681. OUT PULONG ReturnBufferLength,
  1682. OUT PNTSTATUS ProtocolStatus
  1683. )
  1684. {
  1685. return LsaICallPackageEx( AuthenticationPackage,
  1686. ProtocolSubmitBuffer, // client buffer base is same as local buffer
  1687. ProtocolSubmitBuffer,
  1688. SubmitBufferLength,
  1689. ProtocolReturnBuffer,
  1690. ReturnBufferLength,
  1691. ProtocolStatus );
  1692. }
  1693. //+-------------------------------------------------------------------------
  1694. //
  1695. // Function: LsaICallPackageEx
  1696. //
  1697. // Synopsis: Function to call another security package
  1698. //
  1699. // Effects:
  1700. //
  1701. // Arguments:
  1702. //
  1703. // Requires:
  1704. //
  1705. // Returns:
  1706. //
  1707. // Notes:
  1708. //
  1709. //
  1710. //--------------------------------------------------------------------------
  1711. extern "C"
  1712. NTSTATUS
  1713. LsaICallPackageEx(
  1714. IN PUNICODE_STRING AuthenticationPackage,
  1715. IN PVOID ClientBufferBase,
  1716. IN PVOID ProtocolSubmitBuffer,
  1717. IN ULONG SubmitBufferLength,
  1718. OUT PVOID *ProtocolReturnBuffer,
  1719. OUT PULONG ReturnBufferLength,
  1720. OUT PNTSTATUS ProtocolStatus
  1721. )
  1722. {
  1723. NTSTATUS Status = STATUS_SUCCESS;
  1724. PLSAP_SECURITY_PACKAGE Package;
  1725. PSession OldSession;
  1726. Package = SpmpLookupPackageAndRequest(
  1727. AuthenticationPackage,
  1728. SP_ORDINAL_CALLPACKAGE
  1729. );
  1730. if (Package == NULL)
  1731. {
  1732. DebugLog((DEB_WARN,"LsapCallPackage failed: package %wZ not found\n",
  1733. AuthenticationPackage ));
  1734. Status = STATUS_NO_SUCH_PACKAGE;
  1735. goto Cleanup;
  1736. }
  1737. //
  1738. // Set the session to be the LSA's so calls to allocate memory
  1739. // will allocate in the correct process
  1740. //
  1741. OldSession = GetCurrentSession();
  1742. SetCurrentSession( pDefaultSession );
  1743. Status = Package->FunctionTable.CallPackage(
  1744. NULL,
  1745. ProtocolSubmitBuffer,
  1746. ClientBufferBase,
  1747. SubmitBufferLength,
  1748. ProtocolReturnBuffer,
  1749. ReturnBufferLength,
  1750. ProtocolStatus
  1751. );
  1752. //
  1753. // Restore our original session
  1754. //
  1755. SetCurrentSession( OldSession );
  1756. Cleanup:
  1757. return(Status);
  1758. }
  1759. //+-------------------------------------------------------------------------
  1760. //
  1761. // Function: LsaICallPackagePassthrough
  1762. //
  1763. // Synopsis: Function to call another security package for pass-through request
  1764. //
  1765. // Effects:
  1766. //
  1767. // Arguments:
  1768. //
  1769. // Requires:
  1770. //
  1771. // Returns:
  1772. //
  1773. // Notes:
  1774. //
  1775. //
  1776. //--------------------------------------------------------------------------
  1777. extern "C"
  1778. NTSTATUS
  1779. LsaICallPackagePassthrough(
  1780. IN PUNICODE_STRING AuthenticationPackage,
  1781. IN PVOID ClientBufferBase,
  1782. IN PVOID ProtocolSubmitBuffer,
  1783. IN ULONG SubmitBufferLength,
  1784. OUT PVOID *ProtocolReturnBuffer,
  1785. OUT PULONG ReturnBufferLength,
  1786. OUT PNTSTATUS ProtocolStatus
  1787. )
  1788. {
  1789. NTSTATUS Status = STATUS_SUCCESS;
  1790. PLSAP_SECURITY_PACKAGE Package;
  1791. PSession OldSession;
  1792. Package = SpmpLookupPackageAndRequest(
  1793. AuthenticationPackage,
  1794. SP_ORDINAL_CALLPACKAGE
  1795. );
  1796. if (Package == NULL)
  1797. {
  1798. DebugLog((DEB_WARN,"LsapCallPackage failed: package %wZ not found\n",
  1799. AuthenticationPackage ));
  1800. Status = STATUS_NO_SUCH_PACKAGE;
  1801. goto Cleanup;
  1802. }
  1803. //
  1804. // Set the session to be the LSA's so calls to allocate memory
  1805. // will allocate in the correct process
  1806. //
  1807. OldSession = GetCurrentSession();
  1808. SetCurrentSession( pDefaultSession );
  1809. Status = Package->FunctionTable.CallPackagePassthrough(
  1810. NULL,
  1811. ProtocolSubmitBuffer,
  1812. ClientBufferBase,
  1813. SubmitBufferLength,
  1814. ProtocolReturnBuffer,
  1815. ReturnBufferLength,
  1816. ProtocolStatus
  1817. );
  1818. //
  1819. // Restore our original session
  1820. //
  1821. SetCurrentSession( OldSession );
  1822. Cleanup:
  1823. return(Status);
  1824. }
  1825. extern "C"
  1826. VOID
  1827. LsaIFreeReturnBuffer(
  1828. IN PVOID Buffer
  1829. )
  1830. /*++
  1831. Routine Description:
  1832. Some of the LSA authentication services allocate memory buffers to
  1833. hold returned information. This service is used to free those buffers
  1834. when no longer needed.
  1835. Arguments:
  1836. Buffer - Supplies a pointer to the return buffer to be freed.
  1837. Return Status:
  1838. STATUS_SUCCESS - Indicates the service completed successfully.
  1839. Others - returned by NtFreeVirtualMemory().
  1840. --*/
  1841. {
  1842. SIZE_T Length;
  1843. Length = 0;
  1844. DebugLog(( DEB_TRACE_HELPERS, "LsaIFreeReturnBuffer - freeing VM at %x\n", Buffer ));
  1845. if (((ULONG_PTR) Buffer & 0xfff) != 0)
  1846. {
  1847. DbgPrint("Freeing non-page address: %p\n",Buffer);
  1848. DbgBreakPoint();
  1849. }
  1850. NtFreeVirtualMemory(
  1851. NtCurrentProcess(),
  1852. &Buffer,
  1853. &Length,
  1854. MEM_RELEASE
  1855. );
  1856. }
  1857. NTSTATUS
  1858. LsaClientCallback(
  1859. PCHAR Callback,
  1860. ULONG_PTR Argument1,
  1861. ULONG_PTR Argument2,
  1862. PSecBuffer Input,
  1863. PSecBuffer Output
  1864. )
  1865. {
  1866. PSession Session ;
  1867. ULONG Type ;
  1868. Session = GetCurrentSession();
  1869. if ( !Session )
  1870. {
  1871. Session = pDefaultSession ;
  1872. }
  1873. if ( !Session->hPort &&
  1874. ((Session->fSession & SESFLAG_DEFAULT) == 0) )
  1875. {
  1876. return SEC_E_INVALID_HANDLE ;
  1877. }
  1878. if ( (ULONG_PTR) Callback < 0x00010000 )
  1879. {
  1880. Type = SPM_CALLBACK_PACKAGE ;
  1881. }
  1882. else
  1883. {
  1884. Type = SPM_CALLBACK_EXPORT ;
  1885. }
  1886. return LsapClientCallback( Session,
  1887. Type,
  1888. Callback,
  1889. (PVOID) Argument1,
  1890. (PVOID) Argument2,
  1891. Input,
  1892. Output );
  1893. }
  1894. #if 0
  1895. BOOL
  1896. LsapCaptureAuthData(
  1897. PVOID pvAuthData,
  1898. BOOLEAN DesiredAnsi,
  1899. PSEC_WINNT_AUTH_IDENTITY * AuthData
  1900. )
  1901. {
  1902. SEC_WINNT_AUTH_IDENTITY Auth ;
  1903. PSEC_WINNT_AUTH_IDENTITY pAuth ;
  1904. SECURITY_STATUS Status ;
  1905. ULONG TotalSize ;
  1906. PWSTR CurrentW ;
  1907. PSTR CurrentA ;
  1908. PVOID Current ;
  1909. PWSTR ConvertBufferW ;
  1910. PSTR ConvertBufferA ;
  1911. PVOID Convert;
  1912. ULONG Longest ;
  1913. ZeroMemory( &Auth, sizeof( Auth ) );
  1914. Status = LsapCopyFromClientBuffer(
  1915. NULL,
  1916. sizeof( SEC_WINNT_AUTH_IDENTITY ),
  1917. & Auth,
  1918. pvAuthData );
  1919. if ( !NT_SUCCESS( Status ) )
  1920. {
  1921. return FALSE ;
  1922. }
  1923. Longest = Auth.UserLength ;
  1924. Longest = max( Longest, Auth.DomainLength );
  1925. Longest = max( Longest, Auth.PasswordLength );
  1926. Longest = (Longest + 1) * sizeof(WCHAR);
  1927. //
  1928. // Always go with the extra, so we can handle DBCS
  1929. //
  1930. TotalSize = sizeof( SEC_WINNT_AUTH_IDENTITY ) +
  1931. ( Auth.UserLength + 1 +
  1932. Auth.DomainLength + 1 +
  1933. Auth.PasswordLength + 1 ) * sizeof( WCHAR );
  1934. pAuth = (PSEC_WINNT_AUTH_IDENTITY) LsapAllocateLsaHeap( TotalSize );
  1935. if ( !pAuth )
  1936. {
  1937. return FALSE ;
  1938. }
  1939. ConvertBufferW = NULL ;
  1940. ConvertBufferA = NULL ;
  1941. Convert = NULL ;
  1942. CurrentA = NULL ;
  1943. CurrentW = NULL ;
  1944. if ( Auth.Flags & SEC_WINNT_AUTH_IDENTITY_ANSI )
  1945. {
  1946. if ( !DesiredAnsi )
  1947. {
  1948. ConvertBufferA = (PSTR) LocalAlloc( LMEM_FIXED, Longest );
  1949. Convert = ConvertBufferA ;
  1950. CurrentW = (PWSTR) (pAuth + 1);
  1951. }
  1952. else
  1953. {
  1954. CurrentA = (PSTR) (pAuth + 1);
  1955. }
  1956. }
  1957. else
  1958. {
  1959. if ( DesiredAnsi )
  1960. {
  1961. ConvertBufferW = (PWSTR) LocalAlloc( LMEM_FIXED, Longest );
  1962. CurrentA = (PSTR) (pAuth + 1);
  1963. }
  1964. else
  1965. {
  1966. CurrentW = (PWSTR) pAuth + 1);
  1967. }
  1968. }
  1969. pAuth->Flags = Auth.Flags ;
  1970. CurrentW = (PWSTR) (pAuth + 1);
  1971. CurrentA = (PSTR) (pAuth + 1);
  1972. Current = CurrentW ;
  1973. if ( Auth.User )
  1974. {
  1975. pAuth->User = Current ;
  1976. Status = LsapCopyFromClientBuffer(
  1977. NULL,
  1978. (Auth.Flags & SEC_WINNT_AUTH_IDENTITY_ANSI ?
  1979. ( Auth.UserLength + 1 ) :
  1980. ( (Auth.UserLength + 1 ) * sizeof( WCHAR ) ) ),
  1981. (Convert ? Convert : Current ),
  1982. Auth.User );
  1983. if ( Convert )
  1984. {
  1985. if ( ConvertBufferA )
  1986. {
  1987. }
  1988. }
  1989. else
  1990. {
  1991. pAuth->UserLength = Auth.UserLength ;
  1992. }
  1993. Status = LsaTable->CopyFromClientBuffer(
  1994. NULL,
  1995. (Auth.UserLength + 1) * sizeof(WCHAR) ,
  1996. pAuth->User,
  1997. Auth.User );
  1998. if ( !NT_SUCCESS( Status ) )
  1999. {
  2000. goto Error_Cleanup ;
  2001. }
  2002. Current += Auth.UserLength + 1;
  2003. }
  2004. if ( Auth.Domain )
  2005. {
  2006. pAuth->Domain = Current ;
  2007. pAuth->DomainLength = Auth.DomainLength ;
  2008. Status = LsaTable->CopyFromClientBuffer(
  2009. NULL,
  2010. (Auth.DomainLength + 1) * sizeof( WCHAR ),
  2011. pAuth->Domain,
  2012. Auth.Domain );
  2013. if ( !NT_SUCCESS( Status ) )
  2014. {
  2015. goto Error_Cleanup ;
  2016. }
  2017. Current += Auth.DomainLength + 1;
  2018. }
  2019. if ( Auth.Password )
  2020. {
  2021. pAuth->Password = Current ;
  2022. pAuth->PasswordLength = Auth.PasswordLength ;
  2023. Status = LsaTable->CopyFromClientBuffer(
  2024. NULL,
  2025. (Auth.PasswordLength + 1) * sizeof( WCHAR ),
  2026. pAuth->Password,
  2027. Auth.Password );
  2028. if ( !NT_SUCCESS( Status ) )
  2029. {
  2030. goto Error_Cleanup ;
  2031. }
  2032. Current += Auth.PasswordLength + 1;
  2033. }
  2034. *AuthData = pAuth ;
  2035. return TRUE ;
  2036. Error_Cleanup:
  2037. LocalFree( pAuth );
  2038. return FALSE ;
  2039. }
  2040. #endif
  2041. //+-------------------------------------------------------------------------
  2042. //
  2043. // Function: LsapUpdateCredentials
  2044. //
  2045. // Synopsis: This function provides a mechanism for one package to notify
  2046. // another package that the credentials for a logon session
  2047. // have changed.
  2048. //
  2049. // Effects:
  2050. //
  2051. // Arguments: PrimaryCredentials - Primary information about the user.
  2052. // All fields may be NULL but the LogonId
  2053. // Credentials - Array of credentials for different packages
  2054. //
  2055. // Requires:
  2056. //
  2057. // Returns:
  2058. //
  2059. // Notes:
  2060. //
  2061. //
  2062. //--------------------------------------------------------------------------
  2063. NTSTATUS
  2064. LsapUpdateCredentials(
  2065. IN PSECPKG_PRIMARY_CRED PrimaryCredentials,
  2066. IN OPTIONAL PSECPKG_SUPPLEMENTAL_CRED_ARRAY Credentials
  2067. )
  2068. {
  2069. return(LsapUpdateCredentialsWorker(
  2070. (SECURITY_LOGON_TYPE) 0, // no logon type
  2071. NULL, // no account name
  2072. PrimaryCredentials,
  2073. Credentials ));
  2074. }
  2075. //+-------------------------------------------------------------------------
  2076. //
  2077. // Function: LsapUpdateCredentialsWorker
  2078. //
  2079. // Synopsis: Worker function for updated credentials - calls all package
  2080. // with specified credentials
  2081. //
  2082. // Effects:
  2083. //
  2084. // Arguments:
  2085. //
  2086. // Requires:
  2087. //
  2088. // Returns:
  2089. //
  2090. // Notes:
  2091. //
  2092. //
  2093. //--------------------------------------------------------------------------
  2094. NTSTATUS
  2095. LsapUpdateCredentialsWorker(
  2096. IN SECURITY_LOGON_TYPE LogonType,
  2097. IN PUNICODE_STRING AccountName,
  2098. IN PSECPKG_PRIMARY_CRED PrimaryCredentials,
  2099. IN OPTIONAL PSECPKG_SUPPLEMENTAL_CRED_ARRAY Credentials
  2100. )
  2101. {
  2102. NTSTATUS Status;
  2103. ULONG_PTR CurrentPackageId;
  2104. PLSAP_SECURITY_PACKAGE SupplementalPackage;
  2105. SupplementalPackage = SpmpIteratePackagesByRequest( NULL, SP_ORDINAL_ACCEPTCREDS );
  2106. CurrentPackageId = GetCurrentPackageId();
  2107. while (SupplementalPackage)
  2108. {
  2109. if (SupplementalPackage->dwPackageID != CurrentPackageId)
  2110. {
  2111. ULONG Index;
  2112. PSECPKG_SUPPLEMENTAL_CRED SuppCreds;
  2113. //
  2114. // For all packages, do the accept call so the
  2115. // package can associate the credentials with
  2116. // the logon session.
  2117. //
  2118. DebugLog((DEB_TRACE_WAPI, "Whacking package %ws with %x:%x = %wZ\n",
  2119. SupplementalPackage->Name.Buffer,
  2120. PrimaryCredentials->LogonId.HighPart, PrimaryCredentials->LogonId.LowPart,
  2121. AccountName));
  2122. SetCurrentPackageId( SupplementalPackage->dwPackageID );
  2123. //
  2124. // Find any supplmental credentials
  2125. //
  2126. SuppCreds = NULL;
  2127. if (Credentials != NULL)
  2128. {
  2129. for (Index = 0; Index < Credentials->CredentialCount ; Index++ ) {
  2130. if (RtlEqualUnicodeString(
  2131. &Credentials->Credentials[Index].PackageName,
  2132. &SupplementalPackage->Name,
  2133. TRUE))
  2134. {
  2135. SuppCreds = &Credentials->Credentials[Index];
  2136. break;
  2137. }
  2138. }
  2139. }
  2140. __try
  2141. {
  2142. Status = SupplementalPackage->FunctionTable.AcceptCredentials(
  2143. LogonType,
  2144. AccountName,
  2145. PrimaryCredentials,
  2146. SuppCreds
  2147. );
  2148. }
  2149. __except (SP_EXCEPTION)
  2150. {
  2151. Status = GetExceptionCode();
  2152. Status = SPException(Status, SupplementalPackage->dwPackageID);
  2153. }
  2154. // Note: if an exception occurs, we don't fail the logon, we just
  2155. // do the magic on the package that blew. If the package blows,
  2156. // the other packages may succeed, and so the user may not be able
  2157. // to use that provider.
  2158. }
  2159. SupplementalPackage = SpmpIteratePackagesByRequest(
  2160. SupplementalPackage,
  2161. SP_ORDINAL_ACCEPTCREDS
  2162. );
  2163. }
  2164. return(STATUS_SUCCESS);
  2165. }