Skip to content

Commit

Permalink
bring password functions from ssp (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
Markus Beckschulte authored and davidcoutadeur committed Apr 2, 2024
1 parent d04f93d commit f979f92
Show file tree
Hide file tree
Showing 4 changed files with 639 additions and 1 deletion.
132 changes: 132 additions & 0 deletions src/Ltb/Ldap.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,139 @@ static function sorted_search($ldap, $ldap_base, $ldap_filter, $attributes, $sor

return array($ldap_result,$errno,$entries);
}

/**
* Gets the value of the password attribute
* @param \LDAP\Connection|array $ldap An LDAP\Connection instance, returned by ldap_connect()
* @param string $dn the dn of the user
* @param type $pwdattribute the Attribute that contains the password
* @return string the value of $pwdattribute
*/
static function get_password_value($ldap, $dn, $pwdattribute): string {
$search_userpassword = \Ltb\PhpLDAP::ldap_read($ldap, $dn, "(objectClass=*)", array($pwdattribute));
if ($search_userpassword) {
return \Ltb\PhpLDAP::ldap_get_values($ldap, ldap_first_entry($ldap, $search_userpassword), $pwdattribute);
}
}

/**
* Changes the password of an user while binded as the user in an Active Directory
* @param \LDAP\Connection|array $ldap An LDAP\Connection instance, returned by ldap_connect()
* @param string $dn the dn of the user
* @param string $oldpassword the old password
* @param string $password the new password
* @return array [$error_code, $error_msg]
*/
static function change_ad_password_as_user($ldap, $dn, $oldpassword, $password): array {
# The AD password change procedure is modifying the attribute unicodePwd by
# first deleting unicodePwd with the old password and them adding it with the
# the new password
$oldpassword_hashed = make_ad_password($oldpassword);

$modifications = array(
array(
"attrib" => "unicodePwd",
"modtype" => LDAP_MODIFY_BATCH_REMOVE,
"values" => array($oldpassword_hashed),
),
array(
"attrib" => "unicodePwd",
"modtype" => LDAP_MODIFY_BATCH_ADD,
"values" => array($password),
),
);

\Ltb\PhpLDAP::ldap_modify_batch($ldap, $dn, $modifications);
$error_code = ldap_errno($ldap);
$error_msg = ldap_error($ldap);
return array($error_code, $error_msg);
}

static protected function get_ppolicy_error_code($ctrls) {
if (isset($ctrls[LDAP_CONTROL_PASSWORDPOLICYRESPONSE])) {
$value = $ctrls[LDAP_CONTROL_PASSWORDPOLICYRESPONSE]['value'];
if (isset($value['error'])) {
$ppolicy_error_code = $value['error'];
error_log("LDAP - Ppolicy error code: $ppolicy_error_code");
return $ppolicy_error_code;
}
}
return false;
}

/**
* Changes the Password using extended password modification
* @param \LDAP\Connection|array $ldap An LDAP\Connection instance, returned by ldap_connect()
* @param string $dn the dn of the user
* @param string $oldpassword the old password
* @param string $password the new password
* @param array $userdata
* @param bool $use_ppolicy_control
* @return array 0: error_code, 1: error_msg, 2: ppolicy_error_code
*/
static function change_password_with_exop($ldap, $dn, $oldpassword, $password, $use_ppolicy_control): array {
$ppolicy_error_code = false;
$exop_passwd = FALSE;
if ( $use_ppolicy_control ) {
$ctrls = array();
$exop_passwd = \Ltb\PhpLDAP::ldap_exop_passwd($ldap, $dn, $oldpassword, $password, $ctrls);
$error_code = \Ltb\PhpLDAP::ldap_errno($ldap);
$error_msg = \Ltb\PhpLDAP::ldap_error($ldap);
if (!$exop_passwd) {
$ppolicy_error_code = self::get_ppolicy_error_code($ctrls);
}
} else {
$exop_passwd = \Ltb\PhpLDAP::ldap_exop_passwd($ldap, $dn, $oldpassword, $password);
$error_code = \Ltb\PhpLDAP::ldap_errno($ldap);
$error_msg = \Ltb\PhpLDAP::ldap_error($ldap);
}
return array($error_code, $error_msg, $ppolicy_error_code);
}

/**
* Changes attributes (and password) using Password Policy Control
* @param \LDAP\Connection|array $ldap An LDAP\Connection instance, returned by ldap_connect()
* @param string $dn the dn of the user
* @param array $userdata the array, containing the new (hashed) password
* @return array 0: error_code, 1: error_msg, 2: ppolicy_error_code
*/
static function modify_attributes_using_ppolicy($ldap, $dn, $userdata): array {
$error_code = "";
$error_msg = "";
$ctrls = array();
$ppolicy_error_code = false;
$ppolicy_replace = \Ltb\PhpLDAP::ldap_mod_replace_ext($ldap, $dn, $userdata, [['oid' => LDAP_CONTROL_PASSWORDPOLICYREQUEST]]);
if (\Ltb\PhpLDAP::ldap_parse_result($ldap, $ppolicy_replace, $error_code, $matcheddn, $error_msg, $referrals, $ctrls)) {
$ppolicy_error_code = self::get_ppolicy_error_code($ctrls);
}
return array($error_code, $error_msg, $ppolicy_error_code);
}

/**
* Changes attributes (and password)
* @param \LDAP\Connection|array $ldap An LDAP\Connection instance, returned by ldap_connect()
* @param string $dn the dn of the user
* @param array $userdata the array, containing the new (hashed) password
* @return array 0: error_code, 1: error_msg
*/
static function modify_attributes($ldap, $dn, $userdata): array {
\Ltb\PhpLDAP::ldap_mod_replace($ldap, $dn, $userdata);
$error_code = ldap_errno($ldap);
$error_msg = ldap_error($ldap);
return array($error_code, $error_msg);
}

const PPOLICY_ERROR_CODE_TO_RESULT_MAPPER = [
0 => "passwordExpired",
1 => "accountLocked",
2 => "changeAfterReset",
3 => "passwordModNotAllowed",
4 => "mustSupplyOldPassword",
5 => "badquality",
6 => "tooshort",
7 => "tooyoung",
8 => "inhistory"
];

}
?>
Loading

0 comments on commit f979f92

Please sign in to comment.