Reading Security Descriptors with Security Masks

Every object in Active Directory and ADAM contains an attribute called ntSecurityDescriptor. This attribute contains a Windows security descriptor object that contains the discretionary access control list (DACL), the system access control list (SACL), group, and owner information that controls the object's access control behavior.

In .NET 2.0, a new property called SecurityMasks has been added to DirectorySearcher that allows us to control which components of the security descriptor are returned in the data when we request the ntSecurityDescriptor attribute in a search operation.

We cover security descriptors in great detail in Chapters 6 and 8. Chapter 6 contains a complete discussion of reading and writing security descriptors as a whole, and Chapter 8 actually focuses on the internal structure of security descriptors. Please refer to both of those chapters for an explanation of why this property is important and what we can do with the data once we have it.

In this chapter, we will simply demonstrate how to use the new property of the DirectorySearcher effectively. Listing 5.9 contains a sample.

Listing 5.9. Retrieving a Security Descriptor

string adsPath = "LDAP://dc=domain,dc=com"; //explicitly create our searchroot DirectoryEntry searchRoot = new DirectoryEntry( adsPath, null, null, AuthenticationTypes.Secure ); using (searchRoot) //we are responsible for disposing { DirectorySearcher ds = new DirectorySearcher( searchRoot, "(cn=User1)", new string[]{"ntSecurityDescriptor"} ); //Get the Security for this object ds.SecurityMasks = SecurityMasks.Dacl | SecurityMasks.Group | SecurityMasks.Owner; SearchResult sr = ds.FindOne(); if (sr == null) throw new Exception("No user found"); byte[] descriptorBytes = (byte[])sr.Properties["ntSecurityDescriptor"][0]; ActiveDirectorySecurity ads = new ActiveDirectorySecurity(); ads.SetSecurityDescriptorBinaryForm( descriptorBytes, AccessControlSections.All ); //helper function PrintSD(ads); AuthorizationRuleCollection rules = ads.GetAccessRules( true, true, typeof(NTAccount) ); foreach (ActiveDirectoryAccessRule rule in rules) { //helper function PrintAce(rule); } } Sample output: =====Security Descriptor===== Owner: S-1-450115865-2557621802-512 Group: S-1-450115865-2557621802-512 =====ACE===== Identity: NT AUTHORITYSELF AccessControlType: Allow ActiveDirectoryRights: ExtendedRight InheritanceType: None ObjectType: ab721a53-1e2f-11d0-9819-00aa0040529b InheritedObjectType: ObjectFlags: ObjectAceTypePresent

We show the code for the two helper functions mentioned in Listing 5.3, called PrintSD and PrintAce, in Chapter 8, Listing 8.2. We omitted them here for brevity.

Asynchronous Searches

Категории