对于如何正确使用windows api来确定文件权限,我真是绞尽脑汁。我看过很多关于这方面的文章,但我似乎没能把它写对。具体来说,我想检查用户是否具有对给定文件的读或写权限。以下是我的步骤:
(1)使用getusernameex访问调用客户端(包括域名)的完全限定用户名;(返回0错误;用户名似乎使用cout debug消息正确打印)。
(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描述符如下:
ACL dacl;
PACL ppDacl = &dacl;
SECURITY_DESCRIPTOR sd;
PSECURITY_DESCRIPTO = &sd;
而不是新的它们似乎没有正确地填充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)
我希望你们中的一个能解释一下
干杯,
本。
最佳答案
对GetNamedSecurityInfo()
的调用应在作为第三个参数传递的标志集中设置DACL_SECURITY_INFORMATION
。只有在调用返回后,第6个参数中返回的值所引用的数据才有效。
逐字从GetNamedSecurityInfo()
'sdocumentation on MSDN:
ppdacl[输出,可选]
…
返回的指针只有在设置dacl_security_信息标志时才有效。
另请注意:不需要初始化ppDacl
和ppSecurityDescriptor
,因为这是由GetNamedSecurityInfo()
完成的。如果动态地分配内存,这会导致内存泄漏,就像调用GetNamedSecurityInfo()
一样,会丢失对分配内容的引用。