Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Talk to Sun One LDAP with .NET DirectoryServices

0.00/5 (No votes)
24 Jun 2009 1  
Add, Update, Delete and Search Sun One LDAP with .NET DirectoryServices

Introduction

There are many code snippets out there for DirectoryServices but trying to find one that actually connects to and works with Sun One LDAP or any other platform other than AD is not so easy! This will help users work with alternative LDAP solutions. 

Background 

The concept of LDAP and having web pages talk to it or even other client tools is fairly straight forward. Unfortunately trying to figure out what it takes to actually get results from anything but Active Directory (AD) is not the easiest thing to do. Hopefully you will find this information useful.

** Note all code is based on a standard install of Sun One with no added OUs or anything specific.

Using the Code

This article is mostly code snippets. I will demonstrate how to connect, add, update, delete and find LDAP entries. This is based on Sun One, but will most likely be useful for anyone that has LDAP that is not AD.

First there are 2 separate methods for working with LDAP. There is the  System.DirectoryServices method for dealing with DirectoryEntry and DirectorySearcher. and then there is the System.DirectoryServices.Protocols for a more down and dirty approach of sending specific requests.

* You will probably want to wrap these statements in try catch blocks in case errors happen for proper handling.

Let's explore them both!

First things. In your project, add a reference to System.DirectoryServices and / or using System.DirectoryServices.Protocols.

Add one or both of the following to the using clauses to make life easier:

using System.DirectoryServices;
using System.DirectoryServices.Protocols;

To connect directly, there are a few things to note. There are Authentication Types. These may need to be changed based on your connectivity, but if they are not configured correctly you can get strange errors. Also the user / password is different from AD. You will have to explicitly use a fully qualified username for most 3rd party LDAP servers.

To simply connect with Protocols, you can use the following code as an example:

 //Use the servername and port that you setup LDAP Directory Service on
//9605 is the example port here
LdapDirectoryIdentifier ldapDir = new LdapDirectoryIdentifier("servername", 9605);
LdapConnection ldapConn = new LdapConnection(ldapDir);
//You may need to try different types of Authentication depending on your setup
ldapConn.AuthType = AuthType.Basic;
//Update the next line to include the Fully Qualified LDAP name 
// of the user along with that user's password
System.Net.NetworkCredential myCredentials = 
	new System.Net.NetworkCredential("uid=admin,ou=Administrators,
	ou=TopologyManagement,o=netscapeRoot", "password");
//This is the actual Connection establishment here
ldapConn.Bind(myCredentials); 

Now, without using the Protocols, you have to connect and perform an action all at the same time, therefore you don't have control of leaving the connection established like you do with Protocols. For this example, we will connect and start with a DirectoryEntry. In this example, the entry is the root. 

DirectoryEntry dirEntry = new DirectoryEntry();
dirEntry.Path = @"LDAP://servername:9605/dc=example,dc=com";
dirEntry.Username = "uid=admin,ou=Administrators,
			ou=TopologyManagement,o=netscapeRoot";
dirEntry.Password = "password";
dirEntry.AuthenticationType = AuthenticationTypes.ServerBind;
dirEntry.RefreshCache();

The RefreshCache method (last line of code above) is the actual establishment of the connection. It connects and loads all of the properties and attributes of the DirectoryEntry

Now let's add a new user! With the protocols method, this looks like this. Now it's important to note that LDAP servers will have requirements for adding a user, i.e. must have the correct objectclasses, and must have certain attributes. Below are the typical attributes for Sun One. Please check your LDAP server for Attribute requirements for entries.

AddRequest addme = new AddRequest(@"uid=nuser,ou=People,dc=example,dc=com");
addme.Attributes.Add(new DirectoryAttribute("objectclass", new object[] 
	{ "top", "person", "organizationalPerson", "inetorgPerson" }));
addme.Attributes.Add(new DirectoryAttribute("uid", "nuser"));
addme.Attributes.Add(new DirectoryAttribute("givenName", "new"));
addme.Attributes.Add(new DirectoryAttribute("sn", "user"));
addme.Attributes.Add(new DirectoryAttribute("cn", "new user"));
addme.Attributes.Add(new DirectoryAttribute("userPassword", "nuser"));
ldapConn.SendRequest(addme);

Ok so how do I add something without the Protocols method? Fear not, it can be done!

DirectoryEntry newUser = dirEntry.Children.Add
	("uid=nuser,ou=People,dc=example,dc=com", "person");
newUser.Properties["objectClass"].Value = new object[] 
	{ "top", "person", "organizationalPerson", "inetorgPerson" };
newUser.Properties["uid"].Value = "nuser";
newUser.Properties["givenName"].Value = "new";
newUser.Properties["sn"].Value = "user";
newUser.Properties["cn"].Value = "new user";
newUser.Properties["userPassword"].Value = "nuser";
newUser.CommitChanges();

** Note the dirEntry is the same as above, which is the root of the server. This will add a user to the root of the LDAP server directory. The CommitChanges method does the work for us.

Ok now let's find the new user! (This is useful for updating the user properties or just checking if they exist!) 

SearchRequest findme = new SearchRequest(); 
findme.DistinguishedName = "ou=People,dc=example,dc=com"; //Find all People in this ou
findme.Filter = "(objectClass=person)"; //The type of entry we are looking for
findme.Scope = System.DirectoryServices.Protocols.SearchScope.Subtree; //We want all 
							//entries below this ou
SearchResponse results = (SearchResponse)ldapConn.SendRequest(findme); //Run the query 
							//and get results
SearchResultEntryCollection entries =  results.Entries;
for (int i = 0; i < entries.Count; i++)//Iterate through the results
{
    SearchResultEntry entry = entries[i];
    IDictionaryEnumerator attribEnum = entry.Attributes.GetEnumerator();
    while (attribEnum.MoveNext())//Iterate through the result attributes
    {        
//Attributes have one or more values so we iterate through all the values 
//for each attribute
        DirectoryAttribute subAttrib = (DirectoryAttribute)attribEnum.Value;
        for (int ic = 0; ic < subAttrib.Count; ic++)
        {
            //Attribute Name below
            attribEnum.Key.ToString();
            //Attribute Sub Value below
            subAttrib[ic].ToString();
        }
    }    
} 

The same thing without the Protocols:

 DirectorySearcher search = new DirectorySearcher(dirEntry);
search.Filter = "(objectClass=person)";
search.SearchScope = System.DirectoryServices.SearchScope.Subtree;
SearchResultCollection searchResults = search.FindAll();
for (int i = 0; i < searchResults.Count; i++)
{

    System.Collections.IDictionaryEnumerator subColl = 
			searchResults[i].Properties.GetEnumerator();
    while (subColl.MoveNext())
    {
        ResultPropertyValueCollection pc = (ResultPropertyValueCollection)subColl.Value;
        System.Collections.IEnumerator subPcol = pc.GetEnumerator();
        while (subPcol.MoveNext())
        {          
           //Property Name
           subColl.Key.ToString();
           //Property Value
           subPcol.Current.ToString();
        }
    }
}

Ok now to modify something! The below will add a user to a group.

ModifyRequest request = new ModifyRequest();
request.DistinguishedName = distinguishedgroupname;
DirectoryAttributeModification dirmod = new DirectoryAttributeModification();
dirmod.Operation = DirectoryAttributeOperation.Add;
dirmod.Name = "uniquemember";
dirmod.Add(distinguishedusername);
request.Modifications.Add(dirmod);
ModifyResponse response = (ModifyResponse)ldapConnection.SendRequest(request); 

The below will remove a user from a group. Notice the dirmod.Operation which specifies the type of modification request.

ModifyRequest request = new ModifyRequest();
request.DistinguishedName = distinguishedgroupname;
DirectoryAttributeModification dirmod = new DirectoryAttributeModification();
dirmod.Operation = DirectoryAttributeOperation.Delete;
dirmod.Name = "uniquemember";
dirmod.Add(distinguishedusername);
request.Modifications.Add(dirmod);
ModifyResponse response = (ModifyResponse)ldapConnection.SendRequest(request);

And lastly code on how to delete an object!

DeleteRequest request = new DeleteRequest(distinguishedname);
DeleteResponse response = (DeleteResponse)ldapConnection.SendRequest(request); 

With this, you should be able to work with LDAP solutions to create your own user management solutions. I created a web site to add / delete users and modify groups for users with this code. You can also build a first time synch to load all the current user permissions that were stored in a database into LDAP. Some 8000 users loaded in about 10 minutes during cutover.

Have fun, happy coding!

History

  • 24th June, 2009: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here