本地计算机上有两个地方会拥有其域帐户组成员身份:域\computer$ 的用户令牌和域\computer$ 的 Kerberos 票证。每当本地计算机需要其用户令牌时,它将被设置为 SYSTEM,而不是 domain\computer$,所以这不是一个选项。从域\计算机$ 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;
}
}