Click here to Skip to main content
15,879,535 members
Articles / Web Development / ASP.NET

Talk to Sun One LDAP with .NET DirectoryServices

Rate me:
Please Sign up or sign in to vote.
4.90/5 (8 votes)
24 Jun 2009CPOL3 min read 57.4K   26   11
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:

C#
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:

C#
 //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. 

C#
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.

C#
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!

C#
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!) 

C#
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:

C#
 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.

C#
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.

C#
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!

C#
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Database Developer
United States United States
DB2 / MSSQL Database Administrator / PeopleSoft Administrator

Comments and Discussions

 
Questionhow to change users password using ldap Pin
Member 1460117723-Sep-19 2:31
Member 1460117723-Sep-19 2:31 
QuestionWant code sample or snippet to sync from SQL database to LDAP. Pin
Member 31370788-Oct-12 21:06
Member 31370788-Oct-12 21:06 
GeneralMy vote of 5 Pin
Member 31370788-Oct-12 21:03
Member 31370788-Oct-12 21:03 
QuestionHow to access operational attributes? Pin
gogsthecoder18-Aug-11 6:14
gogsthecoder18-Aug-11 6:14 
QuestionHow could I use service account in Sunone authentication Pin
hiteh8-Sep-10 11:19
hiteh8-Sep-10 11:19 
GeneralUnknown error with sendRequest() on windows 2000 Pin
MozoDev13-Jan-10 5:24
MozoDev13-Jan-10 5:24 
GeneralSecure Socket Layer Pin
lmingle28-Jul-09 9:57
lmingle28-Jul-09 9:57 
GeneralRe: Secure Socket Layer Pin
rogwabbit520-Aug-09 1:39
rogwabbit520-Aug-09 1:39 
For SSL
Try authentication type AuthenticationTypes.SecureSocketsLayer
Also may want to explicitly set the port. i.e. 636 during connection. You may have to play with both ot these options but one or the other or maybe even both should do the trick for SSL.

Thanks!
GeneralSUN OpenDS Pin
hstahl11-Jul-09 4:14
hstahl11-Jul-09 4:14 
GeneralRe: SUN OpenDS Pin
rogwabbit528-Jul-09 5:28
rogwabbit528-Jul-09 5:28 
GeneralRe: SUN OpenDS Pin
CherezZaboro4-Mar-10 5:26
CherezZaboro4-Mar-10 5:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.