mirror of
https://github.com/reactos/reactos.git
synced 2025-07-27 06:51:57 +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;
|
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 ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
|
@ -526,6 +539,8 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
|
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
ACCESS_MASK PreviouslyGrantedAccess = 0;
|
ACCESS_MASK PreviouslyGrantedAccess = 0;
|
||||||
|
PPRIVILEGE_SET Privileges = NULL;
|
||||||
|
ULONG CapturedPrivilegeSetLength, RequiredPrivilegeSetLength;
|
||||||
PTOKEN Token;
|
PTOKEN Token;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
@ -561,8 +576,8 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
ProbeForWrite(GrantedAccess, sizeof(ACCESS_MASK), sizeof(ULONG));
|
ProbeForWrite(GrantedAccess, sizeof(ACCESS_MASK), sizeof(ULONG));
|
||||||
ProbeForWrite(AccessStatus, sizeof(NTSTATUS), sizeof(ULONG));
|
ProbeForWrite(AccessStatus, sizeof(NTSTATUS), sizeof(ULONG));
|
||||||
|
|
||||||
/* Initialize the privilege set */
|
/* Capture the privilege set length and the mapping */
|
||||||
PrivilegeSet->PrivilegeCount = 0;
|
CapturedPrivilegeSetLength = *PrivilegeSetLength;
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
@ -604,6 +619,64 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
return STATUS_BAD_IMPERSONATION_LEVEL;
|
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 */
|
/* Capture the security descriptor */
|
||||||
Status = SeCaptureSecurityDescriptor(SecurityDescriptor,
|
Status = SeCaptureSecurityDescriptor(SecurityDescriptor,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue