Example #1
0
 public void Modify_DNNull()
 {
     Assert.ThrowsAsync <ArgumentNullException>(async() =>
     {
         var mods = new LdapModification(LdapModificationOp.Replace, new LdapAttribute("ui"));
         await Connection.Modify(null, new[] { mods });
     });
 }
        void UpdatePassword()
        {
            string ldapPwd = LDAPUtils.EncodeSSHA(passData.NewPassword);
            var    pwdMod  = new LdapModification(LdapModification.Replace,
                                                  new LdapAttribute("userPassword", ldapPwd));

            Startup.ldap.Connection.Modify(User.FindFirstValue(ClaimTypes.NameIdentifier),
                                           pwdMod);
        }
Example #3
0
        private static void ChangePasswordReplace(string newPassword, ILdapConnection ldap, string userDN)
        {
            // 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 attribute   = new LdapAttribute("userPassword", newPassword);
            var ldapReplace = new LdapModification(LdapModification.REPLACE, attribute);

            ldap.Modify(userDN, new[] { ldapReplace }); // Change with Replace
        }
Example #4
0
 private SignInResult ChangePassword(string uid, string newPassword)
 {
     using (var ldap = CreateLdap())
     {
         LdapAttribute    attr = new LdapAttribute("userPassword", ToMd5(newPassword));
         LdapModification mod  = new LdapModification(LdapModification.REPLACE, attr);
         ldap.Modify(string.Format("uid={0},{1}", uid, settings.Options.LdapPeopleOU), mod);
     }
     return(SignInResult.Success);
 }
Example #5
0
 private SignInResult ChangeMail(string uid, string newEmail)
 {
     using (var ldap = CreateLdap())
     {
         LdapAttribute    attr = new LdapAttribute("mail", newEmail);
         LdapModification mod  = new LdapModification(LdapModification.REPLACE, attr);
         ldap.Modify(string.Format("uid={0},{1}", uid, settings.Options.LdapPeopleOU), mod);
     }
     return(SignInResult.Success);
 }
Example #6
0
        /// <summary>
        /// change the password
        /// </summary>
        /// <param name="dn">sn for which change is to be done</param>
        /// <param name="password">password</param>
        /// <returns>true if changed successfully</returns>
        public bool ChangePassword(string dn, string password)
        {
            // TODO: Modify this to support Active Directory.

            LdapAttribute attribute = new LdapAttribute("userPassword", password);

            LdapModification modification = new LdapModification(LdapModification.REPLACE, attribute);

            connection.Modify(dn, modification);
            return(true);
        }
    public static bool _AddUserToGroup(LdapConnection conn, System.String userdn, System.String groupdn)
    {
        // modifications for group and user
        LdapModification[] modGroup = new LdapModification[2];
        LdapModification[] modUser  = new LdapModification[2];

        // Add modifications to modUser
        LdapAttribute membership = new LdapAttribute("groupMembership", groupdn);

        modUser[0] = new LdapModification(LdapModification.ADD, membership);
        LdapAttribute security = new LdapAttribute("securityEquals", groupdn);

        modUser[1] = new LdapModification(LdapModification.ADD, security);

        // Add modifications to modGroup
        LdapAttribute member = new LdapAttribute("uniqueMember", userdn);

        modGroup[0] = new LdapModification(LdapModification.ADD, member);
        LdapAttribute equivalent = new LdapAttribute("equivalentToMe", userdn);

        modGroup[1] = new LdapModification(LdapModification.ADD, equivalent);

        try
        {
            // Modify the user's attributes
            conn.Modify(userdn, modUser);
            System.Console.Out.WriteLine("Modified the user's attribute.");
        }
        catch (LdapException e)
        {
            System.Console.Out.WriteLine("Failed to modify user's attributes: " + e.LdapErrorMessage);
            return(false);
        }

        try
        {
            // Modify the group's attributes
            conn.Modify(groupdn, modGroup);
            System.Console.Out.WriteLine("Modified the group's attribute.");
        }
        catch (LdapException e)
        {
            System.Console.Out.WriteLine("Failed to modify group's attributes: " + e.LdapErrorMessage);
            doCleanup(conn, userdn, groupdn);
            return(false);
        }
        catch (Exception e)
        {
            Console.WriteLine("Error:" + e.Message);
            return(false);
        }
        return(true);
    }
        private static void ChangePasswordDelAdd(string currentPassword, string newPassword, ILdapConnection ldap, string userDN)
        {
            var oldPassBytes = Encoding.Unicode.GetBytes($@"""{currentPassword}""");
            var newPassBytes = Encoding.Unicode.GetBytes($@"""{newPassword}""");

            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
        }
Example #9
0
        public async Task Modify_OfNotExistingEntry_ShouldThrowNoSuchObject()
        {
            var ldapEntry = LdapEntryHelper.NewLdapEntry();

            var ldapException = await Assert.ThrowsAsync <LdapException>(
                () => TestHelper.WithAuthenticatedLdapConnectionAsync(async ldapConnection =>
            {
                var newAttribute = new LdapAttribute("givenName", "blah");
                var modification = new LdapModification(LdapModification.Replace, newAttribute);
                await ldapConnection.ModifyAsync(ldapEntry.Dn, modification);
            }));

            Assert.Equal(LdapException.NoSuchObject, ldapException.ResultCode);
        }
        public void Modify_OfNotExistingEntry_ShouldThrowNoSuchObject()
        {
            var ldapEntry = LdapEntryHelper.NewLdapEntry();

            var ldapException = Assert.Throws <LdapException>(
                () => TestHelper.WithAuthenticatedLdapConnection(ldapConnection =>
            {
                var newAttribute = new LdapAttribute("givenName", "blah");
                var modification = new LdapModification(LdapModification.REPLACE, newAttribute);
                ldapConnection.Modify(ldapEntry.DN, modification);
            })
                );

            Assert.Equal(LdapException.NO_SUCH_OBJECT, ldapException.ResultCode);
        }
Example #11
0
        static void MainTest(string[] args)
        {
            if (args.Length != 5)
            {
                Console.WriteLine("Usage:   mono ModifyEntry <host name> <ldap port>  <login dn>" + " <password> <Modify dn>");
                Console.WriteLine("Example: mono ModifyEntry Acme.com 389" + " \"cn=admin,o=Acme\"" + " secret \"cn=ksmith,o=Acme\"");
                return;
            }

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

            try
            {
                Console.WriteLine("Connecting to:" + ldapHost);
                LdapConnection conn    = new LdapConnection();
                ArrayList      modList = new ArrayList();
                String         desc    = "This object belongs to test user";
                // Add a new value to the description attribute
                LdapAttribute attribute = new LdapAttribute("description", desc);
                modList.Add(new LdapModification(LdapModification.ADD, attribute));

                String email = "*****@*****.**";
                attribute = new LdapAttribute("mail", email);
                modList.Add(new LdapModification(LdapModification.REPLACE, attribute));
                LdapModification[] mods = new LdapModification[modList.Count];
                mods = (LdapModification[])modList.ToArray(typeof(LdapModification));

                conn.Connect(ldapHost, ldapPort);
                conn.Bind(loginDN, password);
                conn.Modify(dn, mods);
                Console.WriteLine(" Entry: " + dn + "Modified Successfully");
                conn.Disconnect();
            }
            catch (LdapException e)
            {
                Console.WriteLine("Error:" + e.LdapErrorMessage);
                return;
            }
            catch (Exception e)
            {
                Console.WriteLine("Error:" + e.Message);
                return;
            }
        }
        public void AddNewAttribute_ToExistingEntry_ShouldWork()
        {
            var          existingEntry = LdapOps.AddEntry();
            var          value         = Guid.NewGuid().ToString();
            const string attrName      = "description";

            TestHelper.WithAuthenticatedLdapConnection(ldapConnection =>
            {
                var newAttribute = new LdapAttribute(attrName, value);
                var modification = new LdapModification(LdapModification.ADD, newAttribute);
                ldapConnection.Modify(existingEntry.DN, modification);
            });

            var modifiedEntry = LdapOps.GetEntry(existingEntry.DN);

            Assert.Equal(value, modifiedEntry.getAttribute(attrName).StringValue);
        }
        public void ModifyAttributeValue_OfExistingEntry_ShouldWork()
        {
            var          existingEntry = LdapOps.AddEntry();
            var          value         = Guid.NewGuid().ToString();
            const string attrName      = "givenName";

            TestHelper.WithAuthenticatedLdapConnection(ldapConnection =>
            {
                var modifiedAttribute = new LdapAttribute(attrName, value);
                var modification      = new LdapModification(LdapModification.Replace, modifiedAttribute);
                ldapConnection.Modify(existingEntry.Dn, modification);
            });

            var modifiedEntry = LdapOps.GetEntry(existingEntry.Dn);

            Assert.Equal(value, modifiedEntry.GetAttribute(attrName).StringValue);
        }
Example #14
0
        public void OnOkClicked(object o, EventArgs args)
        {
            Connection conn = GetCurrentConnection();

            LdapEntry[] sr = conn.Data.Search(conn.DirectoryRoot, searchEntry.Text);

            foreach (object[] row in modListStore)
            {
                string _action = (string)row[0];
                string _name   = (string)row[1];
                string _value  = (string)row[2];

                LdapAttribute    a = new LdapAttribute(_name, _value);
                LdapModification m = null;

                switch (_action.ToLower())
                {
                case "add":
                    m = new LdapModification(LdapModification.ADD, a);
                    break;

                case "delete":
                    m = new LdapModification(LdapModification.DELETE, a);
                    break;

                case "replace":
                    m = new LdapModification(LdapModification.REPLACE, a);
                    break;

                default:
                    break;
                }

                if (m != null)
                {
                    _modList.Add(m);
                }
            }

            foreach (LdapEntry e in sr)
            {
                Util.ModifyEntry(conn, e.DN, _modList.ToArray());
            }

            massEditDialog.HideAll();
        }
        public void ModifyPassword_OfExistingEntry_ShouldWork()
        {
            var existingEntry = LdapOps.AddEntry();
            var newPassword   = "******" + new Random().Next();

            TestHelper.WithAuthenticatedLdapConnection(ldapConnection =>
            {
                var newAttribute = new LdapAttribute("userPassword", newPassword);
                var modification = new LdapModification(LdapModification.Replace, newAttribute);
                ldapConnection.Modify(existingEntry.Dn, modification);
            });

            TestHelper.WithLdapConnection(
                ldapConnection =>
            {
                ldapConnection.Bind(existingEntry.Dn, newPassword);
            });
        }
Example #16
0
        public async Task AddNewAttribute_ToExistingEntry_ShouldWork()
        {
            var existingEntry = await LdapOps.AddEntryAsync();

            var          value    = Guid.NewGuid().ToString();
            const string attrName = "description";

            await TestHelper.WithAuthenticatedLdapConnectionAsync(async ldapConnection =>
            {
                var newAttribute = new LdapAttribute(attrName, value);
                var modification = new LdapModification(LdapModification.Add, newAttribute);
                await ldapConnection.ModifyAsync(existingEntry.Dn, modification);
            });

            var modifiedEntry = await LdapOps.GetEntryAsync(existingEntry.Dn);

            Assert.Equal(value, modifiedEntry.GetAttribute(attrName).StringValue);
        }
Example #17
0
        void updateGroupMembership()
        {
            LdapEntry groupEntry = null;

            LdapModification[] mods = new LdapModification [1];

            foreach (string key in _memberOfGroups.Keys)
            {
                LdapAttribute    attr = new LdapAttribute("memberUid", usernameEntry.Text);
                LdapModification lm   = new LdapModification(LdapModification.ADD, attr);

                groupEntry = (LdapEntry)_allGroups[key];

                mods[0] = lm;
            }

            modifyGroup(groupEntry, mods);
        }
        static void MainTest(string[] args)
        {
            if (args.Length != 5)
            {
                Console.WriteLine("Usage:   mono ModifyPass <host name> <ldap port>  <login dn>" + " <old password> <new password>");
                Console.WriteLine("Example: mono ModifyPass Acme.com 389" + " \"cn=tjhon,o=Acme\"" + " secret \"newpass\"");
                return;
            }

            string ldapHost  = args[0];
            int    ldapPort  = System.Convert.ToInt32(args[1]);
            String loginDN   = args[2];
            String opassword = args[3];
            String npassword = args[4];

            try
            {
                LdapConnection conn = new LdapConnection();
                Console.WriteLine("Connecting to:" + ldapHost);
                conn.Connect(ldapHost, ldapPort);
                conn.Bind(loginDN, opassword);
                LdapModification[] modifications  = new LdapModification[2];
                LdapAttribute      deletePassword = new LdapAttribute("userPassword", opassword);
                modifications[0] = new LdapModification(LdapModification.DELETE, deletePassword);
                LdapAttribute addPassword = new LdapAttribute("userPassword", npassword);
                modifications[1] = new LdapModification(LdapModification.ADD, addPassword);

                conn.Modify(loginDN, modifications);

                System.Console.Out.WriteLine("Your password has been modified.");

                conn.Disconnect();
            }
            catch (LdapException e)
            {
                Console.WriteLine("Error:" + e.LdapErrorMessage);
                return;
            }
            catch (Exception e)
            {
                Console.WriteLine("Error:" + e.Message);
                return;
            }
        }
        public async Task ModifyPassword_OfExistingEntry_ShouldWork()
        {
            var existingEntry = await LdapOps.AddEntryAsync();

            var newPassword = "******" + new Random().Next();

            await TestHelper.WithAuthenticatedLdapConnectionAsync(async ldapConnection =>
            {
                var newAttribute = new LdapAttribute("userPassword", newPassword);
                var modification = new LdapModification(LdapModification.Replace, newAttribute);
                await ldapConnection.ModifyAsync(existingEntry.Dn, modification);
            });

            await TestHelper.WithLdapConnectionAsync(
                async ldapConnection =>
            {
                await ldapConnection.BindAsync(existingEntry.Dn, newPassword);
            });
        }
Example #20
0
        private void SetAttribute(LdapEntry userEntry, string attr, string attrValue)
        {
            using (var ldapClient = new LdapConnection {
                SecureSocketLayer = _config.UseSsl
            })
            {
                try
                {
                    if (_config.SkipSslVerify)
                    {
                        ldapClient.UserDefinedServerCertValidationDelegate +=
                            LdapClient_UserDefinedServerCertValidationDelegate;
                    }

                    ldapClient.Connect(_config.LdapServer, _config.LdapPort);
                    if (_config.UseStartTls)
                    {
                        ldapClient.StartTls();
                    }

                    ldapClient.Bind(_config.LdapBindUser, _config.LdapBindPassword);
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "Failed to Connect or Bind to server");
                    throw new AuthenticationException("Failed to Connect or Bind to server");
                }
                finally
                {
                    ldapClient.UserDefinedServerCertValidationDelegate -=
                        LdapClient_UserDefinedServerCertValidationDelegate;
                }

                var existingAttr = GetAttribute(userEntry, attr);
                var ldapModType  = existingAttr == null ? LdapModification.Add : LdapModification.Replace;
                var modification = new LdapModification(
                    ldapModType,
                    new LdapAttribute(attr, attrValue ?? string.Empty)
                    );
                ldapClient.Modify(userEntry.Dn, modification);
            }
        }
Example #21
0
        /// <summary>
        /// Add a new LDAP user
        /// </summary>
        /// <param name="entry">OpenLdapUserEntry object</param>
        /// <returns>True(Success)/False(Fail)</returns>
        public async Task <bool> UpdateAsync(OpenLdapUserEntry entry)
        {
            Func <LdapConnection, bool> action = (ldapConn) =>
            {
                var existEntry = this.FindAsync(entry.Uid).Result;
                if (existEntry != null)
                {
                    var modifiedAttributes = new ArrayList();

                    // Iterate all properties and add to modifiedAttributes
                    PropertyInfo[] props = typeof(OpenLdapUserEntry).GetProperties();
                    foreach (PropertyInfo prop in props)
                    {
                        var ldapAttr = Attribute.GetCustomAttributes(prop).FirstOrDefault(a => a.GetType().Equals(typeof(LdapAttrAttribute))) as LdapAttrAttribute;

                        if (ldapAttr != null)
                        {
                            var name  = ldapAttr.Name;
                            var value = prop.GetValue(entry, null)?.ToString();

                            if (!string.IsNullOrEmpty(value))
                            {
                                modifiedAttributes.Add(new LdapModification(LdapModification.REPLACE, new LdapAttribute(name, value)));
                            }
                        }
                    }

                    var ldapModification = new LdapModification[modifiedAttributes.Count];
                    ldapModification = (LdapModification[])modifiedAttributes.ToArray(typeof(LdapModification));

                    ldapConn.Modify(existEntry.DN, ldapModification);
                    return(true);
                }
                else
                {
                    return(false);
                }
            };

            return(await this.ldapActionAsync(action));
        }
Example #22
0
 /// <summary>
 /// Grant Read Rights to the LDAP User on the the LDAP Container
 /// </summary>
 /// <param name="userDN">The LDAP User DN</param>
 /// <param name="containerDN">The LDAP Container DN</param>
 public void GrantReadRights(string userDN, string containerDN)
 {
     if (DirectoryType.Equals(LdapDirectoryType.ActiveDirectory))
     {
         // TODO: Modify this to support Active Directory
     }
     else if (DirectoryType.Equals(LdapDirectoryType.OpenLDAP))
     {
         // TODO: Modify this to support OpenLDAP.
     }
     else if (DirectoryType.Equals(LdapDirectoryType.eDirectory))
     {
         LdapAttribute attribute = new LdapAttribute("acl", new String[]
         {
             String.Format("1#subtree#{0}#[Entry Rights]", userDN),
             String.Format("3#subtree#{0}#[All Attributes Rights]", userDN)
         });
         LdapModification modification = new LdapModification(LdapModification.ADD, attribute);
         connection.Modify(containerDN, modification);
     }
 }
Example #23
0
        public bool ChangePassword(string dn, string password)
        {
            LdapDirectoryType LdapType = QueryDirectoryType();

            switch (LdapType)
            {
            case LdapDirectoryType.ActiveDirectory:
            {
                string   quotedPassword  = "******"" + password + "\"";
                char []  unicodePassword = quotedPassword.ToCharArray();
                sbyte [] passwordArray   = new sbyte[unicodePassword.Length * 2];

                for (int i = 0; i < unicodePassword.Length; i++)
                {
                    passwordArray[i * 2 + 1] = (sbyte)(unicodePassword[i] >> 8);
                    passwordArray[i * 2 + 0] = (sbyte)(unicodePassword[i] & 0xff);
                }

                LdapAttribute    attribute    = new LdapAttribute("UnicodePwd", passwordArray);
                LdapModification modification = new LdapModification(LdapModification.REPLACE, attribute);
                connection.Modify(dn, modification);

                return(true);
            }

            case LdapDirectoryType.OpenLDAP:
            case LdapDirectoryType.eDirectory:
deafult:
                {
                    LdapAttribute attribute = new LdapAttribute("userPassword", password);

                    LdapModification modification = new LdapModification(LdapModification.REPLACE, attribute);

                    connection.Modify(dn, modification);
                    return(true);
                }
                //return false;
            }
            return(false);
        }
Example #24
0
        /// <summary>
        /// Changes the users password (Requires privileged bind user).
        /// </summary>
        /// <param name="user">The user who's password will be changed.</param>
        /// <param name="newPassword">The new password to set.</param>
        /// <returns>Completed Task notification.</returns>
        /// <exception cref="NotImplementedException">Thrown if AllowPassChange set to false.</exception>
        /// <exception cref="InvalidOperationException">Thrown if LdapPasswordAttribute field is null or empty.</exception>
        public Task ChangePassword(User user, string newPassword)
        {
            if (!LdapPlugin.Instance.Configuration.AllowPassChange)
            {
                throw new NotImplementedException();
            }

            if (string.IsNullOrEmpty(LdapPlugin.Instance.Configuration.LdapPasswordAttribute))
            {
                throw new InvalidOperationException("Password attribute is not set");
            }

            var passAttr = LdapPlugin.Instance.Configuration.LdapPasswordAttribute;
            var ldapUser = LocateLdapUser(user.Username);

            using var ldapClient = ConnectToLdap();
            var ldapAttr = new LdapAttribute(passAttr, newPassword);
            var ldapMod  = new LdapModification(LdapModification.Replace, ldapAttr);

            ldapClient.Modify(ldapUser.Dn, ldapMod);
            return(Task.CompletedTask);
        }
Example #25
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="groupDN"></param>
        /// <returns></returns>
        public static bool RemoveUserFromGroup(string loginName, string groupDN)
        {
            LdapEntry entry = GetUser(loginName);

            if (entry == null)
            {
                throw new Exception($"名为:{loginName} 的用户在AD中不存在");
            }

            List <string> memberOf = entry.AttrStringValueArray("memberOf");

            if (!memberOf.Contains(groupDN))
            {
                throw new Exception($"名为:{loginName} 的用户不存在于组: {groupDN} 中");
            }

            LdapModification[] modGroup = new LdapModification[1];
            LdapAttribute      member   = new LdapAttribute("member", entry.DN);

            modGroup[0] = new LdapModification(LdapModification.DELETE, member);

            try
            {
                _connection.Modify(groupDN, modGroup);
            }
            catch (LdapException e)
            {
                System.Console.Error.WriteLine("Failed to delete group's attributes: " + e.LdapErrorMessage);
                return(false);
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("RemoveUserFromGroup Error:" + e.Message);
                return(false);
            }
            return(true);
        }
Example #26
0
        void ChangePassword(LdapEntry entry, PasswordDialog pd)
        {
            List <LdapModification> mods = new List <LdapModification> ();

            LdapAttribute    la;
            LdapModification lm;

            la = new LdapAttribute("userPassword", pd.UnixPassword);
            lm = new LdapModification(LdapModification.REPLACE, la);
            mods.Add(lm);

            if (Util.CheckSamba(entry))
            {
                la = new LdapAttribute("sambaLMPassword", pd.LMPassword);
                lm = new LdapModification(LdapModification.REPLACE, la);
                mods.Add(lm);

                la = new LdapAttribute("sambaNTPassword", pd.NTPassword);
                lm = new LdapModification(LdapModification.REPLACE, la);
                mods.Add(lm);
            }

            Util.ModifyEntry(conn, entry.DN, mods.ToArray());
        }
    public static void  doCleanup(LdapConnection conn, System.String userdn, System.String groupdn)
    {
        // since we have modified the user's attributes and failed to
        // modify the group's attribute, we need to delete the modified
        // user's attribute values.

        // modifications for user
        LdapModification[] modUser = new LdapModification[2];

        // Delete the groupdn from the user's attributes
        LdapAttribute membership = new LdapAttribute("groupMembership", groupdn);

        modUser[0] = new LdapModification(LdapModification.DELETE, membership);
        LdapAttribute security = new LdapAttribute("securityEquals", groupdn);

        modUser[1] = new LdapModification(LdapModification.DELETE, security);

        try
        {
            // Modify the user's attributes
            conn.Modify(userdn, modUser);

            System.Console.Out.WriteLine("Deleted the modified user's attribute values.");
        }
        catch (LdapException e)
        {
            System.Console.Out.WriteLine("Could not delete modified user's attributes: " + e.LdapErrorMessage);
        }
        catch (Exception e)
        {
            Console.WriteLine("Error:" + e.Message);
            return;
        }

        return;
    }
        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);
        }
        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);
        }
Example #30
0
        void OnApplyClicked(object o, EventArgs args)
        {
            List <LdapModification> modList       = new List <LdapModification> ();
            NameValueCollection     newAttributes = new NameValueCollection();

            foreach (object[] row in this.store)
            {
                string newValue = row[1].ToString();

                if (newValue == "" || newValue == null)
                {
                    continue;
                }

                newAttributes.Add(row[0].ToString(), newValue);
            }

            foreach (string key in newAttributes.AllKeys)
            {
                string[]      newValues = newAttributes.GetValues(key);
                string[]      oldValues = currentAttributes.GetValues(key);
                LdapAttribute la        = new LdapAttribute(key, newValues);

                if (oldValues == null)
                {
                    LdapModification lm = new LdapModification(LdapModification.ADD, la);
                    modList.Add(lm);
                }
                else
                {
                    foreach (string nv in newValues)
                    {
                        bool foundMatch = false;
                        foreach (string ov in oldValues)
                        {
                            if (ov == nv)
                            {
                                foundMatch = true;
                            }
                        }

                        if (!foundMatch)
                        {
                            LdapModification lm = new LdapModification(LdapModification.REPLACE, la);
                            modList.Add(lm);
                        }
                    }
                }
            }

            foreach (string key in currentAttributes.AllKeys)
            {
                string[] newValues = newAttributes.GetValues(key);

                if (newValues == null)
                {
                    string[]         oldValues = currentAttributes.GetValues(key);
                    LdapAttribute    la        = new LdapAttribute(key, oldValues);
                    LdapModification lm        = new LdapModification(LdapModification.DELETE, la);
                    modList.Add(lm);
                }
                else
                {
                    LdapAttribute    la = new LdapAttribute(key, newValues);
                    LdapModification lm = new LdapModification(LdapModification.REPLACE, la);
                    modList.Add(lm);
                }
            }

            Util.ModifyEntry(conn, currentDN, modList.ToArray());
        }