ldapserver, directoryserver: all traces

This commit is contained in:
Girish Ramakrishnan
2026-03-12 23:30:12 +05:30
parent a4c253b9a9
commit 59c9e5397e
2 changed files with 38 additions and 38 deletions

View File

@@ -13,7 +13,7 @@ import safe from 'safetydance';
import users from './users.js';
import util from 'node:util';
const { log } = logger('ldapserver');
const { trace } = logger('ldapserver');
let _MOCK_APP = null;
@@ -142,7 +142,7 @@ function finalSend(results, req, res, next) {
}
async function userSearch(req, res, next) {
log('user search: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id);
trace('user search: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id);
const [error, result] = await safe(getUsersWithAccessToApp(req));
if (error) return next(new ldap.OperationsError(error.message));
@@ -195,7 +195,7 @@ async function userSearch(req, res, next) {
}
async function groupSearch(req, res, next) {
log('group search: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id);
trace('group search: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id);
const results = [];
@@ -230,7 +230,7 @@ async function groupSearch(req, res, next) {
}
async function groupUsersCompare(req, res, next) {
log('group users compare: dn %s, attribute %s, value %s (from %s)', req.dn.toString(), req.attribute, req.value, req.connection.ldap.id);
trace('group users compare: dn %s, attribute %s, value %s (from %s)', req.dn.toString(), req.attribute, req.value, req.connection.ldap.id);
const [error, result] = await safe(getUsersWithAccessToApp(req));
if (error) return next(new ldap.OperationsError(error.message));
@@ -245,7 +245,7 @@ async function groupUsersCompare(req, res, next) {
}
async function groupAdminsCompare(req, res, next) {
log('group admins compare: dn %s, attribute %s, value %s (from %s)', req.dn.toString(), req.attribute, req.value, req.connection.ldap.id);
trace('group admins compare: dn %s, attribute %s, value %s (from %s)', req.dn.toString(), req.attribute, req.value, req.connection.ldap.id);
const [error, result] = await safe(getUsersWithAccessToApp(req));
if (error) return next(new ldap.OperationsError(error.message));
@@ -260,7 +260,7 @@ async function groupAdminsCompare(req, res, next) {
}
async function mailboxSearch(req, res, next) {
log('mailbox search: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id);
trace('mailbox search: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id);
// if cn is set OR filter is mail= we only search for one mailbox specifically
let email, dn;
@@ -350,7 +350,7 @@ async function mailboxSearch(req, res, next) {
}
async function mailAliasSearch(req, res, next) {
log('mail alias get: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id);
trace('mail alias get: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id);
if (!req.dn.rdns[0].attrs.cn) return next(new ldap.NoSuchObjectError('Missing CN'));
@@ -389,7 +389,7 @@ async function mailAliasSearch(req, res, next) {
}
async function mailingListSearch(req, res, next) {
log('mailing list get: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id);
trace('mailing list get: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id);
if (!req.dn.rdns[0].attrs.cn) return next(new ldap.NoSuchObjectError('Missing CN'));
@@ -433,7 +433,7 @@ async function mailingListSearch(req, res, next) {
// Will attach req.user if successful
async function authenticateUser(req, res, next) {
log('user bind: %s (from %s)', req.dn.toString(), req.connection.ldap.id);
trace('user bind: %s (from %s)', req.dn.toString(), req.connection.ldap.id);
const appId = req.app.id;
@@ -478,7 +478,7 @@ async function verifyMailboxPassword(mailbox, password) {
}
async function authenticateSftp(req, res, next) {
log('sftp auth: %s (from %s)', req.dn.toString(), req.connection.ldap.id);
trace('sftp auth: %s (from %s)', req.dn.toString(), req.connection.ldap.id);
if (!req.dn.rdns[0].attrs.cn) return next(new ldap.NoSuchObjectError('Missing CN'));
@@ -492,13 +492,13 @@ async function authenticateSftp(req, res, next) {
const [verifyError] = await safe(users.verifyWithUsername(parts[0], req.credentials, app.id, { skipTotpCheck: true }));
if (verifyError) return next(new ldap.InvalidCredentialsError(verifyError.message));
log('sftp auth: success');
trace('sftp auth: success');
res.end();
}
async function userSearchSftp(req, res, next) {
log('sftp user search: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id);
trace('sftp user search: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id);
if (req.filter.attribute !== 'username' || !req.filter.value) return next(new ldap.NoSuchObjectError());
@@ -556,7 +556,7 @@ async function verifyAppMailboxPassword(serviceId, username, password) {
}
async function authenticateService(serviceId, dn, req, res, next) {
log(`authenticateService: ${req.dn.toString()} (from ${req.connection.ldap.id})`);
trace(`authenticateService: ${req.dn.toString()} (from ${req.connection.ldap.id})`);
if (!dn.rdns[0].attrs.cn) return next(new ldap.NoSuchObjectError(dn.toString()));
@@ -608,7 +608,7 @@ async function authenticateMail(req, res, 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) {
log(`maybeRootDSE: requested with scope:${req.scope} dn:${req.dn.toString()}`);
trace(`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());
@@ -633,16 +633,16 @@ async function start() {
const ldapLogger = {
trace: NOOP,
debug: NOOP,
info: log,
warn: log,
error: log,
fatal: log
info: trace,
warn: trace,
error: trace,
fatal: trace
};
gServer = ldap.createServer({ log: ldapLogger });
gServer.on('error', function (error) {
log('start: server error. %o', error);
trace('start: server error. %o', error);
});
gServer.search('ou=users,dc=cloudron', authenticateApp, userSearch);
@@ -670,14 +670,14 @@ async function start() {
// this is the bind for addons (after bind, they might search and authenticate)
gServer.bind('ou=addons,dc=cloudron', function(req, res /*, next */) {
log('addons bind: %s', req.dn.toString()); // note: cn can be email or id
trace('addons bind: %s', req.dn.toString()); // note: cn can be email or id
res.end();
});
// this is the bind for apps (after bind, they might search and authenticate user)
gServer.bind('ou=apps,dc=cloudron', function(req, res /*, next */) {
// TODO: validate password
log('application bind: %s', req.dn.toString());
trace('application bind: %s', req.dn.toString());
res.end();
});
@@ -693,7 +693,7 @@ async function start() {
// just log that an attempt was made to unknown route, this helps a lot during app packaging
gServer.use(function(req, res, next) {
log('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);
trace('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);
return next();
});