I am working on an SAP BTP CAP app that integrates with Active Directory using LDAP.js. The connection to the LDAP server works fine for most requests, but occasionally, we encounter the following error:
LdapErr: DSID-0C060810, comment: No other operations may be performed on the connection while a bind is outstanding., data 0, v3839
What we are doing:
- We have an API endpoint that calls the ldap.searchAD() function.
- The code ensures that operations like binding, searching, and unbinding are performed sequentially using a mutex to serialize the requests.
Code:
API endpoint:
const { Mutex } = require('async-mutex');
const mutex = new Mutex();
apicall.on('searchAD', async (req) => {
const release = await mutex.acquire();
try {
return await ldap.searchAD (req.data.username); // Call searchAD();
} catch (error) {
req.error({
code: 400,
message: `${error.message}`
});
} finally {
release();
}
});
searchAD function:
async function searchAD (attributesToRead) {
return callLdap(
LDAP_CONFIG.base,
LDAP_CONFIG.scope,
`(&(objectClass=user)(sAMAccountName=${attributesToRead}))`
)
.then() // processing
.catch(error => {
logger.error('Error fetching users Details');
throw error; // Re-throw the error to propagate it
});
}
callLdap function:
async function callLdap(base, scope, filter) {
try {
const client = await createLdapClient();
return await new Promise((resolve, reject) => {
const entries = [];
client.search(base, {
scope: scope,
filter: filter,
paged: false
}, async (err, res) => {
if (err) {
logger.error('Search error in searchLdap:', err);
await client.unbind();
reject(err);
}
res.on('searchEntry', (entry) => {
entries.push({
jsonData: JSON.stringify(entry.object)
});
});
res.on('error', async (err_1) => {
await client.unbind();
reject(err_1);
});
res.on('end', async (result) => {
await client.unbind();
resolve(entries);
});
res.on('close', async (result_1) => {
await client.unbind();
reject(new Error('Socket closed'));
});
});
});
} catch (error) {
throw error;
}
}
createLdapClient function:
const ldap = require('ldapjs'); // Version: "^2.3.3"
async function createLdapClient(options) {
const ldapClient = ldap.createClient({
url: ldapUrl,
tlsOptions: { ...tlsOptions, socket: info.socket }
});
return new Promise((resolve, reject) => {
ldapClient.bind(options.bindUser, options.bindPass, (err) => {
if (err) {
ldapClient.unbind();
return reject(err);
}
logger.info('Bound to LDAP server');
});
ldapClient.on('connect', () => {
resolve(ldapClient); // Resolve when connection is successful
});
ldapClient.on('error', (err) => {
reject(err); // Reject on error
});
});
}
What I’ve tried:
- Mutex Implementation: We are using a mutex to ensure only one LDAP request is processed at a time. This includes connection establishment, search, and unbinding operations.
- Client Unbind: We ensure the LDAP client is properly unbound after each operation.
Problem:
Even with the mutex in place, the following error occurs intermittently:
LdapErr: DSID-0C060810, comment: No other operations may be performed on the connection while a bind is outstanding., data 0, v3839
This error indicates that an operation is being attempted while the LDAP bind is still in progress, even though the mutex is supposed to ensure sequential execution.
Questions:
- What could be causing this intermittent error?
- Is there a potential issue with the LDAP.js connection handling, or is it related to how the mutex is implemented?
- How can we further ensure that the bind operation is completely finished before any subsequent operations are executed?
Any help or suggestions would be greatly appreciated!
Srivastav is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.