Search code examples
c#.netfile-security

C# .Net FileSystemRights Deny Deletion permission and add later on


My Program generates a file. this file should be protected, such that the User can't accidentally remove it. So, it needs to be protected in some way.

Since the file should be protected, while the application is closed FileStream.Lock is not a suitable solution for this task.

I tried to Deny FileSystemRights.Delete on the file like:

    fSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                FileSystemRights.Delete, AccessControlType.Deny));

But that does not prevent deletion, to do this i had to change it like this:

    fSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                FileSystemRights.Delete | FileSystemRights.WriteAttributes, AccessControlType.Deny));

( the user CAN open the file properties and add back the WriteAttribute permissions and can delete the file afterwards, which is fine )

The problem now is: The file should be deletable from the application. but doing:

    fSecurity.RemoveAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                FileSystemRights.Delete | FileSystemRights.WriteAttributes, AccessControlType.Deny));
    // or:
    fSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                FileSystemRights.Delete | FileSystemRights.WriteAttributes, AccessControlType.Allow));

results in an UnauthorizedAccessException. So i cannot undo what I've done. which is strange because in the file explorer its absolutely possible to do so.


So my question(s) is are - How do you grant deletion permissions again - or: what is the best way to protect a file for unintentional deletion



the file already is in %appdata% but since there are other folders the user might delete, it is absolutely mandatory that this file is not deleted accidentally


Solution

  • @canton7 thanks! this was extremely helpful

    okay, with much trial and error I got the solution:

    1. You have to set the file to readonly. Denying Deletion on its own does not work
    2. You have to deny Deletion + WriteAttributes - if you don't the file can be deleted in the File Explorer without asking for privileges.

    3. When unlocking the file again: first add back the Priviliges

      • you have to Remove the deny rules you added
      • and you have to add flags to allow
      • doing only one of this does not work
    4. remove the readonly flag
            private static void LockFile(string _FullPath)
            {
                File.SetAttributes(_FullPath, File.GetAttributes(_FullPath) | FileAttributes.ReadOnly);
    
                FileSecurity fSecurity = File.GetAccessControl(_FullPath);
    
                fSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                    FileSystemRights.Delete | FileSystemRights.WriteAttributes, AccessControlType.Deny));
    
                File.SetAccessControl(_FullPath, fSecurity);
            }
    
            private static void UnLockFile(string _FullPath)
            {
                FileSecurity fSecurity = File.GetAccessControl(_FullPath);
    
                fSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                    FileSystemRights.Delete | FileSystemRights.WriteAttributes, AccessControlType.Allow));
    
                fSecurity.RemoveAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                    FileSystemRights.Delete | FileSystemRights.WriteAttributes, AccessControlType.Deny));
    
                File.SetAccessControl(_FullPath, fSecurity);
    
                File.SetAttributes(_FullPath, FileAttributes.Normal);
            }