簡體   English   中英

盡管是文件的所有者,但 READ_CONTROL 的 CreateFileW 失敗並顯示“訪問被拒絕”

[英]CreateFileW for READ_CONTROL fails with “Access is denied” despite being owner of the file

在Windows上,即使任意ACL(DACL)為空,即沒有人對文件有權限,文件所有者也可以讀寫DACL( READ_CONTROLWRITE_DAC訪問)。

所以我嘗試執行以下操作:

  1. 在文件上設置一個空的 DACL
  2. 獲取READ_CONTROL文件的句柄
  3. 使用GetSecurityInfo和句柄獲取安全描述符
  4. 檢查 DACL 是否實際為空

但是,使用CreateFileW獲取句柄失敗並出現Access is denied錯誤。 令人驚訝的是, GetFileSecurity相當於文件的GetSecurityInfo ,運行良好。 根據文檔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)

Output:

> 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在內部調用NtCreateFile ,並將DesiredAccess參數作為dwDesiredAccess | FILE_READ_ATTRIBUTES | SYNCHRONIZE傳遞。 dwDesiredAccess | FILE_READ_ATTRIBUTES | SYNCHRONIZE dwDesiredAccess | FILE_READ_ATTRIBUTES | SYNCHRONIZE 因此,如果您將dwDesiredAccess作為READ_CONTROL傳遞,那么它實際上會嘗試使用READ_CONTROL | FILE_READ_ATTRIBUTES | SYNCHRONIZE打開文件。 READ_CONTROL | FILE_READ_ATTRIBUTES | SYNCHRONIZE READ_CONTROL | FILE_READ_ATTRIBUTES | SYNCHRONIZE訪問。 如果調用者對父文件夾具有FILE_LIST_DIRECTORY訪問權限,則文件系統會隱式授予FILE_READ_ATTRIBUTES訪問權限。 但是,如果文件具有空 DACL,則不會授予SYNCHRONIZE訪問權限。

這里的一種解決方案是使用NtOpenFileNtCreateFile來控制確切的請求訪問。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM