[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
This commit is contained in:
Alex Ionescu 2011-11-03 07:00:48 +00:00
parent 4ba4fdcb2c
commit 549dd7a686
6 changed files with 91 additions and 31 deletions

View file

@ -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);

View file

@ -312,7 +312,7 @@ OpenFileMappingW(DWORD dwDesiredAccess,
InitializeObjectAttributes(&ObjectAttributes,
&UnicodeName,
(bInheritHandle ? OBJ_INHERIT : 0),
hBaseDir,
BaseGetNamedObjectDirectory(),
NULL);
/* Convert COPY to READ */

View file

@ -41,7 +41,7 @@ CreateMemoryResourceNotification(IN MEMORY_RESOURCE_NOTIFICATION_TYPE Notificati
InitializeObjectAttributes(&ObjectAttributes,
&EventName,
0,
hBaseDir,
BaseGetNamedObjectDirectory(),
NULL);
Status = NtOpenEvent(&hEvent,

View file

@ -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,

View file

@ -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; \

View file

@ -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);