[NTOSKRNL]

- Rename SepAccessCheck to SepAccessCheckEx, start adding support for ObjectType and result lists, call SepAccessCheckEx from SepAccessCheck

svn path=/trunk/; revision=62074
This commit is contained in:
Timo Kreuzer 2014-02-09 16:57:42 +00:00
parent f705bb1dae
commit f75ea0d95a

View file

@ -21,22 +21,25 @@
#define OLD_ACCESS_CHECK #define OLD_ACCESS_CHECK
BOOLEAN NTAPI BOOLEAN NTAPI
SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, SepAccessCheckEx(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK DesiredAccess,
IN POBJECT_TYPE_LIST ObjectTypeList,
IN ULONG ObjectTypeListLength,
IN ACCESS_MASK PreviouslyGrantedAccess, IN ACCESS_MASK PreviouslyGrantedAccess,
OUT PPRIVILEGE_SET* Privileges, OUT PPRIVILEGE_SET* Privileges,
IN PGENERIC_MAPPING GenericMapping, IN PGENERIC_MAPPING GenericMapping,
IN KPROCESSOR_MODE AccessMode, IN KPROCESSOR_MODE AccessMode,
OUT PACCESS_MASK GrantedAccess, OUT PACCESS_MASK GrantedAccessList,
OUT PNTSTATUS AccessStatus) OUT PNTSTATUS AccessStatusList,
IN BOOLEAN UseResultList)
{ {
ACCESS_MASK RemainingAccess; ACCESS_MASK RemainingAccess;
ACCESS_MASK TempAccess; ACCESS_MASK TempAccess;
ACCESS_MASK TempGrantedAccess = 0; ACCESS_MASK TempGrantedAccess = 0;
ACCESS_MASK TempDeniedAccess = 0; ACCESS_MASK TempDeniedAccess = 0;
PACCESS_TOKEN Token; PACCESS_TOKEN Token;
ULONG i; ULONG i, ResultListLength;
PACL Dacl; PACL Dacl;
BOOLEAN Present; BOOLEAN Present;
BOOLEAN Defaulted; BOOLEAN Defaulted;
@ -52,15 +55,14 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
if (!PreviouslyGrantedAccess) if (!PreviouslyGrantedAccess)
{ {
/* Then there's nothing to give */ /* Then there's nothing to give */
*AccessStatus = STATUS_ACCESS_DENIED; Status = STATUS_ACCESS_DENIED;
return FALSE; goto ReturnCommonStatus;
} }
/* Return the previous access only */ /* Return the previous access only */
*GrantedAccess = PreviouslyGrantedAccess; Status = STATUS_SUCCESS;
*AccessStatus = STATUS_SUCCESS;
*Privileges = NULL; *Privileges = NULL;
return TRUE; goto ReturnCommonStatus;
} }
/* Map given accesses */ /* Map given accesses */
@ -83,16 +85,14 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
UserMode); UserMode);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
*AccessStatus = Status; goto ReturnCommonStatus;
return FALSE;
} }
/* Succeed if there are no more rights to grant */ /* Succeed if there are no more rights to grant */
if (RemainingAccess == 0) if (RemainingAccess == 0)
{ {
*GrantedAccess = PreviouslyGrantedAccess; Status = STATUS_SUCCESS;
*AccessStatus = STATUS_SUCCESS; goto ReturnCommonStatus;
return TRUE;
} }
/* Get the DACL */ /* Get the DACL */
@ -102,25 +102,21 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
&Defaulted); &Defaulted);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
*AccessStatus = Status; goto ReturnCommonStatus;
return FALSE;
} }
/* RULE 1: Grant desired access if the object is unprotected */ /* RULE 1: Grant desired access if the object is unprotected */
if (Present == FALSE || Dacl == NULL) if (Present == FALSE || Dacl == NULL)
{ {
if (DesiredAccess & MAXIMUM_ALLOWED) PreviouslyGrantedAccess |= RemainingAccess;
if (RemainingAccess & MAXIMUM_ALLOWED)
{ {
*GrantedAccess = GenericMapping->GenericAll; PreviouslyGrantedAccess &= ~MAXIMUM_ALLOWED;
*GrantedAccess |= (DesiredAccess | PreviouslyGrantedAccess) & ~MAXIMUM_ALLOWED; PreviouslyGrantedAccess |= GenericMapping->GenericAll;
}
else
{
*GrantedAccess = DesiredAccess | PreviouslyGrantedAccess;
} }
*AccessStatus = STATUS_SUCCESS; Status = STATUS_SUCCESS;
return TRUE; goto ReturnCommonStatus;
} }
/* Deny access if the DACL is empty */ /* Deny access if the DACL is empty */
@ -128,24 +124,14 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
{ {
if (RemainingAccess == MAXIMUM_ALLOWED && PreviouslyGrantedAccess != 0) if (RemainingAccess == MAXIMUM_ALLOWED && PreviouslyGrantedAccess != 0)
{ {
*GrantedAccess = PreviouslyGrantedAccess; Status = STATUS_SUCCESS;
*AccessStatus = STATUS_SUCCESS;
return TRUE;
} }
else else
{ {
*GrantedAccess = 0; PreviouslyGrantedAccess = 0;
*AccessStatus = STATUS_ACCESS_DENIED; Status = STATUS_ACCESS_DENIED;
return FALSE;
} }
} goto ReturnCommonStatus;
/* Fail if DACL is absent */
if (Present == FALSE)
{
*GrantedAccess = 0;
*AccessStatus = STATUS_ACCESS_DENIED;
return FALSE;
} }
/* Determine the MAXIMUM_ALLOWED access rights according to the DACL */ /* Determine the MAXIMUM_ALLOWED access rights according to the DACL */
@ -195,23 +181,22 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
RemainingAccess &= ~(MAXIMUM_ALLOWED | TempGrantedAccess); RemainingAccess &= ~(MAXIMUM_ALLOWED | TempGrantedAccess);
if (RemainingAccess != 0) if (RemainingAccess != 0)
{ {
*GrantedAccess = 0; PreviouslyGrantedAccess = 0;
*AccessStatus = STATUS_ACCESS_DENIED; Status = STATUS_ACCESS_DENIED;
return FALSE; goto ReturnCommonStatus;
} }
/* Set granted access right and access status */ /* Set granted access right and access status */
*GrantedAccess = TempGrantedAccess | PreviouslyGrantedAccess; PreviouslyGrantedAccess |= TempGrantedAccess;
if (*GrantedAccess != 0) if (PreviouslyGrantedAccess != 0)
{ {
*AccessStatus = STATUS_SUCCESS; Status = STATUS_SUCCESS;
return TRUE;
} }
else else
{ {
*AccessStatus = STATUS_ACCESS_DENIED; Status = STATUS_ACCESS_DENIED;
return FALSE;
} }
goto ReturnCommonStatus;
} }
/* RULE 4: Grant rights according to the DACL */ /* RULE 4: Grant rights according to the DACL */
@ -226,9 +211,9 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
if (SepSidInToken(Token, Sid)) if (SepSidInToken(Token, Sid))
{ {
#ifdef OLD_ACCESS_CHECK #ifdef OLD_ACCESS_CHECK
*GrantedAccess = 0; PreviouslyGrantedAccess = 0;
*AccessStatus = STATUS_ACCESS_DENIED; Status = STATUS_ACCESS_DENIED;
return FALSE; goto ReturnCommonStatus;
#else #else
/* Map access rights from the ACE */ /* Map access rights from the ACE */
TempAccess = CurrentAce->AccessMask; TempAccess = CurrentAce->AccessMask;
@ -272,23 +257,23 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
DPRINT("PreviouslyGrantedAccess %08lx\n DesiredAccess %08lx\n", DPRINT("PreviouslyGrantedAccess %08lx\n DesiredAccess %08lx\n",
PreviouslyGrantedAccess, DesiredAccess); PreviouslyGrantedAccess, DesiredAccess);
*GrantedAccess = PreviouslyGrantedAccess & DesiredAccess; PreviouslyGrantedAccess &= DesiredAccess;
if ((*GrantedAccess & ~VALID_INHERIT_FLAGS) == if ((PreviouslyGrantedAccess & ~VALID_INHERIT_FLAGS) ==
(DesiredAccess & ~VALID_INHERIT_FLAGS)) (DesiredAccess & ~VALID_INHERIT_FLAGS))
{ {
*AccessStatus = STATUS_SUCCESS; Status = STATUS_SUCCESS;
return TRUE; goto ReturnCommonStatus;
} }
else else
{ {
DPRINT1("HACK: Should deny access for caller: granted 0x%lx, desired 0x%lx (generic mapping %p).\n", DPRINT1("HACK: Should deny access for caller: granted 0x%lx, desired 0x%lx (generic mapping %p).\n",
*GrantedAccess, DesiredAccess, GenericMapping); PreviouslyGrantedAccess, DesiredAccess, GenericMapping);
//*AccessStatus = STATUS_ACCESS_DENIED; //*AccessStatus = STATUS_ACCESS_DENIED;
//return FALSE; //return FALSE;
*GrantedAccess = DesiredAccess; PreviouslyGrantedAccess = DesiredAccess;
*AccessStatus = STATUS_SUCCESS; Status = STATUS_SUCCESS;
return TRUE; goto ReturnCommonStatus;
} }
#else #else
DPRINT("DesiredAccess %08lx\nPreviouslyGrantedAccess %08lx\nRemainingAccess %08lx\n", DPRINT("DesiredAccess %08lx\nPreviouslyGrantedAccess %08lx\nRemainingAccess %08lx\n",
@ -298,25 +283,61 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
if (RemainingAccess != 0) if (RemainingAccess != 0)
{ {
*GrantedAccess = 0; *GrantedAccess = 0;
*AccessStatus = STATUS_ACCESS_DENIED; Status = STATUS_ACCESS_DENIED;
return FALSE; goto ReturnCommonStatus;
} }
/* Set granted access rights */ /* Set granted access rights */
*GrantedAccess = DesiredAccess | PreviouslyGrantedAccess; PreviouslyGrantedAccess |= DesiredAccess;
DPRINT("GrantedAccess %08lx\n", *GrantedAccess); DPRINT("GrantedAccess %08lx\n", *GrantedAccess);
/* Fail if no rights have been granted */ /* Fail if no rights have been granted */
if (*GrantedAccess == 0) if (PreviouslyGrantedAccess == 0)
{ {
*AccessStatus = STATUS_ACCESS_DENIED; Status = STATUS_ACCESS_DENIED;
return FALSE; goto ReturnCommonStatus;
} }
*AccessStatus = STATUS_SUCCESS; Status = STATUS_SUCCESS;
return TRUE; goto ReturnCommonStatus;
#endif #endif
ReturnCommonStatus:
ResultListLength = UseResultList ? ObjectTypeListLength : 1;
for (i = 0; i < ResultListLength; i++)
{
GrantedAccessList[i] = PreviouslyGrantedAccess;
AccessStatusList[i] = Status;
}
return NT_SUCCESS(Status);
}
BOOLEAN NTAPI
SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
IN ACCESS_MASK DesiredAccess,
IN ACCESS_MASK PreviouslyGrantedAccess,
OUT PPRIVILEGE_SET* Privileges,
IN PGENERIC_MAPPING GenericMapping,
IN KPROCESSOR_MODE AccessMode,
OUT PACCESS_MASK GrantedAccess,
OUT PNTSTATUS AccessStatus)
{
return SepAccessCheckEx(SecurityDescriptor,
SubjectSecurityContext,
DesiredAccess,
NULL,
0,
PreviouslyGrantedAccess,
Privileges,
GenericMapping,
AccessMode,
GrantedAccess,
AccessStatus,
FALSE);
} }
static PSID static PSID