Using Attribute Scope Query

Windows 2003 Server and ADAM include an exciting new feature called attribute scope query (ASQ).

As the term implies, an ASQ changes the scope of a query to search the list of objects specified by an attribute value in a specific object, instead of performing a traditional search scope. The attribute to be used must use DN syntax (Object-DN, 2.5.5.1), as those are the types of attributes that specify lists of objects in the directory.

For example, what if we want to find all of the email addresses of the members of a specific distribution list? Since the member list of a group is essentially arbitrary and may contain objects from all over the directory, we do not traditionally have an efficient way to target them specifically. The common approach is to enumerate the group's member attribute and query each object in the list for their email address. This is both tedious and inefficient.

ASQ changes this. We can now directly search the objects referenced in the member attribute of a group and retrieve their email addresses.

An ASQ can only be performed against a single DN-syntax attribute in one object at a time. Because of this, our DirectorySearcher must be configured with the scope set to Base and the SearchRoot pointing to the object whose attribute is the target of the query.

With ASQ, the PropertiesToLoad property now instructs DirectorySearcher to retrieve those attributes from the target of the search, not from the SearchRoot object itself. It is also worth noting that we cannot retrieve attribute values from the SearchRoot object at the same time we are performing an ASQ. We need two separate searches for that.

Listing 5.7 demonstrates this example.

Listing 5.7. Using an Attribute Scope Query to Retrieve Data from the Members of a Group

string adsPath = "LDAP://CN=Group1,OU=Groups,dc=domain,dc=com"; //Explicitly create our SearchRoot DirectoryEntry searchRoot = new DirectoryEntry( adsPath, null, null, AuthenticationTypes.Secure ); using (searchRoot) //we are responsible for Disposing { string[] attribs = new string[]{ "distinguishedName", "sAMAccountName", "name", "mail" }; DirectorySearcher ds = new DirectorySearcher( searchRoot, "(&(objectClass=user)(objectCategory=person))", attribs ); //must be SearchScope.Base ds.SearchScope = SearchScope.Base; //we choose any DN-type attribute ds.AttributeScopeQuery = "member"; using (SearchResultCollection src=ds.FindAll()) { Console.WriteLine("Returning {0}", src.Count); foreach (SearchResult sr in src) { foreach (string s in attribs) { if (sr.Properties.Contains(s)) { Console.WriteLine( "{0}: {1}", s, sr.Properties[s][0] ); } } } } //OUTPUT: //distinguishedName: CN=User4925,OU=Users,DC=domain,DC=com //sAMAccountName: User4925 //name: User4925 //mail: user4925@domain.com //distinguishedName: CN=User4935,OU=Users,DC=domain,DC=com //sAMAccountName: User4935 //name: User4935 //mail: user4935@domain.com //...

Wow! That is an extremely useful feature that was not only easier to program, but also faster and more efficient than binding to each member to get our information. Once again, it is important to note that the value specified in the AttributeScopeQuery property must be a string that represents a DN syntax attribute (either single- or multivalued).

Clever developers will realize that this is probably the easiest way to enumerate a large group's membership. Instead of using attribute range retrieval (Chapter 6), we can simply specify a base-level search on the group of interest and perform an ASQ on the member attribute.

Note: ASQ Requires Windows XP or Higher

Like VLV searches, as of this writing the ADSI client supports only ASQ as of the Windows XP version. Developing a solution on Windows XP and attempting to deploy it to a Windows 2000 application server will not work.

Категории