Re: Запуск функции под другим пользователем
От: Pavel_Agurov Россия  
Дата: 24.06.12 20:10
Оценка: 30 (2)
S>У меня появилась необходимость в одном приложении получить список файлов в нескольких папок.
S>Все бы ничего, да права на папки имею пользователи разные, а если быть точнее, то из разных доменов.
S>Как можно реализовать данный функционал?
S>Пароли, понятно дело, я знаю. Необходимо просто написать функцию, которая умеет это делать.


166. Программная имперсонация
Программную имперсонацию пользователя с заданным именем и паролем можно выполнить с помощью функций, импортированных из Win32 (листинг 69).


Листинг 69 Имперсонация пользователя
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;

namespace LogonUser
{
  class Class1
  {
    private const int LOGON32_LOGON_INTERACTIVE       = 2;
    private const int LOGON32_LOGON_NETWORK_CLEARTEXT = 3;
    private const int LOGON32_PROVIDER_DEFAULT        = 0;
   
    [DllImport("advapi32.dll", CharSet=CharSet.Auto)]
    static extern int LogonUser (string lpszUserName, 
            string lpszDomain, string lpszPassword, int dwLogonType,
            int dwLogonProvider, ref IntPtr phToken);

    [DllImport("advapi32.dll", CharSet=CharSet.Auto,
                                       SetLastError=true)]
    static extern int DuplicateToken (IntPtr hToken, 
            int impersonationLevel, ref IntPtr hNewToken);

    [STAThread]
    static void Main(string[] args)
    {
      // Печатаем текущего пользователя
      WindowsIdentity wi = WindowsIdentity.GetCurrent();
      Console.WriteLine("Name={0} --> {1}", wi.Name,
                                            wi.IsAuthenticated);

      string UserName = "Administrator";
      string Password = "123";

      // Для сохранения текущей имперсонации
      WindowsImpersonationContext impersonationContext = null;

      try
      {
        // Имперсонируем другого пользователя
        WindowsIdentity newIdentity; 
        IntPtr token = IntPtr.Zero; 
        IntPtr tokenDuplicate = IntPtr.Zero; 
        if(LogonUser(UserName, Environment.MachineName, Password, 
          LOGON32_LOGON_NETWORK_CLEARTEXT,
                          LOGON32_PROVIDER_DEFAULT, ref token) != 0)
        { 
          if(DuplicateToken(token, 2, ref tokenDuplicate) != 0)
          { 
            newIdentity = new WindowsIdentity(tokenDuplicate);
            // При имперсонации возвращается текущее значение
            impersonationContext = newIdentity.Impersonate();
          } 
        }
      }
      catch(Exception Ex)
      {
        Console.WriteLine("Ошибка ммперсонации
                          пользователя {0}: {1}", UserName, Ex);
      }

      // Новая имперсонация
      WindowsIdentity wi1 = WindowsIdentity.GetCurrent();
      Console.WriteLine("Name={0} --> {1}",
                             wi1.Name, wi1.IsAuthenticated);

      // Возвращаем предыдущую имперсонацию
      if (impersonationContext != null)
        impersonationContext.Undo();

      // Печатаем снова
      WindowsIdentity wi2 = WindowsIdentity.GetCurrent();
      Console.WriteLine("Name={0} --> {1}",
                             wi2.Name, wi2.IsAuthenticated);
    }
  }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.