我在这里有一个晦涩的问题。

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

我如何尝试解决此问题:对python使用winapi绑定(bind)(准确地说是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时设置它,而不是显式设置。

创建文件夹/文件时,将根据父对象(文件夹)的ACE填充ACE,并将其设置为传播给子对象。但是,除非您对访问列表进行任何更改,否则将不会设置INHERITED_ACE标志!但是继承的权限在那里,它们确实起作用。

如果您进行了一些细微的更改(例如,将一个条目添加到访问列表中,应用更改并删除了它),该标志就会神奇地出现(该行为不会以任何方式更改,尽管它在工作之前和之后都可以工作)!我想要的是找到INHERITED_ACE标志的这种行为的来源,也许找到另一种可靠的方法来确定ACE是否被继承。

繁殖方法:
  • 创建对象(文件或文件夹)
  • 检查Windows资源管理器中的权限,查看它们是否已从父对象传播(例如,使用Windows资源管理器的文件属性对话框的“安全性”选项卡)。
  • 使用例如我正在使用的脚本检查标志(INHERITED_ACE不会在任何ACE上设置)。
  • 更改对象的权限(应用更改),甚至将其更改回。
  • 检查标记(INHERITED_ACE将在其中)
  • ..难以置信地摇摇头(我知道我做到了)

  • 抱歉,篇幅太长了,希望这至少有意义。

    最佳答案

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

    我得到此堆栈跟踪:



    您可以尝试“轻推”要填充的DACL吗?
    我的意思是,如果您对它稍加更改后就知道它可以工作...以编程方式稍作更改,请添加一个 stub ACE并将其删除。你可以吗?

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

    这是我的运行的示例输出:



    我的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();
        }
    }
    

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

    关于python - 确定是否继承了ntfs权限的可靠方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/910696/

    10-13 08:10