-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/se/priv.c
* PROGRAMMERS: No programmer listed.
*/
-/* INCLUDES *****************************************************************/
+/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, SepInitPrivileges)
#endif
-
-/* GLOBALS *******************************************************************/
+/* GLOBALS ********************************************************************/
LUID SeCreateTokenPrivilege;
LUID SeAssignPrimaryTokenPrivilege;
LUID SeSyncAgentPrivilege;
LUID SeEnableDelegationPrivilege;
-
-/* FUNCTIONS ***************************************************************/
+/* PRIVATE FUNCTIONS **********************************************************/
VOID
INIT_FUNCTION
NTAPI
-SepInitPrivileges (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;
- SeUndockPrivilege.LowPart = SE_UNDOCK_PRIVILEGE;
- SeUndockPrivilege.HighPart = 0;
- SeSyncAgentPrivilege.LowPart = SE_SYNC_AGENT_PRIVILEGE;
- SeSyncAgentPrivilege.HighPart = 0;
- SeEnableDelegationPrivilege.LowPart = SE_ENABLE_DELEGATION_PRIVILEGE;
- SeEnableDelegationPrivilege.HighPart = 0;
+ 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;
+ SeUndockPrivilege.LowPart = SE_UNDOCK_PRIVILEGE;
+ SeUndockPrivilege.HighPart = 0;
+ SeSyncAgentPrivilege.LowPart = SE_SYNC_AGENT_PRIVILEGE;
+ SeSyncAgentPrivilege.HighPart = 0;
+ SeEnableDelegationPrivilege.LowPart = SE_ENABLE_DELEGATION_PRIVILEGE;
+ SeEnableDelegationPrivilege.HighPart = 0;
}
BOOLEAN
NTAPI
-SepPrivilegeCheck (PTOKEN Token,
- PLUID_AND_ATTRIBUTES Privileges,
- ULONG PrivilegeCount,
- ULONG PrivilegeControl,
- KPROCESSOR_MODE PreviousMode)
+SepPrivilegeCheck(PTOKEN Token,
+ PLUID_AND_ATTRIBUTES Privileges,
+ ULONG PrivilegeCount,
+ ULONG PrivilegeControl,
+ KPROCESSOR_MODE PreviousMode)
{
- ULONG i;
- ULONG j;
- ULONG k;
+ ULONG i;
+ ULONG j;
+ ULONG k;
- DPRINT ("SepPrivilegeCheck() called\n");
+ DPRINT("SepPrivilegeCheck() called\n");
- PAGED_CODE();
+ PAGED_CODE();
- if (PreviousMode == KernelMode)
+ if (PreviousMode == KernelMode)
{
- return TRUE;
+ return TRUE;
}
- k = 0;
- if (PrivilegeCount > 0)
+ 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++;
- }
- }
- }
- }
+ 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)
+ if ((PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY) &&
+ PrivilegeCount == k)
{
- return TRUE;
+ return TRUE;
}
- if (k > 0 &&
- !(PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY))
+ if (k > 0 &&
+ !(PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY))
{
- return TRUE;
+ return TRUE;
}
- return FALSE;
+ return FALSE;
}
-
NTSTATUS
NTAPI
-SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src,
- ULONG PrivilegeCount,
- KPROCESSOR_MODE PreviousMode,
- PLUID_AND_ATTRIBUTES AllocatedMem,
- ULONG AllocatedLength,
- POOL_TYPE PoolType,
- BOOLEAN CaptureIfKernel,
- PLUID_AND_ATTRIBUTES* Dest,
- PULONG Length)
+SeCaptureLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Src,
+ ULONG PrivilegeCount,
+ KPROCESSOR_MODE PreviousMode,
+ PLUID_AND_ATTRIBUTES AllocatedMem,
+ ULONG AllocatedLength,
+ POOL_TYPE PoolType,
+ BOOLEAN CaptureIfKernel,
+ PLUID_AND_ATTRIBUTES *Dest,
+ PULONG Length)
{
ULONG BufferSize;
NTSTATUS Status = STATUS_SUCCESS;
}
/* FIXME - check PrivilegeCount for a valid number so we don't
- cause an integer overflow or exhaust system resources! */
+ cause an integer overflow or exhaust system resources! */
BufferSize = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
*Length = ROUND_UP(BufferSize, 4); /* round up to a 4 byte alignment */
/* probe the buffer */
if (PreviousMode != KernelMode)
{
- _SEH_TRY
+ _SEH2_TRY
{
ProbeForRead(Src,
BufferSize,
sizeof(ULONG));
}
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if (!NT_SUCCESS(Status))
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- return Status;
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
+ _SEH2_END;
}
/* allocate enough memory or check if the provided buffer is
- large enough to hold the array */
+ large enough to hold the array */
if (AllocatedMem != NULL)
{
if (AllocatedLength < BufferSize)
{
*Dest = ExAllocatePool(PoolType,
BufferSize);
-
- if (&Dest == NULL)
+ if (*Dest == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
}
-
+
/* copy the array to the buffer */
- _SEH_TRY
+ _SEH2_TRY
{
RtlCopyMemory(*Dest,
Src,
BufferSize);
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
if (!NT_SUCCESS(Status) && AllocatedMem == NULL)
{
return Status;
}
-
VOID
NTAPI
-SeReleaseLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Privilege,
- KPROCESSOR_MODE PreviousMode,
- BOOLEAN CaptureIfKernel)
+SeReleaseLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Privilege,
+ KPROCESSOR_MODE PreviousMode,
+ BOOLEAN CaptureIfKernel)
{
PAGED_CODE();
}
}
+/* PUBLIC FUNCTIONS ***********************************************************/
-NTSTATUS STDCALL
-NtPrivilegeCheck (IN HANDLE ClientToken,
- IN PPRIVILEGE_SET RequiredPrivileges,
- OUT PBOOLEAN Result)
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+SeAppendPrivileges(IN OUT PACCESS_STATE AccessState,
+ IN PPRIVILEGE_SET Privileges)
{
- PLUID_AND_ATTRIBUTES Privileges;
- PTOKEN Token;
- ULONG PrivilegeCount = 0;
- ULONG PrivilegeControl = 0;
- ULONG Length;
- BOOLEAN CheckResult;
- KPROCESSOR_MODE PreviousMode;
- NTSTATUS Status = STATUS_SUCCESS;
-
- PAGED_CODE();
-
- PreviousMode = KeGetPreviousMode();
-
- /* probe the buffers */
- if (PreviousMode != KernelMode)
- {
- _SEH_TRY
- {
- ProbeForWrite(RequiredPrivileges,
- FIELD_OFFSET(PRIVILEGE_SET,
- Privilege),
- sizeof(ULONG));
-
- PrivilegeCount = RequiredPrivileges->PrivilegeCount;
- PrivilegeControl = RequiredPrivileges->Control;
-
- /* Check PrivilegeCount to avoid an integer overflow! */
- if (FIELD_OFFSET(PRIVILEGE_SET,
- Privilege[PrivilegeCount]) /
- sizeof(RequiredPrivileges->Privilege[0]) != PrivilegeCount)
- {
- Status = STATUS_INVALID_PARAMETER;
- _SEH_LEAVE;
- }
-
- /* probe all of the array */
- ProbeForWrite(RequiredPrivileges,
- FIELD_OFFSET(PRIVILEGE_SET,
- Privilege[PrivilegeCount]),
- sizeof(ULONG));
-
- ProbeForWriteBoolean(Result);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
+ PAUX_ACCESS_DATA AuxData;
+ ULONG OldPrivilegeSetSize;
+ ULONG NewPrivilegeSetSize;
+ PPRIVILEGE_SET PrivilegeSet;
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
- }
- else
- {
- PrivilegeCount = RequiredPrivileges->PrivilegeCount;
- PrivilegeControl = RequiredPrivileges->Control;
- }
-
- /* reference the token and make sure we're
- not doing an anonymous impersonation */
- Status = ObReferenceObjectByHandle (ClientToken,
- TOKEN_QUERY,
- SepTokenObjectType,
- PreviousMode,
- (PVOID*)&Token,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
+ PAGED_CODE();
- if (Token->TokenType == TokenImpersonation &&
- Token->ImpersonationLevel < SecurityIdentification)
+ /* Get the Auxiliary Data */
+ AuxData = AccessState->AuxData;
+
+ /* Calculate the size of the old privilege set */
+ OldPrivilegeSetSize = sizeof(PRIVILEGE_SET) +
+ (AuxData->PrivilegeSet->PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES);
+
+ if (AuxData->PrivilegeSet->PrivilegeCount +
+ Privileges->PrivilegeCount > INITIAL_PRIVILEGE_COUNT)
{
- ObDereferenceObject (Token);
- return STATUS_BAD_IMPERSONATION_LEVEL;
- }
+ /* Calculate the size of the new privilege set */
+ NewPrivilegeSetSize = OldPrivilegeSetSize +
+ Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
+
+ /* Allocate a new privilege set */
+ PrivilegeSet = ExAllocatePool(PagedPool, NewPrivilegeSetSize);
+ if (PrivilegeSet == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Copy original privileges from the acess state */
+ RtlCopyMemory(PrivilegeSet,
+ AuxData->PrivilegeSet,
+ OldPrivilegeSetSize);
+
+ /* Append privileges from the privilege set*/
+ RtlCopyMemory((PVOID)((ULONG_PTR)PrivilegeSet + OldPrivilegeSetSize),
+ (PVOID)((ULONG_PTR)Privileges + sizeof(PRIVILEGE_SET) - sizeof(LUID_AND_ATTRIBUTES)),
+ Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
+
+ /* Adjust the number of privileges in the new privilege set */
+ PrivilegeSet->PrivilegeCount += Privileges->PrivilegeCount;
+
+ /* Free the old privilege set if it was allocated */
+ if (AccessState->PrivilegesAllocated == TRUE)
+ ExFreePool(AuxData->PrivilegeSet);
- /* capture the privileges */
- Status = SeCaptureLuidAndAttributesArray (RequiredPrivileges->Privilege,
- PrivilegeCount,
- PreviousMode,
- NULL,
- 0,
- PagedPool,
- TRUE,
- &Privileges,
- &Length);
- if (!NT_SUCCESS(Status))
+ /* Now we are using an allocated privilege set */
+ AccessState->PrivilegesAllocated = TRUE;
+
+ /* Assign the new privileges to the access state */
+ AuxData->PrivilegeSet = PrivilegeSet;
+ }
+ else
{
- ObDereferenceObject (Token);
- return Status;
+ /* Append privileges */
+ RtlCopyMemory((PVOID)((ULONG_PTR)AuxData->PrivilegeSet + OldPrivilegeSetSize),
+ (PVOID)((ULONG_PTR)Privileges + sizeof(PRIVILEGE_SET) - sizeof(LUID_AND_ATTRIBUTES)),
+ Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
+
+ /* Adjust the number of privileges in the target privilege set */
+ AuxData->PrivilegeSet->PrivilegeCount += Privileges->PrivilegeCount;
}
- CheckResult = SepPrivilegeCheck (Token,
- Privileges,
- PrivilegeCount,
- PrivilegeControl,
- PreviousMode);
-
- ObDereferenceObject (Token);
-
- /* return the array */
- _SEH_TRY
- {
- RtlCopyMemory(RequiredPrivileges->Privilege,
- Privileges,
- PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
- *Result = CheckResult;
- Status = STATUS_SUCCESS;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- SeReleaseLuidAndAttributesArray (Privileges,
- PreviousMode,
- TRUE);
-
- return Status;
+ return STATUS_SUCCESS;
}
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+SeFreePrivileges(IN PPRIVILEGE_SET Privileges)
+{
+ PAGED_CODE();
+ ExFreePool(Privileges);
+}
/*
* @implemented
*/
-BOOLEAN STDCALL
-SePrivilegeCheck (PPRIVILEGE_SET Privileges,
- PSECURITY_SUBJECT_CONTEXT SubjectContext,
- KPROCESSOR_MODE PreviousMode)
+BOOLEAN
+NTAPI
+SePrivilegeCheck(PPRIVILEGE_SET Privileges,
+ PSECURITY_SUBJECT_CONTEXT SubjectContext,
+ KPROCESSOR_MODE PreviousMode)
{
- PACCESS_TOKEN Token = NULL;
+ PACCESS_TOKEN Token = NULL;
- PAGED_CODE();
+ PAGED_CODE();
- if (SubjectContext->ClientToken == NULL)
+ if (SubjectContext->ClientToken == NULL)
{
- Token = SubjectContext->PrimaryToken;
+ Token = SubjectContext->PrimaryToken;
}
- else
+ else
{
- Token = SubjectContext->ClientToken;
- if (SubjectContext->ImpersonationLevel < 2)
- {
- return FALSE;
- }
+ Token = SubjectContext->ClientToken;
+ if (SubjectContext->ImpersonationLevel < 2)
+ {
+ return FALSE;
+ }
}
- return SepPrivilegeCheck (Token,
- Privileges->Privilege,
- Privileges->PrivilegeCount,
- Privileges->Control,
- PreviousMode);
+ return SepPrivilegeCheck(Token,
+ Privileges->Privilege,
+ Privileges->PrivilegeCount,
+ Privileges->Control,
+ PreviousMode);
}
-
/*
* @implemented
*/
-BOOLEAN STDCALL
-SeSinglePrivilegeCheck (IN LUID PrivilegeValue,
- IN KPROCESSOR_MODE PreviousMode)
+BOOLEAN
+NTAPI
+SeSinglePrivilegeCheck(IN LUID PrivilegeValue,
+ IN KPROCESSOR_MODE PreviousMode)
{
- SECURITY_SUBJECT_CONTEXT SubjectContext;
- PRIVILEGE_SET Priv;
- BOOLEAN Result;
+ SECURITY_SUBJECT_CONTEXT SubjectContext;
+ PRIVILEGE_SET Priv;
+ BOOLEAN Result;
- PAGED_CODE();
+ PAGED_CODE();
- SeCaptureSubjectContext (&SubjectContext);
+ SeCaptureSubjectContext(&SubjectContext);
- Priv.PrivilegeCount = 1;
- Priv.Control = PRIVILEGE_SET_ALL_NECESSARY;
- Priv.Privilege[0].Luid = PrivilegeValue;
- Priv.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
+ 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);
+ Result = SePrivilegeCheck(&Priv,
+ &SubjectContext,
+ PreviousMode);
- if (PreviousMode != KernelMode)
+ if (PreviousMode != KernelMode)
{
#if 0
- SePrivilegedServiceAuditAlarm (0,
- &SubjectContext,
- &PrivilegeValue);
+ SePrivilegedServiceAuditAlarm(0,
+ &SubjectContext,
+ &PrivilegeValue);
#endif
}
- SeReleaseSubjectContext (&SubjectContext);
+ SeReleaseSubjectContext(&SubjectContext);
+
+ return Result;
+}
+
+/* SYSTEM CALLS ***************************************************************/
+
+NTSTATUS
+NTAPI
+NtPrivilegeCheck(IN HANDLE ClientToken,
+ IN PPRIVILEGE_SET RequiredPrivileges,
+ OUT PBOOLEAN Result)
+{
+ PLUID_AND_ATTRIBUTES Privileges;
+ PTOKEN Token;
+ ULONG PrivilegeCount = 0;
+ ULONG PrivilegeControl = 0;
+ ULONG Length;
+ BOOLEAN CheckResult;
+ KPROCESSOR_MODE PreviousMode;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ PreviousMode = KeGetPreviousMode();
+
+ /* probe the buffers */
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(RequiredPrivileges,
+ FIELD_OFFSET(PRIVILEGE_SET,
+ Privilege),
+ sizeof(ULONG));
+
+ PrivilegeCount = RequiredPrivileges->PrivilegeCount;
+ PrivilegeControl = RequiredPrivileges->Control;
+
+ /* Check PrivilegeCount to avoid an integer overflow! */
+ if (FIELD_OFFSET(PRIVILEGE_SET,
+ Privilege[PrivilegeCount]) /
+ sizeof(RequiredPrivileges->Privilege[0]) != PrivilegeCount)
+ {
+ _SEH2_YIELD(return STATUS_INVALID_PARAMETER);
+ }
+
+ /* probe all of the array */
+ ProbeForWrite(RequiredPrivileges,
+ FIELD_OFFSET(PRIVILEGE_SET,
+ Privilege[PrivilegeCount]),
+ sizeof(ULONG));
+
+ ProbeForWriteBoolean(Result);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ PrivilegeCount = RequiredPrivileges->PrivilegeCount;
+ PrivilegeControl = RequiredPrivileges->Control;
+ }
+
+ /* reference the token and make sure we're
+ not doing an anonymous impersonation */
+ Status = ObReferenceObjectByHandle(ClientToken,
+ TOKEN_QUERY,
+ SepTokenObjectType,
+ PreviousMode,
+ (PVOID*)&Token,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ if (Token->TokenType == TokenImpersonation &&
+ Token->ImpersonationLevel < SecurityIdentification)
+ {
+ ObDereferenceObject(Token);
+ return STATUS_BAD_IMPERSONATION_LEVEL;
+ }
+
+ /* capture the privileges */
+ Status = SeCaptureLuidAndAttributesArray(RequiredPrivileges->Privilege,
+ PrivilegeCount,
+ PreviousMode,
+ NULL,
+ 0,
+ PagedPool,
+ TRUE,
+ &Privileges,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject (Token);
+ return Status;
+ }
- return Result;
+ CheckResult = SepPrivilegeCheck(Token,
+ Privileges,
+ PrivilegeCount,
+ PrivilegeControl,
+ PreviousMode);
+
+ ObDereferenceObject(Token);
+
+ /* return the array */
+ _SEH2_TRY
+ {
+ RtlCopyMemory(RequiredPrivileges->Privilege,
+ Privileges,
+ PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
+ *Result = CheckResult;
+ Status = STATUS_SUCCESS;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ SeReleaseLuidAndAttributesArray(Privileges,
+ PreviousMode,
+ TRUE);
+
+ return Status;
}
/* EOF */