Подтвердить что ты не робот

Проблема с разрешениями при запуске приложения .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, но интерактивно в консоли, все работает нормально. Это происходит только при выполнении службы как службы, а не непосредственно в консоли.

Любая помощь была бы очень оценена. Это была головная боль в течение длительного времени, и это последнее средство: (

4b9b3361

Ответ 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, вам необходимо предоставить разрешения учетной записи на оконную станцию ​​и рабочий стол. Но если программа является интерактивной, вам также нужно установить идентификатор сеанса для токена процесса.