File.Move does not inherit permissions from target directory?
Asked Answered
D

1

29

In case something goes wrong in creating a file, I've been writing to a temporary file and then moving to the destination. Something like:

        var destination = @"C:\foo\bar.txt";
        var tempFile = Path.GetTempFileName();
        using (var stream = File.OpenWrite(tempFile))
        {
            // write to file here here
        }

        string backupFile = null;
        try
        {
            var dir = Path.GetDirectoryName(destination);
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
                Util.SetPermissions(dir);
            }

            if (File.Exists(destination))
            {
                backupFile = Path.Combine(Path.GetTempPath(), new Guid().ToString());
                File.Move(destination, backupFile);
            }

            File.Move(tempFile, destination);

            if (backupFile != null)
            {
                File.Delete(backupFile);
            }
        }
        catch(IOException)
        {
            if(backupFile != null && !File.Exists(destination) && File.Exists(backupFile))
            {
                File.Move(backupFile, destination);
            }
        }

The problem is that the new "bar.txt" in this case does not inherit permissions from the "C:\foo" directory. Yet if I create a file via explorer/notepad etc directly in the "C:\foo" there's no issues, so I believe the permissions are correctly set on "C:\foo".

Update

Found Inherited permissions are not automatically updated when you move folders, maybe it applies to files as well. Now looking for a way to force an update of file permissions. Is there a better way overall of doing this?

Draughts answered 28/5, 2010 at 14:36 Comment(1)
I had same issue. I never quite figure out the cause. However, note that File.Copy does NOT have the same problem. (Something about ownership??)Alsace
D
40

Found what I needed was this:

var fs = File.GetAccessControl(destination);
fs.SetAccessRuleProtection(false, false);
File.SetAccessControl(destination, fs);

This resets the file permissions to inherit.

Draughts answered 28/5, 2010 at 16:59 Comment(5)
Do you have to do this once the file has already been moved? In which case it's no longer atomic - there's a risk someone could try and read the file before the permissions are in placeCocci
@Cocci yes, this would be after the move and yes it would make it no longer atomic.Draughts
@JosephKingry. Thanks, this helped me out. But, I also wanted to remove any explicit permissions as a result of the Move. Just a few more lines of code. https://mcmap.net/q/502263/-setting-a-file-39-s-acl-to-be-inheritedEmbowed
Is this also necessary when copying a file or are the permissions automatically inherited in that case?Baksheesh
It seems File.Copy does not have the same problem. Neil it seems ridiculous, but copying the file then deleting the original might be a solution.Alsace

© 2022 - 2024 — McMap. All rights reserved.