Я пытаюсь выяснить, является ли текущий пользователь 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. По словам Google, это должно работать:
string path = "LDAP://<SID=" + adminIdentifier.ToString() + ">";
Однако это не похоже на работу. Любая идея, как должен выглядеть синтаксис?