Unable to set ACL using Set-ACL when not admin on ACL protected folder - by Michael V DK

Status : 

 


7
0
Sign in
to vote
ID 789418 Comments
Status Active Workarounds
Type Suggestion Repros 2
Opened 6/3/2013 11:43:13 PM
Access Restriction Public

Description

Under a sudden condition PowerShell's Set-ACL fails when trying to set permissions on a folder on a NTFS volume.

Error:
Set-ACL : The process does not possess the 'SeSecurityPrivilege' privilege which is required for this operation.
 
At line:48 char:1
 
+ Set-ACL -path $path -AclObject $ACL
 
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
    + CategoryInfo          : PermissionDenied: (\\server\share\subfolder1:String) [Set-Acl], PrivilegeNotHeldException
 
    + FullyQualifiedErrorId : System.Security.AccessControl.PrivilegeNotHeldException,Microsoft.PowerShell.Commands.SetAclCommand


Conditions:

1) Your are not admin on the file server
2) The folder has ACL protection enabled (disabled inheritance from parent)
3) You do have full control access and ownership of the folder

Issue found using PowerShell v2 and v3

The same change kan be done with success under the same conditions using:

Windows Explorer 
FileACL.exe
CACLS.exe

The issue is that Set-ACL tries to write the whole ACL (Access + Audit + Owner). If you only try to write the Access part, then the error doesn't occur. See example in the expected results section.

It would be great if Set-ACL did the following:

Only trying to write what have been changed, so if I only changed the Access part of the ACL, then it only tries to write that back. Then the above should work.

(I guest this is the way Windows Explorer is working)

- or -

Had a parameter that lets you decide what part of ACL you would want to write.


Microsoft Support case # 113052910473011
Sign in to post a comment.
Posted by Rohn Edwards on 7/24/2015 at 6:35 PM
The issue is actually caused by the file system provider's SetSecurityDescriptor() implementation. As Michael says, it tries to write all sections of the security descriptor, including the SACL. If you're running as an administrator, it will succeed (assuming you've been granted SeSecurityPrivilege). If the SACL wasn't requested, this will have the unfortunate effect of overwriting it (see bug here: https://connect.microsoft.com/PowerShell/feedback/details/913134/set-acl-overwrites-sacl-when-run-as-administrator)

The original call checks for a PrivilegeNotHeldException, though, and tries to work around one by attempting to write the SD a second time without writing the Owner, Group, and/or SACL sections unless they don't match the sections contained in the on-disk SD for the file/folder. There's a typo in the SACL test that shows up when the DACL is protected, though. Here's the problem section:

if (fileSystemSecurity.GetAuditRules(true, true, typeFromHandle).Count == 0 && fileSystemSecurity.AreAuditRulesProtected == accessControl.AreAccessRulesProtected) {
    // Remove the AccessControlSections.Audit flag
}

The last part of the check is comparing the in-memory SD's AreAuditRulesProtected against the on-disk SD's AreAccessRulesProtected, which will always fail if the user can't view the SACL (which would make AreAuditRulesProtected -eq $false) and the DACL is protected (which makes AreAccessRulesProtected -eq $true). It should be checking it against accessControl.AreAuditRulesProtected...