私がやろうとしているのは、ドメインアクセスにないマシンが、ドメイン資格情報を偽装してレジストリチェックツールを実行できるようにすることです....ドメイン上のどのマシンでも問題なく動作しますが、ドメイン外の誰かが間違ったユーザー名を取得し、ドメイン管理者アカウントを使用している場合でも、パスワード エラーが発生します。同じ資格情報、1 台のマシンだけがドメイン上にあり、もう 1 台はそうではありません。これが偽装を呼び出す私のコードです...(その下の偽装コード)
private void button1_Click(object sender, EventArgs e)
{
//Variables for Authentication
string userName;
userName = txtUser.Text;
string password;
password = txtPass.Text;
string domain;
domain = txtDomain.Text;
//Start Authentication
using ( new Impersonator( userName, domain, password ) )
{
//Clears last run result
txtResult.Clear();
//Begin Error Handling
try
{
//Variable for remote machine field
string remotemachine;
remotemachine = txtComputer.Text;
// hourglass cursor
Cursor.Current = Cursors.WaitCursor;
//Begin Code to check Registry
RegistryKey hive = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, remotemachine, RegistryView.Registry64);
var key = hive.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI");
if (key == null)
{
}
object oVal = key.GetValue("LastLoggedOnUser"); if (null != oVal)
{
txtResult.Text = oVal.ToString();
//End Registry Check
//Return Cursor
Cursor.Current = Cursors.Default;
}
}
catch (System.IO.IOException)
{
MessageBox.Show("You entered an invalid PC or the firewall is blocking you (Remote Registry Service must be running on remote host and the following ports must be open: TCP 445)", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
catch (System.NullReferenceException)
{
MessageBox.Show("This is not a Windows 7 Device", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
catch (System.UnauthorizedAccessException)
{
MessageBox.Show("Unauthorized Access, run app as Domain Admin or Machine is not on your Domain", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
catch (System.Security.SecurityException)
{
MessageBox.Show("Unauthorized Access, run app as Domain Admin or Machine is not on your Domain", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
catch (System.Exception excep)
{
MessageBox.Show(excep.GetType().ToString());
}
}
これが偽装ファイルです..
namespace Tools
{
using System;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.ComponentModel;
public class Impersonator :
IDisposable
{
#region Public methods.
// ------------------------------------------------------------------
public Impersonator(
string userName,
string domainName,
string password )
{
ImpersonateValidUser( userName, domainName, password );
}
// ------------------------------------------------------------------
#endregion
#region IDisposable member.
// ------------------------------------------------------------------
public void Dispose()
{
UndoImpersonation();
}
// ------------------------------------------------------------------
#endregion
#region P/Invoke.
// ------------------------------------------------------------------
[DllImport("advapi32.dll", SetLastError=true)]
private 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)]
private static extern int DuplicateToken(
IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
private static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private static extern bool CloseHandle(
IntPtr handle);
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
// ------------------------------------------------------------------
#endregion
#region Private member.
// ------------------------------------------------------------------
/// <summary>
/// Does the actual impersonation.
/// </summary>
/// <param name="userName">The name of the user to act as.</param>
/// <param name="domainName">The domain name of the user to act as.</param>
/// <param name="password">The password of the user to act as.</param>
private void ImpersonateValidUser(
string userName,
string domain,
string password )
{
WindowsIdentity tempWindowsIdentity = null;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
try
{
if ( RevertToSelf() )
{
if ( LogonUser(
userName,
domain,
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref token ) != 0 )
{
if ( DuplicateToken( token, 2, ref tokenDuplicate ) != 0 )
{
tempWindowsIdentity = new WindowsIdentity( tokenDuplicate );
impersonationContext = tempWindowsIdentity.Impersonate();
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
finally
{
if ( token!= IntPtr.Zero )
{
CloseHandle( token );
}
if ( tokenDuplicate!=IntPtr.Zero )
{
CloseHandle( tokenDuplicate );
}
}
}
/// <summary>
/// Reverts the impersonation.
/// </summary>
private void UndoImpersonation()
{
if ( impersonationContext!=null )
{
impersonationContext.Undo();
}
}
private WindowsImpersonationContext impersonationContext = null;