+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR Sub System
- * FILE: subsys/csr/csrsrv/init.c
- * PURPOSE: CSR Server DLL Initialization
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include "srv.h"
-
-#define NDEBUG
-#include <debug.h>
-
-/* DATA **********************************************************************/
-
-HANDLE CsrObjectDirectory;
-ULONG SessionId;
-BOOLEAN CsrProfileControl;
-UNICODE_STRING CsrDirectoryName;
-HANDLE CsrHeap;
-HANDLE BNOLinksDirectory;
-HANDLE SessionObjectDirectory;
-HANDLE DosDevicesDirectory;
-HANDLE CsrInitializationEvent;
-SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
-ULONG CsrDebug;
-
-/* PRIVATE FUNCTIONS *********************************************************/
-
-/*++
- * @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 = 0;
- 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;
- DPRINT1("Name=%s, Value=%s\n", ParameterName, ParameterValue);
-
- /* 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"))
- {
- /* Craete 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 */
- Status = CsrLoadServerDll("CSRSS", NULL, CSR_SRV_SERVER);
- }
- 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: Loading ServerDll=%s:%s\n", ParameterValue, EntryPoint);
- Status = CsrLoadServerDll(ParameterValue, EntryPoint, DllIndex);
- 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;
-}
-
-/*++
- * @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 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);
-
-/* FIXME: semi-failure cases! Quickie: */
-Quickie:
- /* Free the SIDs */
- RtlFreeSid(SystemSid);
- RtlFreeSid(WorldSid);
- RtlFreeSid(AdminSid);
- RtlFreeSid(CreatorSid);
-
- /* Return */
- return Status;
-}
-
-/*++
- * @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)
-{
- 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);
-}
-
-/*++
- * @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)
-{
- 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;
-}
-
-/*++
- * @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)
-{
- NTSTATUS Status;
- HANDLE hToken, hProcess = NtCurrentProcess();
- ULONG ReturnLength, Length;
- PTOKEN_USER TokenInfo = NULL;
- PSECURITY_DESCRIPTOR ProcSd = NULL;
- PACL Dacl;
- PSID UserSid;
-
- /* Open our token */
- Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
- if (!NT_SUCCESS(Status)) goto Quickie;
-
- /* Get the Token User Length */
- NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length);
-
- /* Allocate space for it */
- TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length);
- if (!TokenInfo)
- {
- Status = STATUS_NO_MEMORY;
- goto Quickie;
- }
-
- /* 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;
- ReturnLength = 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);
- if (!NT_SUCCESS(Status)) goto Quickie;
-
- /* Create the DACL for it*/
- RtlCreateAcl(Dacl, Length, ACL_REVISION2);
-
- /* 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)) goto Quickie;
-
- /* Clear the DACL in the SD */
- Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE);
- if (!NT_SUCCESS(Status)) goto Quickie;
-
- /* Write the SD into the Process */
- Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd);
-
- /* Free the memory and return */
-Quickie:
- if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd);
- RtlFreeHeap(CsrHeap, 0, TokenInfo);
- return Status;
-}
-
-/*++
- * @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)
-{
- /* FIXME: Implement */
- return STATUS_SUCCESS;
-}
-
-/* PUBLIC FUNCTIONS **********************************************************/
-
-/*++
- * @name CsrServerInitialization
- * @implemented NT4
- *
- * The CsrServerInitialization routine is the native (not Server) entrypoint
- * of this Server DLL. It serves as the entrypoint for csrss.
- *
- * @param ArgumentCount
- * Number of arguments on the command line.
- *
- * @param Arguments
- * Array of arguments from the command line.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrServerInitialization(IN ULONG ArgumentCount,
- IN PCHAR Arguments[])
-{
- NTSTATUS Status = STATUS_SUCCESS;
- ULONG i = 0;
- PVOID ProcessData;
- PCSR_SERVER_DLL ServerDll;
- 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;
- }
-
- /* 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();
-
- /* Set our Security Descriptor to protect the process */
- Status = CsrSetProcessSecurity();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Set up Session Support */
- Status = CsrInitializeNtSessionList();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Set up Process Support */
- Status = CsrInitializeProcessStructure();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Parse the command line */
- Status = CsrParseServerCommandLine(ArgumentCount, Arguments);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* All Server DLLs are now loaded, allocate a heap for the Root Process */
- ProcessData = RtlAllocateHeap(CsrHeap,
- HEAP_ZERO_MEMORY,
- CsrTotalPerProcessDataLength);
- if (!ProcessData)
- {
- DPRINT1("CSRSRV:%s: RtlAllocateHeap failed (Status=%08lx)\n",
- __FUNCTION__, STATUS_NO_MEMORY);
- return STATUS_NO_MEMORY;
- }
-
- /*
- * Our Root Process was never officially initalized, so write the data
- * for each Server DLL manually.
- */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Get the current Server */
- ServerDll = CsrLoadedServerDll[i];
-
- /* Is it loaded, and does it have per process data? */
- if ((ServerDll) && (ServerDll->SizeOfProcessData))
- {
- /* It does, give it part of our allocated heap */
- CsrRootProcess->ServerData[i] = ProcessData;
-
- /* Move to the next heap position */
- ProcessData = (PVOID)((ULONG_PTR)ProcessData +
- ServerDll->SizeOfProcessData);
- }
- else
- {
- /* Nothing for this Server DLL */
- CsrRootProcess->ServerData[i] = NULL;
- }
- }
-
- /* Now initialize the Root Process manually as well */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Get the current Server */
- ServerDll = CsrLoadedServerDll[i];
-
- /* Is it loaded, and does it a callback for new processes? */
- if ((ServerDll) && (ServerDll->NewProcessCallback))
- {
- /* Call the callback */
- ServerDll->NewProcessCallback(NULL, CsrRootProcess);
- }
- }
-
- /* Now initialize our API Port */
- Status = CsrApiPortInitialize();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* 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);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Finito! Signal the event */
- Status = NtSetEvent(CsrInitializationEvent, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Close the event handle now */
- NtClose(CsrInitializationEvent);
-
- /* Have us handle Hard Errors */
- Status = NtSetDefaultHardErrorPort(CsrApiPort);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
-
- /* Return status */
- return Status;
-}
-
-/*++
- * @name CsrPopulateDosDevices
- * @unimplemented NT5.1
- *
- * The CsrPopulateDosDevices routine uses the DOS Device Map from the Kernel
- * to populate the Dos Devices Object Directory for the session.
- *
- * @param None.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrPopulateDosDevices(VOID)
-{
- DPRINT1("Deprecated API\n");
- return;
-}
-
-BOOL
-NTAPI
-DllMain(IN HANDLE hDll,
- IN DWORD dwReason,
- IN LPVOID lpReserved)
-{
- /* We don't do much */
- UNREFERENCED_PARAMETER(hDll);
- UNREFERENCED_PARAMETER(dwReason);
- UNREFERENCED_PARAMETER(lpReserved);
- return TRUE;
-}
-
-/* EOF */