public boolean executePasswordModifyOperation(final String currentDn,
                                                  final char[] oldPassword,
                                                  final char[] newPassword,
                                                  final AbstractLdapProperties.LdapType type) {
        try {
            val oldPasswordAvailable = oldPassword != null && oldPassword.length > 0;
            val connConfig = connectionFactory.getConnectionConfig();
            val secureLdap = connConfig.getLdapUrl() != null && !connConfig.getLdapUrl().toLowerCase(Locale.ENGLISH).contains("ldaps://");
            if (connConfig.getUseStartTLS() || secureLdap) {
                LOGGER.warn("Executing password modification op under a non-secure LDAP connection; "
                            + "To modify password attributes, the connection to the LDAP server {} be secured and/or encrypted.",
                    type == AbstractLdapProperties.LdapType.AD ? "MUST" : "SHOULD");
            }
            if (type == AbstractLdapProperties.LdapType.AD) {
                LOGGER.debug("Executing password change op for active directory based on "
                             + "[https://support.microsoft.com/en-us/kb/269190]"
                             + "change type: [{}]", oldPasswordAvailable ? "change" : "reset");
                val operation = new ModifyOperation(connectionFactory);
                val response = oldPasswordAvailable
                    ?
                    operation.execute(new ModifyRequest(currentDn,
                        new AttributeModification(AttributeModification.Type.DELETE, new UnicodePwdAttribute(new String(oldPassword))),
                        new AttributeModification(AttributeModification.Type.ADD, new UnicodePwdAttribute(new String(newPassword)))))
                    :
                    operation.execute(new ModifyRequest(currentDn,
                        new AttributeModification(AttributeModification.Type.REPLACE, new UnicodePwdAttribute(new String(newPassword)))));

                val success = response.getResultCode() == ResultCode.SUCCESS;
                val logLevel = success ? LOGGER.atDebug() : LOGGER.atError();
                logLevel.log("Result code [{}], message: [{}]", response.getResultCode(), response.getDiagnosticMessage());
                return success;
            }

            LOGGER.debug("Executing password modification op for generic LDAP");
            val operation = new ExtendedOperation(connectionFactory);
            val response = operation.execute(new PasswordModifyRequest(currentDn,
                oldPasswordAvailable ? new String(oldPassword) : null, new String(newPassword)));
            LOGGER.debug("Result code [{}], message: [{}]", response.getResultCode(), response.getDiagnosticMessage());
            return response.getResultCode() == ResultCode.SUCCESS;
        } catch (final Exception e) {
            LoggingUtils.error(LOGGER, e);
        }
        return false;
    }
Execute a password modify operation.

@param currentDn   the current dn
@param oldPassword the old password
@param newPassword the new password
@param type        the type
@return true /false
<p>
AD NOTE: Resetting passwords requires binding to AD as user with privileges to reset other users passwords
and it does not validate old password or respect directory policies such as history or minimum password age.
Changing a password with the old password does respect directory policies and requires no account operator
privileges on the bind user. Pass in blank old password if reset is in order (e.g. forgot password) vs.
letting user change their own (e.g. expiring) password.
support/cas-server-support-ldap-core/src/main/java/org/apereo/cas/util/LdapConnectionFactory.java