From 549dd7a6868c7533055ce4d3ea51e78a6334698c Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 3 Nov 2011 07:00:48 +0000 Subject: [PATCH] [KERNEL32]: BaseNamedObjectDirectory should work on demand, instead of on startup. Also, support cases when the thread is doing impersonation, to make sure it uses its real session ID and security access. Also, support cases when the BNO directory is not available, and use the BNO\Restricted directory instead (we should have our CSRSS create it). svn path=/trunk/; revision=54286 --- reactos/dll/win32/kernel32/client/dllmain.c | 10 -- .../dll/win32/kernel32/client/file/filemap.c | 2 +- reactos/dll/win32/kernel32/client/resntfy.c | 2 +- reactos/dll/win32/kernel32/client/utils.c | 95 ++++++++++++++++--- reactos/dll/win32/kernel32/include/base_x.h | 10 +- reactos/dll/win32/kernel32/include/kernel32.h | 3 +- 6 files changed, 91 insertions(+), 31 deletions(-) diff --git a/reactos/dll/win32/kernel32/client/dllmain.c b/reactos/dll/win32/kernel32/client/dllmain.c index 9894b349127..a417d10a908 100644 --- a/reactos/dll/win32/kernel32/client/dllmain.c +++ b/reactos/dll/win32/kernel32/client/dllmain.c @@ -31,7 +31,6 @@ WCHAR BaseDefaultPathBuffer[6140]; HANDLE BaseNamedObjectDirectory; HMODULE hCurrentModule = NULL; HMODULE kernel32_handle = NULL; -HANDLE hBaseDir = NULL; PPEB Peb; ULONG SessionId; BOOL ConsoleInitialized = FALSE; @@ -288,15 +287,6 @@ DllMain(HANDLE hDll, /* Initialize command line */ InitCommandLines(); - /* Open object base directory */ - Status = BaseGetNamedObjectDirectory(); - hBaseDir = BaseNamedObjectDirectory; - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to open object base directory (Status %lx)\n", Status); - return FALSE; - } - /* Initialize the DLL critical section */ RtlInitializeCriticalSection(&BaseDllDirectoryLock); diff --git a/reactos/dll/win32/kernel32/client/file/filemap.c b/reactos/dll/win32/kernel32/client/file/filemap.c index b40b3c858a2..43b52d5a0fa 100644 --- a/reactos/dll/win32/kernel32/client/file/filemap.c +++ b/reactos/dll/win32/kernel32/client/file/filemap.c @@ -312,7 +312,7 @@ OpenFileMappingW(DWORD dwDesiredAccess, InitializeObjectAttributes(&ObjectAttributes, &UnicodeName, (bInheritHandle ? OBJ_INHERIT : 0), - hBaseDir, + BaseGetNamedObjectDirectory(), NULL); /* Convert COPY to READ */ diff --git a/reactos/dll/win32/kernel32/client/resntfy.c b/reactos/dll/win32/kernel32/client/resntfy.c index ac78a1ec0ca..fec93d43be4 100644 --- a/reactos/dll/win32/kernel32/client/resntfy.c +++ b/reactos/dll/win32/kernel32/client/resntfy.c @@ -41,7 +41,7 @@ CreateMemoryResourceNotification(IN MEMORY_RESOURCE_NOTIFICATION_TYPE Notificati InitializeObjectAttributes(&ObjectAttributes, &EventName, 0, - hBaseDir, + BaseGetNamedObjectDirectory(), NULL); Status = NtOpenEvent(&hEvent, diff --git a/reactos/dll/win32/kernel32/client/utils.c b/reactos/dll/win32/kernel32/client/utils.c index 2d62b087c9c..f5fcb5045f0 100644 --- a/reactos/dll/win32/kernel32/client/utils.c +++ b/reactos/dll/win32/kernel32/client/utils.c @@ -22,15 +22,46 @@ /* GLOBALS ********************************************************************/ PRTL_CONVERT_STRING Basep8BitStringToUnicodeString; +UNICODE_STRING Restricted = RTL_CONSTANT_STRING(L"Restricted"); /* FUNCTIONS ******************************************************************/ -NTSTATUS +HANDLE WINAPI BaseGetNamedObjectDirectory(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; + HANDLE DirHandle, BnoHandle, Token, NewToken; + + if (BaseNamedObjectDirectory) return BaseNamedObjectDirectory; + + if (NtCurrentTeb()->IsImpersonating) + { + Status = NtOpenThreadToken(NtCurrentThread(), + TOKEN_IMPERSONATE, + TRUE, + &Token); + if (!NT_SUCCESS(Status)) return BaseNamedObjectDirectory; + + NewToken = NULL; + Status = NtSetInformationThread(NtCurrentThread(), + ThreadImpersonationToken, + &NewToken, + sizeof(HANDLE)); + if (!NT_SUCCESS (Status)) + { + NtClose(Token); + return BaseNamedObjectDirectory; + } + } + else + { + Token = NULL; + } + + RtlAcquirePebLock(); + if (BaseNamedObjectDirectory) goto Quickie; InitializeObjectAttributes(&ObjectAttributes, &BaseStaticServerData->NamedObjectDirectory, @@ -38,14 +69,54 @@ BaseGetNamedObjectDirectory(VOID) NULL, NULL); - Status = NtOpenDirectoryObject(&BaseNamedObjectDirectory, - DIRECTORY_ALL_ACCESS & - ~(DELETE | WRITE_DAC | WRITE_OWNER), + Status = NtOpenDirectoryObject(&BnoHandle, + DIRECTORY_QUERY | + DIRECTORY_TRAVERSE | + DIRECTORY_CREATE_OBJECT | + DIRECTORY_CREATE_SUBDIRECTORY, &ObjectAttributes); - if (!NT_SUCCESS(Status)) return Status; + if (!NT_SUCCESS(Status)) + { + Status = NtOpenDirectoryObject(&DirHandle, + DIRECTORY_TRAVERSE, + &ObjectAttributes); - DPRINT("Opened BNO: %lx\n", BaseNamedObjectDirectory); - return Status; + if (NT_SUCCESS(Status)) + { + InitializeObjectAttributes(&ObjectAttributes, + (PUNICODE_STRING)&Restricted, + OBJ_CASE_INSENSITIVE, + DirHandle, + NULL); + + Status = NtOpenDirectoryObject(&BnoHandle, + DIRECTORY_QUERY | + DIRECTORY_TRAVERSE | + DIRECTORY_CREATE_OBJECT | + DIRECTORY_CREATE_SUBDIRECTORY, + &ObjectAttributes); + NtClose(DirHandle); + + } + } + + if (NT_SUCCESS(Status)) BaseNamedObjectDirectory = BnoHandle; + +Quickie: + + RtlReleasePebLock(); + + if (Token) + { + NtSetInformationThread(NtCurrentThread(), + ThreadImpersonationToken, + &Token, + sizeof(Token)); + + NtClose(Token); + } + + return BaseNamedObjectDirectory; } VOID @@ -224,7 +295,7 @@ BaseFormatObjectAttributes(OUT POBJECT_ATTRIBUTES ObjectAttributes, if (ObjectName) { Attributes |= OBJ_OPENIF; - RootDirectory = hBaseDir; + RootDirectory = BaseGetNamedObjectDirectory(); } else { @@ -282,10 +353,10 @@ BaseCreateStack(HANDLE hProcess, { StackReserve = ROUND_UP(StackCommit, 1024 * 1024); } - + StackCommit = ROUND_UP(StackCommit, PageSize); StackReserve = ROUND_UP(StackReserve, AllocationGranularity); - + GuaranteedStackCommit = NtCurrentTeb()->GuaranteedStackBytes; if ((GuaranteedStackCommit) && (StackCommit < GuaranteedStackCommit)) { @@ -299,7 +370,7 @@ BaseCreateStack(HANDLE hProcess, StackCommit = ROUND_UP(StackCommit, PageSize); StackReserve = ROUND_UP(StackReserve, AllocationGranularity); - + /* ROS Hack until we support guard page stack expansion */ StackCommit = StackReserve; @@ -337,7 +408,7 @@ BaseCreateStack(HANDLE hProcess, { UseGuard = FALSE; } - + /* Allocate memory for the stack */ Status = ZwAllocateVirtualMemory(hProcess, (PVOID*)&Stack, diff --git a/reactos/dll/win32/kernel32/include/base_x.h b/reactos/dll/win32/kernel32/include/base_x.h index b25540fad58..faca2f97d56 100644 --- a/reactos/dll/win32/kernel32/include/base_x.h +++ b/reactos/dll/win32/kernel32/include/base_x.h @@ -100,7 +100,7 @@ POBJECT_ATTRIBUTES ObjectAttributes = &LocalAttributes; #define CreateNtObjectFromWin32ApiBody(ntobj, sec, name, access, ...) \ if (name) RtlInitUnicodeString(&ObjectName, name); \ - ObjectAttributes = BaseFormatObjectAttributes(&LocalAttributes, \ + ObjectAttributes = BaseFormatObjectAttributes(&LocalAttributes, \ sec, \ name ? &ObjectName : NULL); \ Status = NtCreate##ntobj(&Handle, access, ObjectAttributes, ##__VA_ARGS__); @@ -113,7 +113,7 @@ SetLastError(ERROR_SUCCESS); \ return Handle; \ } \ - BaseSetLastNTError(Status); \ + BaseSetLastNTError(Status); \ return NULL; \ } @@ -138,19 +138,19 @@ CreateNtObjectFromWin32ApiPrologue \ if (!name) \ { \ - BaseSetLastNTError(STATUS_INVALID_PARAMETER); \ + BaseSetLastNTError(STATUS_INVALID_PARAMETER); \ return NULL; \ } \ RtlInitUnicodeString(&ObjectName, name); \ InitializeObjectAttributes(ObjectAttributes, \ &ObjectName, \ inh ? OBJ_INHERIT : 0, \ - hBaseDir, \ + BaseGetNamedObjectDirectory(), \ NULL); \ Status = NtOpen##ntobj(&Handle, acc, ObjectAttributes); \ if (!NT_SUCCESS(Status)) \ { \ - BaseSetLastNTError(Status); \ + BaseSetLastNTError(Status); \ return NULL; \ } \ return Handle; \ diff --git a/reactos/dll/win32/kernel32/include/kernel32.h b/reactos/dll/win32/kernel32/include/kernel32.h index f00a3e6431a..f5994447a04 100644 --- a/reactos/dll/win32/kernel32/include/kernel32.h +++ b/reactos/dll/win32/kernel32/include/kernel32.h @@ -109,7 +109,6 @@ extern WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle; /* GLOBAL VARIABLES **********************************************************/ extern BOOL bIsFileApiAnsi; -extern HANDLE hBaseDir; extern HMODULE hCurrentModule; extern RTL_CRITICAL_SECTION BaseDllDirectoryLock; @@ -243,7 +242,7 @@ typedef NTSTATUS (NTAPI *PRTL_CONVERT_STRING)(IN PUNICODE_STRING UnicodeString, extern PRTL_CONVERT_STRING Basep8BitStringToUnicodeString; extern HANDLE BaseNamedObjectDirectory; -NTSTATUS +HANDLE WINAPI BaseGetNamedObjectDirectory(VOID);