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

pereodic crash #873

Closed
janeblower opened this issue Apr 21, 2023 · 7 comments
Closed

pereodic crash #873

janeblower opened this issue Apr 21, 2023 · 7 comments

Comments

@janeblower
Copy link

Hello!

After some time running I get the following error:

node:events:489
throw er; // Unhandled 'error' event
^

Error: read ECONNRESET
at TCP.onStreamRead (node:internal/stream_base_commons:217:20)
Emitted 'error' event on Client instance at:
at Socket.onSocketError (/mnt/f/Code/EmailVerify-main/node_modules/ldapjs/lib/client/client.js:1001:12)
at Socket.emit (node:events:511:28)
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
errno: -104,
code: 'ECONNRESET',
syscall: 'read'
}

What am I doing wrong?


import LDAP from "ldapjs";

const server = ""; //ip or hostname
const user = ""; // user@domain
const password = ""; //user password
const adSuffix = "dc=rias,dc=ru"; 

const client = LDAP.createClient({
  url: `ldap://${server}`,
});

client.bind(user, password, (err) => {
  if (err) {
    console.log("Error in new connection " + err);
  } else {
    console.log("Connection success");
  }
});

export const searchUser = (value) => {
  return new Promise((resolve, reject) => {
    const opts = {
      filter: `(mail=${value})`,
      scope: "sub",
      attributes: ["cn", "mail"],
    };

    client.search(adSuffix, opts, (err, res) => {
      if (err) {
        reject(err);
      } else {
        res.on("searchEntry", (entry) => {
          resolve(entry.pojo.attributes.find((i) => i.type === "cn")?.values[0]);
        });
        res.on("error", (err) => {
          reject(err);
        });
      }
    });
  });
};
@jsumners
Copy link
Member

You have not registered an error event handler on the client.

@kmilacic
Copy link

I have the same problem. So I should do something like this?
ldapClient.on('error', err => { console.error('error: ' + err.message); });

Is this enough? Do I have to reinstantiate my client or do something else?

@jsumners
Copy link
Member

Have you tried adding the error listener? I would imagine it depends on the error, and your application, as to what needs to be done after receiving the error.

@driverjb
Copy link

I've had the best results by wrapping an ldapjs Client in my own LdapClient abstraction class. Internally, I create the client, and attach to it a handler that listens for the 'error' event. When the error occurs the handler re-binds the client. That way I call my searches and modifications through my wrapper class and the wrapper class takes care of the internal ldapjs class.

@classmatewu
Copy link

classmatewu commented May 29, 2023

Hi, I also met this code if I not unbind or destroy the socket, I also know this question is about the RST response from ldap server.
But what I'm curious about is that every time I get this error, it happens after the client has been idle for about 10-15 minutes. During this period, I didn't send any request. Why do I receive such a tcp return packet? Is it an internal heartbeat request in the ldapjs package? I tried to find the answer from the source code, but I couldn't find it, so I came here to bother.
Thanks a lot. @jsumners

    const client = ldapjs.createClient({ url, connectTimeout });

    client.bind(bindDN, bindPassword, (err) => {
      if (err) {
        console.log(err)
      }
    });

    client.on('error', (err) => {
      if (err) {
        console.log(err)
      }
    });

@jsumners
Copy link
Member

I also know this question is about the RST response from ldap server

What message is this? I don't recall reading about any such "RST response" in the spec.

But what I'm curious about is that every time I get this error, it happens after the client has been idle for about 10-15 minutes. During this period, I didn't send any request. Why do I receive such a tcp return packet?

This is likely a basic TCP keepalive packet.

Is it an internal heartbeat request in the ldapjs package?

I do not believe ldapjs does any such thing.

I'm closing this issue since the original reporter has decided not to respond. If a reproduction can be provided, we can reopen it.

@Fray117
Copy link

Fray117 commented Jan 5, 2024

I think this issue it's a bit old, but somehow I met a similar problems when I tried to write an helper (service) in NestJS.

This issue not came after every restart until it hit a certain interval.

My issue related to credentials validation to Microsoft AD which just went success whatever the password with just a correct dn.

AFAIK, other teams working with this AD were using php which only validate once and flush the client and I assumed with hanging connection like this on JS had some problems.

Minimal reproduction

First, I import Client and make an variable to containing the ldapjs client

import { Client, SearchEntry, createClient } from 'ldapjs'

export class LdapService implements OnApplicationBootstrap {
	private auth: Client
}

then I add function that run everytime the NestJS is started (or restart) to initiate the client

async onApplicationBootstrap() {
	const ldapOptions = {
		url: LDAP_URL,
		reconnect: true,
	}

	this.auth = createClient(ldapOptions)

	this.auth.on('connectError', (err) => {
		this.logger.warn(`Auth ${err}`)
	})

	this.auth.on('error', (err) => this.logger.error(`Auth ${err}`))
}

Finally I had an function to verify dn and password by bind

async authenticateLdap(dn, password): Promise <boolean> {
	return new Promise((resolve) => {
		this.auth.bind(dn, password, (err) => {
			if (err) {
				// Bind failed
				resolve(false)
			} else {
				// Bind was successful, immediately unbind for next user authentication
				this.auth.unbind()

				resolve(true)
			}
		})
	})
}

I tried to unbind immediately after it succesfully binded

However in about several minutes later it came an error Client Error: read ECONNRESET which returned by this listener

this.auth.on('error', (err) => this.logger.error(`Auth ${err}`))

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

6 participants