Monday, December 26, 2011

Property Sets for Permissions in AD and AD LDS

A while back I needed to set up Property Sets in AD LDS for granting of permissions to many of the attributes on the person object all at once, as I reviewed the Technet documentation on AD Property Sets I realized that it doesn’t tell you what object type property sets are, nor does it tell you how to create a property set, nor does it tell you how to assign an attribute to a property set. The MSDN documentation on Property Sets lets you see which attributes where included in which property sets in the different versions of AD, and it hints that property sets are part of Control Access Rights. Finally there is some more MSDN documentation on Control Access Rights that starts to spell it out:

  • For defining property sets, to enable controlling access to a subset of an object's attributes, rather than just to the individual attributes. Using the standard access rights, a single ACE can grant or deny access to all of an object's attributes or to a single attribute. Control access rights provide a way for a single ACE to control access to a set of attributes. For example, the user class supports the Personal-Information property set that includes attributes such as street address and telephone number. Property set rights are created on controlAccessRight objects by setting the validAccesses attribute to contain both the ACTR_DS_READ_PROP (16) and the ACTRL_DS_WRITE_PROP (32) access rights.

This illustrates the first goal of my post: property sets exist in AD as controlAccessRight objects. But still doesn’t tell us where in the AD do they live. In fact they live in the CN=Extended-Rights container inside the Configuration partition(not the schema):


Digging deeper into the MSDN docs on Creating Control Access Rights illustrates how you link attributes to a property set:

If you define a control access right for a property set, use the rightsGUID of the controlAccessRight object to identify the properties in the set. Every property is defined by an attributeSchema object in the Active Directory schema. The attributeSecurityGUID property of an attributeSchema object identifies the property set, if any, that the property belongs to. Be aware that the attributeSecurityGUID property is single-valued and stores the GUID in binary format (octet string syntax).

Another goal of this post is to help by making this a little more visual.When you create a property set, you must first generate a GUID and place in the rightsGUID attribute on the controlAccessRights object. To assign an attribute to a property set you need to place this same GUID in the attributeSecurityGUID attribute on the attributeSchema object (in the Schema partition). Remember an attribute can only belong to one property set.


Take a look at the following

Instructions on how to assign permissions to someone using a Property Set

For information on how to get the GUIDs into the right forms see my post

GUIDs to Octets, GUIDs to Base64 strings and back again

Suppose I generate a GUID of 8c4ac332-975f-4717-ad7b-ba4a4e968fff by running the following PowerShell Command line


Don’t worry if your GUID is different from mine; it should be! If it isn’t let me know because I think I’ll partner with you for the lottery (aka a tax on the mathematically impaired).

Some attributes (like the attributeSecurityGUID) when edited through ADSI Edit require you to convert the GUID to octet string (for little endian systems – Intel processors are little endian): 32c34a8c5f971747ad7bba4a4e968fff

Which you can do with this one line of PowerShell script

[System.String]::Join('',(( new-object system.guid('8c4ac332-975f-4717-ad7b-ba4a4e968fff') ).ToByteArray()
ForEach-Object { $_.ToString('x2') } ) )

Then if you want to put this in an LDIF file you must base64 encode the value

so that it looks like: MsNKjF+XF0ete7pKTpaP/w==

You can do that with this one line of PowerShell

[System.Convert]::ToBase64String((new-Object system.Guid("8c4ac332-975f-4717-ad7b-ba4a4e968fff")).ToByteArray())

To convert from the Base64 string to the GUID use this line of PowerShell:

new-Object -TypeName System.Guid -ArgumentList(, ( ([System.Convert]::FromBase64String("MsNKjF+XF0ete7pKTpaP/w==")) ) )

FYI – I chose to express all of these in PowerShell as opposed to C# as many readers are not C# developers and I still wanted to give all the ability to do these transforms without the complexity of compiling code or downloading an executable.

Thanks to John Geitzen whose reply to someone else’s question helped me see how to make the correct call to be able to pass the array as a whole parameter to the guid constructor instead of it getting splatted.

Thanks to Poshololic whose comment on this post showed how to do the Guid to Octet conversion in one line.