windows-nt/Source/XPSP1/NT/base/subsys/csr/server/apiinit.c

205 lines
5.9 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
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;
}