- 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, 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"))
{ {

View file

@ -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>

View file

@ -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

View file

@ -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(

View file

@ -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 */

View file

@ -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 *****************************************************************/
/* /*

View file

@ -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
*/ */