1

我真的很想知道如何正确使用 Windows api 来确定文件权限。我已经看过很多关于此的帖子,但我似乎无法正确理解。具体来说,我想检查用户是否对给定文件具有读取或写入权限。这些是我的步骤:

(1) 使用 GetUserNameEx 访问调用客户端的完全限定用户名(包括域名);(返回 0 错误;用户名似乎使用 cout 调试消息正确打印出来)。

(2) 使用 LookupAccountName 访问用户的 SID。(我这样做了两次,第一次设置 SID 和域缓冲区大小——第一次调用返回 122 错误,第二次返回 0 错误(预期))。我假设 SID 缓冲区设置正确。

(3) 用获得的sid构建受托者:

        TRUSTEE t;
        PTRUSTEE tptr = &t;
        BuildTrusteeWithSid(tptr,&sid[0]);

(4) 获取DACL:

 // following are freed up later using LocalFree (maybe I should use delete?)
 PACL ppDacl = new ACL;
 PSECURITY_DESCRIPTOR ppSecurityDescriptor = new SECURITY_DESCRIPTOR;
 std::vector<TCHAR> v(pathString.begin(), pathString.end());
 GetNamedSecurityInfo(&v[0],
                      SE_FILE_OBJECT,
                      READ_CONTROL,
                      NULL,
                      NULL,
                      &ppDacl,
                      NULL,
                      &ppSecurityDescriptor);

一个简单的调用

 std::cout<<"ACE count: "<<ppDacl->AceCount<<std::endl;

然后表示有 58 个 ACE 导致我假设 DACL 结构被正确实例化(我进一步假设有 58 个 ACE,尽管我不确定如何手动验证这一点;我真的不是 Windows 人) . 但是,在调用 GetNamedSecurityInfo 之后打印 GetLastError() 会给我一个 122(即 ERROR_INSUFFICIENT_BUFFER),所以这一步似乎出了点问题。

请注意,初始化 PACL 和 PSECURITY_DESCRIPTOR 如下:

 ACL dacl;
 PACL ppDacl = &dacl;
 SECURITY_DESCRIPTOR sd;
 PSECURITY_DESCRIPTO = &sd;

而不是 new-ing 它们似乎没有正确填充 DACL(至少调用

  std::cout<<"ACE count: "<<ppDacl->AceCount<<std::endl;

报告 0 而不是 58)。我不确定为什么。

(5) 最后,我尝试在给定创建的受托人和 dacl 的情况下获取文件的访问掩码:

 ACCESS_MASK access;
 GetEffectiveRightsFromAcl(ppDacl, tptr, &access);

当我这样做时,这表明没有访问权限:

 ((access & GENERIC_WRITE)==GENERIC_WRITE)

或者

 ((access & GENERIC_READ)==GENERIC_READ)

我希望你们中的一个人能对此有所了解

干杯,

本。

4

1 回答 1

2

调用GetNamedSecurityInfo()DACL_SECURITY_INFORMATION设置在作为第三个参数传递的标志集中。只有第 6 个参数返回的值所引用的数据在调用返回后才有效。

逐字逐句来自MSDN 上GetNamedSecurityInfo()的文档:

ppDacl [输出,可选]

...返回的指针只有在您设置了 DACL_SECURITY_INFORMATION 标志时才有效。


另附注:无需初始化ppDaclppSecurityDescriptor因为这是由GetNamedSecurityInfo(). 如果您动态地为这些分配内存,则会导致内存泄漏,因为调用GetNamedSecurityInfo()您会丢失对您分配的内容的引用。

于 2012-11-12T11:02:18.297 回答