#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
группу.