205 lines
5.9 KiB
C
205 lines
5.9 KiB
C
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
apiinit.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the code to initialize the ApiPort of the
|
|
Server side of the Client-Server Runtime Subsystem to the Session
|
|
Manager SubSystem.
|
|
|
|
Author:
|
|
|
|
Steve Wood (stevewo) 8-Oct-1990
|
|
|
|
Environment:
|
|
|
|
User Mode Only
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "csrsrv.h"
|
|
|
|
static SID_IDENTIFIER_AUTHORITY WorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
|
|
static SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
|
|
|
|
NTSTATUS
|
|
CsrApiPortInitialize( VOID )
|
|
{
|
|
NTSTATUS Status;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
HANDLE Thread;
|
|
CLIENT_ID ClientId;
|
|
PLIST_ENTRY ListHead, ListNext;
|
|
PCSR_THREAD ServerThread;
|
|
HANDLE EventHandle;
|
|
ULONG Length;
|
|
PSID SeWorldSid;
|
|
PSID SeRestrictedSid;
|
|
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
|
PACL Dacl;
|
|
|
|
// Though this function does not seem to cleanup on failure, failure
|
|
// will cause Csrss to exit, so any allocated memory will be freed and
|
|
// any open handle will be closed.
|
|
|
|
|
|
Length = CsrDirectoryName.Length +
|
|
sizeof( CSR_API_PORT_NAME ) +
|
|
sizeof( OBJ_NAME_PATH_SEPARATOR );
|
|
CsrApiPortName.Buffer = RtlAllocateHeap( CsrHeap, MAKE_TAG( INIT_TAG ), Length );
|
|
if (CsrApiPortName.Buffer == NULL) {
|
|
return( STATUS_NO_MEMORY );
|
|
}
|
|
CsrApiPortName.Length = 0;
|
|
CsrApiPortName.MaximumLength = (USHORT)Length;
|
|
RtlAppendUnicodeStringToString( &CsrApiPortName, &CsrDirectoryName );
|
|
RtlAppendUnicodeToString( &CsrApiPortName, L"\\" );
|
|
RtlAppendUnicodeToString( &CsrApiPortName, CSR_API_PORT_NAME );
|
|
|
|
IF_CSR_DEBUG( INIT ) {
|
|
DbgPrint( "CSRSS: Creating %wZ port and associated threads\n",
|
|
&CsrApiPortName );
|
|
DbgPrint( "CSRSS: sizeof( CONNECTINFO ) == %ld sizeof( API_MSG ) == %ld\n",
|
|
sizeof( CSR_API_CONNECTINFO ),
|
|
sizeof( CSR_API_MSG )
|
|
);
|
|
}
|
|
|
|
//
|
|
// create a security descriptor that allows all access
|
|
//
|
|
|
|
SeWorldSid = RtlAllocateHeap( CsrHeap, MAKE_TAG( TMP_TAG ), RtlLengthRequiredSid( 1 ) );
|
|
if (SeWorldSid == NULL) {
|
|
return( STATUS_NO_MEMORY );
|
|
}
|
|
|
|
RtlInitializeSid( SeWorldSid, &WorldSidAuthority, 1 );
|
|
*(RtlSubAuthoritySid( SeWorldSid, 0 )) = SECURITY_WORLD_RID;
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority ,
|
|
1,
|
|
SECURITY_RESTRICTED_CODE_RID,
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
&SeRestrictedSid);
|
|
if (!NT_SUCCESS(Status)){
|
|
return Status;
|
|
}
|
|
|
|
Length = SECURITY_DESCRIPTOR_MIN_LENGTH +
|
|
(ULONG)sizeof(ACL) +
|
|
2 * (ULONG)sizeof(ACCESS_ALLOWED_ACE) +
|
|
RtlLengthSid( SeWorldSid ) +
|
|
RtlLengthSid( SeRestrictedSid ) +
|
|
8; // The 8 is just for good measure
|
|
SecurityDescriptor = RtlAllocateHeap( CsrHeap, MAKE_TAG( TMP_TAG ), Length);
|
|
if (SecurityDescriptor == NULL) {
|
|
return( STATUS_NO_MEMORY );
|
|
}
|
|
|
|
Dacl = (PACL)((PCHAR)SecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);
|
|
|
|
RtlCreateSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
|
|
RtlCreateAcl( Dacl, Length - SECURITY_DESCRIPTOR_MIN_LENGTH, ACL_REVISION2);
|
|
|
|
RtlAddAccessAllowedAce (
|
|
Dacl,
|
|
ACL_REVISION2,
|
|
PORT_ALL_ACCESS,
|
|
SeWorldSid
|
|
);
|
|
|
|
RtlAddAccessAllowedAce (
|
|
Dacl,
|
|
ACL_REVISION2,
|
|
PORT_ALL_ACCESS,
|
|
SeRestrictedSid
|
|
);
|
|
|
|
RtlSetDaclSecurityDescriptor (
|
|
SecurityDescriptor,
|
|
TRUE,
|
|
Dacl,
|
|
FALSE
|
|
);
|
|
|
|
InitializeObjectAttributes( &ObjectAttributes, &CsrApiPortName, 0,
|
|
NULL, SecurityDescriptor );
|
|
Status = NtCreatePort( &CsrApiPort,
|
|
&ObjectAttributes,
|
|
sizeof( CSR_API_CONNECTINFO ),
|
|
sizeof( CSR_API_MSG ),
|
|
4096 * 16
|
|
);
|
|
if (!NT_SUCCESS(Status)){
|
|
return Status;
|
|
}
|
|
//
|
|
// clean up security stuff
|
|
//
|
|
|
|
RtlFreeHeap( CsrHeap, 0, SeWorldSid );
|
|
RtlFreeHeap( CsrHeap, 0, SeRestrictedSid );
|
|
RtlFreeHeap( CsrHeap, 0, SecurityDescriptor );
|
|
|
|
Status = NtCreateEvent(&EventHandle,
|
|
EVENT_ALL_ACCESS,
|
|
NULL,
|
|
SynchronizationEvent,
|
|
FALSE
|
|
);
|
|
if (!NT_SUCCESS(Status)){
|
|
return Status;
|
|
}
|
|
//
|
|
// Create the inital request thread
|
|
//
|
|
|
|
Status = RtlCreateUserThread( NtCurrentProcess(),
|
|
NULL,
|
|
TRUE,
|
|
0,
|
|
0,
|
|
0,
|
|
CsrApiRequestThread,
|
|
(PVOID)EventHandle,
|
|
&Thread,
|
|
&ClientId
|
|
);
|
|
if (!NT_SUCCESS(Status)){
|
|
return Status;
|
|
}
|
|
|
|
CsrAddStaticServerThread(Thread,&ClientId,CSR_STATIC_API_THREAD);
|
|
|
|
ListHead = &CsrRootProcess->ThreadList;
|
|
ListNext = ListHead->Flink;
|
|
while (ListNext != ListHead) {
|
|
ServerThread = CONTAINING_RECORD( ListNext, CSR_THREAD, Link );
|
|
Status = NtResumeThread( ServerThread->ThreadHandle, NULL );
|
|
if (ServerThread->Flags & CSR_STATIC_API_THREAD) {
|
|
Status = NtWaitForSingleObject(EventHandle,FALSE,NULL);
|
|
ASSERT( NT_SUCCESS( Status ) );
|
|
}
|
|
ListNext = ListNext->Flink;
|
|
}
|
|
NtClose(EventHandle);
|
|
|
|
|
|
return( Status );
|
|
}
|
|
|
|
HANDLE
|
|
CsrQueryApiPort(VOID)
|
|
{
|
|
return CsrApiPort;
|
|
}
|
|
|