2

I've been trying to use the Windows 10 icacls utility to do this. I did some searching here, and I found this, but it doesn't my specific question. I tried adding a comment to this question, but I don't have enough reputations.

As an administrator on my Windows 10 Professional machine, I want to prevent local users from deleting executable programs, while still providing executable access (like the Linux chmod rx command). I've set the file owner to Administrator. I've been trying to achieve this using the utility, as follows.

For the specified (non-administrator) user, the following all prevent the file being deleted, but also disable executable access

  • icacls /deny user:W
  • icacls /deny user:M
  • icacls /deny user:(D)
  • icacls /deny user:(WO)
  • icacls /deny user:F followed by /grant user:(RX)

The following allows executable access, but also allows the file to be deleted

  • icacls /deny user:(WDAC)

Is what I'm trying to do even possible? It seems that executable and write access are identical?

Paul
  • 131

2 Answers2

2

Yes, it's possible – that's how all of the system executables are set up. You can execute notepad.exe but you cannot write to it, because you're only granted (RX) permissions to that file.

But every one of your attempts is mistaken in the assumption that /deny removes permission bits. That's not what it does – it adds an explicit denial, a concept that doesn't exist in Linux file modes. Explicit "Deny" entries within an ACL always have a higher priority than "Allow" entries, so after you have /denied F (full control) to a user, no amount of /grant will override that.

(Unix file modes and even POSIX ACLs are exclusive – either you're granted "owner" permissions or "group" permissions, but not both – so there's no difference between removing and denying a permission. However, Windows-style ACLs are additive, as in you're granted the sum of all rights granted to all SIDs that you match, so there is a need to have an "explicit deny" that overrides broader grants.)

Now in theory, /deny Foo:W would still do what you want (even if it's not the right way to do it). But due to some historical design issues, the W and M macros (each of which expands to several distinct permission bits) are not usable within 'deny' ACEs as they slightly overlap with R (in the Synchronize right, which is obscure enough that many tools won't even show it). The other post's comments have a longer explanation.

The correct way to do what you want is by removing the unwanted rights from all access entries, rather than adding denials. Unfortunately icacls lacks an option to clear or "un-grant" only specific rights from an entry, so instead you'll have to /remove the whole entries that grant excessive permissions, then re-/grant only read/execute rights to the same users or groups.

For example, if your directory has read+write rights granted to (for example) the "Users" group, you'll need to /remove Users followed by /grant Users:(OI)(CI)(RX).


Keep in mind also that renaming or deleting a file isn't necessarily a right on the file itself – it's a right on the parent directory, as you rename files by "writing" the list of files (i.e. the…directory).

So in order for your protection to be useful, it needs to be defined on the directory itself (and inherited by files) – there's no point in trying to write-restrict individual items within a directory that still allows everyone to move those items aside and replace them with new ones.

grawity
  • 501,077
1

I think I've found the answer. Explained here

This prevents the exe-file from being deleted or modified, and grants it read/write access to its local directory.

Summary:

  • icacls directory/inheritance:d /grant:r Users:(OI)(IO)
  • icacls directory/remove:g Users /C
  • icacls directory/remove:d Users /C
  • icacls directory/grant:r Users:(RX)
  • icacls directory /deny Users:(DE)
  • cd directory
  • icacls exe-file /inheritance:d /grant:r "Users:(OI)(IO)"
  • icacls exe-file /remove:g "Users"
  • icacls exe-file /remove:d "Users"
  • icacls exe-file /grant:r "Users:(RX)"
  • icacls exe-file /deny "Users":(DE)

Not quite as simple as chmod 7555 ;<)

Paul
  • 131