【发布时间】:2012-06-29 18:28:27
【问题描述】:
我需要以管理员权限静默安装不同的设置。 我必须对权限进行硬编码,因为用户不知道用户名和密码来自行安装设置。
我尝试了两种不同的方法。
- ProcessStartInfo 的用户名、密码和 UseShellExecute = false。
-
用户模拟
[DllImport("advapi32.dll", SetLastError = true)] private static extern bool LogonUser(...);
在这两种情况下windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator) 返回 false
由于权限不足,我的设置无法运行。
奇怪的行为:LogonUser 总是返回 true,即使凭据无效。
这是模拟类:
namespace BlackBlade.Utilities
{
/// <summary>
/// Quelle: http://www.blackbladeinc.com/en-us/community/blogs/archive/2009/08/10/runas-in-c.aspx
/// </summary>
public class SecurityUtilities
{
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
public delegate void RunAsDelegate();
public static void RunAs(RunAsDelegate methodToRunAs, string username, string password)
{
string userName;
string domain;
if (username.IndexOf('\\') > 0)
{
//a domain name was supplied
string[] usernameArray = username.Split('\\');
userName = usernameArray[1];
domain = usernameArray[0];
}
else
{
//there was no domain name supplied
userName = username;
domain = ".";
}
RunAs(methodToRunAs, userName, password, domain);
}
public static void RunAs(RunAsDelegate methodToRunAs, string username, string password, string domain)
{
IntPtr userToken;
WindowsIdentity adminIdentity = null;
WindowsImpersonationContext adminImpersonationContext = null;
try
{
if (LogonUser(username, string.IsNullOrEmpty(domain) ? "." : domain, password, 9, 0, out userToken))
{
//the impersonation suceeded
adminIdentity = new WindowsIdentity(userToken);
adminImpersonationContext = adminIdentity.Impersonate();
// todo: Entfernen.
WindowsPrincipal p = new WindowsPrincipal(adminIdentity);
MessageBox.Show(p.IsInRole(WindowsBuiltInRole.Administrator).ToString());
//run the delegate method
//methodToRunAs();
}
else
throw new Exception(string.Format("Could not impersonate user {0} in domain {1} with the specified password.", username, domain));
}
catch (Exception se)
{
int ret = Marshal.GetLastWin32Error();
if (adminImpersonationContext != null)
adminImpersonationContext.Undo();
throw new Exception("Error code: " + ret.ToString(), se);
}
finally
{
//revert to self
if (adminImpersonationContext != null)
adminImpersonationContext.Undo();
}
}
}
}
【问题讨论】:
-
请给你的问题一个更有意义的标题!
-
感谢您让 SO 变得更好 :)
-
LogonUser 是正确的,即使对于无效凭据也返回 true,因为使用 NEW_CREDENTIALS 登录类型它实际上并没有登录提供的用户!它只是将凭据存储在调用用户令牌的副本中以用于网络操作(想想
net use /U)。如果要将用户登录到本地计算机,请使用 rdkleine 建议的 INTERACTIVE 登录类型。 -
根据您的 cmets,我必须对这个问题投反对票。你没有和用户详细说明情况。
-
但我描述了我想要的,但似乎没有人关心,并且描述了其他方式。我知道安全问题,但这是实际设置。
标签: c# .net impersonation runas