Windows File Permissions not inherited when moved only when copied?

RainMotorsports

Partition Master
I was writing a sync program for someone I mirror for and I noticed when I move the downloaded files after verifying the md5 the permissions are not inherited.

According to Brian Lich a Microsoft Moderator on Technet:
When you move a file, it simply updates the file pointers and does not create a new file so the permissions will stay the same. When you copy a file, a new file is created and the permissions on the target folder are inherited. This has been by design for a long time.
I would lay down and accept this but there is a suggestion this isn't 100% the case? I mean he is indeed correct and copying the files from another location does give the new copies permissions of the target folder.

Normally I manually download the files from his primary mirror and cut paste them into the folder. The folder they are downloaded to does not have the permissions for the HTTP and FTP servers. The files moved via cut and paste inherit the permissions...

Not really an issue I can just do a copy and delete instead of a move in code. But is the behaviour of cut and paste in windows different than the Move in API?
 
Last edited:

marfig

No ROM battery
I suppose you are using the MoveFile() function in WinAPI?

If that's the case, security descriptors aren't moved with the file when moving across different volumes. This is also by design. Something that Brian Lich apparently forgot to mention, or just didn't think about it because it wasn't in context.

If you wish to preserve file permissions, you will want to use MoveFileEx() with the MOVEFILE_COPY_ALLOWED flag.

Code:
MoveFileEx(szSourceFile, szDestFile, MOVEFILE_COPY_ALLOWED);

That flag will instruct windows to move the file by copying it and then deleting the original, effectively moving the file security descriptors with it.

I don't use the WinAPI often. So you may want to check other means for fast sync. In any case, that's pretty fast in terms of program control. The function doesn't wait for the file to finish being copied and deleted. It just checks if it can be performed and instructs the OS to do it, returning control to the program immediately. If you do want for the function to wait until the operation is flushed to disk before moving to the next file, also use the MOVEFILE_WRITE_THROUGH flag.

Two notes:
1.
This isn't syncing obviously, since the original file would be deleted (and ACLs will be inherited). However the function still returns success if the original can't be deleted, which gives you room to use this function as a sync tool if you make sure to protect the original file from deletion first. But I'm also a bit confused as to why you are using MoveFile() in the context of folder sync ;)

2.
Alternatively, you may want to use GetNamedSecurityInfo() to store the file ACL structure, followed by MoveFile() or CopyFile(), followed by SetNamedSecurityInfo() to set the ACL structure on the new file. This is, I suppose what Robocopy does and it ensures file permissions aren't inherited, but perfectly sync with the original.

And yes, the Windows explorer move and copy operations are performed by following these security descriptor rules.
 
Last edited:

RainMotorsports

Partition Master
Well the problem is the file doesn't have the permissions it needs. So im trying to inherit from the destination rather than preserve the original. But either way you have me pointed in the right direction.

The "sync" is between 2 servers and is effectively manual but in code. The primary mirror is a linux server in which I can not install anything on and the secondary mirror is a windows server I have full control of. He provides a sync list that gets parsed. Files are downloaded from their public URL's, the checksum's in the sync list are verified and they are moved from the temporary location to their intended location.

Using MoveFile() the file only has the Users, Administrator, and Administrators permissions same as the folder they were downloaded to. The destination folder has additional permissions for the HTTP and FTP services. Back before i did this with my program I never ran into a problem inheriting permissions cutting and pasting so I was not understanding the behavior in windows.

I am sure there is a solution already out there but I have already written one that just needs some minor fixes. Truthfully i have been out of the saddle for 14 months it was nice to get back in and code for a day. This also allows us to do whats convenient for the "client".

As always marfig thank you.
 
Last edited:
Top