Почему функция WinAPI :: NetUserGetLocalGroups () не возвращает все группы? - PullRequest
0 голосов
/ 01 апреля 2019

У меня есть пользователь DOMAIN\User.Name, который соответствует whoami /GROUPS в более чем 200 группах доменов Windows.

Когда я пытаюсь определить все группы для этого пользователя, используя функцию WinAPI :: NetUserGetLocalGroups ()Я получаю только 27 групп для указанного пользователя:

#include <windows.h> 
#include <lm.h>
#include <string>

int main()
{
  //query the domain server for the groups of the user
  LPGROUP_USERS_INFO_0 pBuf = NULL;
  DWORD dwLevel = 0;
  DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
  DWORD dwEntriesRead = 0;
  DWORD dwTotalEntries = 0;
  NET_API_STATUS nStatus = MAX_NERR;

  std::wstring serverName(L"\\\\MyDomainNameDns");
  std::wstring userName(L"DOMAIN\\user.name");

  nStatus = ::NetUserGetLocalGroups(serverName.c_str(),
    userName.c_str(),
    dwLevel,
    LG_INCLUDE_INDIRECT,
    reinterpret_cast<PBYTE*>(&pBuf),
    dwPrefMaxLen,
    &dwEntriesRead,
    &dwTotalEntries);
}

dwTotalEntries - это 27, а nStatus - это 0, поэтому я не выбираю только часть всех групп.Также я попытался использовать ::NetUserGetGroups() вместо этого, но безуспешно.

ПРИМЕЧАНИЕ. Использование функциональности .NET System.Security.Principal.WindowsIdentity.GetCurrent().Groups действительно дает мне все группы.

В чем может быть причина, по которой NetUserGetLocalGroups этого не делаетвернуть получить все группы как whoami или .NET / WindowsIdentity?В чем может быть разница между возвращенными / не возвращенными группами?

1 Ответ

0 голосов
/ 02 апреля 2019

После еще нескольких копаний я нашел следующее утверждение в обсуждении группы пользователей Windows :

На самом деле, NetUserGetLocalGroups / NetUserGetGroups не обрабатывать вложенные или универсальные группы в Windows 2000 родные домены. Перечисление SID из токена единственный надежный способ.

Итак, другими словами, используйте ::NetUserGetLocalGroups / NetUserGetGroups, если хотите прямое членство в группе. Если вы хотите узнать, кто является владельцем группы, чтобы выяснить, имеет ли пользователь право что-либо делать, используйте способ токена / SID (например, используя ::OpenProcessToken, ::GetTokenInformation и ::LookupAccountSid).

Пример

Пользователь находится в (доменной локальной) группе Employee. Все сотрудники имеют доступ к зданию с помощью карточки-ключа, поэтому группа Employe является членом группы HasBuildingAccess (локальный домен).

Если вы хотите узнать, входит ли пользователь (напрямую) в группу Employee, используйте ::NetUserGetLocalGroups. Он содержит группу Employee, но не группу HasBuildingAccess.

Если вы хотите узнать, имеет ли пользователь право на доступ к зданию, перечислите SID из токена. Он будет содержать группу HasBuildingAccess.

...