Anastasia Black
Anastasia Black

Reputation: 1900

C# - How to grant access only to current user and restrict access to others

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

Upvotes: 2

Views: 2510

Answers (2)

Anastasia Black
Anastasia Black

Reputation: 1900

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);
    

Upvotes: 2

zerkms
zerkms

Reputation: 255015

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.

Upvotes: 1

Related Questions