C++의 액세스 토큰에서 SID 검색
다음 예제에서는 OpenProcessToken 및 GetTokenInformation 함수를 사용하여 액세스 토큰의 그룹 멤버 자격을 가져옵니다. 그런 다음 AllocateAndInitializeSid 함수를 사용하여 로컬 컴퓨터에 대한 관리자 그룹의 잘 알려진 SID를 식별하는 SID를 만듭니다. 다음으로 EqualSid 함수를 사용하여 잘 알려진 SID와 액세스 토큰의 그룹 SID를 비교합니다. SID가 토큰에 있는 경우 함수는 SID의 특성을 확인하여 사용하도록 설정되었는지 여부를 확인합니다.
CheckTokenMembership 함수를 사용하여 지정된 SID가 액세스 토큰에 있는지 여부를 확인해야 합니다. 이 함수는 활성 그룹 멤버 자격의 잠재적인 잘못된 해석을 제거합니다.
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "advapi32.lib")
#define MAX_NAME 256
BOOL SearchTokenGroupsForSID (VOID)
{
DWORD i, dwSize = 0, dwResult = 0;
HANDLE hToken;
PTOKEN_GROUPS pGroupInfo;
SID_NAME_USE SidType;
char lpName[MAX_NAME];
char lpDomain[MAX_NAME];
PSID pSID = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
// Open a handle to the access token for the calling process.
if (!OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken ))
{
printf( "OpenProcessToken Error %u\n", GetLastError() );
return FALSE;
}
// Call GetTokenInformation to get the buffer size.
if(!GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize))
{
dwResult = GetLastError();
if( dwResult != ERROR_INSUFFICIENT_BUFFER ) {
printf( "GetTokenInformation Error %u\n", dwResult );
return FALSE;
}
}
// Allocate the buffer.
pGroupInfo = (PTOKEN_GROUPS) GlobalAlloc( GPTR, dwSize );
// Call GetTokenInformation again to get the group information.
if(! GetTokenInformation(hToken, TokenGroups, pGroupInfo,
dwSize, &dwSize ) )
{
printf( "GetTokenInformation Error %u\n", GetLastError() );
return FALSE;
}
// Create a SID for the BUILTIN\Administrators group.
if(! AllocateAndInitializeSid( &SIDAuth, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pSID) )
{
printf( "AllocateAndInitializeSid Error %u\n", GetLastError() );
return FALSE;
}
// Loop through the group SIDs looking for the administrator SID.
for(i=0; i<pGroupInfo->GroupCount; i++)
{
if ( EqualSid(pSID, pGroupInfo->Groups[i].Sid) )
{
// Lookup the account name and print it.
dwSize = MAX_NAME;
if( !LookupAccountSid( NULL, pGroupInfo->Groups[i].Sid,
lpName, &dwSize, lpDomain,
&dwSize, &SidType ) )
{
dwResult = GetLastError();
if( dwResult == ERROR_NONE_MAPPED )
strcpy_s (lpName, dwSize, "NONE_MAPPED" );
else
{
printf("LookupAccountSid Error %u\n", GetLastError());
return FALSE;
}
}
printf( "Current user is a member of the %s\\%s group\n",
lpDomain, lpName );
// Find out whether the SID is enabled in the token.
if (pGroupInfo->Groups[i].Attributes & SE_GROUP_ENABLED)
printf("The group SID is enabled.\n");
else if (pGroupInfo->Groups[i].Attributes &
SE_GROUP_USE_FOR_DENY_ONLY)
printf("The group SID is a deny-only SID.\n");
else
printf("The group SID is not enabled.\n");
}
}
if (pSID)
FreeSid(pSID);
if ( pGroupInfo )
GlobalFree( pGroupInfo );
return TRUE;
}