mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 10:20:03 +00:00
- 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:
parent
e553dd4145
commit
db04986dce
|
@ -534,6 +534,7 @@ WinMain(HINSTANCE hInstance,
|
||||||
LPSTR lpCmdLine,
|
LPSTR lpCmdLine,
|
||||||
int nShowCmd)
|
int nShowCmd)
|
||||||
{
|
{
|
||||||
|
BOOLEAN Old;
|
||||||
#if SUPPORT_CONSOLESTART
|
#if SUPPORT_CONSOLESTART
|
||||||
// WCHAR LoginName[255];
|
// WCHAR LoginName[255];
|
||||||
// WCHAR Password[255];
|
// WCHAR Password[255];
|
||||||
|
@ -555,6 +556,9 @@ WinMain(HINSTANCE hInstance,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get privilege */
|
||||||
|
RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old);
|
||||||
|
|
||||||
#if START_LSASS
|
#if START_LSASS
|
||||||
if (StartProcess(L"StartLsass"))
|
if (StartProcess(L"StartLsass"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <winwlx.h>
|
#include <winwlx.h>
|
||||||
#include <rtlfuncs.h>
|
#include <rtlfuncs.h>
|
||||||
#include <exfuncs.h>
|
#include <exfuncs.h>
|
||||||
|
#include <setypes.h>
|
||||||
|
|
||||||
#include <reactos/winlogon.h>
|
#include <reactos/winlogon.h>
|
||||||
|
|
||||||
|
|
|
@ -59,10 +59,11 @@ PsOpenTokenOfProcess(
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
NTAPI
|
||||||
PspAssignPrimaryToken(
|
PspSetPrimaryToken(
|
||||||
PEPROCESS Process,
|
IN PEPROCESS Process,
|
||||||
HANDLE TokenHandle
|
IN HANDLE TokenHandle OPTIONAL,
|
||||||
|
IN PTOKEN Token OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
PETHREAD
|
PETHREAD
|
||||||
|
|
|
@ -129,6 +129,13 @@ SeSubProcessToken(
|
||||||
IN ULONG SessionId
|
IN ULONG SessionId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
SeIsTokenChild(
|
||||||
|
IN PTOKEN Token,
|
||||||
|
OUT PBOOLEAN IsChild
|
||||||
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
SepCreateImpersonationTokenDacl(
|
SepCreateImpersonationTokenDacl(
|
||||||
|
|
|
@ -581,7 +581,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
|
||||||
if (!NT_SUCCESS(Status)) break;
|
if (!NT_SUCCESS(Status)) break;
|
||||||
|
|
||||||
/* Assign the actual token */
|
/* Assign the actual token */
|
||||||
Status = PspAssignPrimaryToken(Process, TokenHandle);
|
Status = PspSetPrimaryToken(Process, TokenHandle, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Hard error processing */
|
/* Hard error processing */
|
||||||
|
|
|
@ -25,7 +25,7 @@ PspLockProcessSecurityShared(IN PEPROCESS Process)
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
/* Lock the Process */
|
/* Lock the Process */
|
||||||
//ExAcquirePushLockShared(&Process->ProcessLock);
|
ExAcquirePushLockShared(&Process->ProcessLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Turn into Macro */
|
/* FIXME: Turn into Macro */
|
||||||
|
@ -34,7 +34,31 @@ NTAPI
|
||||||
PspUnlockProcessSecurityShared(IN PEPROCESS Process)
|
PspUnlockProcessSecurityShared(IN PEPROCESS Process)
|
||||||
{
|
{
|
||||||
/* Unlock the 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 */
|
/* Leave Critical Region */
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
@ -119,28 +143,92 @@ PspInitializeProcessSecurity(IN PEPROCESS Process,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
PspAssignPrimaryToken(IN PEPROCESS Process,
|
PspAssignPrimaryToken(IN PEPROCESS Process,
|
||||||
IN HANDLE TokenHandle)
|
IN PTOKEN Token)
|
||||||
{
|
{
|
||||||
PACCESS_TOKEN Token, OldToken;
|
PACCESS_TOKEN OldToken;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Reference the Token */
|
/* Lock the process */
|
||||||
Status = ObReferenceObjectByHandle(TokenHandle,
|
PspLockProcessSecurityExclusive(Process);
|
||||||
TOKEN_ASSIGN_PRIMARY,
|
|
||||||
SepTokenObjectType,
|
|
||||||
KeGetPreviousMode(),
|
|
||||||
(PVOID*)&Token,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
|
||||||
|
|
||||||
/* Exchange them */
|
/* Exchange them */
|
||||||
Status = SeExchangePrimaryToken(Process, Token, &OldToken);
|
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);
|
ObDereferenceObject(Token);
|
||||||
return Status;
|
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 *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -368,6 +368,36 @@ SeSubProcessToken(IN PTOKEN ParentToken,
|
||||||
return Status;
|
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
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue