forked from extern/egroupware
* ActiveDirectory: real password change (not reset) for PHP 5.4>=5.4.26, 5.5>=5.5.10, 5.6+ (subject to minimum password age policy!)
This commit is contained in:
parent
8d7ab2f06c
commit
1f70db76b1
@ -1433,6 +1433,80 @@ class adLDAPUsers_egw extends adLDAPUsers
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we can to a real password change, not just a password reset
|
||||
*
|
||||
* Requires PHP 5.4 >= 5.4.26, PHP 5.5 >= 5.5.10 or PHP 5.6 >= 5.6.0
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function changePasswordSupported()
|
||||
{
|
||||
return function_exists('ldap_modify_batch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password of a user - This must be performed over SSL
|
||||
*
|
||||
* @param string $username The username to modify
|
||||
* @param string $password The new password
|
||||
* @param bool $isGUID Is the username passed a GUID or a samAccountName
|
||||
* @param string $old_password old password for password change, if supported
|
||||
* @return bool
|
||||
*/
|
||||
public function password($username, $password, $isGUID = false, $old_password=null)
|
||||
{
|
||||
if ($username === NULL) { return false; }
|
||||
if ($password === NULL) { return false; }
|
||||
if (!$this->adldap->getLdapBind()) { return false; }
|
||||
if (!$this->adldap->getUseSSL() && !$this->adldap->getUseTLS()) {
|
||||
throw new adLDAPException('SSL must be configured on your webserver and enabled in the class to set passwords.');
|
||||
}
|
||||
|
||||
$userDn = $this->dn($username, $isGUID);
|
||||
if ($userDn === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$add=array();
|
||||
|
||||
if (empty($old_password) || !function_exists('ldap_modify_batch')) {
|
||||
$add["unicodePwd"][0] = $this->encodePassword($password);
|
||||
|
||||
$result = @ldap_mod_replace($this->adldap->getLdapConnection(), $userDn, $add);
|
||||
}
|
||||
else {
|
||||
$mods = array(
|
||||
array(
|
||||
"attrib" => "unicodePwd",
|
||||
"modtype" => LDAP_MODIFY_BATCH_REMOVE,
|
||||
"values" => array($this->encodePassword($old_password)),
|
||||
),
|
||||
array(
|
||||
"attrib" => "unicodePwd",
|
||||
"modtype" => LDAP_MODIFY_BATCH_ADD,
|
||||
"values" => array($this->encodePassword($password)),
|
||||
),
|
||||
);
|
||||
$result = ldap_modify_batch($this->adldap->getLdapConnection(), $userDn, $mods);
|
||||
}
|
||||
if ($result === false){
|
||||
$err = ldap_errno($this->adldap->getLdapConnection());
|
||||
if ($err) {
|
||||
$msg = 'Error ' . $err . ': ' . ldap_err2str($err) . '.';
|
||||
if($err == 53) {
|
||||
$msg .= ' Your password might not match the password policy.';
|
||||
}
|
||||
throw new adLDAPException($msg);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify a user
|
||||
*
|
||||
@ -1550,4 +1624,24 @@ class adLDAPUtils_egw extends adLDAPUtils
|
||||
{
|
||||
return $this->adldap->encode8bit($item, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape strings for the use in LDAP filters
|
||||
*
|
||||
* DEVELOPERS SHOULD BE DOING PROPER FILTERING IF THEY'RE ACCEPTING USER INPUT
|
||||
* Ported from Perl's Net::LDAP::Util escape_filter_value
|
||||
*
|
||||
* @param string $str The string the parse
|
||||
* @author Port by Andreas Gohr <andi@splitbrain.org>
|
||||
* @return string
|
||||
*/
|
||||
public function ldapSlashes($str){
|
||||
return preg_replace_callback(
|
||||
'/([\x00-\x1F\*\(\)\\\\])/',
|
||||
function ($matches) {
|
||||
return "\\".join("", unpack("H2", $matches[1]));
|
||||
},
|
||||
$str
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -219,14 +219,15 @@ class auth_ads implements auth_backend
|
||||
$admin = true;
|
||||
$username = $GLOBALS['egw']->accounts->id2name($account_id);
|
||||
}
|
||||
// Check the old_passwd to make sure this is legal
|
||||
if(!$admin && !$this->authenticate($username, $old_passwd))
|
||||
// Check the old_passwd to make sure this is legal, if we dont support password change
|
||||
if (!$admin && (!method_exists($adldap->user(), 'passwordChangeSupported') ||
|
||||
!$adldap->user()->passwordChangeSupported()) && !$this->authenticate($username, $old_passwd))
|
||||
{
|
||||
//error_log(__METHOD__."() old password '$old_passwd' for '$username' is wrong!");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
$ret = $adldap->user()->password($username, $new_passwd);
|
||||
$ret = $adldap->user()->password($username, $new_passwd, false, $old_passwd);
|
||||
//error_log(__METHOD__."('$old_passwd', '$new_passwd', $account_id) admin=$admin adldap->user()->password('$username', '$new_passwd') returned ".array2string($ret));
|
||||
return $ret;
|
||||
}
|
||||
@ -243,7 +244,7 @@ class auth_ads implements auth_backend
|
||||
'Server is unwilling to perform.' => lang('Server is unwilling to perform.'),
|
||||
'Your password might not match the password policy.' => lang('Your password might not match the password policy.'),
|
||||
));
|
||||
throw new egw_exception('<p><b>'.lang('Failed to change password.')."</b></p>\n".$msg.($error ? "\n<p>".$error."</p>\n" : ''));
|
||||
throw new egw_exception('<p>'.lang('Failed to change password.')."</p>\n".$msg.($error ? "\n<p>".$error."</p>\n" : ''));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user