Yesterday I was at customer site to talk about identity management and as it often happens some other topics were discussed with customer tech stuff after discussing main topics. In this discussion I was asked how to read and parse security descriptor for  Active Directory object. After few questions we came to conclusion that they need this information to determine if Web application which uses user security context is allowed to read or write particular attribute.

Of course this information is available as it is stored in nTSecurityDescriptor attribute, but reading it and parsing might be a little complicated, especially if this has to be done to create list of attribute to which user account has access permissions (BTW, if You are using .NET 2.0 there is cool helper class ActiveDirectorySecurity which makes this task much easier, but in this case they were using PHP to manage data in AD). But there is easier solution for this problem.

When Active Directory object is being read with LDAP two additional parameters are constructed and available among this object's attributes.

First, allowedAttributes contains list of all object's attributes which are available to be accessed in security context used to access this object.

Second, allowedAttributesEffective is even more informative, as it contains list of attributes which can be updated with security context which was used to access this object.

Lets perform quick test using ADFIND.EXE to access CN=Jan Kowalski … object with different user's security context (we will use account tkrajewski).

adfind -b "CN=Jan Kowalski,OU=Employees,DC=w2k,DC=pl" -s base allowedAttributes

AdFind V01.32.00cpp Joe Richards (joe@joeware.net) October 2006

Using server: DC1.w2k.pl:389
Directory: Windows Server 2003

dn:CN=Jan Kowalski,OU=Location1,OU=Employees,DC=w2k,DC=pl
>allowedAttributes: msExchTUISpeed
>allowedAttributes: msExchTUIVolume
>allowedAttributes: msExchTUIPassword
>allowedAttributes: msExchVoiceMailboxID
>allowedAttributes: msExchOriginatingForest
>allowedAttributes: msExchIMAPOWAURLPrefixOverride
>allowedAttributes: msExchPfRootUrl
>allowedAttributes: msExchMailboxUrl
>allowedAttributes: msExchPoliciesExcluded
>allowedAttributes: msExchPoliciesIncluded
>allowedAttributes: msExchCustomProxyAddresses

(…)

>allowedAttributes: serialNumber
>allowedAttributes: sn
>allowedAttributes: objectCategory
>allowedAttributes: sAMAccountName
>allowedAttributes: objectSid
>allowedAttributes: nTSecurityDescriptor
>allowedAttributes: instanceType
>allowedAttributes: cn
>allowedAttributes: objectClass

1 Objects returned

Now lets try to check which attributes for this object user tkrajewski  can update:

adfind -b "CN=Jan Kowalski,OU=Employees,DC=w2k,DC=pl" -s base allowedAttributesEffective

AdFind V01.32.00cpp Joe Richards (joe@joeware.net) October 2006

Using server: DC1.w2k.pl:389
Directory: Windows Server 2003

dn:CN=Jan Kowalski,OU=Location1,OU=Employees,DC=w2k,DC=pl

1 Objects returned

As we can see we can read quite a lot (default permissions are topic for other post) but we are not able to update anything. To prove that this is really working lets try to check list of attributes which tkrajewski can update for his own account:

adfind -b "CN=Tomasz Krajewski,OU=Employees,DC=w2k,DC=pl" -s base allowedAttributesEffective

AdFind V01.32.00cpp Joe Richards (joe@joeware.net) October 200

Using server: DC1.w2k.pl:389
Directory: Windows Server 2003

dn:CN=Tomasz Krajweski,OU=Location1,OU=Employees,DC=w2k,DC=pl
>allowedAttributesEffective: otherTelephone
>allowedAttributesEffective: info
>allowedAttributesEffective: otherPager
>allowedAttributesEffective: publicDelegates
>allowedAttributesEffective: streetAddress
>allowedAttributesEffective: otherHomePhone
>allowedAttributesEffective: wWWHomePage
>allowedAttributesEffective: personalTitle

(…)

>allowedAttributesEffective: userSMIMECertificate
>allowedAttributesEffective: homePhone
>allowedAttributesEffective: mobile
>allowedAttributesEffective: pager
>allowedAttributesEffective: thumbnailPhoto

1 Objects returned

So it works !!! :). This is easy way to check if we are able to update attribute in current security context before actualy trying to update its value. This may be good habit for every DS application developer.