Exemple #1
0
        public List <LdapEntry> ExecuteSearch(string searchBase, string filter = "")
        {
            var results = new List <LdapEntry>();

            var lcm  = LdapConnectionManager.Instance;
            var conn = lcm.GetConnection();
            var sb   = searchBase + config.searchBase;

            LdapControl[] requestControls = new LdapControl[1];

            LdapSortKey[] keys = new LdapSortKey[1];
            keys[0] = new LdapSortKey("cn"); //samaccountname
            // Create the sort control
            requestControls[0] = new LdapSortControl(keys, true);

            // Set the controls to be sent as part of search request
            LdapSearchConstraints cons = conn.SearchConstraints;

            cons.SetControls(requestControls);
            conn.Constraints = cons;

            LdapSearchResults resps = (LdapSearchResults)conn.Search(sb, LdapConnection.ScopeSub, filter, null, false, (LdapSearchConstraints)null);

            //var resps = SendSearch(searchBase, type, filter);

            while (resps.HasMore())
            {
                /* Get next returned entry.  Note that we should expect a Ldap-
                 * Exception object as well just in case something goes wrong
                 */
                LdapEntry nextEntry = null;
                try
                {
                    nextEntry = resps.Next();
                    results.Add(nextEntry);
                }
                catch (Exception e)
                {
                    if (e is LdapReferralException)
                    {
                        continue;
                    }
                    else
                    {
                        logger.Error("Search stopped with exception " + e.ToString());
                        break;
                    }
                }

                /* Print out the returned Entries distinguished name.  */
                logger.Debug(nextEntry.Dn);
            }

            return(results);
        }
Exemple #2
0
    public static void  Main(System.String[] args)
    {
        /* Check if we have the correct number of command line arguments */
        if (args.Length != 4)
        {
            System.Console.Error.WriteLine("Usage:   mono VLVControl <host name> <login dn>" + " <password> <container>");
            System.Console.Error.WriteLine("Example: mono VLVControl Acme.com \"cn=admin,o=Acme\" secret" + " \"ou=Sales,o=Acme\"");
            System.Environment.Exit(1);
        }

        /* Parse the command line arguments  */
        System.String  LdapHost    = args[0];
        System.String  loginDN     = args[1];
        System.String  password    = args[2];
        System.String  searchBase  = args[3];
        int            LdapPort    = LdapConnection.DEFAULT_PORT;
        int            LdapVersion = LdapConnection.Ldap_V3;
        LdapConnection conn        = new LdapConnection();

        try
        {
            // connect to the server
            conn.Connect(LdapHost, LdapPort);
            // bind to the server
            conn.Bind(LdapVersion, loginDN, password);
            System.Console.Out.WriteLine("Succesfully logged in to server: " + LdapHost);

            /* Set default filter - Change this line if you need a different set
             * of search restrictions. Read the "NDS and Ldap Integration Guide"
             * for information on support by Novell eDirectory of this
             * functionaliry.
             */
            System.String MY_FILTER = "cn=*";

            /* We are requesting that the givenname and cn fields for each
             * object be returned
             */
            System.String[] attrs = new System.String[2];
            attrs[0] = "givenname";
            attrs[1] = "cn";

            // We will be sending two controls to the server
            LdapControl[] requestControls = new LdapControl[2];

            /* Create the sort key to be used by the sort control
             * Results should be sorted based on the cn attribute.
             * See the "NDS and Ldap Integration Guide" for information on
             * Novell eDirectory support of this functionaliry.
             */
            LdapSortKey[] keys = new LdapSortKey[1];
            keys[0] = new LdapSortKey("cn");

            // Create the sort control
            requestControls[0] = new LdapSortControl(keys, true);

            /* Create the VLV Control.
             * These two fields in the VLV Control identify the before and
             * after count of entries to be returned
             */
            int beforeCount = 0;
            int afterCount  = 2;

            /* The VLV control request can specify the index
             * using one of the two methods described below:
             *
             * TYPED INDEX: Here we request all objects that have cn greater
             * than or equal to the letter "a"
             */
            requestControls[1] = new LdapVirtualListControl("a", beforeCount, afterCount);

            /* The following code needs to be enabled to specify the index
             * directly
             *   int offset = 0; - offset of the index
             *   int contentCount = 3; - our estimate of the search result size
             *   requestControls[1] = new LdapVirtualListControl(offset,
             *                          beforeCount, afterCount, contentCount);
             */

            // Set the controls to be sent as part of search request
            LdapSearchConstraints cons = conn.SearchConstraints;
            cons.setControls(requestControls);
            conn.Constraints = cons;

            // Send the search request - Synchronous Search is being used here
            System.Console.Out.WriteLine("Calling Asynchronous Search...");
            LdapSearchResults res = conn.Search(searchBase, LdapConnection.SCOPE_SUB, MY_FILTER, attrs, false, (LdapSearchConstraints)null);

            // Loop through the results and print them out
            while (res.HasMore())
            {
                /* Get next returned entry.  Note that we should expect a Ldap-
                 * Exception object as well just in case something goes wrong
                 */
                LdapEntry nextEntry = null;
                try
                {
                    nextEntry = res.Next();
                }
                catch (LdapException e)
                {
                    if (e is LdapReferralException)
                    {
                        continue;
                    }
                    else
                    {
                        System.Console.Out.WriteLine("Search stopped with exception " + e.ToString());
                        break;
                    }
                }

                /* Print out the returned Entries distinguished name.  */
                System.Console.Out.WriteLine();
                System.Console.Out.WriteLine(nextEntry.DN);

                /* Get the list of attributes for the current entry */
                LdapAttributeSet findAttrs = nextEntry.getAttributeSet();

                /* Convert attribute list to Enumeration */
                System.Collections.IEnumerator enumAttrs = findAttrs.GetEnumerator();
                System.Console.Out.WriteLine("Attributes: ");

                /* Loop through all attributes in the enumeration */
                while (enumAttrs.MoveNext())
                {
                    LdapAttribute anAttr = (LdapAttribute)enumAttrs.Current;

                    /* Print out the attribute name */
                    System.String attrName = anAttr.Name;
                    System.Console.Out.WriteLine("" + attrName);

                    // Loop through all values for this attribute and print them
                    System.Collections.IEnumerator enumVals = anAttr.StringValues;
                    while (enumVals.MoveNext())
                    {
                        System.String aVal = (System.String)enumVals.Current;
                        System.Console.Out.WriteLine("" + aVal);
                    }
                }
            }

            // Server should send back a control irrespective of the
            // status of the search request
            LdapControl[] controls = res.ResponseControls;
            if (controls == null)
            {
                System.Console.Out.WriteLine("No controls returned");
            }
            else
            {
                // We are likely to have multiple controls returned
                for (int i = 0; i < controls.Length; i++)
                {
                    /* Is this the Sort Response Control. */
                    if (controls[i] is LdapSortResponse)
                    {
                        System.Console.Out.WriteLine("Received Ldap Sort Control from " + "Server");

                        /* We could have an error code and maybe a string
                         * identifying erring attribute in the response control.
                         */
                        System.String bad    = ((LdapSortResponse)controls[i]).FailedAttribute;
                        int           result = ((LdapSortResponse)controls[i]).ResultCode;

                        // Print out error code (0 if no error) and any
                        // returned attribute
                        System.Console.Out.WriteLine("Error code: " + result);
                        if ((System.Object)bad != null)
                        {
                            System.Console.Out.WriteLine("Offending " + "attribute: " + bad);
                        }
                        else
                        {
                            System.Console.Out.WriteLine("No offending " + "attribute " + "returned");
                        }
                    }

                    /* Is this a VLV Response Control */
                    if (controls[i] is LdapVirtualListResponse)
                    {
                        System.Console.Out.WriteLine("Received VLV Response Control from " + "Server...");

                        /* Get all returned fields */
                        int           firstPosition = ((LdapVirtualListResponse)controls[i]).FirstPosition;
                        int           ContentCount  = ((LdapVirtualListResponse)controls[i]).ContentCount;
                        int           resultCode    = ((LdapVirtualListResponse)controls[i]).ResultCode;
                        System.String context       = ((LdapVirtualListResponse)controls[i]).Context;


                        /* Print out the returned fields.  Typically you would
                         * have used these fields to reissue another VLV request
                         * or to display the list on a GUI
                         */
                        System.Console.Out.WriteLine("Result Code    => " + resultCode);
                        System.Console.Out.WriteLine("First Position => " + firstPosition);
                        System.Console.Out.WriteLine("Content Count  => " + ContentCount);
                        if ((System.Object)context != null)
                        {
                            System.Console.Out.WriteLine("Context String => " + context);
                        }
                        else
                        {
                            System.Console.Out.WriteLine("No Context String in returned" + " control");
                        }
                    }
                }
            }

            /* We are done - disconnect */
            if (conn.Connected)
            {
                conn.Disconnect();
            }
        }
        catch (LdapException e)
        {
            System.Console.Out.WriteLine(e.ToString());
        }
        catch (System.IO.IOException e)
        {
            System.Console.Out.WriteLine("Error: " + e.ToString());
        }
        catch (Exception e)
        {
            System.Console.WriteLine("Error: " + e.Message);
        }
    }
        public IEnumerable <User> GetUsers(string searchFilter)
        {
            _connection.Connect(_config.Url, _config.Port);
            _connection.Bind(_config.BindDn, _config.BindCredentials);

            int startIndex   = 1;
            int contentCount = 0;
            int afterIndex   = 1000;
            int count        = 0;

            do
            {
                LdapVirtualListControl ctrl = new LdapVirtualListControl(startIndex, 0, afterIndex, contentCount);
                LdapSortKey[]          keys = new LdapSortKey[1];
                keys[0] = new LdapSortKey("samaccountname");
                LdapSortControl sort = new LdapSortControl(keys, true);

                LdapSearchConstraints constraints = _connection.SearchConstraints;
                constraints.setControls(new LdapControl[] { ctrl, sort });

                _connection.Constraints = constraints;
                LdapSearchResults lsc = _connection.Search(
                    _config.SearchBase,
                    LdapConnection.SCOPE_SUB,
                    searchFilter,
                    new[] { MemberOfAttribute, DisplayNameAttribute, SamAccountNameAttribute, "sn", "givenName", "mail", "displayName" },
                    false,
                    constraints);

                foreach (var item in lsc.ToList())
                {
                    var user = new User
                    {
                        DisplayName  = $"{item.getAttribute("displayName")?.StringValue ?? "noSn"}",
                        Sam          = item.getAttribute(SamAccountNameAttribute)?.StringValue ?? "noSam",
                        IsAdmin      = item.getAttribute(MemberOfAttribute)?.StringValueArray.Contains(_config.AdminCn) ?? false,
                        Subordinates = null,
                        Email        = item.getAttribute("mail")?.StringValue ?? "noMail"
                    };
                    yield return(user);
                }

                LdapControl[] controls = lsc.ResponseControls;
                if (controls == null)
                {
                    Console.Out.WriteLine("No controls returned");
                }
                else
                {
                    foreach (LdapControl control in controls)
                    {
                        if (control.ID == "2.16.840.1.113730.3.4.10")
                        {
                            LdapVirtualListResponse response = new LdapVirtualListResponse(control.ID, control.Critical, control.getValue());
                            startIndex  += afterIndex + 1;
                            contentCount = response.ContentCount;
                            count       += afterIndex;
                        }
                    }
                }
                // Console.WriteLine(i);
            } while (count <= contentCount);
            yield break;
        }
Exemple #4
0
        /// <summary>
        /// Executes the paged search.
        /// </summary>
        /// <returns>The paged search.</returns>
        /// <param name="searchBase">Search base.</param>
        /// <param name="filter">Filter.</param>
        /// <param name="cookie">Cookie to restore last search.</param>
        public LdapPagedResponse ExecutePagedSearch(string searchBase, string filter, string cookie = "")
        {
            var results = new List <LdapEntry>();

            var lcm  = LdapConnectionManager.Instance;
            var conn = lcm.GetConnection();

            var sb = searchBase + config.searchBase;


            // We will be sending two controls to the server
            LdapControl[] requestControls = new LdapControl[2];


            /* Create the sort key to be used by the sort control
             * Results should be sorted based on the cn attribute.
             * See the "NDS and Ldap Integration Guide" for information on
             * Novell eDirectory support of this functionaliry.
             */
            LdapSortKey[] keys = new LdapSortKey[1];
            keys[0] = new LdapSortKey("cn");

            // Create the sort control
            requestControls[0] = new LdapSortControl(keys, true);

            /* Create the VLV Control.
             * These two fields in the VLV Control identify the before and
             * after count of entries to be returned
             */
            //int beforeCount = 0;
            //int afterCount = 0;
            //int afterCount = config.maxResults -1;

            //System.String cookie = "";

            if (cookie != "")
            {
                byte[] data = System.Convert.FromBase64String(cookie);
                cookie = System.Text.Encoding.UTF8.GetString(data);
                //cookie = System.Text.ASCIIEncoding.ASCII.GetString(data);
            }


            requestControls[1] = new LdapPagedResultsControl(config.maxResults, cookie);

            // Set the controls to be sent as part of search request
            LdapSearchConstraints cons = conn.SearchConstraints;

            cons.SetControls(requestControls);
            conn.Constraints = cons;


            // Send the search request - Synchronous Search is being used here
            logger.Debug("Calling Asynchronous Search...");

            string[] attrs = null;

            ILdapSearchResults res = (LdapSearchResults)conn.Search(sb, LdapConnection.ScopeSub, filter, attrs, false, (LdapSearchConstraints)null);

            // Loop through the results and print them out
            while (res.HasMore())
            {
                /* Get next returned entry.  Note that we should expect a Ldap-
                 * Exception object as well just in case something goes wrong
                 */
                LdapEntry nextEntry = null;
                try
                {
                    nextEntry = res.Next();
                    results.Add(nextEntry);
                }
                catch (Exception e)
                {
                    if (e is LdapReferralException)
                    {
                        continue;
                    }
                    else
                    {
                        logger.Error("Search stopped with exception " + e.ToString());
                        break;
                    }
                }

                /* Print out the returned Entries distinguished name.  */
                logger.Debug(nextEntry.Dn);
            }

            var response = new LdapPagedResponse {
                Entries = results
            };

            // Server should send back a control irrespective of the
            // status of the search request
            LdapControl[] controls = ((LdapSearchResults)res).ResponseControls;
            if (controls == null)
            {
                logger.Debug("No controls returned");
            }
            else
            {
                // We are likely to have multiple controls returned
                for (int i = 0; i < controls.Length; i++)
                {
                    /* Is this the Sort Response Control. */
                    if (controls[i] is LdapPagedResultsResponse)
                    {
                        logger.Debug("Received Ldap Paged Control from Server");

                        LdapPagedResultsResponse cresp = new LdapPagedResultsResponse(controls[i].Id, controls[i].Critical, controls[i].GetValue());

                        cookie = cresp.Cookie;



                        byte[] hexCookie = System.Text.Encoding.UTF8.GetBytes(cookie);
                        response.Cookie = Convert.ToBase64String(hexCookie);

                        /*
                         * // Cookie is an opaque octet string. The chacters it contains might not be printable.
                         * byte[] hexCookie = System.Text.Encoding.ASCII.GetBytes(cookie);
                         * StringBuilder hex = new StringBuilder(hexCookie.Length);
                         * foreach (byte b in hexCookie)
                         *  hex.AppendFormat("{0:x}", b);
                         *
                         * System.Console.Out.WriteLine("Cookie: {0}", hex.ToString());
                         * System.Console.Out.WriteLine("Size: {0}", cresp.Size);
                         */
                    }
                }
            }


            return(response);
        }
Exemple #5
0
        /// <summary>
        /// Executes the limited search.
        /// </summary>
        /// <returns>The limited search.</returns>
        /// <param name="searchBase">Search base.</param>
        /// <param name="filter">Filter.</param>
        /// <param name="start">Must be 1 or greater</param>
        /// <param name="end">End.</param>
        public List <LdapEntry> ExecuteLimitedSearch(string searchBase, string filter, int start, int end)
        {
            int sSize = getSearchSize(searchBase, filter);

            //int sSize = 1000;

            var results = new List <LdapEntry>();

            var lcm  = LdapConnectionManager.Instance;
            var conn = lcm.GetConnection();

            var sb = searchBase + config.searchBase;

            LdapControl[] requestControls = new LdapControl[2];

            LdapSortKey[] keys = new LdapSortKey[1];
            keys[0] = new LdapSortKey("cn"); //samaccountname

            // Create the sort control
            requestControls[0] = new LdapSortControl(keys, true);

            logger.Debug("Search Size:" + sSize);

            requestControls[1] = new LdapVirtualListControl(start, 0, end, sSize);

            //requestControls[1] = new LdapVirtualListControl(filter,0, end, null);

            // Set the controls to be sent as part of search request
            LdapSearchConstraints cons = conn.SearchConstraints;

            cons.SetControls(requestControls);
            conn.Constraints = cons;


            // Send the search request - Synchronous Search is being used here
            logger.Debug("Calling Asynchronous Search...");
            LdapSearchResults res = (LdapSearchResults)conn.Search(sb, LdapConnection.ScopeSub, filter, null, false, (LdapSearchConstraints)null);

            // Loop through the results and print them out
            while (res.HasMore())
            {
                /* Get next returned entry.  Note that we should expect a Ldap-
                 * Exception object as well just in case something goes wrong
                 */
                LdapEntry nextEntry = null;
                try
                {
                    nextEntry = res.Next();
                    results.Add(nextEntry);
                }
                catch (Exception e)
                {
                    if (e is LdapReferralException)
                    {
                        continue;
                    }
                    else
                    {
                        logger.Error("Search stopped with exception " + e.ToString());
                        break;
                    }
                }

                /* Print out the returned Entries distinguished name.  */
                logger.Debug(nextEntry.Dn);
            }

            // Server should send back a control irrespective of the
            // status of the search request
            LdapControl[] controls = res.ResponseControls;
            if (controls == null)
            {
                logger.Debug("No controls returned");
            }
            else
            {
                // We are likely to have multiple controls returned
                for (int i = 0; i < controls.Length; i++)
                {
                    /* Is this the Sort Response Control. */
                    if (controls[i] is LdapSortResponse)
                    {
                        logger.Debug("Received Ldap Sort Control from " + "Server");

                        /* We could have an error code and maybe a string
                         * identifying erring attribute in the response control.
                         */
                        System.String bad    = ((LdapSortResponse)controls[i]).FailedAttribute;
                        int           result = ((LdapSortResponse)controls[i]).ResultCode;

                        // Print out error code (0 if no error) and any
                        // returned attribute
                        logger.Debug("Error code: " + result);
                        if ((System.Object)bad != null)
                        {
                            logger.Debug("Offending " + "attribute: " + bad);
                        }
                        else
                        {
                            logger.Debug("No offending " + "attribute " + "returned");
                        }
                    }

                    /* Is this a VLV Response Control */
                    if (controls[i] is LdapVirtualListResponse)
                    {
                        logger.Debug("Received VLV Response Control from " + "Server...");

                        /* Get all returned fields */
                        int           firstPosition = ((LdapVirtualListResponse)controls[i]).FirstPosition;
                        int           ContentCount  = ((LdapVirtualListResponse)controls[i]).ContentCount;
                        int           resultCode    = ((LdapVirtualListResponse)controls[i]).ResultCode;
                        System.String context       = ((LdapVirtualListResponse)controls[i]).Context;

                        /* Print out the returned fields.  Typically you would
                         * have used these fields to reissue another VLV request
                         * or to display the list on a GUI
                         */
                        logger.Debug("Result Code    => " + resultCode);
                        logger.Debug("First Position => " + firstPosition);
                        logger.Debug("Content Count  => " + ContentCount);
                        if ((System.Object)context != null)
                        {
                            logger.Debug("Context String => " + context);
                        }
                        else
                        {
                            logger.Debug("No Context String in returned" + " control");
                        }
                    }
                }
            }

            return(results);
        }
Exemple #6
0
        private int getSearchSize(string searchBase, string filter)
        {
            var results = new List <LdapEntry>();

            var lcm  = LdapConnectionManager.Instance;
            var conn = lcm.GetConnection();

            var sb = searchBase + config.searchBase;

            LdapControl[] requestControls = new LdapControl[2];

            LdapSortKey[] keys = new LdapSortKey[1];
            keys[0] = new LdapSortKey("cn"); //samaccountname

            // Create the sort control
            requestControls[0] = new LdapSortControl(keys, true);

            requestControls[1] = new LdapVirtualListControl(1, 0, 1, config.maxResults);

            //requestControls[1] = new LdapVirtualListControl(sb,0, config.maxResults, null);

            // Set the controls to be sent as part of search request
            LdapSearchConstraints cons = conn.SearchConstraints;

            cons.SetControls(requestControls);
            conn.Constraints = cons;


            // Send the search request - Synchronous Search is being used here
            logger.Debug("Calling Asynchronous Search...");
            LdapSearchResults res = (LdapSearchResults)conn.Search(sb, LdapConnection.ScopeOne, filter, null, false,
                                                                   (LdapSearchConstraints)null);

            while (res.HasMore())
            {
                res.Next();
            }

            // Server should send back a control irrespective of the
            // status of the search request
            LdapControl[] controls = res.ResponseControls;
            if (controls == null)
            {
                logger.Debug("No controls returned");
            }
            else
            {
                // We are likely to have multiple controls returned
                for (int i = 0; i < controls.Length; i++)
                {
                    /* Is this a VLV Response Control */
                    if (controls[i] is LdapVirtualListResponse)
                    {
                        logger.Debug("Received VLV Response Control from " + "Server...");

                        /* Get all returned fields */
                        int           firstPosition = ((LdapVirtualListResponse)controls[i]).FirstPosition;
                        int           ContentCount  = ((LdapVirtualListResponse)controls[i]).ContentCount;
                        int           resultCode    = ((LdapVirtualListResponse)controls[i]).ResultCode;
                        System.String context       = ((LdapVirtualListResponse)controls[i]).Context;

                        /* Print out the returned fields.  Typically you would
                         * have used these fields to reissue another VLV request
                         * or to display the list on a GUI
                         */
                        logger.Debug("Result Code    => " + resultCode);
                        logger.Debug("First Position => " + firstPosition);
                        logger.Debug("Content Count  => " + ContentCount);
                        if ((System.Object)context != null)
                        {
                            logger.Debug("Context String => " + context);
                        }
                        else
                        {
                            logger.Debug("No Context String in returned" + " control");
                        }

                        return(ContentCount);
                    }
                }
            }

            return(-1);
        }
        static void Main(string[] args)
        {
            if (args.Length != 6)
            {
                Console.WriteLine("Usage:   mono SortSearch <host name> <ldap port>  <login dn>" + " <password> <search base>" + " <search filter>");
                Console.WriteLine("Example: mono SortSearch Acme.com 389" + " \"cn=admin,o=Acme\"" + " secret \"ou=sales,o=Acme\"" + "         \"(objectclass=*)\"");
                return;
            }

            string ldapHost     = args[0];
            int    ldapPort     = System.Convert.ToInt32(args[1]);
            String loginDN      = args[2];
            String password     = args[3];
            String searchBase   = args[4];
            String searchFilter = args[5];

            String[] attrs = new String[1];
            attrs[0] = "sn";

            LdapSortKey[] keys = new LdapSortKey[1];
            keys[0] = new LdapSortKey("sn");

            try
            {
                LdapConnection conn = new LdapConnection();
                conn.Connect(ldapHost, ldapPort);
                conn.Bind(loginDN, password);


                // Create a LDAPSortControl object - Fail if cannot sort
                LdapSortControl sort = new LdapSortControl(keys, true);

                // Set the Sort control to be sent as part of search request
                LdapSearchConstraints cons = conn.SearchConstraints;
                cons.setControls(sort);
                conn.Constraints = cons;

                Console.WriteLine("Connecting to:" + ldapHost);
                LdapSearchResults lsc = conn.Search(searchBase,
                                                    LdapConnection.SCOPE_SUB,
                                                    searchFilter,
                                                    attrs,
                                                    false,
                                                    (LdapSearchConstraints)null);

                while (lsc.hasMore())
                {
                    LdapEntry nextEntry = null;
                    try
                    {
                        nextEntry = lsc.next();
                    }
                    catch (LdapException e)
                    {
                        Console.WriteLine("Error: " + e.LdapErrorMessage);
                        // Exception is thrown, go for next entry
                        continue;
                    }
                    Console.WriteLine("\n" + nextEntry.DN);
                    LdapAttributeSet attributeSet        = nextEntry.getAttributeSet();
                    System.Collections.IEnumerator ienum = attributeSet.GetEnumerator();
                    while (ienum.MoveNext())
                    {
                        LdapAttribute attribute     = (LdapAttribute)ienum.Current;
                        string        attributeName = attribute.Name;
                        string        attributeVal  = attribute.StringValue;
                        Console.WriteLine(attributeName + "value:" + attributeVal);
                    }
                }

                conn.Disconnect();
            }
            catch (LdapException e)
            {
                Console.WriteLine("Error:" + e.LdapErrorMessage);
                Console.WriteLine("Error:" + e.ToString());
                return;
            }
            catch (Exception e)
            {
                Console.WriteLine("Error:" + e.Message);
                return;
            }
        }
    public static void Main(String[] args)
    {
        // Verify correct number of parameters
        if (args.Length != 4)
        {
            Console.WriteLine("Usage:   mono AsynchronousSortControl <host name> "
                              + "<login dn> <password> <container>");
            Console.WriteLine("Example: mono AsynchronousSortControl Acme.com"
                              + " \"cn=admin,o=Acme\" secret \"ou=Sales,o=Acme\"");
            Environment.Exit(0);
        }

        // Read command line arguments
        String ldapHost    = args[0];
        String loginDN     = args[1];
        String password    = args[2];
        String searchBase  = args[3];
        int    MY_PORT     = 389;
        int    ldapVersion = LdapConnection.Ldap_V3;

        try
        {
            // Create a LdapConnection object
            LdapConnection lc = new LdapConnection();

            // Connect to server
            lc.Connect(ldapHost, MY_PORT);
            lc.Bind(ldapVersion, loginDN, password);
            Console.WriteLine("Login succeeded");

            // We will be searching for all objects
            String MY_FILTER = "(objectClass=*)";

            //  Results of the search should include givenname and cn
            String[] attrs = new String[2];
            attrs[0] = "givenname";
            attrs[1] = "cn";

            // The results should be sorted using the cn attribute
            LdapSortKey[] keys = new LdapSortKey[1];
            keys[0] = new LdapSortKey("cn");

            // Create a LdapSortControl object - Fail if cannot sort
            LdapSortControl sort = new LdapSortControl(keys, true);

            // Set the Sort control to be sent as part of search request
            LdapSearchConstraints cons = lc.SearchConstraints;
            cons.setControls(sort);
            lc.Constraints = cons;

            // Perform the search - ASYNCHRONOUS SEARCH USED HERE
            Console.WriteLine("Calling search request");
            LdapSearchQueue queue = lc.Search(searchBase,
                                              LdapConnection.SCOPE_SUB,
                                              MY_FILTER,
                                              attrs,
                                              false,
                                              (LdapSearchQueue)null,
                                              (LdapSearchConstraints)null);

            LdapMessage message;
            while ((message = queue.getResponse()) != null)
            {
                // OPTION 1: the message is a search result reference
                if (message is LdapSearchResultReference)
                {
                    // Not following referrals to keep things simple
                    String[] urls = ((LdapSearchResultReference)message).Referrals;
                    Console.WriteLine("Search result references:");
                    for (int i = 0; i < urls.Length; i++)
                    {
                        Console.WriteLine(urls[i]);
                    }
                }

                // OPTION 2:the message is a search result
                else if (message is LdapSearchResult)
                {
                    // Get the object name
                    LdapEntry entry = ((LdapSearchResult)message).Entry;

                    Console.WriteLine("\n" + entry.DN);
                    Console.WriteLine("\tAttributes: ");

                    // Get the attributes and print them out
                    LdapAttributeSet attributeSet  = entry.getAttributeSet();
                    IEnumerator      allAttributes = attributeSet.GetEnumerator();

                    while (allAttributes.MoveNext())
                    {
                        LdapAttribute attribute     = (LdapAttribute)allAttributes.Current;
                        String        attributeName = attribute.Name;

                        Console.WriteLine("\t\t" + attributeName);

                        // Print all values of the attribute
                        IEnumerator allValues = attribute.StringValues;
                        if (allValues != null)
                        {
                            while (allValues.MoveNext())
                            {
                                String Value = (String)allValues.Current;
                                Console.WriteLine("\t\t\t" + Value);
                            }
                        }
                    }
                }

                // OPTION 3: The message is a search response
                else
                {
                    LdapResponse response = (LdapResponse)message;
                    int          status   = response.ResultCode;

                    // the return code is Ldap success
                    if (status == LdapException.SUCCESS)
                    {
                        Console.WriteLine("Asynchronous search succeeded.");
                    }

                    // the return code is referral exception
                    else if (status == LdapException.REFERRAL)
                    {
                        String[] urls = ((LdapResponse)message).Referrals;
                        Console.WriteLine("Referrals:");
                        for (int i = 0; i < urls.Length; i++)
                        {
                            Console.WriteLine(urls[i]);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Asynchronous search failed.");
                        Console.WriteLine(response.ErrorMessage);
                    }

                    // Server should send back a control irrespective of the
                    // status of the search request
                    LdapControl[] controls = response.Controls;
                    if (controls != null)
                    {
                        // Theoritically we could have multiple controls returned
                        for (int i = 0; i < controls.Length; i++)
                        {
                            // We are looking for the LdapSortResponse Control class - the control
                            // sent back in response to LdapSortControl
                            if (controls[i] is LdapSortResponse)
                            {
                                Console.WriteLine("Received Ldap Sort Control fromserver");

                                // We must have an error code and maybe a string identifying
                                // erring attribute in the response control.  Get these.
                                String bad    = ((LdapSortResponse)controls[i]).FailedAttribute;
                                int    result = ((LdapSortResponse)controls[i]).ResultCode;

                                // Print out error ccode (0 if no error) and any returned
                                // attribute
                                Console.WriteLine("Error code: " + result);
                                if (bad != null)
                                {
                                    Console.WriteLine("Offending " + "attribute: " + bad);
                                }
                                else
                                {
                                    Console.WriteLine("No offending " + "attribute " + "returned");
                                }
                            }
                        }
                    }
                }
            }

            // All done - disconnect
            if (lc.Connected == true)
            {
                lc.Disconnect();
            }
        }

        catch (LdapException e)
        {
            Console.WriteLine(e.ToString());
        }
        catch (Exception e)
        {
            Console.WriteLine("Error: " + e.ToString());
        }
    }