Frequently Asked Questions about SetACL

Frequently Asked Questions

Listing permissions in CSV format: what is the meaning of the second column (a number)?

When you instruct SetACL to list permissions in CSV format, output like the following is generated:

"ShareName",5,"DACL(not_protected):Everyone,READ_CONTROL,allow,no_inheritance"

The second column, 5 in above example, is a numerical constant defining the object type. Its value is derived from the Windows API enumeration SE_OBJECT_TYPE in AccCtrl.h. SetACL uses the following values:

Object Type Number
File/Directory 1
Service 2
Printer 3
Registry Key 4
Network Share 5
WMI Object 11

Error message: “The data area passed to a system call is too small” / “A privilege could not be enabled”

SetACL might display the following error message:

ERROR: [...] failed with: The data area passed to a system call is too small.
SetACL finished with error(s):
SetACL error message: A privilege could not be enabled

This happens if you instruct SetACL to read and/or write from/to the SACL and the privilege SE_SECURITY_NAME could not be enabled. This privilege is also called SeSecurityPrivilege and is required to access SACLs.

Either make sure the user account SetACL is run from has the privilege or, when listing permissions, do not list the SACL’s contents.

Revoking permissions may not revoke all ACEs of a trustee on a given object

SetACL offers two ways for removing ACEs for a specific trustee on an object:

  1. Action “ace” with subtype “revoke”
  2. Action “trustee” with subtype “remtrst”

When the former (1) is invoked, SetACL mainly passes the arguments to the Windows API function SetNamedSecurityInfo which then revokes the permissions, or fails to do so. In many cases, the API will fail to remove any or all ACEs of the trustee.

The latter (2) is implemented directly in SetACL which looks at all ACEs in the ACL and removes all ACEs belonging to the trustee specified.

Recommendation: If you want to safely remove all ACEs of a given trustee, use action “trustee” with subtype “remtrst”. Example:

SetACL -on "c:\Some folder" -ot file -actn trustee -trst n1:MyDomain\SomeUserOrGroup;ta:remtrst;w:dacl

Where is name to SID resolution performed?

When SetACL needs to look up the SID for a user or group name, it always does that on the “right” target system. Let me explain:

User names are specified in the format DOMAIN\ACCOUNT or COMPUTER\ACCOUNT. When SetACL needs to look up ACCOUNT, it first analyzes the DOMAIN aka COMPUTER string. If that string represents a domain, SetACL looks up the name of a domain controller and then asks that DC to give it the SID of ACCOUNT. If, on the other hand, the string represents a (workgroup) computer, SetACL asks the computer name specified for a SID to the given ACCOUNT.

This algorithm has the advantage that any name can be resolved to a SID as long as DOMAIN or COMPUTER is known to the local system (in other words: can be resolved via DNS). There need not be any trust relationships between the local machine (where SetACL is executed) and the machine “knowing” the SID of ACCOUNT. However, the current user must of course have the appropriate permissions on the other machine. If there is no trust, such permissions are easiest set up by either using identical username/password combinations on the local and the remote system or by establishing a network connection to the other computer using alternate credentials (press WIN+R, enter \\COMPUTER\C$ and press return; when prompted, enter appropriate credentials).

User and group names can, of course, also be specified without giving a domain or computer name. In that case, name lookup is performed on the local machine and all trusted domains.

Setting the owner fails with access denied

If the ownership on a directory tree is to be set recursively and currently there is NO ACCESS granted to the user issuing the command, then SetACL fails with “Access denied” on all but the top level directory. This only happens on network paths (UNC paths or mapped drives). The same command works with local drives (i.e. locally on the file server).

Example:

setacl -on \\server\share\dir1\dir2\dir3\dir4 -ot file -actn setowner -ownr n:domain\username

This will fail if the user running the command has no access to (and is not the owner of) dir1, dir2, and dir3.

Workaround: Issue the command locally instead over the network, e.g.:

setacl -on c:\data\dir1\dir2\dir3\dir4 -ot file -actn setowner -ownr n:domain\username

Fix: This issue has been fixed in SetACL 2.1. If only the action “setowner” has been specified, SetACL uses backup/restore privileges and is able to set the owner in any case.

Why can’t I restore everything I backed up earlier?

With the help of the privilege SE_BACKUP_NAME SetACL is able to read permissions of any file and registry key, as long as the user running SetACL holds the backup privilege. Unfortunately, the same is not true for writing permissions.

Although the privilege SE_RESTORE_NAME would enable SetACL to write permissions to any object (regardless of access checks, i.e. it does not matter if the user running SetACL has any access to the object or is its owner), using SE_RESTORE_NAME breaks propagation of inheritance. As a consequence, permissions restored to a folder would not propagate to files within that folder and to subfolders. This has the potential of making a very big mess of permission structures (think NT4). For this reason, the functionality to bypass access checks when restoring permissions is disabled in SetACL. Those of you that are daring enough and know how to play with the source code can enable it easily.

Workaround: To make sure that all permissions from a backup can be restored, set the owner prior to restoring permissions (setting the owner while bypassing access checks works thanks to the privilege SE_TAKE_OWNERSHIP_NAME). Example:

setacl -on d:\temp\test -ot file -actn setowner -ownr n:administrators -rec cont_obj

How do I create a backup file that can be restored later?

When creating a backup file that is suitable for restore purposes (as opposed to, for example, documentation only) you should follow these guidelines:

  • Use the SDDL format
  • When recursively backing up, make sure to only include folders (files inherit from their parent folders)
  • Do not include inherited permissions (this is the default)

Here is an example:

setacl -on d:\temp\test -ot file -actn list -lst f:sddl;w:d,s,o,g -rec cont -bckp d:\temp\backup.txt

The backup can then be restored like this:

setacl -on d:\temp\test -ot file -actn restore -bckp d:\temp\backup.txt

Which privileges are used by SetACL and for what purpose?

SetACL (tries to) use several privileges that are typically held by administrators but can be assigned to any user account if desired. Here is a list.

Privilege Remarks
SE_SECURITY_NAME Required for reading from and writing to the SACL. SetACL only tries to use this privilege if required, i.e. if you specified an operation that involves the SACL. In all other cases this privilege is not required.
SE_TAKE_OWNERSHIP_NAME Required for setting the owner without any access checks. If it cannot be enabled, SetACL can only set the owner if you have the appropriate permissions to the object in question. SetACL always tries to enable this privilege when starting up. However, if that fails, SetACL does not quit but continues while issuing a warning (“Privilege ‘Take ownership of files or other objects’ could not be enabled. SetACL’s powers are restricted. Better run SetACL with admin rights.”).
SE_BACKUP_NAME This privilege is required for reading permissions without access checks. If it cannot be enabled, SetACL can only read if you have the appropriate permissions to the object in question. SetACL always tries to enable this privilege when starting up. However, if that fails, SetACL does not quit but continues while issuing a warning (“Privilege ‘Back up files and directories’ could not be enabled. SetACL’s powers are restricted. Better run SetACL with admin rights.”).
SE_RESTORE_NAME This privilege is required for writing permissions without access checks, a functionality that is disabled in SetACL because it breaks inheritance. It is also required for setting the owner to any user. SetACL always tries to enable this privilege when starting up. However, if that fails, SetACL does not quit but continues while issuing a warning (“Privilege ‘Restore files and directories’ could not be enabled. SetACL’s powers are restricted. Better run SetACL with admin rights.”).

For information on how to configure privileges and user rights please see this article by Microsoft.

What are pseudo-protected ACLs and pseudo-inherited ACEs? [SetACL 2.1]

Pseudo-inherited ACEs are access control entries that are effectively inherited from their parent object but not marked as such in the child with the flag INHERITED_ACE. In theory this should not happen, but in reality pseudo-inherited ACEs are common. This is unfortunate since it has the potential of breaking the inheritance concept. Similar to Windows Explorer’s ACL Editor SetACL detects such pseudo-inherited ACEs (since version 2.1). If inherited ACEs are not to be displayed (the default), pseudo-inherited ACEs are now omitted, too. On the other hand, if inherited ACEs are to be displayed, SetACL marks pseudo-inherited ACEs with the tag “pseudo_inherited”.

Beginning with version 2.1.1 SetACL auto-converts pseudo-inherited ACEs to ACEs correctly marked as inherited. This happens for every security descriptor that is written.

Pseudo-protected ACLs are access control lists that do not have the inheritance protection flags (SE_DACL_PROTECTED or SE_SACL_PROTECTED) set, but nevertheless are missing inheritable permissions from their parent object. As with pseudo-inherited ACEs this should not happen in theory, but frequently does in practice. Again, this is unfortunate since it has the potential of breaking the inheritance concept. Similar to Windows Explorer’s ACL Editor SetACL detects such pseudo-protected ACLs (since version 2.1). SetACL marks pseudo-protected ACLs with the tag “pseudo_protected”.

Command-line arguments, quoting and backslashes

The command-line string needs to be parsed into parameters that can then be processed by SetACL. This parsing is generally done by the operating system. Since there is only one routine doing the “tokenizing” of command-lines, all console programs behave similarly. If every tool would implement its own tokenizing algorithm, each console program would have different bugs and other peculiarities. So all in all, you pass parameters to SetACL just as to any other console program.

For reference sake, here are the rules:

  • Parameters are separated by spaces. <A B> are two parameters. If you want <A B> to be one parameter, put quotes around them: “A B”.
  • Quotes (single or double, ‘ or “) are required only if a parameter contains spaces. You need to put quotes around the path “C:\My folder”, but not around C:\MyFolder.
  • Backslashes are treated literally, except if followed by a double quotation mark. In that case, they escape the quotation mark. This is only important for the object name parameter. If you want to specify a drive root, typing <“C:\”> fails because it becomes <C:>! You can work around this using either one of the following two techniques:
    • Do not use double quotes. Just type: C:\
    • Escape the backslash preceding the closing double quotes: “C:\\”

Listing permissions of some files in “System Volume Information” fails with access denied

When you try to list the permissions of the folder “System Volume Information” and its contents, you get access denied errors on some files. This happens although you run SetACL as administrator with the privilege SE_BACKUP_NAME which should enable SetACL to read every file on the harddisk. Here is an example:

C:\>setacl -on "d:\System Volume Information\{3808876b-c176-4e48-b7ae-04046e6cc752}" -ot file -actn list
ERROR: Parsing the SD of <\\?\d:\System Volume Information\{3808876b-c176-4e48-b7ae-04046e6cc752}> failed with: Access is denied.
 
SetACL finished with error(s):
SetACL error message: The call to GetNamedSecurityInfo () failed
Operating system error message: Access is denied.

Explanation: According to the Microsoft Knowledge Base files in “System Volume Information” with names containing the GUID {3808876b-c176-4e48-b7ae-04046e6cc752} store volume snapshots (shadow copies) and related information. The fact that SetACL gets access denied when trying to read the security descriptor of the files is an indication that there is a kernel-mode filter driver blocking access to these files. A search in Sysinternals’ Process Explorer confirms this. It shows that the “System” process with PID 4 has open handles to various files with above GUID in their names.

Dealing with ‘Access Denied’ errors

If you receive ‘Access Denied’ errors when attempting to set ACEs on an object or its subobjects, it may be because the owner of that object has removed all inherited ACEs and set an ACL which denies access even to Administrators.

The solution to this is to take ownership of the object(s) – which will then allow you to add the ACE with SetACL, but will lose the original file ownership information. In situations where some of the permissions depend on CREATOR OWNER, this could cause problems.

Before taking ownership of the objects, you can however create a backup of the owner information and restore it afterwards:

Step 1: Create the backup.

In this case we’re taking a full backup of everything under ; adjust the -rec option if this is not what you want.

SetACL -on <name> -ot <type> -actn list -lst w:o;f:sddl -bckp <backup_file_name> -rec cont_obj

Step 2: Set owner to Administrators

WARNING: In most circumstances, changing owner will allow other users to continue to access the objects, but in circumstances where CREATOR OWNER permissions have been used it may cause problems until the correct owner is restored.

SetACL -on <name> -ot <type> -actn setowner -ownr n:Administrators -rec cont_obj

Step 3: Apply your ACE

Step 4: Restore the ownership backup

SetACL -on <name> -ot <type> -actn restore -bckp <backup_file_name> -rec cont_obj