Skip to content
This repository has been archived by the owner on May 14, 2024. It is now read-only.

problems changing passwords #980

Open
byteAr opened this issue May 2, 2024 · 2 comments
Open

problems changing passwords #980

byteAr opened this issue May 2, 2024 · 2 comments

Comments

@byteAr
Copy link

byteAr commented May 2, 2024

I have had the problem that when trying to change the password of a user with valid credentials:

const ldap = require('ldapjs');

const ldapClient = ldap.createClient({
url: 'ldap://ipldap',
reconnect: true
});

const adminDN = 'cn=admin,cn=Users,dc=iugnad,dc=lan';
const adminPassword = 'passAdmin';

const searchFilter = '(sAMAccountName=mlopez)';

const searchOptions = {
scope: 'sub',
filter: searchFilter
};

ldapClient.bind(adminDN, adminPassword, (err) => {
if (err) {
console.error('Error LDAP:', err);
return;
}
console.log('Administrador autenticado correctamente.');

ldapClient.search('DC=example, DC=lan', searchOptions, (err, res) => {
if (err) {
console.error('Error User:', err);
return;
}

res.on('searchEntry', (entry) => {
  const userDN = entry.objectName;
  const newPassword= '********'
  console.log('DN del usuario encontrado:', userDN);

  const userCN = 'User';
 const userDN2 = `CN=${userCN},CN=Users,DC=iugnad,DC=lan`;

  const userPasswordAttribute = new ldap.Attribute({
    type: 'userPassword',
    vals: newPassword
  })

  ldapClient.modify(userDN2, 
    [
      new ldap.Change({
        operation: 'replace',
        modification: userPasswordAttribute
      })
    ],  
    (err) => {
    if (err) {
      console.log(err);
    } else {
      console.log('Password change successful');
    }
    ldapClient.unbind();
  });

I manage to log in and find the user to change the password. But when I change it I receive the following error:

ConnectionError: 1__ldap://servereldap:port closed
at C:\Users\mlopez\Desktop\prueba intranet\LDAP_Nodejs\node_modules\ldapjs\lib\client\client.js:1083:17
at C:\Users\mlopez\Desktop\prueba intranet\LDAP_Nodejs\node_modules\ldapjs\lib\client\message-tracker\index.js:113:7
at Map.forEach ()
at Object.purgeMessages [as purge] (C:\Users\mlopez\Desktop\prueba intranet\LDAP_Nodejs\node_modules\ldapjs\lib\client\message-tracker\index.js:110:14)
at Client._onClose (C:\Users\mlopez\Desktop\prueba intranet\LDAP_Nodejs\node_modules\ldapjs\lib\client\client.js:1081:11)
at Object.onceWrapper (node:events:633:26)
at Socket.emit (node:events:518:28)
at TCP. (node:net:337:12) {
lde_message: '1__ldap://10.98.40.22:389 closed',
lde_dn: null
}

@WanpengQian
Copy link

WanpengQian commented May 14, 2024

Since your code has an attribute sAMAccountName, assume your LDAP server is Windows AD Server.

AFAIK, For changing AD password, you should use delete operation follow a add operation, instead of replace operation.

replace operation is for password reset, that is the permission of administrator. while normal user has not such permission. for ref: https://learn.microsoft.com/en-us/troubleshoot/windows-server/active-directory/change-windows-active-directory-user-password

another thing, when you change password, you should use LDAPS instead of LDAP. for AD server, you have to enable LDAPS manually, (default configuration is not enabled.)

Connection sample code

const url = "ldaps://xxx.xxx.xxx.xxx:636";
const client = ldap.createClient({
  url: `${url}`,
  tlsOptions: {
    rejectUnauthorized: false
  }
});

PWD change sample code:

client.search("DC=xxx,DC=xxx,DC=xxx", searchOptions, (err, res) => {
  res.on('searchEntry', entry => {
    let dn = entry.pojo.objectName;
    client.modify(dn, [
      new ldap.Change({
        operation: 'delete',
        modification: new ldap.Attribute({
          type: 'unicodePwd',
          values: encodePassword(currentPassword)
        })
      }),
      new ldap.Change({
        operation: 'add',
        modification: new ldap.Attribute({
          type: 'unicodePwd',
          values: encodePassword(newPassword)
        })
      })
    ], function (e) {
      if (e) {
        resp.json({
          result: "failed",
          message: e
        });
        console.log(e);
      }
      else {
        resp.json({
          result: "success"
        });
        console.log('Password changed!');
      }
    });
  });
  res.on('error', e => {
    console.error('error: ' + e.message);
    resp.json({
      result: "failed",
      message: e
    });
  });
});

function encodePassword(password) {
  return new Buffer('"' + password + '"', 'utf16le').toString();
}

@WanpengQian
Copy link

WanpengQian commented May 14, 2024

And for TLS version, it depends on your Server Version. NodeJS is mark TLS 1.0/1.1 disabled by default. you have to make sure client and server can success have an TLS handshake.
You can capture the TLS packet by wireshark for sure.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants