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.

1729 lines
42 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // Global Definitions //
  4. // //
  5. //////////////////////////////////////////////////////////////////////////////
  6. #define DevPrint
  7. //#define DevPrint DbgPrint
  8. #define Error(N,S) { DbgPrint(#N); DbgPrint(" Error %08lx\n", S); }
  9. #define Delay(SECONDS) { \
  10. LARGE_INTEGER Time; \
  11. Time.QuadPart = -10 * 1000 * 1000, ((LONGLONG)SECONDS); \
  12. NtDelayExecution(TRUE,(PLARGE_INTEGER)&Time); \
  13. }
  14. //////////////////////////////////////////////////////////////////////////////
  15. // //
  16. // Global Variables //
  17. // //
  18. //////////////////////////////////////////////////////////////////////////////
  19. NTSTATUS Status;
  20. OBJECT_ATTRIBUTES ObjectAttributes;
  21. STRING EventName;
  22. UNICODE_STRING UnicodeEventName;
  23. HANDLE EventHandle;
  24. STRING PortName;
  25. UNICODE_STRING UnicodePortName;
  26. STRING RelativePortName;
  27. UNICODE_STRING UnicodeRelativePortName;
  28. HANDLE EarPort;
  29. HANDLE TalkPort;
  30. SECURITY_QUALITY_OF_SERVICE SecurityQos;
  31. ULONG RequestCount;
  32. HANDLE ClientToken;
  33. TOKEN_STATISTICS ClientTokenStatistics;
  34. ULONG IgnoreLength;
  35. HANDLE SepServerThread;
  36. //////////////////////////////////////////////////////////////////////////////
  37. // //
  38. // Test Routine Definitions //
  39. // //
  40. //////////////////////////////////////////////////////////////////////////////
  41. BOOLEAN
  42. SepClientTestStatic(VOID);
  43. BOOLEAN
  44. SepClientTestDynamic(VOID);
  45. BOOLEAN
  46. SepClientTestEffectiveOnly(
  47. BOOLEAN StaticTest
  48. );
  49. BOOLEAN
  50. SepClientTestNotEffectiveOnly(
  51. BOOLEAN StaticTest
  52. );
  53. BOOLEAN
  54. SepClientTestAnonymous(
  55. BOOLEAN StaticTest,
  56. BOOLEAN EffectiveOnly
  57. );
  58. BOOLEAN
  59. SepClientTestIdentification(
  60. BOOLEAN StaticTest,
  61. BOOLEAN EffectiveOnly
  62. );
  63. BOOLEAN
  64. SepClientTestImpersonation(
  65. BOOLEAN StaticTest,
  66. BOOLEAN EffectiveOnly
  67. );
  68. VOID
  69. SepClientConnect(
  70. SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
  71. SECURITY_CONTEXT_TRACKING_MODE TrackingMode,
  72. BOOLEAN EffectiveOnly
  73. );
  74. VOID
  75. SepClientMakeRemoteCall( VOID );
  76. VOID
  77. SepClientDropConnection( VOID );
  78. BOOLEAN
  79. SepClientTest(VOID);
  80. NTSTATUS
  81. SepClientInitialize(
  82. );
  83. BOOLEAN
  84. SepServerTestStatic(VOID);
  85. BOOLEAN
  86. SepServerTestDynamic(VOID);
  87. BOOLEAN
  88. SepServerTestEffectiveOnly(
  89. BOOLEAN StaticTest
  90. );
  91. BOOLEAN
  92. SepServerTestNotEffectiveOnly(
  93. BOOLEAN StaticTest
  94. );
  95. BOOLEAN
  96. SepServerTestAnonymous(
  97. BOOLEAN StaticTest,
  98. BOOLEAN EffectiveOnly
  99. );
  100. BOOLEAN
  101. SepServerTestIdentification(
  102. BOOLEAN StaticTest,
  103. BOOLEAN EffectiveOnly
  104. );
  105. BOOLEAN
  106. SepServerTestImpersonation(
  107. BOOLEAN StaticTest,
  108. BOOLEAN EffectiveOnly
  109. );
  110. VOID
  111. SepServerWaitForNextConnect( VOID );
  112. VOID
  113. SepServerGetNextMessage( VOID );
  114. VOID
  115. SepServerCompleteMessage( VOID );
  116. VOID
  117. SepServerDropConnection( VOID );
  118. BOOLEAN
  119. SepServerTest(VOID);
  120. NTSTATUS
  121. SepServerInitialize(
  122. );
  123. VOID
  124. SepServerSpawnClientProcess(VOID);
  125. VOID
  126. SepWritePipe( PSZ String );
  127. VOID
  128. SepReadPipe(VOID);
  129. VOID
  130. SepTransceivePipe( PSZ String );
  131. HANDLE
  132. SepServerCreatePipe(VOID);
  133. VOID
  134. SepServerListenPipe(VOID);
  135. VOID
  136. SepServerImpersonatePipe(VOID);
  137. VOID
  138. SepServerDisconnectPipe(VOID);
  139. HANDLE
  140. SepClientOpenPipe( VOID );
  141. BOOLEAN
  142. CtLnpQos (VOID);
  143. //////////////////////////////////////////////////////////////////////////////
  144. // //
  145. // Client-Side Test Routines //
  146. // //
  147. //////////////////////////////////////////////////////////////////////////////
  148. VOID
  149. SepClientConnect(
  150. SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
  151. SECURITY_CONTEXT_TRACKING_MODE TrackingMode,
  152. BOOLEAN EffectiveOnly
  153. )
  154. {
  155. SecurityQos.ImpersonationLevel = ImpersonationLevel;
  156. SecurityQos.ContextTrackingMode = TrackingMode;
  157. SecurityQos.EffectiveOnly = EffectiveOnly;
  158. DevPrint("\nClient: ");
  159. TalkPort = SepClientOpenPipe();
  160. return;
  161. }
  162. VOID
  163. SepClientMakeRemoteCall( VOID )
  164. {
  165. DevPrint("\nClient: ");
  166. SepTransceivePipe( "Make Client Call\n" );
  167. RequestCount += 1;
  168. return;
  169. }
  170. VOID
  171. SepClientDropConnection( VOID )
  172. {
  173. Status = NtClose( TalkPort ); SEASSERT_SUCCESS(Status);
  174. return;
  175. }
  176. BOOLEAN
  177. SepClientTestStatic(VOID)
  178. {
  179. BOOLEAN CompletionStatus;
  180. //
  181. // Static Context Tracking ... Suite
  182. //
  183. CompletionStatus = SepClientTestEffectiveOnly( TRUE );
  184. if (CompletionStatus == TRUE) {
  185. CompletionStatus = SepClientTestNotEffectiveOnly( TRUE );
  186. }
  187. return CompletionStatus;
  188. }
  189. BOOLEAN
  190. SepClientTestDynamic(VOID)
  191. {
  192. BOOLEAN CompletionStatus;
  193. //
  194. // Dynamic Context Tracking ... Suite
  195. //
  196. CompletionStatus = SepClientTestEffectiveOnly( FALSE );
  197. if (CompletionStatus == TRUE) {
  198. CompletionStatus = SepClientTestNotEffectiveOnly( FALSE );
  199. }
  200. return CompletionStatus;
  201. }
  202. BOOLEAN
  203. SepClientTestEffectiveOnly(
  204. BOOLEAN StaticTest
  205. )
  206. {
  207. BOOLEAN CompletionStatus;
  208. //
  209. // Effective Only ... Test
  210. //
  211. CompletionStatus = SepClientTestAnonymous( StaticTest, TRUE );
  212. if (CompletionStatus == TRUE) {
  213. CompletionStatus = SepClientTestIdentification( StaticTest, TRUE );
  214. }
  215. if (CompletionStatus == TRUE) {
  216. CompletionStatus = SepClientTestImpersonation( StaticTest, TRUE );
  217. }
  218. return CompletionStatus;
  219. }
  220. BOOLEAN
  221. SepClientTestNotEffectiveOnly(
  222. BOOLEAN StaticTest
  223. )
  224. {
  225. BOOLEAN CompletionStatus;
  226. //
  227. // Not Effective Only ... Test
  228. //
  229. CompletionStatus = SepClientTestAnonymous( StaticTest, FALSE );
  230. if (CompletionStatus == TRUE) {
  231. CompletionStatus = SepClientTestIdentification( StaticTest, FALSE );
  232. }
  233. if (CompletionStatus == TRUE) {
  234. CompletionStatus = SepClientTestImpersonation( StaticTest, FALSE );
  235. }
  236. return CompletionStatus;
  237. }
  238. BOOLEAN
  239. SepClientTestAnonymous(
  240. BOOLEAN StaticTest,
  241. BOOLEAN EffectiveOnly
  242. )
  243. {
  244. //////////////////////////////////////////////////////////////////////////
  245. // //
  246. // Anonymous Use Test //
  247. // //
  248. //////////////////////////////////////////////////////////////////////////
  249. SECURITY_CONTEXT_TRACKING_MODE TrackingMode;
  250. if (StaticTest) {
  251. TrackingMode = SECURITY_STATIC_TRACKING;
  252. } else {
  253. TrackingMode = SECURITY_DYNAMIC_TRACKING;
  254. }
  255. if (!StaticTest) {
  256. //
  257. // No action for dynamic test
  258. //
  259. return TRUE;
  260. }
  261. //
  262. // Anonymous Use ... Test
  263. //
  264. SepClientConnect(
  265. SecurityAnonymous,
  266. TrackingMode,
  267. EffectiveOnly
  268. );
  269. SepClientMakeRemoteCall();
  270. SepClientDropConnection();
  271. return TRUE;
  272. }
  273. BOOLEAN
  274. SepClientTestIdentification(
  275. BOOLEAN StaticTest,
  276. BOOLEAN EffectiveOnly
  277. )
  278. {
  279. //////////////////////////////////////////////////////////////////////////
  280. // //
  281. // Identification Use Test //
  282. // //
  283. //////////////////////////////////////////////////////////////////////////
  284. SECURITY_CONTEXT_TRACKING_MODE TrackingMode;
  285. if (StaticTest) {
  286. TrackingMode = SECURITY_STATIC_TRACKING;
  287. } else {
  288. TrackingMode = SECURITY_DYNAMIC_TRACKING;
  289. }
  290. //
  291. // Identification Use ... Test
  292. //
  293. SepClientConnect(
  294. SecurityIdentification,
  295. TrackingMode,
  296. EffectiveOnly
  297. );
  298. SepClientMakeRemoteCall();
  299. SepClientDropConnection();
  300. return TRUE;
  301. }
  302. BOOLEAN
  303. SepClientTestImpersonation(
  304. BOOLEAN StaticTest,
  305. BOOLEAN EffectiveOnly
  306. )
  307. {
  308. //////////////////////////////////////////////////////////////////////////
  309. // //
  310. // Impersonation Use Test //
  311. // //
  312. //////////////////////////////////////////////////////////////////////////
  313. SECURITY_CONTEXT_TRACKING_MODE TrackingMode;
  314. if (StaticTest) {
  315. TrackingMode = SECURITY_STATIC_TRACKING;
  316. } else {
  317. TrackingMode = SECURITY_DYNAMIC_TRACKING;
  318. }
  319. //
  320. // Impersonation Use ... Test
  321. //
  322. SepClientConnect(
  323. SecurityImpersonation,
  324. TrackingMode,
  325. EffectiveOnly
  326. );
  327. SepClientMakeRemoteCall();
  328. SepClientDropConnection();
  329. return TRUE;
  330. }
  331. BOOLEAN
  332. SepClientTest(VOID)
  333. //
  334. // Tests:
  335. //
  336. // Static Context Tracking Tests
  337. // Effective Only
  338. // Anonymous
  339. // Identification
  340. // Impersonation
  341. // Not Effective Only
  342. // Anonymous
  343. // Identification
  344. // Impersonation
  345. //
  346. // Dynamic Context Tracking Tests
  347. // Effective Only
  348. // Identification
  349. // Impersonation
  350. // Not Effective Only
  351. // Identification
  352. // Impersonation
  353. //
  354. {
  355. BOOLEAN CompletionStatus;
  356. //
  357. // Run the static test suite...
  358. //
  359. CompletionStatus = SepClientTestStatic();
  360. //
  361. // Run the dynamic test suite...
  362. //
  363. if (CompletionStatus == TRUE) {
  364. CompletionStatus = SepClientTestDynamic();
  365. }
  366. DbgPrint("Se: Client Test Complete.\n");
  367. return CompletionStatus;
  368. }
  369. NTSTATUS
  370. SepClientInitialize(
  371. )
  372. {
  373. DbgPrint("Se: Client Initializing ...\n");
  374. RequestCount = 0;
  375. //
  376. // Signal the named event to start the test
  377. //
  378. DbgPrint("Se: Client Starting Test ...\n");
  379. Status = NtSetEvent( EventHandle, NULL ); SEASSERT_SUCCESS(Status);
  380. Status = NtClose( EventHandle ); SEASSERT_SUCCESS(Status);
  381. return STATUS_SUCCESS;
  382. }
  383. //////////////////////////////////////////////////////////////////////////////
  384. // //
  385. // Server-Side Test Routines //
  386. // //
  387. //////////////////////////////////////////////////////////////////////////////
  388. VOID
  389. SepServerWaitForNextConnect( VOID )
  390. {
  391. DevPrint("\nServer: ");
  392. SepServerListenPipe();
  393. Status = NtDuplicateObject(
  394. NtCurrentProcess(), // SourceProcessHandle
  395. EarPort, // SourceHandle
  396. NtCurrentProcess(), // TargetProcessHandle
  397. &TalkPort, // TargetHandle
  398. 0, // DesiredAccess (over-ridden by option)
  399. 0, // HandleAttributes
  400. DUPLICATE_SAME_ACCESS // Options
  401. );
  402. ASSERT(NT_SUCCESS(Status));
  403. return;
  404. }
  405. VOID
  406. SepServerGetNextMessage( VOID )
  407. {
  408. DevPrint("\nServer: ");
  409. SepReadPipe();
  410. RequestCount += 1;
  411. return;
  412. }
  413. VOID
  414. SepServerCompleteMessage( VOID )
  415. {
  416. DevPrint("\nServer: ");
  417. SepWritePipe("Return From Server\n");
  418. return;
  419. }
  420. VOID
  421. SepServerImpersonateClient( VOID )
  422. {
  423. DevPrint("\nServer: ");
  424. SepServerImpersonatePipe( );
  425. }
  426. VOID
  427. SepServerRevertToSelf( VOID )
  428. {
  429. NTSTATUS TmpStatus;
  430. HANDLE NullHandle;
  431. NullHandle = NULL;
  432. TmpStatus = NtSetInformationThread(
  433. SepServerThread,
  434. ThreadImpersonationToken,
  435. (PVOID)&NullHandle,
  436. (ULONG)sizeof(HANDLE)
  437. ); SEASSERT_SUCCESS(TmpStatus);
  438. }
  439. VOID
  440. SepServerDropConnection( VOID )
  441. {
  442. DevPrint("\nServer: ");
  443. SepServerDisconnectPipe();
  444. return;
  445. }
  446. BOOLEAN
  447. SepServerTestStatic(VOID)
  448. {
  449. BOOLEAN CompletionStatus;
  450. DbgPrint("Se: Static Context Tracking ... Suite\n");
  451. CompletionStatus = SepServerTestEffectiveOnly( TRUE );
  452. if (CompletionStatus == TRUE) {
  453. CompletionStatus = SepServerTestNotEffectiveOnly( TRUE );
  454. }
  455. return CompletionStatus;
  456. }
  457. BOOLEAN
  458. SepServerTestDynamic(VOID)
  459. {
  460. BOOLEAN CompletionStatus;
  461. DbgPrint("Se: Dynamic Context Tracking ... Suite\n");
  462. CompletionStatus = SepServerTestEffectiveOnly( FALSE );
  463. if (CompletionStatus == TRUE) {
  464. CompletionStatus = SepServerTestNotEffectiveOnly( FALSE );
  465. }
  466. return CompletionStatus;
  467. }
  468. BOOLEAN
  469. SepServerTestEffectiveOnly(
  470. BOOLEAN StaticTest
  471. )
  472. {
  473. BOOLEAN CompletionStatus;
  474. DbgPrint("Se: Effective Only ... Test\n");
  475. CompletionStatus = SepServerTestAnonymous( StaticTest, TRUE );
  476. if (CompletionStatus == TRUE) {
  477. CompletionStatus = SepServerTestIdentification( StaticTest, TRUE );
  478. }
  479. if (CompletionStatus == TRUE) {
  480. CompletionStatus = SepServerTestImpersonation( StaticTest, TRUE );
  481. }
  482. return CompletionStatus;
  483. }
  484. BOOLEAN
  485. SepServerTestNotEffectiveOnly(
  486. BOOLEAN StaticTest
  487. )
  488. {
  489. BOOLEAN CompletionStatus;
  490. DbgPrint("Se: Not Effective Only ... Test\n");
  491. CompletionStatus = SepServerTestAnonymous( StaticTest, FALSE );
  492. if (CompletionStatus == TRUE) {
  493. CompletionStatus = SepServerTestIdentification( StaticTest, FALSE );
  494. }
  495. if (CompletionStatus == TRUE) {
  496. CompletionStatus = SepServerTestImpersonation( StaticTest, FALSE );
  497. }
  498. return CompletionStatus;
  499. }
  500. BOOLEAN
  501. SepServerTestAnonymous(
  502. BOOLEAN StaticTest,
  503. BOOLEAN EffectiveOnly
  504. )
  505. {
  506. BOOLEAN CompletionStatus = TRUE;
  507. //////////////////////////////////////////////////////////////////////////
  508. // //
  509. // Anonymous Use Test //
  510. // //
  511. //////////////////////////////////////////////////////////////////////////
  512. if (!StaticTest) {
  513. //
  514. // No action for dynamic test
  515. //
  516. return TRUE;
  517. }
  518. DbgPrint("Se: Anonymous Use ... ");
  519. SepServerWaitForNextConnect();
  520. SepServerGetNextMessage();
  521. SepServerImpersonateClient();
  522. Status = NtOpenThreadToken(
  523. SepServerThread,
  524. TOKEN_ALL_ACCESS,
  525. TRUE,
  526. &ClientToken
  527. );
  528. SepServerRevertToSelf();
  529. if (Status == STATUS_CANT_OPEN_ANONYMOUS) {
  530. DbgPrint(" Succeeded\n");
  531. } else {
  532. DbgPrint("* ! FAILED (srvr) ! *\n");
  533. DbgPrint("Status is: 0x%lx \n", Status );
  534. CompletionStatus = FALSE;
  535. }
  536. SepServerCompleteMessage();
  537. SepServerDropConnection();
  538. //
  539. // Appease the compiler Gods..
  540. //
  541. if (EffectiveOnly) {;}
  542. return CompletionStatus;
  543. }
  544. BOOLEAN
  545. SepServerTestIdentification(
  546. BOOLEAN StaticTest,
  547. BOOLEAN EffectiveOnly
  548. )
  549. {
  550. BOOLEAN CompletionStatus = TRUE;
  551. //////////////////////////////////////////////////////////////////////////
  552. // //
  553. // Identification Use Test //
  554. // //
  555. //////////////////////////////////////////////////////////////////////////
  556. DbgPrint("Se: Identification Use ... ");
  557. SepServerWaitForNextConnect();
  558. SepServerGetNextMessage();
  559. SepServerImpersonateClient();
  560. Status = NtOpenThreadToken(
  561. SepServerThread,
  562. TOKEN_ALL_ACCESS,
  563. TRUE,
  564. &ClientToken
  565. ); SEASSERT_SUCCESS(Status);
  566. SepServerRevertToSelf();
  567. Status = NtQueryInformationToken(
  568. ClientToken,
  569. TokenStatistics,
  570. &ClientTokenStatistics,
  571. (ULONG)sizeof(TOKEN_STATISTICS),
  572. &IgnoreLength
  573. ); SEASSERT_SUCCESS(Status);
  574. if ( (ClientTokenStatistics.TokenType == TokenImpersonation) &&
  575. (ClientTokenStatistics.ImpersonationLevel == SecurityIdentification)
  576. ) {
  577. DbgPrint(" Succeeded\n");
  578. } else {
  579. DbgPrint("* ! FAILED (srvr) ! *\n");
  580. CompletionStatus = FALSE;
  581. }
  582. SepServerCompleteMessage();
  583. SepServerDropConnection();
  584. //
  585. // Appease the compiler Gods..
  586. //
  587. if (StaticTest) {;}
  588. if (EffectiveOnly) {;}
  589. return CompletionStatus;
  590. }
  591. BOOLEAN
  592. SepServerTestImpersonation(
  593. BOOLEAN StaticTest,
  594. BOOLEAN EffectiveOnly
  595. )
  596. {
  597. BOOLEAN CompletionStatus = TRUE;
  598. //////////////////////////////////////////////////////////////////////////
  599. // //
  600. // Impersonation Use Test //
  601. // //
  602. //////////////////////////////////////////////////////////////////////////
  603. DbgPrint("Se: Impersonation Use ... ");
  604. SepServerWaitForNextConnect();
  605. SepServerGetNextMessage();
  606. SepServerImpersonateClient();
  607. Status = NtOpenThreadToken(
  608. SepServerThread,
  609. TOKEN_ALL_ACCESS,
  610. TRUE,
  611. &ClientToken
  612. ); SEASSERT_SUCCESS(Status);
  613. SepServerRevertToSelf();
  614. Status = NtQueryInformationToken(
  615. ClientToken,
  616. TokenStatistics,
  617. &ClientTokenStatistics,
  618. (ULONG)sizeof(TOKEN_STATISTICS),
  619. &IgnoreLength
  620. ); SEASSERT_SUCCESS(Status);
  621. if ( (ClientTokenStatistics.TokenType == TokenImpersonation) &&
  622. (ClientTokenStatistics.ImpersonationLevel == SecurityImpersonation)
  623. ) {
  624. DbgPrint(" Succeeded\n");
  625. } else {
  626. DbgPrint("* ! FAILED (srvr) ! *\n");
  627. CompletionStatus = FALSE;
  628. }
  629. SepServerCompleteMessage();
  630. SepServerDropConnection();
  631. //
  632. // Appease the compiler gods
  633. //
  634. if (StaticTest) {;}
  635. if (EffectiveOnly) {;}
  636. return CompletionStatus;
  637. }
  638. BOOLEAN
  639. SepServerTest(VOID)
  640. //
  641. // Tests:
  642. //
  643. // Static Context Tracking Tests
  644. // Effective Only
  645. // Anonymous
  646. // Identification
  647. // Impersonation
  648. // Not Effective Only
  649. // Anonymous
  650. // Identification
  651. // Impersonation
  652. //
  653. // Dynamic Context Tracking Tests
  654. // Effective Only
  655. // Identification
  656. // Impersonation
  657. // Not Effective Only
  658. // Identification
  659. // Impersonation
  660. //
  661. {
  662. BOOLEAN CompletionStatus;
  663. DbgPrint("Se: Server Starting Test ...\n");
  664. //
  665. // Run the static test suite...
  666. //
  667. CompletionStatus = SepServerTestStatic();
  668. //
  669. // Run the dynamic test suite...
  670. //
  671. if (CompletionStatus == TRUE) {
  672. CompletionStatus = SepServerTestDynamic();
  673. }
  674. DbgPrint("Se: Server Test Complete.\n");
  675. //
  676. // Print test results
  677. //
  678. DbgPrint("\n");
  679. DbgPrint("\n");
  680. DbgPrint("**********************\n");
  681. DbgPrint("** **\n");
  682. if (CompletionStatus == TRUE) {
  683. DbgPrint("** Test Succeeded **\n");
  684. } else {
  685. DbgPrint("** Test Failed !! **\n");
  686. }
  687. DbgPrint("** **\n");
  688. DbgPrint("**********************\n");
  689. return CompletionStatus;
  690. }
  691. NTSTATUS
  692. SepServerInitialize(
  693. )
  694. {
  695. OBJECT_ATTRIBUTES ThreadAttributes;
  696. PTEB CurrentTeb;
  697. DbgPrint("Se: Server Initializing ...\n");
  698. //
  699. // Initialize global variables
  700. //
  701. RequestCount = 0;
  702. //
  703. // Get a handle to our thread to so that we can access our thread
  704. // even when impersonating an anonymous client (which we can't do
  705. // using NtCurrentThread()).
  706. //
  707. CurrentTeb = NtCurrentTeb();
  708. InitializeObjectAttributes(&ThreadAttributes, NULL, 0, NULL, NULL);
  709. Status = NtOpenThread(
  710. &SepServerThread, // TargetHandle
  711. THREAD_ALL_ACCESS, // DesiredAccess
  712. &ThreadAttributes, // ObjectAttributes
  713. &CurrentTeb->ClientId // ClientId
  714. );
  715. ASSERT( NT_SUCCESS(Status) );
  716. //
  717. // Create the server's port
  718. //
  719. EarPort = SepServerCreatePipe();
  720. //
  721. // Spawn a copy of ourselves...
  722. //
  723. DbgPrint("Se: Server Spawning client process ...\n");
  724. SepServerSpawnClientProcess();
  725. DbgPrint("Se: Server waiting for start of test signal ...\n");
  726. Status = NtWaitForSingleObject(
  727. EventHandle,
  728. TRUE,
  729. NULL
  730. ); SEASSERT_SUCCESS(Status);
  731. Status = NtClose( EventHandle ); SEASSERT_SUCCESS(Status);
  732. return STATUS_SUCCESS;
  733. }
  734. VOID
  735. SepServerSpawnClientProcess(VOID)
  736. {
  737. RTL_USER_PROCESS_INFORMATION ProcessInformation;
  738. STRING ProgramName;
  739. UNICODE_STRING UnicodeProgramName;
  740. STRING ImagePathName;
  741. UNICODE_STRING UnicodeImagePathName;
  742. PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
  743. RtlInitString( &ProgramName, "\\SystemRoot\\Bin\\utlnpqos.exe" );
  744. Status = RtlAnsiStringToUnicodeString(
  745. &UnicodeProgramName,
  746. &ProgramName,
  747. TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
  748. RtlInitString( &ImagePathName, "utlnpqos.exe");
  749. Status = RtlAnsiStringToUnicodeString(
  750. &UnicodeImagePathName,
  751. &ImagePathName,
  752. TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
  753. Status = RtlCreateProcessParameters(
  754. &ProcessParameters,
  755. &ImagePathName, // FIX, FIX &UnicodeImagePathName, (when converted to unicode)
  756. NULL,
  757. NULL,
  758. NULL,
  759. NULL,
  760. NULL,
  761. NULL,
  762. NULL,
  763. NULL
  764. );
  765. SEASSERT_SUCCESS(Status);
  766. RtlFreeUnicodeString( &UnicodeImagePathName );
  767. Status = RtlCreateUserProcess(
  768. &ProgramName, // FIX, FIX &UnicodeProgramName (when converted to unicode)
  769. ProcessParameters, // ProcessParameters
  770. NULL, // ProcessSecurityDescriptor
  771. NULL, // ThreadSecurityDescriptor
  772. NtCurrentProcess(), // ParentProcess
  773. FALSE, // InheritHandles
  774. NULL, // DebugPort
  775. NULL, // ExceptionPort
  776. &ProcessInformation // ProcessInformation
  777. ); SEASSERT_SUCCESS(Status);
  778. RtlFreeUnicodeString( &UnicodeProgramName );
  779. Status = NtResumeThread(
  780. ProcessInformation.Thread,
  781. NULL
  782. ); SEASSERT_SUCCESS(Status);
  783. RtlDestroyProcessParameters( ProcessParameters );
  784. }
  785. //////////////////////////////////////////////////////////////////////////////
  786. // //
  787. // Main Program Entry Routine //
  788. // //
  789. //////////////////////////////////////////////////////////////////////////////
  790. BOOLEAN
  791. CtLnpQos (VOID)
  792. {
  793. BOOLEAN Result = TRUE;
  794. RtlInitString( &PortName, "\\Device\\NamedPipe\\TestLnpQosServerPort" );
  795. Status = RtlAnsiStringToUnicodeString(
  796. &UnicodePortName,
  797. &PortName,
  798. TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
  799. RtlInitString( &RelativePortName, "TestLnpQosServerPort" );
  800. Status = RtlAnsiStringToUnicodeString(
  801. &UnicodeRelativePortName,
  802. &RelativePortName,
  803. TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
  804. //
  805. // Determine whether we are the client or server side of the test.
  806. // This is done by creating or opening a named event object. If the
  807. // event does not yet exist, then we are the client, and must create
  808. // the server process. Otherwise, we are the server and the client
  809. // is waiting for us to signal the event.
  810. //
  811. RtlInitString( &EventName, "\\TestLnpQosEvent" );
  812. Status = RtlAnsiStringToUnicodeString(
  813. &UnicodeEventName,
  814. &EventName,
  815. TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
  816. InitializeObjectAttributes(
  817. &ObjectAttributes,
  818. &UnicodeEventName,
  819. OBJ_OPENIF,
  820. NULL,
  821. NULL
  822. );
  823. Status = NtCreateEvent(
  824. &EventHandle,
  825. EVENT_ALL_ACCESS,
  826. &ObjectAttributes,
  827. SynchronizationEvent,
  828. FALSE
  829. );
  830. RtlFreeUnicodeString( &UnicodeEventName );
  831. if (Status == STATUS_OBJECT_NAME_EXISTS) {
  832. //
  833. // Server is already running, therefore, this process gets to be
  834. // the client.
  835. //
  836. Status = SepClientInitialize(); SEASSERT_SUCCESS(Status);
  837. Result = SepClientTest();
  838. } else {
  839. SEASSERT_SUCCESS(Status);
  840. //
  841. // Event wasn't yet there, so we must be the server.
  842. //
  843. DbgPrint("Se: Starting Local Named Pipe Impersonation Test.\n");
  844. Status = SepServerInitialize(); SEASSERT_SUCCESS(Status);
  845. Result = SepServerTest();
  846. DbgPrint("Se: End Test.\n");
  847. }
  848. Status = NtTerminateThread( NtCurrentThread(), STATUS_SUCCESS);
  849. SEASSERT_SUCCESS(Status);
  850. return Result;
  851. }
  852. //////////////////////////////////////////////////////////////////////////////
  853. // //
  854. // Named Pipe Common Operations //
  855. // //
  856. //////////////////////////////////////////////////////////////////////////////
  857. VOID
  858. SepReadPipe(
  859. )
  860. {
  861. IO_STATUS_BLOCK Iosb;
  862. UCHAR Buffer[512];
  863. DevPrint("ReadPipe...\n", 0);
  864. if (!NT_SUCCESS(Status = NtReadFile( TalkPort,
  865. (HANDLE)NULL,
  866. (PIO_APC_ROUTINE)NULL,
  867. (PVOID)NULL,
  868. &Iosb,
  869. Buffer,
  870. 512,
  871. (PLARGE_INTEGER)NULL,
  872. (PULONG) NULL ))) {
  873. Error( NtReadFile, Status );
  874. }
  875. if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) {
  876. Error( NtWaitForSingleObject, Status );
  877. }
  878. if (!NT_SUCCESS(Iosb.Status)) {
  879. Error( NtReadFileFinalStatus, Iosb.Status );
  880. }
  881. return;
  882. }
  883. VOID
  884. SepWritePipe(
  885. PSZ String
  886. )
  887. {
  888. NTSTATUS Status;
  889. IO_STATUS_BLOCK Iosb;
  890. DevPrint("WritePipe...\n", 0);
  891. if (!NT_SUCCESS(Status = NtWriteFile( TalkPort,
  892. (HANDLE)NULL,
  893. (PIO_APC_ROUTINE)NULL,
  894. (PVOID)NULL,
  895. &Iosb,
  896. String,
  897. strlen( String ),
  898. (PLARGE_INTEGER)NULL,
  899. (PULONG)NULL ))) {
  900. Error( NtWriteFile, Status );
  901. }
  902. if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) {
  903. Error( NtWaitForSingleObject, Status );
  904. }
  905. if (!NT_SUCCESS(Iosb.Status)) {
  906. Error( NtWriteFileFinalStatus, Iosb.Status );
  907. }
  908. return;
  909. }
  910. VOID
  911. SepTransceivePipe(
  912. PSZ String
  913. )
  914. {
  915. NTSTATUS Status;
  916. IO_STATUS_BLOCK Iosb;
  917. UCHAR Buffer[512];
  918. DevPrint("TransceivePipe...\n", 0);
  919. if (!NT_SUCCESS(Status = NtFsControlFile(
  920. TalkPort,
  921. NULL, // Event
  922. NULL, // ApcRoutine
  923. NULL, // ApcContext
  924. &Iosb,
  925. FSCTL_PIPE_TRANSCEIVE,
  926. String,
  927. strlen( String ),
  928. Buffer,
  929. 511
  930. ))) {
  931. Error( NtTransceiveFile, Status );
  932. }
  933. if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) {
  934. Error( NtWaitForSingleObject, Status );
  935. }
  936. if (!NT_SUCCESS(Iosb.Status)) {
  937. Error( NtTransceiveFileFinalStatus, Iosb.Status );
  938. }
  939. return;
  940. }
  941. //////////////////////////////////////////////////////////////////////////////
  942. // //
  943. // Named Pipe Server Operations //
  944. // //
  945. //////////////////////////////////////////////////////////////////////////////
  946. HANDLE
  947. SepServerCreatePipe(
  948. VOID
  949. )
  950. {
  951. HANDLE PipeHandle;
  952. NTSTATUS Status;
  953. IO_STATUS_BLOCK Iosb;
  954. LARGE_INTEGER Timeout;
  955. READ_MODE Mode;
  956. ULONG Share;
  957. NAMED_PIPE_CONFIGURATION Config = FILE_PIPE_FULL_DUPLEX;
  958. NAMED_PIPE_TYPE PipeType = FILE_PIPE_MESSAGE_TYPE;
  959. COMPLETION_MODE CompletionMode = FILE_PIPE_QUEUE_OPERATION;
  960. ULONG MaximumInstances = 4;
  961. //
  962. // Set the default timeout to 60 seconds, and initalize the attributes
  963. //
  964. Timeout.QuadPart = -10 * 1000 * 1000 * 60;
  965. InitializeObjectAttributes(
  966. &ObjectAttributes,
  967. &UnicodePortName,
  968. OBJ_CASE_INSENSITIVE,
  969. NULL,
  970. NULL
  971. );
  972. //
  973. // Calculate the readmode and share access
  974. //
  975. Mode = (PipeType == FILE_PIPE_MESSAGE_TYPE ? FILE_PIPE_MESSAGE_MODE :
  976. FILE_PIPE_BYTE_STREAM_MODE);
  977. Share = (Config == FILE_PIPE_INBOUND ? FILE_SHARE_WRITE :
  978. (Config == FILE_PIPE_OUTBOUND ? FILE_SHARE_READ :
  979. FILE_SHARE_READ | FILE_SHARE_WRITE));
  980. if (!NT_SUCCESS(Status = NtCreateNamedPipeFile(
  981. &PipeHandle,
  982. GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
  983. &ObjectAttributes,
  984. &Iosb,
  985. Share,
  986. FILE_CREATE,
  987. 0,
  988. PipeType,
  989. Mode,
  990. CompletionMode,
  991. MaximumInstances,
  992. 1024,
  993. 1024,
  994. (PLARGE_INTEGER)&Timeout ))) {
  995. Error( CreatePipe, Status );
  996. }
  997. RtlFreeUnicodeString( &UnicodePortName );
  998. return PipeHandle;
  999. }
  1000. VOID
  1001. SepServerListenPipe(
  1002. )
  1003. {
  1004. NTSTATUS Status;
  1005. IO_STATUS_BLOCK Iosb;
  1006. DevPrint("ListenPipe...\n", 0);
  1007. if (!NT_SUCCESS(Status = NtFsControlFile(
  1008. EarPort,
  1009. NULL, // Event
  1010. NULL, // ApcRoutine
  1011. NULL, // ApcContext
  1012. &Iosb,
  1013. FSCTL_PIPE_LISTEN,
  1014. NULL, // InputBuffer
  1015. 0, // InputBufferLength,
  1016. NULL, // OutputBuffer
  1017. 0 // OutputBufferLength
  1018. ))) {
  1019. Error( ListenPipe, Status );
  1020. }
  1021. if (!NT_SUCCESS(Status = NtWaitForSingleObject( EarPort, TRUE, NULL ))) {
  1022. Error( NtWaitForSingleObject, Status );
  1023. }
  1024. if (!NT_SUCCESS(Iosb.Status)) {
  1025. Error( ListenPipeFinalStatus, Iosb.Status );
  1026. }
  1027. return;
  1028. }
  1029. VOID
  1030. SepServerImpersonatePipe(
  1031. )
  1032. {
  1033. NTSTATUS Status;
  1034. IO_STATUS_BLOCK Iosb;
  1035. DevPrint("ImpersonatePipe...\n", 0);
  1036. if (!NT_SUCCESS(Status = NtFsControlFile(
  1037. TalkPort,
  1038. NULL, // Event
  1039. NULL, // ApcRoutine
  1040. NULL, // ApcContext
  1041. &Iosb,
  1042. FSCTL_PIPE_IMPERSONATE,
  1043. NULL, // InputBuffer
  1044. 0, // InputBufferLength,
  1045. NULL, // OutputBuffer
  1046. 0 // OutputBufferLength
  1047. ))) {
  1048. Error( ImpersonatePipe, Status );
  1049. }
  1050. if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) {
  1051. Error( NtWaitForSingleObject, Status );
  1052. }
  1053. if (!NT_SUCCESS(Iosb.Status)) {
  1054. Error( ImpersonatePipeFinalStatus, Iosb.Status );
  1055. }
  1056. return;
  1057. }
  1058. VOID
  1059. SepServerDisconnectPipe(
  1060. )
  1061. {
  1062. NTSTATUS Status;
  1063. IO_STATUS_BLOCK Iosb;
  1064. DevPrint("DisconnectPipe...\n", 0);
  1065. DevPrint(" (Flush)...\n", 0);
  1066. if (!NT_SUCCESS(Status = NtFlushBuffersFile(
  1067. TalkPort,
  1068. &Iosb
  1069. ))) {
  1070. Error( DisconnectPipe, Status );
  1071. }
  1072. if (!NT_SUCCESS(Iosb.Status)) {
  1073. Error( FlushPipeFinalStatus, Iosb.Status );
  1074. }
  1075. DevPrint(" (Close Talk Port)...\n", 0);
  1076. Status = NtClose( TalkPort ); SEASSERT_SUCCESS(Status);
  1077. DevPrint(" (Disconnect)...\n", 0);
  1078. if (!NT_SUCCESS(Status = NtFsControlFile(
  1079. EarPort,
  1080. NULL, // Event
  1081. NULL, // ApcRoutine
  1082. NULL, // ApcContext
  1083. &Iosb,
  1084. FSCTL_PIPE_DISCONNECT,
  1085. NULL, // InputBuffer
  1086. 0, // InputBufferLength,
  1087. NULL, // OutputBuffer
  1088. 0 // OutputBufferLength
  1089. ))) {
  1090. Error( DisconnectPipe, Status );
  1091. }
  1092. if (!NT_SUCCESS(Status = NtWaitForSingleObject( EarPort, TRUE, NULL ))) {
  1093. Error( NtWaitForSingleObject, Status );
  1094. }
  1095. if (!NT_SUCCESS(Iosb.Status)) {
  1096. Error( DisconnectPipeFinalStatus, Iosb.Status );
  1097. }
  1098. return;
  1099. }
  1100. //////////////////////////////////////////////////////////////////////////////
  1101. // //
  1102. // Named Pipe Client Operations //
  1103. // //
  1104. //////////////////////////////////////////////////////////////////////////////
  1105. HANDLE
  1106. SepClientOpenPipe(
  1107. VOID
  1108. )
  1109. {
  1110. HANDLE PipeHandle, NpfsHandle;
  1111. NTSTATUS Status;
  1112. IO_STATUS_BLOCK Iosb;
  1113. ULONG Share;
  1114. STRING Npfs;
  1115. UNICODE_STRING UnicodeNpfs;
  1116. PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
  1117. ULONG WaitPipeLength;
  1118. NAMED_PIPE_CONFIGURATION Config = FILE_PIPE_FULL_DUPLEX;
  1119. READ_MODE ReadMode = FILE_PIPE_MESSAGE_MODE;
  1120. COMPLETION_MODE CompletionMode = FILE_PIPE_QUEUE_OPERATION;
  1121. //#ifdef NOT_YET_WORKING
  1122. //
  1123. // Wait for the server's pipe to reach a listen state...
  1124. //
  1125. RtlInitString( &Npfs, "\\Device\\NamedPipe\\");
  1126. Status = RtlAnsiStringToUnicodeString(
  1127. &UnicodeNpfs,
  1128. &Npfs,
  1129. TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
  1130. InitializeObjectAttributes(
  1131. &ObjectAttributes,
  1132. &UnicodeNpfs,
  1133. OBJ_CASE_INSENSITIVE,
  1134. NULL,
  1135. NULL);
  1136. if (!NT_SUCCESS(Status = NtOpenFile(
  1137. &NpfsHandle,
  1138. GENERIC_READ | SYNCHRONIZE,
  1139. &ObjectAttributes,
  1140. &Iosb,
  1141. FILE_SHARE_READ,
  1142. 0 ))) {
  1143. Error( OpenNpfs, Status );
  1144. }
  1145. RtlFreeUnicodeString( &UnicodeNpfs );
  1146. WaitPipeLength =
  1147. FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER, Name[0]) +
  1148. RelativePortName.MaximumLength; //UNICODEFIX UnicodeRelativePortName.MaximumLength;
  1149. WaitPipe = RtlAllocateHeap(RtlProcessHeap(), 0, WaitPipeLength);
  1150. WaitPipe->TimeoutSpecified = FALSE;
  1151. WaitPipe->NameLength = RelativePortName.Length; //UNICODEFIX UnicodeRelativePortName.Length;
  1152. strcpy(WaitPipe->Name, RelativePortName.Buffer); //UNICODEFIX UnicodePortName.Buffer;
  1153. if (!NT_SUCCESS(Status = NtFsControlFile(
  1154. NpfsHandle,
  1155. NULL, // Event
  1156. NULL, // ApcRoutine
  1157. NULL, // ApcContext
  1158. &Iosb,
  1159. FSCTL_PIPE_WAIT,
  1160. WaitPipe, // Buffer for data to the FS
  1161. WaitPipeLength,
  1162. NULL, // OutputBuffer
  1163. 0 // OutputBufferLength
  1164. ))) {
  1165. Error( ClientWaitPipe, Status );
  1166. }
  1167. if (Status == STATUS_PENDING) {
  1168. if (!NT_SUCCESS(Status = NtWaitForSingleObject( NpfsHandle, TRUE, NULL ))) {
  1169. Error( NtWaitForSingleObject, Status );
  1170. }
  1171. }
  1172. if (!NT_SUCCESS(Iosb.Status)) {
  1173. Error( ClientWaitPipeFinalStatus, Iosb.Status );
  1174. }
  1175. Status = NtClose( NpfsHandle );
  1176. ASSERT(NT_SUCCESS(Status));
  1177. //#endif // NOT_YET_WORKING
  1178. // Delay(1);
  1179. //
  1180. // Initialize the attributes
  1181. //
  1182. InitializeObjectAttributes(
  1183. &ObjectAttributes,
  1184. &UnicodePortName,
  1185. OBJ_CASE_INSENSITIVE,
  1186. NULL,
  1187. NULL
  1188. );
  1189. ObjectAttributes.SecurityQualityOfService = (PVOID)(&SecurityQos);
  1190. //
  1191. // Calculate the share access
  1192. //
  1193. Share = (Config == FILE_PIPE_INBOUND ? FILE_SHARE_WRITE :
  1194. (Config == FILE_PIPE_OUTBOUND ? FILE_SHARE_READ :
  1195. FILE_SHARE_READ | FILE_SHARE_WRITE));
  1196. //
  1197. // And now open it...
  1198. //
  1199. if (!NT_SUCCESS(Status = NtOpenFile(
  1200. &PipeHandle,
  1201. GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
  1202. &ObjectAttributes,
  1203. &Iosb,
  1204. Share,
  1205. 0 ))) {
  1206. Error( OpenPipe, Status );
  1207. }
  1208. if ((ReadMode != FILE_PIPE_BYTE_STREAM_MODE) ||
  1209. (CompletionMode != FILE_PIPE_QUEUE_OPERATION)) {
  1210. FILE_PIPE_INFORMATION Buffer;
  1211. Buffer.ReadMode = ReadMode;
  1212. Buffer.CompletionMode = CompletionMode;
  1213. if (!NT_SUCCESS(Status = NtSetInformationFile(
  1214. PipeHandle,
  1215. &Iosb,
  1216. &Buffer,
  1217. sizeof(FILE_PIPE_INFORMATION),
  1218. FilePipeInformation ))) {
  1219. Error( NtSetInformationFile, Status );
  1220. }
  1221. }
  1222. return PipeHandle;
  1223. }