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.

Was it helpful?

Solution 2

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.

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);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top