none
Admin権限のユーザとパスワードがわかるから、そのフォルダのファイル情報を取得したり、ファイルを作成したい。 RRS feed

  • 質問

  • こんにちは。アべです。

    ファイルシステムに関する操作系のアプリケーションを作成しております。

    そこで、Windows Server 2000やWindows 2003 Serverなどの共有に対して
    ある操作(ファイル情報の取得やファイルの作成)を行いたいのですが、
    上手くいっておりません。

     ▼発生する例外
     System.IO.IOException はハンドルされませんでした。
       Message="ネットワーク パスが見つかりません。\r\n"
       Source="mscorlib"
       StackTrace:
            場所 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
            場所 System.IO.FileSystemInfo.get_CreationTimeUtc()
            場所 System.IO.FileSystemInfo.get_CreationTime()
            場所 WindowsApplication.Form1.button3_Click(Object sender, EventArgs e)
            ~割愛~

    原因は、その共有にアクセスするユーザ名とパスワードを指定していない
    からだということはわかっているのですが、どうやってプログラムから
    それらを指定すれば良いかわからず困っております。

    当方は苦肉の策で処理都度に、ユーザ名とパスワードを用いて、
    ネットワークドライブを作成して、そこで処理するという方法を
    編み出しましたが、それでは本来のコーディングではないと
    思っており、相談させていただきました。

    何かこの当りのユーザ名とパスワードを指定してFileInfoなどを
    作成する方法がありましたら、アドバイスをお願いします。

    すみませんが、よろしくお願いします。

     

    2006年6月19日 12:12

すべての返信

  • 偽装などを元に調べてみてください。

    2006年6月19日 12:47
  • 中博俊さん
    有難うございます。

    MSDNのサンプルを見て偽装が出来ました。

    ただし、ドメインに参加していないマシンは偽装が出来ませんでした、、、

    今回はドメインに参加していないWindows2000Serverに接続して処理をしたいのですが、この場合はどのように偽装すればよいのでしょうか?いろいろ調べてみたのですが、見つかりませんでした。

    イメージとしては、エクスプローラから、\\Server-Name\c$とやると
    ユーザ名とパスワードを聞いてきますが、それをプログラムから行い、
    ユーザ名とパスワードの情報で、\\Server-Name\c$のファイルを取得
    したいと考えております。

    ソース
    ---
    using System;
    using System.Runtime.InteropServices;
    using System.Security.Principal;
    using System.Security.Permissions;
    using System.Windows.Forms;

    [assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode = true)]
    [assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Name = "FullTrust")]
    public class ImpersonationDemo
    {
     [DllImport("advapi32.dll", SetLastError = true)]
     public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
      int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

     [DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
     private unsafe static extern int FormatMessage(int dwFlags, ref IntPtr lpSource,
      int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr* Arguments);

     [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
     public extern static bool CloseHandle(IntPtr handle);

     [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
     public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
      int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

     // Test harness.
     // If you incorporate this code into a DLL, be sure to demand FullTrust.
     [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
     public static void Main(string[] args)
     {
      IntPtr tokenHandle = new IntPtr(0);
      IntPtr dupeTokenHandle = new IntPtr(0);
      try
      {
       string userName, domainName;
       // Get the user token for the specified user, domain, and password using the
       // unmanaged LogonUser method. 
       // The local machine name can be used for the domain name to impersonate a user on this machine.
       Console.Write("Enter the name of the domain on which to log on: ");
       domainName = Console.ReadLine();

       Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", domainName);
       userName = Console.ReadLine();

       Console.Write("Enter the password for {0}: ", userName);

       const int LOGON32_PROVIDER_DEFAULT = 0;
       //This parameter causes LogonUser to create a primary token.
       const int LOGON32_LOGON_INTERACTIVE = 2;

       tokenHandle = IntPtr.Zero;

       // Call LogonUser to obtain a handle to an access token.
       bool returnValue = LogonUser(userName, domainName, Console.ReadLine(),
        LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
        ref tokenHandle);

       Console.WriteLine("LogonUser called.");

       if (false == returnValue)
       {
        int ret = Marshal.GetLastWin32Error();
        Console.WriteLine("LogonUser failed with error code : {0}", ret);
        throw new System.ComponentModel.Win32Exception(ret);
       }

       Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
       Console.WriteLine("Value of Windows NT token: " + tokenHandle);

       // Check the identity.
       Console.WriteLine("Before impersonation: "
        + WindowsIdentity.GetCurrent().Name);
       // Use the token handle returned by LogonUser.
       WindowsIdentity newId = new WindowsIdentity(tokenHandle);
       WindowsImpersonationContext impersonatedUser = newId.Impersonate();

       // Check the identity.
       Console.WriteLine("After impersonation: "
        + WindowsIdentity.GetCurrent().Name);

       // Stop impersonating the user.
       impersonatedUser.Undo();

       // Check the identity.
       Console.WriteLine("After Undo: " + WindowsIdentity.GetCurrent().Name);

       // Free the tokens.
       if (tokenHandle != IntPtr.Zero)
        CloseHandle(tokenHandle);

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

     }
    }


     

    2006年6月22日 6:20