确定是否继承了ntfs权限的可靠方法

shy*_*ent 5 python winapi acl file-permissions ntfs

我这里有一个有点模糊的问题.

我需要的:确定是否继承了文件/文件夹的权限(或严格来说,DACL的特定ACE).

我是如何解决这个问题的:使用winapi绑定python(确切地说是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:])
Run Code Online (Sandbox Code Playgroud)

足够简单 - 获取安全描述符,从中获取DACL,然后遍历DACL中的ACE.这里真正重要的是INHERITED_ACE访问标志.它应该在继承ACE时设置,而不是显式设置.

创建文件夹/文件时,其ACL将根据父对象(文件夹)的ACE进行填充,这些ACE设置为传播给子项.但是,除非您对访问列表进行任何更改,否则将不会设置INHERITED_ACE标志!但继承的权限在那里,他们可以工作.

如果你做了任何微小的改变(比如,在访问列表中添加一个条目,应用更改并将其删除),那么标志就会神奇地出现(行为不会以任何方式改变,不过,它之前有效,之后有效)!我想要的是找到INHERITED_ACE标志的这种行为的来源,并且可能找到另一种可靠的方法来确定ACE是否被继承.

如何重现:

  1. 创建一个对象(文件或文件夹)
  2. 检查Windows资源管理器中的权限,查看它们是否已从父对象传播(例如,使用Windows资源管理器的文件属性对话框的安全选项卡).
  3. 例如,使用我正在使用的脚本检查标志(不会在任何ACE上设置INHERITED_ACE).
  4. 更改对象的权限(应用更改),甚至更改它们.
  5. 检查标志(INHERITED_ACE 在那里)
  6. ..难以置信地摇头(我知道我做过)

对不起有点冗长的帖子,希望这至少有点意义.

Max*_*kin 0

在我的 Win XP Home Edition 上,此代码似乎根本不起作用:-)

我得到这个堆栈跟踪:

回溯(最近一次调用):
文件“C:\1.py”,第 37 行,在 main(sys.argv[1:])
文件“C:\1.py”,第 29 行,在 main 中 for ace_index范围(dacl.GetAceCount()):

AttributeError:“NoneType”对象没有属性“GetAceCount”

您可以尝试“推动”DACL 来填充吗?我的意思是,如果您知道在对其进行轻微更改后它会起作用...以编程方式进行轻微更改,添加存根 ACE 并将其删除。你可以吗?

更新。我在我的工作机器(使用 Win XP Prof)上用 C# 程序进行了实验,我必须告诉您,获取此安全信息的 .net 方法确实有效。因此,当我创建新文件时,我的 C# 程序会检测到 ACE 已被继承,而您的 Python 代码则不会。

这是我运行的示例输出:

C:>csharp_tricks.exe 2.txt

完全控制 --> IsInherited: True

完全控制 --> IsInherited: True

读取并执行、同步 --> IsInherited: True


C:>1.py 2.txt

2.txt

内置\管理员 0x0

NT 权限\系统 0x0

内置\用户 0x0

我的 C# 课程:

public class InheritedAce
{
    public static string GetDACLReport(string path)
    {
        StringBuilder result = new StringBuilder();
        FileSecurity fs = new FileSecurity(path, AccessControlSections.Access);
        foreach (var rule in fs.GetAccessRules(true, true, typeof(SecurityIdentifier)).OfType<FileSystemAccessRule>())
        {
            result.AppendFormat("{0}  -->  IsInherited:  {1}", rule.FileSystemRights, rule.IsInherited);
            result.AppendLine();
        }

        return result.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,这似乎是 python pywin32 安全库中的一个错误。也许他们没有执行所有必要的系统调用......