2010-08-23 3 views

Antwort

-1

Sie könnten dieses Stück Code versuchen. Es gibt eine Skizze von dem, was getan werden muss:

const HANDLE hProcess = GetCurrentProcess(); 
if (hProcess==NULL) 
    return FAILURE; 

HANDLE hToken; 
const BOOL lR = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken); 
if (lR == NULL) 
    return FAILURE; 

PSID psidAdministrators; 
SID_IDENTIFIER_AUTHORITY x = SECURITY_NT_AUTHORITY; 
if (!AllocateAndInitializeSid(
    &x, 2, 
    SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, 
    &psidAdministrators)) 
    return FAILURE; 

bool isAdmin = false; //dummy init 
DWORD size; 
GetTokenInformation(hToken, TokenGroups, NULL, 0, &size); 
char* buffer = new char[size]; 
DWORD notUsed; 
if (!GetTokenInformation(hToken, TokenGroups, (void*)buffer, size, &notUsed)) 
    return FAILURE; 

TOKEN_GROUPS* ptgGroups = (TOKEN_GROUPS*)buffer; 
isAdmin = false; //until proven otherwise 
for (UINT32 i=0; i<ptgGroups->GroupCount; ++i) 
{ 
    if (EqualSid(psidAdministrators, ptgGroups->Groups[i].Sid)) 
    { 
     isAdmin = true; 
     break; 
    } 
} 

FreeSid(psidAdministrators); 
return isAdmin; 
+0

Dieser Code ist die NT4-Methode, mit der überprüft werden kann, ob eine SID Teil eines Benutzer-Tokens ist. Bei neueren Systemen funktioniert sie nicht korrekt und sollte nicht verwendet werden. Siehe Rup SO-Link für meine Antwort und welche Funktion zu rufen ... – Anders

+0

@Anders: Es funktioniert sicher unter Windows XP, Windows Vista und Windows 7. Dieser Code wurde auf diesen drei Systemen ziemlich ausführlich getestet. Warum denkst du, es würde nicht funktionieren? –

+1

Ich weiß, es ist kaputt, also haben Sie einfach nicht richtig getestet. Es gibt eine Sache, die SID nur verweigern genannt wird, und Ihr aktueller Code behandelt diese nicht, Sie sollten CheckTokenMembership verwenden. – Anders

2

Dieser Code löst Ihr Problem. Fühlen Sie sich frei, es zu benutzen. Es funktioniert mit SE_GROUP_USE_FOR_DENY_ONLY.

/** 
    IsGroupMember determines if the current thread or process has a token that contais a given and enabled user group. 

    Parameters 
    dwRelativeID: Defines a relative ID (par of a SID) of a user group (e.g. Administrators DOMAIN_ALIAS_RID_ADMINS (544) = S-1-5-32-544) 
    bProcessRelative: Defines whether to use the process token (TRUE) instead of the thread token (FALSE). If FALSE and no thread token is present 
    the process token will be used though. 
    bIsMember: Returns the result of the function. The value returns TRUE if the user is an enabled member of the group; otherwise FALSE. 

    Return Value 
    If the function succeeds, the return value is TRUE; otherwise FALSE. Call GetLastError for more information. 
*/ 
BOOL IsGroupMember(DWORD dwRelativeID, BOOL bProcessRelative, BOOL* pIsMember) 
{ 
    HANDLE hToken, hDupToken; 
    PSID pSid = NULL; 
    SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_NT_AUTHORITY; 

    if (!pIsMember) 
    { 
     SetLastError(ERROR_INVALID_USER_BUFFER); 
     return FALSE; 
    } 

    if (bProcessRelative || !OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_DUPLICATE, TRUE, &hToken)) 
    { 
     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &hToken)) 
     { 
      return FALSE; 
     } 
    } 

    if (!DuplicateToken(hToken, SecurityIdentification, &hDupToken)) 
    { 
     CloseHandle(hToken); 
     return FALSE; 
    } 

    CloseHandle(hToken); 
    hToken = hDupToken; 

    if (!AllocateAndInitializeSid(&SidAuthority, 2, 
      SECURITY_BUILTIN_DOMAIN_RID, dwRelativeID, 0, 0, 0, 0, 0, 0, 
      &pSid)) 
    { 
     CloseHandle(hToken); 
     return FALSE; 
    } 

    if (!CheckTokenMembership(hToken, pSid, pIsMember)) 
    { 
     CloseHandle(hToken); 
     FreeSid(pSid); 

     *pIsMember = FALSE; 
     return FALSE; 
    } 

    CloseHandle(hToken); 
    FreeSid(pSid); 

    return TRUE; 
} 

BOOL IsUserAdministrator(BOOL* pIsAdmin) 
{ 
    return IsGroupMember(DOMAIN_ALIAS_RID_ADMINS, FALSE, pIsAdmin); 
} 
Verwandte Themen