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

时间:2022-06-08 09:06:12

I have a somewhat obscure question here.

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

What I need: To determine if the permissions (or, strictly speaking, a specific ACE of a DACL) of a file/folder was inherited.

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

How I tried to solve this: using winapi bindings for python (win32security module, to be precise). Here is the stripped down version, that does just that, - it simply takes a path to a file as an argument and prints out ACEs one by one, indicating which flags are set.

我是如何尝试解决这个问题的:使用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:])

Simple enough - get a security descriptor, get a DACL from it then iterate through the ACEs in the DACL. The really important bit here is INHERITED_ACE access flag. It should be set when the ACE is inherited and not set explicitly.

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

When you create a folder/file, its ACL gets populated with ACEs according to the ACEs of the parent object (folder), that are set to propagate to children. However, unless you do any change to the access list, the INHERITED_ACE flag will NOT be set! But the inherited permissions are there and they DO work.

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

If you do any slight change (say, add an entry to the access list, apply changes and delete it), the flag magically appears (the behaviour does not change in any way, though, it worked before and it works afterwards)! What I want is to find the source of this behaviour of the INHERITED_ACE flag and, maybe find another reliable way to determine if the ACE was inherited or not.

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

How to reproduce:

如何重现:

  1. Create an object (file or folder)
  2. 创建一个对象(文件或文件夹)
  3. Check permissions in windows explorer, see that they have been propagated from the parent object (using, say, security tab of file properties dialog of windows explorer).
  4. 检查Windows资源管理器中的权限,查看它们是否已从父对象传播(例如,使用Windows资源管理器的文件属性对话框的安全选项卡)。
  5. Check the flags using, for example, the script I was using (INHERITED_ACE will NOT be set on any ACEs).
  6. 例如,使用我正在使用的脚本检查标志(不会在任何ACE上设置INHERITED_ACE)。
  7. Change permissions of an object (apply changes), change them back even.
  8. 更改对象的权限(应用更改),甚至更改它们。
  9. Check the flags (INHERITED_ACE will be there)
  10. 检查标志(INHERITED_ACE将在那里)
  11. ..shake your head in disbelief (I know I did)
  12. ..难以置信地摇头(我知道我做过)

Sorry for a somewhat lengthy post, hope this makes at least a little sense.

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

3 个解决方案

#1


0  

On my Win XP Home Edition this code doesn't seem to work at all :-)

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

I get this stack trace:

我得到这个堆栈跟踪:

Traceback (most recent call last):
File "C:\1.py", line 37, in main(sys.argv[1:])
File "C:\1.py", line 29, in main for ace_index in range(dacl.GetAceCount()):

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

AttributeError: 'NoneType' object has no attribute 'GetAceCount'

AttributeError:'NoneType'对象没有属性'GetAceCount'

Can you just try to "nudge" the DACL to be filled? I mean, if you know it's going to work after you make a slight change in it... do a slight change programmatically, add a stub ACE and remove it. Can you?

你能尝试“轻推”DACL吗?我的意思是,如果你知道它在你做了一些细微的改变之后就会起作用......以编程方式做一点改动,添加一个存根ACE并将其删除。你可以吗?

UPDATE. I made an experiment with a C# program on my work machine (with Win XP Prof) and I must tell you that the .net way of getting this security information actually works. So, when I create a new file, my C# program detects that the ACEs were inherited, while your python code doesn't.

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

Here is the sample output of my runs:

以下是我的运行的示例输出:

C:>csharp_tricks.exe 2.txt

C:> csharp_tricks.exe 2.txt

FullControl --> IsInherited: True

FullControl - > IsInherited:True

FullControl --> IsInherited: True

FullControl - > IsInherited:True

ReadAndExecute, Synchronize --> IsInherited: True

ReadAndExecute,Synchronize - > IsInherited:True


C:>1.py 2.txt

C:> 1.py 2.txt

2.txt

2.txt

BUILTIN\Administrators 0x0

BUILTIN \ Administrators 0x0

NT AUTHORITY\SYSTEM 0x0

NT AUTHORITY \ SYSTEM 0x0

BUILTIN\Users 0x0

BUILTIN \ Users 0x0

My C# class:

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

So, it seems to be a bug in the python pywin32 security library. Maybe they aren't doing all the necessary system calls...

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

#2


1  

You can use the .Net framework

您可以使用.Net框架

System.Security.AccessControl

This covers ACL and DACL and SACL.

这包括ACL和DACL以及SACL。

#3


1  

I think the original poster is seeing behavior detailed in

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

This newsgroup posting

这个新闻组发布

Note that the control flags set on the container can change simply by un-ticking and re-ticking the inheritance box in the GUI.

请注意,容器上设置的控制标志只需通过取消勾选并重新勾选GUI中的继承框即可更改。

Further note that simply adding an ACE to the DACL using Microsoft's tools will also change the control flags.

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

Further note that the GUI, cacls and icacls can NOT be relied on when it comes to inheritance due to many subtle bugs as discussed in the newsgroup posting.

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

It seems that the "old" way of controlling inheritance was to use the control flags on the container in combination with inheritance related ACE flags.

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

The "new" way does not use the control flags on the container and instead uses duplicate ACEs; one to control the access on the object and a second one to control what is inherited by child objects.

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

BUT, it seems the existing Microsoft tools (e.g. Vista) can not work in the "new" way yet, so when you make a simple change using the tools, it resorts to the old way of using control flags on the container.

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

If you create a new partition on Vista, then create a new folder, then look at the flags and ACEs, it will look something like this

如果你在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

Note the ControlFlags and the duplicated ACEs.

请注意ControlFlags和重复的ACE。

#1


0  

On my Win XP Home Edition this code doesn't seem to work at all :-)

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

I get this stack trace:

我得到这个堆栈跟踪:

Traceback (most recent call last):
File "C:\1.py", line 37, in main(sys.argv[1:])
File "C:\1.py", line 29, in main for ace_index in range(dacl.GetAceCount()):

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

AttributeError: 'NoneType' object has no attribute 'GetAceCount'

AttributeError:'NoneType'对象没有属性'GetAceCount'

Can you just try to "nudge" the DACL to be filled? I mean, if you know it's going to work after you make a slight change in it... do a slight change programmatically, add a stub ACE and remove it. Can you?

你能尝试“轻推”DACL吗?我的意思是,如果你知道它在你做了一些细微的改变之后就会起作用......以编程方式做一点改动,添加一个存根ACE并将其删除。你可以吗?

UPDATE. I made an experiment with a C# program on my work machine (with Win XP Prof) and I must tell you that the .net way of getting this security information actually works. So, when I create a new file, my C# program detects that the ACEs were inherited, while your python code doesn't.

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

Here is the sample output of my runs:

以下是我的运行的示例输出:

C:>csharp_tricks.exe 2.txt

C:> csharp_tricks.exe 2.txt

FullControl --> IsInherited: True

FullControl - > IsInherited:True

FullControl --> IsInherited: True

FullControl - > IsInherited:True

ReadAndExecute, Synchronize --> IsInherited: True

ReadAndExecute,Synchronize - > IsInherited:True


C:>1.py 2.txt

C:> 1.py 2.txt

2.txt

2.txt

BUILTIN\Administrators 0x0

BUILTIN \ Administrators 0x0

NT AUTHORITY\SYSTEM 0x0

NT AUTHORITY \ SYSTEM 0x0

BUILTIN\Users 0x0

BUILTIN \ Users 0x0

My C# class:

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

So, it seems to be a bug in the python pywin32 security library. Maybe they aren't doing all the necessary system calls...

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

#2


1  

You can use the .Net framework

您可以使用.Net框架

System.Security.AccessControl

This covers ACL and DACL and SACL.

这包括ACL和DACL以及SACL。

#3


1  

I think the original poster is seeing behavior detailed in

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

This newsgroup posting

这个新闻组发布

Note that the control flags set on the container can change simply by un-ticking and re-ticking the inheritance box in the GUI.

请注意,容器上设置的控制标志只需通过取消勾选并重新勾选GUI中的继承框即可更改。

Further note that simply adding an ACE to the DACL using Microsoft's tools will also change the control flags.

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

Further note that the GUI, cacls and icacls can NOT be relied on when it comes to inheritance due to many subtle bugs as discussed in the newsgroup posting.

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

It seems that the "old" way of controlling inheritance was to use the control flags on the container in combination with inheritance related ACE flags.

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

The "new" way does not use the control flags on the container and instead uses duplicate ACEs; one to control the access on the object and a second one to control what is inherited by child objects.

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

BUT, it seems the existing Microsoft tools (e.g. Vista) can not work in the "new" way yet, so when you make a simple change using the tools, it resorts to the old way of using control flags on the container.

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

If you create a new partition on Vista, then create a new folder, then look at the flags and ACEs, it will look something like this

如果你在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

Note the ControlFlags and the duplicated ACEs.

请注意ControlFlags和重复的ACE。