It appears that there's no LDAP check on the Request New Password page or /user/password... Anyone have a quick solution for this?
Users that have created a password on another site/app using the LDAP server that want to recover that password can not do so.

Thanks...

Comments

deven_’s picture

Which LDAP server you are using? In case of OpenLDAP, changing the password in drupal, it changes the password in LDAP as well.

jeffsawyer’s picture

Perhaps I didn't explain well enough. The trouble is in user accounts that have not been created on Drupal yet, but do exist on the LDAP server... If there is no Drupal account, there's no way for the user to request a new password.

Thanks,

Jeff

jeffsawyer’s picture

Soooo.... Please excuse the length of this post and note that this is a bit of a hack!!

I managed to get the Request new Password feature to query LDAP, create a Drupal account based on the users LDAP info and email the user to change their password...

First, I added a callback to the ldapprov_menu_alter function in ldapprov.module:

// Take over the request new password form
$callbacks['user/password']['page arguments'] = array('ldapprov_user_pass', 2);
unset($callbacks['user/password']['file']);

Second, I included all the override code needed along with custom code to query LDAP in the validation function:

//////////////////////////////////////////////////////////////////////////////
// USER FORGOT PASSWORD -- REQUEST NEW PASSWORD FORM

/**
* Form builder; Request a password reset.
*
* @ingroup forms
* @see user_pass_validate()
* @see user_pass_submit()
*/
function ldapprov_user_pass() {
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Username or e-mail address'),
'#size' => 60,
'#maxlength' => max(USERNAME_MAX_LENGTH, EMAIL_MAX_LENGTH),
'#required' => TRUE,
);
$form['submit'] = array('#type' => 'submit', '#value' => t('E-mail new password'));

return $form;
}

function ldapprov_user_pass_validate($form, &$form_state) {
$values = $form_state['values'];
$account = $form['_account']['#value'];

if (isset($values['name']) && $account->name != $values['name']) {
$name = trim($form_state['values']['name']);
}

// Blocked accounts cannot request a new password,
// check provided username and email against access rules.
if (drupal_is_denied('user', $name) || drupal_is_denied('mail', $name)) {
form_set_error('name', t('%name is not allowed to request a new password.', array('%name' => $name)));
}

if (isset($name)) {
// Try to load by email.
$account = user_load(array('mail' => $name, 'status' => 1));
if (!$account) {
// No success, try to load by name.
$account = user_load(array('name' => $name, 'status' => 1));
}
if (isset($account->uid)) {
form_set_value(array('#parents' => array('account')), $account, $form_state);
}
else { // load didn't work by username or email, try LDAP
global $_ldapprov_ldap;

// Search for the entry in LDAP.
if (isset($name)) {
if (!$_ldapprov_ldap->connect(LDAPPROV_DN, LDAPPROV_PASS)) {
watchdog('ldapprov', 'User validate: user data could not be read in the LDAP directory. Could not bind as %dn.', array('%dn' => LDAPPROV_DN), WATCHDOG_ERROR);
form_set_error('name', t('User data could not be read in the LDAP directory. Please contact site administrator.'));
return;
}

$basedn = $_ldapprov_ldap->getOption('basedn');
$mail_attr = $_ldapprov_ldap->getOption('mail_attr') ? $_ldapprov_ldap->getOption('mail_attr') : LDAP_DEFAULT_USER_ATTRIBUTE;
$name_attr = $_ldapprov_ldap->getOption('user_attr') ? $_ldapprov_ldap->getOption('user_attr') : LDAP_DEFAULT_USER_ATTRIBUTE;
if ($ret = $_ldapprov_ldap->search($basedn, '('. $name_attr .'='. $name .')', array($name_attr))) {
//set up the values for the ldapprov_user_pass_submit to use
$name = trim($ret['0'][$name_attr]['0']);
$ret1 = $_ldapprov_ldap->search($basedn, '('. $name_attr .'='. $name .')', array($mail_attr));
$mail = $ret1['0'][$mail_attr]['0'];
$ret2 = $_ldapprov_ldap->search($basedn, '('. $name_attr .'='. $name .')', array('userPassword'));
$pass = trim($ret2['0']['userpassword']['0']);
$account['name'] = $name;
$account['mail'] = $mail;
$account['pass'] = $pass;
$account['init'] = $mail;
$account['status'] = 1;
$user = user_save('', $account);
form_set_value(array('#parents' => array('account')), $user, $form_state);
} else {
//try as email
if ($ret = $_ldapprov_ldap->search($basedn, '('. $mail_attr .'='. $name .')', array($mail_attr))) {
//set up the values for the ldapprov_user_pass_submit to use
$mail = $ret['0'][$mail_attr]['0'];
$ret1 = $_ldapprov_ldap->search($basedn, '('. $mail_attr .'='. $mail .')', array($name_attr));
$name = trim($ret1['0'][$name_attr]['0']);
$ret2 = $_ldapprov_ldap->search($basedn, '('. $name_attr .'='. $name .')', array('userPassword'));
$pass = trim($ret2['0']['userpassword']['0']);
$account['name'] = $name;
$account['mail'] = $mail;
$account['pass'] = $pass;
$account['init'] = $mail;
$account['status'] = 1;
$user = user_save('', $account);
form_set_value(array('#parents' => array('account')), $user, $form_state);
} else {
//$name is not a user name or email so set an error message...
form_set_error('name', t('%name is not a registered account, please click !reglink to sign up.', array('%name' => $name, '!reglink' => l(t('register'), 'user/register'))));
}
}
$_ldapprov_ldap->disconnect();
}
}
} else {
form_set_error('name', t('Please enter a username or e-mail address.'));
}
}

function ldapprov_user_pass_submit($form, &$form_state) {
global $language;

$account = $form_state['values']['account'];
// Mail one time login URL and instructions using current language.
_user_mail_notify('password_reset', $account, $language);
watchdog('user', 'Password reset instructions mailed to %name at %email.', array('%name' => $account->name, '%email' => $account->mail));
drupal_set_message(t('Further instructions have been sent to your e-mail address.'));

$form_state['redirect'] = 'user';
return;
}

-----------
Note that the most important function is ldapprov_user_pass_validate($form, &$form_state)... I also have some hard coded stuff in there that could use cleaning up, but I wasn't sure of a better way to do this at the time...

I didn't do the best job of commenting here, so if you have questions please let me know!

If anyone wants to help make this a regular patch, that'd be great. Or if anyone wants to look into adding this into a future release, I'd really like to see that!

Thanks,
Jeff

yadavy’s picture

I tried using this code but the "Request New Password" on user/password is not taking over. I still see the basic page coming from user.module.

* Added callback lines in ldapprov_menu_alter() method (ldapprov.module)
* Added other methods.
* Saved and refreshed the page.

I'll appreciate if you guide me here.

Thanks.

madhusudan’s picture

Status: Active » Needs review

@jeffsawyer, Thanks for the code.. its working fine.. I was looking for this..you could have managed to search username or email in one go..

@yadavy, what exact problem you are facing..?