Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)
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;
}



[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 12/22/2022]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

비밀번호

댓글 작성자
 




1  [2]  3  4  5  6  7  8 
NoWriterDateCnt.TitleFile(s)
173정성태4/12/201111211레지스트리 : 11. BHO를 IE와 탐색기에서 선택적으로 로드하고 싶다면?
172정성태4/1/201110165.NET : 44. ContextBoundObject
171정성태3/30/201110034.NET 4.0 : 1. ASP.NET WF4 / WCF and Async Calls
170정성태3/25/20119816.NET 3.0 : 5. WCF How To’s Index [2]
169정성태3/10/201111212.NET : 43. 열려진 소켓 포트를 소유한 Process ID 구하는 방법 [2]
165정성태10/20/201010813레지스트리 : 10. 탐색기의 특정 폴더에 대해 Webdev.WebServer40.exe 로 호스팅을 시작하는 메뉴 추가
164정성태10/11/201010066.NET : 42. Writing Windows Shell Extension with .NET Framework 4 (C#, VB.NET)
163정성태8/27/20108870.NET : 41. Writing Files from Low-Integrity Processes
162정성태8/24/20109032.NET : 40. Self STS
161정성태5/16/201011960.NET : 39. #SNMP - C# Based Open Source SNMP for .NET and Mono
160정성태5/11/20109002.NET : 38. How to get info from client certificates issued by a CA (C#)
159정성태4/30/20108868.NET : 37. How to write a VS2010 Extension using Statement Lambdas
158정성태12/20/200922828명령행 : 6. 배치 파일에서 현재 디렉터리 알아내는 방법 [1]
157정성태11/12/20099582.NET : 36. Dictionary&lt;,&gt; 개체 직렬화
156정성태11/10/200910737.NET : 35. UDP 패킷의 경유 IP 설정 (Source Routing)
155정성태11/4/20099375.NET : 34. MSDeploy 명령행에 대응되는 C# 코드 예제
154정성태7/13/20098909.NET 3.0 : 4. WCF - 연결 개체 닫기
153정성태6/29/20098284.NET : 33. Creating audio signals in .NET
152정성태1/6/20098907.NET 3.0 : 3. WPF - StatefulUserControlBase.cs
151정성태1/1/200911600.NET : 32. Wake-On-Lan C# 코드 [1]
150정성태12/12/20088257.NET 3.5 : 7. ETW / .NET Framework 3.5
149정성태12/3/20088694Win32 : 4. Using Windows Vista Built-In Double Buffering
148정성태11/25/20087641.NET : 31. ThreadPool.UnsafeQueueNativeOverlapped [1]
147정성태11/21/20086908.NET 3.5 : 6. ProcessGeneratedCode
146정성태10/29/20086807레지스트리 : 9. How to detect what .NET Framework X service pack is installed
145정성태5/6/20087051.NET : 30. XML Serializable Dictionary
1  [2]  3  4  5  6  7  8