A customer found that if they used the GUI and the icacls
program to deny Delete permission to a folder, the results were different, even though the resulting ACLs are the same.
Create a user, say, Bob, and create a folder, say, C:\test
.
With the GUI
- Right-click the folder and select Properties.
- Go the Security tab, click Advanced.
- Click the Add button to add a new ACE.
- Select Bob as the Principal.
- Set the Type to Deny.
- Click Show advanced permissions.
- Check Delete and uncheck everything else.
- Click OK a bunch of times to save the changes.
With icacls
- From a command prompt, type
icacls C:\test /deny Bob:D
If you followed the GUI steps, then Bob can open the directory in Explorer. On the other hand, if you followed the icacls
steps, then Bob cannot open the directory in Explorer.
In both cases, running icacls
to view the permissions report the same results:
C:\> icacls c:\test test THISPC\Bob:(DENY)(D) BUILTIN\Administrators:(I)(OI)(CI)(F) NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F) BUILTIN\Users:(I)(OI)(CI)(RX) NT AUTHORITY\Authenticated Users:(I)(M) NT AUTHORITY\Authenticated Users:(I)(OI)(CI)(IO)(M)
How is it possible that the permissions are identical, yet the results are different depending on how you set the permissions?
The problem is that your tools are lying to you. The Deny ACE on the directory is not what icacls
reports.
If you change the security with the GUI, then the Deny ACE is 0x00010000
= DELETE
. But if you change it with the icacls
program, then the Deny ACE is is 0x00110000
= DELETE | SYNCHRONIZE
.
So the icacls
program is lying when it says that it denied Delete (D) permission. It actually denied both Delete and Synchronize.
And then on top of that, the icacls
program is lying when it says that the actual ACE is a Deny D. It’s hiding the denied SYNCHRONIZE
access.
And it’s that denied SYNCHRONIZE
access which is the difference. Explorer cannot open a folder where SYNCHRONIZE
is denied. (And the command prompt cannot chdir
into such a directory either.)
I’m guessing that the icacls
is doing this extra work as a courtesy, but it also makes diagnosing problems more difficult.
Synchronise is new to me… Off to do some reading. Thanks!
Powershell appears to show everything. I’m guessing that’s best bet if this matters to you.
PS C:\>get-acl C:\test | select -expand access
. . .
FileSystemRights : Delete, Synchronize
AccessControlType : Deny
IdentityReference : Bob
. . .
Not everything. For example:
Get-Acl C:\Windows\system32 | Select-Object -ExpandProperty Access
FileSystemRights : 268435456
AccessControlType : Allow
IdentityReference : CREATOR OWNER
IsInherited : False
InheritanceFlags : ContainerInherit, ObjectInherit
PropagationFlags : InheritOnly
FileSystemRights : 268435456
AccessControlType : Allow
IdentityReference : NT AUTHORITY\SYSTEM
IsInherited : False
InheritanceFlags : ContainerInherit, ObjectInherit
PropagationFlags : InheritOnly
...
Update: 268435456, I believe is “Generic_ALL” or “Full control”
I would definitely call this a bug. "(D)" is the friendly shorthand for a group of rights (0x00110000) The indicator for Delete alone (0x00010000), without the rest of the group, is "(DE)".
icacls should be showing "(D)" for the file it acted on, where both Delete and Synchronize are in the ACE. And it should be showing "(DE)" for the permissions as set by the GUI, where only Delete appears in the ACE.
From...
It’s not a bug, it’s PEBKAC: the correct command is “icacls C:\test /deny Bob:DE”
It’s a bug that “/deny Bob:DE” results in “(D)” on inspection.
Still PEBKAC, or "you too, Brutus": you use the wrong tool for "inspection"!
Both CACLS.exe C:\test /S and CACLS.exe C:\test show the correct ACE set by ICACLS.exe C:\test /Deny Bob:(D) as well as ICACLS.exe C:\test /Deny Bob:(DE)
I recommend to read the title of Raymond's post, CAREFUL!
Also ignore the wrong part "even though the resulting ACLs are the same" of his first sentence: the ACLs differ.
“This command has been deprecated. Please use icacls instead.”
Btw, that doesn’t change the idea that apparently this is a bug in ICACLS command for displaying information inaccurately.
https://docs.microsoft.com/en-us/windows/win32/fileio/file-security-and-access-rights
Note: the NTFS.com description of the flag is much better than the Microsoft description, in my opinion. But that's just my opinion.
"Note that you cannot use an access-denied ACE to deny only GENERIC_READ or only GENERIC_WRITE access to a file. This is because for file objects, the generic mappings for both GENERIC_READ or GENERIC_WRITE include the SYNCHRONIZE access right. If an ACE denies GENERIC_WRITE access to a trustee, and the trustee requests GENERIC_READ access,...
But I suppose the icacls behavior is a compatibility constraint now and can’t be fixed.