I didn't have permission to call GetAccessControl on any file that wasn't on my local machine (the first error), and I couldnt set the owner of any file I owned (the second error), I could only grant "take ownership" rights. Running the tool as the domain admin solved everything.
How do I Copy a File and preserve ownership?
-
30-06-2022 - |
Question
I need to replace all the files in one directory with backup files in another directory. ALL the file properties/permissions/ownership must be retained. File.Copy, just like Windows Explorer, copies the files, clears all permissions, and changes the owner to myself.
I found an example on SO that SHOULD preserve its original permissions but doesn't: Copy a file with its original permissions
The code:
File.Copy(originFile, destinationFile);
FileInfo originFileInfo = new FileInfo(originFile);
FileInfo destinationFileInfo = new FileInfo(destinationFile);
FileSecurity ac1 = originFileInfo.GetAccessControl(AccessControlSections.All);
ac1.SetAccessRuleProtection(true, true);
destinationFileInfo.SetAccessControl(ac1);
I get a PrivilegeNotHeldException:
The process does not possess the 'SeSecurityPrivilege' privilege which is required for this operation.
If I disable UAC I get this error instead:
The security identifier is not allowed to be the owner of this object.
I get this exception with AccessControlSections.All and AccessControlSections.Owner. The code works if I change the enum to AccessControlSections.Access, but only the permissions are retained, not the ownership. I am a local admin, and even when the destination is my local PC it doesn't work. And I am running Visual Studio 2010 as administrator.
Solution 2
OTHER TIPS
You may need to explicitly acquire the 'SeSecurityPrivilege'. Perhaps the easiest way of doing that is to use Process Privileges.
// Untested code, but it might look like this...
// (Add exception handling as necessary)
Process process = Process.GetCurrentProcess();
using (new PrivilegeEnabler(process, Privilege.Security))
{
// Privilege is enabled within the using block.
File.Copy(originFile, destinationFile);
FileInfo originFileInfo = new FileInfo(originFile);
FileInfo destinationFileInfo = new FileInfo(destinationFile);
FileSecurity ac1 = originFileInfo.GetAccessControl(AccessControlSections.All);
ac1.SetAccessRuleProtection(true, true);
destinationFileInfo.SetAccessControl(ac1);
}