Search code examples
phpldap

ldap_mod_replace returns true but password does not change


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?


Solution

  • 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);