Open byteAr opened 4 months ago
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();
}
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.
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; }
I manage to log in and find the user to change the password. But when I change it I receive the following error:
ConnectionError: 1ldap://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
}