New with .NET 2.0 comes the System.DirectoryServices.ActiveDirectory (SDS.AD) namespace. While this namespace is primarily targeted at administrators, it does contain a few nuggets of functionality that might appeal to the .NET developer.
One of the challenges in working with Active Directory programmatically is that we cannot perform all of the operations we need to perform using standard LDAP calls. As we mentioned before, Active Directory ships with a variety of API functions that provide access to many of these additional functions. We collectively refer to these as the Ds* APIs. The challenge was that these APIs were designed to be called only from C/C++ and did not have an equivalent COM interface that allowed them to be called via scripting clients. Because of this, the primary audience for these APIsnamely, the administratorsdid not have an easy means to use them.
Microsoft addressed this problem by creating the SDS.AD namespace. SDS.AD is new functionality built on top of SDS that expands the tools a developer might use to manage or control Active Directory and ADAM. Many of the concrete concepts of Active Directory find themselves represented as classes in SDS.AD. Some of these include:
Forest ActiveDirectoryPartition (instantiable as Domain) DirectoryServer (instantiable as DomainController, GlobalCatalogServer, and ADAMInstance) ActiveDirectorySchemaClass ActiveDirectorySite ActiveDirectorySubnet ReplicationConnection TrustRelationshipInformation
SDS.AD does a nice job of marrying together the SDS ADSI model with the Ds* APIs, which actually don't use ADSI at all. A lot of work goes on under the hood to make all of this work together. The result is really the best of both worlds for the .NET developer.
Using these classes or derived subclasses, we can exercise very granular control over Active Directory and ADAM operations such as replication, schema updates, and trust management between domains. For the rest of this section, we will cover some of the more important classes or groups of classes, and we will discuss what they contain.
Introduced with this namespace is the concept of the ActiveDirectoryPartition class. This abstract class manifests itself in concrete implementations of things like Domain, ApplicationPartition, and ActiveDirectory-Schema. These classes have drastically simplified what was once difficult and obscure functionality.
We assume that you are familiar with domains and the purposes they serve, so we won't spend a lot of time talking about the specifics of setting up domains. Oftentimes, decisions to set up domains are not based on technical criteria as much as they are based on political decisions that take into account differing security needs or segregation of the objects they contain. Briefly, domains are logical units of security and replication. Only domains within the same forest share the same schema, but they do not share objects or security policies. In order for one domain to communicate with another domain, some sort of communication channel must exist. A trust is used to secure this communication channel, and trusts are the mechanism by which security contexts and objects can be resolved from one domain into another. In practical terms, a trust allows users or objects in one domain to be authenticated in another domain. There are different types of trusts (transitive and nontransitive), as well as directions (oneway and two-way). With the Domain class, it is now possible to do things such as enumerate, create, and verify trusts, enumerate domain controllers, and enumerate child domains. Previously, many of these capabilities were available only using C/C++, or they required nontrivial searches to extract this information.
Application partitions are a new type of directory partition available in Windows 2003 that typically are specific to a particular domain controller. The data that resides in these types of partitions is usually useful only locally and is relevant to a particular application that uses this domain controller. By default, the data that resides in the partition will not replicate outside of the local domain controller where it resides. This has the benefit of reducing replication traffic on the network when that data is not relevant for the entire domain. It is now possible to manage and create these application partitions with the aptly named ApplicationPartition class. Furthermore, it is possible to selectively set up replicas, or replication partners, for these partitions in Windows 2003 for backup or redundancy purposes.
Schema defines the shape of a directory object. That is, it defines its properties (what it contains) and its relationships to other objects (what it is). Out of the box, Active Directory and ADAM ship with hundreds of classes and attributes which serve the interests of developers and users in the vast majority of situations. For reasons of specificity or clarity, it is often useful to define our own schema instead of bludgeoning data into an unused (and unrelated) attribute on an object. When this is done, it is called extending the schema (for more on schema and extensions, see Chapter 7). The ActiveDirectorySchema class is responsible for all things related to Active Directory and ADAM schema. It is now possible to easily retrieve, inspect, and if necessary, modify schema classes and attributes. Additionally, we can now easily locate the schema master to perform operations such as reloading the schema.
The abstract DirectoryServer class exists in concrete implementations to operate directly on domain controllers, ADAM instances, and global catalog servers. It encapsulates much of the functionality needed to maintain, promote, or modify the server and its roles.
The DomainController class encapsulates many of the operations an Active Directory admin would like to perform on her domain controllers. For instance, with this class, it is possible to find other domain controllers, enable global catalog operations, determine OS version and IP address, check replication consistency, find replication partners, and even determine FSMO roles. We can also determine the site, forest, and current time on any domain controller. Whew! If you don't know what all of those things are, or why they are useful, don't sweat it. Administrators are going to be the likely consumers of these classes, and we will cover the parts that the average enterprise developer should know.
The DomainController class allows us to use the domain controller Locator service (packaged in the DsGetDCName API) directly from within our code. This is our favorite feature in the namespace for enterprise developers, as it allows us to use the full power of the locator service to do things like dynamically find domain controllers in any site and force rediscovery of a domain controller in a failure situation. We'll come back to this class in Chapter 9.
The global catalog server is a special type of domain controller that holds a subset of all of the data in the forest. This powerful functionality exists to make searching across domains efficient. It means that in multidomain forests, it is possible to connect to a global catalog in one domain and search it for objects that reside in another domain. There is an associated cost with creating a global catalog in terms of replication traffic, as all global catalog replicated objects and their subset of attributes are replicated across domains. The GlobalCatalog class wraps all the functionality of the DomainController class, but adds the ability to find, create, demote, and enumerate other global catalogs.
The AdamInstance class operates for ADAM in much the same way as the DomainController class operates for Active Directory. ADAM instances don't participate in trusts, so we won't find any support here for that. However, we can find ADAM instances and set up replication using this class model.
System DirectoryServices Protocols Overview
Part I: Fundamentals
Introduction to LDAP and Active Directory
Introduction to .NET Directory Services Programming
Binding and CRUD Operations with DirectoryEntry
Searching with the DirectorySearcher
Advanced LDAP Searches
Reading and Writing LDAP Attributes
Active Directory and ADAM Schema
Security in Directory Services Programming
Introduction to the ActiveDirectory Namespace
Part II: Practical Applications
Part III: Appendixes
Appendix A. Three Approaches to COM Interop with ADSI
Appendix B. LDAP Tools for Programmers
Appendix C. Troubleshooting and Help