Есть два места на локальном компьютере, которые будут иметь членство в группе учетных записей домена: токен пользователя для домена \ компьютера $ и билет Kerberos для домена \ компьютера $. Всякий раз, когда локальному компьютеру нужен свой токен пользователя, он будет настроен как SYSTEM, а не домен \ компьютер $, так что это не вариант. Единственный способ получить токен пользователя из билета Kerberos домена \ компьютера $ - это запускаться от имени SYSTEM, так как вам нужен его ключ для расшифровки билета (вам также понадобится привилегия Действовать как часть операционной системы, и даже тогда я не знаю, как создать токен из билета).
Итак, вы должны запросить AD:
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
using System.Security.Principal;
using System.ComponentModel;
using System.DirectoryServices;
public static SecurityIdentifier[] GetLocalComputerGroups()
{
string sAMAccountName = PInvoke.GetSYSTEMsAMAccountName();
DirectorySearcher searcher = new DirectorySearcher("(sAMAccountName=" + sAMAccountName + ")");
DirectoryEntry entry = searcher.FindOne().GetDirectoryEntry();
entry.RefreshCache(new string[] { "tokenGroups" });
List<SecurityIdentifier> groupSids = new List<SecurityIdentifier>();
foreach(byte[] byteSid in entry.Properties["tokenGroups"])
{
groupSids.Add(new SecurityIdentifier(byteSid, 0));
}
return groupSids.ToArray();
}
public class PInvoke
{
public const int STATUS_SUCCESS = 0;
public static readonly IntPtr NULL = IntPtr.Zero;
public enum SECURITY_LOGON_TYPE
{
UndefinedLogonType = 0,
Interactive = 2,
Network,
Batch,
Service,
Proxy,
Unlock,
NetworkCleartext,
NewCredentials,
RemoteInteractive,
CachedInteractive,
CachedRemoteInteractive,
CachedUnlock
}
[StructLayout(LayoutKind.Sequential)]
public struct LARGE_INTEGER
{
public uint LowPart;
public int HighPart;
}
[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public uint LowPart;
public int HighPart;
public static LUID GetSYSTEMLuid()
{
return new LUID() { LowPart = 0x3E7, HighPart = 0 };
}
}
[StructLayout(LayoutKind.Sequential)]
public struct LSA_UNICODE_STRING
{
public ushort Length;
public ushort MaximumLength;
public IntPtr Buffer;
public override string ToString()
{
if (Buffer == NULL) return null;
return Marshal.PtrToStringUni(Buffer, Length / UnicodeEncoding.CharSize);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_LOGON_SESSION_DATA
{
public uint Size;
public LUID LogonId;
public LSA_UNICODE_STRING UserName;
public LSA_UNICODE_STRING LogonDomain;
public LSA_UNICODE_STRING AuthenticationPackage;
public SECURITY_LOGON_TYPE LogonType;
public uint Session;
public IntPtr Sid;
public LARGE_INTEGER LogonTime;
public LSA_UNICODE_STRING LogonServer;
public LSA_UNICODE_STRING DnsDomainName;
public LSA_UNICODE_STRING Upn;
}
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_LOGON_SESSION_Managed
{
public LUID LogonId;
public string UserName;
public string LogonDomain;
public string AuthenticationPackage;
public SECURITY_LOGON_TYPE LogonType;
public uint Session;
public SecurityIdentifier Sid;
public LARGE_INTEGER LogonTime;
public string LogonServer;
public string DnsDomainName;
public string Upn;
public SECURITY_LOGON_SESSION_DATA_Managed(IntPtr pSecurityLogonSessionData)
{
SECURITY_LOGON_SESSION_DATA data = (SECURITY_LOGON_SESSION_DATA)Marshal.PtrToStructure(pSecurityLogonSessionData, typeof(SECURITY_LOGON_SESSION_DATA));
this.LogonId = data.LogonId;
this.UserName = data.UserName.ToString();
this.LogonDomain = data.LogonDomain.ToString();
this.AuthenticationPackage = data.AuthenticationPackage.ToString();
this.LogonType = data.LogonType;
this.Session = data.Session;
this.Sid = new SecurityIdentifier(ConvertPSIDToString(data.Sid));
this.LogonTime = data.LogonTime;
this.LogonServer = data.LogonServer.ToString();
this.DnsDomainName = data.DnsDomainName.ToString();
this.Upn = data.Upn.ToString();
}
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LocalFree(IntPtr hMem);
[DllImport("advapi32.dll", SetLastError = true)]
protected static extern bool ConvertSidToStringSidW(IntPtr Sid, out IntPtr StringSid);
public static string ConvertPSIDToString(IntPtr pSid)
{
IntPtr pString;
if (ConvertSidToStringSidW(pSid, out pString))
{
try
{
return Marshal.PtrToStringUni(pString);
}
finally
{
LocalFree(pString);
}
}
else
{
throw new Win32Exception();
}
}
[DllImport("advapi32.dll")]
protected static extern int LsaNtStatusToWinError(uint Status);
public static Win32Exception NtStatusToWinException(uint ntstatus)
{
return new Win32Exception(LsaNtStatusToWinError(ntstatus);
}
[DllImport("secur32.dll")]
public static extern uint LsaFreeReturnBuffer(IntPtr Buffer);
[DllImport("secur32.dll")]
protected static extern uint LsaGetLogonSessionData(ref LUID LogonId, out IntPtr ppLogonSessionData);
public static SECURITY_LOGON_SESSION_DATA_Managed GetLogonSessionData(LUID logonId)
{
IntPtr pLogonSessionData;
uint ntstatus = LsaGetLogonSessionData(ref logonId, out pLogonSessionData);
if(ntstatus != STATUS_SUCCESS)
{
throw NtStatusToWinException(ntstatus);
}
try
{
return new SECURITY_LOGON_SESSION_DATA_Managed(pLogonSessionData);
}
finally
{
LsaFreeReturnBuffer(pLogonSessionData);
}
}
public static string GetSYSTEMsAMAccountName()
{
LUID systemLuid = LUID.GetSYSTEMLuid();
SECURITY_LOGON_SESSION_DATA_Managed systemData = GetLogonSessionData(systemLuid);
return systemData.UserName;
}
}