如何以编程方式确定用户帐户是否是Windows中特定组的成员?

时间:2022-04-13 16:46:27

Given a group name and a user account, I would like to know if the supplied user belongs to a particular group. The user can be a local user or a domain user and the group could be a local group or a domain group and the group could also be nested inside other groups. In short I am looking for a function like bool IsUserMemberOf(User, Group) that will internally call the appropriate Win32 APIs to do the search. I guess the process making the above query should have the necessary privileges to query local and AD groups. I guess runing the process under enterprise admin account should do the job of querying any DCs in the forest but may not work for machines that are not part of a domain. Any ideas on what account this querying process should run so that it can query the LSA as well as the AD?

给定组名称和用户帐户,我想知道提供的用户是否属于特定组。用户可以是本地用户或域用户,该组可以是本地组或域组,该组也可以嵌套在其他组中。总之,我正在寻找像bool IsUserMemberOf(User,Group)这样的函数,它将在内部调用相应的Win32 API来进行搜索。我想进行上述查询的过程应具有查询本地和AD组的必要权限。我想在企业管理员帐户下运行该流程应该完成查询林中任何DC的工作,但可能不适用于不属于域的计算机。有关此查询过程应该运行的任何想法,以便它可以查询LSA以及AD?

3 个解决方案

#1


You need to read up on GetTokenInformation (TOKEN_USER), AllocateAndInitializeSid and CheckTokenMemberShip.

您需要阅读GetTokenInformation(TOKEN_USER),AllocateAndInitializeSid和CheckTokenMemberShip。

#2


UserPrincipal.IsMemberOf(GroupPrincipal) "returns a Boolean value that specifies whether the principal is a member of the specified group".

UserPrincipal.IsMemberOf(GroupPrincipal)“返回一个布尔值,指定主体是否是指定组的成员”。

#3


Magnus is right, you must use CheckTokenMembership

马格努斯是对的,你必须使用CheckTokenMembership

You can find a sample in UnlockPolicy.c (download the full source here), function ShouldUnlockForUser and UsagerEstDansGroupe (excuse my French;).

您可以在UnlockPolicy.c中找到一个示例(在这里下载完整的源代码),函数ShouldUnlockForUser和UsagerEstDansGroupe(请原谅我的法语;)。

Here is the guts of it :

以下是它的内容:

HRESULT IsUserInGroup(HANDLE user, const wchar_t* groupe)
{
    HRESULT result = E_FAIL;
    SID_NAME_USE snu;
    WCHAR szDomain[256];
    DWORD dwSidSize = 0;
    DWORD dwSize = sizeof szDomain / sizeof * szDomain;

    if ((LookupAccountNameW(NULL, groupe, 0, &dwSidSize, szDomain, &dwSize, &snu) == 0)
            && (ERROR_INSUFFICIENT_BUFFER == GetLastError()))
    {
        SID* pSid = (SID*)malloc(dwSidSize);

        if (LookupAccountNameW(NULL, groupe, pSid, &dwSidSize, szDomain, &dwSize, &snu))
        {
            BOOL b;

            if (CheckTokenMembership(user, pSid, &b))
            {
                if (b == TRUE)
                {
                    result = S_OK;
                }
            }
            else
            {
                result = S_FALSE;
            }
        }

        //Si tout vas bien (la presque totalitée des cas), on delete notre pointeur
        //avec le bon operateur.
        free(pSid);
    }

    return result;
}

#1


You need to read up on GetTokenInformation (TOKEN_USER), AllocateAndInitializeSid and CheckTokenMemberShip.

您需要阅读GetTokenInformation(TOKEN_USER),AllocateAndInitializeSid和CheckTokenMemberShip。

#2


UserPrincipal.IsMemberOf(GroupPrincipal) "returns a Boolean value that specifies whether the principal is a member of the specified group".

UserPrincipal.IsMemberOf(GroupPrincipal)“返回一个布尔值,指定主体是否是指定组的成员”。

#3


Magnus is right, you must use CheckTokenMembership

马格努斯是对的,你必须使用CheckTokenMembership

You can find a sample in UnlockPolicy.c (download the full source here), function ShouldUnlockForUser and UsagerEstDansGroupe (excuse my French;).

您可以在UnlockPolicy.c中找到一个示例(在这里下载完整的源代码),函数ShouldUnlockForUser和UsagerEstDansGroupe(请原谅我的法语;)。

Here is the guts of it :

以下是它的内容:

HRESULT IsUserInGroup(HANDLE user, const wchar_t* groupe)
{
    HRESULT result = E_FAIL;
    SID_NAME_USE snu;
    WCHAR szDomain[256];
    DWORD dwSidSize = 0;
    DWORD dwSize = sizeof szDomain / sizeof * szDomain;

    if ((LookupAccountNameW(NULL, groupe, 0, &dwSidSize, szDomain, &dwSize, &snu) == 0)
            && (ERROR_INSUFFICIENT_BUFFER == GetLastError()))
    {
        SID* pSid = (SID*)malloc(dwSidSize);

        if (LookupAccountNameW(NULL, groupe, pSid, &dwSidSize, szDomain, &dwSize, &snu))
        {
            BOOL b;

            if (CheckTokenMembership(user, pSid, &b))
            {
                if (b == TRUE)
                {
                    result = S_OK;
                }
            }
            else
            {
                result = S_FALSE;
            }
        }

        //Si tout vas bien (la presque totalitée des cas), on delete notre pointeur
        //avec le bon operateur.
        free(pSid);
    }

    return result;
}