- Give winlogon SE_ASSIGNPRIMARYTOKEN_PRIVILEGE because it was lacking it and would fail under this kernel patch.

- PspAssignPrimaryToken was good enough for actually *assigning* the token, but when NtSetInfoProcess is called with ProcessPrimaryToken, we want to do a lot more then just randomly assigning it. Added PspSetPrimaryToken which first verifies if the token being assigned is a child token and if not, checks for SeAssignPrimaryTokenPrivilege. Also added a fixme for more code that's needed, to actually re-calculate the process's granted access towards itself. Also added thread-safety.

svn path=/trunk/; revision=23226
This commit is contained in:
Alex Ionescu 2006-07-22 16:03:12 +00:00
parent e553dd4145
commit db04986dce
7 changed files with 149 additions and 18 deletions

View file

@ -534,6 +534,7 @@ WinMain(HINSTANCE hInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
BOOLEAN Old;
#if SUPPORT_CONSOLESTART
// WCHAR LoginName[255];
// WCHAR Password[255];
@ -555,6 +556,9 @@ WinMain(HINSTANCE hInstance,
return 0;
}
/* Get privilege */
RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old);
#if START_LSASS
if (StartProcess(L"StartLsass"))
{

View file

@ -33,6 +33,7 @@
#include <winwlx.h>
#include <rtlfuncs.h>
#include <exfuncs.h>
#include <setypes.h>
#include <reactos/winlogon.h>

View file

@ -59,10 +59,11 @@ PsOpenTokenOfProcess(
);
NTSTATUS
STDCALL
PspAssignPrimaryToken(
PEPROCESS Process,
HANDLE TokenHandle
NTAPI
PspSetPrimaryToken(
IN PEPROCESS Process,
IN HANDLE TokenHandle OPTIONAL,
IN PTOKEN Token OPTIONAL
);
PETHREAD

View file

@ -129,6 +129,13 @@ SeSubProcessToken(
IN ULONG SessionId
);
NTSTATUS
NTAPI
SeIsTokenChild(
IN PTOKEN Token,
OUT PBOOLEAN IsChild
);
NTSTATUS
STDCALL
SepCreateImpersonationTokenDacl(

View file

@ -581,7 +581,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
if (!NT_SUCCESS(Status)) break;
/* Assign the actual token */
Status = PspAssignPrimaryToken(Process, TokenHandle);
Status = PspSetPrimaryToken(Process, TokenHandle, NULL);
break;
/* Hard error processing */

View file

@ -25,7 +25,7 @@ PspLockProcessSecurityShared(IN PEPROCESS Process)
KeEnterCriticalRegion();
/* Lock the Process */
//ExAcquirePushLockShared(&Process->ProcessLock);
ExAcquirePushLockShared(&Process->ProcessLock);
}
/* FIXME: Turn into Macro */
@ -34,7 +34,31 @@ NTAPI
PspUnlockProcessSecurityShared(IN PEPROCESS Process)
{
/* Unlock the Process */
//ExReleasePushLockShared(&Process->ProcessLock);
ExReleasePushLockShared(&Process->ProcessLock);
/* Leave Critical Region */
KeLeaveCriticalRegion();
}
/* FIXME: Turn into Macro */
VOID
NTAPI
PspLockProcessSecurityExclusive(IN PEPROCESS Process)
{
/* Enter a Critical Region */
KeEnterCriticalRegion();
/* Lock the Process */
ExAcquirePushLockExclusive(&Process->ProcessLock);
}
/* FIXME: Turn into Macro */
VOID
NTAPI
PspUnlockProcessSecurityExclusive(IN PEPROCESS Process)
{
/* Unlock the Process */
ExReleasePushLockExclusive(&Process->ProcessLock);
/* Leave Critical Region */
KeLeaveCriticalRegion();
@ -119,28 +143,92 @@ PspInitializeProcessSecurity(IN PEPROCESS Process,
NTSTATUS
NTAPI
PspAssignPrimaryToken(IN PEPROCESS Process,
IN HANDLE TokenHandle)
IN PTOKEN Token)
{
PACCESS_TOKEN Token, OldToken;
PACCESS_TOKEN OldToken;
NTSTATUS Status;
PAGED_CODE();
/* Reference the Token */
Status = ObReferenceObjectByHandle(TokenHandle,
TOKEN_ASSIGN_PRIMARY,
SepTokenObjectType,
KeGetPreviousMode(),
(PVOID*)&Token,
NULL);
if (!NT_SUCCESS(Status)) return Status;
/* Lock the process */
PspLockProcessSecurityExclusive(Process);
/* Exchange them */
Status = SeExchangePrimaryToken(Process, Token, &OldToken);
/* Derefernece Tokens and Return */
/* Release the lock */
PspUnlockProcessSecurityExclusive(Process);
/* Dereference Tokens and Return */
if (NT_SUCCESS(Status)) ObDereferenceObject(OldToken);
ObDereferenceObject(Token);
return Status;
}
NTSTATUS
NTAPI
PspSetPrimaryToken(IN PEPROCESS Process,
IN HANDLE TokenHandle OPTIONAL,
IN PTOKEN Token OPTIONAL)
{
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
BOOLEAN IsChild;
NTSTATUS Status;
/* Make sure we got a handle */
if (TokenHandle)
{
/* Reference it */
Status = ObReferenceObjectByHandle(TokenHandle,
TOKEN_ASSIGN_PRIMARY,
SepTokenObjectType,
PreviousMode,
(PVOID*)&Token,
NULL);
if (!NT_SUCCESS(Status)) return Status;
}
/* Check if this is a child */
Status = SeIsTokenChild(Token, &IsChild);
if (!NT_SUCCESS(Status))
{
/* Failed, dereference */
if (TokenHandle) ObDereferenceObject(Token);
return Status;
}
/* Check if this was an independent token */
if (!IsChild)
{
/* Make sure we have the privilege to assign a new one */
if (!SeSinglePrivilegeCheck(SeAssignPrimaryTokenPrivilege,
PreviousMode))
{
/* Failed, dereference */
if (TokenHandle) ObDereferenceObject(Token);
return STATUS_PRIVILEGE_NOT_HELD;
}
}
/* Assign the token */
Status = PspAssignPrimaryToken(Process, Token);
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.
*/
DPRINT1("Process security not complete\n");
}
/* Dereference the token */
if (TokenHandle) ObDereferenceObject(Token);
return Status;
}
/* FUNCTIONS *****************************************************************/
/*

View file

@ -368,6 +368,36 @@ SeSubProcessToken(IN PTOKEN ParentToken,
return Status;
}
NTSTATUS
NTAPI
SeIsTokenChild(IN PTOKEN Token,
OUT PBOOLEAN IsChild)
{
PTOKEN ProcessToken;
LUID ProcessLuid, CallerLuid;
/* Assume failure */
*IsChild = FALSE;
/* Reference the process token */
ProcessToken = PsReferencePrimaryToken(PsGetCurrentProcess());
/* Get the ID */
ProcessLuid = ProcessToken->TokenId;
/* Dereference the token */
ObFastDereferenceObject(&PsGetCurrentProcess()->Token, ProcessToken);
/* Get our LUID */
CallerLuid = Token->TokenId;
/* Compare the LUIDs */
if (RtlEqualLuid(&CallerLuid, &ProcessLuid)) *IsChild = TRUE;
/* Return success */
return STATUS_SUCCESS;
}
/*
* @unimplemented
*/