mirror of
https://github.com/reactos/reactos.git
synced 2025-07-04 13:21:21 +00:00
- Move access checks from NtAccessCheck() to SeAccessCheck().
- Check for 'take ownership' privilege. svn path=/trunk/; revision=10111
This commit is contained in:
parent
6e17c87e59
commit
c6ec21e207
2 changed files with 179 additions and 170 deletions
|
@ -136,6 +136,13 @@ SeReleaseLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Privilege,
|
||||||
KPROCESSOR_MODE PreviousMode,
|
KPROCESSOR_MODE PreviousMode,
|
||||||
ULONG a);
|
ULONG a);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
SepPrivilegeCheck(PACCESS_TOKEN Token,
|
||||||
|
PLUID_AND_ATTRIBUTES Privileges,
|
||||||
|
ULONG PrivilegeCount,
|
||||||
|
ULONG PrivilegeControl,
|
||||||
|
KPROCESSOR_MODE PreviousMode);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_SE_H */
|
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_SE_H */
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: semgr.c,v 1.32 2004/07/13 16:59:35 ekohl Exp $
|
/* $Id: semgr.c,v 1.33 2004/07/14 14:25:31 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -15,6 +15,7 @@
|
||||||
#include <internal/ps.h>
|
#include <internal/ps.h>
|
||||||
#include <internal/se.h>
|
#include <internal/se.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
#define TAG_SXPT TAG('S', 'X', 'P', 'T')
|
#define TAG_SXPT TAG('S', 'X', 'P', 'T')
|
||||||
|
@ -273,50 +274,55 @@ SeDeassignSecurity(PSECURITY_DESCRIPTOR* SecurityDescriptor)
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
VOID SepGetDefaultsSubjectContext(PSECURITY_SUBJECT_CONTEXT SubjectContext,
|
VOID
|
||||||
PSID* Owner,
|
SepGetDefaultsSubjectContext(PSECURITY_SUBJECT_CONTEXT SubjectContext,
|
||||||
PSID* PrimaryGroup,
|
PSID* Owner,
|
||||||
PSID* ProcessOwner,
|
PSID* PrimaryGroup,
|
||||||
PSID* ProcessPrimaryGroup,
|
PSID* ProcessOwner,
|
||||||
PACL* DefaultDacl)
|
PSID* ProcessPrimaryGroup,
|
||||||
|
PACL* DefaultDacl)
|
||||||
{
|
{
|
||||||
PACCESS_TOKEN Token;
|
PACCESS_TOKEN Token;
|
||||||
|
|
||||||
if (SubjectContext->ClientToken != NULL)
|
if (SubjectContext->ClientToken != NULL)
|
||||||
{
|
{
|
||||||
Token = SubjectContext->ClientToken;
|
Token = SubjectContext->ClientToken;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Token = SubjectContext->PrimaryToken;
|
Token = SubjectContext->PrimaryToken;
|
||||||
}
|
}
|
||||||
*Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
|
*Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
|
||||||
*PrimaryGroup = Token->PrimaryGroup;
|
*PrimaryGroup = Token->PrimaryGroup;
|
||||||
*DefaultDacl = Token->DefaultDacl;
|
*DefaultDacl = Token->DefaultDacl;
|
||||||
*ProcessOwner = SubjectContext->PrimaryToken->
|
*ProcessOwner = SubjectContext->PrimaryToken->
|
||||||
UserAndGroups[Token->DefaultOwnerIndex].Sid;
|
UserAndGroups[Token->DefaultOwnerIndex].Sid;
|
||||||
*ProcessPrimaryGroup = SubjectContext->PrimaryToken->PrimaryGroup;
|
*ProcessPrimaryGroup = SubjectContext->PrimaryToken->PrimaryGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS SepInheritAcl(PACL Acl,
|
|
||||||
BOOLEAN IsDirectoryObject,
|
NTSTATUS
|
||||||
PSID Owner,
|
SepInheritAcl(PACL Acl,
|
||||||
PSID PrimaryGroup,
|
BOOLEAN IsDirectoryObject,
|
||||||
PACL DefaultAcl,
|
PSID Owner,
|
||||||
PSID ProcessOwner,
|
PSID PrimaryGroup,
|
||||||
PSID ProcessGroup,
|
PACL DefaultAcl,
|
||||||
PGENERIC_MAPPING GenericMapping)
|
PSID ProcessOwner,
|
||||||
|
PSID ProcessGroup,
|
||||||
|
PGENERIC_MAPPING GenericMapping)
|
||||||
{
|
{
|
||||||
if (Acl == NULL)
|
if (Acl == NULL)
|
||||||
{
|
{
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
if (Acl->AclRevision != 2 &&
|
|
||||||
Acl->AclRevision != 3 )
|
if (Acl->AclRevision != 2 &&
|
||||||
{
|
Acl->AclRevision != 3 )
|
||||||
|
{
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -448,64 +454,117 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
OUT PACCESS_MASK GrantedAccess,
|
OUT PACCESS_MASK GrantedAccess,
|
||||||
OUT PNTSTATUS AccessStatus)
|
OUT PNTSTATUS AccessStatus)
|
||||||
{
|
{
|
||||||
ULONG i;
|
LUID_AND_ATTRIBUTES Privilege;
|
||||||
PACL Dacl;
|
ACCESS_MASK CurrentAccess;
|
||||||
BOOLEAN Present;
|
PACCESS_TOKEN Token;
|
||||||
BOOLEAN Defaulted;
|
ULONG i;
|
||||||
NTSTATUS Status;
|
PACL Dacl;
|
||||||
PACE CurrentAce;
|
BOOLEAN Present;
|
||||||
PSID Sid;
|
BOOLEAN Defaulted;
|
||||||
ACCESS_MASK CurrentAccess;
|
PACE CurrentAce;
|
||||||
|
PSID Sid;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
CurrentAccess = PreviouslyGrantedAccess;
|
CurrentAccess = PreviouslyGrantedAccess;
|
||||||
|
|
||||||
/*
|
Token = SubjectSecurityContext->ClientToken ?
|
||||||
* Check the DACL
|
SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken;
|
||||||
*/
|
|
||||||
Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
|
/* Get the DACL */
|
||||||
&Present,
|
Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
|
||||||
&Dacl,
|
&Present,
|
||||||
|
&Dacl,
|
||||||
|
&Defaulted);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
*AccessStatus = Status;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RULE 1: Grant desired access if the object is unprotected */
|
||||||
|
if (Dacl == NULL)
|
||||||
|
{
|
||||||
|
*GrantedAccess = DesiredAccess;
|
||||||
|
*AccessStatus = STATUS_SUCCESS;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentAccess = PreviouslyGrantedAccess;
|
||||||
|
|
||||||
|
/* RULE 2: Check token for 'take ownership' privilege */
|
||||||
|
Privilege.Luid = SeTakeOwnershipPrivilege;
|
||||||
|
Privilege.Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
|
||||||
|
if (SepPrivilegeCheck(Token,
|
||||||
|
&Privilege,
|
||||||
|
1,
|
||||||
|
PRIVILEGE_SET_ALL_NECESSARY,
|
||||||
|
AccessMode))
|
||||||
|
{
|
||||||
|
CurrentAccess |= WRITE_OWNER;
|
||||||
|
if (DesiredAccess == CurrentAccess)
|
||||||
|
{
|
||||||
|
*GrantedAccess = CurrentAccess;
|
||||||
|
*AccessStatus = STATUS_SUCCESS;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RULE 3: Check whether the token is the owner */
|
||||||
|
Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
|
||||||
|
&Sid,
|
||||||
&Defaulted);
|
&Defaulted);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
*AccessStatus = Status;
|
DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status);
|
||||||
return FALSE;
|
*AccessStatus = Status;
|
||||||
}
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
CurrentAce = (PACE)(Dacl + 1);
|
if (SepSidInToken(Token, Sid))
|
||||||
for (i = 0; i < Dacl->AceCount; i++)
|
{
|
||||||
{
|
CurrentAccess |= (READ_CONTROL | WRITE_DAC);
|
||||||
Sid = (PSID)(CurrentAce + 1);
|
if (DesiredAccess == CurrentAccess)
|
||||||
if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
|
{
|
||||||
{
|
*GrantedAccess = CurrentAccess;
|
||||||
if (SepSidInToken(SubjectSecurityContext->ClientToken, Sid))
|
*AccessStatus = STATUS_SUCCESS;
|
||||||
{
|
return TRUE;
|
||||||
*AccessStatus = STATUS_ACCESS_DENIED;
|
}
|
||||||
*GrantedAccess = 0;
|
}
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
|
/* RULE 4: Grant rights according to the DACL */
|
||||||
{
|
CurrentAce = (PACE)(Dacl + 1);
|
||||||
if (SepSidInToken(SubjectSecurityContext->ClientToken, Sid))
|
for (i = 0; i < Dacl->AceCount; i++)
|
||||||
{
|
{
|
||||||
CurrentAccess |= CurrentAce->AccessMask;
|
Sid = (PSID)(CurrentAce + 1);
|
||||||
}
|
if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
|
||||||
}
|
{
|
||||||
}
|
if (SepSidInToken(Token, Sid))
|
||||||
if (!(CurrentAccess & DesiredAccess) &&
|
{
|
||||||
!((~CurrentAccess) & DesiredAccess))
|
*GrantedAccess = 0;
|
||||||
{
|
*AccessStatus = STATUS_ACCESS_DENIED;
|
||||||
*AccessStatus = STATUS_ACCESS_DENIED;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
*AccessStatus = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
*GrantedAccess = CurrentAccess;
|
|
||||||
|
|
||||||
return TRUE;
|
if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
|
||||||
|
{
|
||||||
|
if (SepSidInToken(Token, Sid))
|
||||||
|
{
|
||||||
|
CurrentAccess |= CurrentAce->AccessMask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
|
||||||
|
CurrentAccess, DesiredAccess);
|
||||||
|
|
||||||
|
*GrantedAccess = CurrentAccess & DesiredAccess;
|
||||||
|
|
||||||
|
*AccessStatus =
|
||||||
|
(*GrantedAccess == DesiredAccess) ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -519,15 +578,9 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
OUT PACCESS_MASK GrantedAccess,
|
OUT PACCESS_MASK GrantedAccess,
|
||||||
OUT PNTSTATUS AccessStatus)
|
OUT PNTSTATUS AccessStatus)
|
||||||
{
|
{
|
||||||
|
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
PACCESS_TOKEN Token;
|
PACCESS_TOKEN Token;
|
||||||
BOOLEAN Present;
|
|
||||||
BOOLEAN Defaulted;
|
|
||||||
PACE CurrentAce;
|
|
||||||
PACL Dacl;
|
|
||||||
PSID Sid;
|
|
||||||
ACCESS_MASK CurrentAccess;
|
|
||||||
ULONG i;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("NtAccessCheck() called\n");
|
DPRINT("NtAccessCheck() called\n");
|
||||||
|
@ -568,89 +621,38 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
return STATUS_ACCESS_VIOLATION;
|
return STATUS_ACCESS_VIOLATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the DACL */
|
RtlZeroMemory(&SubjectSecurityContext,
|
||||||
Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
|
sizeof(SECURITY_SUBJECT_CONTEXT));
|
||||||
&Present,
|
SubjectSecurityContext.ClientToken = Token;
|
||||||
&Dacl,
|
SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel;
|
||||||
&Defaulted);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("RtlGetDaclSecurityDescriptor() failed (Status %lx)\n", Status);
|
|
||||||
ObDereferenceObject(Token);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RULE 1: Grant desired access if the object is unprotected */
|
/* FIXME: Lock subject context */
|
||||||
if (Dacl == NULL)
|
|
||||||
|
if (!SeAccessCheck(SecurityDescriptor,
|
||||||
|
&SubjectSecurityContext,
|
||||||
|
TRUE,
|
||||||
|
DesiredAccess,
|
||||||
|
0,
|
||||||
|
&PrivilegeSet,
|
||||||
|
GenericMapping,
|
||||||
|
PreviousMode,
|
||||||
|
GrantedAccess,
|
||||||
|
AccessStatus))
|
||||||
{
|
{
|
||||||
*GrantedAccess = DesiredAccess;
|
Status = *AccessStatus;
|
||||||
*AccessStatus = STATUS_SUCCESS;
|
}
|
||||||
return STATUS_SUCCESS;
|
else
|
||||||
|
{
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentAccess = 0;
|
/* FIXME: Unlock subject context */
|
||||||
|
|
||||||
/* FIXME: RULE 2: Check token for 'take ownership' privilege */
|
|
||||||
|
|
||||||
/* RULE 3: Check whether the token is the owner */
|
|
||||||
Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
|
|
||||||
&Sid,
|
|
||||||
&Defaulted);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status);
|
|
||||||
ObDereferenceObject(Token);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SepSidInToken(Token, Sid))
|
|
||||||
{
|
|
||||||
CurrentAccess |= (READ_CONTROL | WRITE_DAC);
|
|
||||||
if (DesiredAccess == CurrentAccess)
|
|
||||||
{
|
|
||||||
*AccessStatus = STATUS_SUCCESS;
|
|
||||||
*GrantedAccess = CurrentAccess;
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RULE 4: Grant rights according to the DACL */
|
|
||||||
CurrentAce = (PACE)(Dacl + 1);
|
|
||||||
for (i = 0; i < Dacl->AceCount; i++)
|
|
||||||
{
|
|
||||||
Sid = (PSID)(CurrentAce + 1);
|
|
||||||
if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
|
|
||||||
{
|
|
||||||
if (SepSidInToken(Token, Sid))
|
|
||||||
{
|
|
||||||
*AccessStatus = STATUS_ACCESS_DENIED;
|
|
||||||
*GrantedAccess = 0;
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
|
|
||||||
{
|
|
||||||
if (SepSidInToken(Token, Sid))
|
|
||||||
{
|
|
||||||
CurrentAccess |= CurrentAce->AccessMask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
|
|
||||||
CurrentAccess, DesiredAccess);
|
|
||||||
|
|
||||||
ObDereferenceObject(Token);
|
ObDereferenceObject(Token);
|
||||||
|
|
||||||
*GrantedAccess = CurrentAccess & DesiredAccess;
|
|
||||||
|
|
||||||
*AccessStatus =
|
|
||||||
(*GrantedAccess == DesiredAccess) ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
|
||||||
|
|
||||||
DPRINT("NtAccessCheck() done\n");
|
DPRINT("NtAccessCheck() done\n");
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue