reactos/reactos/ntoskrnl/se/priv.c
Eric Kohl 627e330d0d Disable debug messages.
svn path=/trunk/; revision=4934
2003-06-20 18:19:29 +00:00

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