如何为AD组使用AllocateAndInitializeSid?

时间:2017-02-07 19:06:37

标签: c++ winapi visual-c++ active-directory

我想为域管理员组创建一个SID,并将其传递给CheckTokenMembership,以确定给定的AD用户是否属于该组。但是,我不太确定AllocateAndInitializeSid应使用哪些标识符权限和子权限。所有'工作'我到目前为止看到的例子只与当地团体打交道。

示例:

SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
PSID adminGroup;

AllocateAndInitializeSid(&ntAuthority,
                         2,
                         SECURITY_BUILTIN_DOMAIN_RID,
                         DOMAIN_ALIAS_RID_ADMINS,
                         0, 0, 0, 0, 0, 0,
                         &adminGroup);

应该使用哪些权限和子权限为AD Administrators组创建SID?我使用DOMAIN_GROUP_RID_ADMINS尝试DOMAIN_USER_RID_ADMINSECURITY_NT_AUTHORITY,但CheckTokenMembership始终报告给定用户不是该组不正确的成员。

任何有关在线文档的示例和指示都将不胜感激。

2 个答案:

答案 0 :(得分:2)

您可以LsaQueryInformationPolicy()PolicyDnsDomainInformation一起使用来检索计算机主域的SID。

或者,如果您知道要查询的帐户属于您感兴趣的域管理员组所在的域,则可以使用GetWindowsAccountDomainSid()从帐户SID中提取域SID。

获得域SID后,您可以使用CreateWellKnownSid()为Domain Admins组创建SID。使用WinAccountDomainAdminsSid选项。然后,只需按照您的建议调用CheckTokenMembership()即可。

答案 1 :(得分:0)

您可以枚举令牌组并检查您是否感兴趣SID

volatile UCHAR guz;

ULONG IsDomainAdmin(HANDLE hToken, PBOOL IsMember)
{
    ULONG cb = 0, rcb = 0x100, err;
    PVOID stack = alloca(guz);

    union {
        PVOID buf;
        PTOKEN_GROUPS ptg;
    };

    do 
    {
        if (cb < rcb)
        {
            cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
        }

        if (GetTokenInformation(hToken, TokenGroups, buf, cb, &rcb))
        {
            *IsMember = FALSE;

            if (ULONG GroupCount = ptg->GroupCount)
            {
                PSID_AND_ATTRIBUTES Groups = ptg->Groups;
                do 
                {
                    // S-1-5-21-domain-512
                    PSID Sid = Groups++->Sid;
                    PSID_IDENTIFIER_AUTHORITY psia = GetSidIdentifierAuthority(Sid);

                    static SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;

                    if (!memcmp(psia, &ntAuthority, sizeof(SID_IDENTIFIER_AUTHORITY)))
                    {
                        ULONG n = *GetSidSubAuthorityCount(Sid);

                        if (
                            1 < n &&
                            *GetSidSubAuthority(Sid, 0) == SECURITY_NT_NON_UNIQUE &&
                            *GetSidSubAuthority(Sid, n - 1) == DOMAIN_GROUP_RID_ADMINS
                            )
                        {
                            *IsMember = TRUE;

                            return NOERROR;
                        }
                    }

                } while (--GroupCount);
            }
            return NOERROR;
        }

    } while ((err = GetLastError()) == ERROR_INSUFFICIENT_BUFFER);

    return err;
}