我在这里有一个有点模糊的问题。
我需要什么:确定文件/文件夹的权限(或者,严格来说,DACL 的特定 ACE)是否被继承。
我如何尝试解决这个问题:使用 python 的 winapi 绑定(准确地说是 win32security 模块)。这是精简版,它就是这样做的——它只是将文件的路径作为参数,并一一打印出 ACE,指示设置了哪些标志。
#!/usr/bin/env python
from win32security import *
import sys
def decode_flags(flags):
_flags = {
SE_DACL_PROTECTED:"SE_DACL_PROTECTED",
SE_DACL_AUTO_INHERITED:"SE_DACL_AUTO_INHERITED",
OBJECT_INHERIT_ACE:"OBJECT_INHERIT_ACE",
CONTAINER_INHERIT_ACE:"CONTAINER_INHERIT_ACE",
INHERIT_ONLY_ACE:"INHERIT_ONLY_ACE",
NO_INHERITANCE:"NO_INHERITANCE",
NO_PROPAGATE_INHERIT_ACE:"NO_PROPAGATE_INHERIT_ACE",
INHERITED_ACE:"INHERITED_ACE"
}
for key in _flags.keys():
if (flags & key):
print '\t','\t',_flags[key],"is set!"
def main(argv):
target = argv[0]
print target
security_descriptor = GetFileSecurity(target,DACL_SECURITY_INFORMATION)
dacl = security_descriptor.GetSecurityDescriptorDacl()
for ace_index in range(dacl.GetAceCount()):
(ace_type,ace_flags),access_mask,sid = dacl.GetAce(ace_index)
name,domain,account_type = LookupAccountSid(None,sid)
print '\t',domain+'\\'+name,hex(ace_flags)
decode_flags(ace_flags)
if __name__ == '__main__':
main(sys.argv[1:])
很简单——获取一个安全描述符,从中获取一个 DACL,然后遍历 DACL 中的 ACE。这里真正重要的一点是 INHERITED_ACE 访问标志。它应该在 ACE 被继承而不是显式设置时设置。
当您创建文件夹/文件时,其 ACL 会根据父对象(文件夹)的 ACE 填充 ACE,这些 ACE 设置为传播给子对象。但是,除非您对访问列表进行任何更改,否则不会设置 INHERITED_ACE 标志!但是继承的权限在那里并且它们确实有效。
如果您进行任何细微的更改(例如,在访问列表中添加一个条目,应用更改并删除它),标志就会神奇地出现(该行为不会以任何方式改变,但它之前有效,之后有效)!我想要的是找到 INHERITED_ACE 标志的这种行为的来源,并且可能找到另一种可靠的方法来确定 ACE 是否被继承。
如何重现:
- 创建对象(文件或文件夹)
- 检查 Windows 资源管理器中的权限,查看它们是否已从父对象传播(例如,使用 Windows 资源管理器的文件属性对话框的安全选项卡)。
- 例如,使用我正在使用的脚本检查标志(不会在任何 ACE 上设置 INHERITED_ACE)。
- 更改对象的权限(应用更改),甚至将它们更改回来。
- 检查标志(INHERITED_ACE将在那里)
- ..难以置信地摇头(我知道我做到了)
抱歉,这篇文章有点冗长,希望这至少有点意义。