mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 08:00:24 +00:00
- Cleanup AccessCheck, and set the correct last error in the case where the check succeeds but access is denied
- Cleanup NtAccessCheck, properly set desired access when previous mode is kernel, remove a duplicate check that is performed in SeAccessCheck, and don't fail with STATUS_ACCESS_DENIED when the check succeeds but denies access -- the result of the access check is returned in the 'AccessStatus' parameter svn path=/trunk/; revision=38510
This commit is contained in:
parent
226c5fb558
commit
fbd7681b84
2 changed files with 76 additions and 65 deletions
|
@ -135,19 +135,21 @@ SetTokenInformation(HANDLE TokenHandle,
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI
|
BOOL
|
||||||
AccessCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,
|
WINAPI
|
||||||
HANDLE ClientToken,
|
AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
|
||||||
DWORD DesiredAccess,
|
IN HANDLE ClientToken,
|
||||||
PGENERIC_MAPPING GenericMapping,
|
IN DWORD DesiredAccess,
|
||||||
PPRIVILEGE_SET PrivilegeSet,
|
IN PGENERIC_MAPPING GenericMapping,
|
||||||
LPDWORD PrivilegeSetLength,
|
OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL,
|
||||||
LPDWORD GrantedAccess,
|
IN OUT LPDWORD PrivilegeSetLength,
|
||||||
LPBOOL AccessStatus)
|
OUT LPDWORD GrantedAccess,
|
||||||
|
OUT LPBOOL AccessStatus)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
NTSTATUS AccessStat;
|
NTSTATUS NtAccessStatus;
|
||||||
|
|
||||||
|
/* Do the access check */
|
||||||
Status = NtAccessCheck(pSecurityDescriptor,
|
Status = NtAccessCheck(pSecurityDescriptor,
|
||||||
ClientToken,
|
ClientToken,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
|
@ -155,22 +157,30 @@ AccessCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,
|
||||||
PrivilegeSet,
|
PrivilegeSet,
|
||||||
(PULONG)PrivilegeSetLength,
|
(PULONG)PrivilegeSetLength,
|
||||||
(PACCESS_MASK)GrantedAccess,
|
(PACCESS_MASK)GrantedAccess,
|
||||||
&AccessStat);
|
&NtAccessStatus);
|
||||||
|
|
||||||
|
/* See if the access check operation succeeded */
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* Check failed */
|
||||||
SetLastError(RtlNtStatusToDosError(Status));
|
SetLastError(RtlNtStatusToDosError(Status));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(AccessStat))
|
/* Now check the access status */
|
||||||
|
if (!NT_SUCCESS(NtAccessStatus))
|
||||||
{
|
{
|
||||||
SetLastError(RtlNtStatusToDosError(Status));
|
/* Access denied */
|
||||||
|
SetLastError(RtlNtStatusToDosError(NtAccessStatus));
|
||||||
*AccessStatus = FALSE;
|
*AccessStatus = FALSE;
|
||||||
return TRUE;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Access granted */
|
||||||
|
*AccessStatus = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*AccessStatus = TRUE;
|
/* Check succeeded */
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -619,33 +619,48 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
|
|
||||||
/* SYSTEM CALLS ***************************************************************/
|
/* SYSTEM CALLS ***************************************************************/
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
IN HANDLE TokenHandle,
|
IN HANDLE TokenHandle,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
IN PGENERIC_MAPPING GenericMapping,
|
IN PGENERIC_MAPPING GenericMapping,
|
||||||
OUT PPRIVILEGE_SET PrivilegeSet,
|
OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL,
|
||||||
OUT PULONG ReturnLength,
|
IN OUT PULONG PrivilegeSetLength,
|
||||||
OUT PACCESS_MASK GrantedAccess,
|
OUT PACCESS_MASK GrantedAccess,
|
||||||
OUT PNTSTATUS AccessStatus)
|
OUT PNTSTATUS AccessStatus)
|
||||||
{
|
{
|
||||||
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext = { NULL, 0, NULL, NULL };
|
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
PTOKEN Token;
|
PTOKEN Token;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("NtAccessCheck() called\n");
|
/* Check if this is kernel mode */
|
||||||
|
|
||||||
PreviousMode = KeGetPreviousMode();
|
|
||||||
if (PreviousMode == KernelMode)
|
if (PreviousMode == KernelMode)
|
||||||
{
|
{
|
||||||
*GrantedAccess = DesiredAccess;
|
/* Check if kernel wants everything */
|
||||||
|
if (DesiredAccess & MAXIMUM_ALLOWED)
|
||||||
|
{
|
||||||
|
/* Give it */
|
||||||
|
*GrantedAccess = GenericMapping->GenericAll;
|
||||||
|
*GrantedAccess |= (DesiredAccess &~ MAXIMUM_ALLOWED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Just give the desired access */
|
||||||
|
*GrantedAccess = DesiredAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Success */
|
||||||
*AccessStatus = STATUS_SUCCESS;
|
*AccessStatus = STATUS_SUCCESS;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reference the token */
|
||||||
Status = ObReferenceObjectByHandle(TokenHandle,
|
Status = ObReferenceObjectByHandle(TokenHandle,
|
||||||
TOKEN_QUERY,
|
TOKEN_QUERY,
|
||||||
SepTokenObjectType,
|
SepTokenObjectType,
|
||||||
|
@ -657,57 +672,43 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
DPRINT1("Failed to reference token (Status %lx)\n", Status);
|
DPRINT1("Failed to reference token (Status %lx)\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check token type */
|
/* Check token type */
|
||||||
if (Token->TokenType != TokenImpersonation)
|
if (Token->TokenType != TokenImpersonation)
|
||||||
{
|
{
|
||||||
DPRINT1("No impersonation token\n");
|
DPRINT1("No impersonation token\n");
|
||||||
ObDereferenceObject(Token);
|
ObDereferenceObject(Token);
|
||||||
return STATUS_ACCESS_VIOLATION;
|
return STATUS_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check impersonation level */
|
/* Set up the subject context, and lock it */
|
||||||
if (Token->ImpersonationLevel < SecurityIdentification)
|
|
||||||
{
|
|
||||||
DPRINT1("Invalid impersonation level\n");
|
|
||||||
ObDereferenceObject(Token);
|
|
||||||
return STATUS_ACCESS_VIOLATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
SubjectSecurityContext.ClientToken = Token;
|
SubjectSecurityContext.ClientToken = Token;
|
||||||
SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel;
|
SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel;
|
||||||
|
SubjectSecurityContext.PrimaryToken = NULL;
|
||||||
/* Lock subject context */
|
SubjectSecurityContext.ProcessAuditId = NULL;
|
||||||
SeLockSubjectContext(&SubjectSecurityContext);
|
SeLockSubjectContext(&SubjectSecurityContext);
|
||||||
|
|
||||||
if (SeAccessCheck(SecurityDescriptor,
|
/* Now perform the access check */
|
||||||
&SubjectSecurityContext,
|
SeAccessCheck(SecurityDescriptor,
|
||||||
TRUE,
|
&SubjectSecurityContext,
|
||||||
DesiredAccess,
|
TRUE,
|
||||||
0,
|
DesiredAccess,
|
||||||
&PrivilegeSet,
|
0,
|
||||||
GenericMapping,
|
&PrivilegeSet, //FIXME
|
||||||
PreviousMode,
|
GenericMapping,
|
||||||
GrantedAccess,
|
PreviousMode,
|
||||||
AccessStatus))
|
GrantedAccess,
|
||||||
{
|
AccessStatus);
|
||||||
Status = *AccessStatus;
|
|
||||||
}
|
/* Unlock subject context and dereference the token */
|
||||||
else
|
|
||||||
{
|
|
||||||
Status = STATUS_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unlock subject context */
|
|
||||||
SeUnlockSubjectContext(&SubjectSecurityContext);
|
SeUnlockSubjectContext(&SubjectSecurityContext);
|
||||||
|
|
||||||
ObDereferenceObject(Token);
|
ObDereferenceObject(Token);
|
||||||
|
|
||||||
DPRINT("NtAccessCheck() done\n");
|
/* Check succeeded */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NtAccessCheckByType(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
NtAccessCheckByType(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
|
|
Loading…
Reference in a new issue