Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute code in another users context

I have an app with a manifest that requires running as administrator, but part of the app is to map a drive using WNetAddConnection2 which I believe requires it to be run in the normal user context due to credentials etc. Is there a way to execute this bit of code in the normal user context without creating a separate process.

EDIT

From the comments I have got this far but it doesnt work. I expected it not to as I dont really understand quite how I should use this. Perhaps it best if I open a new question?

class Program
{
    [DllImport("advapi32.DLL")]
    public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
    [DllImport("advapi32.DLL")]
    public static extern bool RevertToSelf();

    static void Main(string[] args)
    {
        IntPtr phToken = IntPtr.Zero;
        ImpersonateLoggedOnUser(phToken);
        MapDrives();
        RevertToSelf();
    }
}

EDIT

If the current user has admin privileges then the main process is elevated with the manifest, in the code which is elevated I want to run a command in the users non-elevated space as this appears to have different environment variables etc. I believe once a thread is started it cant change itself, it needs to run a new one.

like image 934
Charles Gargent Avatar asked Jun 04 '10 13:06

Charles Gargent


2 Answers

take a look on A small C# Class for impersonating a User code project article. It implements an IDisposable class (that releases the authentication token after its use). I've seen .NET code leaking due to not releasing the impersonation tokens.

You can impersonate a user only for a block of code that will access the network resource you need to access as a different user. Your code will look like

using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
{
   /* code that executes under the new context */
   ...
}

I hope it helps.

like image 140
CARLOS LOTH Avatar answered Nov 01 '22 12:11

CARLOS LOTH


First you need to obtain the user token that you want to start the app as, you can do this using WTSQueryUserToken. If the user is not yet logged on you can use LogonUser Win32 API to obtain a new one in a new session. To get all the sessions on your computer you can use WTSEnumerateSessions.

Then once you have the token you can use CreateProcessAsUser or else ImpersonateLoggedOnUser Win32 APIs.

Please make sure to call CloseHandle on the handles you obtain, they are especially bad leaks for this type of work.

like image 44
Brian R. Bondy Avatar answered Nov 01 '22 14:11

Brian R. Bondy