mirror of
https://github.com/reactos/reactos.git
synced 2024-06-26 07:51:52 +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,
|
||||
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"))
|
||||
{
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <winwlx.h>
|
||||
#include <rtlfuncs.h>
|
||||
#include <exfuncs.h>
|
||||
#include <setypes.h>
|
||||
|
||||
#include <reactos/winlogon.h>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -129,6 +129,13 @@ SeSubProcessToken(
|
|||
IN ULONG SessionId
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SeIsTokenChild(
|
||||
IN PTOKEN Token,
|
||||
OUT PBOOLEAN IsChild
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
SepCreateImpersonationTokenDacl(
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 *****************************************************************/
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue