我正在尝试启用和禁用文件的某些访问权限。我想到要做到这一点,你必须搞乱DACL。我正在使用以下代码修改文件的DACL:
void set_DACL_for_object(const char *object, SE_OBJECT_TYPE object_type,
int access_perms, int access_mode) {
PACL pDACL = NULL, pOldDACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea;
GetNamedSecurityInfo((LPTSTR)object, object_type,
DACL_SECURITY_INFORMATION, NULL, NULL,
&pOldDACL, NULL, &pSD);
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = access_perms;
ea.grfAccessMode = access_mode;
ea.grfInheritance = NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
ea.Trustee.ptstrName = _T("ADMINISTRATORS");
SetEntriesInAcl(1, &ea, pOldDACL, &pDACL);
SetNamedSecurityInfo((LPTSTR)object, object_type,
DACL_SECURITY_INFORMATION, NULL, NULL, pDACL, NULL);
}
首先,我使用fopen()创建一个文件,创建一个ACL以授予对Administrators组的所有访问权限,然后拒绝对Administrators组的写入权限:
set_DACL_for_object("C:\\file.txt", SE_FILE_OBJECT, GENERIC_ALL, SET_ACCESS);
set_DACL_for_object("C:\\file.txt", SE_FILE_OBJECT, GENERIC_WRITE, DENY_ACCESS);
然而,在这些调用之后,我没有对该文件的读访问权。如果我不进行调用,我有读/写访问权限(正如预期的那样)。
我应该注意到我在管理员帐户下运行,并且功能正在返回成功。我也尝试为特定的有限用户修改ACL,但同样的事情发生......用户被拒绝读访问权限,而不是我想要的写访问权。
我尝试了一系列不同的set_DACL_for_object()调用组合,比如将DENY_ACCESS替换为REVOKE_ACCESS,将SET_ACCESS替换为GRANT_ACCESS,不进行任何SET_ACCESS调用等,但似乎没有任何工作。
我应该注意,大部分代码都来自this MSDN example,所以我认为它应该有效。我究竟做错了什么?
答案 0 :(得分:4)
打开并阅读哪个程序? ACL设置为我的预期,但FILE_GENERIC_WRITE可能过于通用;它看起来也设置了一个影响阅读属性的“特殊”权限。
来自winnt.h的:
#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |\
FILE_WRITE_DATA |\
FILE_WRITE_ATTRIBUTES |\
FILE_WRITE_EA |\
FILE_APPEND_DATA |\
SYNCHRONIZE)
如果我使用更有限的标志集调用,现在可以打开和读取测试文件,至少在记事本中,但管理员用户无法保存文档:
DWORD dwCustomWrite = FILE_WRITE_DATA |
FILE_WRITE_ATTRIBUTES |
FILE_WRITE_EA |
FILE_APPEND_DATA;
set_DACL_for_object(..., SE_FILE_OBJECT, dwCustomWrite, DENY_ACCESS);
在文件安全选项卡的高级权限列表中,只有以下调用对“管理员”组标记为“拒绝”:
'创建文件/写入数据','创建文件夹/追加数据','写属性','写扩展属性'
有了这些知识,你应该能够选择你需要的确切标志。
答案 1 :(得分:1)
我认为set_DACL_for_object
来电应指定FILE_ALL_ACCESS
和FILE_GENERIC_WRITE
,而不是GENERIC_ALL
和GENERIC_WRITE
。我使用这些更改编译了您的代码段,并且它按预期工作。
作为旁注,LPTSTR
强制转换会阻止编译器检测到此代码是Ansi,如果您应该将其编译为Unicode,那么在这种情况下代码将在运行时失败。
您应该使用_T("ADMINISTRATORS")
代替。