【发布时间】:2015-04-01 04:29:28
【问题描述】:
自助服务密码重置网站。对于某些操作,我冒充在域中具有帐户操作员权限的技术用户。它可以在我的笔记本电脑上完美运行,我可以更改用户密码、解锁帐户或查询所有锁定帐户的域。
直到大约 2 周前,它甚至还可以在服务器上运行。我试图调查我们的环境机器人的变化,没有人知道任何可能对此产生影响的变化。
最好的部分是我根本没有错误消息。 Marshal.GetLastWin32Error() 返回零,基本上是“一切正常”。
这是发生模拟的代码:
#region accountManagement
[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
WindowsImpersonationContext impersonationContext;
private bool impersonateValidUser(String userName, String domain, String password)
{
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_BATCH = 4;
const int LOGON32_LOGON_SERVICE = 5;
const int LOGON32_LOGON_UNLOCK = 7;
const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
const int LOGON32_PROVIDER_DEFAULT = 0;
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
// Int32 result = LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token);
// Response.Write(">>> " + result.ToString());
if (LogonUserA(userName, domain, password, LOGON32_LOGON_UNLOCK, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}
private void undoImpersonation()
{
impersonationContext.Undo();
}
#endregion
这就是它的名字(不相关的部分被删除):
String iuUser = System.Configuration.ConfigurationManager.AppSettings["domain.accountop.user"];
String iuPass = System.Configuration.ConfigurationManager.AppSettings["domain.accountop.pass"];
String iuDomn = System.Configuration.ConfigurationManager.AppSettings["domain.name"];
if (impersonateValidUser(iuUser, iuDomn, iuPass))
{
try
{
email = user.Properties["mail"].Value.ToString();
user.Invoke("SetPassword", new object[] { pw1 });
user.Properties["LockOutTime"].Value = 0; //unlock account
user.CommitChanges();
user.Close();
undoImpersonation();
// clear form and redirect
pPopupSuccess.Visible = true;
hfSuccess.Value = "The account is unlocked now and the password has been reset successfully.";
}
catch (Exception ex)
{
Exception innerException = ex.InnerException;
DirectoryServicesCOMException exds = (DirectoryServicesCOMException)innerException;
String errorMessage = "<p><strong>Your password probably did not meet the requirements.</strong></p>";
errorMessage += "<p>" + System.Configuration.ConfigurationManager.AppSettings["domain.pwreqmessage"] + "</p>";
errorMessage += "<strong>Detailed error message:</strong><br />";
errorMessage += ex.Message;
errorMessage += "<br />";
errorMessage += ex.StackTrace;
if (innerException != null) {
errorMessage = errorMessage + innerException.Message;
}
pPopupError.Visible = true;
hfErrorMessage.Value = errorMessage;
}
}
else
{
// The impersonation failed. Include a fail-safe mechanism here.
pPopupError.Visible = true;
hfErrorMessage.Value = "<p>Impersonation error. Failed to elevate the rights to account operator. Please report this error to the Help Desk.</p>";
hfErrorMessage.Value += "<p>" + Marshal.GetLastWin32Error().ToString() + "</p>";
}
我一直得到的不是中间的异常,而是我自己在第二个代码段末尾的消息说模拟不成功。而 Marshal.GetLastWin32Error() 只是返回零。
这里可能出了什么问题,我如何才能获得有关正在发生的事情的更多信息?在我的开发 PC 上运行正常时,导致此代码失败的服务器上有什么不同?
【问题讨论】:
-
附加信息:我的笔记本电脑和服务器都不是我现在正在开发/测试的域的成员。但是这些域是受信任的。
标签: c# asp.net active-directory impersonation