2010-03-10 04:59:39 +00:00
|
|
|
/*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS CSR Sub System
|
2011-07-25 05:54:37 +00:00
|
|
|
* FILE: subsystems/win32/csrss/csrsrv/init.c
|
2010-03-10 04:59:39 +00:00
|
|
|
* PURPOSE: CSR Server DLL Initialization
|
|
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
1999-06-08 22:50:59 +00:00
|
|
|
*/
|
1999-12-22 14:48:30 +00:00
|
|
|
|
2010-03-10 04:59:39 +00:00
|
|
|
/* INCLUDES *******************************************************************/
|
1999-06-08 22:50:59 +00:00
|
|
|
|
2010-03-10 04:59:39 +00:00
|
|
|
#include "srv.h"
|
2005-02-19 23:07:22 +00:00
|
|
|
#define NDEBUG
|
2003-08-11 18:50:12 +00:00
|
|
|
#include <debug.h>
|
|
|
|
|
2010-03-10 04:59:39 +00:00
|
|
|
/* DATA ***********************************************************************/
|
1999-06-08 22:50:59 +00:00
|
|
|
|
2005-03-20 22:55:05 +00:00
|
|
|
HANDLE CsrHeap = (HANDLE) 0;
|
|
|
|
HANDLE CsrObjectDirectory = (HANDLE) 0;
|
2000-02-27 02:12:07 +00:00
|
|
|
UNICODE_STRING CsrDirectoryName;
|
2012-02-15 19:53:31 +00:00
|
|
|
UNICODE_STRING CsrSbApiPortName;
|
|
|
|
HANDLE CsrSbApiPort = 0;
|
|
|
|
PCSR_THREAD CsrSbApiRequestThreadPtr;
|
2010-05-22 23:47:54 +00:00
|
|
|
static unsigned ServerProcCount;
|
|
|
|
static CSRPLUGIN_SERVER_PROCS *ServerProcs = NULL;
|
2012-02-15 19:53:31 +00:00
|
|
|
HANDLE CsrSmApiPort;
|
2005-03-20 22:55:05 +00:00
|
|
|
HANDLE hSbApiPort = (HANDLE) 0;
|
|
|
|
HANDLE hApiPort = (HANDLE) 0;
|
2012-02-15 16:11:12 +00:00
|
|
|
ULONG CsrDebug = 0xFFFFFFFF;
|
|
|
|
ULONG CsrMaxApiRequestThreads;
|
|
|
|
ULONG CsrTotalPerProcessDataLength;
|
|
|
|
ULONG SessionId;
|
|
|
|
HANDLE BNOLinksDirectory;
|
|
|
|
HANDLE SessionObjectDirectory;
|
|
|
|
HANDLE DosDevicesDirectory;
|
2012-02-15 19:53:31 +00:00
|
|
|
HANDLE CsrInitializationEvent;
|
|
|
|
SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
|
2005-03-20 22:55:05 +00:00
|
|
|
|
2010-03-10 04:59:39 +00:00
|
|
|
/* PRIVATE FUNCTIONS **********************************************************/
|
|
|
|
|
2004-05-28 21:33:41 +00:00
|
|
|
static NTSTATUS FASTCALL
|
2010-05-22 23:47:54 +00:00
|
|
|
CsrpAddServerProcs(CSRPLUGIN_SERVER_PROCS *Procs)
|
2004-05-28 21:33:41 +00:00
|
|
|
{
|
2010-05-22 23:47:54 +00:00
|
|
|
CSRPLUGIN_SERVER_PROCS *NewProcs;
|
2004-05-28 21:33:41 +00:00
|
|
|
|
2005-03-20 22:55:05 +00:00
|
|
|
DPRINT("CSR: %s called\n", __FUNCTION__);
|
|
|
|
|
2012-02-15 19:53:31 +00:00
|
|
|
NewProcs = RtlAllocateHeap(CsrHeap, 0,
|
2010-05-22 23:47:54 +00:00
|
|
|
(ServerProcCount + 1)
|
|
|
|
* sizeof(CSRPLUGIN_SERVER_PROCS));
|
2004-05-28 21:33:41 +00:00
|
|
|
if (NULL == NewProcs)
|
|
|
|
{
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
2010-05-22 23:47:54 +00:00
|
|
|
if (0 != ServerProcCount)
|
2004-05-28 21:33:41 +00:00
|
|
|
{
|
2010-05-22 23:47:54 +00:00
|
|
|
RtlCopyMemory(NewProcs, ServerProcs,
|
|
|
|
ServerProcCount * sizeof(CSRPLUGIN_SERVER_PROCS));
|
2012-02-15 19:53:31 +00:00
|
|
|
RtlFreeHeap(CsrHeap, 0, ServerProcs);
|
2004-05-28 21:33:41 +00:00
|
|
|
}
|
2010-05-22 23:47:54 +00:00
|
|
|
NewProcs[ServerProcCount] = *Procs;
|
|
|
|
ServerProcs = NewProcs;
|
|
|
|
ServerProcCount++;
|
2004-05-28 21:33:41 +00:00
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-10-30 14:20:45 +00:00
|
|
|
BOOL
|
2012-02-15 20:29:08 +00:00
|
|
|
CallHardError(IN PCSR_PROCESS ProcessData,
|
2007-12-22 17:18:32 +00:00
|
|
|
IN PHARDERROR_MSG HardErrorMessage)
|
2006-10-30 14:20:45 +00:00
|
|
|
{
|
|
|
|
BOOL Ok;
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
DPRINT("CSR: %s called\n", __FUNCTION__);
|
|
|
|
|
|
|
|
Ok = TRUE;
|
2010-05-22 23:47:54 +00:00
|
|
|
for (i = 0; i < ServerProcCount && Ok; i++)
|
2006-10-30 14:20:45 +00:00
|
|
|
{
|
2010-05-22 23:47:54 +00:00
|
|
|
Ok = (*ServerProcs[i].HardErrorProc)(ProcessData, HardErrorMessage);
|
2006-10-30 14:20:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2010-05-22 23:47:54 +00:00
|
|
|
NTSTATUS
|
2012-02-15 20:29:08 +00:00
|
|
|
CallProcessInherit(IN PCSR_PROCESS SourceProcessData,
|
|
|
|
IN PCSR_PROCESS TargetProcessData)
|
2010-05-22 23:47:54 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
DPRINT("CSR: %s called\n", __FUNCTION__);
|
|
|
|
|
|
|
|
for (i = 0; i < ServerProcCount && NT_SUCCESS(Status); i++)
|
|
|
|
Status = (*ServerProcs[i].ProcessInheritProc)(SourceProcessData, TargetProcessData);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
2012-02-15 20:29:08 +00:00
|
|
|
CallProcessDeleted(IN PCSR_PROCESS ProcessData)
|
2010-05-22 23:47:54 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
DPRINT("CSR: %s called\n", __FUNCTION__);
|
|
|
|
|
|
|
|
for (i = 0; i < ServerProcCount && NT_SUCCESS(Status); i++)
|
|
|
|
Status = (*ServerProcs[i].ProcessDeletedProc)(ProcessData);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2005-03-20 22:55:05 +00:00
|
|
|
/**********************************************************************
|
2005-10-08 22:41:49 +00:00
|
|
|
* CsrpInitWin32Csr/3
|
2005-03-20 22:55:05 +00:00
|
|
|
*
|
|
|
|
* TODO: this function should be turned more general to load an
|
|
|
|
* TODO: hosted server DLL as received from the command line;
|
|
|
|
* TODO: for instance: ServerDll=winsrv:ConServerDllInitialization,2
|
|
|
|
* TODO: ^method ^dll ^api ^sid
|
|
|
|
* TODO:
|
|
|
|
* TODO: CsrpHostServerDll (LPWSTR DllName,
|
|
|
|
* TODO: LPWSTR ApiName,
|
|
|
|
* TODO: DWORD ServerId)
|
|
|
|
*/
|
|
|
|
static NTSTATUS
|
2012-02-15 16:11:12 +00:00
|
|
|
CsrpInitWin32Csr (VOID)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
UNICODE_STRING DllName;
|
|
|
|
HINSTANCE hInst;
|
|
|
|
ANSI_STRING ProcName;
|
|
|
|
CSRPLUGIN_INITIALIZE_PROC InitProc;
|
|
|
|
CSRSS_EXPORTED_FUNCS Exports;
|
|
|
|
PCSRSS_API_DEFINITION ApiDefinitions;
|
2010-05-22 23:47:54 +00:00
|
|
|
CSRPLUGIN_SERVER_PROCS ServerProcs;
|
2003-12-02 11:38:47 +00:00
|
|
|
|
2005-03-20 22:55:05 +00:00
|
|
|
DPRINT("CSR: %s called\n", __FUNCTION__);
|
|
|
|
|
2003-12-02 11:38:47 +00:00
|
|
|
RtlInitUnicodeString(&DllName, L"win32csr.dll");
|
|
|
|
Status = LdrLoadDll(NULL, 0, &DllName, (PVOID *) &hInst);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
RtlInitAnsiString(&ProcName, "Win32CsrInitialization");
|
|
|
|
Status = LdrGetProcedureAddress(hInst, &ProcName, 0, (PVOID *) &InitProc);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
2005-12-01 22:38:03 +00:00
|
|
|
Exports.CsrEnumProcessesProc = CsrEnumProcesses;
|
2012-02-15 19:53:31 +00:00
|
|
|
if (! (*InitProc)(&ApiDefinitions, &ServerProcs, &Exports, CsrHeap))
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = CsrApiRegisterDefinitions(ApiDefinitions);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
2010-05-22 23:47:54 +00:00
|
|
|
Status = CsrpAddServerProcs(&ServerProcs);
|
2003-12-02 11:38:47 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSRSS_API_DEFINITION NativeDefinitions[] =
|
|
|
|
{
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
CSRSS_DEFINE_API(CREATE_PROCESS, CsrCreateProcess),
|
2010-03-10 06:49:53 +00:00
|
|
|
CSRSS_DEFINE_API(CREATE_THREAD, CsrSrvCreateThread),
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
CSRSS_DEFINE_API(TERMINATE_PROCESS, CsrTerminateProcess),
|
|
|
|
CSRSS_DEFINE_API(CONNECT_PROCESS, CsrConnectProcess),
|
|
|
|
CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS, CsrRegisterServicesProcess),
|
|
|
|
CSRSS_DEFINE_API(GET_SHUTDOWN_PARAMETERS, CsrGetShutdownParameters),
|
|
|
|
CSRSS_DEFINE_API(SET_SHUTDOWN_PARAMETERS, CsrSetShutdownParameters),
|
|
|
|
{ 0, 0, NULL }
|
2003-12-02 11:38:47 +00:00
|
|
|
};
|
|
|
|
|
2008-11-29 22:48:58 +00:00
|
|
|
static NTSTATUS WINAPI
|
2005-03-20 22:55:05 +00:00
|
|
|
CsrpCreateListenPort (IN LPWSTR Name,
|
|
|
|
IN OUT PHANDLE Port,
|
|
|
|
IN PTHREAD_START_ROUTINE ListenThread)
|
|
|
|
{
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
OBJECT_ATTRIBUTES PortAttributes;
|
|
|
|
UNICODE_STRING PortName;
|
2010-03-09 20:23:22 +00:00
|
|
|
HANDLE ServerThread;
|
|
|
|
CLIENT_ID ClientId;
|
2005-03-20 22:55:05 +00:00
|
|
|
|
|
|
|
DPRINT("CSR: %s called\n", __FUNCTION__);
|
|
|
|
|
|
|
|
RtlInitUnicodeString (& PortName, Name);
|
|
|
|
InitializeObjectAttributes (& PortAttributes,
|
|
|
|
& PortName,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
Status = NtCreatePort ( Port,
|
|
|
|
& PortAttributes,
|
2012-02-08 21:56:23 +00:00
|
|
|
sizeof(SB_CONNECTION_INFO),
|
|
|
|
sizeof(SB_API_MSG),
|
|
|
|
32 * sizeof(SB_API_MSG));
|
2005-03-20 22:55:05 +00:00
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSR: %s: NtCreatePort failed (Status=%08lx)\n",
|
|
|
|
__FUNCTION__, Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
Status = RtlCreateUserThread(NtCurrentProcess(),
|
|
|
|
NULL,
|
2010-03-09 20:23:22 +00:00
|
|
|
TRUE,
|
2005-03-20 22:55:05 +00:00
|
|
|
0,
|
2005-07-12 01:56:14 +00:00
|
|
|
0,
|
|
|
|
0,
|
2005-03-20 22:55:05 +00:00
|
|
|
(PTHREAD_START_ROUTINE) ListenThread,
|
2006-10-30 18:45:22 +00:00
|
|
|
*Port,
|
2010-03-09 20:23:22 +00:00
|
|
|
&ServerThread,
|
|
|
|
&ClientId);
|
2012-02-15 19:53:31 +00:00
|
|
|
|
2010-03-09 20:23:22 +00:00
|
|
|
if (ListenThread == (PVOID)ClientConnectionThread)
|
|
|
|
{
|
|
|
|
CsrAddStaticServerThread(ServerThread, &ClientId, 0);
|
|
|
|
}
|
2012-02-15 19:53:31 +00:00
|
|
|
|
2010-03-09 20:23:22 +00:00
|
|
|
NtResumeThread(ServerThread, NULL);
|
|
|
|
NtClose(ServerThread);
|
2005-03-20 22:55:05 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* === INIT ROUTINES === */
|
|
|
|
|
2011-08-03 06:18:42 +00:00
|
|
|
VOID
|
|
|
|
WINAPI
|
|
|
|
BasepFakeStaticServerData(VOID);
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
CsrSrvCreateSharedSection(IN PCHAR ParameterValue);
|
|
|
|
|
2012-02-15 19:53:31 +00:00
|
|
|
/*++
|
|
|
|
* @name CsrSetProcessSecurity
|
|
|
|
*
|
|
|
|
* The CsrSetProcessSecurity routine protects access to the CSRSS process
|
|
|
|
* from unauthorized tampering.
|
|
|
|
*
|
|
|
|
* @param None.
|
|
|
|
*
|
|
|
|
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
|
|
|
|
* othwerwise.
|
|
|
|
*
|
|
|
|
* @remarks None.
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
CsrSetProcessSecurity(VOID)
|
2005-02-19 22:56:59 +00:00
|
|
|
{
|
2012-02-15 19:53:31 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
HANDLE hToken, hProcess = NtCurrentProcess();
|
|
|
|
ULONG Length;
|
|
|
|
PTOKEN_USER TokenInfo = NULL;
|
|
|
|
PSECURITY_DESCRIPTOR ProcSd = NULL;
|
|
|
|
PACL Dacl;
|
|
|
|
PSID UserSid;
|
2005-03-20 22:55:05 +00:00
|
|
|
|
2012-02-15 19:53:31 +00:00
|
|
|
/* Open our token */
|
|
|
|
Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
|
|
|
|
if (!NT_SUCCESS(Status)) goto Quickie;
|
2005-02-19 22:56:59 +00:00
|
|
|
|
2012-02-15 19:53:31 +00:00
|
|
|
/* Get the Token User Length */
|
|
|
|
NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length);
|
2005-03-20 22:55:05 +00:00
|
|
|
|
2012-02-15 19:53:31 +00:00
|
|
|
/* Allocate space for it */
|
|
|
|
TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length);
|
|
|
|
if (!TokenInfo)
|
|
|
|
{
|
|
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
2005-03-20 22:55:05 +00:00
|
|
|
|
2012-02-15 19:53:31 +00:00
|
|
|
/* Now query the data */
|
|
|
|
Status = NtQueryInformationToken(hToken, TokenUser, TokenInfo, Length, &Length);
|
|
|
|
NtClose(hToken);
|
|
|
|
if (!NT_SUCCESS(Status)) goto Quickie;
|
|
|
|
|
|
|
|
/* Now check the SID Length */
|
|
|
|
UserSid = TokenInfo->User.Sid;
|
|
|
|
Length = RtlLengthSid(UserSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
|
|
|
|
|
|
|
|
/* Allocate a buffer for the Security Descriptor, with SID and DACL */
|
|
|
|
ProcSd = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
|
|
|
|
if (!ProcSd)
|
|
|
|
{
|
|
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the pointer to the DACL */
|
|
|
|
Dacl = (PACL)((ULONG_PTR)ProcSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
|
|
|
|
|
|
|
|
/* Now create the SD itself */
|
|
|
|
Status = RtlCreateSecurityDescriptor(ProcSd, SECURITY_DESCRIPTOR_REVISION);
|
2012-02-08 21:56:23 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2012-02-15 19:53:31 +00:00
|
|
|
DPRINT1("CSRSS: SD creation failed - status = %lx\n", Status);
|
|
|
|
goto Quickie;
|
2012-02-08 21:56:23 +00:00
|
|
|
}
|
2012-02-15 19:53:31 +00:00
|
|
|
|
|
|
|
/* Create the DACL for it*/
|
|
|
|
Status = RtlCreateAcl(Dacl, Length, ACL_REVISION2);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSS: DACL creation failed - status = %lx\n", Status);
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create the ACE */
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
PROCESS_VM_READ | PROCESS_VM_WRITE |
|
|
|
|
PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE |
|
|
|
|
PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME |
|
|
|
|
PROCESS_QUERY_INFORMATION | READ_CONTROL,
|
|
|
|
UserSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSS: ACE creation failed - status = %lx\n", Status);
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear the DACL in the SD */
|
|
|
|
Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSS: set DACL failed - status = %lx\n", Status);
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Write the SD into the Process */
|
|
|
|
Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSS: set process DACL failed - status = %lx\n", Status);
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free the memory and return */
|
|
|
|
Quickie:
|
|
|
|
if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd);
|
|
|
|
RtlFreeHeap(CsrHeap, 0, TokenInfo);
|
|
|
|
return Status;
|
2005-02-19 22:56:59 +00:00
|
|
|
}
|
|
|
|
|
2012-02-15 16:11:12 +00:00
|
|
|
/*++
|
|
|
|
* @name CsrSetDirectorySecurity
|
|
|
|
*
|
|
|
|
* The CsrSetDirectorySecurity routine sets the security descriptor for the
|
|
|
|
* specified Object Directory.
|
|
|
|
*
|
|
|
|
* @param ObjectDirectory
|
|
|
|
* Handle fo the Object Directory to protect.
|
|
|
|
*
|
|
|
|
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
|
|
|
|
* othwerwise.
|
|
|
|
*
|
|
|
|
* @remarks None.
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
CsrSetDirectorySecurity(IN HANDLE ObjectDirectory)
|
2005-03-20 22:55:05 +00:00
|
|
|
{
|
2012-02-15 16:11:12 +00:00
|
|
|
/* FIXME: Implement */
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2005-03-20 22:55:05 +00:00
|
|
|
|
2012-02-15 16:11:12 +00:00
|
|
|
/*++
|
|
|
|
* @name GetDosDevicesProtection
|
|
|
|
*
|
|
|
|
* The GetDosDevicesProtection creates a security descriptor for the DOS Devices
|
|
|
|
* Object Directory.
|
|
|
|
*
|
|
|
|
* @param DosDevicesSd
|
|
|
|
* Pointer to the Security Descriptor to return.
|
|
|
|
*
|
|
|
|
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
|
|
|
|
* othwerwise.
|
|
|
|
*
|
|
|
|
* @remarks Depending on the DOS Devices Protection Mode (set in the registry),
|
|
|
|
* regular users may or may not have full access to the directory.
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
GetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR DosDevicesSd)
|
|
|
|
{
|
|
|
|
SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
|
|
|
|
SID_IDENTIFIER_AUTHORITY CreatorAuthority = {SECURITY_CREATOR_SID_AUTHORITY};
|
|
|
|
SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
|
|
|
|
PSID WorldSid, CreatorSid, AdminSid, SystemSid;
|
|
|
|
UCHAR KeyValueBuffer[0x40];
|
|
|
|
PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
|
|
|
|
UNICODE_STRING KeyName;
|
|
|
|
ULONG ProtectionMode = 0;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
PACL Dacl;
|
|
|
|
PACCESS_ALLOWED_ACE Ace;
|
|
|
|
HANDLE hKey;
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG ResultLength, SidLength, AclLength;
|
|
|
|
|
|
|
|
/* Create the SD */
|
|
|
|
Status = RtlCreateSecurityDescriptor(DosDevicesSd, SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Initialize the System SID */
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
|
|
|
|
SECURITY_LOCAL_SYSTEM_RID,
|
|
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
|
|
&SystemSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Initialize the World SID */
|
|
|
|
Status = RtlAllocateAndInitializeSid(&WorldAuthority, 1,
|
|
|
|
SECURITY_WORLD_RID,
|
|
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
|
|
&WorldSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Initialize the Admin SID */
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 2,
|
|
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
|
|
0, 0, 0, 0, 0, 0,
|
|
|
|
&AdminSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Initialize the Creator SID */
|
|
|
|
Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1,
|
|
|
|
SECURITY_CREATOR_OWNER_RID,
|
|
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
|
|
&CreatorSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Open the Session Manager Key */
|
|
|
|
RtlInitUnicodeString(&KeyName, SM_REG_KEY);
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&KeyName,
|
|
|
|
OBJ_CASE_INSENSITIVE,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Read the key value */
|
|
|
|
RtlInitUnicodeString(&KeyName, L"ProtectionMode");
|
|
|
|
Status = NtQueryValueKey(hKey,
|
|
|
|
&KeyName,
|
|
|
|
KeyValuePartialInformation,
|
|
|
|
KeyValueBuffer,
|
|
|
|
sizeof(KeyValueBuffer),
|
|
|
|
&ResultLength);
|
|
|
|
|
|
|
|
/* Make sure it's what we expect it to be */
|
|
|
|
KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
|
|
|
|
if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) &&
|
|
|
|
(*(PULONG)KeyValuePartialInfo->Data))
|
|
|
|
{
|
|
|
|
/* Save the Protection Mode */
|
|
|
|
ProtectionMode = *(PULONG)KeyValuePartialInfo->Data;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Close the handle */
|
|
|
|
NtClose(hKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check the Protection Mode */
|
|
|
|
if (ProtectionMode & 3)
|
|
|
|
{
|
|
|
|
/* Calculate SID Lengths */
|
|
|
|
SidLength = RtlLengthSid(CreatorSid) + RtlLengthSid(SystemSid) +
|
|
|
|
RtlLengthSid(AdminSid);
|
|
|
|
AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
|
|
|
|
|
|
|
|
/* Allocate memory for the DACL */
|
|
|
|
Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength);
|
|
|
|
ASSERT(Dacl != NULL);
|
|
|
|
|
|
|
|
/* Build the ACL and add 3 ACEs */
|
|
|
|
Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, AdminSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, CreatorSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Edit the ACEs to make them inheritable */
|
|
|
|
Status = RtlGetAce(Dacl, 0, (PVOID*)&Ace);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
|
|
|
|
Status = RtlGetAce(Dacl, 1, (PVOID*)&Ace);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
|
|
|
|
Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
|
|
|
|
|
|
|
|
/* Set this DACL with the SD */
|
|
|
|
Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Calculate SID Lengths */
|
|
|
|
SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(SystemSid);
|
|
|
|
AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
|
|
|
|
|
|
|
|
/* Allocate memory for the DACL */
|
|
|
|
Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength);
|
|
|
|
ASSERT(Dacl != NULL);
|
|
|
|
|
|
|
|
/* Build the ACL and add 3 ACEs */
|
|
|
|
Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, WorldSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, WorldSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Edit the last ACE to make it inheritable */
|
|
|
|
Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
|
|
|
|
|
|
|
|
/* Set this DACL with the SD */
|
|
|
|
Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: failure cases! Fail: */
|
|
|
|
/* Free the memory */
|
|
|
|
RtlFreeHeap(CsrHeap, 0, Dacl);
|
2007-06-14 16:47:24 +00:00
|
|
|
|
2012-02-15 16:11:12 +00:00
|
|
|
/* FIXME: semi-failure cases! Quickie: */
|
|
|
|
Quickie:
|
|
|
|
/* Free the SIDs */
|
|
|
|
RtlFreeSid(SystemSid);
|
|
|
|
RtlFreeSid(WorldSid);
|
|
|
|
RtlFreeSid(AdminSid);
|
|
|
|
RtlFreeSid(CreatorSid);
|
|
|
|
|
|
|
|
/* Return */
|
|
|
|
return Status;
|
2005-03-20 22:55:05 +00:00
|
|
|
}
|
|
|
|
|
2012-02-15 16:11:12 +00:00
|
|
|
/*++
|
|
|
|
* @name FreeDosDevicesProtection
|
|
|
|
*
|
|
|
|
* The FreeDosDevicesProtection frees the security descriptor that was created
|
|
|
|
* by GetDosDevicesProtection
|
|
|
|
*
|
|
|
|
* @param DosDevicesSd
|
|
|
|
* Pointer to the security descriptor to free.
|
|
|
|
|
|
|
|
* @return None.
|
|
|
|
*
|
|
|
|
* @remarks None.
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
FreeDosDevicesProtection(IN PSECURITY_DESCRIPTOR DosDevicesSd)
|
2005-03-20 22:55:05 +00:00
|
|
|
{
|
2012-02-15 16:11:12 +00:00
|
|
|
PACL Dacl;
|
|
|
|
BOOLEAN Present, Default;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Get the DACL corresponding to this SD */
|
|
|
|
Status = RtlGetDaclSecurityDescriptor(DosDevicesSd, &Present, &Dacl, &Default);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
ASSERT(Present);
|
|
|
|
ASSERT(Dacl != NULL);
|
|
|
|
|
|
|
|
/* Free it */
|
|
|
|
if ((NT_SUCCESS(Status)) && (Dacl)) RtlFreeHeap(CsrHeap, 0, Dacl);
|
2005-03-20 22:55:05 +00:00
|
|
|
}
|
|
|
|
|
2012-02-15 16:11:12 +00:00
|
|
|
/*++
|
|
|
|
* @name CsrCreateSessionObjectDirectory
|
|
|
|
*
|
|
|
|
* The CsrCreateSessionObjectDirectory routine creates the BaseNamedObjects,
|
|
|
|
* Session and Dos Devices directories for the specified session.
|
|
|
|
*
|
|
|
|
* @param Session
|
|
|
|
* Session ID for which to create the directories.
|
|
|
|
*
|
|
|
|
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
|
|
|
|
* othwerwise.
|
|
|
|
*
|
|
|
|
* @remarks None.
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
CsrCreateSessionObjectDirectory(IN ULONG Session)
|
2006-10-26 04:55:34 +00:00
|
|
|
{
|
2012-02-15 16:11:12 +00:00
|
|
|
WCHAR SessionBuffer[512], BnoBuffer[512];
|
|
|
|
UNICODE_STRING SessionString, BnoString;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
HANDLE BnoHandle;
|
|
|
|
SECURITY_DESCRIPTOR DosDevicesSd;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Generate the Session BNOLINKS Directory name */
|
|
|
|
swprintf(SessionBuffer, L"%ws\\BNOLINKS", SESSION_ROOT);
|
|
|
|
RtlInitUnicodeString(&SessionString, SessionBuffer);
|
|
|
|
|
|
|
|
/* Create it */
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&SessionString,
|
|
|
|
OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
Status = NtCreateDirectoryObject(&BNOLinksDirectory,
|
|
|
|
DIRECTORY_ALL_ACCESS,
|
|
|
|
&ObjectAttributes);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
|
|
|
|
"CsrCreateSessionObjectDirectory - status = %lx\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now add the Session ID */
|
|
|
|
swprintf(SessionBuffer, L"%ld", Session);
|
|
|
|
RtlInitUnicodeString(&SessionString, SessionBuffer);
|
|
|
|
|
|
|
|
/* Check if this is the first Session */
|
|
|
|
if (Session)
|
|
|
|
{
|
|
|
|
/* Not the first, so the name will be slighly more complex */
|
|
|
|
swprintf(BnoBuffer, L"%ws\\%ld\\BaseNamedObjects", SESSION_ROOT, Session);
|
|
|
|
RtlInitUnicodeString(&BnoString, BnoBuffer);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Use the direct name */
|
|
|
|
RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create the symlink */
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&SessionString,
|
|
|
|
OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
|
|
|
|
BNOLinksDirectory,
|
|
|
|
NULL);
|
|
|
|
Status = NtCreateSymbolicLinkObject(&BnoHandle,
|
|
|
|
SYMBOLIC_LINK_ALL_ACCESS,
|
|
|
|
&ObjectAttributes,
|
|
|
|
&BnoString);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSS: NtCreateSymbolicLinkObject failed in "
|
|
|
|
"CsrCreateSessionObjectDirectory - status = %lx\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create the \DosDevices Security Descriptor */
|
|
|
|
Status = GetDosDevicesProtection(&DosDevicesSd);
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
|
|
|
/* Now create a directory for this session */
|
|
|
|
swprintf(SessionBuffer, L"%ws\\%ld", SESSION_ROOT, Session);
|
|
|
|
RtlInitUnicodeString(&SessionString, SessionBuffer);
|
|
|
|
|
|
|
|
/* Create the directory */
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&SessionString,
|
|
|
|
OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
|
|
|
|
0,
|
|
|
|
&DosDevicesSd);
|
|
|
|
Status = NtCreateDirectoryObject(&SessionObjectDirectory,
|
|
|
|
DIRECTORY_ALL_ACCESS,
|
|
|
|
&ObjectAttributes);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
|
|
|
|
"CsrCreateSessionObjectDirectory - status = %lx\n", Status);
|
|
|
|
FreeDosDevicesProtection(&DosDevicesSd);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Next, create a directory for this session's DOS Devices */
|
|
|
|
RtlInitUnicodeString(&SessionString, L"DosDevices");
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&SessionString,
|
|
|
|
OBJ_CASE_INSENSITIVE,
|
|
|
|
SessionObjectDirectory,
|
|
|
|
&DosDevicesSd);
|
|
|
|
Status = NtCreateDirectoryObject(&DosDevicesDirectory,
|
|
|
|
DIRECTORY_ALL_ACCESS,
|
|
|
|
&ObjectAttributes);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
|
|
|
|
"CsrCreateSessionObjectDirectory - status = %lx\n", Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Release the Security Descriptor */
|
|
|
|
FreeDosDevicesProtection(&DosDevicesSd);
|
|
|
|
|
|
|
|
/* Return */
|
|
|
|
return Status;
|
2006-10-26 04:55:34 +00:00
|
|
|
}
|
2005-03-20 22:55:05 +00:00
|
|
|
|
2012-02-15 16:11:12 +00:00
|
|
|
/*++
|
|
|
|
* @name CsrParseServerCommandLine
|
|
|
|
*
|
|
|
|
* The CsrParseServerCommandLine routine parses the CSRSS command-line in the
|
|
|
|
* registry and performs operations for each entry found.
|
|
|
|
*
|
|
|
|
* @param ArgumentCount
|
|
|
|
* Number of arguments on the command line.
|
|
|
|
*
|
|
|
|
* @param Arguments
|
|
|
|
* Array of arguments.
|
|
|
|
*
|
|
|
|
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
|
|
|
|
* othwerwise.
|
|
|
|
*
|
|
|
|
* @remarks None.
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
NTSTATUS
|
|
|
|
FASTCALL
|
|
|
|
CsrParseServerCommandLine(IN ULONG ArgumentCount,
|
|
|
|
IN PCHAR Arguments[])
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCHAR ParameterName = NULL, ParameterValue = NULL, EntryPoint, ServerString;
|
|
|
|
ULONG i, DllIndex;
|
|
|
|
ANSI_STRING AnsiString;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
|
|
|
|
/* Set the Defaults */
|
|
|
|
CsrTotalPerProcessDataLength = 0;
|
|
|
|
CsrObjectDirectory = NULL;
|
|
|
|
CsrMaxApiRequestThreads = 16;
|
|
|
|
|
|
|
|
/* Save our Session ID, and create a Directory for it */
|
|
|
|
SessionId = NtCurrentPeb()->SessionId;
|
|
|
|
Status = CsrCreateSessionObjectDirectory(SessionId);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n",
|
|
|
|
Status);
|
|
|
|
|
|
|
|
/* It's not fatal if the session ID isn't zero */
|
|
|
|
if (SessionId) return Status;
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Loop through every argument */
|
|
|
|
for (i = 1; i < ArgumentCount; i++)
|
|
|
|
{
|
|
|
|
/* Split Name and Value */
|
|
|
|
ParameterName = Arguments[i];
|
|
|
|
ParameterValue = NULL;
|
|
|
|
ParameterValue = strchr(ParameterName, '=');
|
|
|
|
if (ParameterValue) *ParameterValue++ = ANSI_NULL;
|
|
|
|
|
|
|
|
/* Check for Object Directory */
|
|
|
|
if (!_stricmp(ParameterName, "ObjectDirectory"))
|
|
|
|
{
|
|
|
|
/* Check if a session ID is specified */
|
|
|
|
if (SessionId)
|
|
|
|
{
|
|
|
|
DPRINT1("Sessions not yet implemented\n");
|
|
|
|
ASSERT(SessionId);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize the directory name */
|
|
|
|
RtlInitAnsiString(&AnsiString, ParameterValue);
|
|
|
|
Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName,
|
|
|
|
&AnsiString,
|
|
|
|
TRUE);
|
|
|
|
ASSERT(NT_SUCCESS(Status) || SessionId != 0);
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
|
|
|
/* Create it */
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&CsrDirectoryName,
|
|
|
|
OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
Status = NtCreateDirectoryObject(&CsrObjectDirectory,
|
|
|
|
DIRECTORY_ALL_ACCESS,
|
|
|
|
&ObjectAttributes);
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
|
|
|
/* Secure it */
|
|
|
|
Status = CsrSetDirectorySecurity(CsrObjectDirectory);
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
}
|
|
|
|
else if (!_stricmp(ParameterName, "SubSystemType"))
|
|
|
|
{
|
|
|
|
/* Ignored */
|
|
|
|
}
|
|
|
|
else if (!_stricmp(ParameterName, "MaxRequestThreads"))
|
|
|
|
{
|
|
|
|
Status = RtlCharToInteger(ParameterValue,
|
|
|
|
0,
|
|
|
|
&CsrMaxApiRequestThreads);
|
|
|
|
}
|
|
|
|
else if (!_stricmp(ParameterName, "RequestThreads"))
|
|
|
|
{
|
|
|
|
/* Ignored */
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else if (!_stricmp(ParameterName, "ProfileControl"))
|
|
|
|
{
|
|
|
|
/* Ignored */
|
|
|
|
}
|
|
|
|
else if (!_stricmp(ParameterName, "SharedSection"))
|
|
|
|
{
|
|
|
|
/* Create the Section */
|
|
|
|
Status = CsrSrvCreateSharedSection(ParameterValue);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n",
|
|
|
|
ParameterName, ParameterValue, Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Load us */
|
|
|
|
BasepFakeStaticServerData();
|
|
|
|
#if 0
|
|
|
|
Status = CsrLoadServerDll("CSRSS", NULL, CSR_SRV_SERVER);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (!_stricmp(ParameterName, "ServerDLL"))
|
|
|
|
{
|
|
|
|
/* Loop the command line */
|
|
|
|
EntryPoint = NULL;
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
ServerString = ParameterValue;
|
|
|
|
while (*ServerString)
|
|
|
|
{
|
|
|
|
/* Check for the Entry Point */
|
|
|
|
if ((*ServerString == ':') && (!EntryPoint))
|
|
|
|
{
|
|
|
|
/* Found it. Add a nullchar and save it */
|
|
|
|
*ServerString++ = ANSI_NULL;
|
|
|
|
EntryPoint = ServerString;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for the Dll Index */
|
|
|
|
if (*ServerString++ == ',') break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Did we find something to load? */
|
|
|
|
if (!*ServerString)
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n",
|
|
|
|
ParameterValue, Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert it to a ULONG */
|
|
|
|
Status = RtlCharToInteger(ServerString, 10, &DllIndex);
|
|
|
|
|
|
|
|
/* Add a null char if it was valid */
|
|
|
|
if (NT_SUCCESS(Status)) ServerString[-1] = ANSI_NULL;
|
|
|
|
|
|
|
|
/* Load it */
|
|
|
|
if (CsrDebug & 1) DPRINT1("CSRSS: Should be loading ServerDll=%s:%s\n", ParameterValue, EntryPoint);
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n",
|
|
|
|
ParameterValue, Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!_stricmp(ParameterName, "Windows"))
|
|
|
|
{
|
|
|
|
/* Ignored */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Invalid parameter on the command line */
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return status */
|
|
|
|
return Status;
|
|
|
|
}
|
2002-06-14 14:23:14 +00:00
|
|
|
|
2012-02-15 19:53:31 +00:00
|
|
|
/*++
|
|
|
|
* @name CsrCreateLocalSystemSD
|
|
|
|
*
|
|
|
|
* The CsrCreateLocalSystemSD routine creates a Security Descriptor for
|
|
|
|
* the local account with PORT_ALL_ACCESS.
|
|
|
|
*
|
|
|
|
* @param LocalSystemSd
|
|
|
|
* Pointer to a pointer to the security descriptor to create.
|
|
|
|
*
|
|
|
|
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
|
|
|
|
* othwerwise.
|
|
|
|
*
|
|
|
|
* @remarks None.
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd)
|
|
|
|
{
|
|
|
|
SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
|
|
|
|
PSID SystemSid;
|
|
|
|
ULONG Length;
|
|
|
|
PSECURITY_DESCRIPTOR SystemSd;
|
|
|
|
PACL Dacl;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Initialize the System SID */
|
|
|
|
RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
|
|
|
|
SECURITY_LOCAL_SYSTEM_RID,
|
|
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
|
|
&SystemSid);
|
|
|
|
|
|
|
|
/* Get the length of the SID */
|
|
|
|
Length = RtlLengthSid(SystemSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
|
|
|
|
|
|
|
|
/* Allocate a buffer for the Security Descriptor, with SID and DACL */
|
|
|
|
SystemSd = RtlAllocateHeap(CsrHeap, 0, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
|
|
|
|
|
|
|
|
/* Set the pointer to the DACL */
|
|
|
|
Dacl = (PACL)((ULONG_PTR)SystemSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
|
|
|
|
|
|
|
|
/* Now create the SD itself */
|
|
|
|
Status = RtlCreateSecurityDescriptor(SystemSd, SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Fail */
|
|
|
|
RtlFreeHeap(CsrHeap, 0, SystemSd);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create the DACL for it*/
|
|
|
|
RtlCreateAcl(Dacl, Length, ACL_REVISION2);
|
|
|
|
|
|
|
|
/* Create the ACE */
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, PORT_ALL_ACCESS, SystemSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Fail */
|
|
|
|
RtlFreeHeap(CsrHeap, 0, SystemSd);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear the DACL in the SD */
|
|
|
|
Status = RtlSetDaclSecurityDescriptor(SystemSd, TRUE, Dacl, FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Fail */
|
|
|
|
RtlFreeHeap(CsrHeap, 0, SystemSd);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free the SID and return*/
|
|
|
|
RtlFreeSid(SystemSid);
|
|
|
|
*LocalSystemSd = SystemSd;
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*++
|
|
|
|
* @name CsrSbApiPortInitialize
|
|
|
|
*
|
|
|
|
* The CsrSbApiPortInitialize routine initializes the LPC Port used for
|
|
|
|
* communications with the Session Manager (SM) and initializes the static
|
|
|
|
* thread that will handle connection requests and APIs.
|
|
|
|
*
|
|
|
|
* @param None
|
|
|
|
*
|
|
|
|
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
|
|
|
|
* othwerwise.
|
|
|
|
*
|
|
|
|
* @remarks None.
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
CsrSbApiPortInitialize(VOID)
|
|
|
|
{
|
|
|
|
ULONG Size;
|
|
|
|
PSECURITY_DESCRIPTOR PortSd;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
NTSTATUS Status;
|
|
|
|
HANDLE hRequestThread;
|
|
|
|
CLIENT_ID ClientId;
|
|
|
|
|
|
|
|
/* Calculate how much space we'll need for the Port Name */
|
|
|
|
Size = CsrDirectoryName.Length + sizeof(SB_PORT_NAME) + sizeof(WCHAR);
|
|
|
|
|
|
|
|
/* Create the buffer for it */
|
|
|
|
CsrSbApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size);
|
|
|
|
if (!CsrSbApiPortName.Buffer) return STATUS_NO_MEMORY;
|
|
|
|
|
|
|
|
/* Setup the rest of the empty string */
|
|
|
|
CsrSbApiPortName.Length = 0;
|
|
|
|
CsrSbApiPortName.MaximumLength = (USHORT)Size;
|
|
|
|
|
|
|
|
/* Now append the full port name */
|
|
|
|
RtlAppendUnicodeStringToString(&CsrSbApiPortName, &CsrDirectoryName);
|
|
|
|
RtlAppendUnicodeToString(&CsrSbApiPortName, UNICODE_PATH_SEP);
|
|
|
|
RtlAppendUnicodeToString(&CsrSbApiPortName, SB_PORT_NAME);
|
|
|
|
if (CsrDebug & 2) DPRINT1("CSRSS: Creating %wZ port and associated thread\n", &CsrSbApiPortName);
|
|
|
|
|
|
|
|
/* Create Security Descriptor for this Port */
|
|
|
|
Status = CsrCreateLocalSystemSD(&PortSd);
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
|
|
|
/* Initialize the Attributes */
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&CsrSbApiPortName,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
PortSd);
|
|
|
|
|
|
|
|
/* Create the Port Object */
|
|
|
|
Status = NtCreatePort(&CsrSbApiPort,
|
|
|
|
&ObjectAttributes,
|
|
|
|
sizeof(SB_CONNECTION_INFO),
|
|
|
|
sizeof(SB_API_MSG),
|
|
|
|
32 * sizeof(SB_API_MSG));
|
|
|
|
if (PortSd) RtlFreeHeap(CsrHeap, 0, PortSd);
|
|
|
|
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Create the Thread to handle the API Requests */
|
|
|
|
Status = RtlCreateUserThread(NtCurrentProcess(),
|
|
|
|
NULL,
|
|
|
|
TRUE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
(PVOID)CsrSbApiRequestThread,
|
|
|
|
NULL,
|
|
|
|
&hRequestThread,
|
|
|
|
&ClientId);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Add it as a Static Server Thread */
|
|
|
|
CsrSbApiRequestThreadPtr = CsrAddStaticServerThread(hRequestThread,
|
|
|
|
&ClientId,
|
|
|
|
0);
|
|
|
|
|
|
|
|
/* Activate it */
|
|
|
|
Status = NtResumeThread(hRequestThread, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2010-03-10 04:59:39 +00:00
|
|
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2012-02-15 19:53:31 +00:00
|
|
|
CsrServerInitialization(IN ULONG ArgumentCount,
|
|
|
|
IN PCHAR Arguments[])
|
1999-06-08 22:50:59 +00:00
|
|
|
{
|
2012-02-15 19:53:31 +00:00
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
DPRINT("CSRSRV: %s called\n", __FUNCTION__);
|
|
|
|
|
|
|
|
/* Create the Init Event */
|
|
|
|
Status = NtCreateEvent(&CsrInitializationEvent,
|
|
|
|
EVENT_ALL_ACCESS,
|
|
|
|
NULL,
|
|
|
|
SynchronizationEvent,
|
|
|
|
FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSRV:%s: NtCreateEvent failed (Status=%08lx)\n",
|
|
|
|
__FUNCTION__, Status);
|
|
|
|
return Status;
|
|
|
|
}
|
2003-12-02 11:38:47 +00:00
|
|
|
|
2012-02-15 19:53:31 +00:00
|
|
|
/* Cache System Basic Information so we don't always request it */
|
|
|
|
Status = NtQuerySystemInformation(SystemBasicInformation,
|
|
|
|
&CsrNtSysInfo,
|
|
|
|
sizeof(SYSTEM_BASIC_INFORMATION),
|
|
|
|
NULL);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSRV:%s: NtQuerySystemInformation failed (Status=%08lx)\n",
|
|
|
|
__FUNCTION__, Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Save our Heap */
|
|
|
|
CsrHeap = RtlGetProcessHeap();
|
2003-12-02 11:38:47 +00:00
|
|
|
|
2012-02-15 19:53:31 +00:00
|
|
|
/* Set our Security Descriptor to protect the process */
|
|
|
|
Status = CsrSetProcessSecurity();
|
2012-02-15 16:11:12 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2012-02-15 19:53:31 +00:00
|
|
|
DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n",
|
|
|
|
__FUNCTION__, Status);
|
|
|
|
return Status;
|
2012-02-15 16:11:12 +00:00
|
|
|
}
|
|
|
|
|
2012-02-16 03:41:18 +00:00
|
|
|
/* Set up Process Support */
|
|
|
|
Status = CsrInitializeProcessStructure();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n",
|
|
|
|
__FUNCTION__, Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2012-02-15 16:11:12 +00:00
|
|
|
/* Parse the command line */
|
|
|
|
Status = CsrParseServerCommandLine(ArgumentCount, Arguments);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n",
|
|
|
|
__FUNCTION__, Status);
|
|
|
|
return Status;
|
|
|
|
}
|
2012-02-15 19:53:31 +00:00
|
|
|
|
|
|
|
Status = CsrApiRegisterDefinitions(NativeDefinitions);
|
2012-02-15 16:11:12 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2012-02-15 19:53:31 +00:00
|
|
|
DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrApiRegisterDefinitions", Status);
|
2012-02-15 16:11:12 +00:00
|
|
|
}
|
|
|
|
|
2012-02-15 19:53:31 +00:00
|
|
|
Status = CsrpCreateListenPort(L"\\Windows\\ApiPort", &hApiPort, (PTHREAD_START_ROUTINE)ClientConnectionThread);
|
2012-02-15 16:11:12 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2012-02-15 19:53:31 +00:00
|
|
|
DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpCreateApiPort", Status);
|
2012-02-15 16:11:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Status = CsrpInitWin32Csr();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpInitWin32Csr", Status);
|
|
|
|
}
|
|
|
|
|
2012-02-15 19:53:31 +00:00
|
|
|
/* Initialize the API Port for SM communication */
|
|
|
|
Status = CsrSbApiPortInitialize();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n",
|
|
|
|
__FUNCTION__, Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We're all set! Connect to SM! */
|
|
|
|
Status = SmConnectToSm(&CsrSbApiPortName,
|
|
|
|
CsrSbApiPort,
|
|
|
|
IMAGE_SUBSYSTEM_WINDOWS_GUI,
|
|
|
|
&CsrSmApiPort);
|
2012-02-15 16:11:12 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2012-02-15 19:53:31 +00:00
|
|
|
DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
|
|
|
|
__FUNCTION__, Status);
|
|
|
|
return Status;
|
2012-02-15 16:11:12 +00:00
|
|
|
}
|
|
|
|
|
2012-02-15 19:53:31 +00:00
|
|
|
/* Finito! Signal the event */
|
|
|
|
Status = NtSetEvent(CsrInitializationEvent, NULL);
|
2012-02-15 16:11:12 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2012-02-15 19:53:31 +00:00
|
|
|
DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n",
|
|
|
|
__FUNCTION__, Status);
|
|
|
|
return Status;
|
2012-02-15 16:11:12 +00:00
|
|
|
}
|
|
|
|
|
2012-02-15 19:53:31 +00:00
|
|
|
/* Close the event handle now */
|
|
|
|
NtClose(CsrInitializationEvent);
|
|
|
|
|
|
|
|
/* Have us handle Hard Errors */
|
2012-02-15 16:11:12 +00:00
|
|
|
Status = NtSetDefaultHardErrorPort(hApiPort);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2012-02-15 19:53:31 +00:00
|
|
|
DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n",
|
|
|
|
__FUNCTION__, Status);
|
|
|
|
return Status;
|
2012-02-15 16:11:12 +00:00
|
|
|
}
|
2012-02-15 19:53:31 +00:00
|
|
|
|
|
|
|
/* Return status */
|
|
|
|
return Status;
|
2010-03-10 04:59:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
NTAPI
|
2011-08-02 22:54:30 +00:00
|
|
|
DllMain(HANDLE hDll,
|
|
|
|
DWORD dwReason,
|
|
|
|
LPVOID lpReserved)
|
2010-03-10 04:59:39 +00:00
|
|
|
{
|
|
|
|
/* We don't do much */
|
|
|
|
UNREFERENCED_PARAMETER(hDll);
|
|
|
|
UNREFERENCED_PARAMETER(dwReason);
|
|
|
|
UNREFERENCED_PARAMETER(lpReserved);
|
|
|
|
return TRUE;
|
1999-06-08 22:50:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|