// Application-level hardening for the LDAP server: per-IP failed-bind rate // limiting / lockout (the LDAP port is outside Saltcorn's web-login throttling). // The parser-level guards (max inbound bytes per connection, filter-nesting // depth) now live in our owned layer -- lib/ldap/vendor.js (byte cap via the // connectionRouter) and lib/ldap/search.js (filter-depth walk) -- so no ldapjs // fork is needed. const WINDOW_MS = 5 * 60 * 1000; const MAX_FAILS = 10; const fails = new Map(); const isLocked = (ip) => { const e = fails.get(ip); if (!e) { return false; } if (Date.now() - e.first > WINDOW_MS) { fails.delete(ip); return false; } return e.count >= MAX_FAILS; }; const recordFail = (ip) => { const e = fails.get(ip); if (!e || Date.now() - e.first > WINDOW_MS) { fails.set(ip, { count: 1, first: Date.now() }); } else { e.count = e.count + 1; } }; const recordSuccess = (ip) => { fails.delete(ip); }; module.exports = { isLocked, recordFail, recordSuccess, MAX_FAILS };