[英]LookupAccountSid() throws System.AccessViolationException on Server 2016
几年来,我在托管的 C# 代码中使用了LookupAccountSid
的 pinvoke 实现。
在German Windows Server 2016
上,它在解析S-1-5-11
(经过身份验证的用户)时开始抛出System.AccessViolationException
,其中德国名称为:“NT-Authorität\Authentifizierte Benutzer”。
我测试了 3 种不同的实现以排除 pinvoke 错误。 他们都在同一个电话中抛出。
它们都抛出相同的异常,因此这可能是 api 中的一般问题。 可能是因为名称中的变音符号Ä
?
SO的类似问题
这个问题听起来很相似,但这不是我面临的问题。
我在早期项目中的经验
我在(2.)年前在 Windodws 7 / Server 2008 环境中使用了实现,没有任何问题,但不幸的是我目前没有这样的系统来验证我最近的代码。
类似报告的问题
我发现这个线程关于法语系统上的类似行为
我目前的解决方法是
ntAccountName = realSid.Translate(typeof(NTAccount)).ToString();
AdvApi32.LookupAccountName(systemName, ntAccountName, out foundSid, out domainName, out sidNameUse)
但是 sid.Translate(..) 在传递外国委托人时抛出,我不知道在其他情况下它有多可靠。
问题
LsaLookupSids
,因为它不返回 SID_NAME_USE 标志) 我使用Vanara 库和 @RbMm 的注释编写了以下内容,以使用LsaLookupSids
来模仿LookupAccountSid
功能。
private static NTStatus LookupAccountSid2([Optional] string lpSystemName, PSID lpSid, out string lpName,
out string lpReferencedDomainName, out SID_NAME_USE peUse)
{
lpName = lpReferencedDomainName = null;
peUse = default;
using var pol = LsaOpenPolicy(LsaPolicyRights.POLICY_LOOKUP_NAMES, lpSystemName);
var ret = LsaLookupSids2(pol, LsaLookupSidsFlags.LSA_LOOKUP_RETURN_LOCAL_NAMES, 1, new[] { lpSid }, out var refDom, out var names);
if (ret.Failed) return ret;
using (refDom)
using (names)
{
lpReferencedDomainName = refDom.ToStructure<LSA_REFERENCED_DOMAIN_LIST>().DomainList.First().Name;
var name = names.ToArray<LSA_TRANSLATED_NAME>(1)[0];
lpName = name.Name;
peUse = name.Use;
}
return ret;
}
对于那些不熟悉 vanara 库以及如何将SecurityIdentifier
转换为PSID
指针的人,这里是已接受答案的包装器。 要使用该库,只需获取 nuget package Vanara.AdvApi32
using Vanara.PInvoke;
public static bool LookupAccountSid2(string lpSystemName, SecurityIdentifier sid, out string samAccountName,
out string domainName, out AdvApi32.SID_NAME_USE useFlags)
{
using (AdvApi32.SafePSID safePSID = new AdvApi32.SafePSID(sid))
{
PSID lpSid = new PSID(safePSID);
/// call the actual implementation from: https://stackoverflow.com/a/65202841/1574221
return LookupAccountSid2(lpSystemName, lpSid, out samAccountName, out domainName, out useFlags);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.