【发布时间】:2009-04-04 11:57:26
【问题描述】:
我试图弄清楚当前的 windows 用户是本地管理员还是可以使用 UAC 来“获得”该组成员身份。
到目前为止,我的想法是这样的:
var adminIdentifier = new SecurityIdentifier("S-1-5-32-544");
var current = WindowsIdentity.GetCurrent();
bool isAdmin = current.Groups.Contains(adminIdentifier);
bool canBeAdmin = isAdmin;
if (!isAdmin)
{
var adminGroupName = adminIdentifier.Translate(typeof(NTAccount)).Value;
adminGroupName = adminGroupName.Substring(adminGroupName.LastIndexOf('\\'));
string path = "WinNT://./" + adminGroupName + ",group";
using (DirectoryEntry groupEntry = new DirectoryEntry(path))
{
foreach (object member in (IEnumerable)groupEntry.Invoke("Members"))
{
using (DirectoryEntry memberEntry = new DirectoryEntry(member))
{
object obVal = memberEntry.Properties["objectSid"].Value;
SecurityIdentifier sid = null;
if (null != obVal)
{
sid = new SecurityIdentifier((Byte[])obVal,0);
}
canBeAdmin = Equals(current.User, sid);
if (canBeAdmin)
break;
}
}
}
}
Console.WriteLine(canBeAdmin +" "+isAdmin);
此解决方案需要几毫秒的计算时间。比我之前尝试的基于 System.DirectoryServices.AccountManagement 的方法快得多。
不过,还有最后一件事让我感到困扰。我必须将管理组的 SecurityIdentifier 转换为名称。应该有办法得到 DirectoryEntry 直接使用 SID。根据谷歌的说法,这应该可行:
string path = "LDAP://<SID=" + adminIdentifier.ToString() + ">";
但是,这似乎不起作用。知道语法应该是什么样子吗?
【问题讨论】:
-
在我给出另一个答案之前有几个问题... a) 您使用的是什么版本的 Windows?,b) 您能否确认 adminIdentifier.ToString() 的计算结果为“S-1-5 -32-544", c) 查询 LDAP 时是否遇到任何特定错误?
-
a) Windows Vista Ultimate。 b) 是的。 c) 错误表示找不到指定的域。我的计算机不在任何域中,因此这可能是一个线索。但是,我需要一个无论计算机是否在域中都能正常工作的解决方案。
-
语法很好。我知道它有效,因为我也在使用它。我猜它不适用于 knownsids
标签: .net windows membership active-directory-group