Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

580 lines
16 KiB

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
srvinit.c
Abstract:
This is the main initialization module for the Server side of the Client
Server Runtime Subsystem (CSRSS)
Author:
Steve Wood (stevewo) 08-Oct-1990
Environment:
User Mode Only
Revision History:
--*/
#include "csrsrv.h"
PCSR_API_ROUTINE CsrServerApiDispatchTable[ CsrpMaxApiNumber ] = {
(PCSR_API_ROUTINE)CsrSrvNullApiCall,
(PCSR_API_ROUTINE)CsrSrvClientConnect,
(PCSR_API_ROUTINE)NULL,
(PCSR_API_ROUTINE)CsrSrvProfileControl,
(PCSR_API_ROUTINE)CsrSrvIdentifyAlertableThread,
(PCSR_API_ROUTINE)CsrSrvSetPriorityClass
};
BOOLEAN CsrServerApiServerValidTable[ CsrpMaxApiNumber ] = {
TRUE, // CsrSrvNullApiCall,
TRUE, // CsrSrvClientConnect,
FALSE, // CsrSrvThreadConnect,
TRUE, // CsrSrvProfileControl,
TRUE, // CsrSrvIdentifyAlertableThread
TRUE // CsrSrvSetPriorityClass
};
#if DBG
PSZ CsrServerApiNameTable[ CsrpMaxApiNumber ] = {
"NullApiCall",
"ClientConnect",
"ThreadConnect",
"ProfileControl",
"IdentifyAlertableThread",
"SetPriorityClass"
};
#endif // DBG
NTSTATUS
CsrSetProcessSecurity(
VOID
);
NTSTATUS
CsrServerInitialization(
IN ULONG argc,
IN PCH argv[]
)
{
NTSTATUS Status;
ULONG i;
PVOID ProcessDataPtr;
PTEB Teb;
PCSR_SERVER_DLL LoadedServerDll;
// Initialize GDI accelerators. This thread ends up in GDI doing graphics,
// courtesy of USER! (Also see SRVQUICK.C, APIREQST.C)
Teb = NtCurrentTeb();
Teb->GdiClientPID = PID_SERVERLPC;
Teb->GdiClientTID = (ULONG) Teb->ClientId.UniqueThread;
Status = NtCreateEvent(&CsrInitializationEvent,
EVENT_ALL_ACCESS,
NULL,
SynchronizationEvent,
FALSE
);
ASSERT( NT_SUCCESS( Status ) );
//
// Save away system information in a global variable
//
Status = NtQuerySystemInformation( SystemBasicInformation,
&CsrNtSysInfo,
sizeof( CsrNtSysInfo ),
NULL
);
ASSERT( NT_SUCCESS( Status ) );
//
// Use the process heap for memory allocation.
//
CsrHeap = RtlProcessHeap();
CsrBaseTag = RtlCreateTagHeap( CsrHeap,
0,
L"CSRSS!",
L"TMP\0"
L"INIT\0"
L"CAPTURE\0"
L"PROCESS\0"
);
//
// Set up CSRSS process security
//
Status = CsrSetProcessSecurity();
ASSERT( NT_SUCCESS( Status ) );
//
// Initialize the Session List
//
Status = CsrInitializeNtSessionList();
ASSERT( NT_SUCCESS( Status ) );
//
// Initialize the Process List
//
Status = CsrInitializeProcessStructure();
ASSERT( NT_SUCCESS( Status ) );
//
// Process the command line arguments
//
Status = CsrParseServerCommandLine( argc, argv );
ASSERT( NT_SUCCESS( Status ) );
//
// Fix up per-process data for root process
//
ProcessDataPtr = (PCSR_PROCESS)RtlAllocateHeap( CsrHeap,
MAKE_TAG( PROCESS_TAG ) | HEAP_ZERO_MEMORY,
CsrTotalPerProcessDataLength
);
for (i=0; i<CSR_MAX_SERVER_DLL; i++) {
LoadedServerDll = CsrLoadedServerDll[ i ];
if (LoadedServerDll && LoadedServerDll->PerProcessDataLength) {
CsrRootProcess->ServerDllPerProcessData[i] = ProcessDataPtr;
ProcessDataPtr = (PVOID)QUAD_ALIGN((ULONG)ProcessDataPtr + LoadedServerDll->PerProcessDataLength);
}
else {
CsrRootProcess->ServerDllPerProcessData[i] = NULL;
}
}
//
// Let server dlls know about the root process.
//
for (i=0; i<CSR_MAX_SERVER_DLL; i++) {
LoadedServerDll = CsrLoadedServerDll[ i ];
if (LoadedServerDll && LoadedServerDll->AddProcessRoutine) {
(*LoadedServerDll->AddProcessRoutine)( NULL, CsrRootProcess );
}
}
//
// Initialize the Windows Server API Port, and one or more
// request threads.
//
CsrpServerDebugInitialize = FALSE;
Status = CsrApiPortInitialize();
ASSERT( NT_SUCCESS( Status ) );
Status = DbgSsInitialize( CsrApiPort, CsrUiLookup , NULL, NULL );
ASSERT( NT_SUCCESS( Status ) );
//
// Initialize the Server Session Manager API Port and one
// request thread.
//
Status = CsrSbApiPortInitialize();
ASSERT( NT_SUCCESS( Status ) );
//
// Connect to the session manager so we can start foreign sessions
//
Status = SmConnectToSm( &CsrSbApiPortName,
CsrSbApiPort,
CsrSubSystemType,
&CsrSmApiPort
);
ASSERT( NT_SUCCESS( Status ) );
Status = NtSetEvent(CsrInitializationEvent,NULL);
ASSERT( NT_SUCCESS( Status ) );
NtClose(CsrInitializationEvent);
Status = NtSetDefaultHardErrorPort(CsrApiPort);
return( Status );
}
// BUGBUG this routine should go away when we get exportable DLL data
NTSTATUS
CsrGetApiPorts(
OUT PHANDLE SbApiPort OPTIONAL,
OUT PHANDLE SmApiPort OPTIONAL
)
{
if (ARGUMENT_PRESENT(SbApiPort)) {
*SbApiPort = CsrSbApiPort;
}
if (ARGUMENT_PRESENT(SmApiPort)) {
*SmApiPort = CsrSmApiPort;
}
return STATUS_SUCCESS;
}
NTSTATUS
CsrParseServerCommandLine(
IN ULONG argc,
IN PCH argv[]
)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
ULONG i, ServerDllIndex;
PCH KeyName, KeyValue, s;
PCH InitRoutine;
CsrTotalPerProcessDataLength = 0;
CsrTotalPerThreadDataLength = 0;
CsrSubSystemType = IMAGE_SUBSYSTEM_WINDOWS_GUI;
CsrObjectDirectory = NULL;
CsrMaxApiRequestThreads = CSR_MAX_THREADS;
for (i=1; i<argc ; i++) {
KeyName = argv[ i ];
KeyValue = NULL;
while (*KeyName) {
if (*KeyName == '=') {
*KeyName++ = '\0';
KeyValue = KeyName;
break;
}
KeyName++;
}
KeyName = argv[ i ];
if (!_stricmp( KeyName, "ObjectDirectory" )) {
ANSI_STRING AnsiString;
//
// Create an object directory in the object name space with the
// name specified. It will be the root for all object names
// created by the Server side of the Client Server Runtime
// SubSystem.
//
RtlInitString( &AnsiString, KeyValue );
Status = RtlAnsiStringToUnicodeString( &CsrDirectoryName, &AnsiString, TRUE );
ASSERT(NT_SUCCESS(Status));
InitializeObjectAttributes( &ObjectAttributes,
&CsrDirectoryName,
OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
Status = NtCreateDirectoryObject( &CsrObjectDirectory,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes
);
if (!NT_SUCCESS( Status )) {
break;
}
}
else
if (!_stricmp( KeyName, "SubSystemType" )) {
}
else
if (!_stricmp( KeyName, "MaxRequestThreads" )) {
Status = RtlCharToInteger( KeyValue,
(ULONG)NULL,
&CsrMaxApiRequestThreads
);
}
else
if (!_stricmp( KeyName, "RequestThreads" )) {
#if 0
Status = RtlCharToInteger( KeyValue,
(ULONG)NULL,
&CsrNumberApiRequestThreads
);
#else
//
// wait until hive change !
//
Status = STATUS_SUCCESS;
#endif
}
else
if (!_stricmp( KeyName, "ProfileControl" )) {
if(!_stricmp( KeyValue, "On" )) {
CsrProfileControl = TRUE;
}
else {
CsrProfileControl = FALSE;
}
}
else
if (!_stricmp( KeyName, "SharedSection" )) {
Status = CsrSrvCreateSharedSection( KeyValue );
if (!NT_SUCCESS( Status )) {
IF_DEBUG {
DbgPrint( "CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n",
KeyName,
KeyValue,
Status
);
}
}
Status = CsrLoadServerDll( "CSRSS", NULL, CSRSRV_SERVERDLL_INDEX );
}
else
if (!_stricmp( KeyName, "ServerDLL" )) {
s = KeyValue;
InitRoutine = NULL;
Status = STATUS_INVALID_PARAMETER;
while (*s) {
if ((*s == ':') && (InitRoutine == NULL)) {
*s++ = '\0';
InitRoutine = s;
}
if (*s++ == ',') {
Status = RtlCharToInteger ( s, 10, &ServerDllIndex );
if (NT_SUCCESS( Status )) {
s[ -1 ] = '\0';
}
break;
}
}
if (!NT_SUCCESS( Status )) {
IF_DEBUG {
DbgPrint( "CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n",
KeyValue,
Status
);
}
}
else {
IF_CSR_DEBUG( INIT) {
DbgPrint( "CSRSS: Loading ServerDll=%s:%s\n", KeyValue, InitRoutine );
}
Status = CsrLoadServerDll( KeyValue, InitRoutine, ServerDllIndex);
IF_DEBUG {
if (!NT_SUCCESS( Status )) {
DbgPrint( "CSRSS: *** Failed loading ServerDll=%s (Status == %X)\n",
KeyValue,
Status
);
}
}
}
}
else
//
// This is a temporary hack until Windows & Console are friends.
//
if (!_stricmp( KeyName, "Windows" )) {
}
else {
Status = STATUS_INVALID_PARAMETER;
}
}
return( Status );
}
NTSTATUS
CsrServerDllInitialization(
IN PCSR_SERVER_DLL LoadedServerDll
)
{
PVOID SharedHeap;
PCSR_FAST_ANSI_OEM_TABLES XlateTables;
PVOID p;
NTSTATUS Status;
LoadedServerDll->ApiNumberBase = CSRSRV_FIRST_API_NUMBER;
LoadedServerDll->MaxApiNumber = CsrpMaxApiNumber;
LoadedServerDll->ApiDispatchTable = CsrServerApiDispatchTable;
LoadedServerDll->ApiServerValidTable = CsrServerApiServerValidTable;
#if DBG
LoadedServerDll->ApiNameTable = CsrServerApiNameTable;
#else
LoadedServerDll->ApiNameTable = NULL;
#endif
LoadedServerDll->PerProcessDataLength = 0;
LoadedServerDll->PerThreadDataLength = 0;
LoadedServerDll->ConnectRoutine = NULL;
LoadedServerDll->DisconnectRoutine = NULL;
SharedHeap = LoadedServerDll->SharedStaticServerData;
XlateTables = RtlAllocateHeap(SharedHeap, MAKE_SHARED_TAG( SHR_INIT_TAG ), sizeof(CSR_FAST_ANSI_OEM_TABLES));
if ( !XlateTables ) {
return STATUS_NO_MEMORY;
}
LoadedServerDll->SharedStaticServerData = (PVOID)XlateTables;
return( STATUS_SUCCESS );
}
NTSTATUS
CsrSrvProfileControl(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
return STATUS_INVALID_PARAMETER;
}
NTSTATUS
CsrSetProcessSecurity(
VOID
)
{
HANDLE Token;
NTSTATUS Status;
PTOKEN_USER User;
ULONG LengthSid, Length;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PACL Dacl;
//
// Open the token and get the system sid
//
Status = NtOpenProcessToken( NtCurrentProcess(),
TOKEN_QUERY,
&Token
);
if (!NT_SUCCESS(Status)) {
return Status;
}
NtQueryInformationToken( Token,
TokenUser,
NULL,
0,
&Length
);
User = (PTOKEN_USER)RtlAllocateHeap( CsrHeap,
MAKE_TAG( PROCESS_TAG ) | HEAP_ZERO_MEMORY,
Length
);
ASSERT( User != NULL );
Status = NtQueryInformationToken( Token,
TokenUser,
User,
Length,
&Length
);
NtClose( Token );
if (!NT_SUCCESS(Status)) {
RtlFreeHeap( CsrHeap, 0, User );
return Status;
}
LengthSid = RtlLengthSid( User->User.Sid );
//
// Allocate a buffer to hold the SD
//
SecurityDescriptor = RtlAllocateHeap( CsrHeap,
MAKE_TAG( PROCESS_TAG ) | HEAP_ZERO_MEMORY,
SECURITY_DESCRIPTOR_MIN_LENGTH +
sizeof(ACL) + LengthSid +
sizeof(ACCESS_ALLOWED_ACE)
);
ASSERT( SecurityDescriptor != NULL );
Dacl = (PACL)((PCHAR)SecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);
//
// Create the SD
//
Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(Status)) {
IF_DEBUG {
DbgPrint("CSRSS: SD creation failed - status = %lx\n", Status);
}
goto error_cleanup;
}
RtlCreateAcl( Dacl,
sizeof(ACL) + LengthSid + sizeof(ACCESS_ALLOWED_ACE),
ACL_REVISION2
);
Status = RtlAddAccessAllowedAce( Dacl,
ACL_REVISION,
( PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION |
PROCESS_DUP_HANDLE | PROCESS_TERMINATE | PROCESS_SET_PORT |
READ_CONTROL | PROCESS_QUERY_INFORMATION ),
User->User.Sid
);
if (!NT_SUCCESS(Status)) {
IF_DEBUG {
DbgPrint("CSRSS: ACE creation failed - status = %lx\n", Status);
}
goto error_cleanup;
}
//
// Set DACL to NULL to deny all access
//
Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
TRUE,
Dacl,
FALSE);
if (!NT_SUCCESS(Status)) {
IF_DEBUG {
DbgPrint("CSRSS: set DACL failed - status = %lx\n", Status);
}
goto error_cleanup;
}
//
// Put the DACL onto the process
//
Status = NtSetSecurityObject(NtCurrentProcess(),
DACL_SECURITY_INFORMATION,
SecurityDescriptor);
if (!NT_SUCCESS(Status)) {
IF_DEBUG {
DbgPrint("CSRSS: set process DACL failed - status = %lx\n", Status);
}
}
//
// Cleanup
//
error_cleanup:
RtlFreeHeap( CsrHeap, 0, SecurityDescriptor );
RtlFreeHeap( CsrHeap, 0, User );
return Status;
}