Commit 4ec643d1 authored by Côme Bernigaud's avatar Côme Bernigaud Committed by Benoit Mortier
Browse files

Fixes #3813 Ppolicy plugin should check password history

Showing with 70 additions and 11 deletions
+70 -11
......@@ -121,6 +121,12 @@ class passwordMethodCrypt extends passwordMethod
return "{CRYPT}".crypt($pwd, $salt);
}
function checkPassword($pwd, $hash)
{
// Not implemented
return FALSE;
}
/*!
* \brief Get the hash name
*/
......
......@@ -68,6 +68,15 @@ class passwordMethodsmd5 extends passwordMethod
return $hash;
}
function checkPassword($pwd, $hash)
{
$hash = base64_decode(substr($hash, 6));
$salt = substr($hash, 16);
$hash = substr($hash, 0, 16);
$nhash = pack("H*", md5($pwd . $salt));
return ($nhash == $hash);
}
/*!
* \brief Get the hash name
*/
......
......@@ -78,6 +78,22 @@ class passwordMethodssha extends passwordMethod
return $pwd;
}
function checkPassword($pwd, $hash)
{
$hash = base64_decode(substr($hash, 6));
$salt = substr($hash, 20);
$hash = substr($hash, 0, 20);
if (function_exists("sha1")) {
$nhash = pack("H*", sha1($pwd . $salt));
} elseif (function_exists("mhash")) {
$nhash = mhash(MHASH_SHA1, $pwd.$salt);
} else {
msg_dialog::display(_("Configuration error"), msgPool::missingext("mhash"), ERROR_DIALOG);
return FALSE;
}
return ($nhash == $hash);
}
/*!
* \brief Get the hash name
*/
......
......@@ -133,7 +133,7 @@ class passwordMethod
}
/*!
* \brief (Un)locks an account (gosaAccount) which was locked by 'lock_account()'.
* \brief Unlocks an account (gosaAccount) which was locked by 'lock_account()'.
* For details about the locking mechanism see 'lock_account()'.
*/
private function generic_modify_account($config, $dn, $mode)
......@@ -175,6 +175,9 @@ class passwordMethod
$modify = lock_samba_account($mode, $attrs);
// (Un)lock the account by modifying the password hash.
$pwdClass = new password($config, $dn);
$pwdClass->callHook($pwdClass, 'PRE'.$mode, array(), $ret);
if ($mode == 'LOCK') {
/* Lock entry */
$pwd = preg_replace("/(^[^\}]+\})(.*$)/", "\\1!\\2", $pwd);
......@@ -186,7 +189,10 @@ class passwordMethod
$ldap->cd($dn);
$ldap->modify($modify);
if (!$ldap->success()) {
// Call the password post-lock hook, if defined.
if ($ldap->success()) {
$pwdClass->callHook($pwdClass, 'POST'.$mode, array(), $ret);
} else {
msg_dialog::display(_('LDAP error'), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD), LDAP_ERROR);
}
return $ldap->success();
......@@ -256,7 +262,6 @@ class passwordMethod
{
}
/*!
* \brief Method to let passwords backends manage additional information
* besides the userAttribute entry
......@@ -266,6 +271,14 @@ class passwordMethod
return TRUE;
}
/*!
* \brief Method to check if a password matches a hash
*/
function checkPassword($pwd, $hash)
{
return ($hash == $this->generate_hash($pwd));
}
/*!
* \brief Return true if this password method provides a configuration dialog
......
......@@ -480,12 +480,6 @@ class user extends simplePlugin
{
global $config, $ui;
if ($new_password != $repeated_password) {
return _('The passwords you\'ve entered as "New password" and "Repeated new password" do not match.');
} elseif ($new_password == '') {
return msgPool::required(_('New password'));
} else
/* Should we check different characters in new password */
$check_differ = ($config->get_cfg_value('passwordMinDiffer') != '');
$differ = $config->get_cfg_value('passwordMinDiffer', 0);
......@@ -498,7 +492,7 @@ class user extends simplePlugin
$length = $config->get_cfg_value('passwordMinLength', 0);
$ldap = $config->get_ldap_link();
$ldap->cat($user, array('pwdPolicySubentry', 'pwdHistory', 'pwdChangedTime'));
$ldap->cat($user, array('pwdPolicySubentry', 'pwdHistory', 'pwdChangedTime', 'userPassword'));
$attrs = $ldap->fetch();
$ppolicydn = '';
if (isset($attrs['pwdPolicySubentry'][0])) {
......@@ -533,13 +527,34 @@ class user extends simplePlugin
if (empty($current_password)) {
$current_password = NULL;
}
} elseif (isset($attrs['pwdHistory'][0])) {
}
if (isset($attrs['pwdHistory'][0])) {
unset($attrs['pwdHistory']['count']);
foreach ($attrs['pwdHistory'] as $pwdHistory) {
$pwdHistory = explode('#', $pwdHistory, 4);
$method = passwordMethod::get_method($pwdHistory[3], $user);
if (($method !== NULL) && $method->checkPassword($new_password, $pwdHistory[3])) {
return _('Password is in history of old passwords');
}
}
}
if (($current_password !== NULL) && ($current_password == $new_password)) {
return _('Password is not being changed from existing value');
} elseif (isset($attrs['userPassword'][0])) {
$method = passwordMethod::get_method($attrs['userPassword'][0], $user);
if (($method !== NULL) && $method->checkPassword($new_password, $attrs['userPassword'][0])) {
return _('Password is not being changed from existing value');
}
}
}
// Perform FusionDirectory password policy checks
if (($current_password !== NULL) && empty($current_password)) {
return _('You need to specify your current password in order to proceed.');
} elseif ($new_password != $repeated_password) {
return _('The passwords you\'ve entered as "New password" and "Repeated new password" do not match.');
} elseif ($new_password == '') {
return msgPool::required(_('New password'));
} elseif ($check_differ && (substr($current_password, 0, $differ) == substr($new_password, 0, $differ))) {
return _('The password used as new and current are too similar.');
} elseif ($check_length && (strlen($new_password) < $length)) {
......
  • bmortier @bmortier

    mentioned in issue #1260

    By Côme Chilliet on 2017-09-02T15:19:50 (imported from GitLab)

    ·

    mentioned in issue #1260

    By Côme Chilliet on 2017-09-02T15:19:50 (imported from GitLab)

    Toggle commit list
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment