PowerShell Remoting Project Home

Monday, January 16, 2006

Combination Rights, Inheritance and Propagation Settings of File System Access Rules

A more complexed example of combination rights, inheritance and propagation settings of access rules for directory.

Yesterday, I happened to find a code example of manipulating ACLs for .NET framework 1.0: ACLs in .NET: A C# library containing wrapper classes for ACL, ACE, Security descriptors, Security Attributes, Access tokens, etc. It is so complicated to working on platform invokation. As you can see from my previous blog entry Play with ACL in MSH, Play with ACL in MSH (continued) and /\/\o\/\/'s blog entry Adding a Simple AccesRule to a file ACL in MSH, with  .NET 2.0 things getting much easier. Today I am going to dig a little deeper and talk about more  complex example.

1. We have to deal with FileSystemRights enumeration when creating a new FileSystemAccessRule object. We can see from following that FileSystemRights contain 23 names:
[system.enum]::getnames([System.Security.AccessControl.FileSystemRights])
ListDirectory
ReadData
WriteData
CreateFiles
CreateDirectories
AppendData
ReadExtendedAttributes
WriteExtendedAttributes
Traverse
ExecuteFile
DeleteSubdirectoriesAndFiles
ReadAttributes
WriteAttributes
Write
Delete
ReadPermissions
Read
ReadAndExecute
Modify
ChangePermissions
TakeOwnership
Synchronize
FullControl

FileSystemRights enumeration has a FlagsAttribute attribute that allows a bitwise combination of its member values. In MSH, "-bor" is used as "Bitwise OR" Operator. To better understand that, we can find from following example that "Read" actually means ReadData | ReadExtendedAttributes | ReadAttributes |ReadPermissions.
[int]([System.Security.AccessControl.FileSystemRights]::Read)
131209
[System.Security.AccessControl.FileSystemRights]::ReadData `
-bor [System.Security.AccessControl.FileSystemRights]::ReadExtendedAttributes `
-bor [System.Security.AccessControl.FileSystemRights]::ReadAttributes `
-bor [System.Security.AccessControl.FileSystemRights]::ReadPermissions
131209

Added on 2006-01-17 12:27
Marcel Comment:"A comma separated list of values cast can be cast to a flags enum."
[System.Security.AccessControl.FileSystemRights] "ReadData, ReadExtendedAttributes, ReadAttributes, ReadPermissions"

Will do same thing!

So it is easier to use the combination values such as FullControl, Read and Write, rather than specifying each component value separately. But we still can build a custumized value such as "Read OR Write" as below.
$Rights= [System.Security.AccessControl.FileSystemRights]::Read `
-bor [System.Security.AccessControl.FileSystemRights]::Write
2. All of our previous examples were simple because we never deal with inheritance and propagation settings. If a directroy contain both files and child directory, things get more compicated. Every access rule is either explicit or inherited: inherited rules come from a parent container while explicit rules are added by user later on. So you can only manipulate its explicit rules.
There are two inheritance flags: container inherit (CI), object inherit (OI) and None.
There are two propagation flags: inherit only (IO), no-propagate inherit (NP) and None.
$Inherit=[System.Security.AccessControl.InheritanceFlags]::ContainerInherit `
        -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit
$Prop=[System.Security.AccessControl.PropagationFlags]::InheritOnly
Now we can construct our access rule and set it to a directory:
# set AccessControlType : Allow / Deny
$Access=[System.Security.AccessControl.AccessControlType]::Allow
# create new access rule
$AccessRule = new-object System.Security.AccessControl.FileSystemAccessRule `
("testac",$Rights,$Inherit,$Prop,$Access)
# validate access rule
$Sid = $AccessRule.IdentityReference.Translate`
([System.Security.Principal.securityidentifier])
$ACL=get-acl D:\msh\tmp
$ACL.AddAccessRule($AccessRule)
set-acl -AclObject $ACL -Path D:\msh\tmp

 3. What if you do NOT want to inherit access rules from you parents?
$ACL=get-acl D:\msh\tmp
$ACL.SetAccessRuleProtection(
           # changes from parent won't propagate
           $true,
           # do not keep current inheritance settings
           $false );
set-acl -AclObject $ACL -Path D:\msh\tmp
Reference: Manage Access to Windows Objects with ACLs and the .NET Framework

[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]

Tags:       


Comments:
Instead of typing all of this:

[System.Security.AccessControl.FileSystemRights]::ReadData `
-bor [System.Security.AccessControl.FileSystemRights]::ReadExtendedAttributes `
-bor [System.Security.AccessControl.FileSystemRights]::ReadAttributes `
-bor [System.Security.AccessControl.FileSystemRights]::ReadPermissions

You can always do this:

[System.Security.AccessControl.FileSystemRights] "ReadData, ReadExtendedAttributes, ReadAttributes, ReadPermissions"

A comma separated list of values cast can be cast to a flags enum.
 
Nice Tips! Thank you
 
This looks like the way to go for me, however I only want to produce a CSV of ACLs, Inheritance and perhaps share settings of a large tree of folders and ideally use this CSV to reverse settings automatically afterwards, if necessary. I need this to safeguard any settings before I correct inheritance settings on a few network shares. Could anyone help me ?

Thanks, Marc

marc DOT dieleman AT helphire.co.uk
 

Post a Comment





<< Home