5

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

我需要什么:确定文件/文件夹的权限(或者,严格来说,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 是否被继承。

如何重现:

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

抱歉,这篇文章有点冗长,希望这至少有点意义。

4

3 回答 3

1

您可以使用 .Net 框架

System.Security.AccessControl

这包括 ACL 和 DACL 和 SACL。

于 2009-06-24T02:32:39.537 回答
1

我认为原始海报正在看到详细的行为

此新闻组发布

请注意,在容器上设置的控制标志可以通过取消勾选和重新勾选 GUI 中的继承框来更改。

进一步注意,使用 Microsoft 的工具简单地将 ACE 添加到 DACL 也会更改控制标志。

进一步注意,由于新闻组发布中讨论的许多细微错误,在继承方面不能依赖 GUI、cacls 和 icacls。

似乎控制继承的“旧”方法是结合使用容器上的控制标志与继承相关的 ACE 标志。

“新”方式不使用容器上的控制标志,而是使用重复的 ACE;一个控制对对象的访问,另一个控制子对象继承的内容。

但是,现有的 Microsoft 工具(例如 Vista)似乎还不能以“新”方式工作,因此当您使用工具进行简单更改时,它会求助于在容器上使用控制标志的旧方式。

如果你在 Vista 上创建一个新分区,然后创建一个新文件夹,然后查看标志和 ACE,它看起来像这样

ControlFlags : 0x8004
Owner : BUILTIN\Administrators
Group : WS1\None
S-1-5-32-544 : BUILTIN\Administrators : 0x0 : 0x0 : 0x1F01FF
S-1-5-32-544 : BUILTIN\Administrators : 0x0 : 0xB : 0x10000000
S-1-5-18 : NT AUTHORITY\SYSTEM : 0x0 : 0x0 : 0x1F01FF
S-1-5-18 : NT AUTHORITY\SYSTEM : 0x0 : 0xB : 0x10000000
S-1-5-11 : NT AUTHORITY\Authenticated Users : 0x0 : 0x0 : 0x1301BF
S-1-5-11 : NT AUTHORITY\Authenticated Users : 0x0 : 0xB : 0xE0010000
S-1-5-32-545 : BUILTIN\Users : 0x0 : 0x0 : 0x1200A9
S-1-5-32-545 : BUILTIN\Users : 0x0 : 0xB : 0xA0000000

请注意 ControlFlags 和重复的 ACE。

于 2010-02-06T12:50:53.143 回答
0

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

我得到这个堆栈跟踪:

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

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

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

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

这是我运行的示例输出:

C:>csharp_tricks.exe 2.txt

FullControl --> IsInherited: True

FullControl --> IsInherited: True

ReadAndExecute,同步 --> IsInherited: True


C:>1.py 2.txt

2.txt

内置\管理员 0x0

NT AUTHORITY\SYSTEM 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();
    }
}

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

于 2009-06-24T20:58:07.857 回答