take ownership of a file c#

12.4k views Asked by At

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");
4

There are 4 answers

3
Nick Hill On

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");
1
Josiah On
        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.

0
Meryan On

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/

0
AudioBubble On

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