2009-09-21 49 views
2

如何确定当前用户(运行我的应用程序的用户)是否具有管理权限(即,是管理员组的成员)?对于访问受限的用户,我需要以不同方式注册一些COM组件。我正在使用C++(WTL和Win32)。发现用户是否具有管理权限

+0

什么类型的管理员权限? – 2009-09-21 08:59:13

回答

4

在工作中,我们使用了Anders的方式,但几个月前我们的系统因为该功能而失败。现在我们用这个:

bool IsUserAdmin() 
{ 
    struct Data 
    { 
     PACL pACL; 
     PSID psidAdmin; 
     HANDLE hToken; 
     HANDLE hImpersonationToken; 
     PSECURITY_DESCRIPTOR  psdAdmin; 
     Data() : pACL(NULL), psidAdmin(NULL), hToken(NULL), 
      hImpersonationToken(NULL), psdAdmin(NULL) 
     {} 
     ~Data() 
     { 
      if (pACL) 
       LocalFree(pACL); 
      if (psdAdmin) 
       LocalFree(psdAdmin); 
      if (psidAdmin) 
       FreeSid(psidAdmin); 
      if (hImpersonationToken) 
       CloseHandle (hImpersonationToken); 
      if (hToken) 
       CloseHandle (hToken); 
     } 
    } data; 

BOOL fReturn   = FALSE; 
Dword dwStatus; 
Dword dwAccessMask; 
Dword dwAccessDesired; 
Dword dwACLSize; 
Dword dwStructureSize = sizeof(PRIVILEGE_SET); 

PRIVILEGE_SET ps; 
GENERIC_MAPPING GenericMapping; 
SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY; 

const DWORD ACCESS_READ = 1; 
const DWORD ACCESS_WRITE = 2; 

if (!OpenThreadToken (GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, TRUE, &data.hToken)) 
{ 
    if (GetLastError() != ERROR_NO_TOKEN) 
     return false; 

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &data.hToken)) 
     return false; 
} 

if (!DuplicateToken (data.hToken, SecurityImpersonation, &data.hImpersonationToken)) 
    return false; 

if (!AllocateAndInitializeSid(&SystemSidAuthority, 2, 
          SECURITY_BUILTIN_DOMAIN_RID, 
          DOMAIN_ALIAS_RID_ADMINS, 
          0, 0, 0, 0, 0, 0, &data.psidAdmin)) 
    return false; 

data.psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); 
if (data.psdAdmin == NULL) 
    return false; 

if (!InitializeSecurityDescriptor(data.psdAdmin, SECURITY_DESCRIPTOR_REVISION)) 
    return false; 

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

data.pACL = (PACL)LocalAlloc(LPTR, dwACLSize); 
if (data.pACL == NULL) 
    return false; 

if (!InitializeAcl(data.pACL, dwACLSize, ACL_REVISION2)) 
    return false; 

dwAccessMask = ACCESS_READ | ACCESS_WRITE; 

if (!AddAccessAllowedAce(data.pACL, ACL_REVISION2, dwAccessMask, data.psidAdmin)) 
    return false; 

if (!SetSecurityDescriptorDacl(data.psdAdmin, TRUE, data.pACL, FALSE)) 
    return false; 

// 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(data.psdAdmin, data.psidAdmin, FALSE); 
SetSecurityDescriptorOwner(data.psdAdmin, data.psidAdmin, FALSE); 

if (!IsValidSecurityDescriptor(data.psdAdmin)) 
    return false; 

dwAccessDesired = ACCESS_READ; 

GenericMapping.GenericRead = ACCESS_READ; 
GenericMapping.GenericWrite = ACCESS_WRITE; 
GenericMapping.GenericExecute = 0; 
GenericMapping.GenericAll  = ACCESS_READ | ACCESS_WRITE; 

if (!AccessCheck(data.psdAdmin, data.hImpersonationToken, dwAccessDesired, 
       &GenericMapping, &ps, &dwStructureSize, &dwStatus, 
       &fReturn)) 
{ 
    return false; 
} 

return fReturn; 
} 
相关问题