- ImperstionationLocale -> ImpersonationLocale.

- Implement PspWriteTebImpersonationInfo for setting the impersonation locale and impersonation status in the TEB (since User-mode needs to read this value and we don't want to NtQueryInformationThread for it each time to read the ETHERAD flag).
- Complete the implementation of PspSetPrimaryToken to recalculate a process's access rights to itself based on a new primary token.
- Reorganize ps.h header like ob.h and io.h, implement Tracing support but not the tracing itself yet.
- Get rid of some deprecated cruft.

svn path=/trunk/; revision=23233
This commit is contained in:
Alex Ionescu 2006-07-23 05:43:28 +00:00
parent 04e0d8c7bf
commit 90ea51a96b
7 changed files with 352 additions and 160 deletions

View file

@ -780,7 +780,7 @@ typedef struct _TEB
ULONG SoftPatchPtr1;
ULONG SoftPatchPtr2;
PVOID *TlsExpansionSlots;
ULONG ImpersionationLocale;
ULONG ImpersonationLocale;
ULONG IsImpersonating;
PVOID NlsCache;
PVOID pShimData;

View file

@ -30,8 +30,6 @@
// - Add security calls where necessary.
// - Add tracing.
// - Add failure/race checks for thread creation.
// - Complete PspSetPrimaryToken.
// - Update TEB Security information when impersonating.
//
// Ob:
// - Possible bug in deferred deletion under Cc Rewrite branch.

View file

@ -1,13 +0,0 @@
#ifndef __NTOSKRNL_INCLUDE_INTERNAL_ARCH_PS_H
#define __NTOSKRNL_INCLUDE_INTERNAL_ARCH_PS_H
#ifdef _M_IX86
#define KiArchContextSwitch KiSwapContext
#define KiArchInitThreadWithContext Ke386InitThreadWithContext
#else
#error "Unknown processor"
#endif
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_ARCH_PS_H */
/* EOF */

View file

@ -5,6 +5,7 @@
* PURPOSE: Internal header for the Object Manager
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
//
// Define this if you want debugging support
//

View file

@ -1,61 +1,160 @@
#ifndef __INCLUDE_INTERNAL_PS_H
#define __INCLUDE_INTERNAL_PS_H
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/include/ps.h
* PURPOSE: Internal header for the Process Manager
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* Forward declarations. */
struct _KTHREAD;
struct _KTRAPFRAME;
struct _EJOB;
//
// Define this if you want debugging support
//
#define _PS_DEBUG_ 0x00
#include <internal/arch/ps.h>
//
// These define the Debug Masks Supported
//
#define PS_THREAD_DEBUG 0x01
#define PS_PROCESS_DEBUG 0x02
#define PS_SECURITY_DEBUG 0x04
#define PS_JOB_DEBUG 0x08
#define PS_NOTIFICATIONS_DEBUG 0x10
#define PS_WIN32K_DEBUG 0x20
#define PS_STATE_DEBUG 0x40
#define PS_QUOTA_DEBUG 0x80
/* Top level irp definitions. */
#define FSRTL_FSP_TOP_LEVEL_IRP (0x01)
#define FSRTL_CACHE_TOP_LEVEL_IRP (0x02)
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP (0x03)
#define FSRTL_FAST_IO_TOP_LEVEL_IRP (0x04)
#define FSRTL_MAX_TOP_LEVEL_IRP_FLAG (0x04)
//
// Debug/Tracing support
//
#if _PS_DEBUG_
#ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
#define PSTRACE DbgPrintEx
#else
#define PSTRACE(x, ...) \
if (x & PspTraceLevel) DbgPrint(__VA_ARGS__)
#endif
#else
#define PSTRACE(x, ...) DPRINT(__VA_ARGS__)
#endif
//
// Maximum Count of Notification Routines
//
#define PSP_MAX_CREATE_THREAD_NOTIFY 8
#define PSP_MAX_LOAD_IMAGE_NOTIFY 8
#define PSP_MAX_CREATE_PROCESS_NOTIFY 8
//
// Maximum Job Scheduling Classes
//
#define PSP_JOB_SCHEDULING_CLASSES 10
//
// Initialization Functions
//
VOID
NTAPI
PspShutdownProcessManager(VOID);
VOID
NTAPI
PsInitThreadManagment(VOID);
PspShutdownProcessManager(
VOID
);
VOID
INIT_FUNCTION
NTAPI
PiInitProcessManager(VOID);
PsInitThreadManagment(
VOID
);
VOID
INIT_FUNCTION
NTAPI
PsInitProcessManagment(VOID);
PiInitProcessManager(
VOID
);
VOID
INIT_FUNCTION
NTAPI
PsInitIdleThread(VOID);
PsInitProcessManagment(
VOID
);
PACCESS_TOKEN
STDCALL
PsReferenceEffectiveToken(
PETHREAD Thread,
PTOKEN_TYPE TokenType,
PUCHAR b,
PSECURITY_IMPERSONATION_LEVEL Level
VOID
INIT_FUNCTION
NTAPI
PsInitIdleThread(
VOID
);
NTSTATUS
STDCALL
NTAPI
PsInitializeIdleOrFirstThread(
IN PEPROCESS Process,
OUT PETHREAD* ThreadPtr,
IN PKSTART_ROUTINE StartRoutine,
IN KPROCESSOR_MODE AccessMode,
IN BOOLEAN First
);
VOID
NTAPI
INIT_FUNCTION
PsInitJobManagment(
VOID
);
//
// Utility Routines
//
PETHREAD
NTAPI
PsGetNextProcessThread(
IN PEPROCESS Process,
IN PETHREAD Thread OPTIONAL
);
PEPROCESS
NTAPI
PsGetNextProcess(
IN PEPROCESS OldProcess OPTIONAL
);
NTSTATUS
NTAPI
PspMapSystemDll(
IN PEPROCESS Process,
OUT PVOID *DllBase
);
NTSTATUS
NTAPI
PsLocateSystemDll(
VOID
);
NTSTATUS
NTAPI
PspGetSystemDllEntryPoints(
VOID
);
//
// Security Routines
//
PACCESS_TOKEN
NTAPI
PsReferenceEffectiveToken(
IN PETHREAD Thread,
OUT PTOKEN_TYPE TokenType,
OUT PUCHAR b,
OUT PSECURITY_IMPERSONATION_LEVEL Level
);
NTSTATUS
NTAPI
PsOpenTokenOfProcess(
HANDLE ProcessHandle,
PACCESS_TOKEN* Token
IN HANDLE ProcessHandle,
OUT PACCESS_TOKEN* Token
);
NTSTATUS
@ -66,15 +165,30 @@ PspSetPrimaryToken(
IN PTOKEN Token OPTIONAL
);
PETHREAD
NTSTATUS
NTAPI
PsGetNextProcessThread(
PspInitializeProcessSecurity(
IN PEPROCESS Process,
IN PETHREAD Thread OPTIONAL
IN PEPROCESS Parent OPTIONAL
);
VOID
STDCALL
NTAPI
PspDeleteProcessSecurity(
IN PEPROCESS Process
);
VOID
NTAPI
PspDeleteThreadSecurity(
IN PETHREAD Thread
);
//
// Reaping and Deletion
//
VOID
NTAPI
PsExitSpecialApc(
PKAPC Apc,
PKNORMAL_ROUTINE *NormalRoutine,
@ -83,97 +197,101 @@ PsExitSpecialApc(
PVOID *SystemArgument2
);
NTSTATUS
STDCALL
PspInitializeProcessSecurity(
PEPROCESS Process,
PEPROCESS Parent OPTIONAL
VOID
NTAPI
PspReapRoutine(
IN PVOID Context
);
VOID
STDCALL
NTAPI
PspExitThread(
IN NTSTATUS ExitStatus
);
NTSTATUS
NTAPI
PspTerminateThreadByPointer(
IN PETHREAD Thread,
IN NTSTATUS ExitStatus,
IN BOOLEAN bSelf
);
VOID
NTAPI
PspExitProcess(
IN BOOLEAN LastThread,
IN PEPROCESS Process
);
VOID
NTAPI
PspDeleteProcess(
IN PVOID ObjectBody
);
VOID
NTAPI
PspDeleteThread(
IN PVOID ObjectBody
);
//
// Thread/Process Startup
//
VOID
NTAPI
PspSystemThreadStartup(
PKSTART_ROUTINE StartRoutine,
PVOID StartContext
);
NTSTATUS
NTAPI
PsInitializeIdleOrFirstThread(
PEPROCESS Process,
PETHREAD* ThreadPtr,
PKSTART_ROUTINE StartRoutine,
KPROCESSOR_MODE AccessMode,
BOOLEAN First
);
VOID
STDCALL
PspReapRoutine(PVOID Context);
VOID
STDCALL
PspExitThread(NTSTATUS ExitStatus);
NTSTATUS
STDCALL
PspTerminateThreadByPointer(
PETHREAD Thread,
NTSTATUS ExitStatus,
BOOLEAN bSelf
);
PEPROCESS
STDCALL
PsGetNextProcess(PEPROCESS OldProcess);
VOID
STDCALL
PsIdleThreadMain(PVOID Context);
VOID
STDCALL
PspExitProcess(BOOLEAN LastThread,
PEPROCESS Process);
VOID
STDCALL
PspDeleteProcess(PVOID ObjectBody);
VOID
STDCALL
PspDeleteThread(PVOID ObjectBody);
VOID
NTAPI
INIT_FUNCTION
PsInitJobManagment(VOID);
PsIdleThreadMain(
IN PVOID Context
);
//
// Quota Support
//
VOID
STDCALL
NTAPI
PspInheritQuota(
PEPROCESS Process,
PEPROCESS ParentProcess
IN PEPROCESS Process,
IN PEPROCESS ParentProcess
);
VOID
STDCALL
PspDestroyQuotaBlock(PEPROCESS Process);
NTAPI
PspDestroyQuotaBlock(
IN PEPROCESS Process
);
//
// VDM Support
//
NTSTATUS
STDCALL
PspMapSystemDll(
PEPROCESS Process,
PVOID *DllBase
NTAPI
PspDeleteLdt(
IN PEPROCESS Process
);
NTSTATUS
STDCALL
PsLocateSystemDll(VOID);
NTAPI
PspDeleteVdmObjects(
IN PEPROCESS Process
);
NTSTATUS
STDCALL
PspGetSystemDllEntryPoints(VOID);
//
// Job Routines
//
VOID
NTAPI
PspExitProcessFromJob(
IN PEJOB Job,
IN PEPROCESS Process
);
VOID
NTAPI
@ -182,29 +300,10 @@ PspRemoveProcessFromJob(
IN PEJOB Job
);
NTSTATUS
NTAPI
PspDeleteLdt(IN PEPROCESS Process);
NTSTATUS
NTAPI
PspDeleteVdmObjects(IN PEPROCESS Process);
VOID
NTAPI
PspDeleteProcessSecurity(IN PEPROCESS Process);
VOID
NTAPI
PspDeleteThreadSecurity(IN PETHREAD Thread);
VOID
NTAPI
PspExitProcessFromJob(
IN PEJOB Job,
IN PEPROCESS Process
);
//
// Global data inside the Process Manager
//
extern ULONG PspTraceLevel;
extern LCID PsDefaultThreadLocaleId;
extern LCID PsDefaultSystemLocaleId;
extern LIST_ENTRY PspReaperListHead;
@ -231,6 +330,8 @@ extern PVOID PspSystemDllEntryPoint;
extern PVOID PspSystemDllBase;
extern BOOLEAN PspUseJobSchedulingClasses;
extern CHAR PspJobSchedulingClasses[PSP_JOB_SCHEDULING_CLASSES];
#include "ps_x.h"
#endif /* __INCLUDE_INTERNAL_PS_H */
//
// Inlined Functions
//
#include "ps_x.h"

View file

@ -187,7 +187,7 @@ KiDispatchThreadNoLock(ULONG NewThreadStatus)
/* Special note for Filip: This will release the Dispatcher DB Lock ;-) -- Alex */
DPRINT("You are : %x, swapping to: %x\n", OldThread, CurrentThread);
KiArchContextSwitch(CurrentThread);
KiSwapContext(CurrentThread);
DPRINT("You are : %x, swapped from: %x\n", OldThread, CurrentThread);
return;
}
@ -841,11 +841,11 @@ KeInitThread(IN OUT PKTHREAD Thread,
_SEH_TRY
{
/* Initalize the Thread Context */
KiArchInitThreadWithContext(Thread,
SystemRoutine,
StartRoutine,
StartContext,
Context);
Ke386InitThreadWithContext(Thread,
SystemRoutine,
StartRoutine,
StartContext,
Context);
}
_SEH_HANDLE
{

View file

@ -97,6 +97,75 @@ PspInitializeProcessSecurity(IN PEPROCESS Process,
return Status;
}
NTSTATUS
NTAPI
PspWriteTebImpersonationInfo(IN PETHREAD Thread,
IN PETHREAD CurrentThread)
{
PEPROCESS Process;
PTEB Teb;
BOOLEAN Attached = FALSE;
BOOLEAN IsImpersonating;
KAPC_STATE ApcState;
PAGED_CODE();
/* Sanity check */
ASSERT(CurrentThread == PsGetCurrentThread());
/* Get process and TEB */
Process = Thread->ThreadsProcess;
Teb = Thread->Tcb.Teb;
if (Teb)
{
/* Check if we're not in the right process */
if (Thread->Tcb.ApcState.Process != &Process->Pcb)
{
/* Attach to the process */
KeStackAttachProcess(&Process->Pcb, &ApcState);
Attached = TRUE;
}
/* Check if we're in a different thread */
if (Thread != CurrentThread)
{
/* Acquire thread rundown protection */
ExAcquireRundownProtection(&Thread->RundownProtect);
}
/* Check if the thread is impersonating */
IsImpersonating = Thread->ActiveImpersonationInfo;
if (IsImpersonating)
{
/* Set TEB data */
Teb->ImpersonationLocale = -1;
Teb->IsImpersonating = 1;
}
else
{
/* Set TEB data */
Teb->ImpersonationLocale = 0;
Teb->IsImpersonating = 0;
}
/* Set new flag */
Thread->ActiveImpersonationInfo = TRUE;
/* Check if we're in a different thread */
if (Thread != CurrentThread)
{
/* Release protection */
ExReleaseRundownProtection(&Thread->RundownProtect);
}
/* Dettach */
if (Attached) KeUnstackDetachProcess(&ApcState);
}
/* Return to caller */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
PspAssignPrimaryToken(IN PEPROCESS Process,
@ -129,7 +198,10 @@ PspSetPrimaryToken(IN PEPROCESS Process,
{
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
BOOLEAN IsChild;
NTSTATUS Status;
NTSTATUS Status, AccessStatus;
BOOLEAN Result, SdAllocated;
PSECURITY_DESCRIPTOR SecurityDescriptor;
SECURITY_SUBJECT_CONTEXT SubjectContext;
/* Make sure we got a handle */
if (TokenHandle)
@ -171,14 +243,42 @@ PspSetPrimaryToken(IN PEPROCESS Process,
if (NT_SUCCESS(Status))
{
/*
* The idea here is that we need to completely reverify
* if the process still has access to itself under this new
* token, by doing an SeAccessCheck with the Primary Token and
* the SD of the Process (ObGetObjectSecurity).
* In the really twisted case where we lose access to ourselves,
* we would set Process->GrantedAccess to 0.
* We need to completely reverify if the process still has access to
* itself under this new token.
*/
DPRINT1("Process security not complete\n");
Status = ObGetObjectSecurity(Process,
&SecurityDescriptor,
&SdAllocated);
if (NT_SUCCESS(Status))
{
/* Setup the security context */
SubjectContext.ProcessAuditId = Process;
SubjectContext.PrimaryToken = PsReferencePrimaryToken(Process);
SubjectContext.ClientToken = NULL;
/* Do the access check */
Result = SeAccessCheck(SecurityDescriptor,
&SubjectContext,
FALSE,
MAXIMUM_ALLOWED,
0,
NULL,
&PsProcessType->TypeInfo.GenericMapping,
PreviousMode,
&Process->GrantedAccess,
&AccessStatus);
/* Dereference the token and let go the SD */
ObFastDereferenceObject(&Process->Token,
SubjectContext.PrimaryToken);
ObReleaseObjectSecurity(SecurityDescriptor, SdAllocated);
/* Remove access if it failed */
if (!Result) Process->GrantedAccess = 0;
}
/* Dereference the process */
ObDereferenceObject(Process);
}
/* Dereference the token */
@ -437,6 +537,9 @@ PsRevertThreadToSelf(IN PETHREAD Thread)
/* Dereference the impersonation token */
if (Token) ObDereferenceObject(Token);
/* Write impersonation info to the TEB */
PspWriteTebImpersonationInfo(Thread, PsGetCurrentThread());
}
/*
@ -529,8 +632,10 @@ PsImpersonateClient(IN PETHREAD Thread,
PspUnlockThreadSecurityExclusive(Thread);
}
/* Write impersonation info to the TEB */
PspWriteTebImpersonationInfo(Thread, PsGetCurrentThread());
/* Dereference the token and return success */
ObReferenceObject(Token);
if (OldToken) ObDereferenceObject(OldToken);
return STATUS_SUCCESS;
}