我正在尝试获取当前用户登录的计算机帐户的WindowsIdentity。
目前,我使用以下代码获取当前用户的组成员资格:
WindowsIdentity currentIdent = WindowsIdentity.GetCurrent();
foreach (IdentityReference indentity in currentGroups)
{
String groupName = indentity.Translate(typeof(NTAccount)).ToString();
}
这很好用,但我也需要对当前的计算机帐户执行相同操作,最好不要查询AD。
我相信我必须使用模仿来做这件事,但却无法找到方法。
答案 0 :(得分:1)
本地计算机上有两个具有其域帐户组成员身份的位置:domain \ computer $的用户令牌和域\ computer $的Kerberos票证。每当本地计算机需要其用户令牌时,它将被设置为SYSTEM,而不是domain \ computer $,因此这不是一个选项。从domain \ computer $ Kerberos票证获取用户令牌的唯一方法是以SYSTEM身份运行,因为您需要其密钥来解密票证(同样,您需要将Act作为操作系统权限的一部分,甚至然后我不知道如何从票证中创建令牌。
所以,你必须查询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;
}
}