我想要做的是允许不在域访问中的机器通过模拟域凭据运行注册表检查工具......它适用于我域上的任何机器,但域外的任何人都会得到错误的用户名和密码错误,即使他们使用的是域管理员帐户。相同的凭据,只有一台机器在域上,而另一台不在。这是我调用模拟的代码...(下面的模拟代码)
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;