//
// Don't forget to remove the HTML tags above and at the end of the file using System; using System.Collections; using System.Xml; using System.DirectoryServices; using System.Runtime.InteropServices; /// /// Example of LDAP Authentication code using ADSI with MCIT custom error messages /// written by Dmitriy Kashchenko, IDM team public class LdapAuthetication { // const private const string ERR_NOT_FOUND = "(0x80072030): not found"; // LDAP metrics private string _ldapserver = "LDAP://ldap.ent.med.umich.edu:636/"; private string _topContainer = "dc=med,dc=umich,dc=edu"; private String _defaultFilter = "(uid={0})"; // errors handling // messages file name private string _messages = "ldapautherrors.xml"; // variables private string _errorMsg; private string _provider; private const string nodeKey = "message"; private const string indexAttr = "index"; private Hashtable errors = null; private void parseFile(string fname) { XmlTextReader node = new XmlTextReader(fname); node.WhitespaceHandling = WhitespaceHandling.None; while (node.Read()) { if (node.NodeType == XmlNodeType.Element && node.Name.Equals(nodeKey)) { if (node.HasAttributes) { string index = node.GetAttribute("index"); node.Read(); string message = node.Value; errors.Add(index, message); } } } node.Close(); } [DllImport("activeds.dll", ExactSpelling = true, EntryPoint = "ADsGetLastError", CharSet = System.Runtime.InteropServices.CharSet.Unicode)] private static extern int ADsGetLastError(ref int error, IntPtr errorbuf, int errorbuflen, IntPtr namebuf, int namebuflen); private int getExtendedError() { IntPtr errorbuf = (IntPtr)0; IntPtr namebuf = (IntPtr)0; int error = 0; try { errorbuf = Marshal.AllocHGlobal(256 * 2); namebuf = Marshal.AllocHGlobal(256 * 2); ADsGetLastError(ref error, errorbuf, 256, namebuf, 256); _errorMsg = Marshal.PtrToStringUni(errorbuf); _provider = Marshal.PtrToStringUni(namebuf); return error; } finally { if (errorbuf != (IntPtr)0) Marshal.FreeHGlobal(errorbuf); if (namebuf != (IntPtr)0) Marshal.FreeHGlobal(namebuf); } } public string getErrorMessage(Exception e) { string rc = e.ToString(); if (errors != null) { int ee = getExtendedError(); if (ee != 0) rc = _errorMsg; foreach (DictionaryEntry entry in errors) { string index = (string)entry.Key; if (rc.IndexOf(index) != -1) { rc = (string)entry.Value; break; } } } return rc; } public LdapAuthetication() { errors = new Hashtable(); parseFile(_messages); } public DirectoryEntry Authenticate(string user, string password) { DirectoryEntry de = new DirectoryEntry(_ldapserver+_topContainer); // required to initate anonymous bind de.AuthenticationType = System.DirectoryServices.AuthenticationTypes.ServerBind; DirectorySearcher searcher = new DirectorySearcher(de); //set the filer. the filter syntax is the standard LDAP filter syntax searcher.Filter = string.Format(_defaultFilter, user); SearchResult result = searcher.FindOne(); if (result == null) throw new Exception(ERR_NOT_FOUND); de = result.GetDirectoryEntry(); // Distingushed Name of the found account string DN = de.Path.Substring (de.Path.ToUpper().IndexOf("CN=")); // Close search connection de.Close(); // now bind de = new DirectoryEntry(_ldapserver+_topContainer); de.Username = DN; de.Password = password; de.AuthenticationType = System.DirectoryServices.AuthenticationTypes.SecureSocketsLayer; Object obj = de.NativeObject; return de; } public static void Main(string[] args) { LdapAuthetication auth = new LdapAuthetication(); if (args.Length == 2) { try { DirectoryEntry de = auth.Authenticate(args[0], args[1]); Console.WriteLine("Authentication Succesful: " + de.Username); } catch (Exception e) { Console.WriteLine(auth.getErrorMessage(e)); } } else { Console.WriteLine("Usage: LdapAuthentication Username Password"); } } } //