summaryrefslogtreecommitdiffstats
path: root/private/ntos/se/ctlnpqos.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/se/ctlnpqos.c')
-rw-r--r--private/ntos/se/ctlnpqos.c1729
1 files changed, 1729 insertions, 0 deletions
diff --git a/private/ntos/se/ctlnpqos.c b/private/ntos/se/ctlnpqos.c
new file mode 100644
index 000000000..ffaf1520d
--- /dev/null
+++ b/private/ntos/se/ctlnpqos.c
@@ -0,0 +1,1729 @@
+
+//////////////////////////////////////////////////////////////////////////////
+// //
+// Global Definitions //
+// //
+//////////////////////////////////////////////////////////////////////////////
+
+#define DevPrint
+//#define DevPrint DbgPrint
+
+#define Error(N,S) { DbgPrint(#N); DbgPrint(" Error %08lx\n", S); }
+
+#define Delay(SECONDS) { \
+ LARGE_INTEGER Time; \
+ Time.QuadPart = -10 * 1000 * 1000, ((LONGLONG)SECONDS); \
+ NtDelayExecution(TRUE,(PLARGE_INTEGER)&Time); \
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// //
+// Global Variables //
+// //
+//////////////////////////////////////////////////////////////////////////////
+
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ STRING EventName;
+ UNICODE_STRING UnicodeEventName;
+ HANDLE EventHandle;
+ STRING PortName;
+ UNICODE_STRING UnicodePortName;
+ STRING RelativePortName;
+ UNICODE_STRING UnicodeRelativePortName;
+ HANDLE EarPort;
+ HANDLE TalkPort;
+ SECURITY_QUALITY_OF_SERVICE SecurityQos;
+ ULONG RequestCount;
+ HANDLE ClientToken;
+ TOKEN_STATISTICS ClientTokenStatistics;
+ ULONG IgnoreLength;
+
+ HANDLE SepServerThread;
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// //
+// Test Routine Definitions //
+// //
+//////////////////////////////////////////////////////////////////////////////
+BOOLEAN
+SepClientTestStatic(VOID);
+
+BOOLEAN
+SepClientTestDynamic(VOID);
+
+BOOLEAN
+SepClientTestEffectiveOnly(
+ BOOLEAN StaticTest
+ );
+
+BOOLEAN
+SepClientTestNotEffectiveOnly(
+ BOOLEAN StaticTest
+ );
+
+BOOLEAN
+SepClientTestAnonymous(
+ BOOLEAN StaticTest,
+ BOOLEAN EffectiveOnly
+ );
+
+BOOLEAN
+SepClientTestIdentification(
+ BOOLEAN StaticTest,
+ BOOLEAN EffectiveOnly
+ );
+
+BOOLEAN
+SepClientTestImpersonation(
+ BOOLEAN StaticTest,
+ BOOLEAN EffectiveOnly
+ );
+
+VOID
+SepClientConnect(
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
+ SECURITY_CONTEXT_TRACKING_MODE TrackingMode,
+ BOOLEAN EffectiveOnly
+ );
+
+VOID
+SepClientMakeRemoteCall( VOID );
+
+VOID
+SepClientDropConnection( VOID );
+
+BOOLEAN
+SepClientTest(VOID);
+
+NTSTATUS
+SepClientInitialize(
+ );
+
+
+
+
+
+
+BOOLEAN
+SepServerTestStatic(VOID);
+
+BOOLEAN
+SepServerTestDynamic(VOID);
+
+BOOLEAN
+SepServerTestEffectiveOnly(
+ BOOLEAN StaticTest
+ );
+
+BOOLEAN
+SepServerTestNotEffectiveOnly(
+ BOOLEAN StaticTest
+ );
+
+BOOLEAN
+SepServerTestAnonymous(
+ BOOLEAN StaticTest,
+ BOOLEAN EffectiveOnly
+ );
+
+BOOLEAN
+SepServerTestIdentification(
+ BOOLEAN StaticTest,
+ BOOLEAN EffectiveOnly
+ );
+
+BOOLEAN
+SepServerTestImpersonation(
+ BOOLEAN StaticTest,
+ BOOLEAN EffectiveOnly
+ );
+
+VOID
+SepServerWaitForNextConnect( VOID );
+
+VOID
+SepServerGetNextMessage( VOID );
+
+VOID
+SepServerCompleteMessage( VOID );
+
+VOID
+SepServerDropConnection( VOID );
+
+
+
+BOOLEAN
+SepServerTest(VOID);
+
+NTSTATUS
+SepServerInitialize(
+ );
+
+VOID
+SepServerSpawnClientProcess(VOID);
+
+
+
+
+VOID
+SepWritePipe( PSZ String );
+
+VOID
+SepReadPipe(VOID);
+
+VOID
+SepTransceivePipe( PSZ String );
+
+
+
+
+HANDLE
+SepServerCreatePipe(VOID);
+
+VOID
+SepServerListenPipe(VOID);
+
+VOID
+SepServerImpersonatePipe(VOID);
+
+VOID
+SepServerDisconnectPipe(VOID);
+
+
+
+
+HANDLE
+SepClientOpenPipe( VOID );
+
+
+
+
+BOOLEAN
+CtLnpQos (VOID);
+
+
+//////////////////////////////////////////////////////////////////////////////
+// //
+// Client-Side Test Routines //
+// //
+//////////////////////////////////////////////////////////////////////////////
+
+
+VOID
+SepClientConnect(
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
+ SECURITY_CONTEXT_TRACKING_MODE TrackingMode,
+ BOOLEAN EffectiveOnly
+ )
+
+{
+
+ SecurityQos.ImpersonationLevel = ImpersonationLevel;
+ SecurityQos.ContextTrackingMode = TrackingMode;
+ SecurityQos.EffectiveOnly = EffectiveOnly;
+
+ DevPrint("\nClient: ");
+ TalkPort = SepClientOpenPipe();
+
+ return;
+}
+
+
+VOID
+SepClientMakeRemoteCall( VOID )
+
+{
+
+ DevPrint("\nClient: ");
+ SepTransceivePipe( "Make Client Call\n" );
+
+ RequestCount += 1;
+
+ return;
+}
+
+
+VOID
+SepClientDropConnection( VOID )
+
+{
+
+ Status = NtClose( TalkPort ); SEASSERT_SUCCESS(Status);
+
+ return;
+
+}
+
+
+BOOLEAN
+SepClientTestStatic(VOID)
+
+{
+
+ BOOLEAN CompletionStatus;
+
+ //
+ // Static Context Tracking ... Suite
+ //
+
+ CompletionStatus = SepClientTestEffectiveOnly( TRUE );
+
+
+ if (CompletionStatus == TRUE) {
+
+ CompletionStatus = SepClientTestNotEffectiveOnly( TRUE );
+ }
+
+ return CompletionStatus;
+
+}
+
+
+BOOLEAN
+SepClientTestDynamic(VOID)
+
+{
+ BOOLEAN CompletionStatus;
+
+ //
+ // Dynamic Context Tracking ... Suite
+ //
+
+ CompletionStatus = SepClientTestEffectiveOnly( FALSE );
+
+
+ if (CompletionStatus == TRUE) {
+
+ CompletionStatus = SepClientTestNotEffectiveOnly( FALSE );
+ }
+
+ return CompletionStatus;
+
+}
+
+
+BOOLEAN
+SepClientTestEffectiveOnly(
+ BOOLEAN StaticTest
+ )
+
+
+{
+
+ BOOLEAN CompletionStatus;
+
+ //
+ // Effective Only ... Test
+ //
+
+ CompletionStatus = SepClientTestAnonymous( StaticTest, TRUE );
+ if (CompletionStatus == TRUE) {
+ CompletionStatus = SepClientTestIdentification( StaticTest, TRUE );
+ }
+ if (CompletionStatus == TRUE) {
+ CompletionStatus = SepClientTestImpersonation( StaticTest, TRUE );
+ }
+
+ return CompletionStatus;
+
+}
+
+
+BOOLEAN
+SepClientTestNotEffectiveOnly(
+ BOOLEAN StaticTest
+ )
+
+{
+ BOOLEAN CompletionStatus;
+
+ //
+ // Not Effective Only ... Test
+ //
+
+ CompletionStatus = SepClientTestAnonymous( StaticTest, FALSE );
+ if (CompletionStatus == TRUE) {
+ CompletionStatus = SepClientTestIdentification( StaticTest, FALSE );
+ }
+ if (CompletionStatus == TRUE) {
+ CompletionStatus = SepClientTestImpersonation( StaticTest, FALSE );
+ }
+
+ return CompletionStatus;
+
+}
+
+
+BOOLEAN
+SepClientTestAnonymous(
+ BOOLEAN StaticTest,
+ BOOLEAN EffectiveOnly
+ )
+
+{
+
+ //////////////////////////////////////////////////////////////////////////
+ // //
+ // Anonymous Use Test //
+ // //
+ //////////////////////////////////////////////////////////////////////////
+
+ SECURITY_CONTEXT_TRACKING_MODE TrackingMode;
+
+ if (StaticTest) {
+ TrackingMode = SECURITY_STATIC_TRACKING;
+ } else {
+ TrackingMode = SECURITY_DYNAMIC_TRACKING;
+ }
+
+ if (!StaticTest) {
+ //
+ // No action for dynamic test
+ //
+ return TRUE;
+ }
+
+ //
+ // Anonymous Use ... Test
+ //
+
+
+ SepClientConnect(
+ SecurityAnonymous,
+ TrackingMode,
+ EffectiveOnly
+ );
+
+ SepClientMakeRemoteCall();
+
+ SepClientDropConnection();
+
+
+ return TRUE;
+}
+
+
+BOOLEAN
+SepClientTestIdentification(
+ BOOLEAN StaticTest,
+ BOOLEAN EffectiveOnly
+ )
+
+{
+
+ //////////////////////////////////////////////////////////////////////////
+ // //
+ // Identification Use Test //
+ // //
+ //////////////////////////////////////////////////////////////////////////
+
+ SECURITY_CONTEXT_TRACKING_MODE TrackingMode;
+
+ if (StaticTest) {
+ TrackingMode = SECURITY_STATIC_TRACKING;
+ } else {
+ TrackingMode = SECURITY_DYNAMIC_TRACKING;
+ }
+
+ //
+ // Identification Use ... Test
+ //
+
+
+ SepClientConnect(
+ SecurityIdentification,
+ TrackingMode,
+ EffectiveOnly
+ );
+
+ SepClientMakeRemoteCall();
+
+ SepClientDropConnection();
+
+
+ return TRUE;
+
+}
+
+
+BOOLEAN
+SepClientTestImpersonation(
+ BOOLEAN StaticTest,
+ BOOLEAN EffectiveOnly
+ )
+
+{
+
+ //////////////////////////////////////////////////////////////////////////
+ // //
+ // Impersonation Use Test //
+ // //
+ //////////////////////////////////////////////////////////////////////////
+
+ SECURITY_CONTEXT_TRACKING_MODE TrackingMode;
+
+ if (StaticTest) {
+ TrackingMode = SECURITY_STATIC_TRACKING;
+ } else {
+ TrackingMode = SECURITY_DYNAMIC_TRACKING;
+ }
+
+
+ //
+ // Impersonation Use ... Test
+ //
+
+
+ SepClientConnect(
+ SecurityImpersonation,
+ TrackingMode,
+ EffectiveOnly
+ );
+
+ SepClientMakeRemoteCall();
+
+ SepClientDropConnection();
+
+
+
+ return TRUE;
+
+}
+
+
+
+
+BOOLEAN
+SepClientTest(VOID)
+//
+// Tests:
+//
+// Static Context Tracking Tests
+// Effective Only
+// Anonymous
+// Identification
+// Impersonation
+// Not Effective Only
+// Anonymous
+// Identification
+// Impersonation
+//
+// Dynamic Context Tracking Tests
+// Effective Only
+// Identification
+// Impersonation
+// Not Effective Only
+// Identification
+// Impersonation
+//
+{
+
+ BOOLEAN CompletionStatus;
+
+
+
+
+ //
+ // Run the static test suite...
+ //
+
+ CompletionStatus = SepClientTestStatic();
+
+ //
+ // Run the dynamic test suite...
+ //
+
+ if (CompletionStatus == TRUE) {
+ CompletionStatus = SepClientTestDynamic();
+ }
+
+ DbgPrint("Se: Client Test Complete.\n");
+
+
+ return CompletionStatus;
+}
+
+
+NTSTATUS
+SepClientInitialize(
+ )
+
+{
+
+
+
+ DbgPrint("Se: Client Initializing ...\n");
+
+
+ RequestCount = 0;
+
+
+ //
+ // Signal the named event to start the test
+ //
+
+ DbgPrint("Se: Client Starting Test ...\n");
+ Status = NtSetEvent( EventHandle, NULL ); SEASSERT_SUCCESS(Status);
+
+ Status = NtClose( EventHandle ); SEASSERT_SUCCESS(Status);
+
+
+ return STATUS_SUCCESS;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// //
+// Server-Side Test Routines //
+// //
+//////////////////////////////////////////////////////////////////////////////
+
+
+VOID
+SepServerWaitForNextConnect( VOID )
+{
+
+ DevPrint("\nServer: ");
+ SepServerListenPipe();
+
+ Status = NtDuplicateObject(
+ NtCurrentProcess(), // SourceProcessHandle
+ EarPort, // SourceHandle
+ NtCurrentProcess(), // TargetProcessHandle
+ &TalkPort, // TargetHandle
+ 0, // DesiredAccess (over-ridden by option)
+ 0, // HandleAttributes
+ DUPLICATE_SAME_ACCESS // Options
+ );
+ ASSERT(NT_SUCCESS(Status));
+
+
+ return;
+
+}
+
+VOID
+SepServerGetNextMessage( VOID )
+
+{
+
+
+
+ DevPrint("\nServer: ");
+ SepReadPipe();
+
+ RequestCount += 1;
+
+ return;
+}
+
+VOID
+SepServerCompleteMessage( VOID )
+
+{
+
+ DevPrint("\nServer: ");
+ SepWritePipe("Return From Server\n");
+ return;
+}
+
+VOID
+SepServerImpersonateClient( VOID )
+
+{
+
+ DevPrint("\nServer: ");
+ SepServerImpersonatePipe( );
+
+}
+
+
+VOID
+SepServerRevertToSelf( VOID )
+
+{
+ NTSTATUS TmpStatus;
+ HANDLE NullHandle;
+
+ NullHandle = NULL;
+ TmpStatus = NtSetInformationThread(
+ SepServerThread,
+ ThreadImpersonationToken,
+ (PVOID)&NullHandle,
+ (ULONG)sizeof(HANDLE)
+ ); SEASSERT_SUCCESS(TmpStatus);
+
+}
+
+
+VOID
+SepServerDropConnection( VOID )
+
+{
+ DevPrint("\nServer: ");
+ SepServerDisconnectPipe();
+
+ return;
+}
+
+BOOLEAN
+SepServerTestStatic(VOID)
+
+{
+ BOOLEAN CompletionStatus;
+
+ DbgPrint("Se: Static Context Tracking ... Suite\n");
+
+ CompletionStatus = SepServerTestEffectiveOnly( TRUE );
+
+
+ if (CompletionStatus == TRUE) {
+
+ CompletionStatus = SepServerTestNotEffectiveOnly( TRUE );
+ }
+
+ return CompletionStatus;
+
+}
+
+
+BOOLEAN
+SepServerTestDynamic(VOID)
+
+{
+ BOOLEAN CompletionStatus;
+
+ DbgPrint("Se: Dynamic Context Tracking ... Suite\n");
+
+ CompletionStatus = SepServerTestEffectiveOnly( FALSE );
+
+
+ if (CompletionStatus == TRUE) {
+
+ CompletionStatus = SepServerTestNotEffectiveOnly( FALSE );
+ }
+
+ return CompletionStatus;
+
+}
+
+
+BOOLEAN
+SepServerTestEffectiveOnly(
+ BOOLEAN StaticTest
+ )
+
+{
+
+ BOOLEAN CompletionStatus;
+
+ DbgPrint("Se: Effective Only ... Test\n");
+
+ CompletionStatus = SepServerTestAnonymous( StaticTest, TRUE );
+ if (CompletionStatus == TRUE) {
+ CompletionStatus = SepServerTestIdentification( StaticTest, TRUE );
+ }
+ if (CompletionStatus == TRUE) {
+ CompletionStatus = SepServerTestImpersonation( StaticTest, TRUE );
+ }
+
+ return CompletionStatus;
+
+}
+
+
+BOOLEAN
+SepServerTestNotEffectiveOnly(
+ BOOLEAN StaticTest
+ )
+
+{
+
+ BOOLEAN CompletionStatus;
+
+ DbgPrint("Se: Not Effective Only ... Test\n");
+
+ CompletionStatus = SepServerTestAnonymous( StaticTest, FALSE );
+ if (CompletionStatus == TRUE) {
+ CompletionStatus = SepServerTestIdentification( StaticTest, FALSE );
+ }
+ if (CompletionStatus == TRUE) {
+ CompletionStatus = SepServerTestImpersonation( StaticTest, FALSE );
+ }
+
+ return CompletionStatus;
+
+}
+
+
+BOOLEAN
+SepServerTestAnonymous(
+ BOOLEAN StaticTest,
+ BOOLEAN EffectiveOnly
+ )
+
+{
+ BOOLEAN CompletionStatus = TRUE;
+
+ //////////////////////////////////////////////////////////////////////////
+ // //
+ // Anonymous Use Test //
+ // //
+ //////////////////////////////////////////////////////////////////////////
+
+
+ if (!StaticTest) {
+ //
+ // No action for dynamic test
+ //
+
+ return TRUE;
+ }
+
+ DbgPrint("Se: Anonymous Use ... ");
+
+ SepServerWaitForNextConnect();
+
+ SepServerGetNextMessage();
+
+
+ SepServerImpersonateClient();
+ Status = NtOpenThreadToken(
+ SepServerThread,
+ TOKEN_ALL_ACCESS,
+ TRUE,
+ &ClientToken
+ );
+ SepServerRevertToSelf();
+ if (Status == STATUS_CANT_OPEN_ANONYMOUS) {
+
+ DbgPrint(" Succeeded\n");
+
+ } else {
+ DbgPrint("* ! FAILED (srvr) ! *\n");
+ DbgPrint("Status is: 0x%lx \n", Status );
+ CompletionStatus = FALSE;
+ }
+
+
+ SepServerCompleteMessage();
+
+ SepServerDropConnection();
+
+ //
+ // Appease the compiler Gods..
+ //
+
+ if (EffectiveOnly) {;}
+
+
+ return CompletionStatus;
+
+}
+
+
+BOOLEAN
+SepServerTestIdentification(
+ BOOLEAN StaticTest,
+ BOOLEAN EffectiveOnly
+ )
+
+{
+
+ BOOLEAN CompletionStatus = TRUE;
+ //////////////////////////////////////////////////////////////////////////
+ // //
+ // Identification Use Test //
+ // //
+ //////////////////////////////////////////////////////////////////////////
+
+ DbgPrint("Se: Identification Use ... ");
+
+ SepServerWaitForNextConnect();
+
+ SepServerGetNextMessage();
+
+ SepServerImpersonateClient();
+ Status = NtOpenThreadToken(
+ SepServerThread,
+ TOKEN_ALL_ACCESS,
+ TRUE,
+ &ClientToken
+ ); SEASSERT_SUCCESS(Status);
+ SepServerRevertToSelf();
+ Status = NtQueryInformationToken(
+ ClientToken,
+ TokenStatistics,
+ &ClientTokenStatistics,
+ (ULONG)sizeof(TOKEN_STATISTICS),
+ &IgnoreLength
+ ); SEASSERT_SUCCESS(Status);
+
+ if ( (ClientTokenStatistics.TokenType == TokenImpersonation) &&
+ (ClientTokenStatistics.ImpersonationLevel == SecurityIdentification)
+ ) {
+ DbgPrint(" Succeeded\n");
+
+ } else {
+ DbgPrint("* ! FAILED (srvr) ! *\n");
+ CompletionStatus = FALSE;
+ }
+
+
+ SepServerCompleteMessage();
+
+ SepServerDropConnection();
+
+ //
+ // Appease the compiler Gods..
+ //
+ if (StaticTest) {;}
+ if (EffectiveOnly) {;}
+
+ return CompletionStatus;
+}
+
+
+BOOLEAN
+SepServerTestImpersonation(
+ BOOLEAN StaticTest,
+ BOOLEAN EffectiveOnly
+ )
+
+{
+ BOOLEAN CompletionStatus = TRUE;
+
+ //////////////////////////////////////////////////////////////////////////
+ // //
+ // Impersonation Use Test //
+ // //
+ //////////////////////////////////////////////////////////////////////////
+
+ DbgPrint("Se: Impersonation Use ... ");
+
+
+ SepServerWaitForNextConnect();
+
+ SepServerGetNextMessage();
+
+
+
+ SepServerImpersonateClient();
+ Status = NtOpenThreadToken(
+ SepServerThread,
+ TOKEN_ALL_ACCESS,
+ TRUE,
+ &ClientToken
+ ); SEASSERT_SUCCESS(Status);
+ SepServerRevertToSelf();
+ Status = NtQueryInformationToken(
+ ClientToken,
+ TokenStatistics,
+ &ClientTokenStatistics,
+ (ULONG)sizeof(TOKEN_STATISTICS),
+ &IgnoreLength
+ ); SEASSERT_SUCCESS(Status);
+
+ if ( (ClientTokenStatistics.TokenType == TokenImpersonation) &&
+ (ClientTokenStatistics.ImpersonationLevel == SecurityImpersonation)
+ ) {
+ DbgPrint(" Succeeded\n");
+
+ } else {
+ DbgPrint("* ! FAILED (srvr) ! *\n");
+ CompletionStatus = FALSE;
+ }
+
+
+
+
+ SepServerCompleteMessage();
+
+ SepServerDropConnection();
+
+ //
+ // Appease the compiler gods
+ //
+ if (StaticTest) {;}
+ if (EffectiveOnly) {;}
+
+ return CompletionStatus;
+}
+
+
+BOOLEAN
+SepServerTest(VOID)
+//
+// Tests:
+//
+// Static Context Tracking Tests
+// Effective Only
+// Anonymous
+// Identification
+// Impersonation
+// Not Effective Only
+// Anonymous
+// Identification
+// Impersonation
+//
+// Dynamic Context Tracking Tests
+// Effective Only
+// Identification
+// Impersonation
+// Not Effective Only
+// Identification
+// Impersonation
+//
+{
+
+ BOOLEAN CompletionStatus;
+
+
+ DbgPrint("Se: Server Starting Test ...\n");
+
+ //
+ // Run the static test suite...
+ //
+
+ CompletionStatus = SepServerTestStatic();
+
+ //
+ // Run the dynamic test suite...
+ //
+
+ if (CompletionStatus == TRUE) {
+ CompletionStatus = SepServerTestDynamic();
+ }
+
+ DbgPrint("Se: Server Test Complete.\n");
+
+ //
+ // Print test results
+ //
+
+ DbgPrint("\n");
+ DbgPrint("\n");
+ DbgPrint("**********************\n");
+ DbgPrint("** **\n");
+
+ if (CompletionStatus == TRUE) {
+ DbgPrint("** Test Succeeded **\n");
+ } else {
+ DbgPrint("** Test Failed !! **\n");
+ }
+
+ DbgPrint("** **\n");
+ DbgPrint("**********************\n");
+
+ return CompletionStatus;
+
+}
+
+NTSTATUS
+SepServerInitialize(
+ )
+
+{
+
+ OBJECT_ATTRIBUTES ThreadAttributes;
+ PTEB CurrentTeb;
+
+
+ DbgPrint("Se: Server Initializing ...\n");
+
+ //
+ // Initialize global variables
+ //
+
+ RequestCount = 0;
+
+ //
+ // Get a handle to our thread to so that we can access our thread
+ // even when impersonating an anonymous client (which we can't do
+ // using NtCurrentThread()).
+ //
+
+ CurrentTeb = NtCurrentTeb();
+ InitializeObjectAttributes(&ThreadAttributes, NULL, 0, NULL, NULL);
+ Status = NtOpenThread(
+ &SepServerThread, // TargetHandle
+ THREAD_ALL_ACCESS, // DesiredAccess
+ &ThreadAttributes, // ObjectAttributes
+ &CurrentTeb->ClientId // ClientId
+ );
+ ASSERT( NT_SUCCESS(Status) );
+
+
+ //
+ // Create the server's port
+ //
+
+ EarPort = SepServerCreatePipe();
+
+
+
+ //
+ // Spawn a copy of ourselves...
+ //
+
+ DbgPrint("Se: Server Spawning client process ...\n");
+ SepServerSpawnClientProcess();
+
+
+ DbgPrint("Se: Server waiting for start of test signal ...\n");
+
+ Status = NtWaitForSingleObject(
+ EventHandle,
+ TRUE,
+ NULL
+ ); SEASSERT_SUCCESS(Status);
+
+ Status = NtClose( EventHandle ); SEASSERT_SUCCESS(Status);
+
+
+ return STATUS_SUCCESS;
+}
+
+VOID
+SepServerSpawnClientProcess(VOID)
+
+{
+
+ RTL_USER_PROCESS_INFORMATION ProcessInformation;
+ STRING ProgramName;
+ UNICODE_STRING UnicodeProgramName;
+ STRING ImagePathName;
+ UNICODE_STRING UnicodeImagePathName;
+ PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
+
+ RtlInitString( &ProgramName, "\\SystemRoot\\Bin\\utlnpqos.exe" );
+ Status = RtlAnsiStringToUnicodeString(
+ &UnicodeProgramName,
+ &ProgramName,
+ TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
+ RtlInitString( &ImagePathName, "utlnpqos.exe");
+ Status = RtlAnsiStringToUnicodeString(
+ &UnicodeImagePathName,
+ &ImagePathName,
+ TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
+
+
+ Status = RtlCreateProcessParameters(
+ &ProcessParameters,
+ &ImagePathName, // FIX, FIX &UnicodeImagePathName, (when converted to unicode)
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ );
+
+ SEASSERT_SUCCESS(Status);
+ RtlFreeUnicodeString( &UnicodeImagePathName );
+
+
+ Status = RtlCreateUserProcess(
+ &ProgramName, // FIX, FIX &UnicodeProgramName (when converted to unicode)
+ ProcessParameters, // ProcessParameters
+ NULL, // ProcessSecurityDescriptor
+ NULL, // ThreadSecurityDescriptor
+ NtCurrentProcess(), // ParentProcess
+ FALSE, // InheritHandles
+ NULL, // DebugPort
+ NULL, // ExceptionPort
+ &ProcessInformation // ProcessInformation
+ ); SEASSERT_SUCCESS(Status);
+ RtlFreeUnicodeString( &UnicodeProgramName );
+
+ Status = NtResumeThread(
+ ProcessInformation.Thread,
+ NULL
+ ); SEASSERT_SUCCESS(Status);
+
+ RtlDestroyProcessParameters( ProcessParameters );
+
+}
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// //
+// Main Program Entry Routine //
+// //
+//////////////////////////////////////////////////////////////////////////////
+
+BOOLEAN
+CtLnpQos (VOID)
+{
+
+ BOOLEAN Result = TRUE;
+
+ RtlInitString( &PortName, "\\Device\\NamedPipe\\TestLnpQosServerPort" );
+ Status = RtlAnsiStringToUnicodeString(
+ &UnicodePortName,
+ &PortName,
+ TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
+
+ RtlInitString( &RelativePortName, "TestLnpQosServerPort" );
+ Status = RtlAnsiStringToUnicodeString(
+ &UnicodeRelativePortName,
+ &RelativePortName,
+ TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
+
+
+ //
+ // Determine whether we are the client or server side of the test.
+ // This is done by creating or opening a named event object. If the
+ // event does not yet exist, then we are the client, and must create
+ // the server process. Otherwise, we are the server and the client
+ // is waiting for us to signal the event.
+ //
+
+ RtlInitString( &EventName, "\\TestLnpQosEvent" );
+ Status = RtlAnsiStringToUnicodeString(
+ &UnicodeEventName,
+ &EventName,
+ TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
+
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &UnicodeEventName,
+ OBJ_OPENIF,
+ NULL,
+ NULL
+ );
+ Status = NtCreateEvent(
+ &EventHandle,
+ EVENT_ALL_ACCESS,
+ &ObjectAttributes,
+ SynchronizationEvent,
+ FALSE
+ );
+ RtlFreeUnicodeString( &UnicodeEventName );
+
+ if (Status == STATUS_OBJECT_NAME_EXISTS) {
+
+ //
+ // Server is already running, therefore, this process gets to be
+ // the client.
+ //
+
+ Status = SepClientInitialize(); SEASSERT_SUCCESS(Status);
+ Result = SepClientTest();
+
+ } else {
+
+ SEASSERT_SUCCESS(Status);
+
+ //
+ // Event wasn't yet there, so we must be the server.
+ //
+
+ DbgPrint("Se: Starting Local Named Pipe Impersonation Test.\n");
+
+ Status = SepServerInitialize(); SEASSERT_SUCCESS(Status);
+ Result = SepServerTest();
+
+ DbgPrint("Se: End Test.\n");
+
+ }
+
+
+
+ Status = NtTerminateThread( NtCurrentThread(), STATUS_SUCCESS);
+ SEASSERT_SUCCESS(Status);
+
+ return Result;
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// //
+// Named Pipe Common Operations //
+// //
+//////////////////////////////////////////////////////////////////////////////
+
+
+VOID
+SepReadPipe(
+ )
+{
+ IO_STATUS_BLOCK Iosb;
+ UCHAR Buffer[512];
+
+ DevPrint("ReadPipe...\n", 0);
+
+ if (!NT_SUCCESS(Status = NtReadFile( TalkPort,
+ (HANDLE)NULL,
+ (PIO_APC_ROUTINE)NULL,
+ (PVOID)NULL,
+ &Iosb,
+ Buffer,
+ 512,
+ (PLARGE_INTEGER)NULL,
+ (PULONG) NULL ))) {
+ Error( NtReadFile, Status );
+ }
+
+ if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) {
+
+ Error( NtWaitForSingleObject, Status );
+ }
+
+ if (!NT_SUCCESS(Iosb.Status)) {
+
+ Error( NtReadFileFinalStatus, Iosb.Status );
+ }
+
+ return;
+}
+
+
+VOID
+SepWritePipe(
+ PSZ String
+ )
+{
+ NTSTATUS Status;
+ IO_STATUS_BLOCK Iosb;
+
+
+ DevPrint("WritePipe...\n", 0);
+
+ if (!NT_SUCCESS(Status = NtWriteFile( TalkPort,
+ (HANDLE)NULL,
+ (PIO_APC_ROUTINE)NULL,
+ (PVOID)NULL,
+ &Iosb,
+ String,
+ strlen( String ),
+ (PLARGE_INTEGER)NULL,
+ (PULONG)NULL ))) {
+ Error( NtWriteFile, Status );
+ }
+
+ if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) {
+
+ Error( NtWaitForSingleObject, Status );
+ }
+
+ if (!NT_SUCCESS(Iosb.Status)) {
+
+ Error( NtWriteFileFinalStatus, Iosb.Status );
+ }
+
+ return;
+}
+
+
+VOID
+SepTransceivePipe(
+ PSZ String
+ )
+{
+ NTSTATUS Status;
+ IO_STATUS_BLOCK Iosb;
+ UCHAR Buffer[512];
+
+
+ DevPrint("TransceivePipe...\n", 0);
+
+ if (!NT_SUCCESS(Status = NtFsControlFile(
+ TalkPort,
+ NULL, // Event
+ NULL, // ApcRoutine
+ NULL, // ApcContext
+ &Iosb,
+ FSCTL_PIPE_TRANSCEIVE,
+ String,
+ strlen( String ),
+ Buffer,
+ 511
+ ))) {
+ Error( NtTransceiveFile, Status );
+ }
+
+ if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) {
+
+ Error( NtWaitForSingleObject, Status );
+ }
+
+ if (!NT_SUCCESS(Iosb.Status)) {
+
+ Error( NtTransceiveFileFinalStatus, Iosb.Status );
+ }
+
+ return;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// //
+// Named Pipe Server Operations //
+// //
+//////////////////////////////////////////////////////////////////////////////
+
+HANDLE
+SepServerCreatePipe(
+ VOID
+ )
+{
+ HANDLE PipeHandle;
+ NTSTATUS Status;
+ IO_STATUS_BLOCK Iosb;
+ LARGE_INTEGER Timeout;
+ READ_MODE Mode;
+ ULONG Share;
+ NAMED_PIPE_CONFIGURATION Config = FILE_PIPE_FULL_DUPLEX;
+ NAMED_PIPE_TYPE PipeType = FILE_PIPE_MESSAGE_TYPE;
+ COMPLETION_MODE CompletionMode = FILE_PIPE_QUEUE_OPERATION;
+ ULONG MaximumInstances = 4;
+
+
+ //
+ // Set the default timeout to 60 seconds, and initalize the attributes
+ //
+
+ Timeout.QuadPart = -10 * 1000 * 1000 * 60;
+
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &UnicodePortName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL
+ );
+
+ //
+ // Calculate the readmode and share access
+ //
+
+ Mode = (PipeType == FILE_PIPE_MESSAGE_TYPE ? FILE_PIPE_MESSAGE_MODE :
+ FILE_PIPE_BYTE_STREAM_MODE);
+
+ Share = (Config == FILE_PIPE_INBOUND ? FILE_SHARE_WRITE :
+ (Config == FILE_PIPE_OUTBOUND ? FILE_SHARE_READ :
+ FILE_SHARE_READ | FILE_SHARE_WRITE));
+
+ if (!NT_SUCCESS(Status = NtCreateNamedPipeFile(
+ &PipeHandle,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
+ &ObjectAttributes,
+ &Iosb,
+ Share,
+ FILE_CREATE,
+ 0,
+ PipeType,
+ Mode,
+ CompletionMode,
+ MaximumInstances,
+ 1024,
+ 1024,
+ (PLARGE_INTEGER)&Timeout ))) {
+
+ Error( CreatePipe, Status );
+ }
+ RtlFreeUnicodeString( &UnicodePortName );
+
+ return PipeHandle;
+}
+
+
+VOID
+SepServerListenPipe(
+ )
+{
+ NTSTATUS Status;
+ IO_STATUS_BLOCK Iosb;
+
+ DevPrint("ListenPipe...\n", 0);
+
+ if (!NT_SUCCESS(Status = NtFsControlFile(
+ EarPort,
+ NULL, // Event
+ NULL, // ApcRoutine
+ NULL, // ApcContext
+ &Iosb,
+ FSCTL_PIPE_LISTEN,
+ NULL, // InputBuffer
+ 0, // InputBufferLength,
+ NULL, // OutputBuffer
+ 0 // OutputBufferLength
+ ))) {
+
+ Error( ListenPipe, Status );
+ }
+ if (!NT_SUCCESS(Status = NtWaitForSingleObject( EarPort, TRUE, NULL ))) {
+
+ Error( NtWaitForSingleObject, Status );
+ }
+
+ if (!NT_SUCCESS(Iosb.Status)) {
+
+ Error( ListenPipeFinalStatus, Iosb.Status );
+ }
+
+
+ return;
+}
+
+
+VOID
+SepServerImpersonatePipe(
+ )
+{
+ NTSTATUS Status;
+ IO_STATUS_BLOCK Iosb;
+
+ DevPrint("ImpersonatePipe...\n", 0);
+
+ if (!NT_SUCCESS(Status = NtFsControlFile(
+ TalkPort,
+ NULL, // Event
+ NULL, // ApcRoutine
+ NULL, // ApcContext
+ &Iosb,
+ FSCTL_PIPE_IMPERSONATE,
+ NULL, // InputBuffer
+ 0, // InputBufferLength,
+ NULL, // OutputBuffer
+ 0 // OutputBufferLength
+ ))) {
+
+ Error( ImpersonatePipe, Status );
+ }
+ if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) {
+
+ Error( NtWaitForSingleObject, Status );
+ }
+
+ if (!NT_SUCCESS(Iosb.Status)) {
+
+ Error( ImpersonatePipeFinalStatus, Iosb.Status );
+ }
+
+ return;
+}
+
+
+VOID
+SepServerDisconnectPipe(
+ )
+{
+ NTSTATUS Status;
+ IO_STATUS_BLOCK Iosb;
+
+ DevPrint("DisconnectPipe...\n", 0);
+ DevPrint(" (Flush)...\n", 0);
+
+ if (!NT_SUCCESS(Status = NtFlushBuffersFile(
+ TalkPort,
+ &Iosb
+ ))) {
+ Error( DisconnectPipe, Status );
+ }
+
+ if (!NT_SUCCESS(Iosb.Status)) {
+
+ Error( FlushPipeFinalStatus, Iosb.Status );
+ }
+
+
+ DevPrint(" (Close Talk Port)...\n", 0);
+ Status = NtClose( TalkPort ); SEASSERT_SUCCESS(Status);
+
+ DevPrint(" (Disconnect)...\n", 0);
+ if (!NT_SUCCESS(Status = NtFsControlFile(
+ EarPort,
+ NULL, // Event
+ NULL, // ApcRoutine
+ NULL, // ApcContext
+ &Iosb,
+ FSCTL_PIPE_DISCONNECT,
+ NULL, // InputBuffer
+ 0, // InputBufferLength,
+ NULL, // OutputBuffer
+ 0 // OutputBufferLength
+ ))) {
+
+ Error( DisconnectPipe, Status );
+ }
+ if (!NT_SUCCESS(Status = NtWaitForSingleObject( EarPort, TRUE, NULL ))) {
+
+ Error( NtWaitForSingleObject, Status );
+ }
+
+ if (!NT_SUCCESS(Iosb.Status)) {
+
+ Error( DisconnectPipeFinalStatus, Iosb.Status );
+ }
+
+ return;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// //
+// Named Pipe Client Operations //
+// //
+//////////////////////////////////////////////////////////////////////////////
+
+HANDLE
+SepClientOpenPipe(
+ VOID
+ )
+{
+ HANDLE PipeHandle, NpfsHandle;
+ NTSTATUS Status;
+ IO_STATUS_BLOCK Iosb;
+ ULONG Share;
+ STRING Npfs;
+ UNICODE_STRING UnicodeNpfs;
+ PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
+ ULONG WaitPipeLength;
+ NAMED_PIPE_CONFIGURATION Config = FILE_PIPE_FULL_DUPLEX;
+ READ_MODE ReadMode = FILE_PIPE_MESSAGE_MODE;
+ COMPLETION_MODE CompletionMode = FILE_PIPE_QUEUE_OPERATION;
+
+
+//#ifdef NOT_YET_WORKING
+ //
+ // Wait for the server's pipe to reach a listen state...
+ //
+
+ RtlInitString( &Npfs, "\\Device\\NamedPipe\\");
+ Status = RtlAnsiStringToUnicodeString(
+ &UnicodeNpfs,
+ &Npfs,
+ TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
+
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &UnicodeNpfs,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ if (!NT_SUCCESS(Status = NtOpenFile(
+ &NpfsHandle,
+ GENERIC_READ | SYNCHRONIZE,
+ &ObjectAttributes,
+ &Iosb,
+ FILE_SHARE_READ,
+ 0 ))) {
+
+ Error( OpenNpfs, Status );
+ }
+ RtlFreeUnicodeString( &UnicodeNpfs );
+
+ WaitPipeLength =
+ FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER, Name[0]) +
+ RelativePortName.MaximumLength; //UNICODEFIX UnicodeRelativePortName.MaximumLength;
+ WaitPipe = RtlAllocateHeap(RtlProcessHeap(), 0, WaitPipeLength);
+ WaitPipe->TimeoutSpecified = FALSE;
+
+ WaitPipe->NameLength = RelativePortName.Length; //UNICODEFIX UnicodeRelativePortName.Length;
+ strcpy(WaitPipe->Name, RelativePortName.Buffer); //UNICODEFIX UnicodePortName.Buffer;
+
+ if (!NT_SUCCESS(Status = NtFsControlFile(
+ NpfsHandle,
+ NULL, // Event
+ NULL, // ApcRoutine
+ NULL, // ApcContext
+ &Iosb,
+ FSCTL_PIPE_WAIT,
+ WaitPipe, // Buffer for data to the FS
+ WaitPipeLength,
+ NULL, // OutputBuffer
+ 0 // OutputBufferLength
+ ))) {
+
+ Error( ClientWaitPipe, Status );
+ }
+ if (Status == STATUS_PENDING) {
+ if (!NT_SUCCESS(Status = NtWaitForSingleObject( NpfsHandle, TRUE, NULL ))) {
+
+ Error( NtWaitForSingleObject, Status );
+ }
+ }
+
+ if (!NT_SUCCESS(Iosb.Status)) {
+
+ Error( ClientWaitPipeFinalStatus, Iosb.Status );
+ }
+
+ Status = NtClose( NpfsHandle );
+ ASSERT(NT_SUCCESS(Status));
+//#endif // NOT_YET_WORKING
+// Delay(1);
+
+
+ //
+ // Initialize the attributes
+ //
+
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &UnicodePortName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL
+ );
+ ObjectAttributes.SecurityQualityOfService = (PVOID)(&SecurityQos);
+
+ //
+ // Calculate the share access
+ //
+
+ Share = (Config == FILE_PIPE_INBOUND ? FILE_SHARE_WRITE :
+ (Config == FILE_PIPE_OUTBOUND ? FILE_SHARE_READ :
+ FILE_SHARE_READ | FILE_SHARE_WRITE));
+
+
+
+ //
+ // And now open it...
+ //
+
+ if (!NT_SUCCESS(Status = NtOpenFile(
+ &PipeHandle,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
+ &ObjectAttributes,
+ &Iosb,
+ Share,
+ 0 ))) {
+
+ Error( OpenPipe, Status );
+ }
+
+ if ((ReadMode != FILE_PIPE_BYTE_STREAM_MODE) ||
+ (CompletionMode != FILE_PIPE_QUEUE_OPERATION)) {
+
+ FILE_PIPE_INFORMATION Buffer;
+
+ Buffer.ReadMode = ReadMode;
+ Buffer.CompletionMode = CompletionMode;
+
+ if (!NT_SUCCESS(Status = NtSetInformationFile(
+ PipeHandle,
+ &Iosb,
+ &Buffer,
+ sizeof(FILE_PIPE_INFORMATION),
+ FilePipeInformation ))) {
+
+ Error( NtSetInformationFile, Status );
+ }
+ }
+
+ return PipeHandle;
+}