Аутентификация сети при запуске exe из WMI
У меня есть С# exe, который нужно запустить с помощью WMI и получить доступ к сетевому ресурсу. Однако, когда я получаю доступ к ресурсу, я получаю UnauthorizedAccessException. Если я запускаю exe напрямую, доступ к нему доступен. Я использую одну и ту же учетную запись пользователя в обоих случаях.
В моем приложении есть две части: клиент GUI, который работает на локальном ПК и бэкэнд-процесс, который работает на удаленном ПК. Когда клиент должен подключиться к бэкэнд, он сначала запускает удаленный процесс с использованием WMI (код воспроизводится ниже). Удаленный процесс выполняет ряд действий, включая доступ к сетевому ресурсу с помощью Directory.GetDirectories() и отчёт для клиента.
Когда удаленный процесс запускается автоматически клиентом с использованием WMI, он не может получить доступ к сетевому ресурсу. Однако, если я подключаюсь к удаленному компьютеру с помощью удаленного рабочего стола и запускаю серверный процесс вручную, доступ к сетевому ресурсу успешно завершается.
Пользователь, указанный в вызове WMI, и пользователь, зарегистрированный для сеанса удаленного рабочего стола, одинаковый, поэтому разрешения должны быть одинаковыми, не так ли?
В записи MSDN для Directory.Exists() указано, что "метод Exists не выполняет сетевую проверку подлинности. Если вы запрашиваете существующий сетевой ресурс без предварительной аутентификации, метод Exists возвращает false." Я полагаю, это связано? Как я могу гарантировать правильность аутентификации пользователя на сеансе WMI?
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);
}
Ответы
Ответ 1
Следуя ссылке, предложенной Исаламоном выше (спасибо), я пошел за советом Jestro и переписал с помощью psexec.exe(который можно скачать из http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx) вместо WMI. Похоже, что это так много, но это похоже на работу.
Новый код для тех, кто испытывает подобные проблемы:
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();
Ответ 2
WMI использует олицетворение при выполнении удаленного процесса, что не дает вам доступа к сети. Если вы согласны выйти за пределы управляемого кода, вы можете просто наметить путь UNC в удаленном процессе. WMI начал использовать любые учетные данные, которые вы хотите. Затем у вас есть доступ к сети, который вы хотите. Я использую NetUseAdd и NetUseDel из netapi32.dll для сопоставления пути UNC. Подробнее об использовании API-интерфейсов см. http://pinvoke.net/.
Ответ 3
Я знаю, что вы отсортировали его, используя PSEXEC, что является фантастической программой, но если вы хотите вернуться к WMI, попробуйте ли вы включить следующее в ConnectionOptions:
- Флаг EnablePrivileges
- настройка олицетворения для олицетворения уровня личности .Impersonate
Что делает следующее:
http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.impersonation.aspx
http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.enableprivileges.aspx
Я думаю, что они должны сообщить вашему WMI, чтобы на самом деле разрешить программе иметь правильные учетные данные и, таким образом, получить доступ к вашему сетевому ресурсу
Ответ 4
Вы можете написать все свои команды для пакетного файла на удаленный компьютер, который включает использование сети (без необходимости использовать букву диска) для аутентификации. Отлично работает. Я все еще работаю над альтернативой.