为硬链接重新计算 Windows 继承的 ACL

Pet*_*ter 6 windows permissions hardlink access-control-list

如何让 Windows 重新计算文件的继承权限?

一个工具 (Mercurial) 从不同目录创建了多个指向同一文件的 NTFS 硬链接。我可以看到他们使用fsutil hardlink list. 这不会更改文件的 ACL。但我现在希望该文件从第二个父文件夹继承 ACL。我怎样才能做到这一点?我怎样才能为整个子树做到这一点?

icacls /inheritance:e 似乎没有帮助...

Old New Thing有两篇关于继承权限和硬链接的文章:

但似乎也没有提到如何触发这种重新计算。

小智 2

我在寻找如何触发权限重新计算时遇到了这个问题,所以部分我想留下一个答案,以便下一个人可以找到如何触发重新计算,但是 ACL 和硬链接如何交互的问题引起了我的兴趣,所以我运行了一些实验。

我不是 NTFS 权限方面的专家,所以我可能错过了一些东西。但七年后,部分答案可能比没有答案要好。希望专家指正。

对“如何触发此类重新计算”这个狭隘问题的简短回答是使用以下/reset选项icacls

icacls filename /reset
Run Code Online (Sandbox Code Playgroud)

添加/t获得递归的选项,此时您可能还需要/q/c

那么它如何与硬链接交互呢?答案似乎是,应用于该文件的 ACL 将是为您传递到的文件的一个路径计算的 ACL icacls /reset

这意味着,您的问题“我现在希望该文件继承第二个父文件夹的 ACL”的答案意味着这取决于您是否愿意:

  1. 除了第一个父文件的 ACL 之外,该文件还继承第二个父文件的 ACL;或者
  2. 该文件从第二个父级继承 ACL,而不是从第一个父级继承 ACL。

第二个选项似乎可以通过使用icacls /reset第二个父级的路径(也许使用/t)来实现。第一个选项似乎并不容易实现。

这是我的实验。在每种情况下,我都会给出命令,然后给出一个小图表。

首先,我创建了两个具有不同可继承权限的文件夹:

C:\Users\User0\AppData\Local\Temp>md icacls_test

C:\Users\User0\AppData\Local\Temp>cd icacls_test

C:\Users\User0\AppData\Local\Temp\icacls_test>md foo

C:\Users\User0\AppData\Local\Temp\icacls_test>md bar

C:\Users\User0\AppData\Local\Temp\icacls_test>icacls foo /grant User1:(oi)(ci)(rx)
processed file: foo
Successfully processed 1 files; Failed processing 0 files

C:\Users\User0\AppData\Local\Temp\icacls_test>icacls bar /grant User2:(oi)(ci)(rx)
processed file: bar
Successfully processed 1 files; Failed processing 0 files


                             c:\
                              |
                            Users
                              |
                            User0
                         +user0:(oi)(ci)(f)
                              :
                              :
                         icacls_test
                        /           \
                      foo           bar
            +user1:(oi)(ci)(rx)  +user2:(oi)(ci)(rx)
Run Code Online (Sandbox Code Playgroud)

接下来,我在两个目录之一下创建了一个文件,正如预期的那样,它继承了其父目录的权限:

C:\Users\User0\AppData\Local\Temp\icacls_test>cd foo

C:\Users\User0\AppData\Local\Temp\icacls_test\foo>copy con: baz.txt
Baz
^Z
        1 file(s) copied.

C:\Users\User0\AppData\Local\Temp\icacls_test\foo>icacls baz.txt
baz.txt ThisMachine\User1:(I)(RX)
        NT AUTHORITY\SYSTEM:(I)(F)
        BUILTIN\Administrators:(I)(F)
        ThisMachine\User0:(I)(F)

Successfully processed 1 files; Failed processing 0 files

                             c:\
                              |
                            Users
                              |
                            User0
                         +user0:(oi)(ci)(f)
                              :
                              :
                         icacls_test
                        /           \
                      foo           bar
            +user1:(oi)(ci)(rx)  +user2:(oi)(ci)(rx)
                       |
                    baz.txt
            user0:(f) user1(rx)
Run Code Online (Sandbox Code Playgroud)

接下来,我创建了从第二个目录到该文件的硬链接。据提问者报告,文件的权限没有更改。该文件保留创建时从第一个目录继承的权限。

C:\Users\User0\AppData\Local\Temp\icacls_test\foo>cd ..

C:\Users\User0\AppData\Local\Temp\icacls_test>cd bar

C:\Users\User0\AppData\Local\Temp\icacls_test\bar>fsutil hardlink create link.txt c:\Users\User0\AppData\Local\Temp\icacls_test\foo\baz.txt
Hardlink created for C:\Users\User0\AppData\Local\Temp\icacls_test\bar\link.txt <<===>> c:\Users\User0\AppData\Local\Temp\icacls_test\foo\baz.txt

C:\Users\User0\AppData\Local\Temp\icacls_test\bar>icacls link.txt
link.txt ThisMachine\User1:(I)(RX)
         NT AUTHORITY\SYSTEM:(I)(F)
         BUILTIN\Administrators:(I)(F)
         ThisMachine\User0:(I)(F)

Successfully processed 1 files; Failed processing 0 files


                             c:\
                              |
                            Users
                              |
                            User0
                         +user0:(oi)(ci)(f)
                              :
                              :
                         icacls_test
                        /           \
                      foo           bar
            +user1:(oi)(ci)(rx)  +user2:(oi)(ci)(rx)
                       |               |
                    baz.txt        link.txt
                        \             /
                         \           /
                          \         /
                      user0:(f) user1:(rx)
Run Code Online (Sandbox Code Playgroud)

如果我现在使用icacls /reset文件的新路径,将使用沿该路径(即从第二个目录)继承的权限重新计算 ACL,并且这些权限将覆盖当前的 ACL。这意味着从第一个目录继承的权限将丢失:

C:\Users\User0\AppData\Local\Temp\icacls_test\bar>icacls link.txt /reset
processed file: link.txt
Successfully processed 1 files; Failed processing 0 files

C:\Users\User0\AppData\Local\Temp\icacls_test\bar>cd ..

C:\Users\User0\AppData\Local\Temp\icacls_test>icacls *.txt /t
bar\link.txt ThisMachine\User2:(I)(RX)
             NT AUTHORITY\SYSTEM:(I)(F)
             BUILTIN\Administrators:(I)(F)
             ThisMachine\User0:(I)(F)

foo\baz.txt ThisMachine\User2:(I)(RX)
            NT AUTHORITY\SYSTEM:(I)(F)
            BUILTIN\Administrators:(I)(F)
            ThisMachine\User0:(I)(F)

Successfully processed 2 files; Failed processing 0 files


                             c:\
                              |
                            Users
                              |
                            User0
                         +user0:(oi)(ci)(f)
                              :
                              :
                         icacls_test
                        /           \
                      foo           bar
            +user1:(oi)(ci)(rx)  +user2:(oi)(ci)(rx)
                       |               |
                    baz.txt        link.txt
                        \             /
                         \           /
                          \         /
                      user0:(f) user2:(rx)
Run Code Online (Sandbox Code Playgroud)

正如您所期望的,将 an 应用于icacls /reset第一个路径会产生相反的效果:从第一个目录继承的权限将被恢复,而从第二个目录继承的权限将丢失。

C:\Users\User0\AppData\Local\Temp\icacls_test>icacls foo\baz.txt /reset
processed file: foo\baz.txt
Successfully processed 1 files; Failed processing 0 files

C:\Users\User0\AppData\Local\Temp\icacls_test>icacls *.txt /t
bar\link.txt ThisMachine\User1:(I)(RX)
             NT AUTHORITY\SYSTEM:(I)(F)
             BUILTIN\Administrators:(I)(F)
             ThisMachine\User0:(I)(F)

foo\baz.txt ThisMachine\User1:(I)(RX)
            NT AUTHORITY\SYSTEM:(I)(F)
            BUILTIN\Administrators:(I)(F)
            ThisMachine\User0:(I)(F)

Successfully processed 2 files; Failed processing 0 files


                             c:\
                              |
                            Users
                              |
                            User0
                         +user0:(oi)(ci)(f)
                              :
                              :
                         icacls_test
                        /           \
                      foo           bar
            +user1:(oi)(ci)(rx)  +user2:(oi)(ci)(rx)
                       |               |
                    baz.txt        link.txt
                        \             /
                         \           /
                          \         /
                      user0:(f) user1:(rx)
Run Code Online (Sandbox Code Playgroud)

如果我尝试发出一个针对这两个文件的 icacls 命令,那么icacls *.txt /t /reset它仍然不起作用。我获得了两组权限之一(user1 或 user2,但不是两者)。哪一个取决于 icacls 处理路径的顺序。