【问题标题】:How to get ACL permissions for a folder for a specific user with C++?如何使用 C++ 为特定用户获取文件夹的 ACL 权限?
【发布时间】:2013-02-13 08:22:40
【问题描述】:

首先,让我问一下,Windows-NT 上每个用户的 ACL 权限是否会更改?我问的原因是因为accesschk 实用程序似乎将用户名作为参数,同时还需要检查对象(在我的情况下为文件夹路径)。

在任何一种情况下,如何使用 C++ 为特定 Windows 用户获取文件夹的 ACL 权限 (this stuff)?我假设我需要致电 GetNamedSecurityInfo,但如何获得用户帐户的权限?

【问题讨论】:

    标签: c++ winapi permissions acl


    【解决方案1】:

    ACL 的全部意义在于用户之间的区别。它们是访问控制列表;他们控制哪些用户可以访问资源。

    GetNamedSecurityInfo 上你是对的。它为您提供两种 ACL,SACL 和 DACL。 SACL 处理文件访问审计(很少使用),DACL 有权限。您可以分解使用 GetExplicitEntriesFromAcl 返回的 DACL。

    【讨论】:

    • 谢谢。但我仍然不清楚一些事情。如果我调用GetNamedSecurityInfo 获取文件夹路径上的DACL,然后使用GetExplicitEntriesFromAcl 检索权限,那么用户帐户在哪里发挥作用?
    • DACL 中的每个 ACE 都说明它适用于哪个用户。例如,一个 ACE 可能会说“Bob 具有完全控制权”,而另一个可能会说“Charlie 可以阅读”。这就是用户名发挥作用的地方。如果您是 Bob,并且您请求写入权限,则它会成功。如果您是 Charlie,并且您要求写访问权限,那么它会失败。 Details on MSDN.
    【解决方案2】:

    “在任何一种情况下,您如何使用 C++ 为特定 Windows 用户获取文件夹的 ACL 权限(这个东西)?”

    DACL 返回一个指针,您可以使用该指针从中提取值。

    我有一个你可以看的演示程序,它基本上从给定的文件或目录加载 DACL 信息。该页面的链接如下所示。

    Sample GetNamedSecurityInfo() call

    “我假设我需要调用 GetNamedSecurityInfo,但如何从它获取用户帐户的权限?”

    您可以通过调用 GetAce() 遍历列表并从每个项目中提取域/用户名。

    再次查看我用 C++ 编写的示例代码。

    【讨论】:

    • 谢谢...如果我 2 年前没有问过这个问题 ;)
    【解决方案3】:
    #include <windows.h>
    #include <iostream>
    #include<fileapi.h>
    #include<aclapi.h>
    #include <unistd.h>
    #include <sys/stat.h>
    #include<time.h>
    using namespace std;
    
    void printFileProperties(struct stat stats)
    {
        struct tm dt;
        printf("\nFile access: ");
        if (stats.st_mode & R_OK)
            printf("read ");
        if (stats.st_mode & W_OK)
            printf("write ");
        if (stats.st_mode & X_OK)
            printf("execute");
    
    
      
        printf("\nFile size: %d Bytes", stats.st_size);  
        dt = *(gmtime(&stats.st_ctime));
        printf("\nCreated on: %d-%d-%d %d:%d:%d", dt.tm_mday, dt.tm_mon, dt.tm_year + 1900, 
                                                  dt.tm_hour, dt.tm_min, dt.tm_sec);
        dt = *(gmtime(&stats.st_mtime));
        printf("\nModified on: %d-%d-%d %d:%d:%d", dt.tm_mday, dt.tm_mon, dt.tm_year + 1900, 
                                                  dt.tm_hour, dt.tm_min, dt.tm_sec);
        dt = *(gmtime(&stats.st_atime));
        printf("\nAccessed on: %d-%d-%d %d:%d:%d", dt.tm_mday, dt.tm_mon, dt.tm_year + 1900, 
                                                  dt.tm_hour, dt.tm_min, dt.tm_sec); 
        
    }
    void printGroupProperties(char filepath[])
    {
        LPCSTR fname;
    
        fname = filepath;
      
        DWORD dwRtnCode = 0;
        PSECURITY_DESCRIPTOR psd = NULL;
        PACL pdacl;
        ACL_SIZE_INFORMATION aclSize = {0};
        PSID sidowner = NULL;
        PSID sidgroup = NULL;
        HANDLE hFile;
        LPTSTR   oname = NULL;
        LPTSTR doname=NULL;
        DWORD namelen=0;        
        DWORD domainnamelen=0;
        SID_NAME_USE peUse;
        ACCESS_ALLOWED_ACE* ace;
                     
        dwRtnCode = GetNamedSecurityInfo(fname
                ,SE_FILE_OBJECT
                ,OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION 
                ,&sidowner
                ,&sidgroup
                ,&pdacl
                ,NULL
                ,&psd);
             
    
        LookupAccountSid(NULL, sidowner,  oname, (LPDWORD)  &namelen, doname,  (LPDWORD) &domainnamelen, &peUse);
        
           oname = (LPTSTR)GlobalAlloc(
              GMEM_FIXED,
              namelen);
               doname = (LPTSTR)GlobalAlloc(
               GMEM_FIXED,
               domainnamelen);
                
    //  wcout<<"Owner: " << doname << "/" << oname <<"\n";
    
        LookupAccountSid(NULL, sidgroup, oname,  (LPDWORD) &namelen, doname,   (LPDWORD)&domainnamelen, &peUse);
        wcout<<"\n\nGroup: " << doname << "/" << oname;      
        wcout<< "\n::ACCESS CONTROL LIST::";
        SID *sid;
        unsigned long i, mask;
        char *stringsid;
    
        for (int i=0; i<(*pdacl).AceCount; i++) {
            int c=1;
            namelen=0;
            domainnamelen=0;
            BOOL b = GetAce(pdacl, i, (PVOID*)&ace);
            //SID *sid = (SID *) ace->SidStart;
            if (((ACCESS_ALLOWED_ACE *) ace)->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) {
                sid = (SID *) &((ACCESS_ALLOWED_ACE *) ace)->SidStart;
                LookupAccountSid(NULL, sid,  oname,  (LPDWORD) &namelen, doname,   (LPDWORD)&domainnamelen, &peUse);
                oname = (LPTSTR)GlobalAlloc(GMEM_FIXED,namelen);
                doname = (LPTSTR)GlobalAlloc(GMEM_FIXED,domainnamelen);
                LookupAccountSid(NULL, sid,  oname,  (LPDWORD) &namelen, doname,   (LPDWORD)&domainnamelen, &peUse);
                wcout<<"\nUser Group "<<i+1<<":"<< doname << "/" << oname;
                mask = ((ACCESS_ALLOWED_ACE *) ace)->Mask;
            }
            else if (((ACCESS_DENIED_ACE *) ace)->Header.AceType == ACCESS_DENIED_ACE_TYPE) {
                sid = (SID *) &((ACCESS_DENIED_ACE *) ace)->SidStart;
                LookupAccountSid(NULL, sid,  oname,(LPDWORD) &namelen, doname, (LPDWORD)&domainnamelen, &peUse);
                oname = (LPTSTR)GlobalAlloc(GMEM_FIXED,namelen);
                doname = (LPTSTR)GlobalAlloc(GMEM_FIXED,domainnamelen);
                LookupAccountSid(NULL, sid,  oname,  (LPDWORD) &namelen, doname,   (LPDWORD)&domainnamelen, &peUse);
                    wcout<<"\nUser Group "<<i+1<<":"<< doname << "/" << oname;
                mask = ((ACCESS_DENIED_ACE *) ace)->Mask;
            }
            else printf("Other ACE\n");
            cout<<"\nPERMISSIONS:\n";
        //  wcout<<"ACE: mask:" << ace->Mask << " sidStart:" << ace->SidStart << " header type=" << ace->Header.AceType << " header flags=" << ace->Header.AceFlags <<"\n";
        
            if (DELETE & ace->Mask) {
                wcout<< " Delete" << "\n";
            }
            if (FILE_GENERIC_READ & ace->Mask) {
                wcout<< " File_Generic_Read" << "\n";
            }
            if (FILE_GENERIC_WRITE & ace->Mask) {
                wcout<< " File_Generic_Write" << "\n";
            }
            if (FILE_GENERIC_EXECUTE & ace->Mask) {
                wcout<< " File_Generic_Execute" << "\n";
            }
            if (GENERIC_READ & ace->Mask) {
                wcout<< " Generic_Read" << "\n";
            }
            if (GENERIC_WRITE & ace->Mask) {
                wcout<< " Generic_Write" << "\n";
            }
            if (GENERIC_EXECUTE & ace->Mask) {
                wcout<< " Generic_Execute" << "\n";
            }
            if (GENERIC_ALL & ace->Mask) {
                wcout<< " Generic_All" << "\n";
            }
            if (READ_CONTROL & ace->Mask) {
                wcout<< " Read_Control" << "\n";
            }
            if (WRITE_DAC & ace->Mask) {
                wcout<< " Write_DAC" << "\n";
            }
            if (WRITE_OWNER & ace->Mask) {
                wcout<< " Write_Owner" << "\n";
            }
            if (SYNCHRONIZE & ace->Mask) {
                wcout<< " Synchronize" << "\n";
            }
            wcout<<"\n";
        }
    
        SECURITY_DESCRIPTOR* p1 = (SECURITY_DESCRIPTOR*)psd;
    
        wcout<< "\n::SECURITY_DESCRIPTOR_CONTROL::" << "\n";
    
        SECURITY_DESCRIPTOR_CONTROL ctrl = (*p1).Control;
            if (SE_OWNER_DEFAULTED & ctrl) {
                wcout<< " SE_OWNER_DEFAULTED" << "\n";
            }
            if (SE_DACL_PRESENT & ctrl) {
                wcout<< " SE_DACL_PRESENT" << "\n";
            }
            if (SE_DACL_DEFAULTED & ctrl) {
                wcout<< " SE_DACL_DEFAULTED" << "\n";
            }
            if (SE_SACL_PRESENT & ctrl) {
                wcout<< " SE_SACL_PRESENT" << "\n";
            }
            if (SE_SACL_DEFAULTED & ctrl) {
                wcout<< " SE_SACL_DEFAULTED" << "\n";
            }
            if (SE_DACL_AUTO_INHERIT_REQ & ctrl) {
                wcout<< " SE_DACL_AUTO_INHERIT_REQ" << "\n";
            }
            if (SE_SACL_AUTO_INHERIT_REQ & ctrl) {
                wcout<< " SE_SACL_AUTO_INHERIT_REQ" << "\n";
            }
            if (SE_SACL_AUTO_INHERITED & ctrl) {
                wcout<< " SE_SACL_AUTO_INHERITED" << "\n";
            }
            if (SE_DACL_PROTECTED & ctrl) {
                wcout<< " SE_DACL_PROTECTED" << "\n";
            }
            if (SE_SACL_PROTECTED & ctrl) {
                wcout<< " SE_SACL_PROTECTED" << "\n";
            }
            if (SE_RM_CONTROL_VALID & ctrl) {
                wcout<< " SE_RM_CONTROL_VALID" << "\n";
            }
            if (SE_SELF_RELATIVE & ctrl) {
                wcout<< " SE_SELF_RELATIVE" << "\n";
            }
    
    //  LocalFree(psd);
    //  LocalFree(sidowner);
    //  LocalFree(pdacl);
    }
    
    
    void printFileAttributes(char filepath[])
    {
        long unsigned int FileAttributes;
        FileAttributes=GetFileAttributesA(filepath);
        printf("\nFile type:");
        if (FileAttributes & FILE_ATTRIBUTE_ARCHIVE) 
        {
            printf("Archive ");
        }
        if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            printf("Directory ");
        }
        if (FileAttributes & FILE_ATTRIBUTE_READONLY) 
        {
            printf("Read-Only ");
        }
        if (FileAttributes &    FILE_ATTRIBUTE_HIDDEN) 
        {
            printf("Hidden");
        }
    }
    
    int main()
    {
        WIN32_FIND_DATA data;
        char dir[100];
        cout<<"\nEnter the directory path:";
        gets(dir);
        char dirname[100];
        strcpy(dirname,dir);
        strcat(dirname,"\\*");
        //cout<<dirname;
        HANDLE hFind = FindFirstFile(dirname, &data);      // DIRECTORY
        struct stat stats;
        if ( hFind != INVALID_HANDLE_VALUE ) {
            do {
                std::cout << "\n\nFile name:"<<data.cFileName;
                //cout<<"\nFile Type:";
                char filepath[100];
                strcpy(filepath,dir);
                strcat(filepath,"\\");
                strcat(filepath,data.cFileName);
              
                if( stat(filepath, &stats) == 0)   
                {
                    printFileProperties(stats); 
               }
              printFileAttributes(filepath);
             printGroupProperties(filepath);
             
                        
            } while (FindNextFile(hFind, &data));
            FindClose(hFind);
        }
    }
    

    【讨论】:

    • 这是一个 C++ 程序,它从用户读取文件夹/目录路径并列出文件及其属性、属性和组权限 (ACL)。
    猜你喜欢
    • 1970-01-01
    • 2019-09-07
    • 2016-04-14
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2015-05-15
    • 2018-07-29
    • 2020-09-05
    相关资源
    最近更新 更多