Skip to content

Commit

Permalink
[DS-Heuristics] Fix ACLs order (solve issue FuseCP#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanSchulz committed Jun 9, 2022
1 parent 7ab03e8 commit f784acb
Showing 1 changed file with 66 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,72 @@ public static void DisableInheritance(string objectPath)
var obj = new DirectoryEntry(objectPath);
obj.ObjectSecurity.SetAccessRuleProtection(true, true);
obj.CommitChanges();
CanonicalizeDacl(objectPath);
}

private static void CanonicalizeDacl(string objectPath)
{
var obj = new DirectoryEntry(objectPath);
ActiveDirectorySecurity objectSecurity = obj.ObjectSecurity;
if (objectSecurity == null) { throw new ArgumentNullException("objectSecurity"); }
if (objectSecurity.AreAccessRulesCanonical) { return; }

// A canonical ACL must have ACES sorted according to the following order:
// 1. Access-denied on the object
// 2. Access-denied on a child or property
// 3. Access-allowed on the object
// 4. Access-allowed on a child or property
// 5. All inherited ACEs
RawSecurityDescriptor descriptor = new RawSecurityDescriptor(objectSecurity.GetSecurityDescriptorSddlForm(AccessControlSections.Access));

List<QualifiedAce> implicitDenyDacl = new List<QualifiedAce>();
List<QualifiedAce> implicitDenyObjectDacl = new List<QualifiedAce>();
List<QualifiedAce> inheritedDacl = new List<QualifiedAce>();
List<QualifiedAce> implicitAllowDacl = new List<QualifiedAce>();
List<QualifiedAce> implicitAllowObjectDacl = new List<QualifiedAce>();

foreach (QualifiedAce ace in descriptor.DiscretionaryAcl)
{
if ((ace.AceFlags & AceFlags.Inherited) == AceFlags.Inherited) { inheritedDacl.Add(ace); }
else
{
switch (ace.AceType)
{
case AceType.AccessAllowed:
implicitAllowDacl.Add(ace);
break;

case AceType.AccessDenied:
implicitDenyDacl.Add(ace);
break;

case AceType.AccessAllowedObject:
implicitAllowObjectDacl.Add(ace);
break;

case AceType.AccessDeniedObject:
implicitDenyObjectDacl.Add(ace);
break;
}
}
}

Int32 aceIndex = 0;
RawAcl newDacl = new RawAcl(descriptor.DiscretionaryAcl.Revision, descriptor.DiscretionaryAcl.Count);
implicitDenyDacl.ForEach(x => newDacl.InsertAce(aceIndex++, x));
implicitDenyObjectDacl.ForEach(x => newDacl.InsertAce(aceIndex++, x));
implicitAllowDacl.ForEach(x => newDacl.InsertAce(aceIndex++, x));
implicitAllowObjectDacl.ForEach(x => newDacl.InsertAce(aceIndex++, x));
inheritedDacl.ForEach(x => newDacl.InsertAce(aceIndex++, x));

if (aceIndex != descriptor.DiscretionaryAcl.Count)
{
throw new ArgumentException("The DACL cannot be canonicalized since it would potentially result in a loss of information");
}

descriptor.DiscretionaryAcl = newDacl;
objectSecurity.SetSecurityDescriptorSddlForm(descriptor.GetSddlForm(AccessControlSections.Access), AccessControlSections.Access);
obj.CommitChanges();
}

public static bool IsIdentityAllowed(string objectPath, IdentityReference identity)
Expand Down

0 comments on commit f784acb

Please sign in to comment.