I want to change a LDAP directory user's password using PHP.
After I bind to LDAP, I look for the desired user's dn with the samaccount
name and retrieve the dn
:
$filter="(samaccountname=desiredname.desiredname)";
$result = ldap_search($lh, $personnel_base, $filter) or die(ldap_error($lh));
//$data = ldap_get_entries($lh, $result);
$entry = ldap_first_entry($lh, $result);
$atribute = ldap_get_attributes($lh, $entry);
Then I use ldap_mode_replace to change the password:
$newpass = "Cevadetest123#!";
ldap_mod_replace($lh, $dn, array('userpassword' => "{MD5}".base64_encode(pack("H*",md5($newpass) ) ) ) ) or die(ldap_error($lh));
echo "Password changed!";
Though I get Password changed!
output, the password remains unchanged.
Any suggestions?
EDIT: I just noticed that the attribute userpassword
does change, but to login via LDAP I have to use the OLD password! What soccerry is this?
I found the answer. First of all, the field I had to change was unicodePwd
, which cannot be read - it can only be modified. In order to write to this field you must firstly have a secure connection to LDAP. The hostname therefore is: ldaps://hostname.something.local
The next important step is to encrypt the password before writing the field:
$newpassword="HelloWorld123";
$newpassword = "\"".$newpassword."\"";
$newPass = mb_convert_encoding($newpassword, 'UTF_16LE')
You can find the complete code here.
I'll just paste it below in case something happens with the link:
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
$ldapconn = ldap_connect('ldaps://127.0.0.1', 636);
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);
$ldapuser="ldapuser";
$ldappwd="*****";
// search for user
ldap_bind($ldapconn, "CN=$ldapuser,CN=Users,DC=my,DC=company,DC=example", $ldappwd);
$res_id = ldap_search( $ldapconn, "CN=Users,DC=my,DC=company,DC=example", "sAMAccountName=$username");
if ($res_id) {
$entry_id = ldap_first_entry($ldapconn, $res_id);
if($entry_id){
$user_dn = ldap_get_dn($ldapconn, $entry_id);
if ($user_dn) {
$ldapbind = ldap_bind($ldapconn, $user_dn, $oldpassword);
// check if the old password allows a successfull login
if($ldapbind) {
if(strcmp($newpassword, $newpassword2)==0){
// create the unicode password
$newpassword = "\"" . $newpassword . "\"";
$newPass = mb_convert_encoding($newpassword, "UTF-16LE");
//rebind as admin to change the password
ldap_bind($ldapconn, "CN=$ldapuser,CN=Users,DC=my,DC=company,DC=example", $ldappwd);
$pwdarr = array('unicodePwd' => $newPass);
if(ldap_mod_replace ($ldapconn, $user_dn, $pwdarr)) {
print "<p class='success'>Change password succeded.</p>\n";
} else {
print "<p class='error'>Change password failed.</p>\n";
}
}else{
print "<p class='error'>New password must be entered the same way twice.</p>\n";
}
}else{
print "<p class='error'>Wrong user name or password.</p>\n";
}
} else {
print "<p class='error'>Couldn't load user data.</p>\n";
}
} else {
print "<p class='error'>Couldn't find user data.</p>\n";
}
} else {
print "<p class='error'>Username was not found.</p>\n";
}
if(ldap_error($ldapconn)!="Success"){
print "<p class='error'>LDAP Error:<br />\n";
var_dump(ldap_error($ldapconn));
print "</p>\n";
}
@ldap_close($ldapconn);