- Fix definitions of SecurityAnonymous, SecurityIdentification, SecurityImpersonation, SecurityDelegation.

- Fix prototype of NtDuplicateToken and change DuplicateTokenEx accordingly.
- Implement NtOpenThreadToken[Ex] (complete rewrite), PsDisableImpersonation and PsRestoreImpersonation.

svn path=/trunk/; revision=11999
This commit is contained in:
Filip Navara 2004-12-10 16:50:38 +00:00
parent bc28145d48
commit c5adfe4512
8 changed files with 254 additions and 105 deletions

View file

@ -188,10 +188,10 @@ typedef enum _TOKEN_INFORMATION_CLASS
typedef ULONG SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
#define SecurityAnonymous ((SECURITY_IMPERSONATION_LEVEL)1)
#define SecurityIdentification ((SECURITY_IMPERSONATION_LEVEL)2)
#define SecurityImpersonation ((SECURITY_IMPERSONATION_LEVEL)3)
#define SecurityDelegation ((SECURITY_IMPERSONATION_LEVEL)4)
#define SecurityAnonymous ((SECURITY_IMPERSONATION_LEVEL)0)
#define SecurityIdentification ((SECURITY_IMPERSONATION_LEVEL)1)
#define SecurityImpersonation ((SECURITY_IMPERSONATION_LEVEL)2)
#define SecurityDelegation ((SECURITY_IMPERSONATION_LEVEL)3)
typedef ULONG ACCESS_MASK, *PACCESS_MASK;
typedef ULONG TOKEN_TYPE, *PTOKEN_TYPE;

View file

@ -1,5 +1,5 @@
/* $Id: zw.h,v 1.36 2004/11/25 22:18:15 ion Exp $
/* $Id: zw.h,v 1.37 2004/12/10 16:50:36 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -5839,7 +5839,7 @@ NtDuplicateToken(
IN HANDLE ExistingToken,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
IN BOOLEAN EffectiveOnly,
IN TOKEN_TYPE TokenType,
OUT PHANDLE NewToken
);

View file

@ -1,4 +1,4 @@
/* $Id: token.c,v 1.14 2004/09/27 20:04:53 gvg Exp $
/* $Id: token.c,v 1.15 2004/12/10 16:50:37 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -259,9 +259,15 @@ DuplicateTokenEx (HANDLE ExistingTokenHandle,
PHANDLE DuplicateTokenHandle)
{
OBJECT_ATTRIBUTES ObjectAttributes;
SECURITY_QUALITY_OF_SERVICE Qos;
HANDLE NewToken;
NTSTATUS Status;
Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
Qos.ImpersonationLevel = ImpersonationLevel;
Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
Qos.EffectiveOnly = FALSE;
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
ObjectAttributes.ObjectName = NULL;
@ -271,12 +277,12 @@ DuplicateTokenEx (HANDLE ExistingTokenHandle,
ObjectAttributes.Attributes |= OBJ_INHERIT;
}
ObjectAttributes.SecurityDescriptor = lpTokenAttributes->lpSecurityDescriptor;
ObjectAttributes.SecurityQualityOfService = NULL;
ObjectAttributes.SecurityQualityOfService = &Qos;
Status = NtDuplicateToken (ExistingTokenHandle,
dwDesiredAccess,
&ObjectAttributes,
ImpersonationLevel,
FALSE,
TokenType,
&NewToken);
if (!NT_SUCCESS(Status))

View file

@ -110,6 +110,11 @@ BOOLEAN SepInitSecurityIDs(VOID);
BOOLEAN SepInitDACLs(VOID);
BOOLEAN SepInitSDs(VOID);
NTSTATUS STDCALL
SepCreateImpersonationTokenDacl(PACCESS_TOKEN Token,
PACCESS_TOKEN PrimaryToken,
PACL *Dacl);
VOID SepInitializeTokenImplementation(VOID);
NTSTATUS SepCreateSystemProcessToken(struct _EPROCESS* Process);

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.86 2004/11/20 16:46:05 weiden Exp $
/* $Id: create.c,v 1.87 2004/12/10 16:50:37 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -232,63 +232,6 @@ NtImpersonateThread(IN HANDLE ThreadHandle,
return STATUS_SUCCESS;
}
/*
* @implemented
*/
NTSTATUS STDCALL
NtOpenThreadToken (IN HANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN BOOLEAN OpenAsSelf,
OUT PHANDLE TokenHandle)
{
PACCESS_TOKEN Token;
PETHREAD Thread;
NTSTATUS Status;
Status = ObReferenceObjectByHandle (ThreadHandle,
0,
PsThreadType,
UserMode,
(PVOID*)&Thread,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (OpenAsSelf)
{
Token = Thread->ThreadsProcess->Token;
}
else
{
if (Thread->ActiveImpersonationInfo == FALSE)
{
ObDereferenceObject (Thread);
return STATUS_NO_TOKEN;
}
Token = Thread->ImpersonationInfo->Token;
}
if (Token == NULL)
{
ObDereferenceObject (Thread);
return STATUS_NO_TOKEN;
}
Status = ObCreateHandle (PsGetCurrentProcess(),
Token,
DesiredAccess,
FALSE,
TokenHandle);
ObDereferenceObject (Thread);
return Status;
}
/*
* @implemented
*/
@ -339,7 +282,7 @@ PsDereferencePrimaryToken(
}
/*
* @unimplemented
* @implemented
*/
BOOLEAN
STDCALL
@ -348,12 +291,32 @@ PsDisableImpersonation(
IN PSE_IMPERSONATION_STATE ImpersonationState
)
{
UNIMPLEMENTED;
return FALSE;
if (Thread->ActiveImpersonationInfo == FALSE)
{
ImpersonationState->Token = NULL;
ImpersonationState->CopyOnOpen = FALSE;
ImpersonationState->EffectiveOnly = FALSE;
ImpersonationState->Level = 0;
return TRUE;
}
/* FIXME */
/* ExfAcquirePushLockExclusive(&Thread->ThreadLock); */
Thread->ActiveImpersonationInfo = FALSE;
ImpersonationState->Token = Thread->ImpersonationInfo->Token;
ImpersonationState->CopyOnOpen = Thread->ImpersonationInfo->CopyOnOpen;
ImpersonationState->EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
ImpersonationState->Level = Thread->ImpersonationInfo->Level;
/* FIXME */
/* ExfReleasePushLock(&Thread->ThreadLock); */
return TRUE;
}
/*
* @unimplemented
* @implemented
*/
VOID
STDCALL
@ -362,7 +325,11 @@ PsRestoreImpersonation(
IN PSE_IMPERSONATION_STATE ImpersonationState
)
{
UNIMPLEMENTED;
PsImpersonateClient(Thread, ImpersonationState->Token,
ImpersonationState->CopyOnOpen,
ImpersonationState->EffectiveOnly,
ImpersonationState->Level);
ObfDereferenceObject(ImpersonationState->Token);
}
VOID

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.139 2004/11/27 16:52:35 hbirr Exp $
/* $Id: thread.c,v 1.140 2004/12/10 16:50:37 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -1006,21 +1006,4 @@ PsLookupThreadByThreadId(IN PVOID ThreadId,
return STATUS_INVALID_PARAMETER;
}
/*
* @unimplemented
*/
NTSTATUS
STDCALL
NtOpenThreadTokenEx(
IN HANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN BOOLEAN OpenAsSelf,
IN ULONG HandleAttributes,
OUT PHANDLE TokenHandle
)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: acl.c,v 1.21 2004/11/06 21:32:16 navaraf Exp $
/* $Id: acl.c,v 1.22 2004/12/10 16:50:37 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -219,4 +219,47 @@ SepInitDACLs(VOID)
return(TRUE);
}
NTSTATUS STDCALL
SepCreateImpersonationTokenDacl(PACCESS_TOKEN Token,
PACCESS_TOKEN PrimaryToken,
PACL *Dacl)
{
ULONG AclLength;
PVOID TokenDacl;
AclLength = sizeof(ACL) +
(sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) +
(sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)) +
(sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
(sizeof(ACE) + RtlLengthSid(Token->UserAndGroups->Sid)) +
(sizeof(ACE) + RtlLengthSid(PrimaryToken->UserAndGroups->Sid));
TokenDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL);
if (TokenDacl == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCreateAcl(TokenDacl, AclLength, ACL_REVISION);
RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL,
Token->UserAndGroups->Sid);
RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL,
PrimaryToken->UserAndGroups->Sid);
RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL,
SeAliasAdminsSid);
RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL,
SeLocalSystemSid);
/* FIXME */
#if 0
if (Token->RestrictedSids != NULL || PrimaryToken->RestrictedSids != NULL)
{
RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL,
SeRestrictedCodeSid);
}
#endif
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: token.c,v 1.42 2004/10/22 20:48:00 ekohl Exp $
/* $Id: token.c,v 1.43 2004/12/10 16:50:38 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -133,9 +133,9 @@ SepFindPrimaryGroupAndDefaultOwner(PACCESS_TOKEN Token,
NTSTATUS
SepDuplicateToken(PACCESS_TOKEN Token,
POBJECT_ATTRIBUTES ObjectAttributes,
BOOLEAN EffectiveOnly,
TOKEN_TYPE TokenType,
SECURITY_IMPERSONATION_LEVEL Level,
SECURITY_IMPERSONATION_LEVEL ExistingLevel,
KPROCESSOR_MODE PreviousMode,
PACCESS_TOKEN* NewAccessToken)
{
@ -281,9 +281,9 @@ SepInitializeNewProcess(struct _EPROCESS* NewProcess,
Status = SepDuplicateToken(pParentToken,
&ObjectAttributes,
FALSE,
TokenPrimary,
pParentToken->ImpersonationLevel,
pParentToken->ImpersonationLevel,
KernelMode,
&pNewToken);
if ( ! NT_SUCCESS(Status) )
@ -307,10 +307,12 @@ SeAppendPrivileges(
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS SeCopyClientToken(PACCESS_TOKEN Token,
SECURITY_IMPERSONATION_LEVEL Level,
KPROCESSOR_MODE PreviousMode,
PACCESS_TOKEN* NewToken)
NTSTATUS
STDCALL
SeCopyClientToken(PACCESS_TOKEN Token,
SECURITY_IMPERSONATION_LEVEL Level,
KPROCESSOR_MODE PreviousMode,
PACCESS_TOKEN* NewToken)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
@ -322,8 +324,8 @@ NTSTATUS SeCopyClientToken(PACCESS_TOKEN Token,
NULL);
Status = SepDuplicateToken(Token,
&ObjectAttributes,
0,
SecurityIdentification,
FALSE,
TokenImpersonation,
Level,
PreviousMode,
NewToken);
@ -968,7 +970,7 @@ NTSTATUS STDCALL
NtDuplicateToken(IN HANDLE ExistingTokenHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
IN BOOLEAN EffectiveOnly,
IN TOKEN_TYPE TokenType,
OUT PHANDLE NewTokenHandle)
{
@ -976,7 +978,6 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle,
PACCESS_TOKEN Token;
PACCESS_TOKEN NewToken;
NTSTATUS Status;
ULONG ExistingImpersonationLevel;
PreviousMode = KeGetPreviousMode();
Status = ObReferenceObjectByHandle(ExistingTokenHandle,
@ -991,12 +992,11 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle,
return Status;
}
ExistingImpersonationLevel = Token->ImpersonationLevel;
Status = SepDuplicateToken(Token,
ObjectAttributes,
EffectiveOnly,
TokenType,
ImpersonationLevel,
ExistingImpersonationLevel,
ObjectAttributes->SecurityQualityOfService->ImpersonationLevel,
PreviousMode,
&NewToken);
@ -1748,4 +1748,149 @@ SeTokenIsWriteRestricted(
}
/*
* @implemented
*/
NTSTATUS
STDCALL
NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN BOOLEAN OpenAsSelf,
IN ULONG HandleAttributes,
OUT PHANDLE TokenHandle)
{
PETHREAD Thread;
PACCESS_TOKEN Token, NewToken, PrimaryToken;
BOOLEAN CopyOnOpen, EffectiveOnly;
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
SE_IMPERSONATION_STATE ImpersonationState;
OBJECT_ATTRIBUTES ObjectAttributes;
SECURITY_DESCRIPTOR SecurityDescriptor;
PACL Dacl = NULL;
NTSTATUS Status;
/*
* At first open the thread token for information access and verify
* that the token associated with thread is valid.
*/
Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION,
PsThreadType, UserMode, (PVOID*)&Thread,
NULL);
if (!NT_SUCCESS(Status))
{
return Status;
}
Token = PsReferenceImpersonationToken(Thread, &CopyOnOpen, &EffectiveOnly,
&ImpersonationLevel);
if (Token == NULL)
{
ObfDereferenceObject(Thread);
return STATUS_NO_TOKEN;
}
ObDereferenceObject(Thread);
if (ImpersonationLevel == SecurityAnonymous)
{
ObfDereferenceObject(Token);
return STATUS_CANT_OPEN_ANONYMOUS;
}
/*
* Revert to self if OpenAsSelf is specified.
*/
if (OpenAsSelf)
{
PsDisableImpersonation(PsGetCurrentThread(), &ImpersonationState);
}
if (CopyOnOpen)
{
Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS,
PsThreadType, UserMode,
(PVOID*)&Thread, NULL);
if (!NT_SUCCESS(Status))
{
ObfDereferenceObject(Token);
if (OpenAsSelf)
{
PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
}
return Status;
}
PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess);
Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl);
ObfDereferenceObject(PrimaryToken);
ObfDereferenceObject(Thread);
if (!NT_SUCCESS(Status))
{
ObfDereferenceObject(Token);
if (OpenAsSelf)
{
PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
}
return Status;
}
RtlCreateSecurityDescriptor(&SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION);
RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl,
FALSE);
InitializeObjectAttributes(&ObjectAttributes, NULL, HandleAttributes,
NULL, &SecurityDescriptor);
Status = SepDuplicateToken(Token, &ObjectAttributes, EffectiveOnly,
TokenImpersonation, ImpersonationLevel,
KernelMode, &NewToken);
ExFreePool(Dacl);
if (!NT_SUCCESS(Status))
{
ObfDereferenceObject(Token);
if (OpenAsSelf)
{
PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
}
return Status;
}
Status = ObInsertObject(NewToken, NULL, DesiredAccess, 0, NULL,
TokenHandle);
ObfDereferenceObject(NewToken);
}
else
{
Status = ObOpenObjectByPointer(Token, HandleAttributes,
NULL, DesiredAccess, SepTokenObjectType,
ExGetPreviousMode(), TokenHandle);
}
ObfDereferenceObject(Token);
if (OpenAsSelf)
{
PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
}
return Status;
}
/*
* @implemented
*/
NTSTATUS STDCALL
NtOpenThreadToken(IN HANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN BOOLEAN OpenAsSelf,
OUT PHANDLE TokenHandle)
{
return NtOpenThreadTokenEx(ThreadHandle, DesiredAccess, OpenAsSelf, 0,
TokenHandle);
}
/* EOF */