mirror of
https://github.com/reactos/reactos.git
synced 2024-06-29 01:12:06 +00:00
[NTOS:SE]
- Implement ACL inheritance for SeAssignSecurityEx CORE-8745 #resolve svn path=/trunk/; revision=65259
This commit is contained in:
parent
418629f6a9
commit
ca809b6cdc
|
@ -488,6 +488,32 @@ SepReleaseAcl(
|
||||||
IN BOOLEAN CaptureIfKernel
|
IN BOOLEAN CaptureIfKernel
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
SepPropagateAcl(
|
||||||
|
_Out_writes_bytes_opt_(DaclLength) PACL AclDest,
|
||||||
|
_Inout_ PULONG AclLength,
|
||||||
|
_In_reads_bytes_(AclSource->AclSize) PACL AclSource,
|
||||||
|
_In_ PSID Owner,
|
||||||
|
_In_ PSID Group,
|
||||||
|
_In_ BOOLEAN IsInherited,
|
||||||
|
_In_ BOOLEAN IsDirectoryObject,
|
||||||
|
_In_ PGENERIC_MAPPING GenericMapping);
|
||||||
|
|
||||||
|
PACL
|
||||||
|
SepSelectAcl(
|
||||||
|
_In_opt_ PACL ExplicitAcl,
|
||||||
|
_In_ BOOLEAN ExplicitPresent,
|
||||||
|
_In_ BOOLEAN ExplicitDefaulted,
|
||||||
|
_In_opt_ PACL ParentAcl,
|
||||||
|
_In_opt_ PACL DefaultAcl,
|
||||||
|
_Out_ PULONG AclLength,
|
||||||
|
_In_ PSID Owner,
|
||||||
|
_In_ PSID Group,
|
||||||
|
_Out_ PBOOLEAN AclPresent,
|
||||||
|
_Out_ PBOOLEAN IsInherited,
|
||||||
|
_In_ BOOLEAN IsDirectoryObject,
|
||||||
|
_In_ PGENERIC_MAPPING GenericMapping);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
SeDefaultObjectMethod(
|
SeDefaultObjectMethod(
|
||||||
|
|
|
@ -367,4 +367,280 @@ SepReleaseAcl(IN PACL CapturedAcl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
SepShouldPropagateAce(
|
||||||
|
_In_ UCHAR AceFlags,
|
||||||
|
_Out_ PUCHAR NewAceFlags,
|
||||||
|
_In_ BOOLEAN IsInherited,
|
||||||
|
_In_ BOOLEAN IsDirectoryObject)
|
||||||
|
{
|
||||||
|
if (!IsInherited)
|
||||||
|
{
|
||||||
|
*NewAceFlags = AceFlags;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsDirectoryObject)
|
||||||
|
{
|
||||||
|
if (AceFlags & OBJECT_INHERIT_ACE)
|
||||||
|
{
|
||||||
|
*NewAceFlags = AceFlags & ~VALID_INHERIT_FLAGS;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AceFlags & NO_PROPAGATE_INHERIT_ACE)
|
||||||
|
{
|
||||||
|
if (AceFlags & CONTAINER_INHERIT_ACE)
|
||||||
|
{
|
||||||
|
*NewAceFlags = AceFlags & ~VALID_INHERIT_FLAGS;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AceFlags & CONTAINER_INHERIT_ACE)
|
||||||
|
{
|
||||||
|
*NewAceFlags = CONTAINER_INHERIT_ACE | (AceFlags & OBJECT_INHERIT_ACE) | (AceFlags & ~VALID_INHERIT_FLAGS);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AceFlags & OBJECT_INHERIT_ACE)
|
||||||
|
{
|
||||||
|
*NewAceFlags = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE | (AceFlags & ~VALID_INHERIT_FLAGS);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
SepPropagateAcl(
|
||||||
|
_Out_writes_bytes_opt_(DaclLength) PACL AclDest,
|
||||||
|
_Inout_ PULONG AclLength,
|
||||||
|
_In_reads_bytes_(AclSource->AclSize) PACL AclSource,
|
||||||
|
_In_ PSID Owner,
|
||||||
|
_In_ PSID Group,
|
||||||
|
_In_ BOOLEAN IsInherited,
|
||||||
|
_In_ BOOLEAN IsDirectoryObject,
|
||||||
|
_In_ PGENERIC_MAPPING GenericMapping)
|
||||||
|
{
|
||||||
|
ACCESS_MASK Mask;
|
||||||
|
PACCESS_ALLOWED_ACE AceSource;
|
||||||
|
PACCESS_ALLOWED_ACE AceDest;
|
||||||
|
PUCHAR CurrentDest;
|
||||||
|
PUCHAR CurrentSource;
|
||||||
|
ULONG i;
|
||||||
|
ULONG Written;
|
||||||
|
UCHAR AceFlags;
|
||||||
|
USHORT AceSize;
|
||||||
|
USHORT AceCount = 0;
|
||||||
|
PSID Sid;
|
||||||
|
BOOLEAN WriteTwoAces;
|
||||||
|
|
||||||
|
if (AclSource->AclRevision != ACL_REVISION)
|
||||||
|
{
|
||||||
|
NT_ASSERT(AclSource->AclRevision == ACL_REVISION);
|
||||||
|
return STATUS_UNKNOWN_REVISION;
|
||||||
|
}
|
||||||
|
|
||||||
|
NT_ASSERT(AclSource->AclSize % sizeof(ULONG) == 0);
|
||||||
|
NT_ASSERT(AclSource->Sbz1 == 0);
|
||||||
|
NT_ASSERT(AclSource->Sbz2 == 0);
|
||||||
|
|
||||||
|
Written = 0;
|
||||||
|
if (*AclLength >= Written + sizeof(ACL))
|
||||||
|
{
|
||||||
|
RtlCopyMemory(AclDest,
|
||||||
|
AclSource,
|
||||||
|
sizeof(ACL));
|
||||||
|
}
|
||||||
|
Written += sizeof(ACL);
|
||||||
|
|
||||||
|
CurrentDest = (PUCHAR)(AclDest + 1);
|
||||||
|
CurrentSource = (PUCHAR)(AclSource + 1);
|
||||||
|
for (i = 0; i < AclSource->AceCount; i++)
|
||||||
|
{
|
||||||
|
NT_ASSERT((ULONG_PTR)CurrentDest % sizeof(ULONG) == 0);
|
||||||
|
NT_ASSERT((ULONG_PTR)CurrentSource % sizeof(ULONG) == 0);
|
||||||
|
AceDest = (PACCESS_ALLOWED_ACE)CurrentDest;
|
||||||
|
AceSource = (PACCESS_ALLOWED_ACE)CurrentSource;
|
||||||
|
|
||||||
|
/* These all have the same structure */
|
||||||
|
NT_ASSERT(AceSource->Header.AceType == ACCESS_ALLOWED_ACE_TYPE ||
|
||||||
|
AceSource->Header.AceType == ACCESS_DENIED_ACE_TYPE ||
|
||||||
|
AceSource->Header.AceType == SYSTEM_AUDIT_ACE_TYPE);
|
||||||
|
|
||||||
|
NT_ASSERT(AceSource->Header.AceSize % sizeof(ULONG) == 0);
|
||||||
|
NT_ASSERT(AceSource->Header.AceSize >= sizeof(*AceSource));
|
||||||
|
if (!SepShouldPropagateAce(AceSource->Header.AceFlags,
|
||||||
|
&AceFlags,
|
||||||
|
IsInherited,
|
||||||
|
IsDirectoryObject))
|
||||||
|
{
|
||||||
|
CurrentSource += AceSource->Header.AceSize;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: filter out duplicate ACEs */
|
||||||
|
AceSize = AceSource->Header.AceSize;
|
||||||
|
Mask = AceSource->Mask;
|
||||||
|
Sid = (PSID)&AceSource->SidStart;
|
||||||
|
NT_ASSERT(AceSize >= FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid(Sid));
|
||||||
|
|
||||||
|
WriteTwoAces = FALSE;
|
||||||
|
/* Map effective ACE to specific rights */
|
||||||
|
if (!(AceFlags & INHERIT_ONLY_ACE))
|
||||||
|
{
|
||||||
|
RtlMapGenericMask(&Mask, GenericMapping);
|
||||||
|
Mask &= GenericMapping->GenericAll;
|
||||||
|
|
||||||
|
if (IsInherited)
|
||||||
|
{
|
||||||
|
if (RtlEqualSid(Sid, SeCreatorOwnerSid))
|
||||||
|
Sid = Owner;
|
||||||
|
else if (RtlEqualSid(Sid, SeCreatorGroupSid))
|
||||||
|
Sid = Group;
|
||||||
|
AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid(Sid);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A generic container ACE becomes two ACEs:
|
||||||
|
* - a specific effective ACE with no inheritance flags
|
||||||
|
* - an inherit-only ACE that keeps the generic rights
|
||||||
|
*/
|
||||||
|
if (IsDirectoryObject &&
|
||||||
|
(AceFlags & CONTAINER_INHERIT_ACE) &&
|
||||||
|
(Mask != AceSource->Mask || Sid != (PSID)&AceSource->SidStart))
|
||||||
|
{
|
||||||
|
WriteTwoAces = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (*AclLength >= Written + AceSize)
|
||||||
|
{
|
||||||
|
AceDest->Header.AceType = AceSource->Header.AceType;
|
||||||
|
AceDest->Header.AceFlags = WriteTwoAces ? AceFlags & ~VALID_INHERIT_FLAGS
|
||||||
|
: AceFlags;
|
||||||
|
AceDest->Header.AceSize = AceSize;
|
||||||
|
AceDest->Mask = Mask;
|
||||||
|
RtlCopySid(AceSize - FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart),
|
||||||
|
(PSID)&AceDest->SidStart,
|
||||||
|
Sid);
|
||||||
|
}
|
||||||
|
Written += AceSize;
|
||||||
|
|
||||||
|
AceCount++;
|
||||||
|
CurrentDest += AceSize;
|
||||||
|
|
||||||
|
if (!WriteTwoAces)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Second ACE keeps all the generics from the source ACE */
|
||||||
|
WriteTwoAces = FALSE;
|
||||||
|
AceDest = (PACCESS_ALLOWED_ACE)CurrentDest;
|
||||||
|
AceSize = AceSource->Header.AceSize;
|
||||||
|
Mask = AceSource->Mask;
|
||||||
|
Sid = (PSID)&AceSource->SidStart;
|
||||||
|
AceFlags |= INHERIT_ONLY_ACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentSource += AceSource->Header.AceSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*AclLength >= sizeof(ACL))
|
||||||
|
{
|
||||||
|
AclDest->AceCount = AceCount;
|
||||||
|
AclDest->AclSize = Written;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Written > *AclLength)
|
||||||
|
{
|
||||||
|
*AclLength = Written;
|
||||||
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
*AclLength = Written;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
PACL
|
||||||
|
SepSelectAcl(
|
||||||
|
_In_opt_ PACL ExplicitAcl,
|
||||||
|
_In_ BOOLEAN ExplicitPresent,
|
||||||
|
_In_ BOOLEAN ExplicitDefaulted,
|
||||||
|
_In_opt_ PACL ParentAcl,
|
||||||
|
_In_opt_ PACL DefaultAcl,
|
||||||
|
_Out_ PULONG AclLength,
|
||||||
|
_In_ PSID Owner,
|
||||||
|
_In_ PSID Group,
|
||||||
|
_Out_ PBOOLEAN AclPresent,
|
||||||
|
_Out_ PBOOLEAN IsInherited,
|
||||||
|
_In_ BOOLEAN IsDirectoryObject,
|
||||||
|
_In_ PGENERIC_MAPPING GenericMapping)
|
||||||
|
{
|
||||||
|
PACL Acl;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
*AclPresent = TRUE;
|
||||||
|
if (ExplicitPresent && !ExplicitDefaulted)
|
||||||
|
{
|
||||||
|
Acl = ExplicitAcl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ParentAcl)
|
||||||
|
{
|
||||||
|
*IsInherited = TRUE;
|
||||||
|
*AclLength = 0;
|
||||||
|
Status = SepPropagateAcl(NULL,
|
||||||
|
AclLength,
|
||||||
|
ParentAcl,
|
||||||
|
Owner,
|
||||||
|
Group,
|
||||||
|
*IsInherited,
|
||||||
|
IsDirectoryObject,
|
||||||
|
GenericMapping);
|
||||||
|
NT_ASSERT(Status == STATUS_BUFFER_TOO_SMALL);
|
||||||
|
|
||||||
|
/* Use the parent ACL only if it's not empty */
|
||||||
|
if (*AclLength != sizeof(ACL))
|
||||||
|
return ParentAcl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ExplicitPresent)
|
||||||
|
{
|
||||||
|
Acl = ExplicitAcl;
|
||||||
|
}
|
||||||
|
else if (DefaultAcl)
|
||||||
|
{
|
||||||
|
Acl = DefaultAcl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*AclPresent = FALSE;
|
||||||
|
Acl = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*IsInherited = FALSE;
|
||||||
|
*AclLength = 0;
|
||||||
|
if (Acl)
|
||||||
|
{
|
||||||
|
/* Get the length */
|
||||||
|
Status = SepPropagateAcl(NULL,
|
||||||
|
AclLength,
|
||||||
|
Acl,
|
||||||
|
Owner,
|
||||||
|
Group,
|
||||||
|
*IsInherited,
|
||||||
|
IsDirectoryObject,
|
||||||
|
GenericMapping);
|
||||||
|
NT_ASSERT(Status == STATUS_BUFFER_TOO_SMALL);
|
||||||
|
}
|
||||||
|
return Acl;
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -1109,7 +1109,6 @@ SeDeassignSecurity(
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -1140,12 +1139,20 @@ SeAssignSecurityEx(
|
||||||
ULONG Current;
|
ULONG Current;
|
||||||
PSID Owner = NULL;
|
PSID Owner = NULL;
|
||||||
PSID Group = NULL;
|
PSID Group = NULL;
|
||||||
|
PACL ExplicitAcl;
|
||||||
|
BOOLEAN ExplicitPresent;
|
||||||
|
BOOLEAN ExplicitDefaulted;
|
||||||
|
PACL ParentAcl;
|
||||||
PACL Dacl = NULL;
|
PACL Dacl = NULL;
|
||||||
PACL Sacl = NULL;
|
PACL Sacl = NULL;
|
||||||
|
BOOLEAN DaclIsInherited;
|
||||||
|
BOOLEAN SaclIsInherited;
|
||||||
|
BOOLEAN DaclPresent;
|
||||||
|
BOOLEAN SaclPresent;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
DBG_UNREFERENCED_PARAMETER(ObjectType);
|
DBG_UNREFERENCED_PARAMETER(ObjectType);
|
||||||
DBG_UNREFERENCED_PARAMETER(AutoInheritFlags);
|
DBG_UNREFERENCED_PARAMETER(AutoInheritFlags);
|
||||||
DBG_UNREFERENCED_PARAMETER(GenericMapping);
|
|
||||||
UNREFERENCED_PARAMETER(PoolType);
|
UNREFERENCED_PARAMETER(PoolType);
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
@ -1180,7 +1187,6 @@ SeAssignSecurityEx(
|
||||||
DPRINT("Use token owner sid!\n");
|
DPRINT("Use token owner sid!\n");
|
||||||
Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
|
Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
|
||||||
}
|
}
|
||||||
|
|
||||||
OwnerLength = RtlLengthSid(Owner);
|
OwnerLength = RtlLengthSid(Owner);
|
||||||
NT_ASSERT(OwnerLength % sizeof(ULONG) == 0);
|
NT_ASSERT(OwnerLength % sizeof(ULONG) == 0);
|
||||||
|
|
||||||
|
@ -1199,56 +1205,77 @@ SeAssignSecurityEx(
|
||||||
SeUnlockSubjectContext(SubjectContext);
|
SeUnlockSubjectContext(SubjectContext);
|
||||||
return STATUS_INVALID_PRIMARY_GROUP;
|
return STATUS_INVALID_PRIMARY_GROUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupLength = RtlLengthSid(Group);
|
GroupLength = RtlLengthSid(Group);
|
||||||
NT_ASSERT(GroupLength % sizeof(ULONG) == 0);
|
NT_ASSERT(GroupLength % sizeof(ULONG) == 0);
|
||||||
|
|
||||||
/* Inherit the DACL */
|
/* Inherit the DACL */
|
||||||
|
DaclLength = 0;
|
||||||
|
ExplicitAcl = NULL;
|
||||||
|
ExplicitPresent = FALSE;
|
||||||
|
ExplicitDefaulted = FALSE;
|
||||||
if (ExplicitDescriptor != NULL &&
|
if (ExplicitDescriptor != NULL &&
|
||||||
(ExplicitDescriptor->Control & SE_DACL_PRESENT) &&
|
(ExplicitDescriptor->Control & SE_DACL_PRESENT))
|
||||||
!(ExplicitDescriptor->Control & SE_DACL_DEFAULTED))
|
|
||||||
{
|
{
|
||||||
DPRINT("Use explicit DACL!\n");
|
ExplicitAcl = SepGetDaclFromDescriptor(ExplicitDescriptor);
|
||||||
Dacl = SepGetDaclFromDescriptor(ExplicitDescriptor);
|
ExplicitPresent = TRUE;
|
||||||
Control |= SE_DACL_PRESENT;
|
if (ExplicitDescriptor->Control & SE_DACL_DEFAULTED)
|
||||||
|
ExplicitDefaulted = TRUE;
|
||||||
}
|
}
|
||||||
else if (ParentDescriptor != NULL &&
|
ParentAcl = NULL;
|
||||||
(ParentDescriptor->Control & SE_DACL_PRESENT))
|
if (ParentDescriptor != NULL &&
|
||||||
|
(ParentDescriptor->Control & SE_DACL_PRESENT))
|
||||||
{
|
{
|
||||||
DPRINT("Use parent DACL!\n");
|
ParentAcl = SepGetDaclFromDescriptor(ParentDescriptor);
|
||||||
/* FIXME: Inherit */
|
|
||||||
Dacl = SepGetDaclFromDescriptor(ParentDescriptor);
|
|
||||||
Control |= SE_DACL_PRESENT;
|
|
||||||
}
|
}
|
||||||
else if (Token->DefaultDacl)
|
Dacl = SepSelectAcl(ExplicitAcl,
|
||||||
{
|
ExplicitPresent,
|
||||||
DPRINT("Use token default DACL!\n");
|
ExplicitDefaulted,
|
||||||
Dacl = Token->DefaultDacl;
|
ParentAcl,
|
||||||
|
Token->DefaultDacl,
|
||||||
|
&DaclLength,
|
||||||
|
Owner,
|
||||||
|
Group,
|
||||||
|
&DaclPresent,
|
||||||
|
&DaclIsInherited,
|
||||||
|
IsDirectoryObject,
|
||||||
|
GenericMapping);
|
||||||
|
if (DaclPresent)
|
||||||
Control |= SE_DACL_PRESENT;
|
Control |= SE_DACL_PRESENT;
|
||||||
}
|
|
||||||
|
|
||||||
DaclLength = (Dacl != NULL) ? Dacl->AclSize : 0;
|
|
||||||
NT_ASSERT(DaclLength % sizeof(ULONG) == 0);
|
NT_ASSERT(DaclLength % sizeof(ULONG) == 0);
|
||||||
|
|
||||||
/* Inherit the SACL */
|
/* Inherit the SACL */
|
||||||
|
SaclLength = 0;
|
||||||
|
ExplicitAcl = NULL;
|
||||||
|
ExplicitPresent = FALSE;
|
||||||
|
ExplicitDefaulted = FALSE;
|
||||||
if (ExplicitDescriptor != NULL &&
|
if (ExplicitDescriptor != NULL &&
|
||||||
(ExplicitDescriptor->Control & SE_SACL_PRESENT) &&
|
(ExplicitDescriptor->Control & SE_SACL_PRESENT))
|
||||||
!(ExplicitDescriptor->Control & SE_SACL_DEFAULTED))
|
|
||||||
{
|
{
|
||||||
DPRINT("Use explicit SACL!\n");
|
ExplicitAcl = SepGetSaclFromDescriptor(ExplicitDescriptor);
|
||||||
Sacl = SepGetSaclFromDescriptor(ExplicitDescriptor);
|
ExplicitPresent = TRUE;
|
||||||
Control |= SE_SACL_PRESENT;
|
if (ExplicitDescriptor->Control & SE_SACL_DEFAULTED)
|
||||||
|
ExplicitDefaulted = TRUE;
|
||||||
}
|
}
|
||||||
else if (ParentDescriptor != NULL &&
|
ParentAcl = NULL;
|
||||||
(ParentDescriptor->Control & SE_SACL_PRESENT))
|
if (ParentDescriptor != NULL &&
|
||||||
|
(ParentDescriptor->Control & SE_SACL_PRESENT))
|
||||||
{
|
{
|
||||||
DPRINT("Use parent SACL!\n");
|
ParentAcl = SepGetSaclFromDescriptor(ParentDescriptor);
|
||||||
/* FIXME: Inherit */
|
|
||||||
Sacl = SepGetSaclFromDescriptor(ParentDescriptor);
|
|
||||||
Control |= SE_SACL_PRESENT;
|
|
||||||
}
|
}
|
||||||
|
Sacl = SepSelectAcl(ExplicitAcl,
|
||||||
SaclLength = (Sacl != NULL) ? Sacl->AclSize : 0;
|
ExplicitPresent,
|
||||||
|
ExplicitDefaulted,
|
||||||
|
ParentAcl,
|
||||||
|
NULL,
|
||||||
|
&SaclLength,
|
||||||
|
Owner,
|
||||||
|
Group,
|
||||||
|
&SaclPresent,
|
||||||
|
&SaclIsInherited,
|
||||||
|
IsDirectoryObject,
|
||||||
|
GenericMapping);
|
||||||
|
if (SaclPresent)
|
||||||
|
Control |= SE_SACL_PRESENT;
|
||||||
NT_ASSERT(SaclLength % sizeof(ULONG) == 0);
|
NT_ASSERT(SaclLength % sizeof(ULONG) == 0);
|
||||||
|
|
||||||
/* Allocate and initialize the new security descriptor */
|
/* Allocate and initialize the new security descriptor */
|
||||||
|
@ -1279,14 +1306,30 @@ SeAssignSecurityEx(
|
||||||
|
|
||||||
if (SaclLength != 0)
|
if (SaclLength != 0)
|
||||||
{
|
{
|
||||||
RtlCopyMemory((PUCHAR)Descriptor + Current, Sacl, SaclLength);
|
Status = SepPropagateAcl((PACL)((PUCHAR)Descriptor + Current),
|
||||||
|
&SaclLength,
|
||||||
|
Sacl,
|
||||||
|
Owner,
|
||||||
|
Group,
|
||||||
|
SaclIsInherited,
|
||||||
|
IsDirectoryObject,
|
||||||
|
GenericMapping);
|
||||||
|
NT_ASSERT(Status == STATUS_SUCCESS);
|
||||||
Descriptor->Sacl = Current;
|
Descriptor->Sacl = Current;
|
||||||
Current += SaclLength;
|
Current += SaclLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DaclLength != 0)
|
if (DaclLength != 0)
|
||||||
{
|
{
|
||||||
RtlCopyMemory((PUCHAR)Descriptor + Current, Dacl, DaclLength);
|
Status = SepPropagateAcl((PACL)((PUCHAR)Descriptor + Current),
|
||||||
|
&DaclLength,
|
||||||
|
Dacl,
|
||||||
|
Owner,
|
||||||
|
Group,
|
||||||
|
DaclIsInherited,
|
||||||
|
IsDirectoryObject,
|
||||||
|
GenericMapping);
|
||||||
|
NT_ASSERT(Status == STATUS_SUCCESS);
|
||||||
Descriptor->Dacl = Current;
|
Descriptor->Dacl = Current;
|
||||||
Current += DaclLength;
|
Current += DaclLength;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue