python - 尽管是文件的所有者,但 READ_CONTROL 的 CreateFileW 失败并显示 "Access is denied"

标签 python windows acl pywin32 dacl

在 Windows 上,即使任意 ACL (DACL) 为空,即没有人拥有该文件的权限,文件所有者也可以读取和写入 DACL(READ_CONTROLWRITE_DAC访问)。

所以我尝试执行以下操作:

  1. 在文件上设置空 DACL
  2. 获取READ_CONTROL的文件句柄
  3. 使用 GetSecurityInfo 和句柄获取安全描述符
  4. 检查 DACL 是否确实为空

但是,使用CreateFileW获取句柄失败,并出现访问被拒绝错误。令人惊讶的是,GetFileSecurity(相当于文件的 GetSecurityInfo)运行良好。 根据documentation , GetFileSecurity 需要 READ_CONTROL 访问权限。

为什么在以下示例中 CreateFileW 失败?

import sys
import win32security
import win32con
import win32file
import ntsecuritycon
import os

path = sys.argv[1]

with open(path, "w"):
    pass  # I am the owner of the file

print("Set empty ACL")
sd = win32security.GetFileSecurity(path, win32security.DACL_SECURITY_INFORMATION)
dacl = win32security.ACL()
sd.SetSecurityDescriptorDacl(1, dacl, 0)
win32security.SetFileSecurity(path, win32security.DACL_SECURITY_INFORMATION, sd)

try:
    print("Ensure that ACL is empty with GetFileSecurity")
    sd = win32security.GetFileSecurity(path, win32security.DACL_SECURITY_INFORMATION)
    dacl = sd.GetSecurityDescriptorDacl()
    assert 0 == dacl.GetAceCount()

    print("Try to ensure that ACL is empty using handle")
    handle = win32file.CreateFileW(
        path,
        ntsecuritycon.READ_CONTROL,
        0,
        None,  # security attributes
        win32con.OPEN_EXISTING,
        0,
        None,
    )
    sd = win32security.GetSecurityInfo(handle, win32security.SE_FILE_OBJECT, win32security.DACL_SECURITY_INFORMATION)
    dacl = sd.GetSecurityDescriptorDacl()
    assert 0 == dacl.GetAceCount()
except Exception as e:
    print("FAILURE:", e)
finally:
    print("Restore inherited ACEs before removing file")
    dacl = win32security.ACL()
    win32security.SetNamedSecurityInfo(
        path, 
        win32security.SE_FILE_OBJECT, 
        win32security.DACL_SECURITY_INFORMATION,
        None,
        None,
        dacl,
        None
    )
    os.unlink(path)

输出:

> python acl-test.py file
Set empty ACL
Ensure that ACL is empty with GetFileSecurity
Try to ensure that ACL is empty using handle
FAILURE: (5, 'CreateFileW', 'Access is denied.')
Restore inherited ACEs before removing file

最佳答案

CreateFileW内部调用NtCreateFileDesiredAccess 参数作为 dwDesiredAccess | 传递文件读取属性 |同步。因此,如果您将 dwDesiredAccess 作为 READ_CONTROL 传递,那么它实际上会尝试使用 READ_CONTROL | 打开该文件。文件读取属性 |同步访问。如果调用者拥有父文件夹的 FILE_LIST_DIRECTORY 访问权限,则文件系统会隐式授予 FILE_READ_ATTRIBUTES 访问权限。但是,如果文件的 DACL 为空,则不会授予SYNCHRONIZE 访问权限。

这里的一个解决方案是使用 NtOpenFileNtCreateFile 以控制确切的请求访问。

关于python - 尽管是文件的所有者,但 READ_CONTROL 的 CreateFileW 失败并显示 "Access is denied",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58393139/

相关文章:

java - 检索给定 objectId 的 ParseObject 的 ACL

Symfony2 : Best practice for access control

python - Pyodbc错误数据源名称未找到并且没有指定默认驱动程序悖论

hibernate - 确保经过身份验证的用户有权访问资源的最佳实践 - Spring mvc、Spring Security、Hibernate

php - Python:PHP "=="的等价物是什么

python - python 的 recvfrom() 队列数据包吗?

c# - 构建 XNA 磁贴编辑器

windows - 我如何在本地拦截和响应浏览器请求?

python - 将 python 中的字符串与文本文件进行比较

python - for循环列表理解中的多个变量