2

I want an application to create a folder and restrict users other than current and admins from accessing it. As a result of the code below though current user loses access as well and cannot delete the folder.

string rootPath = Environment.GetEnvironmentVariable("TEMP");
var rootDirectory = new DirectoryInfo(rootPath);
DirectoryInfo subFolder = rootDirectory.CreateSubdirectory("SubFolder");
var directorySecurity = subFolder.GetAccessControl();

var adminitrators = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
directorySecurity.AddAccessRule(
    new FileSystemAccessRule(
        adminitrators,
        FileSystemRights.FullControl,
        InheritanceFlags.None,
        PropagationFlags.NoPropagateInherit,
        AccessControlType.Allow));

directorySecurity.AddAccessRule(
    new FileSystemAccessRule(
        WindowsIdentity.GetCurrent().Name,
        FileSystemRights.FullControl,
        InheritanceFlags.None,
        PropagationFlags.NoPropagateInherit, 
        AccessControlType.Allow));

var everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
directorySecurity.AddAccessRule(
    new FileSystemAccessRule(
        everyone,
        FileSystemRights.FullControl,
        InheritanceFlags.None,
        PropagationFlags.NoPropagateInherit,
        AccessControlType.Deny));

subFolder.SetAccessControl(directorySecurity);

subFolder.Delete(true); // <-- System.UnauthorizedAccessException
Anastasia Black
  • 1,890
  • 9
  • 21
  • 1
    Just remove all permissions except: allow for the current user and admins. Everyone else would not get permission by default. You don't need an explicit `deny` rule. – zerkms Sep 13 '16 at 23:10
  • It sounds like your two sentences in your opening paragraph explain what you want to happen. You might want to clarify that the first is what you want and the second is what is happening and that you don't want that. – Enigmativity Sep 13 '16 at 23:13
  • @zerkms Thank you. I thought that I need to explicitly deny. If you post it as an answer I will accept it. – Anastasia Black Sep 13 '16 at 23:18
  • @Enigmativity I updated the question though zerkms got the question right without the update – Anastasia Black Sep 13 '16 at 23:21
  • @zerkms No, sorry. That does not seem to work in all scenarios as I thought. If on the root level I set Everyone - FullAccess. Than run this code. And than try to access it using different account I can do it. It inherits the permissions from the parent folder... – Anastasia Black Sep 13 '16 at 23:35
  • @AnastasiaBaranchenkova - Updating your question to make it clear is about making sure this question and answer serve a purpose for future readers. It is important to do it even if someone answers correctly. – Enigmativity Sep 14 '16 at 06:55

2 Answers2

2

Ok, so the full solution would be the following:

  1. As @zerkms proposed we need to remove "Deny for all". That solves System.UnauthorizedAccessException thrown when current user tries to delete the folder.
  2. As explained here use SetAccessRuleProtection to make sure permissions are not inherited from the parent folder.

        string rootPath = Environment.GetEnvironmentVariable("TEMP");
        var rootDirectory = new DirectoryInfo(rootPath);
    
        DirectoryInfo subFolder = rootDirectory.CreateSubdirectory("SubFolder");
        var directorySecurity = subFolder.GetAccessControl();
    
        var adminitrators = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
        directorySecurity.AddAccessRule(
            new FileSystemAccessRule(
                    adminitrators,
                    FileSystemRights.FullControl,
                    InheritanceFlags.None,
                    PropagationFlags.NoPropagateInherit,
                    AccessControlType.Allow));
    
        directorySecurity.AddAccessRule(
            new FileSystemAccessRule(
                    WindowsIdentity.GetCurrent().Name,
                    FileSystemRights.FullControl,
                    InheritanceFlags.None,
                    PropagationFlags.NoPropagateInherit, 
                    AccessControlType.Allow));
    
        directorySecurity.SetAccessRuleProtection(isProtected: true, preserveInheritance: false);
    
        subFolder.SetAccessControl(directorySecurity);
    
Community
  • 1
  • 1
Anastasia Black
  • 1,890
  • 9
  • 21
1

The explicit deny rule is redundant in this case.

What is not allowed is denied by default, so just remove the last deny for all rule and you're fine.

zerkms
  • 249,484
  • 69
  • 436
  • 539
  • Thank you! I thought it is more complicated since in web.config both deny and allow are usually used. – Anastasia Black Sep 13 '16 at 23:26
  • No, sorry. That does not seem to work in all scenarios as I thought. If on the root level I set Everyone - FullAccess. Than run this code. And than try to access it using different account I can do it. It inherits the permissions from the parent folder... – Anastasia Black Sep 13 '16 at 23:35
  • Ok, so if parent folder has Everyone - FullAccess this does not work. If parent folder has Everyone - Read/List than it works. This is good enough for me, though others should be cautions. – Anastasia Black Sep 13 '16 at 23:52
  • @AnastasiaBaranchenkova yep, the answer implies that the permissions are not inherited. – zerkms Sep 14 '16 at 00:17
  • @AnastasiaBaranchenkova not straight away, and if someone provides an answer for that I'd upvote them :-) – zerkms Sep 14 '16 at 20:33