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.

2035 lines
46 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1991 - 1992
  6. //
  7. // File: SesMgr.c
  8. //
  9. // Contents: "Session" manager implementation
  10. //
  11. // Functions: InitSessionManager -- Sets up the session manager
  12. // CreateSession -- Create a session
  13. // DeleteSession -- Delete a session
  14. // LocateSession -- Locates a session based on CallerContext
  15. // GetAndSetSession -- Sticks session in TLS
  16. // FreeSession -- Frees a session from a thread
  17. // AddCredHandle -- Adds a cred handle to session
  18. // DelCredHandle -- Deletes a cred handle from a session
  19. //
  20. // History:
  21. //
  22. //------------------------------------------------------------------------
  23. #include <lsapch.hxx>
  24. extern "C"
  25. {
  26. #include <adtp.h>
  27. }
  28. NTSTATUS
  29. LsapCleanUpHandles(
  30. PSession pSession,
  31. PVOID Ignored
  32. );
  33. NTSTATUS
  34. I_DeleteSession(PSession pSession);
  35. RTL_CRITICAL_SECTION csSessionMgr;
  36. #if DBG
  37. ULONG SessionLock;
  38. #define LockSessions(x) RtlEnterCriticalSection(&csSessionMgr); SessionLock = x
  39. #define UnlockSessions() SessionLock = 0; RtlLeaveCriticalSection(&csSessionMgr)
  40. #else
  41. #define LockSessions(x) RtlEnterCriticalSection(&csSessionMgr)
  42. #define UnlockSessions() RtlLeaveCriticalSection(&csSessionMgr)
  43. #endif
  44. #define SM_ICREATE 1
  45. #define SM_DELETE 2
  46. #define SM_ADDRUNDOWN 3
  47. #define SM_DELRUNDOWN 4
  48. #define SM_ADDHANDLE 5
  49. #define SM_DELHANDLE 6
  50. #define SM_VALIDHANDLE 7
  51. #define SM_CLONE 9
  52. #define SM_CLEANUP 10
  53. #define SM_FINDEFS 11
  54. #define SM_UPDATEEFS 12
  55. #define SM_ADDCONNECT 13
  56. PSession pDefaultSession;
  57. PSession pEfsSession ;
  58. LIST_ENTRY SessionList ;
  59. LIST_ENTRY SessionConnectList ;
  60. VOID
  61. LsapContextRundown(
  62. PSecHandle phContext,
  63. PVOID Context,
  64. ULONG RefCount
  65. );
  66. VOID
  67. LsapCredentialRundown(
  68. PSecHandle phCreds,
  69. PVOID Context,
  70. ULONG RefCount
  71. );
  72. //+-------------------------------------------------------------------------
  73. //
  74. // Function: InitSessionManager()
  75. //
  76. // Synopsis: Initializes whatever is needed to track sessions
  77. //
  78. // Effects: csSessionMgr, psSessionList;
  79. //
  80. // Arguments: void
  81. //
  82. // Requires:
  83. //
  84. // Returns: TRUE if success, FALSE otherwise.
  85. //
  86. // Notes:
  87. //
  88. //--------------------------------------------------------------------------
  89. BOOL
  90. InitSessionManager(void)
  91. {
  92. NTSTATUS scRet = STATUS_SUCCESS;
  93. PSession pSession;
  94. Session sSess;
  95. //
  96. // Fake a session during init:
  97. //
  98. SetCurrentPackageId( SPMGR_ID );
  99. SetCurrentSession( &sSess );
  100. scRet = RtlInitializeCriticalSection(&csSessionMgr);
  101. if (FAILED(scRet))
  102. {
  103. return(FALSE);
  104. }
  105. SmallHandlePackage.Initialize();
  106. LargeHandlePackage.Initialize();
  107. InitializeListHead( &SessionList );
  108. InitializeListHead( &SessionConnectList );
  109. scRet = CreateSession(
  110. &NtCurrentTeb()->ClientId,
  111. FALSE,
  112. LSA_PROCESS_NAME,
  113. 0, // no flags
  114. &pSession
  115. );
  116. if (FAILED(scRet))
  117. {
  118. return(FALSE);
  119. }
  120. pSession->fSession |= SESFLAG_DEFAULT | SESFLAG_TCB_PRIV ;
  121. pDefaultSession = pSession;
  122. SetCurrentSession( pSession );
  123. return(TRUE);
  124. }
  125. VOID
  126. LsapFindEfsSession(
  127. VOID
  128. )
  129. {
  130. PLIST_ENTRY Scan ;
  131. PSession pSession ;
  132. LockSessions( SM_FINDEFS );
  133. Scan = SessionList.Flink ;
  134. while ( Scan != &SessionList )
  135. {
  136. pSession = CONTAINING_RECORD( Scan, Session, List );
  137. if ( (pSession->dwProcessID == pDefaultSession->dwProcessID) &&
  138. ((pSession->fSession & SESFLAG_KERNEL) != 0 ) )
  139. {
  140. pEfsSession = pSession ;
  141. break;
  142. }
  143. Scan = Scan->Flink ;
  144. }
  145. UnlockSessions();
  146. if ( !pEfsSession )
  147. {
  148. DebugLog(( DEB_ERROR, "EFS Session not found\n" ));
  149. }
  150. }
  151. VOID
  152. LsapUpdateEfsSession(
  153. PSession pSession
  154. )
  155. {
  156. if ( !pEfsSession )
  157. {
  158. return ;
  159. }
  160. LockSessions( SM_UPDATEEFS );
  161. LockSession( pSession );
  162. LockSession( pEfsSession );
  163. pEfsSession->SharedData = pSession->SharedData ;
  164. pSession->SharedData->cRefs++ ;
  165. pEfsSession->fSession |= SESFLAG_EFS ;
  166. UnlockSession( pEfsSession );
  167. UnlockSession( pSession );
  168. UnlockSessions();
  169. }
  170. //+-------------------------------------------------------------------------
  171. //
  172. // Function: CreateSession()
  173. //
  174. // Synopsis: Creates a new session.
  175. //
  176. // Effects: Session list.
  177. //
  178. // Arguments: fOpenImmediate - TRUE indicates the process should be opened
  179. //
  180. // ppSession - receives a pointer to the session.
  181. //
  182. // Requires:
  183. //
  184. // Returns:
  185. //
  186. // Notes:
  187. //
  188. //--------------------------------------------------------------------------
  189. NTSTATUS
  190. CreateSession( CLIENT_ID * pClientId,
  191. BOOL fOpenImmediate,
  192. PWCHAR ClientProcessName,
  193. ULONG Flags,
  194. PSession * ppSession)
  195. {
  196. NTSTATUS scRet = STATUS_SUCCESS;
  197. PSession pSession;
  198. LPWSTR ClientName;
  199. PLIST_ENTRY Scan ;
  200. PLSAP_SESSION_CONNECT Connect ;
  201. ULONG ConnectType = 0 ;
  202. DebugLog(( DEB_TRACE, "Creating session for [%x.%x]\n",
  203. pClientId->UniqueProcess, pClientId->UniqueThread ));
  204. *ppSession = NULL;
  205. if ( *ClientProcessName )
  206. {
  207. ConnectType |= SESSION_CONNECT_TRUSTED ;
  208. ClientName = (LPWSTR) LsapAllocatePrivateHeap(
  209. (wcslen(ClientProcessName)+1) * sizeof(WCHAR));
  210. if (ClientName == NULL)
  211. {
  212. return(STATUS_INSUFFICIENT_RESOURCES);
  213. }
  214. wcscpy(ClientName,ClientProcessName);
  215. }
  216. else
  217. {
  218. ConnectType |= SESSION_CONNECT_UNTRUSTED ;
  219. ClientName = NULL;
  220. }
  221. pSession = (PSession) LsapAllocatePrivateHeap( sizeof( Session ) );
  222. if (!pSession)
  223. {
  224. *ppSession = NULL;
  225. if( ClientName != NULL )
  226. {
  227. LsapFreePrivateHeap( ClientName );
  228. }
  229. return(STATUS_INSUFFICIENT_RESOURCES);
  230. }
  231. RtlZeroMemory(pSession, sizeof(Session));
  232. //
  233. // Initialize stuff:
  234. //
  235. pSession->fSession = Flags;
  236. //
  237. // we check for this much later, after some same initializing
  238. // steps, so we can use the common cleanup
  239. //
  240. scRet = RtlInitializeCriticalSection( &pSession->SessionLock );
  241. InitializeListHead( &pSession->SectionList );
  242. InitializeListHead( &pSession->RundownList );
  243. pSession->ClientProcessName = ClientName;
  244. pSession->dwProcessID = HandleToUlong(pClientId->UniqueProcess);
  245. //
  246. // Store the handle cleanup as a rundown function
  247. //
  248. if ( NT_SUCCESS( scRet ) )
  249. {
  250. if ( !AddRundown( pSession,
  251. LsapCleanUpHandles,
  252. NULL ) )
  253. {
  254. scRet = STATUS_NO_MEMORY ;
  255. }
  256. }
  257. //
  258. // Lock the sessions now so we know that no new kernel sessions
  259. // will be created
  260. //
  261. LockSessions(SM_ICREATE);
  262. //
  263. // Add the session to the list
  264. //
  265. InsertTailList( &SessionList, &pSession->List );
  266. //
  267. // *Now* check if we're doing ok:
  268. //
  269. if ( !NT_SUCCESS( scRet ))
  270. {
  271. UnlockSessions();
  272. goto Cleanup;
  273. }
  274. //
  275. // If the caller is from kernel mode, look for an existing kernel
  276. // session to use the handle list from.
  277. //
  278. if ((Flags & SESFLAG_MAYBEKERNEL) != 0)
  279. {
  280. PSession pTrace = NULL;
  281. //
  282. // Find a kernel-mode session and use its handle list. Make sure
  283. // it's not the default LSA session, although it is ok to use the
  284. // session tagged as the EFS one. This will keep the EFS session
  285. // and the (primary) rdr session in sync.
  286. //
  287. Scan = SessionList.Flink ;
  288. while ( Scan != &SessionList )
  289. {
  290. pTrace = CONTAINING_RECORD( Scan, Session, List );
  291. if ( pTrace != pSession )
  292. {
  293. if ( ( (pTrace->fSession & SESFLAG_KERNEL) != 0 ) &&
  294. ( ( (pTrace->fSession & SESFLAG_EFS) != 0 ) ||
  295. ( pTrace->dwProcessID != pDefaultSession->dwProcessID ) ) )
  296. {
  297. break;
  298. }
  299. }
  300. pTrace = NULL ;
  301. Scan = Scan->Flink ;
  302. }
  303. //
  304. // If we found a session, use its handle list and queue
  305. //
  306. if (pTrace != NULL)
  307. {
  308. pTrace->SharedData->cRefs++;
  309. pSession->SharedData = pTrace->SharedData;
  310. DebugLog(( DEB_TRACE, "Linking session %p to %p\n",
  311. pSession, pTrace ));
  312. }
  313. //
  314. // ConnectType is not definite, it is a hint to others
  315. // watching for new sessions
  316. //
  317. ConnectType |= SESSION_CONNECT_KERNEL ;
  318. }
  319. //
  320. // If we don't have a handle list yet, create one and set it to NULL
  321. //
  322. if (pSession->SharedData == NULL)
  323. {
  324. if ( pSession->fSession & SESFLAG_MAYBEKERNEL )
  325. {
  326. pSession->SharedData = (PLSAP_SHARED_SESSION_DATA) LsapAllocatePrivateHeap(
  327. sizeof( LSAP_SHARED_SESSION_DATA ) );
  328. }
  329. else
  330. {
  331. pSession->SharedData = &pSession->DefaultData ;
  332. }
  333. if ( pSession->SharedData )
  334. {
  335. RtlZeroMemory(
  336. pSession->SharedData,
  337. sizeof( LSAP_SHARED_SESSION_DATA ) );
  338. //
  339. // Create Handle Tables:
  340. //
  341. pSession->SharedData->CredHandlePackage = &SmallHandlePackage ;
  342. pSession->SharedData->ContextHandlePackage = &LargeHandlePackage ;
  343. pSession->SharedData->CredTable = pSession->SharedData->CredHandlePackage->Create(
  344. HANDLE_PACKAGE_CALLBACK_ON_DELETE,
  345. NULL,
  346. LsapCredentialRundown );
  347. pSession->SharedData->ContextTable = pSession->SharedData->ContextHandlePackage->Create(
  348. HANDLE_PACKAGE_CALLBACK_ON_DELETE,
  349. NULL,
  350. LsapContextRundown );
  351. if ((pSession->SharedData->CredTable == NULL) || (pSession->SharedData->ContextTable == NULL))
  352. {
  353. scRet = STATUS_INSUFFICIENT_RESOURCES;
  354. }
  355. pSession->SharedData->cRefs = 1;
  356. }
  357. else
  358. {
  359. scRet = STATUS_INSUFFICIENT_RESOURCES ;
  360. }
  361. }
  362. UnlockSessions();
  363. //
  364. // Check for callbacks when a client connects. Note, this does
  365. // not need to be under the session list lock, because it is
  366. // sufficient that no client is using the session until the
  367. // callbacks are complete. Since the connection attempt is
  368. // stalled until this returns, that requirement is met.
  369. //
  370. Scan = SessionConnectList.Flink ;
  371. while ( Scan != &SessionConnectList )
  372. {
  373. Connect = CONTAINING_RECORD( Scan, LSAP_SESSION_CONNECT, List );
  374. if ( Connect->ConnectFilter & ConnectType )
  375. {
  376. Connect->Callback( pSession, Connect->Parameter );
  377. }
  378. Scan = Scan->Flink ;
  379. }
  380. *ppSession = pSession ;
  381. if (fOpenImmediate & (NT_SUCCESS(scRet)))
  382. {
  383. scRet = LsapOpenCaller(pSession);
  384. }
  385. //
  386. // If we failed somewhere, cleanup now.
  387. //
  388. Cleanup:
  389. if (!NT_SUCCESS(scRet))
  390. {
  391. I_DeleteSession(pSession);
  392. *ppSession = NULL;
  393. }
  394. return(scRet);
  395. }
  396. //+---------------------------------------------------------------------------
  397. //
  398. // Function: CloneSession
  399. //
  400. // Synopsis: Temporary copy of a session for scavenger threads
  401. //
  402. // Arguments: [pOriginalSession] --
  403. // [ppSession] --
  404. //
  405. // History: 5-18-95 RichardW Created
  406. //
  407. // Notes:
  408. //
  409. //----------------------------------------------------------------------------
  410. NTSTATUS
  411. CloneSession(
  412. PSession pOriginalSession,
  413. PSession * ppSession,
  414. ULONG Flags )
  415. {
  416. PSession pSession;
  417. NTSTATUS Status ;
  418. BOOL LockInitialized = FALSE ;
  419. pSession = (PSession) LsapAllocatePrivateHeap( sizeof( Session ) );
  420. if ( !pSession )
  421. {
  422. *ppSession = NULL ;
  423. return STATUS_NO_MEMORY ;
  424. }
  425. //
  426. // Make sure there is no one else mucking with general session stuff
  427. //
  428. LockSessions(SM_CLONE);
  429. Status = STATUS_SUCCESS ;
  430. //
  431. // Copy all the interesting bits
  432. //
  433. CopyMemory(pSession, pOriginalSession, sizeof(Session));
  434. //
  435. // Make sure it has its own critical section
  436. //
  437. Status = RtlInitializeCriticalSection( &pSession->SessionLock );
  438. if ( NT_SUCCESS( Status ) )
  439. {
  440. LockInitialized = TRUE ;
  441. }
  442. //
  443. // note that it is a clone
  444. //
  445. pSession->fSession |= ( SESFLAG_CLONE | Flags );
  446. //
  447. // Initialize our own rundown list.
  448. //
  449. InitializeListHead( &pSession->RundownList );
  450. //
  451. // Use our own rundown
  452. //
  453. if ( AddRundown( pSession, LsapCleanUpHandles, NULL ) )
  454. {
  455. pOriginalSession->SharedData->cRefs++;
  456. }
  457. else
  458. {
  459. Status = STATUS_NO_MEMORY ;
  460. }
  461. UnlockSessions();
  462. if ( !NT_SUCCESS( Status ) )
  463. {
  464. if ( LockInitialized )
  465. {
  466. RtlDeleteCriticalSection( &pSession->SessionLock );
  467. }
  468. LsapFreePrivateHeap( pSession );
  469. *ppSession = NULL ;
  470. return Status ;
  471. }
  472. //
  473. // Set the reference count of the clone to -1, so that the a single
  474. // ref/deref will kill it.
  475. //
  476. pSession->RefCount = -1;
  477. //
  478. // Clones do *NOT* get added to the session list.
  479. //
  480. *ppSession = pSession;
  481. return(STATUS_SUCCESS);
  482. }
  483. NTSTATUS
  484. CreateShadowSession(
  485. DWORD ProcessId,
  486. PSession * NewSession
  487. )
  488. {
  489. NTSTATUS Status ;
  490. CLIENT_ID ClientId;
  491. PSession Session ;
  492. ClientId.UniqueProcess = (HANDLE) LongToHandle(ProcessId) ;
  493. ClientId.UniqueThread = NULL ;
  494. Status = CreateSession(
  495. &ClientId,
  496. FALSE,
  497. L"",
  498. SESFLAG_SHADOW,
  499. &Session );
  500. *NewSession = Session ;
  501. return Status ;
  502. }
  503. VOID
  504. WINAPI
  505. LsapDeleteContextWrap(
  506. PSecHandle Handle,
  507. PVOID Context,
  508. ULONG RefCount
  509. )
  510. {
  511. PLSA_CALL_INFO CallInfo ;
  512. CallInfo = LsapGetCurrentCall();
  513. CallInfo->CallInfo.CallCount = RefCount ;
  514. WLsaDeleteContext( Handle );
  515. CallInfo->CallInfo.CallCount = 0 ;
  516. }
  517. VOID
  518. WINAPI
  519. LsapFreeCredWrap(
  520. PSecHandle Handle,
  521. PVOID Context,
  522. ULONG RefCount
  523. )
  524. {
  525. PLSA_CALL_INFO CallInfo ;
  526. CallInfo = LsapGetCurrentCall();
  527. CallInfo->CallInfo.CallCount = RefCount ;
  528. WLsaFreeCredHandle( Handle );
  529. CallInfo->CallInfo.CallCount = 0;
  530. }
  531. //+---------------------------------------------------------------------------
  532. //
  533. // Function: LsapCleanUpHandles
  534. //
  535. // Synopsis: Closes all context and credential handles for a session
  536. //
  537. // Arguments: [pSession] --
  538. // [Ignored] --
  539. //
  540. // History: 5-15-97 RichardW Created
  541. //
  542. // Notes:
  543. //
  544. //----------------------------------------------------------------------------
  545. NTSTATUS
  546. LsapCleanUpHandles(
  547. PSession pSession,
  548. PVOID Ignored
  549. )
  550. {
  551. NTSTATUS scRet = STATUS_SUCCESS;
  552. PSession pSave;
  553. ULONG HandleRefs;
  554. PLIST_ENTRY ListEntry;
  555. LSA_CALL_INFO CallInfo ;
  556. HANDLE hImp ;
  557. //
  558. // If this is the last user of the handle lists, cleanup
  559. //
  560. if ( pSession->SharedData == NULL )
  561. {
  562. return STATUS_SUCCESS ;
  563. }
  564. LockSessions(SM_CLEANUP);
  565. pSession->SharedData->cRefs--;
  566. HandleRefs = pSession->SharedData->cRefs;
  567. UnlockSessions();
  568. if (HandleRefs == 0)
  569. {
  570. LsapInitializeCallInfo( &CallInfo,
  571. FALSE );
  572. CallInfo.CallInfo.Attributes |= SECPKG_CALL_CLEANUP ;
  573. LsapSetCurrentCall( &CallInfo );
  574. pSave = GetCurrentSession();
  575. SetCurrentSession( pSession );
  576. if (pSession->SharedData->ContextTable != NULL)
  577. {
  578. pSession->SharedData->ContextHandlePackage->Delete( pSession->SharedData->ContextTable,
  579. LsapDeleteContextWrap );
  580. }
  581. if (pSession->SharedData->CredTable != NULL)
  582. {
  583. pSession->SharedData->CredHandlePackage->Delete( pSession->SharedData->CredTable,
  584. LsapFreeCredWrap );
  585. }
  586. if ( pSession->fSession & SESFLAG_KERNEL )
  587. {
  588. LsapFreePrivateHeap( pSession->SharedData );
  589. }
  590. SetCurrentSession( pSave );
  591. LsapSetCurrentCall( NULL );
  592. }
  593. pSession->SharedData = NULL;
  594. return(scRet);
  595. }
  596. //+-------------------------------------------------------------------------
  597. //
  598. // Function: I_DeleteSession()
  599. //
  600. // Synopsis: Deletes the session indicated
  601. //
  602. // Effects: Frees memory
  603. //
  604. // Arguments: pSession Session to delete
  605. //
  606. // Notes:
  607. //
  608. //--------------------------------------------------------------------------
  609. NTSTATUS
  610. I_DeleteSession(PSession pSession)
  611. {
  612. PSession pTrace;
  613. PLIST_ENTRY List ;
  614. PLSAP_SESSION_RUNDOWN Rundown ;
  615. int i;
  616. DebugLog(( DEB_TRACE, "DeleteSession( %x )\n", pSession ));
  617. DsysAssertMsg(pSession, "DeleteSession passed null pointer");
  618. pSession->fSession |= SESFLAG_CLEANUP;
  619. //
  620. // Clones aren't in the list, so don't try to unlink it
  621. //
  622. if ( ( pSession->fSession & SESFLAG_CLONE ) == 0 )
  623. {
  624. LockSessions(SM_DELETE);
  625. RemoveEntryList( &pSession->List );
  626. UnlockSessions();
  627. }
  628. //
  629. // Execute the rundown functions
  630. //
  631. LockSession( pSession );
  632. while ( !IsListEmpty( &pSession->RundownList ) )
  633. {
  634. List = RemoveHeadList( &pSession->RundownList );
  635. Rundown = CONTAINING_RECORD( List, LSAP_SESSION_RUNDOWN, List );
  636. Rundown->Rundown( pSession, Rundown->Parameter );
  637. LsapFreePrivateHeap( Rundown );
  638. }
  639. UnlockSession( pSession );
  640. RtlDeleteCriticalSection( &pSession->SessionLock );
  641. if (pSession->fSession & SESFLAG_CLONE)
  642. {
  643. //
  644. // Clones are not part of the global list, and are
  645. // around just for bookkeepping for scavenger threads
  646. //
  647. pSession->dwProcessID = 0xFFFFFFFF;
  648. LsapFreePrivateHeap( pSession );
  649. return(STATUS_SUCCESS);
  650. }
  651. //
  652. // Close our handles
  653. //
  654. if (pSession->hProcess)
  655. NtClose(pSession->hProcess);
  656. if (pSession->hPort)
  657. {
  658. NtClose(pSession->hPort);
  659. }
  660. pSession->dwProcessID = 0xFFFFFFFF;
  661. if( pSession->ClientProcessName )
  662. {
  663. LsapFreePrivateHeap( pSession->ClientProcessName );
  664. }
  665. LsapFreePrivateHeap( pSession );
  666. return(STATUS_SUCCESS);
  667. }
  668. HRESULT
  669. LsapDeleteWorkQueue(
  670. PSession pSession,
  671. PVOID Parameter
  672. )
  673. {
  674. if ( pSession->SharedData->pQueue )
  675. {
  676. DeleteSubordinateQueue( pSession->SharedData->pQueue, 0 );
  677. pSession->SharedData->pQueue = NULL ;
  678. }
  679. return STATUS_SUCCESS ;
  680. }
  681. //+---------------------------------------------------------------------------
  682. //
  683. // Function: SpmpReferenceSession
  684. //
  685. // Synopsis: Ups the ref count on a session
  686. //
  687. // Arguments: [pSession] --
  688. //
  689. // History: 5-18-95 RichardW Created
  690. //
  691. // Notes:
  692. //
  693. //----------------------------------------------------------------------------
  694. VOID
  695. SpmpReferenceSession(
  696. PSession pSession)
  697. {
  698. InterlockedIncrement(&pSession->RefCount);
  699. }
  700. //+---------------------------------------------------------------------------
  701. //
  702. // Function: SpmpDereferenceSession
  703. //
  704. // Synopsis: Derefs a session. If the session goes negative, it gets
  705. // deleted.
  706. //
  707. // Arguments: [pSession] --
  708. //
  709. // History: 5-18-95 RichardW Created
  710. //
  711. // Notes:
  712. //
  713. //----------------------------------------------------------------------------
  714. VOID
  715. SpmpDereferenceSession(
  716. PSession pSession)
  717. {
  718. LONG RefCount = InterlockedDecrement(&pSession->RefCount);
  719. if( RefCount < 0 )
  720. {
  721. if ( pSession == pDefaultSession )
  722. {
  723. pSession->RefCount = 1 ;
  724. }
  725. else
  726. {
  727. DsysAssert( (pSession->RefCount == -1) && (RefCount == -1) );
  728. I_DeleteSession(pSession);
  729. }
  730. }
  731. }
  732. VOID
  733. LsapSessionDisconnect(
  734. PSession pSession
  735. )
  736. {
  737. if ( pSession->SharedData->cRefs == 1 )
  738. {
  739. LsapDeleteWorkQueue( pSession, NULL );
  740. }
  741. }
  742. //+-------------------------------------------------------------------------
  743. //
  744. // Function: FreeSession
  745. //
  746. // Synopsis: Frees a session
  747. //
  748. // Effects:
  749. //
  750. // Arguments:
  751. //
  752. // Requires:
  753. //
  754. // Returns:
  755. //
  756. // Notes:
  757. //
  758. //--------------------------------------------------------------------------
  759. void
  760. FreeSession(PSession pSession)
  761. {
  762. if (pSession == NULL)
  763. {
  764. pSession = GetCurrentSession();
  765. }
  766. if (!pSession)
  767. {
  768. DebugLog((DEB_ERROR, "FreeSession: No Session?\n"));
  769. return;
  770. }
  771. TlsSetValue(dwSession, pDefaultSession);
  772. }
  773. //
  774. // Rundown Semantics:
  775. //
  776. // Rundowns allow other functions to be called when a session is closed. This
  777. // is useful if you need to keep something around as long as a client is
  778. // connected, but need to clean up afterwards.
  779. //
  780. // Rules: You cannot call back into or reference the client process. This is
  781. // because the process has already terminated.
  782. //
  783. //+---------------------------------------------------------------------------
  784. //
  785. // Function: AddRundown
  786. //
  787. // Synopsis: Adds a function to be called when the session is terminated
  788. //
  789. // Arguments: [pSession] --
  790. // [RundownFn] --
  791. // [pvParameter] --
  792. //
  793. // History: 5-18-95 RichardW Created
  794. //
  795. // Notes:
  796. //
  797. //----------------------------------------------------------------------------
  798. BOOL
  799. AddRundown(
  800. PSession pSession,
  801. PLSAP_SESSION_RUNDOWN_FN RundownFn,
  802. PVOID pvParameter)
  803. {
  804. PLSAP_SESSION_RUNDOWN Rundown ;
  805. Rundown = (PLSAP_SESSION_RUNDOWN) LsapAllocatePrivateHeap(
  806. sizeof( LSAP_SESSION_RUNDOWN ) );
  807. if ( Rundown )
  808. {
  809. Rundown->Rundown = RundownFn ;
  810. Rundown->Parameter = pvParameter ;
  811. LockSession( pSession );
  812. InsertTailList( &pSession->RundownList, &Rundown->List );
  813. UnlockSession( pSession );
  814. return TRUE ;
  815. }
  816. return FALSE ;
  817. }
  818. //+---------------------------------------------------------------------------
  819. //
  820. // Function: DelRundown
  821. //
  822. // Synopsis: Removes a rundown function from a session
  823. //
  824. // Arguments: [pSession] --
  825. // [RundownFn] --
  826. //
  827. // History: 5-18-95 RichardW Created
  828. //
  829. // Notes:
  830. //
  831. //----------------------------------------------------------------------------
  832. BOOL
  833. DelRundown(
  834. PSession pSession,
  835. PLSAP_SESSION_RUNDOWN_FN RundownFn
  836. )
  837. {
  838. PLIST_ENTRY Scan;
  839. PLSAP_SESSION_RUNDOWN Rundown ;
  840. LockSession( pSession );
  841. Scan = pSession->RundownList.Flink ;
  842. Rundown = NULL ;
  843. while ( Scan != &pSession->RundownList )
  844. {
  845. Rundown = (PLSAP_SESSION_RUNDOWN) Scan ;
  846. if ( Rundown->Rundown == RundownFn )
  847. {
  848. RemoveEntryList( &Rundown->List );
  849. break;
  850. }
  851. Rundown = NULL ;
  852. Scan = Scan->Flink ;
  853. }
  854. UnlockSession( pSession );
  855. if ( Rundown )
  856. {
  857. LsapFreePrivateHeap( Rundown );
  858. return TRUE ;
  859. }
  860. return FALSE ;
  861. }
  862. BOOL
  863. AddConnectionHook(
  864. PLSAP_SESSION_CONNECT_FN ConnectFn,
  865. PVOID Parameter,
  866. ULONG Filter
  867. )
  868. {
  869. PLSAP_SESSION_CONNECT Connect ;
  870. Connect = (PLSAP_SESSION_CONNECT) LsapAllocatePrivateHeap( sizeof( LSAP_SESSION_CONNECT ) );
  871. if ( Connect )
  872. {
  873. Connect->Callback = ConnectFn ;
  874. Connect->ConnectFilter = Filter ;
  875. Connect->Parameter = Parameter ;
  876. LockSessions( SM_ADDCONNECT );
  877. InsertTailList( &SessionConnectList, &Connect->List );
  878. UnlockSessions();
  879. }
  880. return (Connect != NULL) ;
  881. }
  882. VOID
  883. LsapCredentialRundown(
  884. PSecHandle phCreds,
  885. PVOID Context,
  886. ULONG RefCount
  887. )
  888. {
  889. PSession pSession = (PSession) Context ;
  890. NTSTATUS scRet;
  891. PLSAP_SECURITY_PACKAGE pPackage;
  892. PSession Previous ;
  893. Previous = GetCurrentSession();
  894. if ( ( ( pSession->fSession & SESFLAG_KERNEL ) != 0 ) &&
  895. ( ( Previous->fSession & SESFLAG_KERNEL ) != 0 ) )
  896. {
  897. NOTHING ;
  898. }
  899. else
  900. {
  901. SetCurrentSession( pSession );
  902. }
  903. DebugLog((DEB_TRACE, "[%x] CredentialRundown (%p:%p) RefCount=%lu\n",
  904. pSession->dwProcessID, phCreds->dwUpper, phCreds->dwLower, RefCount));
  905. pPackage = SpmpValidRequest(phCreds->dwLower,
  906. SP_ORDINAL_FREECREDHANDLE );
  907. if (pPackage)
  908. {
  909. PLSA_CALL_INFO CallInfo;
  910. ULONG OldRefCount;
  911. SetCurrentPackageId(phCreds->dwLower);
  912. StartCallToPackage( pPackage );
  913. ASSERT( RefCount );
  914. CallInfo = LsapGetCurrentCall();
  915. OldRefCount = CallInfo->CallInfo.CallCount;
  916. CallInfo->CallInfo.CallCount = RefCount;
  917. __try
  918. {
  919. scRet = pPackage->FunctionTable.FreeCredentialsHandle(
  920. phCreds->dwUpper);
  921. }
  922. __except (SP_EXCEPTION)
  923. {
  924. scRet = GetExceptionCode();
  925. scRet = SPException(scRet, phCreds->dwLower);
  926. }
  927. CallInfo->CallInfo.CallCount = OldRefCount;
  928. EndCallToPackage( pPackage );
  929. LsapDelPackageHandle( pPackage, FALSE );
  930. }
  931. SetCurrentSession( Previous );
  932. }
  933. VOID
  934. LsapContextRundown(
  935. PSecHandle phContext,
  936. PVOID Context,
  937. ULONG RefCount
  938. )
  939. {
  940. PSession Session = (PSession) Context;
  941. PSession Previous ;
  942. PLSAP_SECURITY_PACKAGE pspPackage;
  943. PLSA_CALL_INFO CallInfo;
  944. ULONG OldRefCount;
  945. NTSTATUS scRet ;
  946. Previous = GetCurrentSession();
  947. if ( ( ( Session->fSession & SESFLAG_KERNEL ) != 0 ) &&
  948. ( ( Previous->fSession & SESFLAG_KERNEL ) != 0 ) )
  949. {
  950. NOTHING ;
  951. }
  952. else
  953. {
  954. SetCurrentSession( Session );
  955. }
  956. pspPackage = SpmpValidRequest( phContext->dwLower,
  957. SP_ORDINAL_DELETECTXT);
  958. if (! pspPackage )
  959. {
  960. DebugLog((DEB_ERROR,"[%x] Invalid request for DeleteContext, package: %d\n",
  961. Session->dwProcessID, phContext->dwLower));
  962. return ;
  963. }
  964. DebugLog(( DEB_TRACE, "[%x] ContextRundown(%p:%p)\n",
  965. Session->dwProcessID, phContext->dwUpper,
  966. phContext->dwLower ));
  967. SetCurrentPackageId(phContext->dwLower);
  968. StartCallToPackage( pspPackage );
  969. //
  970. // RefCount should ALWAYS be 1 currently, as, the context handle code
  971. // assumes context handle issue count never exceeds 1.
  972. //
  973. ASSERT( RefCount == 1 );
  974. CallInfo = LsapGetCurrentCall();
  975. OldRefCount = CallInfo->CallInfo.CallCount;
  976. CallInfo->CallInfo.CallCount = RefCount;
  977. __try
  978. {
  979. scRet = pspPackage->FunctionTable.DeleteContext( phContext->dwUpper );
  980. }
  981. __except (SP_EXCEPTION)
  982. {
  983. scRet = GetExceptionCode();
  984. scRet = SPException( scRet, pspPackage->dwPackageID);
  985. }
  986. CallInfo->CallInfo.CallCount = OldRefCount;
  987. EndCallToPackage( pspPackage );
  988. #if DBG
  989. if ( !NT_SUCCESS( scRet ) )
  990. {
  991. DebugLog((DEB_ERROR, "[%x] package %ws failed DeleteContext with %x\n",
  992. Session->dwProcessID,
  993. pspPackage->Name.Buffer,
  994. scRet ));
  995. }
  996. #endif
  997. DebugLog(( DEB_TRACE_WAPI, "[%x] return code %x\n", Session->dwProcessID,
  998. scRet ));
  999. SetCurrentPackageId( SPMGR_ID );
  1000. SetCurrentSession( Previous );
  1001. LsapDelPackageHandle( pspPackage, TRUE );
  1002. }
  1003. //+-------------------------------------------------------------------------
  1004. //
  1005. // Function: AddCredHandle
  1006. //
  1007. // Synopsis: Adds an obtained cred handle to the list for this session
  1008. //
  1009. // Effects:
  1010. //
  1011. // Arguments:
  1012. //
  1013. // Requires:
  1014. //
  1015. // Returns:
  1016. //
  1017. // Notes:
  1018. //
  1019. //--------------------------------------------------------------------------
  1020. BOOLEAN
  1021. AddCredHandle( PSession pSession,
  1022. PCredHandle phCred,
  1023. ULONG Flags)
  1024. {
  1025. if (pSession->fSession & SESFLAG_CLONE)
  1026. {
  1027. DebugLog((DEB_ERROR, "Attempt to add a credhandle to a clone session\n"));
  1028. return FALSE;
  1029. }
  1030. if ( pSession->fSession & SESFLAG_KERNEL )
  1031. {
  1032. pSession = pEfsSession ;
  1033. }
  1034. DebugLog(( DEB_TRACE_HANDLES, "Adding Cred %p : %p to %p\n",
  1035. phCred->dwUpper, phCred->dwLower, pSession ));
  1036. if(pSession->SharedData->CredHandlePackage->AddHandle(
  1037. pSession->SharedData->CredTable,
  1038. phCred,
  1039. pSession,
  1040. Flags))
  1041. {
  1042. LsapAddPackageHandle( phCred->dwLower, FALSE );
  1043. return TRUE;
  1044. }
  1045. return FALSE;
  1046. }
  1047. //+---------------------------------------------------------------------------
  1048. //
  1049. // Function: AddContextHandle
  1050. //
  1051. // Synopsis: Adds a context handle to this session
  1052. //
  1053. // Arguments: [phContext] --
  1054. //
  1055. // History: 5-18-95 RichardW Created
  1056. //
  1057. // Notes:
  1058. //
  1059. //----------------------------------------------------------------------------
  1060. BOOLEAN
  1061. AddContextHandle( PSession pSession,
  1062. PCtxtHandle phContext,
  1063. ULONG Flags)
  1064. {
  1065. if (pSession->fSession & SESFLAG_CLONE)
  1066. {
  1067. DebugLog((DEB_ERROR, "Attempt to add a ctxthandle to a clone session\n"));
  1068. return FALSE;
  1069. }
  1070. if ( pSession->fSession & SESFLAG_KERNEL )
  1071. {
  1072. pSession = pEfsSession ;
  1073. }
  1074. DebugLog(( DEB_TRACE_HANDLES, "Adding Context %p : %p to %p\n",
  1075. phContext->dwUpper, phContext->dwLower, pSession ));
  1076. //
  1077. // Find out where this 0:0 handle is coming from:
  1078. //
  1079. DsysAssertMsg( (phContext->dwLower | phContext->dwUpper), "Null context handle added\n");
  1080. if(pSession->SharedData->ContextHandlePackage->AddHandle(
  1081. pSession->SharedData->ContextTable,
  1082. phContext,
  1083. pSession,
  1084. Flags
  1085. ))
  1086. {
  1087. LsapAddPackageHandle( phContext->dwLower, TRUE );
  1088. return TRUE;
  1089. }
  1090. return FALSE;
  1091. }
  1092. //+---------------------------------------------------------------------------
  1093. //
  1094. // Function: ValidateContextHandle
  1095. //
  1096. // Synopsis: Validate the context handle against the session list
  1097. //
  1098. // Arguments: [pSession] --
  1099. // [phContext] --
  1100. //
  1101. // History: 5-18-95 RichardW Created
  1102. //
  1103. // Notes:
  1104. //
  1105. //----------------------------------------------------------------------------
  1106. NTSTATUS
  1107. ValidateContextHandle(
  1108. PSession pSession,
  1109. PCtxtHandle phContext,
  1110. PVOID * pKey
  1111. )
  1112. {
  1113. *pKey = pSession->SharedData->ContextHandlePackage->RefHandle(
  1114. pSession->SharedData->ContextTable,
  1115. phContext );
  1116. DebugLog(( DEB_TRACE_HANDLES, "Validate context (%p : %p) for %p returned %p\n",
  1117. phContext->dwUpper, phContext->dwLower,
  1118. pSession, *pKey ));
  1119. if ( *pKey )
  1120. {
  1121. return SEC_E_OK ;
  1122. }
  1123. else
  1124. {
  1125. return SEC_E_INVALID_HANDLE ;
  1126. }
  1127. }
  1128. VOID
  1129. DerefContextHandle(
  1130. PSession pSession,
  1131. PCtxtHandle phContext,
  1132. PVOID Key OPTIONAL
  1133. )
  1134. {
  1135. if ( Key )
  1136. {
  1137. #if DBG
  1138. PSEC_HANDLE_ENTRY Entry = (PSEC_HANDLE_ENTRY) Key ;
  1139. DebugLog(( DEB_TRACE_HANDLES, "Deref context handle by key ( %p : %p ) for %p \n",
  1140. Entry->Handle.dwUpper, Entry->Handle.dwLower,
  1141. pSession ));
  1142. #endif
  1143. pSession->SharedData->ContextHandlePackage->DerefHandleKey(
  1144. pSession->SharedData->ContextTable,
  1145. Key );
  1146. }
  1147. else
  1148. {
  1149. pSession->SharedData->ContextHandlePackage->DeleteHandle(
  1150. pSession->SharedData->ContextTable,
  1151. phContext,
  1152. 0 );
  1153. DebugLog(( DEB_TRACE_HANDLES, "Deref context handle by handle (%p : %p) for %p\n",
  1154. phContext->dwUpper, phContext->dwLower,
  1155. pSession ));
  1156. }
  1157. }
  1158. NTSTATUS
  1159. ValidateAndDerefContextHandle(
  1160. PSession pSession,
  1161. PCtxtHandle phContext
  1162. )
  1163. {
  1164. DebugLog(( DEB_TRACE_HANDLES, "ValidateAndDeref Context (%p : %p)\n",
  1165. phContext->dwUpper, phContext->dwLower ));
  1166. if ( pSession->SharedData->ContextHandlePackage->ValidateHandle(
  1167. pSession->SharedData->ContextTable,
  1168. phContext,
  1169. TRUE ) )
  1170. {
  1171. return SEC_E_OK ;
  1172. }
  1173. return SEC_E_INVALID_HANDLE ;
  1174. }
  1175. //+---------------------------------------------------------------------------
  1176. //
  1177. // Function: ValidateCredHandle
  1178. //
  1179. // Synopsis: Validate the context handle against the session list
  1180. //
  1181. // Arguments: [pSession] --
  1182. // [phCred] --
  1183. //
  1184. // History: 5-18-95 RichardW Created
  1185. //
  1186. // Notes:
  1187. //
  1188. //----------------------------------------------------------------------------
  1189. NTSTATUS
  1190. ValidateCredHandle(
  1191. PSession pSession,
  1192. PCtxtHandle phCred,
  1193. PVOID * pKey
  1194. )
  1195. {
  1196. *pKey = pSession->SharedData->CredHandlePackage->RefHandle(
  1197. pSession->SharedData->CredTable,
  1198. phCred );
  1199. DebugLog(( DEB_TRACE_HANDLES, "Validate cred (%p : %p) for %p returned %p\n",
  1200. phCred->dwUpper, phCred->dwLower,
  1201. pSession, *pKey ));
  1202. if ( *pKey )
  1203. {
  1204. return SEC_E_OK ;
  1205. }
  1206. else
  1207. {
  1208. return SEC_E_INVALID_HANDLE ;
  1209. }
  1210. }
  1211. VOID
  1212. DerefCredHandle(
  1213. PSession pSession,
  1214. PCtxtHandle phCred,
  1215. PVOID Key OPTIONAL
  1216. )
  1217. {
  1218. if ( Key )
  1219. {
  1220. #if DBG
  1221. PSEC_HANDLE_ENTRY Entry = (PSEC_HANDLE_ENTRY) Key ;
  1222. DebugLog(( DEB_TRACE_HANDLES, "Deref cred ( %p : %p ) for %p \n",
  1223. Entry->Handle.dwUpper, Entry->Handle.dwLower,
  1224. pSession ));
  1225. #endif
  1226. pSession->SharedData->CredHandlePackage->DerefHandleKey(
  1227. pSession->SharedData->CredTable,
  1228. Key );
  1229. }
  1230. else
  1231. {
  1232. pSession->SharedData->CredHandlePackage->DeleteHandle(
  1233. pSession->SharedData->CredTable,
  1234. phCred,
  1235. 0 );
  1236. DebugLog(( DEB_TRACE_HANDLES, "Deref cred (%p : %p) for %p\n",
  1237. phCred->dwUpper, phCred->dwLower,
  1238. pSession ));
  1239. }
  1240. }
  1241. NTSTATUS
  1242. ValidateAndDerefCredHandle(
  1243. PSession pSession,
  1244. PCtxtHandle phCred
  1245. )
  1246. {
  1247. DebugLog(( DEB_TRACE_HANDLES, "ValidateAndDeref Cred (%p : %p)\n",
  1248. phCred->dwUpper, phCred->dwLower ));
  1249. if ( pSession->SharedData->CredHandlePackage->ValidateHandle(
  1250. pSession->SharedData->CredTable,
  1251. phCred,
  1252. TRUE ) )
  1253. {
  1254. return SEC_E_OK ;
  1255. }
  1256. return SEC_E_INVALID_HANDLE ;
  1257. }
  1258. BOOL
  1259. LsapMoveContextHandle(
  1260. PSecHandle Handle,
  1261. PSession OriginatingSession,
  1262. PSession DestinationSession
  1263. )
  1264. {
  1265. BOOL Ret ;
  1266. if ( OriginatingSession->SharedData->ContextHandlePackage->DeleteHandle(
  1267. OriginatingSession->SharedData->ContextTable,
  1268. Handle,
  1269. DELHANDLE_FORCE | DELHANDLE_NO_CALLBACK ) )
  1270. {
  1271. Ret = DestinationSession->SharedData->ContextHandlePackage->AddHandle(
  1272. DestinationSession->SharedData->ContextTable,
  1273. Handle,
  1274. DestinationSession,
  1275. 0 );
  1276. } else {
  1277. Ret = FALSE ;
  1278. }
  1279. return Ret ;
  1280. }
  1281. BOOL
  1282. LsapMoveCredHandle(
  1283. PSecHandle Handle,
  1284. PSession OriginatingSession,
  1285. PSession DestinationSession
  1286. )
  1287. {
  1288. BOOL Ret ;
  1289. if ( OriginatingSession->SharedData->CredHandlePackage->DeleteHandle(
  1290. OriginatingSession->SharedData->CredTable,
  1291. Handle,
  1292. DELHANDLE_FORCE | DELHANDLE_NO_CALLBACK ) )
  1293. {
  1294. Ret = DestinationSession->SharedData->CredHandlePackage->AddHandle(
  1295. DestinationSession->SharedData->CredTable,
  1296. Handle,
  1297. DestinationSession,
  1298. 0 );
  1299. } else {
  1300. Ret = FALSE ;
  1301. }
  1302. return Ret ;
  1303. }
  1304. NTSTATUS
  1305. LsapValidLogonProcess(
  1306. IN PVOID Request,
  1307. IN ULONG RequestSize,
  1308. IN PCLIENT_ID ClientId,
  1309. OUT PLUID LogonId,
  1310. OUT PULONG Flags
  1311. )
  1312. /*++
  1313. Routine Description:
  1314. This function checks to see if a calling process qualifies as a logon
  1315. process. If so, a logon process context is created for the caller and
  1316. returned.
  1317. A logon process must hold the SeTcbPrivilege privilege. Since there
  1318. is no way to impersonate a connection requestor (that would be way
  1319. too easy), we have to open the client thread and then open that thread's
  1320. token.
  1321. Arguments:
  1322. ClientId - Pointer to the client Id of the sender of the logon
  1323. message. This is used to locate and open the calling thread or
  1324. process.
  1325. Return Value:
  1326. STATUS_SUCCESS - Indicates the caller is a legitimate logon process
  1327. and a logon process context block is being returned.
  1328. any other value - Indicates the caller is NOT a legitimate logon
  1329. process and a logon process context block is NOT being returned.
  1330. The value returned indicates the reason why the client is not
  1331. acceptable.
  1332. --*/
  1333. {
  1334. NTSTATUS Status, TempStatus;
  1335. BOOLEAN PrivilegeHeld;
  1336. HANDLE ClientThread, ClientProcess, ClientToken;
  1337. PRIVILEGE_SET Privilege;
  1338. OBJECT_ATTRIBUTES NullAttributes;
  1339. UNICODE_STRING Unicode;
  1340. STRING Ansi;
  1341. BOOLEAN Untrusted = FALSE;
  1342. TOKEN_STATISTICS TokenStats;
  1343. PLSAP_AU_REGISTER_CONNECT_INFO_EX ConnectionRequest = (PLSAP_AU_REGISTER_CONNECT_INFO_EX) Request;
  1344. ULONG TokenStatsSize = sizeof(TokenStats);
  1345. LSAP_AU_REGISTER_CONNECT_INFO NullConnectInfo;
  1346. *Flags = 0;
  1347. RtlZeroMemory(
  1348. &NullConnectInfo,
  1349. sizeof(NullConnectInfo)
  1350. );
  1351. //
  1352. // If the connect message is all zeros, setup an untrusted connection.
  1353. //
  1354. if (RtlEqualMemory(
  1355. &NullConnectInfo,
  1356. ConnectionRequest,
  1357. sizeof(NullConnectInfo))) {
  1358. Untrusted = TRUE;
  1359. *Flags |= SESFLAG_UNTRUSTED;
  1360. }
  1361. InitializeObjectAttributes( &NullAttributes, NULL, 0, NULL, NULL );
  1362. //
  1363. // Open the client thread and that thread's token
  1364. //
  1365. Status = NtOpenThread(
  1366. &ClientThread,
  1367. THREAD_QUERY_INFORMATION,
  1368. &NullAttributes,
  1369. ClientId
  1370. );
  1371. if ( !NT_SUCCESS(Status) ) {
  1372. return Status;
  1373. }
  1374. Status = NtOpenThreadToken(
  1375. ClientThread,
  1376. TOKEN_QUERY,
  1377. TRUE,
  1378. &ClientToken
  1379. );
  1380. TempStatus = NtClose( ClientThread );
  1381. DsysAssert( NT_SUCCESS(TempStatus) );
  1382. //
  1383. // Make sure we succeeded in opening the token
  1384. //
  1385. if ( !NT_SUCCESS(Status) ) {
  1386. if ( Status != STATUS_NO_TOKEN ) {
  1387. return Status;
  1388. } else {
  1389. //
  1390. // Open the client process. This is needed to:
  1391. //
  1392. // 1) Access the client's virtual memory (to copy arguments),
  1393. // 2) Duplicate token handles into the process,
  1394. // 3) Open the process's token to see if it qualifies as
  1395. // a logon process.
  1396. //
  1397. Status = NtOpenProcess(
  1398. &ClientProcess,
  1399. PROCESS_QUERY_INFORMATION | // To open primary token
  1400. PROCESS_VM_OPERATION | // To allocate memory
  1401. PROCESS_VM_READ | // To read memory
  1402. PROCESS_VM_WRITE | // To write memory
  1403. PROCESS_DUP_HANDLE, // To duplicate a handle into
  1404. &NullAttributes,
  1405. ClientId
  1406. );
  1407. if ( !NT_SUCCESS(Status) ) {
  1408. return Status;
  1409. }
  1410. //
  1411. // The thread isn't impersonating...open the process's token.
  1412. //
  1413. Status = NtOpenProcessToken(
  1414. ClientProcess,
  1415. TOKEN_QUERY,
  1416. &ClientToken
  1417. );
  1418. TempStatus = NtClose( ClientProcess );
  1419. DsysAssert( NT_SUCCESS(TempStatus) );
  1420. //
  1421. // Make sure we succeeded in opening the token
  1422. //
  1423. if ( !NT_SUCCESS(Status) ) {
  1424. return Status;
  1425. }
  1426. }
  1427. } else {
  1428. *Flags |= SESFLAG_IMPERSONATE;
  1429. }
  1430. //
  1431. // If the caller has the kernel flag set in the LPC message, this is
  1432. // probably a kernel session, but we can't be sure until the first
  1433. // request is made and the LPC_KERNELMODE_MESSAGE flag is set. The
  1434. // handlers will check that, but until then, set the maybe-flag.
  1435. //
  1436. if (!Untrusted &&
  1437. RequestSize == sizeof( LSAP_AU_REGISTER_CONNECT_INFO_EX) &&
  1438. ((ConnectionRequest->ClientMode & LSAP_AU_KERNEL_CLIENT) != 0) )
  1439. {
  1440. *Flags |= SESFLAG_MAYBEKERNEL;
  1441. }
  1442. //
  1443. // OK, we have a token open
  1444. //
  1445. //
  1446. // Get the logon id.
  1447. //
  1448. Status = NtQueryInformationToken(
  1449. ClientToken,
  1450. TokenStatistics,
  1451. (PVOID) &TokenStats,
  1452. TokenStatsSize,
  1453. &TokenStatsSize
  1454. );
  1455. if (!NT_SUCCESS(Status)) {
  1456. TempStatus = NtClose( ClientToken );
  1457. DsysAssert(NT_SUCCESS(TempStatus));
  1458. return(Status);
  1459. }
  1460. *LogonId = TokenStats.AuthenticationId;
  1461. Status = STATUS_SUCCESS ;
  1462. if (((*Flags) & SESFLAG_MAYBEKERNEL) == 0) {
  1463. //
  1464. // Check for the privilege to execute this service.
  1465. //
  1466. Privilege.PrivilegeCount = 1;
  1467. Privilege.Control = PRIVILEGE_SET_ALL_NECESSARY;
  1468. Privilege.Privilege[0].Luid = LsapTcbPrivilege;
  1469. Privilege.Privilege[0].Attributes = 0;
  1470. Status = NtPrivilegeCheck(
  1471. ClientToken,
  1472. &Privilege,
  1473. &PrivilegeHeld
  1474. );
  1475. DsysAssert( NT_SUCCESS(Status) );
  1476. //
  1477. // For untrusted clients who didn't really need TCB anyway don't
  1478. // bother with an audit. If they do have the privilege, by all
  1479. // means audit it.
  1480. //
  1481. if (!Untrusted || PrivilegeHeld) {
  1482. //
  1483. // Generate any necessary audits
  1484. //
  1485. TempStatus = NtPrivilegedServiceAuditAlarm (
  1486. &LsapLsaAuName,
  1487. &LsapRegisterLogonServiceName,
  1488. ClientToken,
  1489. &Privilege,
  1490. PrivilegeHeld
  1491. );
  1492. // DsysAssert( NT_SUCCESS(TempStatus) );
  1493. if ( !PrivilegeHeld ) {
  1494. TempStatus = NtClose( ClientToken );
  1495. DsysAssert( NT_SUCCESS(TempStatus) );
  1496. return STATUS_PRIVILEGE_NOT_HELD;
  1497. }
  1498. }
  1499. if (PrivilegeHeld)
  1500. {
  1501. *Flags |= SESFLAG_TCB_PRIV;
  1502. }
  1503. }
  1504. TempStatus = NtClose( ClientToken );
  1505. DsysAssert( NT_SUCCESS(TempStatus) );
  1506. if (!Untrusted && ((*Flags & SESFLAG_KERNEL) == 0))
  1507. {
  1508. LsapAdtAuditLogonProcessRegistration( ConnectionRequest );
  1509. }
  1510. return(STATUS_SUCCESS);
  1511. }
  1512. //+---------------------------------------------------------------------------
  1513. //
  1514. // Function: LsapSetSessionOptions
  1515. //
  1516. // Synopsis: Allows clients to adjust session options
  1517. //
  1518. // Arguments: [Request] --
  1519. // [Response] --
  1520. //
  1521. // History: 8-05-96 RichardW Created
  1522. //
  1523. // Notes:
  1524. //
  1525. //----------------------------------------------------------------------------
  1526. NTSTATUS
  1527. LsapSetSessionOptions(
  1528. ULONG Request,
  1529. ULONG_PTR Argument,
  1530. PULONG_PTR Response
  1531. )
  1532. {
  1533. PSession pSession;
  1534. PLSAP_TASK_QUEUE pQueue;
  1535. NTSTATUS Status ;
  1536. pSession = GetCurrentSession();
  1537. DebugLog(( DEB_TRACE, "[%d] SetSession( %d )\n",
  1538. pSession->dwProcessID, Request ));
  1539. Status = STATUS_SUCCESS ;
  1540. LockSession( pSession );
  1541. switch ( Request )
  1542. {
  1543. case SETSESSION_GET_STATUS:
  1544. *Response = 0;
  1545. break;
  1546. case SETSESSION_ADD_WORKQUEUE:
  1547. if ( pSession->SharedData->pQueue == NULL )
  1548. {
  1549. if ( CreateSubordinateQueue( pSession, &GlobalQueue ) )
  1550. {
  1551. //
  1552. // If they're going to be that busy, convert the cred list
  1553. // to be a large table
  1554. //
  1555. AddRundown( pSession, LsapDeleteWorkQueue, NULL );
  1556. pSession->SharedData->CredTable = LhtConvertSmallToLarge(
  1557. pSession->SharedData->CredTable );
  1558. pSession->SharedData->CredHandlePackage = &LargeHandlePackage ;
  1559. }
  1560. else
  1561. {
  1562. Status = STATUS_UNSUCCESSFUL ;
  1563. }
  1564. }
  1565. break;
  1566. case SETSESSION_REMOVE_WORKQUEUE:
  1567. break;
  1568. case SETSESSION_GET_DISPATCH:
  1569. if ( pSession->dwProcessID == GetCurrentProcessId() )
  1570. {
  1571. Status = InitializeDirectDispatcher();
  1572. if ( NT_SUCCESS( Status ) )
  1573. {
  1574. DllCallbackHandler = (PLSA_DISPATCH_FN) Argument ;
  1575. *Response = (ULONG_PTR) DispatchAPIDirect;
  1576. }
  1577. }
  1578. else
  1579. {
  1580. Status = STATUS_ACCESS_DENIED ;
  1581. }
  1582. break;
  1583. }
  1584. UnlockSession( pSession );
  1585. return( Status );
  1586. }