【问题标题】:Identifying if a user is in the local administrators group识别用户是否在本地管理员组中
【发布时间】:2010-06-17 17:54:06
【问题描述】:

我的问题

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

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

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

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

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

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

我 PInvoke 的所有内容均来自 PInvoke website 上的示例。唯一的区别是使用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;
                    }

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

【问题讨论】:

    标签: c# .net winapi pinvoke


    【解决方案1】:

    听起来您正在尝试复制NetUserGetLocalGroups 的功能。您也可以使用NetUserGetInfo,信息级别为1,并在USER_INFO_1 中检查usri1_priv 的值是否为USER_PRIV_ADMIN

    【讨论】:

      【解决方案2】:

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

      如果只需要支持2000及以后,PInvokeCheckTokenMembership(那个MSDN页面有IsUserAdmin示例功能)

      在 NT4 上,您需要从 GetTokenInformation 获取 TokenGroups 数组,但您不需要调用 LookupAccountSid,您只需在每个项目上调用 EqualSid 并将其与您使用 AllocateAndInitializeSid(...,SECURITY_BUILTIN_DOMAIN_RID,. ..)

      【讨论】:

      • 酷。很高兴知道。我一定会调查的。
      猜你喜欢
      • 2021-03-13
      • 1970-01-01
      • 2014-03-02
      • 1970-01-01
      • 2014-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-02
      相关资源
      最近更新 更多