mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
[NTOSKRNL]
NtAccessCheck: Call SePrivilegePolicyCheck to get the list of required privileges and return it to the caller. This fixes the ERROR_INSUFFICIENT_BUFFER failures in the advapi32 security winetest. svn path=/trunk/; revision=75028
This commit is contained in:
parent
74a68e0f6b
commit
7b4db04803
1 changed files with 75 additions and 2 deletions
|
@ -316,6 +316,19 @@ SepGetSDGroup(IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
|
|||
return Group;
|
||||
}
|
||||
|
||||
static
|
||||
ULONG
|
||||
SepGetPrivilegeSetLength(IN PPRIVILEGE_SET PrivilegeSet)
|
||||
{
|
||||
if (PrivilegeSet == NULL)
|
||||
return 0;
|
||||
|
||||
if (PrivilegeSet->PrivilegeCount == 0)
|
||||
return (ULONG)(sizeof(PRIVILEGE_SET) - sizeof(LUID_AND_ATTRIBUTES));
|
||||
|
||||
return (ULONG)(sizeof(PRIVILEGE_SET) +
|
||||
(PrivilegeSet->PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES));
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
|
@ -526,6 +539,8 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
|||
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
|
||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||
ACCESS_MASK PreviouslyGrantedAccess = 0;
|
||||
PPRIVILEGE_SET Privileges = NULL;
|
||||
ULONG CapturedPrivilegeSetLength, RequiredPrivilegeSetLength;
|
||||
PTOKEN Token;
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
@ -561,8 +576,8 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
|||
ProbeForWrite(GrantedAccess, sizeof(ACCESS_MASK), sizeof(ULONG));
|
||||
ProbeForWrite(AccessStatus, sizeof(NTSTATUS), sizeof(ULONG));
|
||||
|
||||
/* Initialize the privilege set */
|
||||
PrivilegeSet->PrivilegeCount = 0;
|
||||
/* Capture the privilege set length and the mapping */
|
||||
CapturedPrivilegeSetLength = *PrivilegeSetLength;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
|
@ -604,6 +619,64 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
|||
return STATUS_BAD_IMPERSONATION_LEVEL;
|
||||
}
|
||||
|
||||
/* Check for ACCESS_SYSTEM_SECURITY and WRITE_OWNER access */
|
||||
Status = SePrivilegePolicyCheck(&DesiredAccess,
|
||||
&PreviouslyGrantedAccess,
|
||||
NULL,
|
||||
Token,
|
||||
&Privileges,
|
||||
PreviousMode);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("SePrivilegePolicyCheck failed (Status 0x%08lx)\n", Status);
|
||||
ObDereferenceObject(Token);
|
||||
*AccessStatus = Status;
|
||||
*GrantedAccess = 0;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Check the size of the privilege set and return the privileges */
|
||||
if (Privileges != NULL)
|
||||
{
|
||||
DPRINT("Privileges != NULL\n");
|
||||
|
||||
/* Calculate the required privilege set buffer size */
|
||||
RequiredPrivilegeSetLength = SepGetPrivilegeSetLength(Privileges);
|
||||
|
||||
/* Fail if the privilege set buffer is too small */
|
||||
if (CapturedPrivilegeSetLength < RequiredPrivilegeSetLength)
|
||||
{
|
||||
ObDereferenceObject(Token);
|
||||
SeFreePrivileges(Privileges);
|
||||
*PrivilegeSetLength = RequiredPrivilegeSetLength;
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Copy the privilege set to the caller */
|
||||
RtlCopyMemory(PrivilegeSet,
|
||||
Privileges,
|
||||
RequiredPrivilegeSetLength);
|
||||
|
||||
/* Free the local privilege set */
|
||||
SeFreePrivileges(Privileges);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Privileges == NULL\n");
|
||||
|
||||
/* Fail if the privilege set buffer is too small */
|
||||
if (CapturedPrivilegeSetLength < sizeof(PRIVILEGE_SET))
|
||||
{
|
||||
ObDereferenceObject(Token);
|
||||
*PrivilegeSetLength = sizeof(PRIVILEGE_SET);
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Initialize the privilege set */
|
||||
PrivilegeSet->PrivilegeCount = 0;
|
||||
PrivilegeSet->Control = 0;
|
||||
}
|
||||
|
||||
/* Capture the security descriptor */
|
||||
Status = SeCaptureSecurityDescriptor(SecurityDescriptor,
|
||||
PreviousMode,
|
||||
|
|
Loading…
Reference in a new issue