C++을 사용하여 권한 있는 작업 실행

특수 클라이언트 응용 프로그램은 권한 있는 작업을 호출할 수 있습니다. 예를 들어 응용 프로그램에서 관리자가 응답하지 않는 사무용 컴퓨터를 다시 부팅하도록 허용할 수 있습니다. WMI(Windows Management Instrumentation)를 사용하면 권한 있는 작업에 대해 WMI 공급자를 호출하여 권한 있는 작업을 실행할 수 있습니다.

다음 절차에서는 권한 있는 작업에 대해 공급자를 호출하는 방법을 설명합니다.

권한 있는 작업에 대해 공급자 호출하기

  1. 권한 있는 작업을 실행하는 클라이언트 프로세스에 대한 권한을 가져옵니다.

    일반적으로 관리자는 프로세스를 실행하기 전에 시스템 관리 도구를 사용하여 권한을 설정합니다.

  2. 권한 있는 작업을 사용하는 공급자 프로세스에 대한 권한을 가져옵니다.

    일반적으로 AdjustTokenPrivileges 함수를 호출하여 공급자 권한을 설정할 수 있습니다.

  3. 권한 있는 작업을 사용하는 클라이언트 프로세스에 대한 권한을 가져옵니다.

    이 단계는 공급자가 클라이언트에 로컬인 경우에만 필요합니다. 클라이언트와 공급자가 동일한 컴퓨터에 있는 경우 클라이언트는 다음 기술 중 하나를 사용하여 권한 있는 작업을 구체적으로 사용하도록 설정해야 합니다.

    • 클라이언트가 프로세스를 소유하는 경우 클라이언트는 AdjustTokenPrivileges를 사용하여 WMI를 호출하기 전에 프로세스 토큰을 조정할 수 있습니다. 이 경우 더 이상 코딩할 필요가 없습니다.
    • 클라이언트가 클라이언트 토큰에 액세스할 수 없는 경우 클라이언트는 다음 절차를 사용하여 스레드 토큰을 만들고 해당 토큰에서 AdjustTokenPrivileges를 사용할 수 있습니다.

다음 절차에서는 스레드 토큰을 만들고 해당 토큰에서 AdjustTokenPrivileges를 사용하는 방법을 설명합니다.

스레드 토큰을 만들고 해당 토큰에서 AdjustTokenPrivileges 사용하기

  1. ImpersonateSelf를 호출하여 프로세스 토큰의 복사본을 만듭니다.

  2. GetTokenInformation을 호출하여 새로 만든 스레드 토큰을 검색합니다.

  3. 새 토큰에서 AdjustTokenPrivileges를 호출하여 권한 있는 작업을 사용하도록 설정합니다.

  4. IWbemServices에 대한 포인터를 가져옵니다.

  5. CoSetProxyBlanket을 호출하여 IWbemServices에 대한 포인터를 은폐합니다.

  6. WMI 호출마다 1~5단계를 반복합니다.

    참고

    COM이 토큰을 잘못 캐시하기 때문에 단계를 반복해야 합니다.

     

이 항목의 코드 예제에서는 다음 #include 문을 올바르게 컴파일해야 합니다.

#include <wbemidl.h>

다음 코드 예제에서는 로컬 컴퓨터에서 권한을 사용하도록 설정하는 방법을 보여 줍니다.

// Get the privileges 
// The token has been obtained outside the scope of this code sample
// ================== 
DWORD dwLen;
bool bRes;
HANDLE hToken;

// obtain dwLen
bRes = GetTokenInformation(
  hToken, 
  TokenPrivileges, 
  NULL, 
  0,
  &dwLen
); 

BYTE* pBuffer = new BYTE[dwLen];
if(pBuffer == NULL)
{
  CloseHandle(hToken);
  return WBEM_E_OUT_OF_MEMORY;
} 

bRes = GetTokenInformation(
  hToken, 
  TokenPrivileges, 
  pBuffer,     
  dwLen,        
  &dwLen
);

if (!bRes)
{
  CloseHandle(hToken);
  delete [] pBuffer;
  return WBEM_E_ACCESS_DENIED;
} 

// Iterate through all the privileges and enable them all
// ====================================================== 
TOKEN_PRIVILEGES* pPrivs = (TOKEN_PRIVILEGES*)pBuffer;
for (DWORD i = 0; i < pPrivs->PrivilegeCount; i++)
{
  pPrivs->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED;
} 
// Store the information back in the token
// ========================================= 
bRes = AdjustTokenPrivileges(
  hToken, 
  FALSE, 
  pPrivs, 
  0, NULL, NULL
);

delete [] pBuffer;
CloseHandle(hToken); 

if (!bRes)
  return WBEM_E_ACCESS_DENIED;
else
  return WBEM_S_NO_ERROR;