Проблема с разрешениями при запуске приложения .NET из службы .NET как другого пользователя?
Я пытаюсь запустить .NET-приложение под другим пользователем из службы .NET. Идея заключается в создании изолированного хостинга в Windows. В сервисе я программно создавал пользователя в окнах, создавал папку для этого пользователя и загружал хост .exe с сервера в эту папку. Затем я запускаю host.exe с помощью System.Diagnostics.Process. Вот StartInfo для процесса:
_process = new Process
{
StartInfo =
{
Arguments = " -debug",
FileName = instanceDirectory + "host.exe",
WorkingDirectory = instanceDirectory,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
UserName = Helpers.GetUserNameForInstance(_hostid),
Password = _hostpass,
Domain = ""
},
EnableRaisingEvents = true
};
Когда я запускаю службу как СЕРВИС, процесс аварийно завершает работу с кодом ошибки -1073741502. но когда я запускаю службу как одного и того же пользователя, указанного в службе Windows, но интерактивно в консоли, все работает нормально. Это происходит только при выполнении службы как службы, а не непосредственно в консоли.
Любая помощь была бы очень оценена. Это была головная боль в течение длительного времени, и это последнее средство: (
Ответы
Ответ 1
Похоже, что с помощью new Process()
с именем пользователя и паролем и в режиме обслуживания "не вычисляется":)
Цитата из MSDN:
Вы можете изменить параметры указанный в свойстве StartInfo вверх до того времени, когда вы назовете Start метод в процессе. После запуска процесс, изменение StartInfo значения не влияют или не перезапускают связанный процесс. Если вы вызываете Начать (ProcessStartInfo) с помощью ProcessStartInfo..::. UserName и ProcessStartInfo..::. Пароль набор свойств, неуправляемый Функция CreateProcessWithLogonW который запускает процесс в новое окно, даже если CreateNoWindow значение свойства истинно или Значение свойства WindowStyle скрыто.
Кроме того, глядя на документацию CreateProcessWithLogonW:
lpStartupInfo [in]
Указатель на структуру STARTUPINFO. Приложение должно добавить разрешение для указанного пользователя учетной записи в указанное окно станции и рабочего стола, даже для Winsta0\Default.
Если член lpDesktop имеет значение NULL или пустую строку, новый процесс наследует рабочий стол и окно станции его родительского процесса. приложение должно добавить разрешение для указанную учетную запись пользователя для унаследованная оконная станция и рабочий стол.
В .NET StartupInfo нет lpDesktop, с другой стороны у пользователя SERVICE нет рабочего стола, что может вызвать проблемы.
Короче говоря, попробуйте установить LoadUserProfile
в true
, чтобы загрузить информацию пользователя из реестра, или, возможно, вам нужно установить рабочий каталог и т.д.
Чтобы продолжить расследование, вы должны проверить свою среду и, возможно, зарегистрировать доступ к файлам с помощью FileMon.
Ответ 2
Я попытался бы создать процесс под олицетворенным контекстом вновь созданного пользователя, как показано ниже.
[DllImport("advapi32.DLL", SetLastError = true)]
public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
[DllImport("advapi32.DLL")]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
static void Main()
{
IntPtr admin_token = new IntPtr();
WindowsIdentity wid_admin = null;
WindowsImpersonationContext wic = null;
LogonUser("username", "domain", "password", 9, 3, out admin_token);
wid_admin = new WindowsIdentity(admin_token);
wic = wid_admin.Impersonate();
_process = new Process
{
StartInfo =
{
Arguments = " -debug",
FileName = instanceDirectory + "host.exe",
WorkingDirectory = instanceDirectory,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
UserName = Helpers.GetUserNameForInstance(_hostid),
Password = _hostpass,
Domain = ""
},
EnableRaisingEvents = true
};
if (wic != null) wic.Undo();
CloseHandle(admin_token);
}
Ответ 3
Двойной прыжок между серверами может привести к тому, что учетные данные службы будут удалены, возможно, настройка Kerberos решит эту проблему.
http://neverknewthat.wordpress.com/2009/05/14/kerberos/
Ответ 4
0xc0000142
(-1073741502) - STATUS_DLL_INIT_FAILED:
Ошибка инициализации библиотеки динамических ссылок [имя]. Процесс прерывается аномально.
Как указал сайт TenaciousImpy, вам необходимо предоставить разрешения учетной записи на оконную станцию и рабочий стол. Но если программа является интерактивной, вам также нужно установить идентификатор сеанса для токена процесса.