mirror of
https://github.com/reactos/reactos.git
synced 2024-10-31 11:56:26 +00:00
627e330d0d
svn path=/trunk/; revision=4934
350 lines
8.6 KiB
C
350 lines
8.6 KiB
C
/* $Id: priv.c,v 1.8 2003/06/20 18:19:29 ekohl Exp $
|
|
*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS kernel
|
|
* PURPOSE: Security manager
|
|
* FILE: kernel/se/priv.c
|
|
* PROGRAMER: ?
|
|
* REVISION HISTORY:
|
|
* 26/07/98: Added stubs for security functions
|
|
*/
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
#include <ddk/ntddk.h>
|
|
#include <internal/se.h>
|
|
|
|
#define NDEBUG
|
|
#include <internal/debug.h>
|
|
|
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
LUID SeCreateTokenPrivilege;
|
|
LUID SeAssignPrimaryTokenPrivilege;
|
|
LUID SeLockMemoryPrivilege;
|
|
LUID SeIncreaseQuotaPrivilege;
|
|
LUID SeUnsolicitedInputPrivilege;
|
|
LUID SeTcbPrivilege;
|
|
LUID SeSecurityPrivilege;
|
|
LUID SeTakeOwnershipPrivilege;
|
|
LUID SeLoadDriverPrivilege;
|
|
LUID SeCreatePagefilePrivilege;
|
|
LUID SeIncreaseBasePriorityPrivilege;
|
|
LUID SeSystemProfilePrivilege;
|
|
LUID SeSystemtimePrivilege;
|
|
LUID SeProfileSingleProcessPrivilege;
|
|
LUID SeCreatePermanentPrivilege;
|
|
LUID SeBackupPrivilege;
|
|
LUID SeRestorePrivilege;
|
|
LUID SeShutdownPrivilege;
|
|
LUID SeDebugPrivilege;
|
|
LUID SeAuditPrivilege;
|
|
LUID SeSystemEnvironmentPrivilege;
|
|
LUID SeChangeNotifyPrivilege;
|
|
LUID SeRemoteShutdownPrivilege;
|
|
|
|
|
|
/* FUNCTIONS ***************************************************************/
|
|
|
|
VOID
|
|
SepInitPrivileges (VOID)
|
|
{
|
|
SeCreateTokenPrivilege.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
|
|
SeCreateTokenPrivilege.HighPart = 0;
|
|
SeAssignPrimaryTokenPrivilege.LowPart = SE_ASSIGNPRIMARYTOKEN_PRIVILEGE;
|
|
SeAssignPrimaryTokenPrivilege.HighPart = 0;
|
|
SeLockMemoryPrivilege.LowPart = SE_LOCK_MEMORY_PRIVILEGE;
|
|
SeLockMemoryPrivilege.HighPart = 0;
|
|
SeIncreaseQuotaPrivilege.LowPart = SE_INCREASE_QUOTA_PRIVILEGE;
|
|
SeIncreaseQuotaPrivilege.HighPart = 0;
|
|
SeUnsolicitedInputPrivilege.LowPart = SE_UNSOLICITED_INPUT_PRIVILEGE;
|
|
SeUnsolicitedInputPrivilege.HighPart = 0;
|
|
SeTcbPrivilege.LowPart = SE_TCB_PRIVILEGE;
|
|
SeTcbPrivilege.HighPart = 0;
|
|
SeSecurityPrivilege.LowPart = SE_SECURITY_PRIVILEGE;
|
|
SeSecurityPrivilege.HighPart = 0;
|
|
SeTakeOwnershipPrivilege.LowPart = SE_TAKE_OWNERSHIP_PRIVILEGE;
|
|
SeTakeOwnershipPrivilege.HighPart = 0;
|
|
SeLoadDriverPrivilege.LowPart = SE_LOAD_DRIVER_PRIVILEGE;
|
|
SeLoadDriverPrivilege.HighPart = 0;
|
|
SeSystemProfilePrivilege.LowPart = SE_SYSTEM_PROFILE_PRIVILEGE;
|
|
SeSystemProfilePrivilege.HighPart = 0;
|
|
SeSystemtimePrivilege.LowPart = SE_SYSTEMTIME_PRIVILEGE;
|
|
SeSystemtimePrivilege.HighPart = 0;
|
|
SeProfileSingleProcessPrivilege.LowPart = SE_PROF_SINGLE_PROCESS_PRIVILEGE;
|
|
SeProfileSingleProcessPrivilege.HighPart = 0;
|
|
SeIncreaseBasePriorityPrivilege.LowPart = SE_INC_BASE_PRIORITY_PRIVILEGE;
|
|
SeIncreaseBasePriorityPrivilege.HighPart = 0;
|
|
SeCreatePagefilePrivilege.LowPart = SE_CREATE_PAGEFILE_PRIVILEGE;
|
|
SeCreatePagefilePrivilege.HighPart = 0;
|
|
SeCreatePermanentPrivilege.LowPart = SE_CREATE_PERMANENT_PRIVILEGE;
|
|
SeCreatePermanentPrivilege.HighPart = 0;
|
|
SeBackupPrivilege.LowPart = SE_BACKUP_PRIVILEGE;
|
|
SeBackupPrivilege.HighPart = 0;
|
|
SeRestorePrivilege.LowPart = SE_RESTORE_PRIVILEGE;
|
|
SeRestorePrivilege.HighPart = 0;
|
|
SeShutdownPrivilege.LowPart = SE_SHUTDOWN_PRIVILEGE;
|
|
SeShutdownPrivilege.HighPart = 0;
|
|
SeDebugPrivilege.LowPart = SE_DEBUG_PRIVILEGE;
|
|
SeDebugPrivilege.HighPart = 0;
|
|
SeAuditPrivilege.LowPart = SE_AUDIT_PRIVILEGE;
|
|
SeAuditPrivilege.HighPart = 0;
|
|
SeSystemEnvironmentPrivilege.LowPart = SE_SYSTEM_ENVIRONMENT_PRIVILEGE;
|
|
SeSystemEnvironmentPrivilege.HighPart = 0;
|
|
SeChangeNotifyPrivilege.LowPart = SE_CHANGE_NOTIFY_PRIVILEGE;
|
|
SeChangeNotifyPrivilege.HighPart = 0;
|
|
SeRemoteShutdownPrivilege.LowPart = SE_REMOTE_SHUTDOWN_PRIVILEGE;
|
|
SeRemoteShutdownPrivilege.HighPart = 0;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
SepPrivilegeCheck (PACCESS_TOKEN Token,
|
|
PLUID_AND_ATTRIBUTES Privileges,
|
|
ULONG PrivilegeCount,
|
|
ULONG PrivilegeControl,
|
|
KPROCESSOR_MODE PreviousMode)
|
|
{
|
|
ULONG i;
|
|
ULONG j;
|
|
ULONG k;
|
|
|
|
DPRINT ("SepPrivilegeCheck() called\n");
|
|
|
|
if (PreviousMode == KernelMode)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
k = 0;
|
|
if (PrivilegeCount > 0)
|
|
{
|
|
for (i = 0; i < Token->PrivilegeCount; i++)
|
|
{
|
|
for (j = 0; j < PrivilegeCount; j++)
|
|
{
|
|
if (Token->Privileges[i].Luid.LowPart == Privileges[j].Luid.LowPart &&
|
|
Token->Privileges[i].Luid.HighPart == Privileges[j].Luid.HighPart)
|
|
{
|
|
DPRINT ("Found privilege\n");
|
|
DPRINT ("Privilege attributes %lx\n",
|
|
Token->Privileges[i].Attributes);
|
|
|
|
if (Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED)
|
|
{
|
|
Privileges[j].Attributes |= SE_PRIVILEGE_USED_FOR_ACCESS;
|
|
k++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY) &&
|
|
PrivilegeCount == k)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if (k > 0 &&
|
|
!(PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src,
|
|
ULONG PrivilegeCount,
|
|
KPROCESSOR_MODE PreviousMode,
|
|
PLUID_AND_ATTRIBUTES AllocatedMem,
|
|
ULONG AllocatedLength,
|
|
POOL_TYPE PoolType,
|
|
ULONG d,
|
|
PLUID_AND_ATTRIBUTES* Dest,
|
|
PULONG Length)
|
|
{
|
|
PLUID_AND_ATTRIBUTES* NewMem;
|
|
ULONG SrcLength;
|
|
|
|
if (PrivilegeCount == 0)
|
|
{
|
|
*Dest = 0;
|
|
*Length = 0;
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
if (PreviousMode == KernelMode && d == 0)
|
|
{
|
|
*Dest = Src;
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
SrcLength = ((PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)) + 3) & 0xfc;
|
|
*Length = SrcLength;
|
|
if (AllocatedMem == NULL)
|
|
{
|
|
NewMem = ExAllocatePool (PoolType,
|
|
SrcLength);
|
|
*Dest = (PLUID_AND_ATTRIBUTES)NewMem;
|
|
if (NewMem == NULL)
|
|
{
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (SrcLength > AllocatedLength)
|
|
{
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
*Dest = AllocatedMem;
|
|
}
|
|
memmove (*Dest, Src, SrcLength);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
VOID
|
|
SeReleaseLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Privilege,
|
|
KPROCESSOR_MODE PreviousMode,
|
|
ULONG a)
|
|
{
|
|
ExFreePool (Privilege);
|
|
}
|
|
|
|
|
|
NTSTATUS STDCALL
|
|
NtPrivilegeCheck (IN HANDLE ClientToken,
|
|
IN PPRIVILEGE_SET RequiredPrivileges,
|
|
IN PBOOLEAN Result)
|
|
{
|
|
PLUID_AND_ATTRIBUTES Privilege;
|
|
PACCESS_TOKEN Token;
|
|
ULONG PrivilegeCount;
|
|
ULONG PrivilegeControl;
|
|
ULONG Length;
|
|
NTSTATUS Status;
|
|
|
|
Status = ObReferenceObjectByHandle (ClientToken,
|
|
0,
|
|
SepTokenObjectType,
|
|
UserMode,
|
|
(PVOID*)&Token,
|
|
NULL);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return Status;
|
|
}
|
|
|
|
if (Token->TokenType == TokenImpersonation &&
|
|
Token->ImpersonationLevel < SecurityAnonymous)
|
|
{
|
|
ObDereferenceObject (Token);
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
PrivilegeCount = RequiredPrivileges->PrivilegeCount;
|
|
PrivilegeControl = RequiredPrivileges->Control;
|
|
Privilege = 0;
|
|
Status = SeCaptureLuidAndAttributesArray (RequiredPrivileges->Privilege,
|
|
PrivilegeCount,
|
|
1,
|
|
0,
|
|
0,
|
|
1,
|
|
1,
|
|
&Privilege,
|
|
&Length);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
ObDereferenceObject (Token);
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
*Result = SepPrivilegeCheck (Token,
|
|
Privilege,
|
|
PrivilegeCount,
|
|
PrivilegeControl,
|
|
UserMode);
|
|
|
|
memmove (RequiredPrivileges->Privilege,
|
|
Privilege,
|
|
Length);
|
|
|
|
SeReleaseLuidAndAttributesArray (Privilege,
|
|
UserMode,
|
|
1);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
BOOLEAN STDCALL
|
|
SePrivilegeCheck (PPRIVILEGE_SET Privileges,
|
|
PSECURITY_SUBJECT_CONTEXT SubjectContext,
|
|
KPROCESSOR_MODE PreviousMode)
|
|
{
|
|
PACCESS_TOKEN Token = NULL;
|
|
|
|
if (SubjectContext->ClientToken == NULL)
|
|
{
|
|
Token = SubjectContext->PrimaryToken;
|
|
}
|
|
else
|
|
{
|
|
Token = SubjectContext->ClientToken;
|
|
if (SubjectContext->ImpersonationLevel < 2)
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return SepPrivilegeCheck (Token,
|
|
Privileges->Privilege,
|
|
Privileges->PrivilegeCount,
|
|
Privileges->Control,
|
|
PreviousMode);
|
|
}
|
|
|
|
|
|
BOOLEAN STDCALL
|
|
SeSinglePrivilegeCheck (IN LUID PrivilegeValue,
|
|
IN KPROCESSOR_MODE PreviousMode)
|
|
{
|
|
SECURITY_SUBJECT_CONTEXT SubjectContext;
|
|
PRIVILEGE_SET Priv;
|
|
BOOLEAN Result;
|
|
|
|
SeCaptureSubjectContext (&SubjectContext);
|
|
|
|
Priv.PrivilegeCount = 1;
|
|
Priv.Control = PRIVILEGE_SET_ALL_NECESSARY;
|
|
Priv.Privilege[0].Luid = PrivilegeValue;
|
|
Priv.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
|
|
Result = SePrivilegeCheck (&Priv,
|
|
&SubjectContext,
|
|
PreviousMode);
|
|
|
|
if (PreviousMode != KernelMode)
|
|
{
|
|
#if 0
|
|
SePrivilegedServiceAuditAlarm (0,
|
|
&SubjectContext,
|
|
&PrivilegeValue);
|
|
#endif
|
|
}
|
|
|
|
SeReleaseSubjectContext (&SubjectContext);
|
|
|
|
return Result;
|
|
}
|
|
|
|
/* EOF */
|