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

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