1

I'm very new to ldapjs, and am trying to write an authenticate(username, password) script.

The steps I'm eventually trying to write are:

  1. bind to the admin, and I want to check for errors to see if the bind succeeded.
  2. search for the user in question (to see if they exist)
  3. bind to that user with their password to see if the password is correct

I'm currently stuck at step 1.

I am intentionally using a bad password when binding to the the admin to see if I can display an error message. My question is, why is my code not outputting an error message when it binds?

ldap3.js

const ldap = require('ldapjs');
const { promisify } = require('util');

// Configure the LDAP client
const ldapClient = ldap.createClient({
  url: 'ldap://my.domain.com:7001',
  tlsOptions: {
    rejectUnauthorized: false,
  },  
  timeout: 10000, //ms
  connectTimeout: 10000,
  idleTimeout: 10000
});


ldapClient.on('error', (err) => {
    console.error('LDAP error:', err);
});
  

function bindToAdmin() {
  console.log("inside BindToAdmin()");
  ldapClient.bind('cn=admin', 'password!qqq', err => {
    if(err){
      ldapClient.unbind();
       console.log("Error in binding (codeID: 5456464727):" + err);
       throw (err);
     }

    });
    
  console.log("after binding (codeID: 878789684654654)");
}
  

  
export default async function authenticateUser(username, password) {
  var assert = require('assert');

   console.log('START BINDING***********************************************************************');

  try {
    console.log("Binding to admin");
    bindToAdmin();
  } catch (err) {
    console.error(err.message);
  } 


  console.log('FINISHED BINDING*******************************************************************');

  //todo: search for the username
  //todo bind to the username using the password.  (if it binds, then we know the password is correct.)

  console.log('START UNBINDING************************************************************************');
  ldapClient.unbind();
  console.log('FINISHED UNBINDING*********************************************************************');

}

to call the code:

import ldapAuthenticate from '../../../library/ldap/ldap3';

    ...
      try {
        ldapAuthenticate(userIDInternal, password);
      } catch (error) {        
        console.log('Failed to authenticate user:', error.message);
      }

Output looks like this:

START BINDING***********************************************************************  
Binding to admin
inside BindToAdmin()
after binding (codeID: 878789684654654)
FINISHED BINDING*******************************************************************   

Edit 2023-03-09 (Additional Testing Info. Hopefully, this gives a clue.)

I waited 20 minutes, and still no additional output. Shouldn't it timeout after a few seconds?

Also, this is ldapjs 3.0.0, which I just realized was released just about 2 weeks ago (2/2023).

Also, I wanted to note, that I added code to Search for a user after the code that binds the admin. I'd say, 99% of the time, it finds nothing. However, ONCE, it actually found the user, and returned the values (phone, email...).

Also, I was able to connect using jXplorer, connecting from the same server. After connecting, I am able to navigate, and find all of the users, as well as edit the phone numbers and emails.

These are the settings I used with jXplorer:

Host: Same host as my code.
Port: 7001

Protocol: LDAP V3
BaseDN: BLANK

SecurityLevel: User+password
UserDN: cn=admin
password: same as my code
NL3294
  • 984
  • 1
  • 10
  • 27
  • 1
    It's likely that the connection to the server fails, if you wait you should get a connectError (at least, due to timeout). The `bind()`method won't do anything until a connection is established, and if it fails it's normal you don't get the "Error in binding" but directly "after binding" since it's a non-blocking function. The port 7001 is very uncommon, standard is 389. Also, once connected I think you will still have a binding issue, because the admin dn is incomplete. – EricLavault Mar 09 '23 at 11:56
  • Thank you for taking the time to review. I edited my post to include additional steps I've taken. I do not know if that helps diagnose the problem or not. If I continue to be stuck, I might opt to write a REST api in PHP to see if I have better luck. Then, connect my NodeJS code to the API written in PHP. – NL3294 Mar 09 '23 at 17:09

1 Answers1

0

I was able to resolve the issue. However, I do not know why the solution works.

I moved the createClient() code inside the authenticateUser() function, and it works flawlessly now.

EricLavault was correct in that it was a connection error. I was able to start getting error messages from the bind function (connection not available) by adding queueDisable: true to the list of parameters in createClient.

I still do not know why the connection wouldn't be available, or why the problem goes away when moving CreateClient() inside the authenticateUser function.

NL3294
  • 984
  • 1
  • 10
  • 27