peteraritchie / LongPath

drop-in library to support long paths in .NET
GNU Lesser General Public License v3.0
112 stars 43 forks source link

Directory.SetAccessControl does not set InheritanceFlags and PropagationFlags #49

Open afkos opened 7 years ago

afkos commented 7 years ago

Directory.SetAccessControl does not set InheritanceFlags and PropagationFlags Directory.CreateDirectory(string path, DirectorySecurity directorySecurity) has the same problem

test to reproduce:

var localAdmins = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
security.AddAccessRule(new FileSystemAccessRule(localAdmins,
    FileSystemRights.FullControl,
    InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
    PropagationFlags.NoPropagateInherit,
    AccessControlType.Allow));

Pri.LongPath.Directory.CreateDirectory(path);
Pri.LongPath.Directory.SetAccessControl(path, security);
ShowDirectorySecurity(path);
// FileSystemRights=FullControl, InheritanceFlags=[None], PropagationFlags=[None], AccessControlType=Allow

Directory.Delete(path);

System.IO.Directory.CreateDirectory(path);
System.IO.Directory.SetAccessControl(path, security);
ShowDirectorySecurity(path);
// FileSystemRights=FullControl, InheritanceFlags=[ContainerInherit, ObjectInherit], PropagationFlags=[NoPropagateInherit], AccessControlType=Allow

Directory.Delete(path);
peteraritchie commented 7 years ago

Do you have a reference for ShowDirectorySecurity? I'd like to be able to reproduce the data it's getting as a series of asserts.

afkos commented 7 years ago

Unfortunately I have no reference for ShowDirectorySecurity for now I wrote another test for this issue

private static FileSystemAccessRule GetFileSystemAccessRule(string path)
{
    return Directory.GetAccessControl(path).GetAccessRules(true, false, typeof(SecurityIdentifier)).OfType<FileSystemAccessRule>().Single();
}

[TestMethod]
public void TestDirectorySetAccessControl()
{
    var path = Path.Combine(Path.GetTempPath(), "TestDir");
    var security = new DirectorySecurity();

    var localAdmins = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
    security.AddAccessRule(new FileSystemAccessRule(localAdmins,
        FileSystemRights.FullControl,
        InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
        PropagationFlags.NoPropagateInherit,
        AccessControlType.Allow));

    // System.IO.Directory.SetAccessControl works fine
    Assert.IsFalse(Directory.Exists(path));
    System.IO.Directory.CreateDirectory(path);
    try
    {
        System.IO.Directory.SetAccessControl(path, security);
        Assert.AreEqual(GetFileSystemAccessRule(path).InheritanceFlags, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit);
        Assert.AreEqual(GetFileSystemAccessRule(path).PropagationFlags, PropagationFlags.NoPropagateInherit);
    }
    finally
    {
        Directory.Delete(path);
    }

    // Pri.LongPath.Directory.SetAccessControl fails
    Assert.IsFalse(Directory.Exists(path));
    Pri.LongPath.Directory.CreateDirectory(path);
    try
    {
        Pri.LongPath.Directory.SetAccessControl(path, security);
        Assert.AreEqual(GetFileSystemAccessRule(path).InheritanceFlags, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit);
        Assert.AreEqual(GetFileSystemAccessRule(path).PropagationFlags, PropagationFlags.NoPropagateInherit);
    }
    finally
    {
        Directory.Delete(path);
    }
}