确定用户是否在本地管理员组中

我的问题

我正在使用PInvoked Windows API函数来validation用户是否属于本地管理员组。 我正在使用GetCurrentProcessOpenProcessTokenGetTokenInformationLookupAccountSid来validation用户是否是本地管理员。

GetTokenInformation返回一个TOKEN_GROUPS结构数组的SID_AND_ATTRIBUTES结构。 我遍历集合并比较LookupAccountSid返回的用户名。

我的问题是,在本地(或更普遍地在我们的内部域),这可以按预期工作。 内置\ Administrators位于当前进程令牌的组成员身份中,我的方法返回true。 在另一个开发人员的另一个域上,该函数返回false。

LookupAccountSidTOKEN_GROUPS结构的前2次迭代中正常运行,返回None和Everyone,然后TOKEN_GROUPS地抱怨“A参数不正确”。

什么会导致只有两组正常工作?

TOKEN_GROUPS结构表示有14个组。 我假设它是无效的SID。

我所拥有的一切都是PInvoke 网站上的一个例子。 唯一的区别是,使用LookupAccountSid我已将Sid参数从byte[]更改为IntPtr因为SID_AND_ATTRIBUTES也是使用IntPtr定义的。 这是正确的,因为LookupAccountSid是用PSID定义的吗?

LookupAccountSid PInvoke

  [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern bool LookupAccountSid( string lpSystemName, IntPtr Sid, StringBuilder lpName, ref uint cchName, StringBuilder ReferencedDomainName, ref uint cchReferencedDomainName, out SID_NAME_USE peUse); 

代码落空的地方

  for (int i = 0; i < usize; i++) { accountCount = 0; domainCount = 0; //Get Sizes LookupAccountSid(null, tokenGroups.Groups[i].SID, null, ref accountCount, null, ref domainCount, out snu); accountName2.EnsureCapacity((int) accountCount); domainName.EnsureCapacity((int) domainCount); if (!LookupAccountSid(null, tokenGroups.Groups[i].SID, accountName2, ref accountCount, domainName, ref domainCount, out snu)) { //Finds its way here after 2 iterations //But only in a different developers domain var error = Marshal.GetLastWin32Error(); _log.InfoFormat("Failed to look up SID's account name. {0}", new Win32Exception(error).Message); continue; } 

如果需要更多代码,请告诉我。 任何帮助将不胜感激。

听起来你正试图复制NetUserGetLocalGroups的function。 您还可以使用信息级别为1的NetUserGetInfo ,并在USER_INFO_1中检查USER_PRIV_ADMINusri1_priv的值。

我不确定NetUserGetLocalGroups是否知道拒绝SID(如果您需要validation当前进程(不是用户帐户!)是否在管理组中,则必须处理拒绝SID)

如果你只需要支持2000及更高版本,PInvoke CheckTokenMembership (那个MSDN页面有一个IsUserAdmin示例函数)

在NT4上,您需要从GetTokenInformation获取TokenGroups数组,但是您不需要调用LookupAccountSid,只需在每个项目上调用EqualSid,并将其与您使用AllocateAndInitializeSid创建的管理组SID(…,SECURITY_BUILTIN_DOMAIN_RID,…)进行比较