Setting a file to "Read-Only" in Windows with ICACLS
I knew how to set a file Read-Only with cacls:
cacls "toto.txt" //E //P Everyone:N cacls "toto.txt" //E //G Everyone:RIt removed all rights for everyone and then only added "Read" right.
How to do the same thing with icacls?
In particular, I tried:
icacls toto.txt /grant "everyone":Rbut the file is still writableicacls toto.txt /deny "everyone":Wbut the file is not readable anymore
2 Answers
The problem is that access rights are inherited from the parent folder.
The following 2 lines will do the trick:
icacls toto.txt /inheritance:r
icacls toto.txt /grant "everyone":RThe first additional line will remove all inheritance.
Or even better, you could join them into a single line:
icacls toto.txt /inheritance:r /grant:r Everyone:R 1 This is a bug in icacls, to this day. The same goes for making folders read only. Denying "W" also denies the "SYNCHRONIZE" right.
You can see it with cacls:
Everyone:(DENY)(special access:) SYNCHRONIZE FILE_WRITE_DATA FILE_APPEND_DATA FILE_WRITE_EA FILE_WRITE_ATTRIBUTESTo get the result you want, you have to specify those other 4 rights explicitly:
icacls toto.txt /deny "everyone":(WD,AD,WEA,WA)And then cacls will tell you SYNCHRONIZE is no longer denied, and the file is still readable.
Everyone:(DENY)(special access:) FILE_WRITE_DATA FILE_APPEND_DATA FILE_WRITE_EA FILE_WRITE_ATTRIBUTESIcacls will give the same output after using either command, with or without synchronize:
Everyone:(DENY)(W)See also this blog: I set the same ACL with the GUI and with icacls, yet the results are different
NOTE If you wonder what "Synchronize" does, here is a description:
"Synchronize
The Synchronize permission allows or denies different threads to wait on the handle for the file or folder and synchronize with another thread that may signal it. This permission applies only to multiple-threaded, multiple-process programs."
Furthermore, .Net does not allow you to deny both write and synchronize. (Powershell). Icacls does something that's not even allowed in .Net. FileSystemAccessRights gets reduced to "Write" only.
New-Object System.Security.AccessControl.FileSystemAccessRule( 'Users','Write, Synchronize','Deny')
FileSystemRights : Write
AccessControlType : Deny
IdentityReference : Users
IsInherited : False
InheritanceFlags : None
PropagationFlags : None 2