Как программно выяснить, является ли учетная запись пользователя членом определенной группы в Windows?
Учитывая имя группы и учетную запись пользователя, я хотел бы знать, принадлежит ли предоставленный пользователь к определенной группе. Пользователь может быть локальным пользователем или пользователем домена, а группа может быть локальной группой или группой домена, и группа также может быть вложенной в другие группы. Короче ищу такую функцию как bool IsUserMemberOf(User, Group)
это вызовет внутренние API-интерфейсы Win32 для поиска. Я предполагаю, что процесс, выполняющий вышеупомянутый запрос, должен иметь необходимые привилегии для запроса локальных групп и групп AD. Я полагаю, что запуск процесса под учетной записью администратора предприятия должен выполнять работу с любыми контроллерами домена в лесу, но может не работать на машинах, которые не являются частью домена. Любые идеи о том, какой учет должен выполнять этот процесс запросов, чтобы он мог запрашивать как LSA, так и AD?
3 ответа
Вам нужно прочитать информацию GetTokenInformation (TOKEN_USER), AllocateAndInitializeSid и CheckTokenMemberShip.
UserPrincipal.IsMemberOf (GroupPrincipal) "возвращает логическое значение, которое указывает, является ли принципал членом указанной группы".
Магнус прав, вы должны использовать CheckTokenMembership
Вы можете найти образец в UnlockPolicy.c (скачать полный исходный код здесь), функция ShouldUnlockForUser
а также UsagerEstDansGroupe
(простите за мой французский;).
Вот его внутренности:
HRESULT IsUserInGroup(HANDLE user, const wchar_t* groupe)
{
HRESULT result = E_FAIL;
SID_NAME_USE snu;
WCHAR szDomain[256];
DWORD dwSidSize = 0;
DWORD dwSize = sizeof szDomain / sizeof * szDomain;
if ((LookupAccountNameW(NULL, groupe, 0, &dwSidSize, szDomain, &dwSize, &snu) == 0)
&& (ERROR_INSUFFICIENT_BUFFER == GetLastError()))
{
SID* pSid = (SID*)malloc(dwSidSize);
if (LookupAccountNameW(NULL, groupe, pSid, &dwSidSize, szDomain, &dwSize, &snu))
{
BOOL b;
if (CheckTokenMembership(user, pSid, &b))
{
if (b == TRUE)
{
result = S_OK;
}
}
else
{
result = S_FALSE;
}
}
//Si tout vas bien (la presque totalitée des cas), on delete notre pointeur
//avec le bon operateur.
free(pSid);
}
return result;
}