Author: ion
Date: Tue Jul 18 19:13:55 2006
New Revision: 23152
URL:
http://svn.reactos.org/svn/reactos?rev=23152&view=rev
Log:
[AUDIT] security.c is mostly composed of trivial implementations of APIs that transfer one
set of data from another, or simply wrap around complex Se* functions which do the actual
work. There are one or two slightly more complex APIs (~15-20 lines), but they were
written by Eric/Thomas, which are well-known for always writing clean code.
[FORMATTING] Re-formatted file properly, ordered functions and annotated them, added
proper programmer credits, etc.
- Pushlocks need to be acquired in a -critical-, not -guarded- region.
- PsDisableImpersonation should return FALSE if it was already disbled.
- Don't forget to reference the token in PsReferenceEffectiveToken.
- PsImpersonateClient should still return success if it was given no token.
- PsImperstonateClient should de-reference the token if there is already active
impersonation info.
Modified:
trunk/reactos/ntoskrnl/KrnlFun.c
trunk/reactos/ntoskrnl/include/internal/tag.h
trunk/reactos/ntoskrnl/ps/security.c (contents, props changed)
Modified: trunk/reactos/ntoskrnl/KrnlFun.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/KrnlFun.c?rev=231…
==============================================================================
--- trunk/reactos/ntoskrnl/KrnlFun.c (original)
+++ trunk/reactos/ntoskrnl/KrnlFun.c Tue Jul 18 19:13:55 2006
@@ -29,6 +29,7 @@
// - Use Process Pushlock Locks.
// - Use Safe Referencing in PsGetNextProcess/Thread.
// - Use Guarded Mutex instead of Fast Mutex for Active Process Locks.
+// - Use Security Locks in security.c
// - Fix referencing problem.
// - Generate process cookie for user-more thread.
// - Add security calls where necessary.
Modified: trunk/reactos/ntoskrnl/include/internal/tag.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/tag.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/tag.h Tue Jul 18 19:13:55 2006
@@ -130,6 +130,7 @@
/* formerly located in ps/cid.c */
#define TAG_CIDOBJECT TAG('C', 'I', 'D', 'O')
+#define TAG_PS_IMPERSONATION TAG('P', 's', 'I', 'm')
/* formerly located in ps/job.c */
#define TAG_EJOB TAG('E', 'J', 'O', 'B') /* EJOB */
Modified: trunk/reactos/ntoskrnl/ps/security.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/security.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ps/security.c (original)
+++ trunk/reactos/ntoskrnl/ps/security.c Tue Jul 18 19:13:55 2006
@@ -1,10 +1,11 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ps/security.c
- * PURPOSE: Process Manager Security (Tokens, Impersionation)
- *
- * PROGRAMMERS: David Welch (welch(a)cwcom.net)
+ * PURPOSE: Process Manager: Process/Thread Security
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Eric Kohl
+ * Thomas Weidenmueller (w3seek(a)reactos.org)
*/
/* INCLUDES ******************************************************************/
@@ -13,15 +14,15 @@
#define NDEBUG
#include <internal/debug.h>
-/* INTERNAL ******************************************************************/
+/* PRIVATE FUNCTIONS *********************************************************/
/* FIXME: Turn into Macro */
VOID
-STDCALL
-PspLockProcessSecurityShared(PEPROCESS Process)
-{
- /* Enter a Guarded Region */
- KeEnterGuardedRegion();
+NTAPI
+PspLockProcessSecurityShared(IN PEPROCESS Process)
+{
+ /* Enter a Critical Region */
+ KeEnterCriticalRegion();
/* Lock the Process */
//ExAcquirePushLockShared(&Process->ProcessLock);
@@ -29,14 +30,14 @@
/* FIXME: Turn into Macro */
VOID
-STDCALL
-PspUnlockProcessSecurityShared(PEPROCESS Process)
+NTAPI
+PspUnlockProcessSecurityShared(IN PEPROCESS Process)
{
/* Unlock the Process */
//ExReleasePushLockShared(&Process->ProcessLock);
- /* Leave Guarded Region */
- KeLeaveGuardedRegion();
+ /* Leave Critical Region */
+ KeLeaveCriticalRegion();
}
VOID
@@ -73,153 +74,10 @@
}
}
-/* FUNCTIONS *****************************************************************/
-
-/*
- * @implemented
- */
-NTSTATUS
-STDCALL
-NtOpenProcessToken(IN HANDLE ProcessHandle,
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE TokenHandle)
-{
- return NtOpenProcessTokenEx(ProcessHandle,
- DesiredAccess,
- 0,
- TokenHandle);
-}
-
-/*
- * @implemented
- */
-NTSTATUS
-STDCALL
-NtOpenProcessTokenEx(IN HANDLE ProcessHandle,
- IN ACCESS_MASK DesiredAccess,
- IN ULONG HandleAttributes,
- OUT PHANDLE TokenHandle)
-{
- PACCESS_TOKEN Token;
- HANDLE hToken;
- KPROCESSOR_MODE PreviousMode;
- NTSTATUS Status = STATUS_SUCCESS;
-
- PAGED_CODE();
-
- PreviousMode = ExGetPreviousMode();
-
- if(PreviousMode != KernelMode)
- {
- _SEH_TRY
- {
- ProbeForWriteHandle(TokenHandle);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- return Status;
- }
- }
-
- Status = PsOpenTokenOfProcess(ProcessHandle,
- &Token);
- if(NT_SUCCESS(Status))
- {
- Status = ObOpenObjectByPointer(Token,
- 0,
- NULL,
- DesiredAccess,
- SepTokenObjectType,
- PreviousMode,
- &hToken);
- ObDereferenceObject(Token);
-
- if(NT_SUCCESS(Status))
- {
- _SEH_TRY
- {
- *TokenHandle = hToken;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
- }
- }
-
- return Status;
-}
-
-/*
- * @implemented
- */
-PACCESS_TOKEN
-STDCALL
-PsReferencePrimaryToken(PEPROCESS Process)
-{
- PACCESS_TOKEN Token;
-
- /* Fast Reference the Token */
- Token = ObFastReferenceObject(&Process->Token);
-
- /* Check if we got the Token or if we got locked */
- if (!Token)
- {
- /* Lock the Process */
- PspLockProcessSecurityShared(Process);
-
- /* Do a Locked Fast Reference */
- Token = ObFastReferenceObjectLocked(&Process->Token);
-
- /* Unlock the Process */
- PspUnlockProcessSecurityShared(Process);
- }
-
- /* Return the Token */
- return Token;
-}
-
-/*
- * @implemented
- */
-NTSTATUS
-STDCALL
-PsOpenTokenOfProcess(HANDLE ProcessHandle,
- PACCESS_TOKEN* Token)
-{
- PEPROCESS Process;
- NTSTATUS Status;
-
- /* Get the Token */
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_QUERY_INFORMATION,
- PsProcessType,
- ExGetPreviousMode(),
- (PVOID*)&Process,
- NULL);
-
- /* Reference it */
- if(NT_SUCCESS(Status)) {
-
- *Token = PsReferencePrimaryToken(Process);
- ObDereferenceObject(Process);
- }
-
- /* Return */
- return Status;
-}
-
-NTSTATUS
-STDCALL
-PspInitializeProcessSecurity(PEPROCESS Process,
- PEPROCESS Parent OPTIONAL)
+NTSTATUS
+NTAPI
+PspInitializeProcessSecurity(IN PEPROCESS Process,
+ IN PEPROCESS Parent OPTIONAL)
{
NTSTATUS Status = STATUS_SUCCESS;
PTOKEN NewToken, ParentToken;
@@ -258,86 +116,233 @@
return Status;
}
-
-NTSTATUS
-STDCALL
-PspAssignPrimaryToken(PEPROCESS Process,
- HANDLE TokenHandle)
-{
- PACCESS_TOKEN Token;
- PACCESS_TOKEN OldToken;
+NTSTATUS
+NTAPI
+PspAssignPrimaryToken(IN PEPROCESS Process,
+ IN HANDLE TokenHandle)
+{
+ PACCESS_TOKEN Token, OldToken;
NTSTATUS Status;
/* Reference the Token */
Status = ObReferenceObjectByHandle(TokenHandle,
- 0,
+ TOKEN_ASSIGN_PRIMARY,
SepTokenObjectType,
KeGetPreviousMode(),
(PVOID*)&Token,
NULL);
- if (!NT_SUCCESS(Status)) {
-
- return(Status);
- }
+ if (!NT_SUCCESS(Status)) return Status;
/* Exchange them */
Status = SeExchangePrimaryToken(Process, Token, &OldToken);
/* Derefernece Tokens and Return */
ObDereferenceObject(Token);
- return(Status);
-}
-
-/*
- * @implemented
- */
-NTSTATUS
-STDCALL
-PsAssignImpersonationToken(PETHREAD Thread,
- HANDLE TokenHandle)
+ return Status;
+}
+
+/* FUNCTIONS *****************************************************************/
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+NtOpenProcessToken(IN HANDLE ProcessHandle,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PHANDLE TokenHandle)
+{
+ /* Call the newer API */
+ return NtOpenProcessTokenEx(ProcessHandle,
+ DesiredAccess,
+ 0,
+ TokenHandle);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+NtOpenProcessTokenEx(IN HANDLE ProcessHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN ULONG HandleAttributes,
+ OUT PHANDLE TokenHandle)
+{
+ PACCESS_TOKEN Token;
+ HANDLE hToken;
+ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ NTSTATUS Status = STATUS_SUCCESS;
+ PAGED_CODE();
+
+ /* Check if caller was user-mode */
+ if (PreviousMode != KernelMode)
+ {
+ /* Enter SEH for probing */
+ _SEH_TRY
+ {
+ /* Probe the token handle */
+ ProbeForWriteHandle(TokenHandle);
+ }
+ _SEH_HANDLE
+ {
+ /* Get the exception code */
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ /* Fail on exception */
+ if (!NT_SUCCESS(Status)) return Status;
+ }
+
+ /* Open the process token */
+ Status = PsOpenTokenOfProcess(ProcessHandle, &Token);
+ if(NT_SUCCESS(Status))
+ {
+ /* Reference it by handle and dereference the pointer */
+ Status = ObOpenObjectByPointer(Token,
+ 0,
+ NULL,
+ DesiredAccess,
+ SepTokenObjectType,
+ PreviousMode,
+ &hToken);
+ ObDereferenceObject(Token);
+
+ /* Make sure we got a handle */
+ if(NT_SUCCESS(Status))
+ {
+ /* Enter SEH for write */
+ _SEH_TRY
+ {
+ /* Return the handle */
+ *TokenHandle = hToken;
+ }
+ _SEH_HANDLE
+ {
+ /* Get exception code */
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+ }
+
+ /* Return status */
+ return Status;
+}
+
+/*
+ * @implemented
+ */
+PACCESS_TOKEN
+NTAPI
+PsReferencePrimaryToken(PEPROCESS Process)
+{
+ PACCESS_TOKEN Token;
+
+ /* Fast Reference the Token */
+ Token = ObFastReferenceObject(&Process->Token);
+
+ /* Check if we got the Token or if we got locked */
+ if (!Token)
+ {
+ /* Lock the Process */
+ PspLockProcessSecurityShared(Process);
+
+ /* Do a Locked Fast Reference */
+ Token = ObFastReferenceObjectLocked(&Process->Token);
+
+ /* Unlock the Process */
+ PspUnlockProcessSecurityShared(Process);
+ }
+
+ /* Return the Token */
+ return Token;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+PsOpenTokenOfProcess(IN HANDLE ProcessHandle,
+ OUT PACCESS_TOKEN* Token)
+{
+ PEPROCESS Process;
+ NTSTATUS Status;
+
+ /* Get the Token */
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_QUERY_INFORMATION,
+ PsProcessType,
+ ExGetPreviousMode(),
+ (PVOID*)&Process,
+ NULL);
+ if(NT_SUCCESS(Status))
+ {
+ /* Reference the token and dereference the process */
+ *Token = PsReferencePrimaryToken(Process);
+ ObDereferenceObject(Process);
+ }
+
+ /* Return */
+ return Status;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+PsAssignImpersonationToken(IN PETHREAD Thread,
+ IN HANDLE TokenHandle)
{
PACCESS_TOKEN Token;
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
NTSTATUS Status;
- if (TokenHandle != NULL) {
-
+ /* Check if we were given a handle */
+ if (TokenHandle)
+ {
+ /* Get the token object */
Status = ObReferenceObjectByHandle(TokenHandle,
TOKEN_IMPERSONATE,
SepTokenObjectType,
KeGetPreviousMode(),
(PVOID*)&Token,
NULL);
-
- if (!NT_SUCCESS(Status)) {
-
- return(Status);
- }
-
+ if (!NT_SUCCESS(Status)) return(Status);
+
+ /* Get the impersionation level */
ImpersonationLevel = SeTokenImpersonationLevel(Token);
-
- } else {
-
+ }
+ else
+ {
+ /* Otherwise, clear values */
Token = NULL;
ImpersonationLevel = 0;
}
+ /* Call the impersonation API */
Status = PsImpersonateClient(Thread,
Token,
FALSE,
FALSE,
ImpersonationLevel);
- if (Token != NULL) ObDereferenceObject(Token);
+ /* Dereference the token and return status */
+ if (Token) ObDereferenceObject(Token);
return Status;
}
/*
* @implemented
*/
-VOID STDCALL
-PsRevertToSelf (VOID)
-{
+VOID
+NTAPI
+PsRevertToSelf(VOID)
+{
+ /* Call the per-thread API */
PsRevertThreadToSelf(PsGetCurrentThread());
}
@@ -345,11 +350,13 @@
* @implemented
*/
VOID
-STDCALL
+NTAPI
PsRevertThreadToSelf(IN PETHREAD Thread)
{
- if (Thread->ActiveImpersonationInfo == TRUE) {
-
+ /* Make sure we had impersonation information */
+ if (Thread->ActiveImpersonationInfo)
+ {
+ /* Dereference the impersonation token and set it as false */
ObDereferenceObject (Thread->ImpersonationInfo->Token);
Thread->ActiveImpersonationInfo = FALSE;
}
@@ -359,59 +366,85 @@
* @implemented
*/
NTSTATUS
-STDCALL
+NTAPI
PsImpersonateClient(IN PETHREAD Thread,
IN PACCESS_TOKEN Token,
IN BOOLEAN CopyOnOpen,
IN BOOLEAN EffectiveOnly,
IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
{
-
- if (Token == NULL) {
-
- if (Thread->ActiveImpersonationInfo == TRUE) {
-
+ PPS_IMPERSONATION_INFORMATION Impersonation;
+
+ /* Check if we don't have a token */
+ if (!Token)
+ {
+ /* Make sure we're impersonating */
+ if (Thread->ActiveImpersonationInfo)
+ {
+ /* Disable impersonation and check for token */
Thread->ActiveImpersonationInfo = FALSE;
-
- if (Thread->ImpersonationInfo->Token != NULL) {
-
- ObDereferenceObject (Thread->ImpersonationInfo->Token);
+ if (Thread->ImpersonationInfo->Token)
+ {
+ /* Dereference it */
+ ObDereferenceObject(Thread->ImpersonationInfo->Token);
}
}
- return STATUS_UNSUCCESSFUL;
- }
-
- if (Thread->ImpersonationInfo == NULL) {
-
- Thread->ImpersonationInfo = ExAllocatePool(NonPagedPool,
-
sizeof(PS_IMPERSONATION_INFORMATION));
- }
-
- Thread->ImpersonationInfo->ImpersonationLevel = ImpersonationLevel;
- Thread->ImpersonationInfo->CopyOnOpen = CopyOnOpen;
- Thread->ImpersonationInfo->EffectiveOnly = EffectiveOnly;
- Thread->ImpersonationInfo->Token = Token;
-
- ObReferenceObject(Token);
-
+ /* Return success */
+ return STATUS_SUCCESS;
+ }
+
+ /* Check if we have active impersonation */
+ if (Thread->ActiveImpersonationInfo)
+ {
+ /* Reuse the block and reference the token */
+ Impersonation = Thread->ImpersonationInfo;
+ if (Impersonation->Token) ObDereferenceObject(Impersonation->Token);
+ }
+ else if (Thread->ImpersonationInfo)
+ {
+ /* It's not active, but we can still reuse the block */
+ Impersonation = Thread->ImpersonationInfo;
+ }
+ else
+ {
+ /* We need to allocate a new one */
+ Impersonation = ExAllocatePoolWithTag(PagedPool,
+ sizeof(*Impersonation),
+ TAG_PS_IMPERSONATION);
+ if (!Impersonation) return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Update the pointer */
+ Thread->ImpersonationInfo = Impersonation;
+ }
+
+ /* Now fill it out */
+ Impersonation->ImpersonationLevel = ImpersonationLevel;
+ Impersonation->CopyOnOpen = CopyOnOpen;
+ Impersonation->EffectiveOnly = EffectiveOnly;
+ Impersonation->Token = Token;
Thread->ActiveImpersonationInfo = TRUE;
+ /* Reference the token and return success */
+ ObReferenceObject(Impersonation->Token);
return STATUS_SUCCESS;
}
-
+/*
+ * @implemented
+ */
PACCESS_TOKEN
-STDCALL
-PsReferenceEffectiveToken(PETHREAD Thread,
- PTOKEN_TYPE TokenType,
- PBOOLEAN EffectiveOnly,
- PSECURITY_IMPERSONATION_LEVEL Level)
+NTAPI
+PsReferenceEffectiveToken(IN PETHREAD Thread,
+ OUT IN PTOKEN_TYPE TokenType,
+ OUT PBOOLEAN EffectiveOnly,
+ OUT PSECURITY_IMPERSONATION_LEVEL Level)
{
PEPROCESS Process;
PACCESS_TOKEN Token;
- if (Thread->ActiveImpersonationInfo == FALSE)
+ /* Check if we don't have impersonation info */
+ if (!Thread->ActiveImpersonationInfo)
{
Process = Thread->ThreadsProcess;
*TokenType = TokenPrimary;
@@ -435,146 +468,64 @@
}
else
{
+ /* Get the token */
Token = Thread->ImpersonationInfo->Token;
+ ObReferenceObject(Token);
+
+ /* Return data to caller */
*TokenType = TokenImpersonation;
*EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
*Level = Thread->ImpersonationInfo->ImpersonationLevel;
}
+ /* Return the token */
return Token;
}
-NTSTATUS
-STDCALL
-NtImpersonateThread(IN HANDLE ThreadHandle,
- IN HANDLE ThreadToImpersonateHandle,
- IN PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService)
-{
- SECURITY_QUALITY_OF_SERVICE SafeServiceQoS;
- SECURITY_CLIENT_CONTEXT ClientContext;
- PETHREAD Thread;
- PETHREAD ThreadToImpersonate;
- KPROCESSOR_MODE PreviousMode;
- NTSTATUS Status = STATUS_SUCCESS;
-
- PAGED_CODE();
-
- PreviousMode = ExGetPreviousMode();
-
- if(PreviousMode != KernelMode)
- {
- _SEH_TRY
- {
- ProbeForRead(SecurityQualityOfService,
- sizeof(SECURITY_QUALITY_OF_SERVICE),
- sizeof(ULONG));
- SafeServiceQoS = *SecurityQualityOfService;
- SecurityQualityOfService = &SafeServiceQoS;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- return Status;
- }
- }
-
- Status = ObReferenceObjectByHandle(ThreadHandle,
- THREAD_IMPERSONATE,
- PsThreadType,
- PreviousMode,
- (PVOID*)&Thread,
- NULL);
- if(NT_SUCCESS(Status))
- {
- Status = ObReferenceObjectByHandle(ThreadToImpersonateHandle,
- THREAD_DIRECT_IMPERSONATION,
- PsThreadType,
- PreviousMode,
- (PVOID*)&ThreadToImpersonate,
- NULL);
- if(NT_SUCCESS(Status))
- {
- Status = SeCreateClientSecurity(ThreadToImpersonate,
- SecurityQualityOfService,
- 0,
- &ClientContext);
- if(NT_SUCCESS(Status))
- {
- SeImpersonateClient(&ClientContext,
- Thread);
- if(ClientContext.ClientToken != NULL)
- {
- ObDereferenceObject (ClientContext.ClientToken);
- }
- }
-
- ObDereferenceObject(ThreadToImpersonate);
- }
- ObDereferenceObject(Thread);
- }
-
- return Status;
-}
-
/*
* @implemented
*/
PACCESS_TOKEN
-STDCALL
+NTAPI
PsReferenceImpersonationToken(IN PETHREAD Thread,
OUT PBOOLEAN CopyOnOpen,
OUT PBOOLEAN EffectiveOnly,
OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
{
-
- if (Thread->ActiveImpersonationInfo == FALSE) {
-
- return NULL;
- }
-
+ /* If we don't have impersonation info, just quit */
+ if (!Thread->ActiveImpersonationInfo) return NULL;
+
+ /* Return data from caller */
*ImpersonationLevel = Thread->ImpersonationInfo->ImpersonationLevel;
*CopyOnOpen = Thread->ImpersonationInfo->CopyOnOpen;
*EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
- ObReferenceObjectByPointer(Thread->ImpersonationInfo->Token,
- TOKEN_ALL_ACCESS,
- SepTokenObjectType,
- KernelMode);
-
+ /* Reference the token and return it */
+ ObReferenceObject(Thread->ImpersonationInfo->Token);
return Thread->ImpersonationInfo->Token;
}
-#ifdef PsDereferencePrimaryToken
#undef PsDereferenceImpersonationToken
-#endif
-/*
- * @implemented
- */
-VOID
-STDCALL
+/*
+ * @implemented
+ */
+VOID
+NTAPI
PsDereferenceImpersonationToken(IN PACCESS_TOKEN ImpersonationToken)
{
- if (ImpersonationToken) {
-
- ObDereferenceObject(ImpersonationToken);
- }
-}
-
-#ifdef PsDereferencePrimaryToken
+ /* If we got a token, dereference it */
+ if (ImpersonationToken) ObDereferenceObject(ImpersonationToken);
+}
+
#undef PsDereferencePrimaryToken
-#endif
-/*
- * @implemented
- */
-VOID
-STDCALL
+/*
+ * @implemented
+ */
+VOID
+NTAPI
PsDereferencePrimaryToken(IN PACCESS_TOKEN PrimaryToken)
{
+ /* Dereference the token*/
ObDereferenceObject(PrimaryToken);
}
@@ -582,30 +533,32 @@
* @implemented
*/
BOOLEAN
-STDCALL
+NTAPI
PsDisableImpersonation(IN PETHREAD Thread,
IN PSE_IMPERSONATION_STATE ImpersonationState)
{
- if (Thread->ActiveImpersonationInfo == FALSE) {
+ PPS_IMPERSONATION_INFORMATION Impersonation;
+
+ /* Check if we don't have impersonation */
+ if (!Thread->ActiveImpersonationInfo)
+ {
+ /* Clear everything */
ImpersonationState->Token = NULL;
ImpersonationState->CopyOnOpen = FALSE;
ImpersonationState->EffectiveOnly = FALSE;
- ImpersonationState->Level = 0;
- return TRUE;
- }
-
-/* FIXME */
-/* ExfAcquirePushLockExclusive(&Thread->ThreadLock); */
-
+ ImpersonationState->Level = SecurityAnonymous;
+ return FALSE;
+ }
+
+ /* Copy the old state */
+ Impersonation = Thread->ImpersonationInfo;
+ ImpersonationState->Token = Impersonation->Token;
+ ImpersonationState->CopyOnOpen = Impersonation->CopyOnOpen;
+ ImpersonationState->EffectiveOnly = Impersonation->EffectiveOnly;
+ ImpersonationState->Level = Impersonation->ImpersonationLevel;
+
+ /* Disable impersonation and return true */
Thread->ActiveImpersonationInfo = FALSE;
- ImpersonationState->Token = Thread->ImpersonationInfo->Token;
- ImpersonationState->CopyOnOpen = Thread->ImpersonationInfo->CopyOnOpen;
- ImpersonationState->EffectiveOnly =
Thread->ImpersonationInfo->EffectiveOnly;
- ImpersonationState->Level = Thread->ImpersonationInfo->ImpersonationLevel;
-
-/* FIXME */
-/* ExfReleasePushLock(&Thread->ThreadLock); */
-
return TRUE;
}
@@ -613,18 +566,104 @@
* @implemented
*/
VOID
-STDCALL
+NTAPI
PsRestoreImpersonation(IN PETHREAD Thread,
IN PSE_IMPERSONATION_STATE ImpersonationState)
{
-
+ /* Call the impersonation API */
PsImpersonateClient(Thread,
ImpersonationState->Token,
ImpersonationState->CopyOnOpen,
ImpersonationState->EffectiveOnly,
ImpersonationState->Level);
- ObfDereferenceObject(ImpersonationState->Token);
-}
-
+ /* Dereference the token */
+ ObDereferenceObject(ImpersonationState->Token);
+}
+
+NTSTATUS
+NTAPI
+NtImpersonateThread(IN HANDLE ThreadHandle,
+ IN HANDLE ThreadToImpersonateHandle,
+ IN PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService)
+{
+ SECURITY_QUALITY_OF_SERVICE SafeServiceQoS;
+ SECURITY_CLIENT_CONTEXT ClientContext;
+ PETHREAD Thread;
+ PETHREAD ThreadToImpersonate;
+ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ NTSTATUS Status = STATUS_SUCCESS;
+ PAGED_CODE();
+
+ /* Check if call came from user mode */
+ if (PreviousMode != KernelMode)
+ {
+ /* Enter SEH for probing */
+ _SEH_TRY
+ {
+ /* Probe QoS */
+ ProbeForRead(SecurityQualityOfService,
+ sizeof(SECURITY_QUALITY_OF_SERVICE),
+ sizeof(ULONG));
+
+ /* Capture it */
+ SafeServiceQoS = *SecurityQualityOfService;
+ SecurityQualityOfService = &SafeServiceQoS;
+ }
+ _SEH_HANDLE
+ {
+ /* Get exception status */
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ /* Fail on exception */
+ if (!NT_SUCCESS(Status)) return Status;
+ }
+
+ /* Reference the thread */
+ Status = ObReferenceObjectByHandle(ThreadHandle,
+ THREAD_IMPERSONATE,
+ PsThreadType,
+ PreviousMode,
+ (PVOID*)&Thread,
+ NULL);
+ if(NT_SUCCESS(Status))
+ {
+ /* Reference the impersonating thead */
+ Status = ObReferenceObjectByHandle(ThreadToImpersonateHandle,
+ THREAD_DIRECT_IMPERSONATION,
+ PsThreadType,
+ PreviousMode,
+ (PVOID*)&ThreadToImpersonate,
+ NULL);
+ if(NT_SUCCESS(Status))
+ {
+ /* Create a client security context */
+ Status = SeCreateClientSecurity(ThreadToImpersonate,
+ SecurityQualityOfService,
+ 0,
+ &ClientContext);
+ if(NT_SUCCESS(Status))
+ {
+ /* Do the impersonation */
+ SeImpersonateClient(&ClientContext, Thread);
+ if(ClientContext.ClientToken)
+ {
+ /* Dereference the client token if we had one */
+ ObDereferenceObject(ClientContext.ClientToken);
+ }
+ }
+
+ /* Dereference the thread to impersonate */
+ ObDereferenceObject(ThreadToImpersonate);
+ }
+
+ /* Dereference the main thread */
+ ObDereferenceObject(Thread);
+ }
+
+ /* Return status */
+ return Status;
+}
/* EOF */
Propchange: trunk/reactos/ntoskrnl/ps/security.c
------------------------------------------------------------------------------
--- svn:needs-lock (original)
+++ svn:needs-lock (removed)
@@ -1,1 +1,0 @@
-*