Search code examples
c#permissionsaclsharefiledirectory-security

C# File/Directory Permissions for local share


I need a file to be editable by all local users. The application saves common information to all users in its own folder under ProgramData. I need to guarantee reading and writing to all users, it is so little information that it does not merit the use of a database.

I get the path to the folder from:Path.Combine(Application.CommonAppDataPath, "InfoConfig");

All users can read, write and create in this folder. Except the files that are created by the other users.

I already tried to remove Creator Owner without success. So my last attempt was not to inherit from the container folder and create the permissions from scratch for SYSTEM, Administrators and Users. But it didn't work either, here is my code.

            string sharedFolder = Path.Combine(Application.CommonAppDataPath, "InfoConfig");
        if (!Directory.Exists(sharedFolder))
        {
            DirectoryInfo directoryInfo = Directory.CreateDirectory(sharedFolder);
            DirectorySecurity directorySecurity = directoryInfo.GetAccessControl();
            directorySecurity.SetAccessRuleProtection(true, false);
            FileSystemRights fileSystemRights = 
                      FileSystemRights.FullControl | 
                      FileSystemRights.Modify | 
                      FileSystemRights.Read | 
                      FileSystemRights.Delete;
            SecurityIdentifier usersSid = 
                      new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
            SecurityIdentifier systemSid = 
                      new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);
            SecurityIdentifier adminsSid = 
                      new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);

            FileSystemAccessRule rule = 
                      new FileSystemAccessRule(systemSid, fileSystemRights, AccessControlType.Allow);

            directorySecurity.AddAccessRule(rule);

            rule = new FileSystemAccessRule(adminsSid, fileSystemRights, AccessControlType.Allow);
            directorySecurity.AddAccessRule(rule);

            rule = new FileSystemAccessRule(usersSid, FileSystemRights.Read 
                     | FileSystemRights.Write 
                     | FileSystemRights.Modify, 
                     AccessControlType.Allow);
            directorySecurity.AddAccessRule(rule);

            directoryInfo.SetAccessControl(directorySecurity);
        }

It still doesn't work. What am I doing wrong?


Solution

  • I have only considered the below snippet for usersSid, you can tweak it for the other userTypes as well

    Have added ObjectSecurity.ModifyAccessRule(AccessControlModification, AccessRule, Boolean) which applies the specified modification to the Discretionary Access Control List (DACL) associated with this ObjectSecurity object (directorySecurity in our instance).


    
    string sharedFolder = Path.Combine(Application.CommonAppDataPath, "InfoConfig");
    
     if (!Directory.Exists(sharedFolder))
     {
        DirectoryInfo directoryInfo = Directory.CreateDirectory(sharedFolder);
        DirectorySecurity directorySecurity = directoryInfo.GetAccessControl();
    
        directorySecurity.SetAccessRuleProtection(true, false);
    
        FileSystemRights fileSystemRights = 
                FileSystemRights.FullControl | 
                FileSystemRights.Modify | 
                FileSystemRights.Read | 
                FileSystemRights.Delete;
    
        SecurityIdentifier usersSid = 
                new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
    
    
        FileSystemAccessRule rule =  new FileSystemAccessRule(usersSid, fileSystemRights,InheritanceFlags.None, PropagationFlags.NoPropagateInherit, AccessControlType.Allow);
        directorySecurity.AddAccessRule(rule);
    
        bool result;
        directorySecurity.ModifyAccessRule(AccessControlModification.Set, rule, out result);
    
        if (!result)
            {
                throw new InvalidOperationException("Failed to give full-control permission to all users for path " + path);
            }
    
        FileSystemAccessRule inheritedRule = new FileSystemAccessRule(
        usersSid,
        fileSystemRights,
        InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
        PropagationFlags.InheritOnly,
        AccessControlType.Allow);
    
        bool inheritedResult;
        directorySecurity.ModifyAccessRule(AccessControlModification.Add, inheritedRule, out inheritedResult);
    
        if (!inheritedResult)
        {
            throw new InvalidOperationException("Failed to give full-control permission inheritance to all users for " + path);
        }
    
    
        directoryInfo.SetAccessControl(directorySecurity);
    }