您的位置:首页 > Web前端

关于如何判断当前用户对文件有无写权限

2014-05-08 20:10 399 查看

如何判断当前用户对文件有无写权限

前一段时间项目要求判断用户对文件有无写权限,于是查了相关资料,拜读了很多大牛的著作写下了一下代码(代码写的杂乱,有很多不足之处,还请各位大牛多多批评):
代码思路:1.获取当前用户名GetUserName
                  2.获取当前用户名所属的组NetUserGetLocalGroups
                  3.获取用户和用户组的sid(安全标识符,表示一个用户,一个用户组,一台计算机,一个域等,计算机可以通过这个识别用户;注册表对应位置:HESY_USERS下)
                  4.通过文件名获取文件的acl列表
                  5.遍历acl列表中的ace,比对sid,判断相应权限
代码缺陷:1.不针对域用户,如果是域用户可在NetUserGetLocalGroups函数之前,获取域名和用户名拼接wstrName,再传参给NetUserGetLocalGroups
                  2.仅针对ntfs,对fat32或fat16仅仅做简单处理
代码参考:http://pnig0s1992.blog.51cto.com/393390/908495
 
#define AllocMem(x) (HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, x))
#define FreeMem(x) (HeapFree(GetProcessHeap(),HEAP_ZERO_MEMORY, x))
bool  hasWritePrivilege(const char* path)
{
 //获得文件的安全描述符
 BOOL bRs = FALSE;
 DWORD dwSizeNeeded = 0;
 PISECURITY_DESCRIPTOR psd = NULL;
 SECURITY_INFORMATION si = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
 
 WCHAR wstr[256] = {0};
 c2w(wstr, 256, path);
 //获取当前用户名
 WCHAR wstrName[256] = {0};
 DWORD dwSize = 256;
 GetUserName(wstrName,&dwSize);
 
 //用户sid
 LPVOID pUserSid = NULL;
 DWORD  cbUserSid = 0;
 
 //组sid
 TCHAR  *szDomain = NULL;
 DWORD  cbDomain  = 0;
 SID_NAME_USE  snuType;
 DWORD dwLevel = 0;
 DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
 DWORD dwEntriesRead = 0;
 DWORD dwTotalEntries = 0;
 NET_API_STATUS nStatus;
 LPLOCALGROUP_USERS_INFO_0 pBuf = NULL;
 LPLOCALGROUP_USERS_INFO_0 pImpBuf;
 LPVOID pDomainSid  = NULL;
 DWORD  cbDomainSid = 0;
 TCHAR  *szDomainnew = NULL;
 DWORD  cbDomainnew  = 0;
 //获取当前用户所属的用户组
 nStatus = NetUserGetLocalGroups(NULL,wstrName,0,LG_INCLUDE_INDIRECT,(LPBYTE*)&pBuf,dwPrefMaxLen,&dwEntriesRead,&dwTotalEntries);
 if (nStatus == NERR_Success)
 {
     //遍历用户组
  if ((pImpBuf = pBuf) != NULL)
  {
   for (int i = 0;i<dwEntriesRead;i++)
   {
    assert(pImpBuf != NULL);
    if (pImpBuf == NULL)
    {
     break;
    }
                //获取用户组的sid,第一次获取可能失败 重新分配buffer后获取
    if (!LookupAccountName(NULL,pImpBuf->lgrui0_name,pDomainSid,&cbDomainSid,szDomainnew,&cbDomainnew,&snuType))
    {
     if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
     {
      pDomainSid = AllocMem(cbDomainSid);
      szDomainnew = (TCHAR*)AllocMem(cbDomainnew*sizeof(TCHAR));
     }
    }
    if (!LookupAccountName(NULL,pImpBuf->lgrui0_name,pDomainSid,&cbDomainSid,szDomainnew,&cbDomainnew,&snuType))
    {
     return true;
    }
    else
    {
        //获取用户的sid
     if (!LookupAccountName(NULL,wstrName,pUserSid,&cbUserSid,szDomain,&cbDomain,&snuType))
     {
      if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
      {
       pUserSid = AllocMem(cbUserSid);
       szDomain = (TCHAR*)AllocMem(cbDomain*sizeof(TCHAR));
      }
     }
     if (!LookupAccountName(NULL,wstrName,pUserSid,&cbUserSid,szDomain,&cbDomain,&snuType))
     {
      return true;
     }
     BOOL bSuccess = TRUE;
     PACL pDacl = NULL;
     ACCESS_ALLOWED_ACE *pAce = NULL;
     //根据文件名获取dacl
     if(ERROR_SUCCESS != GetNamedSecurityInfo(wstr,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,&pDacl,NULL,NULL))
     {
      return true;
     }
     else
     {
         //Dacl不存在话,调用QFile和QDir来判断,这是Qt的类
      if (!pDacl)
      {
       //Fat32系统
       QFile file(QString::fromWCharArray(wstr));
       QDir dir(QString::fromWCharArray(wstr));
       if (file.isWritable())
       {
        return true;
       }
       else if (dir.isReadable())
       {
        return true;
       }
       else
       {
        return false;
       }  
      }
      //DACL存在的话遍历其中的ace
      for (int i = 0; i<pDacl->AceCount;i++)
      {
          //获取ACE
       if (GetAce(pDacl,i,(LPVOID*)&pAce))
       {
        qDebug()<<pAce->SidStart;
        //判断ACE的sid和用户或用户组的sid是否相同
        if (EqualSid(pUserSid,&pAce->SidStart) || EqualSid(pDomainSid,&pAce->SidStart))
        {
         qDebug()<<"pAce->Mask"<<pAce->Mask;
         //判断当前用户或组对文件有无写权限
         if ((pAce->Mask & FILE_WRITE_DATA) == FILE_WRITE_DATA)
         {
          qDebug()<<"可写!!!!!";
          return true;
         }
        } 
       }
      }
     }
    }
    qDebug()<<"用户组:"<<QString::fromWCharArray(pImpBuf->lgrui0_name)<<snuType;
    pImpBuf++;                       
   }
  }
  if (pBuf != NULL)
  {
   NetApiBufferFree(pBuf);
   pBuf = NULL;
  }
 }
 //end
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c 遍历 buffer path security