确定用户是否属于本地管理员组

发布于 2024-09-06 05:37:57 字数 2620 浏览 1 评论 0原文

我的问题

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

GetTokenInformation 返回一个 TOKEN_GROUPS 结构,其中包含 SID_AND_ATTRIBUTES 结构数组。我迭代该集合并比较由 LookupAccountSid 返回的用户名。

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

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

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

TOKEN_GROUPS 结构表明有 14 个组。我假设 SID 无效。

我 PInvoked 的所有内容均取自 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;
                    }

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

My Problem

I'm using PInvoked Windows API functions to verify if a user is part of the local administrators group. I'm utilizing GetCurrentProcess, OpenProcessToken, GetTokenInformationand LookupAccountSid to verify if the user is a local admin.

GetTokenInformation returns a TOKEN_GROUPS struct with an array of SID_AND_ATTRIBUTES structs. I iterate over the collection and compare the user names returned by LookupAccountSid.

My problem is that, locally (or more generally on our in-house domain), this works as expected. The builtin\Administrators is located within the group membership of the current process token and my method returns true. On another domain of another developer the function returns false.

The LookupAccountSid functions properly for the first 2 iterations of the TOKEN_GROUPS struct, returning None and Everyone, and then craps out complaining that "A Parameter is incorrect."

What would cause only two groups to work correctly?

The TOKEN_GROUPS struct indicates that there are 14 groups. I'm assuming it's the SID that is invalid.

Everything that I have PInvoked I have taken from an example on the PInvoke website. The only difference is that with the LookupAccountSid I have changed the Sid parameter from a byte[] to a IntPtr because SID_AND_ATTRIBUTESis also defined with an IntPtr. Is this ok since LookupAccountSid is defined with a 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);

Where the code falls over

                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;
                    }

If more code is needed let me know. Any help would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

開玄 2024-09-13 05:37:57

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

It sounds like you're trying to duplicate the functionality of NetUserGetLocalGroups. You can also use NetUserGetInfo with an information level of 1, and check the value of usri1_priv in the USER_INFO_1 for USER_PRIV_ADMIN.

可是我不能没有你 2024-09-13 05:37:57

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

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

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

I'm not sure if NetUserGetLocalGroups knows about deny SIDs (If you need to verify if the current process (not the user account!) is in the admin group, you have to handle deny SIDs)

If you only need to support 2000 and later, PInvoke CheckTokenMembership (That MSDN page has a IsUserAdmin example function)

On NT4 you need to get a TokenGroups array from GetTokenInformation, but you don't call LookupAccountSid, you just call EqualSid on every item and compare it to a admin group SID you create with AllocateAndInitializeSid(...,SECURITY_BUILTIN_DOMAIN_RID,...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文