我需要从远程注册表中读取一些键值。我使用了类Registry和RegistryKey,它在本地机器上运行良好。然后我在远程机器上尝试了,我只能接收基本密钥(HKLM,HKCU等),但我无法接收任何子密钥,因为我没有访问权限。我搜索谷歌并找到了Impersonation类和写入包装器。
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
namespace WindowsFormsApplication1
{
class ImpersonateClass
{
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
[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);
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
private string userName;
private string computerName;
private string password;
private IntPtr tokenHandle = IntPtr.Zero;
public ImpersonateClass(string aUserName, string aComputerName, string aPassword)
{
userName = aUserName;
computerName = aComputerName;
password = aPassword;
}
public WindowsImpersonationContext impersonateUser()
{
if (LogonUser(userName, computerName, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle))
{
Console.WriteLine("Value of Windows NT token: " + tokenHandle);
WindowsIdentity newId = new WindowsIdentity(tokenHandle);
return newId.Impersonate();
}
else
{
return null;
}
}
public void unimpersonateUser(ref WindowsImpersonationContext anImpersonatedUser)
{
if (anImpersonatedUser != null)
{
anImpersonatedUser.Undo();
}
}
}
}
主要课程
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Security.Principal;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void button_Click(object sender, EventArgs e)
{
ImpersonateClass impersonate = new ImpersonateClass(@"admministrator", "localMachine", "2.71828");
Console.WriteLine("before impersonation: "
+ WindowsIdentity.GetCurrent().Name);
this.output.Text += WindowsIdentity.GetCurrent().Name + "\r\n";
WindowsImpersonationContext tmpid = impersonate.impersonateUser();
Console.WriteLine("After impersonation: "
+ WindowsIdentity.GetCurrent().Name);
this.output.Text += WindowsIdentity.GetCurrent().Name + "\r\n";
impersonate.unimpersonateUser(ref tmpid);
Console.WriteLine("After unimpersonation: "
+ WindowsIdentity.GetCurrent().Name);
this.output.Text += WindowsIdentity.GetCurrent().Name + "\r\n";
}
}
}
如果Constructor的参数是“admministrator”,“localMachine”,“2.71828” 我有输出 LOCALMACHINE \用户 LOCALMACHINE \管理员 LOCALMACHINE \用户
如果Constructor的参数是“administrator”,“remoteMachine”,“2.71828” LOCALMACHINE \用户 LOCALMACHINE \管理员 LOCALMACHINE \用户
如果Constructor的参数是“remoteMachine \ admministrator”,“remoteMachine”,“2.71828” 程序返回
LOCALMACHINE \用户 LOCALMACHINE \用户 LOCALMACHINE \用户
密码正确并且在两台计算机上都创建了用户管理员
我无法理解为什么一个不能成为remoteMachine \ Administrator