我是不是错误地使用了 SetNamedSecurityInfo?我的文件的 ACL 似乎没有被正确修改

Posted

技术标签:

【中文标题】我是不是错误地使用了 SetNamedSecurityInfo?我的文件的 ACL 似乎没有被正确修改【英文标题】:Am I using SetNamedSecurityInfo incorrectly? The ACL of my file doesn't seem to be being modified properly我是否错误地使用了 SetNamedSecurityInfo?我的文件的 ACL 似乎没有被正确修改 【发布时间】:2010-11-08 21:45:07 【问题描述】:

我正在尝试启用和禁用文件的某些访问权限。我发现要做到这一点,你必须弄乱 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() 调用组合,例如用 REVOKE_ACCESS 替换 DENY_ACCESS,用 GRANT_ACCESS 替换 SET_ACCESS,不进行任何 SET_ACCESS 调用等等,但似乎没有任何效果。

我应该注意,大部分代码取自this MSDN example,所以我认为它应该可以工作。我到底做错了什么?

【问题讨论】:

【参考方案1】:

我认为set_DACL_for_object 调用应该指定FILE_ALL_ACCESSFILE_GENERIC_WRITE,而不是GENERIC_ALLGENERIC_WRITE。我用这些更改编译了您的代码 sn-p,它按您的预期工作。

作为旁注,LPTSTR 强制转换会阻止编译器检测到此代码是 Ansi,如果您应该将其编译为 Unicode,因此在这种情况下代码将在运行时失败。

您应该改用_T("ADMINISTRATORS")

【讨论】:

谢谢;我试过了,它仍然为我产生相同的结果(无法读取文件)。在您的系统上,调用这两个函数 - SET_ACCESS 用于 FILE_ALL_ACCESS 和 DENY_ACCESS 用于 FILE_GENERIC_WRITE - 允许您打开文件并读取它,但不能写入它?【参考方案2】:

在哪个程序中打开并阅读? 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);

在文件安全选项卡的高级权限列表中,通过上述调用,“管理员”组仅将以下内容标记为“拒绝”:

'创建文件/写入数据'、'创建文件夹/追加数据'、'写入属性'、'写入扩展属性'

有了这些知识,您应该能够选择您需要的确切标志集。

【讨论】:

谢谢!做到了。在我回复您的第一个答案后,我启动到安全模式并检查了我正在创建和修改 ACL 的文件的安全信息。我注意到写访问确实被拒绝了,并且允许读访问......但也有一些特殊权限被拒绝。感谢您为我指明正确的方向,现在它正在工作。

以上是关于我是不是错误地使用了 SetNamedSecurityInfo?我的文件的 ACL 似乎没有被正确修改的主要内容,如果未能解决你的问题,请参考以下文章

我是不是错误地安装了 create-react-app?

STMicro 是不是错误地解释了“影子寄存器”一词?

我是不是错误地渲染了 BSP 树?

我是不是错误地从 CLion 中的文件中获取环境变量,或者 env 文件语法不正确?

我是不是使用数组作为输入?我犯了啥逻辑错误?

为啥使用用户定义的异常而不是简单地显示错误消息[重复]