Получить SID всех групп участников, к которым принадлежит пользователь?

Я использую приведенный ниже фрагмент кода для получения SID владельца процесса, и здесь все в порядке, но как я могу получить хотя бы любой (и максимум каждый) SID членства, членом которого является владелец процесса?

PSID g_pSID;
BOOL GetCurrentProcessSID()
{
    DWORD dwSize = 0, dwError, dwResult = 0;
    HANDLE hToken;

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
    {
        printf("OpenProcessToken Error %u\n", GetLastError());
        return FALSE;
    }

    // Call GetTokenInformation to get the buffer size.
    TOKEN_USER tU;
    if (!GetTokenInformation(hToken, TokenUser, &tU, 0, &dwSize))
    {
        dwError = GetLastError();
        if (dwError != ERROR_INSUFFICIENT_BUFFER)
        {
            std::cout << "GetTokenInformation failed, error " << dwError;
            CloseHandle(hToken);
            return 0;
        }
    }

    PTOKEN_OWNER to = (PTOKEN_OWNER)LocalAlloc(LPTR, dwSize);
    if (!to)
    {
        dwError = GetLastError();
        std::cout << "LocalAlloc failed, error " << dwError;
        CloseHandle(hToken);
        return 0;
    }

    if (!GetTokenInformation(hToken, TokenOwner, to, dwSize, &dwSize))
    {
        dwError = GetLastError();
        std::cout << "GetTokenInformation failed, error " << dwError;
        LocalFree(to);
        CloseHandle(hToken);
        return 0;
    }

    g_pSID = to->Owner;
    return TRUE;
}

Кроме того, есть ли у меня какие-либо ошибки в фрагменте, кроме использования глобальной переменной, какие-либо предложения?


person Ivan Silkin    schedule 21.10.2019    source источник


Ответы (1)


Сначала вы используете TokenUser, чтобы получить размер буфера TokenInformation, а затем используете TokenOwner во втором вызывающем объекте. Не уверен, что вы действительно хотите. Есть хорошее объяснение.

TokenOwner — это часть токена, определяющая владельца по умолчанию для объектов, созданных процессом или потоком, работающим в контексте безопасности токена. TokenUser — это пользователь, которого представляет токен.

Кроме того, вы должны вызвать LocalFree(to) перед возвратом функции.

Если вы хотите получить групповые учетные записи, связанные с токеном. Вы можете получить его с помощью TokenGroups при звонке GetTokenInformation.

#define MAX_NAME 256
BOOL RetriveGroupSid(VOID)
{
    DWORD i, dwSize = 0, dwResult = 0;
    HANDLE hToken;
    PTOKEN_GROUPS pGroupInfo;
    SID_NAME_USE SidType;
    char lpName[MAX_NAME];
    char lpDomain[MAX_NAME];
    SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;

    // Open a handle to the access token for the calling process.

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
    {
        printf("OpenProcessToken Error %u\n", GetLastError());
        return FALSE;
    }

    // Call GetTokenInformation to get the buffer size.

    if (!GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize))
    {
        dwResult = GetLastError();
        if (dwResult != ERROR_INSUFFICIENT_BUFFER) {
            printf("GetTokenInformation Error %u\n", dwResult);
            return FALSE;
        }
    }

    // Allocate the buffer.

    pGroupInfo = (PTOKEN_GROUPS)GlobalAlloc(GPTR, dwSize);

    // Call GetTokenInformation again to get the group information.

    if (!GetTokenInformation(hToken, TokenGroups, pGroupInfo,
        dwSize, &dwSize))
    {
        printf("GetTokenInformation Error %u\n", GetLastError());
        return FALSE;
    }

    for (i = 0; i < pGroupInfo->GroupCount; i++)
    {
        dwSize = MAX_NAME;
        LPSTR sid;
        if (!ConvertSidToStringSid(pGroupInfo->Groups[i].Sid, &sid))
        {
            printf("ConvertSidToStringSid Error %u\n", GetLastError());
            return FALSE;
        }
        if (!LookupAccountSid(NULL, pGroupInfo->Groups[i].Sid,
            lpName, &dwSize, lpDomain,
            &dwSize, &SidType))
        {
            dwResult = GetLastError();
            if (dwResult == ERROR_NONE_MAPPED)
                strcpy_s(lpName, dwSize, "NONE_MAPPED");
            else
            {
                printf("LookupAccountSid Error %u\n", GetLastError());
                LocalFree(sid);
                return FALSE;
            }
        }
        printf("%s : %s\\%s \n", sid, lpDomain, lpName);


        // Find out whether the SID is enabled in the token.
        if (pGroupInfo->Groups[i].Attributes & SE_GROUP_ENABLED)
            printf("The group SID is enabled.\n");
        else if (pGroupInfo->Groups[i].Attributes &
            SE_GROUP_USE_FOR_DENY_ONLY)
            printf("The group SID is a deny-only SID.\n");
        else
            printf("The group SID is not enabled.\n");
        LocalFree(sid);

    }

    if (pGroupInfo)
        GlobalFree(pGroupInfo);
    return TRUE;
}

Для другого способа см. также извлечение всех групп a пользователь принадлежит… в C++

person Drake Wu    schedule 22.10.2019