How to tell if the current user is in administrators group programmatically
; https://learn.microsoft.com/en-us/archive/blogs/junfeng/how-to-tell-if-the-current-user-is-in-administrators-group-programmatically
기존에는 CheckTokenMembership API를 이용해서 현재 로그인한 계정이 관리자 그룹에 속해 있는지 알아내기 위해서 다음과 같은 예제 코드를 제시하고 있습니다.
BOOL IsUserAdmin(VOID)
{
BOOL b;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup;
b = AllocateAndInitializeSid(
&NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&AdministratorsGroup);
if(b)
{
if (!CheckTokenMembership( NULL, AdministratorsGroup, &b))
{
b = FALSE;
}
FreeSid(AdministratorsGroup);
}
return(b);
}
그런데, Vista에서는 "filtered user token"의 값으로 CheckTokenMembership에 의해 체크되기 때문에 정상적으로 검사가 안 될 테니, 대신에 다음과 같은 코드를 이용해서 확인을 하라고 합니다. (Windows SDK가 설치되어져 있어야 빌드가 됩니다.)
HRESULT IsUserAdmin(BOOL *pIsAdmin)
{
int b;
HANDLE hProcess = NULL;
HANDLE hProcessToken = NULL;
HANDLE hLinkedToken = NULL;
BOOL fIsAdmin = FALSE;
DWORD dwLength = 0;
OSVERSIONINFO osver = {sizeof(OSVERSIONINFO)};
HRESULT hr = S_OK;
*pIsAdmin = FALSE;
hProcess = GetCurrentProcess();
if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken))
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Exit;
}
char AdminSID[SECURITY_MAX_SID_SIZE];
dwLength = sizeof(AdminSID);
if(!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &AdminSID, &dwLength))
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Exit;
}
if (!CheckTokenMembership( NULL, &AdminSID, &fIsAdmin))
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Exit;
}
if (fIsAdmin)
{
*pIsAdmin = TRUE;
goto Exit;
}
if (!GetVersionEx(&osver))
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Exit;
}
if (osver.dwMajorVersion < 6)
{
goto Exit;
}
if (!GetTokenInformation( hProcessToken,
TokenLinkedToken,
(VOID*) &hLinkedToken,
sizeof(HANDLE),
&dwLength) )
{
b = GetLastError();
if ( b == ERROR_NO_SUCH_LOGON_SESSION
|| b == ERROR_PRIVILEGE_NOT_HELD)
{
goto Exit;
}
hr = HRESULT_FROM_WIN32(b); // a real error
goto Exit;
}
if (!CheckTokenMembership( hLinkedToken, &AdminSID, &fIsAdmin))
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Exit;
}
if (fIsAdmin)
{
*pIsAdmin = TRUE;
}
else
{
}
Exit:
if (hProcess)
{
CloseHandle(hProcess);
}
if (hProcessToken)
{
CloseHandle(hProcessToken);
}
if (hLinkedToken)
{
CloseHandle(hLinkedToken);
}
return hr;
}
[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]