스레드 로컬 관리자 계정 사용자 컨텍스트에 있는 실행 중인 여부를 확인하는 방법

기술 자료 번역 기술 자료 번역
기술 자료: 118626 - 이 문서가 적용되는 제품 보기.
모두 확대 | 모두 축소

이 페이지에서

요약

스레드가 로컬 관리자 계정에서 실행 중인지 여부를 확인하려면 스레드와 관련된 액세스 토큰을 검사할 수 있습니다. 이 문서에서는 이 작업을 수행하는 방법에 대해 설명합니다.

Windows 2000 및 이후 버전에서는 이 문서에서 설명하는 단계를 대신 CheckTokenMembership() API 를 사용할 수 있습니다. 자세한 내용은 Microsoft 플랫폼 SDK 설명서를 참조하십시오.

추가 정보

기본적으로 한 스레드에 연결된 토큰을 포함하는 프로세스의 있는 것입니다. 이 "사용자 컨텍스트는" 직접 스레드에 연결된 토큰에 의해 대체될 것입니다. 따라서 스레드의 사용자 컨텍스트를 확인하기 위해 사용자가 먼저 OpenThreadToken 함수 사용하여 스레드 토큰을 얻으려면 시도해야 합니다. 이 메서드는 실패합니다 및 ERROR_NO_TOKEN, OpenProcessToken 함수 사용하여 프로세스에 대한 토큰이 구하는 다음 GetLastError 함수를 보고합니다.

현재 사용자 토큰을 구한 후 AccessCheck 함수를 사용하여 사용자가 관리자인지 여부를 감지할 수 있습니다. 이렇게 하려면 다음과 같이 하십시오.
  1. 로컬 관리자 그룹에 대한 보안 식별자 (SID) AllocateAndInitializeSid 함수를 사용하여 만듭니다.
  2. 새 보안 설명자를 (SD) 함께 DACL (임의 액세스 제어 목록 (관리자 그룹의 SID가 포함된 액세스 제어 항목 (ACE))를 생성하십시오.
  3. 현재 사용자 및 사용자가 관리자인지 여부를 감지하려면 새로 생성된 SD 토큰으로 AccessCheck을 호출하십시오.
다음 샘플 코드에서는 로컬 컴퓨터의 관리자인지 사용자로 현재 스레드의 실행 여부를 테스트하려면 이 문서의 앞부분에 언급한 함수를 사용합니다.

예제 코드


#include <windows.h>
#include <stdio.h>
#include <lmcons.h>


BOOL IsCurrentUserLocalAdministrator(void);


void main(int argc, char **argv)
{
   if (IsCurrentUserLocalAdministrator())
      printf("You are an administrator\n");
   else
      printf("You are not an administrator\n");
}



/*-------------------------------------------------------------------------

-
IsCurrentUserLocalAdministrator ()

This function checks the token of the calling thread to see if the caller
belongs to the Administrators group.

Return Value:
   TRUE if the caller is an administrator on the local machine.
   Otherwise, FALSE.
--------------------------------------------------------------------------*

/
BOOL IsCurrentUserLocalAdministrator(void)
{
   BOOL   fReturn         = FALSE;
   DWORD  dwStatus;
   DWORD  dwAccessMask;
   DWORD  dwAccessDesired;
   DWORD  dwACLSize;
   DWORD  dwStructureSize = sizeof(PRIVILEGE_SET);
   PACL   pACL            = NULL;
   PSID   psidAdmin       = NULL;

   HANDLE hToken              = NULL;
   HANDLE hImpersonationToken = NULL;

   PRIVILEGE_SET   ps;
   GENERIC_MAPPING GenericMapping;

   PSECURITY_DESCRIPTOR     psdAdmin           = NULL;
   SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;


   /*
      Determine if the current thread is running as a user that is a member 

of
      the local admins group.  To do this, create a security descriptor 

that
      has a DACL which has an ACE that allows only local aministrators 

access.
      Then, call AccessCheck with the current thread's token and the 

security
      descriptor.  It will say whether the user could access an object if 

it
      had that security descriptor.  Note: you do not need to actually 

create
      the object.  Just checking access against the security descriptor 

alone
      will be sufficient.
   */
   const DWORD ACCESS_READ  = 1;
   const DWORD ACCESS_WRITE = 2;


   __try
   {

      /*
         AccessCheck() requires an impersonation token.  We first get a 

primary
         token and then create a duplicate impersonation token.  The
         impersonation token is not actually assigned to the thread, but is
         used in the call to AccessCheck.  Thus, this function itself never
         impersonates, but does use the identity of the thread.  If the 

thread
         was impersonating already, this function uses that impersonation 

context.
      */
      if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, 

TRUE, &hToken))
      {
         if (GetLastError() != ERROR_NO_TOKEN)
            __leave;

         if (!OpenProcessToken(GetCurrentProcess(), 

TOKEN_DUPLICATE|TOKEN_QUERY, &hToken))
            __leave;
      }

      if (!DuplicateToken (hToken, SecurityImpersonation, 

&hImpersonationToken))
          __leave;


      /*
        Create the binary representation of the well-known SID that
        represents the local administrators group.  Then create the 

security
        descriptor and DACL with an ACE that allows only local admins 

access.
        After that, perform the access check.  This will determine whether
        the current user is a local admin.
      */
      if (!AllocateAndInitializeSid(&SystemSidAuthority, 2,
                                    SECURITY_BUILTIN_DOMAIN_RID,
                                    DOMAIN_ALIAS_RID_ADMINS,
                                    0, 0, 0, 0, 0, 0, &psidAdmin))
         __leave;

      psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
      if (psdAdmin == NULL)
         __leave;

      if (!InitializeSecurityDescriptor(psdAdmin, 

SECURITY_DESCRIPTOR_REVISION))
         __leave;

      // Compute size needed for the ACL.
      dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) +
                  GetLengthSid(psidAdmin) - sizeof(DWORD);

      pACL = (PACL)LocalAlloc(LPTR, dwACLSize);
      if (pACL == NULL)
         __leave;

      if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2))
         __leave;

      dwAccessMask= ACCESS_READ | ACCESS_WRITE;

      if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, 

psidAdmin))
         __leave;

      if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE))
         __leave;

      /*
         AccessCheck validates a security descriptor somewhat; set the 

group
         and owner so that enough of the security descriptor is filled out 

to
         make AccessCheck happy.
      */
      SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);
      SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);

      if (!IsValidSecurityDescriptor(psdAdmin))
         __leave;

      dwAccessDesired = ACCESS_READ;

      /*
         Initialize GenericMapping structure even though you
         do not use generic rights.
      */
      GenericMapping.GenericRead    = ACCESS_READ;
      GenericMapping.GenericWrite   = ACCESS_WRITE;
      GenericMapping.GenericExecute = 0;
      GenericMapping.GenericAll     = ACCESS_READ | ACCESS_WRITE;

      if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired,
                       &GenericMapping, &ps, &dwStructureSize, &dwStatus,
                       &fReturn))
      {
         fReturn = FALSE;
         __leave;
      }
   }
   __finally
   {
      // Clean up.
      if (pACL) LocalFree(pACL);
      if (psdAdmin) LocalFree(psdAdmin);
      if (psidAdmin) FreeSid(psidAdmin);
      if (hImpersonationToken) CloseHandle (hImpersonationToken);
      if (hToken) CloseHandle (hToken);
   }

   return fReturn;
}

속성

기술 자료: 118626 - 마지막 검토: 2006년 11월 21일 화요일 - 수정: 4.3
본 문서의 정보는 다음의 제품에 적용됩니다.
  • Microsoft Win32 Application Programming Interface?을(를) 다음과 함께 사용했을 때
    • Microsoft Windows NT 4.0
    • the operating system: Microsoft Windows 2000
    • the operating system: Microsoft Windows XP
키워드:?
kbmt kbapi kbhowto kbkernbase kbsecurity KB118626 KbMtko
기계 번역된 문서
중요: 본 문서는 전문 번역가가 번역한 것이 아니라 Microsoft 기계 번역 소프트웨어로 번역한 것입니다. Microsoft는 번역가가 번역한 문서 및 기계 번역된 문서를 모두 제공하므로 Microsoft 기술 자료에 있는 모든 문서를 한글로 접할 수 있습니다. 그러나 기계 번역 문서가 항상 완벽한 것은 아닙니다. 따라서 기계 번역 문서에는 마치 외국인이 한국어로 말할 때 실수를 하는 것처럼 어휘, 구문 또는 문법에 오류가 있을 수 있습니다. Microsoft는 내용상의 오역 또는 Microsoft 고객이 이러한 오역을 사용함으로써 발생하는 부 정확성, 오류 또는 손해에 대해 책임을 지지 않습니다. Microsoft는 이러한 문제를 해결하기 위해 기계 번역 소프트웨어를 자주 업데이트하고 있습니다.

피드백 보내기

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com