June 12, 2009, 6:45 a.m.
posted by vendetta
Using C# to Access a Network Directory
The main .NET class for working with network directory services objects is the DirectoryEntry class, found in the System.DirectoryServices namespace. The DirectoryEntry class allows you to bind to a directory object and perform operations to retrieve, add, delete, and modify information about the object.
The DirectoryEntry class has many constructor formats, depending on your requirements within the database.
| Note |
To perform the examples in this chapter, you will need access to some type of LDAP database system, either a Windows 2000 Active Directory server or an LDAP server. These examples were done using an OpenLDAP server, but the programming principles discussed here apply equally, no matter what type of LDAP server you are using. |
Anonymous Directory Login
Many network directory services allow either all or some database objects to be read by anyone on the network, regardless of network permissions. This allows network users to look up resources on the network, such as a user phone number and address, without requiring advanced privileges on the directory server.
To create a DirectoryEntry instance to reference a directory object without using privileges, you use the following constructor format:
DirectyoryEntry(string ldappath)
The ldappath parameter is a string value that represents the location of the database object. The object must be referenced using a URI-like syntax, which includes the access method, the network directory service server address, and the distinguished name of the object.
The ADSI library offers various access methods for connecting to different types of network directory services. Each access method is specified in a URI format. Figure lists the access methods available to use.
| Warning |
The access methods are case sensitive, so be careful when declaring them. |
|
Access Method |
Accesses |
|---|---|
|
WinNT |
Windows NT domains |
|
IIS |
A Microsoft Internet Information Services server |
|
LDAP |
Any LDAP-compliant network directory (including Active Directory) |
|
NDS |
Novell Netware Directory Service server |
|
NWCOMPAT |
Novell Netware 3.x bindary service |
For AD access, you should use the LDAP access method because it offers the most robust access method, including searching capabilities (described in the “Searching the Network Directory” section).
After the access method, the address of the desired directory server should be specified, along with the full distinguished name of the object to reference. A few examples of proper LDAP paths would be:
LDAP://server1.ispnet1.net/dc=ispnet1, dc=net LDAP://server1.ispnet1.net/cn=kblum, ou=sales, dc=ispnet1, dc=net LDAP://192.168.1.100/ou=accounting, dc=ispnet1, dc=net
Listing 15.1 shows the BindObject.cs program, which binds a variable to a directory object and displays the LDAP path associated with the object.
While the BindObject program is extremely trivial (seeing as you need to know the LDAP path to bind to the object anyway) it shows the basic steps required to bind a variable to a directory services object. The Path property retrieves the LDAP path of the object as a string value, which can be used in a DirectoryEntry instance to bind to the object. This will be used later in the "Searching the Network Directory" section to iterate through objects in a directory service.
The output from this example is simple. If you were successful in binding to the directory service object, the LDAP path should display on the console. This entry should be the same as what you used to create the DirectoryEntry object. If the program was not able to bind to the directory services object, an Exception will be thrown, stating the reason for the error. One of the most common errors is that the directory services server requires that you authenticate yourself before binding to an object.
| Note |
You may notice that many of the errors produced from AD code are COM Exceptions. The ADSI library uses the COM interface of Windows to access the AD environment. |
Logging In to a Directory
For database actions that require user authentication, two formats can be used. The following constructor allows you to specify a username and password to use to login into the directory service:
DirectoryEntry(string ldappath, string username, string password)
Once the connection is authenticated, you can perform the actions that the username specified is allowed to perform, including adding, deleting, or modifying objects.
The second constructor allows you to specify a specific authentication type used for the login:
DirectoryEntry(string ldappath, string username, string password,
AuthenticationTypes authtype)
The AuthenticationTypes enumerator specifies the authentication type used for logging into the directory service server.
Figure shows the authentication types that are available.
|
AuthenticationType |
Description |
|---|---|
|
Anonymous |
No authentication is performed (not supported under Windows NT) |
|
Delegation |
Enables the ADSI to delegate the user’s security context |
|
Encryption |
Uses encryption for all data exchanged with the server |
|
FastBind |
Does not attempt to query the objectClass property, exposing only the base interfaces supported by ADSI |
|
None |
Used as a null reference |
|
ReadonlyServer |
Indicates that read-only access is required to the server |
|
Sealing |
Encrypts data using Kerberos encryption |
|
Secure |
Requests secure authentication. |
|
SecureSocketsLayer |
Uses the Secure Sockets Layer (SSL) encryption with a known certificate |
|
ServerBind |
Used to log the session into a specific server when a server is specified in the LDAP path |
|
Signing |
Signs all packets to verify data integrity |
An example of using authentication to access a directory object is:
DirectoryEntry de = DirectoryEntry("LDAP://192.168.1.100/dc=ispnet1, dc=net",
"rich", "password", AuthenticationTypes.ServerBind);
This example uses the server username “rich” and the appropriate password to log into the directory services server.
| Note |
Almost all network directory services require a user to log in before administrative functions (such as adding, deleting, and modifying objects) can be performed. |