Выполнить код в контексте другого пользователя - PullRequest
8 голосов
/ 04 июня 2010

У меня есть приложение с манифестом, которое требует запуска от имени администратора, но частью приложения является сопоставление диска с использованием WNetAddConnection2, которое, по моему мнению, требует его запуска в обычном пользовательском контексте из-за учетных данных и т. Д. выполнить этот фрагмент кода в обычном пользовательском контексте, не создавая отдельный процесс.

EDIT

Из комментариев я получил это далеко, но это не работает. Я ожидал, что это не так, поскольку я не совсем понимаю, как я должен это использовать. Возможно, будет лучше, если я открою новый вопрос?

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

Если текущий пользователь имеет права администратора, то основной процесс повышается с помощью манифеста, в коде с повышенными правами я хочу выполнить команду в пространстве без повышенных прав пользователя, так как это, похоже, имеет разные переменные среды и т. Д. I поверьте, если поток запущен, он не может изменить себя, ему нужно запустить новый.

Ответы [ 3 ]

4 голосов
/ 04 июня 2010

взгляните на Небольшой класс C # для олицетворения статьи проекта кода пользователя . Он реализует класс IDisposable (который освобождает токен аутентификации после его использования). Я видел утечку кода .NET из-за отсутствия выпуска маркеров олицетворения.

Вы можете выдавать себя за пользователя только за блок кода, который будет обращаться к сетевому ресурсу, к которому вы должны обращаться как другой пользователь. Ваш код будет выглядеть как

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

Надеюсь, это поможет.

1 голос
/ 04 июня 2010

Сначала вам нужно получить маркер пользователя, от которого вы хотите запустить приложение, вы можете сделать это, используя WTSQueryUserToken . Если пользователь еще не вошел в систему, вы можете использовать LogonUser Win32 API для получения нового в новом сеансе. Чтобы получить все сеансы на вашем компьютере, вы можете использовать WTSEnumerateSessions .

Затем, получив токен, вы можете использовать CreateProcessAsUser или ImpersonateLoggedOnUser Win32 API.

Пожалуйста, не забудьте позвонить CloseHandle на полученные вами ручки, они особенно плохие утечки для этого типа работы.

0 голосов
/ 04 июня 2010

Я не уверен, что это способ сделать это без создания нового процесса, ImpersonateLoggedOnUser будет работать только из службы, и я не хочу предоставлять учетные данные.

поправьте меня, если я ошибаюсь

...