Comment modifier un mot de passe d’utilisateur Windows Active Directory et LDS via LDAP

Comment modifier un mot de passe d’utilisateur Windows Active Directory et LDS via LDAP

Cet article vous expliquera comment changer le mot de passe d’un utilisateur dans Windows Active Directory et LDS en utilisant le protocole LDAP.

Résumé

Selon certaines restrictions, vous pouvez définir un nouveau mot de passe pour un utilisateur dans Windows Active Directory et Lightweight Directory Services (LDS) via le protocole LDAP (Lightweight Directory Access Protocol). Cet article vous montrera comment définir ou modifier l’attribut de mot de passe.

Ces étapes s’appliquent également aux utilisateurs ADAM (Active Directory Application Mode) et LDS, ainsi qu’aux objets userProxy, de la même manière que pour les utilisateurs AD. Pour plus d’informations, veuillez consulter les indications supplémentaires à la fin de l’article.

Plus d’informations

Le mot de passe est stocké dans la base de données AD et LDS sous l’attribut unicodePwd. Cet attribut peut être écrit dans des conditions restreintes, mais ne peut pas être lu. Il ne peut être modifié que ; il ne peut pas être ajouté lors de la création d’un objet ou interrogé par une recherche.

Pour modifier cet attribut, le client doit établir une connexion TLS (Transport Layer Security) / SSL (Secure Socket Layer) 128 bits avec le serveur. Une session chiffrée utilisant des clés de session créées par SSP en utilisant Windows New Technology LAN Manager (NTLM) ou Kerberos est également acceptable tant que la longueur minimale de la clé est respectée.

Pour que cette connexion soit possible en utilisant TLS/SSL, les conditions suivantes doivent être remplies :

  • Le serveur doit posséder un certificat de serveur pour une connexion RSA 128 bits.
  • Le client doit approuver l’autorité de certification qui a généré le certificat de serveur.
  • Le client et le serveur doivent être capables d’effectuer un chiffrement 128 bits.

La syntaxe de l’attribut unicodePwd est une chaîne d’octets, mais le service d’annuaire s’attend à ce que la chaîne d’octets contienne une chaîne UNICODE (comme l’indique le nom de l’attribut). Cela signifie que toutes les valeurs de cet attribut transmises via LDAP doivent être des chaînes UNICODE encodées en BER (Basic Encoding Rules) sous la forme d’une chaîne d’octets. De plus, la chaîne UNICODE doit commencer et se terminer par des guillemets qui ne font pas partie du mot de passe souhaité.

Il existe deux façons possibles de modifier l’attribut unicodePwd. La première est similaire à une opération de changement de mot de passe standard pour un utilisateur. Dans ce cas, la demande de modification doit inclure à la fois une opération de suppression et une opération d’ajout. L’opération de suppression doit contenir le mot de passe actuel entre guillemets. L’opération d’ajout doit contenir le nouveau mot de passe souhaité entre guillemets.

La deuxième façon de modifier cet attribut est semblable à la réinitialisation d’un mot de passe par un administrateur pour un utilisateur. Pour cela, le client doit se connecter en tant qu’utilisateur disposant des autorisations suffisantes pour modifier le mot de passe d’un autre utilisateur. La demande de modification doit contenir une opération de remplacement unique avec le nouveau mot de passe souhaité entre guillemets. Si le client dispose des autorisations suffisantes, ce mot de passe deviendra le nouveau mot de passe, quel que soit l’ancien mot de passe.

Les deux fonctions suivantes fournissent des exemples de ces opérations :

ULONG ChangeUserPassword(WCHAR* pszUserDN, WCHAR* pszOldPassword, WCHAR* pszNewPassword) {
  ULONG err = 1;
  LDAPMod modNewPassword;
  LDAPMod modOldPassword;
  LDAPMod *modEntry[3];
  BERVAL newPwdBerVal;
  BERVAL oldPwdBerVal;
  BERVAL *newPwd_attr[2];
  BERVAL *oldPwd_attr[2];
  WCHAR pszNewPasswordWithQuotes[1024];
  WCHAR pszOldPasswordWithQuotes[1024];

  // Construire un tableau de LDAPMod.
  // Pour définir unicodePwd, cela DOIT être une double opération.
  modEntry[0] = &modOldPassword;
  modEntry[1] = &modNewPassword;
  modEntry[2] = NULL;

  // Construire la structure mod pour l'ajout de unicodePwd.
  modNewPassword.mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
  modNewPassword.mod_type = L"unicodePwd";
  modNewPassword.mod_vals.modv_bvals = newPwd_attr;

  // Construire la structure mod pour la suppression de unicodePwd.
  modOldPassword.mod_op = LDAP_MOD_DELETE | LDAP_MOD_BVALUES;
  modOldPassword.mod_type = L"unicodePwd";
  modOldPassword.mod_vals.modv_bvals = oldPwd_attr;

  // Le mot de passe sera à valeur unique, donc nous n'avons qu'un seul élément.
  newPwd_attr[0] = &newPwdBerVal;
  newPwd_attr[1] = NULL;
  oldPwd_attr[0] = &oldPwdBerVal;
  oldPwd_attr[1] = NULL;

  // Entourer les mots de passe de guillemets.
  wsprintf(pszNewPasswordWithQuotes, L"%s", pszNewPassword);
  wsprintf(pszOldPasswordWithQuotes, L"%s", pszOldPassword);

  // Construire les structures BER avec les mots de passe UNICODE entre guillemets.
  newPwdBerVal.bv_len = wcslen(pszNewPasswordWithQuotes) * sizeof(WCHAR);
  newPwdBerVal.bv_val = (char*)pszNewPasswordWithQuotes;
  oldPwdBerVal.bv_len = wcslen(pszOldPasswordWithQuotes) * sizeof(WCHAR);
  oldPwdBerVal.bv_val = (char*)pszOldPasswordWithQuotes;

  // Effectuer la modification unique.
  err = ldap_modify_s(ldapConnection, pszUserDN, modEntry );

  if (err == LDAP_SUCCESS)
    wprintf(L"nMot de passe modifié avec succès !n");
  else
    wprintf(L"nLa modification du mot de passe a échoué !n");

  return err;
}

ULONG SetUserPassword(WCHAR* pszUserDN, WCHAR* pszPassword) {
  ULONG err = 1;
  LDAPMod modPassword;
  LDAPMod *modEntry[2];
  BERVAL pwdBerVal;
  BERVAL *pwd_attr[2];
  WCHAR pszPasswordWithQuotes[1024];

  // Construire un tableau de LDAPMod.
  // Pour définir unicodePwd, cela DOIT être une opération unique.
  modEntry[0] = &modPassword;
  modEntry[1] = NULL;

  // Construire la structure mod pour le remplacement de unicodePwd.
  modPassword.mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
  modPassword.mod_type = L"unicodePwd";
  modPassword.mod_vals.modv_bvals = pwd_attr;

  // Le mot de passe sera à valeur unique, donc nous n'avons qu'un seul élément.
  pwd_attr[0] = &pwdBerVal;
  pwd_attr[1] = NULL;

  // Entourer le mot de passe de guillemets.
  wsprintf(pszPasswordWithQuotes, L"%s", pszPassword);

  // Construire la structure BER avec le mot de passe UNICODE entre guillemets.
  pwdBerVal.bv_len = wcslen(pszPasswordWithQuotes) * sizeof(WCHAR);
  pwdBerVal.bv_val = (char*)pszPasswordWithQuotes;

  // Effectuer la modification unique.
  err = ldap_modify_s(ldapConnection, pszUserDN, modEntry );

  if (err == LDAP_SUCCESS)
    wprintf(L"nMot de passe défini avec succès !n");
  else
    wprintf(L"nLa définition du mot de passe a échoué !n");

  return err;
}

S’applique à

  • Windows Server 2012 Datacenter
  • Windows Server 2012 Standard
  • Windows Server 2012 R2 Centre de données
  • Windows Server 2012 R2 Standard
  • Windows Server 2016
  • Windows Server 2019
  • Windows Server 2022
  • Windows 8.1 Entreprise
  • Windows 8.1 Professionnel
  • Windows 10
  • Windows 11