VB.NET app is setting restricted file permissions on a directory, which is incorrectly restricting user created files in the same directory

gimbel0893 picture gimbel0893 · Jul 19, 2012 · Viewed 7.1k times · Source

My VB.NET application builds a tree of directories with restricted access.

The access should be that a normal user can not delete or rename the existing tree. But the user can add new files/folders anywhere in the tree. A user created file/folder should be fully modifiable by any user.

The problem I'm having is getting access set so that files/folders created by the app can't be changed, but files/folders created by users can be changed by any user.

What is currently happening, is the files/folders made by the application behave correctly. But when a user creates their own file/folder, that file's/folder's permissions only list the current user. So other users (or even system admins that exist of the application created files/folders) can't view or modify this user created file/folder.


Current Code: (when a user creates a file/folder themselves, this code doesn't give access to UserGroup or AdminGroup, only the user who just created the file/folder)

FolderAcl.AddAccessRule(New FileSystemAccessRule(UserGroup,
                        FileSystemRights.ReadAndExecute,
                        InheritanceFlags.None, PropagationFlags.None,
                        AccessControlType.Allow))
FolderAcl.AddAccessRule(New FileSystemAccessRule(UserGroup,
                        FileSystemRights.Write,
                        InheritanceFlags.None, PropagationFlags.None,
                        AccessControlType.Allow))

FolderAcl.AddAccessRule(New FileSystemAccessRule(AdminGroup,
                        FileSystemRights.FullControl,
                        InheritanceFlags.None, PropagationFlags.None,
                        AccessControlType.Allow))

FolderAcl.SetAccessRuleProtection(True, False)


Another Attempt: (when a user create a file/folder themselves, this code gives access to UserGroup and AdminGroup, but doesn't give access to the user. The user is in UserGroup, but UserGroup doesn't have delete or modify privileges so if the user creates a file/folder they can't even name it.)

' same code as above except...
InheritanceFlags.None ---> InheritanceFlags.Container or InheritanceFlags.Object


I've tried other combinations of the InheritanceFlags and PropagationFlags, but no luck yet.

Any ideas?
Thanks, Mike

Answer

nik picture nik · Jul 19, 2012

UPDATE:

You can break inheritance at any time and decide to leave a copy of the inherited access rules or remove it by using

SetAccessRuleProtection(True, True)

First boolean parameter, if true, breaks inheritance protection, second, if true, keeps a copy of access rules so that you can remove only those you don't want.

Following example should reflect your folder structure as commented:

 ' folder structure
        '
        '---Level1
        '     |
        '     ---Level2
        '          |
        '          ---Level3

        'set access rules at level1 with inheritance

        Dim Level1DirSec As DirectorySecurity = Directory.GetAccessControl("c:\level1")

        Level1DirSec.AddAccessRule(New FileSystemAccessRule(New System.Security.Principal.SecurityIdentifier(System.Security.Principal.WellKnownSidType.BuiltinAdministratorsSid, Nothing),
         FileSystemRights.FullControl,
         InheritanceFlags.ContainerInherit + InheritanceFlags.ObjectInherit,
         PropagationFlags.None,
         AccessControlType.Allow))

        Level1DirSec.AddAccessRule(New FileSystemAccessRule(New System.Security.Principal.SecurityIdentifier(System.Security.Principal.WellKnownSidType.AuthenticatedUserSid, Nothing),
          FileSystemRights.ReadAndExecute,
          InheritanceFlags.ContainerInherit + InheritanceFlags.ObjectInherit,
          PropagationFlags.None,
          AccessControlType.Allow))

        Directory.SetAccessControl("c:\level1\", Level1DirSec)


        ' break inheritance at level3 and remove access rule for authenticated user group

        Dim Level3DirSec As DirectorySecurity = Directory.GetAccessControl("c:\level1\level2\level3")

        Level3DirSec.SetAccessRuleProtection(True, True)

        Level3DirSec.RemoveAccessRuleAll(New FileSystemAccessRule(New System.Security.Principal.SecurityIdentifier(System.Security.Principal.WellKnownSidType.AuthenticatedUserSid, Nothing), FileSystemRights.ReadAndExecute, AccessControlType.Allow))

        Directory.SetAccessControl("c:\level1\level2\level3", Level3DirSec)

You can use WellKnownSid to specify groups and set it on you root folder with inheritance:

    FolderAcl.AddAccessRule(New FileSystemAccessRule(New System.Security.Principal.SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, Nothing),
             FileSystemRights.ReadAndExecute,
             InheritanceFlags.ContainerInherit + InheritanceFlags.ObjectInherit,
             PropagationFlags.None,
             AccessControlType.Allow))

    FolderAcl.AddAccessRule(New FileSystemAccessRule(New System.Security.Principal.SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, Nothing),
             FileSystemRights.FullControl,
             InheritanceFlags.ContainerInherit + InheritanceFlags.ObjectInherit,
             PropagationFlags.None,
             AccessControlType.Allow))

That will give r/w access to all authenticated users as well as full access to administrator group to your root folder and all subfolders and files.