2010-08-23 19 views

Respuesta

-1

Puede probar este trozo de código. Se da un esbozo de lo que hay que hacer:

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

Este código es la forma NT4 de comprobar si un SID forma parte de un token de usuario, no funciona correctamente en los sistemas más nuevos y no debe utilizarse. Vea el enlace SO de Rup para mi respuesta y a qué función llamar ... – Anders

+0

@Anders: Funciona en Windows XP, Windows Vista y Windows 7 con seguridad. Este código fue probado bastante extensamente en estos tres sistemas. ¿Por qué crees que no funcionaría? –

+1

SÉ que está roto, por lo que simplemente no se realizó la prueba correctamente. Hay una cosa llamada SID de denegación exclusiva y su código actual no los maneja; se supone que debe usar CheckTokenMembership. – Anders

2

Este código resuelve su problema. Sientase libre de usarlo. Funciona con 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); 
} 
Cuestiones relacionadas