Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Network Authentication when running exe from WMI

I have a C# exe that needs to be run using WMI and access a network share. However, when I access the share I get an UnauthorizedAccessException. If I run the exe directly the share is accessible. I am using the same user account in both cases.

There are two parts to my application, a GUI client that runs on a local PC and a backend process that runs on a remote PC. When the client needs to connect to the backend it first launches the remote process using WMI (code reproduced below). The remote process does a number of things including accessing a network share using Directory.GetDirectories() and reports back to the client.

When the remote process is launched automatically by the client using WMI, it cannot access the network share. However, if I connect to the remote machine using Remote Desktop and manually launch the backend process, access to the network share succeeds.

The user specifed in the WMI call and the user logged in for the Remote Desktop session are the same, so the permissions should be the same, shouldn't they?

I see in the MSDN entry for Directory.Exists() it states "The Exists method does not perform network authentication. If you query an existing network share without being pre-authenticated, the Exists method will return false." I assume this is related? How can I ensure the user is authenticated correctly in a WMI session?

ConnectionOptions opts = new ConnectionOptions();

opts.Username = username;
opts.Password = password;

ManagementPath path = new ManagementPath(string.Format("\\\\{0}\\root\\cimv2:Win32_Process", remoteHost));

ManagementScope scope = new ManagementScope(path, opts);

scope.Connect();

ObjectGetOptions getOpts = new ObjectGetOptions();
using (ManagementClass mngClass = new ManagementClass(scope, path, getOpts))
{
    ManagementBaseObject inParams = mngClass.GetMethodParameters("Create");
    inParams["CommandLine"] = commandLine;
    ManagementBaseObject outParams = mngClass.InvokeMethod("Create", inParams, null);
}
like image 382
Andy Avatar asked Mar 09 '10 16:03

Andy


People also ask

How does WMI authenticate?

WMI normally runs in a shared service host and shares the same authentication as other processes in the host. To run the WMI process with a different level of authentication, run WMI with the winmgmt command with the /standalonehost switch and set the authentication level for WMI generally.

How do I check my WMI authentication level?

Go to Start → Run → wmimgmt. msc to open the Component Services console. Right Click on the WMI Control → select Properties → Security tab → Click Security → Click Advanced button.

Does WMI use NTLM?

WMI has default DCOM impersonation, authentication, and authentication service (NTLM or Kerberos) settings that the a remote system requires. Your local system may use different defaults that the target remote system does not accept. You can change these settings in the connection call.

What is WMI in C#?

WMI is intended to monitor the hardware and software on remote computers. Remote connections for WMI v1 is accomplished through the ManagementScope object. To connect to WMI remotely with C# (System.Management)


1 Answers

Having followed the link suggested by Isalamon above (thanks) I followed Jestro's advice and have rewritten using psexec.exe (which can be downloaded from http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx) instead of WMI. It feels like a bit of a kludge to do it this way, but it seems to work.

New code for anyone who is experiencing similar problems:

Process proc = new Process();
proc.StartInfo.FileName = "PsExec.exe";
proc.StartInfo.Arguments = string.Format("\\\\{0} -d -u {1}\\{2} -p {3} {4}",
                                         remoteHost,
                                         domain,
                                         username,
                                         password,
                                         commandLine);
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
like image 116
Andy Avatar answered Nov 13 '22 01:11

Andy