I have the following code:
DirectoryInfo directory = new DirectoryInfo(@"C:\Program Files\Company\Product");
if (!directory.Exists) { directory.Create(); }
DirectorySecurity directorySecurity = directory.GetAccessControl();
SecurityIdentifier securityIdentifier = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
directorySecurity.AddAccessRule(
new FileSystemAccessRule(
securityIdentifier,
FileSystemRights.Write,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None,
AccessControlType.Allow));
directory.SetAccessControl(directorySecurity);
The call to AddAccessRule throws an InvalidOperationException with the following stack trace:
System.InvalidOperationException: This access control list is not in canonical form and therefore cannot be modified.
at System.Security.AccessControl.CommonAcl.ThrowIfNotCanonical()
at System.Security.AccessControl.CommonAcl.AddQualifiedAce(SecurityIdentifier sid, AceQualifier qualifier, Int32 accessMask, AceFlags flags, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType)
at System.Security.AccessControl.DiscretionaryAcl.AddAccess(AccessControlType accessType, SecurityIdentifier sid, Int32 accessMask, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags)
at System.Security.AccessControl.CommonObjectSecurity.ModifyAccess(AccessControlModification modification, AccessRule rule, Boolean& modified)
at System.Security.AccessControl.CommonObjectSecurity.AddAccessRule(AccessRule rule)
at System.Security.AccessControl.FileSystemSecurity.AddAccessRule(FileSystemAccessRule rule)
This only happens on some systems (I've seen Windows XP and Windows 7). In the situations where the error occurs, viewing the security permissions for the directory using Windows Explorer usually causes a message box to be shown with the following text:
The permissions on are incorrectly ordered, which may cause some entries to be ineffective. Press OK to continue and sort the permissions correctly, or Cancel to reset the permissions.
Clicking OK at this point fixes the problem. What's going on here? How does a system get into this state, and is there any way to detect/fix it programmatically (i.e. without having the user manually use Explorer to fix this)?
Update
I did a bit more research about ACL, what canonical form is, and why it's necessary. I'm still not sure how a file would normally get into this state, but I found that the Icacls tool can be used to create a directory with a non-canonical ACL by saving the permission list, altering it to be out-of-order, and restoring it. Now I just need a way to fix it without requiring user interaction.