Exemplo n.º 1
1
        // Constructor
        public PSearchEventSource(
            LdapConnection conn,
            string searchBase,
            int scope,
            string filter,
            string[] attrs,
            bool typesOnly,
            LdapSearchConstraints constraints,
            LdapEventType eventchangetype,
            bool changeonly
            )
        {
            // validate the input arguments
              if ((conn == null)
              || (searchBase == null)
              || (filter == null)
              || (attrs == null))
              {
            throw new ArgumentException("Null argument specified");
              }

              mConnection = conn;
              mSearchBase = searchBase;
              mScope = scope;
              mFilter = filter;
              mAttrs = attrs;
              mTypesOnly = typesOnly;
              mEventChangeType = eventchangetype;

              // make things ready for starting a search operation
              if (constraints == null)
              {
            mSearchConstraints = new LdapSearchConstraints();
              }
              else
              {
            mSearchConstraints = constraints;
              }

              //Create the persistent search control
              LdapPersistSearchControl psCtrl =
            new LdapPersistSearchControl((int)eventchangetype,// any change
                     changeonly, //only get changes
                     true, //return entry change controls
                     true); //control is critcal

              // add the persistent search control to the search constraints
              mSearchConstraints.setControls(psCtrl);
        }
Exemplo n.º 2
0
        public IActionResult BuscarLoginPorCpf([FromRoute] string cpf)
        {
            var idCelula = string.Empty;
            var login    = string.Empty;

            using (var cn = new LdapConnection())
            {
                cn.Connect(_ldapConfig.First().Hostname, _ldapConfig.First().Port);
                cn.Bind("stefanini-dom\\almintegration", "stefanini@10");

                LdapSearchConstraints cons = cn.SearchConstraints;
                cons.ReferralFollowing = true;
                cn.Constraints         = cons;

                var filterInformacaoUsuario = $"(employeenumber={cpf})";
                var search = cn.Search("DC=stefanini,DC=dom", LdapConnection.SCOPE_SUB, filterInformacaoUsuario, null, false, (LdapSearchConstraints)null);

                while (search.hasMore())
                {
                    var nextEntry = search.next();
                    var user      = nextEntry.getAttributeSet();

                    idCelula = user.getAttribute("department").StringValue;
                    login    = user.getAttribute("sAMAccountName").StringValue;
                    break;
                }
            }

            return(Ok(new { idCelula, login }));
        }
Exemplo n.º 3
0
        private static LdapEntry GetOneUserEntry(
            LdapConnection conn,
            LdapSettings ldapSettings,
            string search)
        {
            LdapSearchConstraints constraints = new LdapSearchConstraints();

            LdapSearchQueue queue = null;

            queue = conn.Search(
                ldapSettings.RootDN,
                LdapConnection.SCOPE_SUB,
                ldapSettings.UserDNKey + "=" + search,
                null,
                false,
                (LdapSearchQueue)null,
                (LdapSearchConstraints)null);

            LdapEntry entry = null;

            if (queue != null)
            {
                LdapMessage message = queue.getResponse();
                if (message != null)
                {
                    if (message is LdapSearchResult)
                    {
                        entry = ((LdapSearchResult)message).Entry;
                    }
                }
            }

            return(entry);
        }
Exemplo n.º 4
0
        public static bool searchGroupEntry(LdapConnection lc, String searchBase, string searchFilter)
        {
            bool status      = true;
            int  searchScope = LdapConnection.SCOPE_SUB;

            String[] attrList          = new String[] { "distinguishedName" };
            LdapSearchConstraints cons = new LdapSearchConstraints();

            cons.TimeLimit = 10000;
            try
            {
                LdapSearchResults searchResults =
                    lc.Search(searchBase,
                              searchScope,
                              searchFilter,
                              attrList,
                              false,
                              cons);                              // time out value

                LdapEntry nextEntry = null;

                if ((nextEntry = searchResults.next()) == null)
                {
                    status = false;
                }
            }
            catch
            {
                status = false;
            }
            return(status);
        }
Exemplo n.º 5
0
        /// <summary> Constructs an LdapSearchConstraints object initialized with values
        /// from an existing constraints object (LdapConstraints
        /// or LdapSearchConstraints).
        /// </summary>
        public LdapSearchConstraints(LdapConstraints cons) : base(cons.TimeLimit, cons.ReferralFollowing, cons.getReferralHandler(), cons.HopLimit)
        {
            InitBlock();
            LdapControl[] lsc = cons.getControls();
            if (lsc != null)
            {
                LdapControl[] generated_var = new LdapControl[lsc.Length];
                lsc.CopyTo(generated_var, 0);
                setControls(generated_var);
            }
            System.Collections.Hashtable lp = cons.Properties;
            if (lp != null)
            {
                Properties = (System.Collections.Hashtable)lp.Clone();
            }

            if (cons is LdapSearchConstraints)
            {
                LdapSearchConstraints scons = (LdapSearchConstraints)cons;
                serverTimeLimit = scons.ServerTimeLimit;
                dereference     = scons.Dereference;
                maxResults      = scons.MaxResults;
                batchSize       = scons.BatchSize;
            }
            // Get a unique connection name for debug
        }
Exemplo n.º 6
0
        ADInfo Search(LdapConnection ldapConn)
        {
            LdapSearchConstraints constraints = new LdapSearchConstraints
            {
                TimeLimit = 10000
            };

            LdapSearchResults lsc = ldapConn.Search(
                SearchBase,
                LdapConnection.SCOPE_SUB,
                "SAMAccountName=" + Username.ToLower(),
                null,  // no specified attributes
                false, // return attr and value
                constraints);

            while (lsc.hasMore())
            {
                LdapEntry nextEntry = null;
                try
                {
                    nextEntry = lsc.next();
                    return(new ADInfo(Username, nextEntry));
                }
                catch (LdapException e)
                {
                    Console.WriteLine("Error: " + e.LdapErrorMessage);
                    // Exception is thrown, go for next entry
                    continue;
                }
            }
            return(null);
        }
Exemplo n.º 7
0
        private string IsUserExistsLDAP(string name, string pwd)
        {
            // Metemos los valores de configuración para conectarnos al ldap de Everis.
            int LdapPort = LdapConnection.DEFAULT_PORT;
            //int searchScope = LdapConnection.SCOPE_ONE;
            int LdapVersion = LdapConnection.Ldap_V3;

            //bool attributeOnly=true;
            String[]       attrs     = { LdapConnection.NO_ATTRS };
            LdapConnection lc        = new LdapConnection();
            string         resultado = "";
            // Vamos a meter una restricción de tiempo.
            LdapSearchConstraints constraints = new LdapSearchConstraints();

            constraints.TimeLimit = 10000; // ms

            try{
                // Nos conectamos al servidor.
                lc.Connect(ldapHost, LdapPort);
                // Accedemos con las credenciales del usuario para ver si está.
                lc.Bind(LdapVersion, Configuration["connectionStrings:LDAPDomain"] + name, pwd);

                // Set values to search
                string          base1      = "OU=Spain,OU=Europe,OU=Everis,DC=usersad,DC=everis,DC=int";
                string[]        attributes = new string[] { "displayName", "samaccountname" };
                string          filter     = String.Format("(&(objectClass=user)(samaccountname={0}))", name);
                LdapSearchQueue lsc        = lc.Search(base1, LdapConnection.SCOPE_SUB, filter, attributes, false, (LdapSearchQueue)null, (LdapSearchConstraints)null);
                LdapMessage     msg;
                if ((msg = lsc.getResponse()) != null)
                {
                    if (msg is LdapSearchResult)
                    {
                        LdapEntry        nextEntry    = ((LdapSearchResult)msg).Entry;
                        LdapAttributeSet attributeSet = nextEntry.getAttributeSet();
                        Console.WriteLine("Nombre corto: " + attributeSet.getAttribute("samaccountname").StringValue);
                        Console.WriteLine("Nombre Largo: " + attributeSet.getAttribute("displayName").StringValue);
                        string[] ss = attributeSet.getAttribute("displayName").StringValue.Split(' ');
                        string   s2 = ss[0];
                        if (ss.Length > 1)
                        {
                            s2 += " " + ss[1];
                        }
                        return(s2);
                    }
                }

                lc.Disconnect();
            } catch (LdapException e) {
                Console.WriteLine(e.Message);
                return(null);
            } catch (Exception) {
                Console.WriteLine("error");
                return(null);
            }
            return(resultado);
        }
Exemplo n.º 8
0
 private void SetLdapControls(LdapFilter pageInfo, LdapSearchConstraints constraints)
 {
     LdapControl[] ldapControls =
     {
         new LdapSortControl(new LdapSortKey(pageInfo.OrderBy ?? LdapConfiguration.Attribute.UniqueName),
                             true),
         new LdapVirtualListControl(pageInfo.TotalResults, 0, pageInfo.TotalPerPage - 1, pageInfo.ContentCount)
     };
     constraints.setControls(ldapControls);
 }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
0
        private void ExecuteSearch(LdapFilter filter, LdapConnection ldapConnection, Action <LdapSearchResults> middleAction)
        {
            LdapSearchConstraints constraints = ldapConnection.SearchConstraints;

            SetLdapControls(filter, constraints);

            LdapSearchResults searchResults = ldapConnection.Search(
                filter.SearchPath, LdapConnection.SCOPE_SUB,
                filter.SearchCriteria, null, false, constraints);

            middleAction(searchResults);
            TotalResultsCallback(filter, searchResults);
        }
Exemplo n.º 11
0
            public DomainSearcher(string username    = "", string password           = "", string Domain = "", string Server = "",
                                  string SearchBase  = "", string SearchString       = "",
                                  int ResultPageSize = 200, TimeSpan ServerTimeLimit = default(TimeSpan), bool TombStone = false,
                                  bool ssl           = false)
            {
                this.Domain     = Domain;
                this.Server     = Server;
                this.SearchBase = SearchBase;
                this.Searcher   = new LdapConnection();
                if (this.Domain == "")
                {
                    this.Domain = Environment.UserDomainName;
                }

                if (this.Server == "")
                {
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        string logonserver = Environment.GetEnvironmentVariable(("logonserver"));
                        this.Server = logonserver.Replace("\\", "");
                    }
                    else
                    {
                        //Attempt to get userdomain from environmental variable linux.
                        this.Server = Environment.GetEnvironmentVariable("userdomain");
                    }
                }

                if (SearchBase == "")
                {
                    //this.SearchBase = "LDAP://" + this.GetBaseDN();
                    this.SearchBase = this.GetBaseDN();
                }

                if (ssl)
                {
                    this.Searcher.SecureSocketLayer = true;
                }
                else
                {
                    this.Searcher.SecureSocketLayer = false;
                }

                LdapSearchConstraints cons = this.Searcher.SearchConstraints;

                cons.ReferralFollowing    = true;
                this.Searcher.Constraints = cons;
                this.Searcher.Connect(this.Server, 389);
                this.Searcher.Bind(username, password);
            }
Exemplo n.º 12
0
        // Constructor
        public PSearchEventSource(
            LdapConnection conn,
            string searchBase,
            int scope,
            string filter,
            string[] attrs,
            bool typesOnly,
            LdapSearchConstraints constraints,
            LdapEventType eventchangetype,
            bool changeonly)
        {
            // validate the input arguments
            if (conn == null ||
                searchBase == null ||
                filter == null ||
                attrs == null)
            {
                throw new ArgumentException("Null argument specified");
            }

            _mConnection      = conn;
            _mSearchBase      = searchBase;
            _mScope           = scope;
            _mFilter          = filter;
            _mAttrs           = attrs;
            _mTypesOnly       = typesOnly;
            _mEventChangeType = eventchangetype;

            // make things ready for starting a search operation
            if (constraints == null)
            {
                _mSearchConstraints = new LdapSearchConstraints();
            }
            else
            {
                _mSearchConstraints = constraints;
            }

            // Create the persistent search control
            var psCtrl =
                new LdapPersistSearchControl(
                    (int)eventchangetype, // any change
                    changeonly,           // only get changes
                    true,                 // return entry change controls
                    true);                // control is critcal

            // add the persistent search control to the search constraints
            _mSearchConstraints.SetControls(psCtrl);
        } // end of Constructor
Exemplo n.º 13
0
        private LdapSearchResults LookupLdapUser(bool retrieveGroupMembership, string username, out LdapConnection conn)
        {
            conn = Bind();

            username = EscapeLdapString(username);

            //search filter is built based on passed userQuery with username substitution
            string searchFilter = this.BuildUserSearchQuery(username);

            //Build interesting attribute list
            List <string> attrs = new List <string>();

            attrs.AddRange(new string[] { "sAMAccountName", "uid", "cn", "userAccountControl", "whenCreated", "name", "givenname", "sn", "telephonenumber", "mail", "description" });
            if (retrieveGroupMembership)
            {
                attrs.Add(_config.GroupMembersAttribute);
            }

            if (!string.IsNullOrEmpty(_config.UserNameAttribute) && !attrs.Contains(_config.UserNameAttribute))
            {
                attrs.Add(_config.UserNameAttribute);
            }

            //add more attributes to lookup if using a displayname-pattern
            string[] patternAttributes = RetrieveAttributesFromPattern(_config.DisplayNamePattern);
            if (patternAttributes != null)
            {
                foreach (string patternAttribute in patternAttributes)
                {
                    if (!attrs.Contains(patternAttribute))
                    {
                        attrs.Add(patternAttribute);
                    }
                }
            }

            LdapSearchConstraints cons = new LdapSearchConstraints(new LdapConstraints(_timeLimit, true, null, 0));

            cons.BatchSize = 0;

            LdapSearchResults results = conn.Search(_config.LdapSearchBase,
                                                    LdapConnection.SCOPE_SUB,
                                                    searchFilter,
                                                    attrs.ToArray(),
                                                    false,
                                                    cons);

            return(results);
        }
Exemplo n.º 14
0
        private bool TrySearchSimple(string searchBase, LdapScope scope, string searchFilter, out List <LdapObject> results,
                                     string[] attributes = null, int limit = -1, LdapSearchConstraints searchConstraints = null)
        {
            try
            {
                results = SearchSimple(searchBase, scope, searchFilter, attributes, limit, searchConstraints);

                return(true);
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("TrySearchSimple() failed. Error: {0}", ex);
            }

            results = null;
            return(false);
        }
Exemplo n.º 15
0
        private int checkUser(String loginDN, String password)
        {
            // Metemos los valores de configuración para conectarnos al ldap de Everis.
            int LdapPort = LdapConnection.DEFAULT_PORT;
            //int searchScope = LdapConnection.SCOPE_ONE;
            int LdapVersion = LdapConnection.Ldap_V3;

            //bool attributeOnly=true;
            String[]       attrs     = { LdapConnection.NO_ATTRS };
            LdapConnection lc        = new LdapConnection();
            int            resultado = 0;
            // Vamos a meter una restricción de tiempo.
            LdapSearchConstraints constraints = new LdapSearchConstraints();

            constraints.TimeLimit = 10000; // ms
            try{
                // Nos conectamos al servidor.
                lc.Connect(Constants.ldapHost, LdapPort);
                // Accedemos con las credenciales del usuario para ver si está.
                lc.Bind(LdapVersion, loginDN, password);
                // Set values to search
                string          base1      = "OU=Spain,OU=Europe,OU=Everis,DC=usersad,DC=everis,DC=int";
                string[]        attributes = new string[] { "displayName", "samaccountname" };
                string          filter     = String.Format("(&(objectClass=user)(samaccountname={0}))", loginDN.Substring(8));
                LdapSearchQueue lsc        = lc.Search(base1, LdapConnection.SCOPE_SUB, filter, attributes, false, (LdapSearchQueue)null, (LdapSearchConstraints)null);
                LdapMessage     msg;
                if ((msg = lsc.getResponse()) != null)
                {
                    if (msg is LdapSearchResult)
                    {
                        LdapEntry        nextEntry    = ((LdapSearchResult)msg).Entry;
                        LdapAttributeSet attributeSet = nextEntry.getAttributeSet();
                        Console.WriteLine("Nombre corto: " + attributeSet.getAttribute("samaccountname").StringValue);
                        Console.WriteLine("Nombre Largo: " + attributeSet.getAttribute("displayName").StringValue);
                    }
                }

                lc.Disconnect();
            } catch (LdapException e) {
                resultado = e.ResultCode;
            } catch (Exception) {
                resultado = -1;
            }
            return(resultado);
        }
Exemplo n.º 16
0
        private void PopulateGroupsForUserWithQuery(XDoc doc, string username, LdapConnection conn)
        {
            doc.Start("groups");

            string searchFilter = string.Format(Dream.PhpUtil.ConvertToFormatString(_config.GroupMembershipQuery), username);

            //Build interesting attribute list
            List <string> attrs = new List <string>();

            attrs.AddRange(new string[] { "whenCreated", "name", "sAMAccountName", "cn" });

            LdapSearchConstraints cons = new LdapSearchConstraints(new LdapConstraints(_timeLimit, true, null, 0));

            cons.BatchSize = 0;

            LdapSearchResults results = conn.Search(_config.LdapSearchBase,
                                                    LdapConnection.SCOPE_SUB,
                                                    searchFilter,
                                                    attrs.ToArray(),
                                                    false,
                                                    cons);

            while (results.hasMore())
            {
                LdapEntry nextEntry = null;
                try {
                    nextEntry = results.next();
                } catch (LdapException x) {
                    HandleLdapException(x);
                }

                if (nextEntry == null)
                {
                    throw new ArgumentNullException("nextEntry");
                }

                //Create xml from search entry
                doc.Start("group").Attr("name", GetNameFromDn(nextEntry.DN)).Start("ldap-dn").Value(nextEntry.DN).End().End();
            }

            doc.End(); //groups
        }
Exemplo n.º 17
0
        /// <summary>
        /// Opens a new connection to the ldap server and returns it.
        /// </summary>
        /// <returns>The ldap connection object</returns>
        private LdapConnection ConnectToServer()
        {
            try {
                LdapConnection ldapConnection = new LdapConnection();
                //A time limit on the connection to the server is added.
                ldapConnection.Constraints.TimeLimit = _settings.ConnectionTimeoutMsec;
                ldapConnection.Connect(_settings.Host, _settings.Port);
                string authenticationMethod          = ldapConnection.AuthenticationMethod;
                int    protocol                      = ldapConnection.ProtocolVersion;
                System.Collections.IDictionary prop  = ldapConnection.SaslBindProperties;
                LdapSearchConstraints          searh = ldapConnection.SearchConstraints;

                //ldapConnection.SearchConstraints.

                return(ldapConnection);
            }
            catch (Exception e) {
                throw new ConnectingToLdapServerFailedException(_settings, e);
            }
        }
Exemplo n.º 18
0
        private static List <Claim> ValidaPermissaoGrupo(Ldap ldap, LoginData loginData, String usuarioDN, List <PermissionGroup> grupos)
        {
            LdapConnection ldapConnection = ldapConnection = new LdapConnection();

            ldapConnection.Connect(ldap.host, ldap.port);
            ldapConnection.Bind(ldap.ldapVersion, ldap.bindLogin, ldap.bindPassword);

            LdapSearchConstraints cons = new LdapSearchConstraints();

            String[] atributos = new String[] { "member" };

            List <Claim> claims = new List <Claim>();

            try
            {
                foreach (PermissionGroup grupo in grupos)
                {
                    String            groupDN       = GetDNGrupo(ldapConnection, ldap, grupo.Name);
                    LdapSearchResults searchResults = ldapConnection.Search(groupDN, LdapConnection.SCOPE_BASE, null, atributos, false, cons);

                    var nextEntry = searchResults.Next();
                    nextEntry.getAttributeSet();

                    try
                    {
                        if (nextEntry.getAttribute("member").StringValueArray.Where(x => x == usuarioDN).Count() > 0)
                        {
                            claims.AddRange(GetClaimType(grupo.AccessType));
                        }
                    }
                    catch { }
                }
            }
            catch (Exception erro) {
                GALibrary.GALogs.SaveLog("AD", "Erro ao validar permissao do usuario: " + erro.ToString(), 1, GALibrary.Models.DB.Context.Parameter.FirstOrDefault());
            }

            ldapConnection.Disconnect();
            return(claims);
        }
        public void Search_when_paging_using_VirtualListViewControl_returns_expected_results()
        {
            const int pages           = 10;
            const int pageSize        = 50;
            var       cnPrefix        = new Random().Next().ToString();
            var       expectedEntries = Enumerable.Range(1, pages * pageSize).Select(x => LdapOps.AddEntry(cnPrefix)).ToList();

            var searchConstraints = new LdapSearchConstraints
            {
                BatchSize  = 0,
                MaxResults = 1000
            };

            var entries = new List <LdapEntry>();

            TestHelper.WithAuthenticatedLdapConnection(
                ldapConnection =>
            {
                var sortControl = new LdapSortControl(new LdapSortKey("cn"), true);
                var pageCount   = 1;
                while (true)
                {
                    searchConstraints.SetControls(new LdapControl[] { BuildLdapVirtualListControl(pageCount, pageSize), sortControl });
                    var searchResults = ldapConnection.Search(TestsConfig.LdapServer.BaseDn, LdapConnection.ScopeSub, "cn=" + cnPrefix + "*", null, false, searchConstraints).ToList();
                    entries.AddRange(searchResults);
                    if (searchResults.Count < pageSize)
                    {
                        break;
                    }

                    pageCount++;
                }
            });

            Assert.Equal(expectedEntries.Count, entries.Count);
            foreach (var pair in expectedEntries.OrderBy(x => x.Dn).Zip(entries.OrderBy(x => x.Dn)))
            {
                pair.First.AssertSameAs(pair.Second);
            }
        }
Exemplo n.º 20
0
        private async Task <List <Claim> > UserVerifyGroup(String userDN)
        {
            LdapSearchConstraints cons = new LdapSearchConstraints();

            String[] atributos = new String[] { "member" };

            List <Claim> claims           = new List <Claim>();
            var          permissionGroups = await permissionGroupRepository.GetList();

            try
            {
                foreach (PermissionGroup group in permissionGroups)
                {
                    String groupDN = await GetGroupDN(group.GroupName);

                    LdapSearchResults searchResults = ldapConnection.Search(groupDN, LdapConnection.SCOPE_BASE, null, atributos, false, cons);

                    var nextEntry = searchResults.Next();
                    nextEntry.getAttributeSet();

                    try
                    {
                        if (nextEntry.getAttribute("member").StringValueArray.Where(x => x == userDN).Count() > 0)
                        {
                            claims.AddRange(GetClaimType(group.AccessType));
                            claims.Add(new Claim("Reports", group.Id.ToString()));
                        }
                    }
                    catch { }
                }
            }
            catch (Exception error)
            {
                await log.SaveLogApplicationError(controllerName, "Erro ao verificar grupo de segurança: " + error.ToString());
            }

            ldapConnection.Disconnect();

            return(claims);
        }
Exemplo n.º 21
0
        /// <summary>Searches the directory
        /// </summary>
        /// <param name="searchBase">Where to start the search</param>
        /// <param name="searchScope">Scope of search</param>
        /// <param name="searchFilter">Filter to search for</param>
        /// <param name="searchAttrs">Attributes to search for</param>
        /// <returns>List of entries matching filter</returns>
        public LdapEntry[] Search(string searchBase, int searchScope, string searchFilter, string[] searchAttrs)
        {
            if (!conn.Connected)
            {
                return(null);
            }

            try {
                List <LdapEntry> retVal    = new List <LdapEntry> ();
                RfcFilter        rfcFilter = new RfcFilter(searchFilter);

                LdapSearchConstraints cons = new LdapSearchConstraints();
                cons.MaxResults = 0;

                LdapSearchQueue queue = conn.Search(searchBase,
                                                    searchScope,
                                                    rfcFilter.filterToString(),
                                                    searchAttrs,
                                                    false,
                                                    (LdapSearchQueue)null,
                                                    cons);

                LdapMessage msg;

                while ((msg = queue.getResponse()) != null)
                {
                    if (msg is LdapSearchResult)
                    {
                        LdapEntry entry = ((LdapSearchResult)msg).Entry;
                        retVal.Add(entry);
                    }
                }

                return(retVal.ToArray());
            } catch (Exception e) {
                Log.Debug(e);
                return(null);
            }
        }
Exemplo n.º 22
0
        public static string lookingForGroupDN(LdapConnection lc, String searchBase, string groupName)
        {
            string searchFilter = String.Concat("(&(objectCategory=Group)(cn=", groupName, "))");
            string dn           = "";
            int    searchScope  = LdapConnection.SCOPE_SUB;

            String[] attrList          = new String[] { "distinguishedName" };
            LdapSearchConstraints cons = new LdapSearchConstraints();

            cons.TimeLimit = 10000;
            try
            {
                LdapSearchResults searchResults =
                    lc.Search(searchBase,
                              searchScope,
                              searchFilter,
                              attrList,
                              false,
                              cons);                              // time out value

                LdapEntry nextEntry = null;
                if ((nextEntry = searchResults.next()) != null)
                {
                    LdapAttributeSet attributeSet        = nextEntry.getAttributeSet();
                    System.Collections.IEnumerator ienum = attributeSet.GetEnumerator();
                    while (ienum.MoveNext())
                    {
                        LdapAttribute attribute = (LdapAttribute)ienum.Current;
                        dn = attribute.StringValue;
                    }
                }
            }
            catch (LdapException e)
            {
                Console.WriteLine("ERROR: Cannot find the group DN {0} (Maybe wrong groupname? ) ", groupName);
                throw new System.Exception(e.ToString());
            }
            return(dn);
        }
Exemplo n.º 23
0
        private LdapSearchQueue StartUserSearch(SearchRequestState requestState)
        {
            var searchConstraints =
                new LdapSearchConstraints(_ldapConfiguration.Value.TimeoutInMilliseconds,
                                          _ldapConfiguration.Value.TimeoutInSeconds,
                                          LdapSearchConstraints.DerefNever,
                                          1,
                                          true,
                                          1,
                                          null,
                                          20);
            var attributes  = new[] { "name", "givenname", "samaccountname", "mail" };
            var searchQueue = requestState.Connection.Search(_ldapConfiguration.Value.SearchBase,
                                                             LdapConnection.ScopeSub,
                                                             requestState.Filter,
                                                             attributes,
                                                             false,
                                                             null,
                                                             searchConstraints);

            return(searchQueue);
        }
Exemplo n.º 24
0
 private LdapSearchResults Search(string @base,
                                  int scope,
                                  string filter,
                                  string[] attrs,
                                  bool typesOnly,
                                  LdapSearchConstraints cons)
 {
     Log.Information("Getting all directory entries with the following config:\n" +
                     $"base: {@base}\n" +
                     $"scope: {scope}\n" +
                     $"filter: {filter}\n" +
                     $"attrs: {attrs}\n" +
                     $"typesOnly: {typesOnly}\n" +
                     $"cons: {cons}\n"
                     );
     return(_connection.Search(
                @base,
                scope,
                filter,
                attrs,
                typesOnly,
                cons));
 }
        public LdapUser GetUserByUserName(string userName)
        {
            LdapUser user = null;

            LdapSearchConstraints lsc = new LdapSearchConstraints();

            lsc.ReferralFollowing = this._ldapSettings.ReferralFollowing;

            var un = userName.Split('@')[0];

            var filter = string.Format(this._ldapSettings.SearchFilter, un);

            using (var ldapConnection = this.GetConnection())
            {
                var search = ldapConnection.Search(
                    this._searchBase,
                    LdapConnection.SCOPE_SUB,
                    filter,
                    this._attributes,
                    false,
                    null,
                    lsc);

                LdapMessage message;

                while ((message = search.getResponse()) != null)
                {
                    if (!(message is LdapSearchResult searchResultMessage))
                    {
                        continue;
                    }
                    user = this.CreateUserFromAttributes(searchResultMessage.Entry.DN, searchResultMessage.Entry.getAttributeSet());
                }
            }

            return(user);
        }
Exemplo n.º 26
0
        /// <summary>
        /// Searchs for a certificate on the ldap server. Uses the connection given and fetches the search string
        /// by calling GetBase() and GetFilter()
        /// </summary>
        /// <exception cref="SearchFailedException">Returned if the search failed</exception>
        /// <param name="ldapConnection">Ldap connection settings</param>
        /// <param name="subject">The certificate subject used in the search</param>
        /// <returns></returns>
        private LdapSearchResults Search(LdapConnection ldapConnection, CertificateSubject subject)
        {
            LdapSearchResults ldapSearchResults;
            string            searchBase   = subject.DnsSearchBase;
            string            searchFilter = subject.DnsSearchFilter;

            LdapSearchConstraints lsc = new LdapSearchConstraints();

            lsc.ServerTimeLimit = _settings.SearchServerTimeoutMsec;
            lsc.TimeLimit       = _settings.SearchClientTimeoutMsec;
            lsc.MaxResults      = _settings.MaxResults;

            string[] attributes = { "userCertificate" };

            try
            {
                ldapSearchResults = ldapConnection.Search(searchBase, LdapConnection.SCOPE_SUB, searchFilter, attributes, false, lsc);
            }
            catch (Exception e) {
                throw new SearchFailedException(e);
            }

            return(ldapSearchResults);
        }
        private string BuscarEmailsParaEnvio(string funcionalidade, Prestador prestador)
        {
            var idFuncionalidade =
                _reajusteContratoRepository.ObterIdFuncionalidade(funcionalidade);

            var logins = _reajusteContratoRepository.ObterLoginsComFuncionalidade(idFuncionalidade, prestador);

            var listaEmails = new List <string>();

            using (var cn = new LdapConnection())
            {
                cn.Connect(_ldapConfig.First().Hostname, _ldapConfig.First().Port);
                cn.Bind("stefanini-dom\\almintegration", "stefanini@10");

                LdapSearchConstraints cons = cn.SearchConstraints;
                cons.ReferralFollowing = true;
                cn.Constraints         = cons;

                foreach (var login in logins)
                {
                    var filterInformacaoUsuario = $"(sAMAccountName={login})";
                    var search = cn.Search("DC=stefanini,DC=dom", LdapConnection.SCOPE_SUB, filterInformacaoUsuario, null, false, (LdapSearchConstraints)null);

                    while (search.hasMore())
                    {
                        var nextEntry = search.next();
                        var user      = nextEntry.getAttributeSet();

                        listaEmails.Add(user.getAttribute("mail").StringValue);
                        break;
                    }
                }
            }

            return(string.Join(",", listaEmails));
        }
Exemplo n.º 28
0
    public static void Main(String[] args)
    {
        if (args.Length != 4)
        {
            Console.WriteLine("Usage:   mono ListGroups <host name> <login dn>"
                              + " <password> <group dn>\n");
            Console.WriteLine("Example: mono ListGroups Acme.com"
                              + " \"cn=admin,o=Acme\" secret "
                              + " cn=salesGroup,ou=sales,o=acme\n");
            Environment.Exit(0);
        }

        int         ldapPort    = LdapConnection.DEFAULT_PORT;
        int         searchScope = LdapConnection.SCOPE_BASE;
        int         ldapVersion = LdapConnection.Ldap_V3;
        int         i;
        IEnumerator objClass = null;
        IEnumerator queryURL = null;
        IEnumerator identity = null;
        IEnumerator excludedMember = null;
        IEnumerator member = null;
        bool        isGroup = false, isDynamicGroup = false;

        String[] attrs = new String[] { "objectClass",
                                        "memberQueryURL",
                                        "dgIdentity",
                                        "excludedMember",
                                        "member" };

        /* Since reading members of a dynamic group could potentially involve
         * a significant directory search, we use a timeout. Setting
         * time out to 10 seconds
         */
        LdapSearchConstraints cons = new LdapSearchConstraints();

        cons.TimeLimit = 10000;

        String ldapHost = args[0];
        String loginDN  = args[1];
        String password = args[2];
        String groupDN  = args[3];

        LdapConnection lc = new LdapConnection();

        try
        {
            // connect to the server
            lc.Connect(ldapHost, ldapPort);
            // bind to the server
            lc.Bind(ldapVersion, loginDN, password);

            Console.WriteLine("\n\tReading object :" + groupDN);
            LdapSearchResults searchResults =
                lc.Search(groupDN,             // object to read
                          searchScope,         // scope - read single object
                          null,                // search filter
                          attrs,               // return only required attributes
                          false,               // return attrs and values
                          cons);               // time out value

            // Examine the attributes that were returned and extract the data

            LdapEntry nextEntry = null;
            try
            {
                nextEntry = searchResults.next();
            }
            catch (LdapException e)
            {
                Console.WriteLine("Error: " + e.ToString());
                Environment.Exit(1);
            }

            LdapAttributeSet attributeSet  = nextEntry.getAttributeSet();
            IEnumerator      allAttributes = attributeSet.GetEnumerator();

            while (allAttributes.MoveNext())
            {
                LdapAttribute attribute     = (LdapAttribute)allAttributes.Current;
                String        attributeName = attribute.Name;
                // Save objectclass values
                if (attributeName.ToUpper().Equals("objectClass".ToUpper()))
                {
                    objClass = attribute.StringValues;
                }

                // Save the memberQueryURL attribute if present
                else if (attributeName.ToUpper().Equals("memberQueryURL".ToUpper()))
                {
                    queryURL = attribute.StringValues;
                }

                // Save the dgIdentity attribute if present
                else if (attributeName.ToUpper().Equals("dgIdentity".ToUpper()))
                {
                    identity = attribute.StringValues;
                }

                // Save the excludedMember attribute if present
                else if (attributeName.ToUpper().Equals("excludedMember".ToUpper()))
                {
                    excludedMember = attribute.StringValues;
                }

                /* Save the member attribute.  This may also show up
                 * as uniqueMember
                 */
                else if (attributeName.ToUpper().Equals("member".ToUpper()) ||
                         attributeName.ToUpper().Equals("uniqueMember".ToUpper()))
                {
                    member = attribute.StringValues;
                }
            }

            /* Verify that this is a group object  (i.e. objectClass contains
             * the value "group", "groupOfNames", or "groupOfUniqueNames").
             * Also determine if this is a dynamic group object
             * (i.e. objectClass contains the value "dynamicGroup" or
             * "dynamicGroupAux").
             */
            while (objClass.MoveNext())
            {
                String objectName = (String)objClass.Current;
                if (objectName.ToUpper().Equals("group".ToUpper()) ||
                    objectName.ToUpper().Equals("groupOfNames".ToUpper()) ||
                    objectName.ToUpper().Equals("groupOfUniqueNames".ToUpper()))
                {
                    isGroup = true;
                }
                else if (objectName.ToUpper().Equals("dynamicGroup".ToUpper()) ||
                         objectName.ToUpper().Equals("dynamicGroupAux".ToUpper()))
                {
                    isGroup = isDynamicGroup = true;
                }
            }

            if (!isGroup)
            {
                Console.WriteLine("\tThis object is NOT a group object."
                                  + "Exiting.\n");
                Environment.Exit(0);
            }

            /* If this is a dynamic group, display its memberQueryURL, identity
             * and excluded member list.
             */
            if (isDynamicGroup)
            {
                if ((queryURL != null) && (queryURL.MoveNext()))
                {
                    Console.WriteLine("\tMember Query URL:");
                    while (queryURL.MoveNext())
                    {
                        Console.WriteLine("\t\t" + queryURL.Current);
                    }
                }

                if ((identity != null) && (identity.MoveNext()))
                {
                    Console.WriteLine("\tIdentity for search:"
                                      + identity.Current);
                }

                if ((excludedMember != null) &&
                    (excludedMember.MoveNext()))
                {
                    Console.WriteLine("\tExcluded member list:");
                    while (excludedMember.MoveNext())
                    {
                        Console.WriteLine("\t\t"
                                          + excludedMember.Current);
                    }
                }
            }

            // Print the goup's member list
            if (member != null && member.MoveNext())
            {
                Console.WriteLine("\n\tMember list:");
                while (member.MoveNext())
                {
                    Console.WriteLine("\t\t" + member.Current);
                }
            }

            // disconnect with the server
            lc.Disconnect();
        }
        catch (LdapException e)
        {
            Console.WriteLine("Error: " + e.ToString());
            Environment.Exit(1);
        }
        catch (Exception e)
        {
            Console.WriteLine("Error: " + e.ToString());
        }
        Environment.Exit(0);
    }
Exemplo n.º 29
0
        public ApiErrorItem PerformPasswordChange(string username,
                                                  string currentPassword, string newPassword)
        {
            var cleanUsername = username;

            var atindex = cleanUsername.IndexOf("@");

            if (atindex >= 0)
            {
                cleanUsername = cleanUsername.Substring(0, atindex);
            }

            // Must sanitize the username to eliminate the possibility of injection attacks:
            //    * https://docs.microsoft.com/en-us/windows/desktop/adschema/a-samaccountname
            //    * https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-2000-server/bb726984(v=technet.10)
            var samInvalid   = "\"/\\[]:;|=,+*?<>";
            var miscInvalid  = "\r\n\t";
            var invalid      = (samInvalid + miscInvalid).ToCharArray();
            var invalidIndex = cleanUsername.IndexOfAny(invalid);

            if (invalidIndex >= 0)
            {
                var msg = "username contains one or more invalid characters";
                _logger.LogWarning(msg);
                return(new ApiErrorItem
                {
                    ErrorCode = ApiErrorCode.InvalidCredentials,
                    FieldName = nameof(username),
                    Message = msg,
                });
            }

            // LDAP filters require escaping of some special chars:
            //    * http://www.ldapexplorer.com/en/manual/109010000-ldap-filter-syntax.htm
            var escape      = "()&|=><!*/\\".ToCharArray();
            var escapeIndex = cleanUsername.IndexOfAny(escape);

            if (escapeIndex >= 0)
            {
                var buff     = new StringBuilder();
                var maxLen   = cleanUsername.Length;
                var copyFrom = 0;
                while (escapeIndex >= 0)
                {
                    buff.Append(cleanUsername.Substring(copyFrom, escapeIndex));
                    buff.Append(string.Format("\\{0:X}", (int)cleanUsername[escapeIndex]));
                    copyFrom    = escapeIndex + 1;
                    escapeIndex = cleanUsername.IndexOfAny(escape, copyFrom);
                }
                if (copyFrom < maxLen)
                {
                    buff.Append(cleanUsername.Substring(copyFrom));
                }
                cleanUsername = buff.ToString();
                _logger.LogWarning("had to clean username: [{0}] => [{1}]", username, cleanUsername);
            }

            // Based on:
            //    * https://www.cs.bham.ac.uk/~smp/resources/ad-passwds/
            //    * https://support.microsoft.com/en-us/help/269190/how-to-change-a-windows-active-directory-and-lds-user-password-through
            //    * https://ltb-project.org/documentation/self-service-password/latest/config_ldap#active_directory
            //    * https://technet.microsoft.com/en-us/library/ff848710.aspx?f=255&MSPPError=-2147217396

            using (var ldap = BindToLdap())
            {
                // First find user DN by username (SAM Account Name)
                var searchConstraints = new LdapSearchConstraints(
                    0, 0, LdapSearchConstraints.DEREF_NEVER,
                    1000, true, 1, null, 10);

                var searchFilter = $"(sAMAccountName={cleanUsername})";
                var search       = ldap.Search(
                    _options.LdapSearchBase, LdapConnection.SCOPE_SUB,
                    searchFilter, new[] { "distinguishedName" },
                    false, searchConstraints);

                // We cannot use search.Count here -- apparently it does not
                // wait for the results to return before resolving the count
                // but fortunately hasMore seems to block until final result
                if (!search.hasMore())
                {
                    _logger.LogWarning("unable to find username: [{0}]", cleanUsername);
                    if (_options.HideUserNotFound)
                    {
                        return(new ApiErrorItem
                        {
                            ErrorCode = ApiErrorCode.InvalidCredentials,
                            FieldName = nameof(currentPassword),
                            Message = "invalid credentials",
                        });
                    }
                    else
                    {
                        return(new ApiErrorItem
                        {
                            ErrorCode = ApiErrorCode.UserNotFound,
                            FieldName = nameof(username),
                            Message = "username could not be located",
                        });
                    }
                }

                if (search.Count > 1)
                {
                    _logger.LogWarning("found multiple with same username: [{0}]", cleanUsername);
                    // Hopefully this should not ever happen if AD is preserving SAM Account Name
                    // uniqueness constraint, but just in case, handling this corner case
                    return(new ApiErrorItem
                    {
                        ErrorCode = ApiErrorCode.UserNotFound,
                        FieldName = nameof(username),
                        Message = "multiple matching user entries resolved",
                    });
                }

                var userDN = search.next().DN;

                var oldPassBytes = Encoding.Unicode.GetBytes($@"""{currentPassword}""")
                                   .Select(x => (sbyte)x).ToArray();
                var newPassBytes = Encoding.Unicode.GetBytes($@"""{newPassword}""")
                                   .Select(x => (sbyte)x).ToArray();

                var oldAttr = new LdapAttribute("unicodePwd", oldPassBytes);
                var newAttr = new LdapAttribute("unicodePwd", newPassBytes);

                var ldapDel = new LdapModification(LdapModification.DELETE, oldAttr);
                var ldapAdd = new LdapModification(LdapModification.ADD, newAttr);

                try
                {
                    ldap.Modify(userDN, new[] { ldapDel, ldapAdd });
                }
                catch (LdapException ex)
                {
                    _logger.LogWarning("failed to update password", ex);
                    return(ParseLdapException(ex));
                }

                ldap.StopTls();
                ldap.Disconnect();
            }

            // Everything seems to have worked:
            return(null);
        }
Exemplo n.º 30
0
        /// <summary>
        /// Retrieves group information from ldap
        /// </summary>
        /// <param name="retrieveGroupMembers">true to return users in each group. This may hurt performance</param>
        /// <param name="optionalGroupName">Group to lookup by name. Null for all groups</param>
        /// <returns></returns>
        public XDoc GetGroupInfo(bool retrieveGroupMembers, string optionalGroupName)
        {
            LdapConnection conn      = null;
            XDoc           resultXml = null;

            try {
                //Confirm a query bind has been established
                conn = Bind();

                string searchFilter;

                //Build the searchfilter based on if a group name is given.
                if (!string.IsNullOrEmpty(optionalGroupName))
                {
                    optionalGroupName = EscapeLdapString(optionalGroupName);

                    //Looking up group by name
                    searchFilter = string.Format(PhpUtil.ConvertToFormatString(_config.GroupQuery), optionalGroupName);
                }
                else
                {
                    //Looking up all groups
                    searchFilter = _config.GroupQueryAll;
                }

                //Build interesting attribute list
                List <string> attrs = new List <string>();
                attrs.AddRange(new string[] { "whenCreated", "name", "sAMAccountName", "cn" });
                if (retrieveGroupMembers)
                {
                    attrs.Add("member");
                }

                if (!string.IsNullOrEmpty(_config.GroupNameAttribute) && !attrs.Contains(_config.GroupNameAttribute))
                {
                    attrs.Add(_config.GroupNameAttribute);
                }

                LdapSearchConstraints cons = new LdapSearchConstraints(new LdapConstraints(_timeLimit, true, null, 0));
                cons.BatchSize = 0;

                LdapSearchResults results = conn.Search(_config.LdapSearchBase,
                                                        LdapConnection.SCOPE_SUB,
                                                        searchFilter,
                                                        attrs.ToArray(),
                                                        false,
                                                        cons);

                //Create outer groups collection if multiple groups are being looked up or none provided
                if (string.IsNullOrEmpty(optionalGroupName))
                {
                    resultXml = new XDoc("groups");
                }

                while (results.hasMore())
                {
                    LdapEntry nextEntry = null;
                    try {
                        nextEntry = results.next();
                    } catch (LdapException x) {
                        HandleLdapException(x);
                        continue;
                    }

                    //Create xml from search entry
                    if (resultXml == null)
                    {
                        resultXml = new XDoc("group");
                    }
                    else
                    {
                        resultXml.Start("group");
                    }

                    string name = string.Empty;

                    //If a groupnameattribute is configured, use that. Otherwise try the common ones.
                    if (!string.IsNullOrEmpty(_config.GroupNameAttribute))
                    {
                        name = GetAttributeSafe(nextEntry, _config.GroupNameAttribute);
                    }
                    else
                    {
                        name = GetAttributeSafe(nextEntry, "sAMAccountName"); //MS Active Directory
                        if (string.IsNullOrEmpty(name))
                        {
                            name = GetAttributeSafe(nextEntry, "uid"); //OpenLDAP
                        }
                        if (string.IsNullOrEmpty(name))
                        {
                            name = GetAttributeSafe(nextEntry, "name"); //OpenLDAP
                        }
                        if (string.IsNullOrEmpty(name))
                        {
                            name = GetAttributeSafe(nextEntry, "cn"); //Novell eDirectory
                        }
                    }

                    resultXml.Attr("name", name);
                    resultXml.Start("ldap-dn").Value(nextEntry.DN).End();
                    resultXml.Start("date.created").Value(ldapStringToDate(GetAttributeSafe(nextEntry, "whenCreated"))).End();

                    //Retrieve and write group membership to xml
                    LdapAttributeSet memberAttrSet = nextEntry.getAttributeSet();
                    LdapAttribute    memberAttr    = memberAttrSet.getAttribute("member");

                    // TODO MaxM: This currently does not differentiate between user and group
                    // members.

                    if (memberAttr != null)
                    {
                        foreach (string member in memberAttr.StringValueArray)
                        {
                            resultXml.Start("member");
                            resultXml.Attr("name", GetNameFromDn(member));
                            resultXml.Start("ldap-dn").Value(member).End();
                            resultXml.End();
                        }
                    }
                    if (string.IsNullOrEmpty(optionalGroupName))
                    {
                        resultXml.End();
                    }
                }
            } finally {
                UnBind(conn);
            }

            return(resultXml);
        }
Exemplo n.º 31
0
        public ApiErrorItem PerformPasswordChange(string username,
                                                  string currentPassword, string newPassword)
        {
            string cleanUsername = username;

            try
            {
                cleanUsername = CleaningUsername(username);
            }
            catch (ApiErrorException ex)
            {
                return(ex.ErrorItem);
            }
            catch (Exception ex)
            {
                return(new ApiErrorItem
                {
                    ErrorCode = ApiErrorCode.UserNotFound,
                    FieldName = nameof(username),
                    Message = "Some error in cleaning username: "******"{Username}"))
                {
                    searchFilter = searchFilter.Replace("{Username}", cleanUsername);
                }
            }
            catch (Exception ex)
            {
                string msg = "ldapSearchFilter could not be parsed. Be sure {Username} is included: " + ex.Message;
                _logger.LogCritical(msg);
                throw new ArgumentException(msg);
            }

            try
            {
                using (var ldap = BindToLdap())
                {
                    var search = ldap.Search(
                        _options.LdapSearchBase, LdapConnection.SCOPE_SUB,
                        searchFilter, new[] { "distinguishedName" },
                        false, searchConstraints);

                    // We cannot use search.Count here -- apparently it does not
                    // wait for the results to return before resolving the count
                    // but fortunately hasMore seems to block until final result
                    if (!search.hasMore())
                    {
                        _logger.LogWarning("unable to find username: [{0}]", cleanUsername);
                        if (_options.HideUserNotFound)
                        {
                            return(new ApiErrorItem
                            {
                                ErrorCode = ApiErrorCode.InvalidCredentials,
                                FieldName = nameof(username),
                                Message = "invalid credentials",
                            });
                        }
                        else
                        {
                            return(new ApiErrorItem
                            {
                                ErrorCode = ApiErrorCode.UserNotFound,
                                FieldName = nameof(username),
                                Message = "username could not be located",
                            });
                        }
                    }

                    if (search.Count > 1)
                    {
                        _logger.LogWarning("found multiple with same username: [{0}]", cleanUsername);
                        // Hopefully this should not ever happen if AD is preserving SAM Account Name
                        // uniqueness constraint, but just in case, handling this corner case
                        return(new ApiErrorItem
                        {
                            ErrorCode = ApiErrorCode.UserNotFound,
                            FieldName = nameof(username),
                            Message = "multiple matching user entries resolved",
                        });
                    }

                    var userDN = search.next().DN;

                    try
                    {
                        if (_options.LdapChangePasswortWithDelAdd)
                        {
                            #region Change Password by Delete/Add
                            var oldPassBytes = Encoding.Unicode.GetBytes($@"""{currentPassword}""")
                                               .Select(x => (sbyte)x).ToArray();
                            var newPassBytes = Encoding.Unicode.GetBytes($@"""{newPassword}""")
                                               .Select(x => (sbyte)x).ToArray();

                            var oldAttr = new LdapAttribute("unicodePwd", oldPassBytes);
                            var newAttr = new LdapAttribute("unicodePwd", newPassBytes);

                            var ldapDel = new LdapModification(LdapModification.DELETE, oldAttr);
                            var ldapAdd = new LdapModification(LdapModification.ADD, newAttr);
                            ldap.Modify(userDN, new[] { ldapDel, ldapAdd }); // Change with Delete/Add
                            #endregion
                        }
                        else
                        {
                            #region Change Password by Replace
                            // If you don't have the rights to Add and/or Delete the Attribute, you might have the right to change the password-attribute.
                            // In this case uncomment the next 2 lines and comment the region 'Change Password by Delete/Add'
                            var replAttr    = new LdapAttribute("userPassword", newPassword);
                            var ldapReplace = new LdapModification(LdapModification.REPLACE, replAttr);
                            ldap.Modify(userDN, new[] { ldapReplace }); // Change with Replace
                            #endregion
                        }
                    }
                    catch (LdapException ex)
                    {
                        _logger.LogWarning("failed to update password", ex);
                        return(ParseLdapException(ex));
                    }

                    if (this._options.LdapStartTls)
                    {
                        ldap.StopTls();
                    }

                    ldap.Disconnect();
                }
            }
            catch (ApiErrorException ex)
            {
                return(ex.ErrorItem);
            }
            catch (Exception ex)
            {
                return(new ApiErrorItem
                {
                    ErrorCode = ApiErrorCode.InvalidCredentials,
                    FieldName = nameof(username),
                    Message = "failed to update password: " + ex.Message,
                });
            }

            // Everything seems to have worked:
            return(null);
        }