如何让 Windows 重新计算文件的继承权限?
一个工具 (Mercurial) 从不同的目录创建了指向同一文件的多个 NTFS 硬链接。我可以看到它们使用fsutil hardlink list
。这不会更改文件的 ACL。但我现在希望文件从第二个父文件夹继承 ACL。我该怎么做?我该如何对整个子树执行此操作?
icacls /inheritance:e
似乎没帮助……
旧事物新有两篇关于继承权限和硬链接的文章:
但似乎也没有提到如何触发这种重新计算。
答案1
我在寻找如何触发权限重新计算时遇到了这个问题,所以部分原因是我想留下一个答案,以便下一个人可以找到如何触发重新计算,但是 ACL 和硬链接如何交互的问题引起了我的兴趣,所以我进行了一些实验。
我不是 NTFS 权限方面的专家,所以可能遗漏了某些内容。但七年过去了,部分答案可能比没有答案要好。我希望得到专家的纠正。
对于“如何触发这种重新计算”这个狭义问题,简短的回答是使用/reset
选择icacls
:
icacls filename /reset
添加/t
获取递归的选项,此时您可能还需要/q
和/c
。
那么这与硬链接如何交互?答案似乎是,应用于文件的 ACL 将是您传递给 的文件的一个路径的计算 ACL icacls /reset
。
这意味着,您的问题的答案“我现在希望文件从第二个父文件夹继承 ACL”意味着它取决于您是否希望这样做:
- 该文件从第二个父级继承 ACL此外来自第一个父母的 ACL;或
- 该文件从第二个父级继承 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)
接下来,我在两个目录之一下创建了一个文件,并且正如预期的那样,它从其父目录继承了权限:
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)
接下来,我创建了从第二个目录到该文件的硬链接。正如提问者所报告的那样,该文件的权限没有改变。该文件保留了创建时从第一个目录继承的权限。
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)
如果我现在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)
正如您所料,将应用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)
如果我尝试发出一个针对两个文件的 icacls 命令,例如,icacls *.txt /t /reset
它仍然不起作用。我获得两组权限中的一组(用户 1 或用户 2,但不是两者)。哪一个取决于 icacls 处理路径的顺序。