Inheritance and Propagation in Active Directory permissions

Disclaimer:
As mentioned before I’m not a programmer, so the information in the next few posts may not be 100%. What I will pass on is what I have found in my experience, and any external links to valid sources that may help provide more detail. With this in mind if you find any inaccuracies, or just have more information to add please feel free to let me know …. :)

There are three types of permissions in regards to Active Directory security: Standard Rights, Extended Rights, and Control Access Rights. We’ve covered Standard Rights in a recent post, and in building up to the remaining two we’ll take a look at Inheritance and Propagation.

Now if we’re dealing with NTFs permissions, we use the System.Security.AccessControl namespace and the Inheritance and Propagation flags.

In AD we use a different method, but the concept is the same. There is only one flag used, and this is ActiveDirectorySecurityInheritance.

For example in NTFS you may have used:

$inherit = [system.security.accesscontrol.InheritanceFlags]“ContainerInherit”
$propagation = [system.security.accesscontrol.PropagationFlags]“InheritOnly”

In Active Directory the same result would be achieved by:

$inherit = [System.DirectoryServices.ActiveDirectorySecurityInheritance]“descendents”

An article that explains this subject well can be found on MSDN here. In particular the paragraph on inheritance and figure 5.

If we want to stop permissions being inherited from the parent Organizational Unit or container, you can use the SetAccessRuleprotection method. The syntax for which is available here
And a simple example:

$root = [adsi]“”
$test = [adsi](“LDAP://ou=Test ou,”+$root.distinguishedName)

# [bool]IsProtected, [bool]PreserveInheritance
# The second option decides whether the inherited ACE’s are copied, or dropped.
$test.psbase.get_objectsecurity().SetAccessRuleProtection($true, $false)

$test.psbase.CommitChanges()

In the next post we’ll build a couple of useful functions for retrieving data needed for Extended and Access Control Rights.

Removing ACE’s from Active Directory with PowerShell

Soon we’ll be looking into some pretty low level permission schemes that can be applied to Active Directory. For now however, following on from yesterdays post, we’ll take a look at how to remove Acccess Control Entries from the Security Descriptor in AD.

Below is our function:

$root = [adsi]“”

#———————————————————————————————————-
function remove-DSace
#———————————————————————————————————-
{
Param (
$DSobject,
$DSidentity
)
$sd = $DSobject.psbase.get_objectSecurity().getAccessRules($true, $false, [System.Security.Principal.NTAccount])
$rar = $sd |? {$_.IdentityReference -eq $DSidentity}
if ($rar -is [array])
{
foreach ($ace in $rar)
{
$DSobject.psbase.get_ObjectSecurity().RemoveAccessRule($ace)
$DSobject.psbase.commitchanges()
}
}
else
{
$DSobject.psbase.get_ObjectSecurity().RemoveAccessRule($rar)
$DSobject.psbase.commitchanges()
}
}
#———————————————————————————————————-
$ou = [adsi](“LDAP://ou=”+$ARGS[0]+”,”+$root.distinguishedName)
remove-DSace $ou $ARGS[1]

Points of interest then:
Details on the parameters for GetAccessRules are here. We then filter our rules to those that match our Group/Account as defined by the IdentityReference attribute on the object, and store these in the $rar variable. By testing if this variable is an array or not we can determine if we have one ACE or several that need removing.

Using an If..Else code block we remove the ACE or ACEs as applicable and commit our changes back to the directory. If the ACE was configured to propagate down the directory this will have the effect of completely removing that permission from everywhere.

Tomorrow we really will look into Propagation and Inheritence ;)

Active Directory Permissions – Standard Rights

We’ve previously covered manipulating NTFS permissions, and in this post we’ll take that basis and apply it to Active Directory.

Marc covered this topic on his old blog, while PowerShell was still in beta (Pre RC2). The approach is basically the same, but you need to utilise psbase in PowerShell 1.0.

So, we want to give our test user bella full control over the Test OU. I would suggest not making permission changes to your AD if you don’t know what you’re doing because things can get nasty very quickly. A bit of useful reading on the subject can be found here and here.

Below is our basic function:

#———————————————————————————————————-
function Add-DSace
#———————————————————————————————————-
{
Param (
$DSobject,
$Identifier,
$DSrights,
$AccessType = “Allow”
)
# GetAccessRules: Explicit ACE’s, Inherited ACE’s, TargetType
$account = New-Object system.security.principal.ntaccount($Identifier)

# Retrieve the SID – as a manual step you can check it’s not empty :)
$sid = $acc.translate([system.security.principal.securityidentifier])
#$sid.ToString()

$ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($account, $DSrights, $AccessType)
$DSobject.psbase.get_objectsecurity().AddAccessRule($ace)
$DSobject.psbase.CommitChanges()
}
#———————————————————————————————————-
$root = [adsi]“”
$test = [adsi](“LDAP://ou=Test OU,”+$root.distinguishedName)

Add-DSace $Test “bella” “GenericAll”

Okay, so points of interest then:

Once we’ve created a variable for the OU we want to add an ACE to, we then define our Security Principal. This can be either a user or a group, and we can present this in either SID format or as the account name.

In this example we’re targeting a user. We could have validated the account by retrieving it’s SID, but for this we’re presuming that everything exists and no checking is performed.

There are several constructors available for the ActiveDirectoryAccessRule. You can see what’s available, by looking at the constructors:

# List the constuctors available to this method:
[System.DirectoryServices.ActiveDirectoryAccessRule].GetConstructors() |% {“$_”}

I’ve found this to be a really useful way of discovering the specific requirements for a method. Once you know what types the method is expecting you can then investigate what each element is. In this instance we are utilising the following constructor:

Void .ctor(
System.Security.Principal.IdentityReference,
System.DirectoryServices.ActiveDirectoryRights,
System.Security.AccessControl.AccessControlType)

You can then either look them up on MSDN or feed in some false data, and see if the constructor will provide you with details on what it needs.

Once we have the ACE, the last two lines are where we add the ACE to the Security Descriptor and then commit our changes back to the directory.

As you can see we need to use psbase. This gives us the “raw” view of the object. I find using psbase very difficult. It’s almost a fall back, for when you can’t seem to make it work any other way. At the moment I just put it down as one of PowerShell’s little quirks ;)

Over the next few days we’ll take a closer look at Propagation, Inheritance and Active Directory Extended Rights.