diff --git a/src/directoryserver.js b/src/directoryserver.js index 8ef0cc643..960a10a38 100644 --- a/src/directoryserver.js +++ b/src/directoryserver.js @@ -143,6 +143,26 @@ async function authorize(req, res, next) { return next(); } +// https://ldapwiki.com/wiki/RootDSE / RFC 4512 - ldapsearch -x -h "${CLOUDRON_LDAP_SERVER}" -p "${CLOUDRON_LDAP_PORT}" -b "" -s base +// ldapjs seems to call this handler for everything when search === '' +async function maybeRootDSE(req, res, next) { + debug(`maybeRootDSE: requested with scope:${req.scope} dn:${req.dn.toString()}`); + + if (req.scope !== 'base') return next(new ldap.NoSuchObjectError()); // per the spec, rootDSE search require base scope + if (!req.dn || req.dn.toString() !== '') return next(new ldap.NoSuchObjectError()); + + res.send({ + dn: '', + attributes: { + objectclass: [ 'RootDSE', 'top', 'OpenLDAProotDSE' ], + supportedLDAPVersion: '3', + vendorName: 'Cloudron LDAP', + vendorVersion: '1.0.0' + } + }); + res.end(); +} + async function userSearch(req, res, next) { debug('user search: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id); @@ -329,6 +349,8 @@ async function start() { res.end(); }); + gServer.search('', maybeRootDSE); // when '', it seems the callback is called for everything else + // just log that an attempt was made to unknown route, this helps a lot during app packaging gServer.use(function(req, res, next) { debug('not handled: dn %s, scope %s, filter %s (from %s)', req.dn ? req.dn.toString() : '-', req.scope, req.filter ? req.filter.toString() : '-', req.connection.ldap.id);