윈도우8에 많은 것들이 변경됐습니다. 그 중에 하나가 UAC 정책입니다. 예전에 UAC를 끄면 UAC가 없는 것과 동일했는데 윈도우8 그게 변경됐습니다. 아예 없는 것이 아니라 관리자 권한 요구가 매니페스트에 포함된 프로그램에게는 사라지는 것과 동일한데 그렇지 않은 프로그램의 경우 UAC를 꺼도 그 프로그램은 일반 권한으로 실행됩니다. 프로그래밍이나 테스트 작업을 하는 사람에게는 조금 불편합니다. 완전히 꺼버리는 방법도 있는데 보안상 그닥 권해 드리고 싶지 않습니다. 관리자 권한으로 자주 사용하는 프로그램의 등록 정보에서 아래 항목을 체크하면 그 프로그램만 관리자 권한으로 실행할 수 있습니다.
종종 반대로 실행된 프로그램 입장에서 현재 실행된 프로세스가 관리자 권한으로 실행됐는지 아니면 일반 권한으로 실행됐는지를 체크할 필요가 있는 경우가 있는데요. 이때는 아래 코드에 나와 있는 것과 같이 프로세스 토큰을 사용해서 관리자 권한인지를 조회해 보면 됩니다.
관리자 권한 체크 코드 소스 코드 다운로드
typedef std::shared_ptr<void> vsptr;
BOOL
IsProcessUserAdmin(HANDLE process, BOOL *is_admin)
{
HANDLE token;
if(!OpenProcessToken(process, TOKEN_QUERY, &token))
return FALSE;
vsptr token_closer(token, ::CloseHandle);
ULONG gsize = 0;
if(!GetTokenInformation(token, TokenGroups, NULL, gsize, &gsize))
{
if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return FALSE;
}
std::vector<UCHAR> gbuffer;
gbuffer.resize(gsize);
PTOKEN_GROUPS ginfo = (PTOKEN_GROUPS) &gbuffer[0];
if(!GetTokenInformation(token, TokenGroups, ginfo, gsize, &gsize))
return FALSE;
PSID admin;
SID_IDENTIFIER_AUTHORITY auth = SECURITY_NT_AUTHORITY;
if(!AllocateAndInitializeSid(&auth
, 2
, SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ADMINS
, 0, 0, 0, 0, 0, 0
, &admin))
{
return FALSE;
}
vsptr sid_closer(admin, ::FreeSid);
for(ULONG i = 0; i < ginfo->GroupCount; ++i)
{
if(EqualSid(admin, ginfo->Groups[i].Sid))
{
*is_admin = TRUE;
return TRUE;
}
}
*is_admin = FALSE;
return TRUE;
}
int main()
{
BOOL is_admin = FALSE;
if(!IsProcessUserAdmin(GetCurrentProcess(), &is_admin))
return 0;
printf("%s\n", is_admin ? "admin" : "not admin");
return 0;
}