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

#windows #winapi #usergroups

#Windows #winapi #группы пользователей

Вопрос:

У меня есть пользователь, DOMAINUser.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*>(amp;pBuf),
    dwPrefMaxLen,
    amp;dwEntriesRead,
    amp;dwTotalEntries);
}
  

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

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

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

Комментарии:

1. whoami /GROUPS возвращает группы из токена.

2. @RbMm Какой токен? Могу ли я получить одну (например, для вошедшего в систему пользователя) и получить группы, используя этот токен через WinAPI?

3. конечно, да. токен процесса. в какой задаче вызывается OpenProcessToken , а затем GetTokenInformation с TokenGroups помощью?

4. @RbMm Я смог получить токен процесса с помощью ::OpenProcessToken , получить информацию о токене с помощью ::GetTokenInformation и выполнить итерацию по идентификаторам группы, ища имя с помощью ::LookupAccountSid . Пока спасибо. Я все еще не понимаю, почему я вижу, что некоторые группы имеют только токен, в то время как я вижу только часть из них, когда не получаю токен и использую ::NetUserGetLocalGroups

5. это разные функции. с помощью GetTokenInformation вы смотрите, что на самом деле присвоено текущему пользовательскому токену. с NetUserGetLocalGroups помощью вы смотрите в постоянной базе данных sam. вопрос — что вам на самом деле нужно?

Ответ №1:

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

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

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

Пример

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

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

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