I'm trying to overcome the following situation.
Given a directory stored on an NTFS volume, where:
(or in short, the all administrators have been locked out of the folder)
But!
(or in short, I have access to fix the DACL/owner)
I should have no problem with the following code:
WindowsIdentity privilegedUser = System.Security.Principal.WindowsIdentity.GetCurrent();
// I cannot use File.GetAccessControl() as I get access denied
// (working as intended! I have no access to read the ACL!)
// so I have to write a new ACL:
FileSecurity acl = new FileSecurity();
acl.SetOwner(admin.User);
acl.AddAccessRule(new FileSystemAccessRule(privilegedUser.User, FileSystemRights.FullControl, AccessControlType.Allow));
File.SetAccessControl("c:\\path\\to\\broken", acl);
But, the SetAccessControl call throws UnauthorizedAccessException. When I alter it to only adjust the owner, the same thing happens. When I only try to adjust the DACL, same thing.
I've verified that the issue is not UAC by checking the resulting process in Process Explorer, and verified that the Administrators group is set to "Owner" instead of "Disabled." I should have all of the necessary rights to do this (Backup Operators should be extraneous in the face of Administrators, but I added it for testing) -- but it just keeps throwing access denied.
Relevant technet documentation: http://technet.microsoft.com/en-us/library/cc783530%28WS.10%29.aspx
What am I missing here?
I had the same problem and just posting here for anybody else who may come here searching like me:
You need to explicitly enable SeTakeOwnershipPrivilege in code. I found Process Privileges to be really helpful dealing with this sort of thing.
Here is how it fixed my code (seems like for some reason even though i have the privilege, the process doesn't unless i explicitly enable it):
using (new ProcessPrivileges.PrivilegeEnabler(Process.GetCurrentProcess(), Privilege.TakeOwnership))
{
directoryInfo = new DirectoryInfo(path);
directorySecurity = directoryInfo.GetAccessControl();
directorySecurity.SetOwner(WindowsIdentity.GetCurrent().User);
Directory.SetAccessControl(path, directorySecurity);
}
PS: Thanks Simon.. your answer gave me a place to start from.