Request only mail/cn/displayName from LDAP instead of every attribute
The real error surfaced by the previous commit's diagnostics: "Parser error ... Encoding too long" from @ldapjs/asn1's BER decoder — a parser desync (it misreads some later byte as a new field's length prefix), most likely triggered while decoding some AD attribute value on one of the ~1000 objects that we never actually use (e.g. nTSecurityDescriptor, msDS-ReplAttributeMetaData, or similar oversized/binary attributes AD attaches to many objects by default). Every call site only ever reads mail/cn/displayName, so there was never a reason to request the full attribute set — doing so avoids decoding whatever was tripping the bug, regardless of exactly which attribute it was. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012o9j9RezxbZVKQMrB7oRLY
This commit is contained in:
1 parent
2a505da975
commit
1e8133ee39
1 file changed
+26
-14
+26
-14
@@ -69,21 +69,33 @@ function search(
|
|||||||
// response handling, not the query itself. ldapjs runs the multi-page
|
// response handling, not the query itself. ldapjs runs the multi-page
|
||||||
// RFC 2696 round-trips internally; callers still just see one continuous
|
// RFC 2696 round-trips internally; callers still just see one continuous
|
||||||
// stream of `searchEntry` events followed by a single `end`.
|
// stream of `searchEntry` events followed by a single `end`.
|
||||||
client.search(baseDn, { filter, scope: "sub", paged: { pageSize: 200 } }, (err, res) => {
|
//
|
||||||
if (err) {
|
// `attributes` is also restricted to just what callers actually read
|
||||||
reject(describeError(client, err));
|
// (mail/cn/displayName) instead of requesting every attribute AD has on
|
||||||
return;
|
// an object. The real failure turned out to be @ldapjs/asn1's BER
|
||||||
}
|
// decoder throwing "Encoding too long" — a parser desync, most likely
|
||||||
res.on("searchEntry", (entry) => {
|
// triggered while decoding some oversized/exotic AD attribute we never
|
||||||
const attributes: Record<string, string> = {};
|
// use anyway (e.g. nTSecurityDescriptor, msDS-ReplAttributeMetaData).
|
||||||
for (const attr of entry.pojo.attributes) {
|
// Not requesting them sidesteps the bug entirely.
|
||||||
attributes[attr.type] = attr.values[0] ?? "";
|
client.search(
|
||||||
|
baseDn,
|
||||||
|
{ filter, scope: "sub", paged: { pageSize: 200 }, attributes: ["mail", "cn", "displayName"] },
|
||||||
|
(err, res) => {
|
||||||
|
if (err) {
|
||||||
|
reject(describeError(client, err));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
results.push({ dn: entry.objectName ?? entry.pojo.objectName, attributes });
|
res.on("searchEntry", (entry) => {
|
||||||
});
|
const attributes: Record<string, string> = {};
|
||||||
res.on("error", (searchErr) => reject(describeError(client, searchErr)));
|
for (const attr of entry.pojo.attributes) {
|
||||||
res.on("end", () => resolve(results));
|
attributes[attr.type] = attr.values[0] ?? "";
|
||||||
});
|
}
|
||||||
|
results.push({ dn: entry.objectName ?? entry.pojo.objectName, attributes });
|
||||||
|
});
|
||||||
|
res.on("error", (searchErr) => reject(describeError(client, searchErr)));
|
||||||
|
res.on("end", () => resolve(results));
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user