问题
I am trying to take ownership of a file and delete it via C#. The file is iexplorer.exe, current owner by default - TrustedInstaller. The method FileSecurity.SetOwner seems to set the specified ownership, but actually doesn't change the initial owner and throws no exception. Obviously, the next attempt to delete the file throws an exception. What should be changed in the code to take ownership of the file and delete it ?
var fileS = File.GetAccessControl(@"C:\Program Files (x86)\Internet Explorer\iexplore.exe");
fileS.SetOwner(new System.Security.Principal.NTAccount(Environment.UserDomainName, Environment.UserName));
File.Delete(@"C:\Program Files (x86)\Internet Explorer\iexplore.exe");
回答1:
You must explicitly enable SeTakeOwnershipPrivilege:
Required to take ownership of an object without being granted discretionary access. This privilege allows the owner value to be set only to those values that the holder may legitimately assign as the owner of an object. User Right: Take ownership of files or other objects.
I suggest you to read the great article written by Mark Novak: Manipulate Privileges in Managed Code Reliably, Securely, and Efficiently.
And/or take a look at his sample.
Update
Example usage:
var fileS = File.GetAccessControl(@"C:\Program Files (x86)\Internet Explorer\iexplore.exe");
Privilege p;
bool ownerChanged = false;
try
{
p = new Privilege(Privilege.TakeOwnership);
p.Enable();
fileS.SetOwner(new System.Security.Principal.NTAccount(
Environment.UserDomainName, Environment.UserName));
ownerChanged = true;
}
catch(PrivilegeNotHeldException e)
{
// privilege not held
// TODO: show an error message, write logs, etc.
}
finally
{
p.Revert();
}
if (ownerChanged)
File.Delete(@"C:\Program Files (x86)\Internet Explorer\iexplore.exe");
回答2:
string filepath = @"C:\Program Files (x86)\Internet Explorer\iexplore.exe";
//Get Currently Applied Access Control
FileSecurity fileS = File.GetAccessControl(filepath);
//Update it, Grant Current User Full Control
SecurityIdentifier cu = WindowsIdentity.GetCurrent().User;
fileS.SetOwner(cu);
fileS.SetAccessRule(new FileSystemAccessRule(cu, FileSystemRights.FullControl, AccessControlType.Allow));
//Update the Access Control on the File
File.SetAccessControl(filepath, fileS);
//Delete the file
File.Delete(filepath);
Add the following imports
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
Run the Code in Elevated Mode.
回答3:
Powered in Windows 8.1 using class Privilege from example: Manipulate Privileges in Managed Code Reliably, Securely, and Efficiently
private bool TryDeleteFile(string fileName)
{
string filePath = Path.GetFullPath(fileName);
var fi = new FileInfo(filePath);
bool ownerChanged = false;
bool accessChanged = false;
bool isDelete = false;
FileSecurity fs = fi.GetAccessControl();
Privilege p = new Privilege(Privilege.TakeOwnership);
try
{
p.Enable();
fs.SetOwner(WindowsIdentity.GetCurrent().User);
File.SetAccessControl(filePath, fs); //Update the Access Control on the File
ownerChanged = true;
}
catch (PrivilegeNotHeldException ex) { }
finally { p.Revert(); }
try
{
fs.SetAccessRule(new FileSystemAccessRule(WindowsIdentity.GetCurrent().User, FileSystemRights.FullControl, AccessControlType.Allow));
File.SetAccessControl(filePath, fs);
accessChanged = true;
}
catch (UnauthorizedAccessException ex) { }
if (ownerChanged && accessChanged)
{
try
{
fi.Delete();
isDelete = true;
}
catch (Exception ex) { }
}
return isDelete;
}
来源:https://stackoverflow.com/questions/12999272/take-ownership-of-a-file-c-sharp