code/model/LDAPGateway.php
public function changePassword($dn, $password, $oldPassword)
    {
        if (!function_exists('ldap_modify_batch')) {
            // Password change is unsupported - missing PHP API method.
            $this->resetPassword($dn, $password);
            return;
        }

        $modifications = [
            [
                "attrib"  => "unicodePwd",
                "modtype" => LDAP_MODIFY_BATCH_REMOVE,
                "values"  => [iconv('UTF-8', 'UTF-16LE', sprintf('"%s"', $oldPassword))],
            ],
            [
                "attrib"  => "unicodePwd",
                "modtype" => LDAP_MODIFY_BATCH_ADD,
                "values"  => [iconv('UTF-8', 'UTF-16LE', sprintf('"%s"', $password))],
            ],
        ];
        // Batch attribute operations are not supported by Zend_Ldap, use raw resource.
        $ldapConn = $this->ldap->getResource();
        \Zend\Stdlib\ErrorHandler::start(E_WARNING);
        $succeeded = ldap_modify_batch($ldapConn, $dn, $modifications);
        \Zend\Stdlib\ErrorHandler::stop();
        if (!$succeeded) {
            throw new Exception($this->getLastPasswordError());
        }
    }
public function changePassword($dn, $password, $oldPassword)
    {
        if (!function_exists('ldap_modify_batch')) {
            // Password change is unsupported - missing PHP API method.
            $this->resetPassword($dn, $password);
            return;
        }

        $modifications = [
            [
                "attrib"  => "unicodePwd",
                "modtype" => LDAP_MODIFY_BATCH_REMOVE,
                "values"  => [iconv('UTF-8', 'UTF-16LE', sprintf('"%s"', $oldPassword))],
            ],
            [
                "attrib"  => "unicodePwd",
                "modtype" => LDAP_MODIFY_BATCH_ADD,
                "values"  => [iconv('UTF-8', 'UTF-16LE', sprintf('"%s"', $password))],
            ],
        ];
        // Batch attribute operations are not supported by Zend_Ldap, use raw resource.
        $ldapConn = $this->ldap->getResource();
        \Zend\Stdlib\ErrorHandler::start(E_WARNING);
        $succeeded = ldap_modify_batch($ldapConn, $dn, $modifications);
        \Zend\Stdlib\ErrorHandler::stop();
        if (!$succeeded) {
            throw new Exception($this->getLastPasswordError());
        }
    }
Changes user password via LDAP.

Change password is different to administrative password reset in that it will respect the password
history policy. This is achieved by sending a remove followed by an add in one batch (which is different
to an ordinary attribute modification operation).

@param string $dn Location to update the entry at.
@param string $password New password to set.
@param string $oldPassword Old password is needed to trigger a password change.
@throws \Zend\Ldap\Exception\LdapException