2011-06-20 28 views
4

別のユーザー名の資格情報でプロセスを起動したいとします。 これは私が今持っているものです。別のユーザーの資格情報でプロセスを起動します。

 /// <summary> 
     /// Do actions under another username's credentials 
     /// </summary> 
     /// <param name="username">Username to inpersonate</param> 
     /// <param name="domain">Domain/Machine</param> 
     /// <param name="password">Password </param> 
     public static void Action(string username,string domain, string password) 
     { 
      try 
      { 
       if (LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref hToken)) 
       { 
        if (DuplicateToken(hToken, 2, ref hTokenDuplicate)) 
        { 

         WindowsIdentity windowsIdentity = new WindowsIdentity(hTokenDuplicate); 

         WindowsImpersonationContext impersonationContext = windowsIdentity.Impersonate(); 

         // Check the identity but it could do any other action under given username credentials 
         try 
         { 
          ProcessStartInfo info = new ProcessStartInfo("cmd.exe"); 
          info.UseShellExecute = false; 
          info.RedirectStandardInput = true; 
          info.RedirectStandardError = true; 
          info.RedirectStandardOutput = true; 
          info.UserName = "dummy"; // see the link mentioned at the top 
          // Define the string value to assign to a new secure string. 
          char[] chars = { 'p', 'a', 's', 's','1','2','3','4','/' }; 
          // Instantiate the secure string. 
          SecureString testString = new SecureString(); 
          // Assign the character array to the secure string. 
          foreach (char ch in chars) 
           testString.AppendChar(ch); 

          info.Password = testString; 

          Process.Start(info); 

         } 
         catch (Exception ex) 
         { 
          Console.WriteLine("Exception Occurred :{0},{1}",ex.Message, ex.StackTrace.ToString()); 
         } 

         // Stop impersonating the user 
         impersonationContext.Undo(); 
        } 
       } 
       // Free the tokens 
       if (hToken != IntPtr.Zero) 
        CloseHandle(hToken); 
       if (hTokenDuplicate != IntPtr.Zero) 
        CloseHandle(hTokenDuplicate); 

     }catch(Exception ex) 
     { 
      Console.WriteLine("Exception occurred. " + ex); 
      } 

動作するようには思えないし、私は「アクセスが拒否されました」を得ます。それを行う方法の任意のアイデア? 資格情報を要求すると正しい資格が得られるので、その資格情報に基づいてプログラムを実行する必要があります。すなわち:

   if (DuplicateToken(hToken, 2, ref hTokenDuplicate)) 
        { 

         WindowsIdentity windowsIdentity = new WindowsIdentity(hTokenDuplicate);      
         WindowsImpersonationContext impersonationContext = windowsIdentity.Impersonate(); 

         // Check the identity but it could do any other action under given username credentials 
         Console.WriteLine("After impersonation: {0}", WindowsIdentity.GetCurrent().Name); 

         // Stop impersonating the user 
         impersonationContext.Undo(); 
        } 

答えは正しいです、私たちは "ダミー"を取得します。

我々はそれをさらに簡単にすることができます:

public static void Run() 
     { 
      try 
      { 
       const string file = "cmd.exe"; 

       var sspw = new SecureString(); 

       foreach (var c in "pass1234/") 
        sspw.AppendChar(c); 

       var proc = new Process(); 

       proc.StartInfo.UseShellExecute = false; 

       proc.StartInfo.WorkingDirectory = Path.GetDirectoryName(file); 

       proc.StartInfo.FileName = Path.GetFileName(file); 

       proc.StartInfo.Domain = "WIN08"; 
       proc.StartInfo.Arguments = ""; 
       proc.StartInfo.UserName = "dummy"; 
       proc.StartInfo.Password = sspw; 
       proc.StartInfo.LoadUserProfile = false; 
       proc.Start(); 
      }catch(Exception e) 
      { 
       Console.WriteLine(e); 
      } 

しかし、私はまだ例外を取得...

+0

あなたがこのアプリを実行している資格情報のどのような? – therealmitchconnors

+0

標準ユーザー – Manolete

+0

の下でアプリケーションを実行しようとしている管理者exeを右クリックして[別のユーザーとして実行...]を選択できませんか? –

答えて

5

私は、ユーザーがログインしてハンドルを複製する必要はないと思います。 ProcessStartInfoオブジェクトにユーザー名、ドメイン、およびパスワードを設定するだけです。これは.NET 3.0以降では正しく使用されています。

EDIT:詳細については、また

、これはあなたがProcessStartInfoにユーザー名/ドメイン/パスワードを与えたときに、本当に何が起こるかです:http://support.microsoft.com/kb/165194。アクセスが拒否された理由は、おそらくユーザーのデスクトップまたはウィンドウステーションにアクセスできないからです。 LoginUserを呼び出すだけでは不十分です。

4

それは一部の人のために奇妙であるかもしれない、私の謝罪は、私は、Linuxの開発者... 検査済み午前:

/// <summary> 
    /// Class that deals with another username credentials 
    /// </summary> 
    class Credentials 
    { 
     /// <summary> 
     /// Constructor of SecureString password, to be used by RunAs 
     /// </summary> 
     /// <param name="text">Plain password</param> 
     /// <returns>SecureString password</returns> 
     private static SecureString MakeSecureString(string text) 
     { 
      SecureString secure = new SecureString(); 
      foreach (char c in text) 
      { 
       secure.AppendChar(c); 
      } 

      return secure; 
     } 

     /// <summary> 
     /// Run an application under another user credentials. 
     /// Working directory set to C:\Windows\System32 
     /// </summary> 
     /// <param name="path">Full path to the executable file</param> 
     /// <param name="username">Username of desired credentials</param> 
     /// <param name="password">Password of desired credentials</param> 
     public static void RunAs(string path, string username, string password) 
     { 
      try 
      { 
       ProcessStartInfo myProcess = new ProcessStartInfo(path); 
       myProcess.UserName = username; 
       myProcess.Password = MakeSecureString(password); 
       myProcess.WorkingDirectory = @"C:\Windows\System32"; 
       myProcess.UseShellExecute = false; 
       Process.Start(myProcess); 
      } 
      catch (Win32Exception w32E) 
      { 
       // The process didn't start. 
       Console.WriteLine(w32E); 
      } 
     } 

    } 
2

は、あなただけのセキュリティで保護された文字列を読んで作るのを忘れてすることはできますか?私の方法は私のために正常に動作します:

Process proc = new Process 
     { 
      StartInfo = 
      { 
       CreateNoWindow = true, 
       UseShellExecute = false, 
       RedirectStandardOutput = true, 
       RedirectStandardInput = true, 
       FileName = "cmd.exe", 
       UserName = "user", 
       Domain = "myDomain", 
       Password = GetSecureString("Password"), 
       Arguments = "/c ipconfig"     
      } 
     }; 
     proc.Start(); 

GetSecureString()関数:

public static SecureString GetSecureString(string str) 
    { 
     SecureString secureString = new SecureString(); 
     foreach (char ch in str) 
     { 
      secureString.AppendChar(ch); 
     } 
     secureString.MakeReadOnly(); 
     return secureString; 
    } 
関連する問題