LDAP - Lightweight Directory Access Protocol
Environments:
Client: |
Server: |
openldap (plain|tls) |
openldap |
winldap (plain|tls) |
openldap |
openldap (plain|tls) |
Active Directory |
winldap (plain|tls) |
Active Directory |
NOTE: Before using the library you have to go through the code and review it.
Building openldap client lib:
Here are the steps to build openldap on windows. To build the client library there is not much tweaking to be done. I used openldap-2.1.12.
The .dsp and .dsw files are under ..\build\
directory. If you open main.dsw, it contains openldap server as well as ldap client library. For the client you need to build libldap_r
and liblber
projects. I didn't use SASL authentication mechanisms so i removed SASL and Regex dependency also from the ldap library (although, it's not hard to build with sasl/regex support). To remove SASL/Regex dependency expand setup project. Open portable.nt
file and comment out
(Or otherwise follow instructions from here .)
Right click on libldap_r
(thread safe version) and liblber
projects and Rebuild. This should build without any problems. Now you have to set the VS.NET search directory for libraries to where the outputed oldap_r.lib
and olber32.lib
are. And the same for include files:
..\openldap-2.1.12\Debug
or ..\openldap-2.1.12\Release
or some common directory or renamed debug and release files.
..\openldap-2.1.12\include
Building openldap server on Windows for testing purposes:
Check the build instructions here, this is for openldap-2.0.xx versions.
You can also successfully build openldap-2.1.xx and I used Sleepycat Berkley's db-4.1.xx, and cyrus-sasl-1.5.xx with it. When everything is built you have to copy *.exe and *.dll files to some directory that will be the base directory for openldap server.
You will need to copy the schema directory from ..\openldap\openldap-2.1.12\servers\slapd\schema
to your base openldap dir and the sample slapd.conf file from ..\openldap\openldap-2.1.12\servers\slapd\slapd.conf
.
In slapd.conf add ucdata-path before any include statements. Like this:
ucdata-path "X:/openldap-2.1.12/ucgendat".
Then open command prompt and run
ucgendat.exe -o X:/openldap-2.1.12/ucgendat
If you get this error: error loading ucdata (error -127), you'll know that ucgendata wasn't setup. In 2.0.xx versions it wasn't needed.
Fill/Change the rest of slapd.conf to your needs. Check various resources, specifically slapd.conf man page at http://www.openldap.org/software/man.cgi and type slapd.conf also check Quick-Start Guide and Administrator's Guide.
To debug possible errors you can start slapd -d 255
to do this you need to compile with LDAP_DEBUG
. This can be added in portable.nt file, it's under setup project; somewhere at the top add:
#define LDAP_DEBUG 1
If you want to add ssl/tls support, you can do that through openssl. You have to get the latest openssl version (for example openssl-0.9.7a) and follow the instructions in INSTALL.W32 file that comes with the package. After you've built openssl into dll or static libraries you have to add it's .lib/.h directories to VS.NET's search directory for libraries/include files. Now you have to open portable.nt from setup project of openldap solution. somewhere at the top add this:
#define HAVE_TLS 1
#define HAVE_OPENSSL_SSL_H 1
#pragma comment(lib, "ssleay32r.lib")
#pragma comment(lib, "libeay32r.lib")
And build openldap. Now you have to edit the slapd.conf file. Related options are: TLSVerifyClient
, TLSCertificateFile
, TLSCertificateKeyFile
, TLSCACertificateFile
, TLSCipherSuite
, etc.
Now you can start ldap to listen for ssl/tls connections:
slapd -h "ldaps://somehost ldap://somehost
Although ldaps:// is not needed when using ldap_start_tls_s
because it talks on normal ldap port (389) and not on 636 for ssl. When connecting with winldap client the CA of server's certificate has to be trusted by the client PC, which means it has to be installed under trusted CA's. You can check if there are any problems with server certificate by connecting to the server with Internet Explorer. More trouble shooting info related to winldap is available by searching groups.google.com for: ldap_sslinit
troubleshoot group:microsoft.public.platformsdk.active.directory there you will find mskb article.
Ldap .NET Class Usage
Connection:
LdapClient c = new LdapClient("127.0.0.1",
LdapClient.DefaultPort,true , true );
c.ldap_simple_bind_s("bind_dn", "your_pass");
Searching:
LdapResult res;
int count = c.ldap_search_ext_s("dn_to_start_the_search_at",
LDAPSearchScope.LDAPSCOPE_SUBTREE,
"sn=*",
new string[0],
false,
60,
0,
out res);
Console.WriteLine("Search Returned: {0}", count);
foreach(Oldap.LdapEntry entry in res)
{
Console.WriteLine("dn:{0}", entry.DN);
foreach(Oldap.LdapAttribute attr in entry)
{
if(attr.Name == "string_type?")
foreach(string val in attr.StringValues)
Console.WriteLine("{0}: {1}", attr.Name, val);
else if(attr.Name == "binary_type?")
foreach(Byte[] val in attr.BinaryValues)
{
mem = new MemoryStream();
mem.Write(val, 0, val.Length);
}
}
Console.WriteLine();
}
Adding new Entry
(supported types: String or String[], Byte[] or array of Byte[]):
string entryDN = "dn_of_new_entry";
ListDictionary attrval = new ListDictionary();
attrval["objectClass"]=new string[]{"top", "person"};
attrval["cn"]=new string[]{"test"};
attrval["sn"]="test";
c.ldap_add_s(entryDN, attrval);
if(c.ldap_compare_s(entryDN, "cn", "test") == true)
Replacing attribute in existing entry:
attrval["sn"]="test_modified";
c.ldap_mod_replace(entryDN, attrval);
Adding attribute to existing entry:
attrval["telephoneNumber"]=new string[]{"phone1","phone2"};
c.ldap_mod_add(entryDN, attrval);
Removing attribute from existing entry:
attrval["telephoneNumber"]=new string[0];
attrval["telephoneNumber"]=new string[]{"phone2"};
c.ldap_mod_delete(entryDN, attrval);
Deleting whole entry:
c.ldap_delete_s(entryDN);
Exception thrown:
LDAPException
LDAPExceptionPartialResult - thrown when searching and specifying size limit.
partial_count data member has the returned count.
InvalidCastException
The rest of ldap functions including async methods, referrals (LDAP_OPT_REFERRALS), etc... are to be added on as needed basis.
Reference:
Winldap related:
Common SSL errors with winldap:
0x80090322 - "The target principal name is incorrect"
0x80090325 - "The certificate chain was issued by an authority that is not trusted"
Active Directory related:
Disclaimer: THIS CODE AND INFORMATION IS PROVIDED 'AS IS' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.