8

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");
alternative
  • 81
  • 1
  • 1
  • 3
  • 2
    What's going on with UAC here? Are you running elevated? – Hans Passant Oct 21 '12 at 16:00
  • Yes and doesn't help. You need to set privileges, then delete the given file. The solution is here: http://msdn.microsoft.com/en-us/magazine/cc164701.aspx?code=true&level=root%2cPrivilege11 – alternative Oct 27 '12 at 19:17

4 Answers4

6

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");
Nick Hill
  • 4,867
  • 3
  • 23
  • 29
  • Thanks, Nikolay. Someone's working code is still more than welcome. – alternative Oct 21 '12 at 17:44
  • @alternative My answer contains link to Mark's implementation of `Privilege` class among with sample code. I don't think I should copy and paste about 1k lines of code here. Although I've updated my answer with an example usage. – Nick Hill Oct 21 '12 at 18:11
  • 1
    The article link is broken but you can still get it in CHM form by scrolling to the bottom of this page: https://msdn.microsoft.com/magazine/msdn-magazine-issues and clicking on March 2005. After saving right click on it and in Properties you need to UnBlock, otherwise it comes up blank. Also the source code is linked from within the CHM in an .exe file of all things, looks like it needs to install for whatever reason. – TripleAntigen May 15 '16 at 03:17
4
        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.

Josiah
  • 81
  • 4
  • I have tried all the other suggestions for taking ownership of a file -- suggestions on this page, which expect me to use a third party class, and from other websites, but it was only yours that worked for me! Thanks! (I left out the file.delete part since I just wanted to take ownership for other reasons.) – Joe Gayetty Mar 19 '19 at 19:40
1

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;
    }
0

See these registry entries for adding a context menu. I was able to rename the folder as well as iexplorer_OFF.exe on Windows 7. You can probably shell/execute the same from your code.

https://www.howtogeek.com/howto/windows-vista/add-take-ownership-to-explorer-right-click-menu-in-vista/

Meryan
  • 1,285
  • 12
  • 25