code/authenticators/LDAPLoginForm.php
public function forgotPassword($data)
    {
        // Passing true returns a float rather than a string
        $startTime = microtime(true);
        // No need to protect against injections, LDAPService will ensure that this is safe
        $login = trim($data['Login']);

        $service = Injector::inst()->get('LDAPService');
        if (Email::validEmailAddress($login)) {
            if (Config::inst()->get('LDAPAuthenticator', 'allow_email_login')!='yes') {
                $this->sessionMessage(
                    _t(
                        'LDAPLoginForm.USERNAMEINSTEADOFEMAIL',
                        'Please enter your username instead of your email to get a password reset link.'
                    ),
                    'bad'
                );
                $this->consistentResponseTime($startTime);
                $this->controller->redirect($this->controller->Link('lostpassword'));
                return;
            }
            $userData = $service->getUserByEmail($login);
        } else {
            $userData = $service->getUserByUsername($login);
        }

        // Avoid information disclosure by displaying the same status,
        // regardless whether the email address actually exists
        if (!isset($userData['objectguid'])) {
            $this->consistentResponseTime($startTime);
            return $this->controller->redirect($this->controller->Link('passwordsent/')
                . urlencode($data['Login']));
        }

        $member = Member::get()->filter('GUID', $userData['objectguid'])->limit(1)->first();
        // User haven't been imported yet so do that now
        if (!($member && $member->exists())) {
            $member = new Member();
            $member->GUID = $userData['objectguid'];
        }

        // Update the users from LDAP so we are sure that the email is correct.
        // This will also write the Member record.
        $service->updateMemberFromLDAP($member);

        // Allow vetoing forgot password requests
        $results = $this->extend('forgotPassword', $member);
        if ($results && is_array($results) && in_array(false, $results, true)) {
            $this->consistentResponseTime($startTime);
            return $this->controller->redirect($this->ldapSecController->Link('lostpassword'));
        }

        if ($member) {
            $token = $member->generateAutologinTokenAndStoreHash();
            $e = Member_ForgotPasswordEmail::create();
            $e->populateTemplate($member);
            $e->populateTemplate([
                'PasswordResetLink' => LDAPSecurityController::getPasswordResetLink($member, $token)
            ]);
            $e->setTo($member->Email);
            $e->send();
            $this->consistentResponseTime($startTime);
            $this->controller->redirect($this->controller->Link('passwordsent/') . urlencode($data['Login']));
        } elseif ($data['Login']) {
            // Avoid information disclosure by displaying the same status,
            // regardless whether the email address actually exists
            $this->consistentResponseTime($startTime);
            $this->controller->redirect($this->controller->Link('passwordsent/') . urlencode($data['Login']));
        } else {
            if (Config::inst()->get('LDAPAuthenticator', 'allow_email_login')==='yes') {
                $this->sessionMessage(
                    _t(
                        'LDAPLoginForm.ENTERUSERNAMEOREMAIL',
                        'Please enter your username or your email address to get a password reset link.'
                    ),
                    'bad'
                );
            } else {
                $this->sessionMessage(
                    _t(
                        'LDAPLoginForm.ENTERUSERNAME',
                        'Please enter your username to get a password reset link.'
                    ),
                    'bad'
                );
            }
            $this->consistentResponseTime($startTime);
            $this->controller->redirect($this->controller->Link('lostpassword'));
        }
    }
public function forgotPassword($data)
    {
        // Passing true returns a float rather than a string
        $startTime = microtime(true);
        // No need to protect against injections, LDAPService will ensure that this is safe
        $login = trim($data['Login']);

        $service = Injector::inst()->get('LDAPService');
        if (Email::validEmailAddress($login)) {
            if (Config::inst()->get('LDAPAuthenticator', 'allow_email_login')!='yes') {
                $this->sessionMessage(
                    _t(
                        'LDAPLoginForm.USERNAMEINSTEADOFEMAIL',
                        'Please enter your username instead of your email to get a password reset link.'
                    ),
                    'bad'
                );
                $this->consistentResponseTime($startTime);
                $this->controller->redirect($this->controller->Link('lostpassword'));
                return;
            }
            $userData = $service->getUserByEmail($login);
        } else {
            $userData = $service->getUserByUsername($login);
        }

        // Avoid information disclosure by displaying the same status,
        // regardless whether the email address actually exists
        if (!isset($userData['objectguid'])) {
            $this->consistentResponseTime($startTime);
            return $this->controller->redirect($this->controller->Link('passwordsent/')
                . urlencode($data['Login']));
        }

        $member = Member::get()->filter('GUID', $userData['objectguid'])->limit(1)->first();
        // User haven't been imported yet so do that now
        if (!($member && $member->exists())) {
            $member = new Member();
            $member->GUID = $userData['objectguid'];
        }

        // Update the users from LDAP so we are sure that the email is correct.
        // This will also write the Member record.
        $service->updateMemberFromLDAP($member);

        // Allow vetoing forgot password requests
        $results = $this->extend('forgotPassword', $member);
        if ($results && is_array($results) && in_array(false, $results, true)) {
            $this->consistentResponseTime($startTime);
            return $this->controller->redirect($this->ldapSecController->Link('lostpassword'));
        }

        if ($member) {
            $token = $member->generateAutologinTokenAndStoreHash();
            $e = Member_ForgotPasswordEmail::create();
            $e->populateTemplate($member);
            $e->populateTemplate([
                'PasswordResetLink' => LDAPSecurityController::getPasswordResetLink($member, $token)
            ]);
            $e->setTo($member->Email);
            $e->send();
            $this->consistentResponseTime($startTime);
            $this->controller->redirect($this->controller->Link('passwordsent/') . urlencode($data['Login']));
        } elseif ($data['Login']) {
            // Avoid information disclosure by displaying the same status,
            // regardless whether the email address actually exists
            $this->consistentResponseTime($startTime);
            $this->controller->redirect($this->controller->Link('passwordsent/') . urlencode($data['Login']));
        } else {
            if (Config::inst()->get('LDAPAuthenticator', 'allow_email_login')==='yes') {
                $this->sessionMessage(
                    _t(
                        'LDAPLoginForm.ENTERUSERNAMEOREMAIL',
                        'Please enter your username or your email address to get a password reset link.'
                    ),
                    'bad'
                );
            } else {
                $this->sessionMessage(
                    _t(
                        'LDAPLoginForm.ENTERUSERNAME',
                        'Please enter your username to get a password reset link.'
                    ),
                    'bad'
                );
            }
            $this->consistentResponseTime($startTime);
            $this->controller->redirect($this->controller->Link('lostpassword'));
        }
    }
Forgot password form handler method.

Called when the user clicks on "I've lost my password".

Extensions can use the 'forgotPassword' method to veto executing
the logic, by returning FALSE. In this case, the user will be redirected back
to the form without further action. It is recommended to set a message
in the form detailing why the action was denied.

Overridden because we need to generate a link to the LDAPSecurityController
instead of the SecurityController

@param array $data Submitted data
@return SS_HTTPResponse