1

私は、ローカル ドメインを介してファイルをコピーするアプリケーションに取り組んできました。Windows XP のアプリケーションで、まったく権限のないアカウントを使用してファイルをコピーしようとすると、権限のあるアカウントになりすまして、すべてが完全に行われます。しかし、Windows 7で上記と同じアカウントになりすましている同じアカウントを取得すると、アプリケーションは最初の行で「アクセスが拒否されました」を返します

Impersonate msdnで同じスニペット コードを使用しましたが、ここに fileSeeker 関数を使用したコードを示します。

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
        int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

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

    // Test harness. 
    // If you incorporate this code into a DLL, be sure to demand FullTrust.
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]

    public impersonateSetting(string userName, string domainName, string password, string pathToSeek)
    {
        SafeTokenHandle safeTokenHandle;
        try
        {

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

            // Call LogonUser to obtain a handle to an access token. 
            bool returnValue = LogonUser(userName, domainName, password,
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                out safeTokenHandle);

            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);
            }
            using (safeTokenHandle)
            {
                Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
                Console.WriteLine("Value of Windows NT token: " + safeTokenHandle);

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

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

                        fileRunner.fileSeeker(pathToSeek, true);

                    }
                }
                // Releasing the context object stops the impersonation 
                // Check the identity.
                Console.WriteLine("After closing the context: " + WindowsIdentity.GetCurrent().Name);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception occurred. " + ex.Message);
        }
    }
}

public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    private SafeTokenHandle()
        : base(true)
    {
    }

    [DllImport("kernel32.dll")]
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    [SuppressUnmanagedCodeSecurity]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool CloseHandle(IntPtr handle);

    protected override bool ReleaseHandle()
    {
        return CloseHandle(handle);
    }

ファイルシーカー関数:

    public static void fileSeeker(string paramFrom, bool copySub)
    {
        DirectoryInfo dir = new DirectoryInfo(paramFrom);
        DirectoryInfo[] dirs = dir.GetDirectories();

        try
        {
            FileInfo[] files = dir.GetFiles();
            foreach (FileInfo file in files)
            {
                    string temppath = Path.Combine(paramFrom, file.Name);
                    try
                    {
                        Console.WriteLine("Accessing: " + temppath);
                    }
                    catch
                    {
                        Console.WriteLine("Cant Access to " + temppath);
                    }
            }

            if (copySub)
            {
                foreach (DirectoryInfo subdir in dirs)
                {
                    string temppath = Path.Combine(paramFrom, subdir.Name);

                    fileSeeker(subdir.FullName, copySub);
                }
            }

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
        }

    }

}

ご協力いただきありがとうございます !

4

1 に答える 1

0

ここで失敗する場合は、偽装したアカウントに、これが実行されている Win7 マシンFileInfo[] files = dir.GetFiles();のパスへのアクセス許可がない可能性があります。このアカウントが最初にソース パスにアクセスできることを確認してください。偽装コードは問題ないようですdir

于 2013-07-15T16:41:03.683 に答える