I am trying to figure out whether the current windows user either is local administrator or can use UAC to "attain" that group membership.
What I've come up so far looks like this:
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);
This solution takes a few milliseconds to compute. Much faster than the System.DirectoryServices.AccountManagement based approach I tried before.
There is one last thing that bothers me, though. I have to translate the SecurityIdentifier of the admin group to the name. There ought to be a way to get the DirectoryEntry directly by using the SID. According to Google, this should work:
string path = "LDAP://<SID=" + adminIdentifier.ToString() + ">";
However, this does not seem to work. Any idea how the syntax should look like?