diff --git a/src/directoryserver.js b/src/directoryserver.js index 406cb43b3..46d0ddd98 100644 --- a/src/directoryserver.js +++ b/src/directoryserver.js @@ -199,10 +199,10 @@ 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); const [error, allUsers] = await safe(users.list()); - if (error) return next(new ldap.OperationsError(error.toString())); + if (error) return next(new ldap.OperationsError(error.message)); const [groupsError, allGroups] = await safe(groups.listWithMembers()); - if (groupsError) return next(new ldap.OperationsError(error.toString())); + if (groupsError) return next(new ldap.OperationsError(groupsError.message)); let results = []; @@ -244,7 +244,7 @@ async function userSearch(req, res, next) { // ensure all filter values are also lowercase const lowerCaseFilter = safe(function () { return ldap.parseFilter(req.filter.toString().toLowerCase()); }, null); - if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.toString())); + if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.message)); if ((req.dn.equals(dn) || req.dn.parentOf(dn)) && lowerCaseFilter.matches(obj.attributes)) { results.push(obj); @@ -258,12 +258,12 @@ async function groupSearch(req, res, next) { debug('group search: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id); const [error, allUsers] = await safe(users.list()); - if (error) return next(new ldap.OperationsError(error.toString())); + if (error) return next(new ldap.OperationsError(error.message)); const results = []; let [errorGroups, allGroups] = await safe(groups.listWithMembers()); - if (errorGroups) return next(new ldap.OperationsError(errorGroups.toString())); + if (errorGroups) return next(new ldap.OperationsError(errorGroups.message)); for (const group of allGroups) { const dn = ldap.parseDN(`cn=${group.name},ou=groups,dc=cloudron`); @@ -283,7 +283,7 @@ async function groupSearch(req, res, next) { // ensure all filter values are also lowercase const lowerCaseFilter = safe(function () { return ldap.parseFilter(req.filter.toString().toLowerCase()); }, null); - if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.toString())); + if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.message)); if ((req.dn.equals(dn) || req.dn.parentOf(dn)) && lowerCaseFilter.matches(obj.attributes)) { results.push(obj); @@ -315,8 +315,8 @@ async function userAuth(req, res, next) { } const [error, user] = await safe(verifyFunc(commonName, req.credentials || '', '', { totpToken })); - if (error && error.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); - if (error && error.reason === BoxError.INVALID_CREDENTIALS) return next(new ldap.InvalidCredentialsError(req.dn.toString())); + if (error && error.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(error.message)); + if (error && error.reason === BoxError.INVALID_CREDENTIALS) return next(new ldap.InvalidCredentialsError(error.message)); if (error) return next(new ldap.OperationsError(error.message)); req.user = user; diff --git a/src/ldap.js b/src/ldap.js index 0893aecb4..e6a761e65 100644 --- a/src/ldap.js +++ b/src/ldap.js @@ -68,8 +68,8 @@ async function userAuthInternal(appId, req, res, next) { } const [error, user] = await safe(verifyFunc(commonName, req.credentials || '', appId || '', { relaxedTotpCheck: true, totpToken })); - if (error && error.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); - if (error && error.reason === BoxError.INVALID_CREDENTIALS) return next(new ldap.InvalidCredentialsError(req.dn.toString())); + if (error && error.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(error.message)); + if (error && error.reason === BoxError.INVALID_CREDENTIALS) return next(new ldap.InvalidCredentialsError(error.message)); if (error) return next(new ldap.OperationsError(error.message)); req.user = user; @@ -149,10 +149,10 @@ 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); const [error, result] = await safe(getUsersWithAccessToApp(req)); - if (error) return next(new ldap.OperationsError(error.toString())); + if (error) return next(new ldap.OperationsError(error.message)); const [groupsError, allGroups] = await safe(groups.listWithMembers()); - if (groupsError) return next(new ldap.OperationsError(error.toString())); + if (groupsError) return next(new ldap.OperationsError(groupsError.message)); let results = []; @@ -192,7 +192,7 @@ async function userSearch(req, res, next) { // ensure all filter values are also lowercase const lowerCaseFilter = safe(function () { return ldap.parseFilter(req.filter.toString().toLowerCase()); }, null); - if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.toString())); + if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.message)); if ((req.dn.equals(dn) || req.dn.parentOf(dn)) && lowerCaseFilter.matches(obj.attributes)) { results.push(obj); @@ -207,8 +207,8 @@ async function groupSearch(req, res, next) { const results = []; - let [errorGroups, resultGroups] = await safe(groups.listWithMembers()); - if (errorGroups) return next(new ldap.OperationsError(errorGroups.toString())); + let [groupsListError, resultGroups] = await safe(groups.listWithMembers()); + if (groupsListError) return next(new ldap.OperationsError(groupsListError.message)); if (req.app.accessRestriction && req.app.accessRestriction.groups) { resultGroups = resultGroups.filter(function (g) { return req.app.accessRestriction.groups.indexOf(g.id) !== -1; }); @@ -229,7 +229,7 @@ async function groupSearch(req, res, next) { // ensure all filter values are also lowercase const lowerCaseFilter = safe(function () { return ldap.parseFilter(req.filter.toString().toLowerCase()); }, null); - if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.toString())); + if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.message)); if ((req.dn.equals(dn) || req.dn.parentOf(dn)) && lowerCaseFilter.matches(obj.attributes)) { results.push(obj); @@ -243,7 +243,7 @@ async function groupUsersCompare(req, res, next) { debug('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.toString())); + if (error) return next(new ldap.OperationsError(error.message)); // we only support memberuid here, if we add new group attributes later add them here if (req.attribute === 'memberuid') { @@ -258,7 +258,7 @@ async function groupAdminsCompare(req, res, next) { debug('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.toString())); + if (error) return next(new ldap.OperationsError(error.message)); // we only support memberuid here, if we add new group attributes later add them here if (req.attribute === 'memberuid') { @@ -287,9 +287,9 @@ async function mailboxSearch(req, res, next) { if (parts.length !== 2) return next(new ldap.NoSuchObjectError(dn.toString())); const [error, mailbox] = await safe(mail.getMailbox(parts[0], parts[1])); - if (error) return next(new ldap.OperationsError(error.toString())); + if (error) return next(new ldap.OperationsError(error.message)); if (!mailbox) return next(new ldap.NoSuchObjectError(dn.toString())); - if (!mailbox.active) return next(new ldap.NoSuchObjectError(dn.toString())); + if (!mailbox.active) return next(new ldap.NoSuchObjectError('Mailbox is not active')); const obj = { dn: dn.toString(), @@ -306,7 +306,7 @@ async function mailboxSearch(req, res, next) { // ensure all filter values are also lowercase const lowerCaseFilter = safe(function () { return ldap.parseFilter(req.filter.toString().toLowerCase()); }, null); - if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.toString())); + if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.message)); if (lowerCaseFilter.matches(obj.attributes)) { finalSend([ obj ], req, res, next); @@ -316,7 +316,7 @@ async function mailboxSearch(req, res, next) { } else { // new sogo and dovecot listing (doveadm -A) // TODO figure out how proper pagination here could work let [error, mailboxes] = await safe(mail.listAllMailboxes(1, 100000)); - if (error) return next(new ldap.OperationsError(error.toString())); + if (error) return next(new ldap.OperationsError(error.message)); mailboxes = mailboxes.filter(m => m.active); @@ -349,7 +349,7 @@ async function mailboxSearch(req, res, next) { // ensure all filter values are also lowercase const lowerCaseFilter = safe(function () { return ldap.parseFilter(req.filter.toString().toLowerCase()); }, null); - if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.toString())); + if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.message)); if ((req.dn.equals(dn) || req.dn.parentOf(dn)) && lowerCaseFilter.matches(obj.attributes)) { results.push(obj); @@ -370,10 +370,10 @@ async function mailAliasSearch(req, res, next) { if (parts.length !== 2) return next(new ldap.NoSuchObjectError(req.dn.toString())); const [error, alias] = await safe(mail.searchAlias(parts[0], parts[1])); - if (error) return next(new ldap.OperationsError(error.toString())); + if (error) return next(new ldap.OperationsError(error.message)); if (!alias) return next(new ldap.NoSuchObjectError(req.dn.toString())); - if (!alias.active) return next(new ldap.NoSuchObjectError(req.dn.toString())); // there is no way to disable an alias. this is just here for completeness + if (!alias.active) return next(new ldap.NoSuchObjectError('Mailbox is not active')); // there is no way to disable an alias. this is just here for completeness // https://wiki.debian.org/LDAP/MigrationTools/Examples // https://docs.oracle.com/cd/E19455-01/806-5580/6jej518pp/index.html @@ -390,7 +390,7 @@ async function mailAliasSearch(req, res, next) { // ensure all filter values are also lowercase const lowerCaseFilter = safe(function () { return ldap.parseFilter(req.filter.toString().toLowerCase()); }, null); - if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.toString())); + if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.message)); if (lowerCaseFilter.matches(obj.attributes)) { finalSend([ obj ], req, res, next); @@ -411,11 +411,11 @@ async function mailingListSearch(req, res, next) { const [error, result] = await safe(mail.resolveList(parts[0], parts[1])); if (error && error.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); - if (error) return next(new ldap.OperationsError(error.toString())); + if (error) return next(new ldap.OperationsError(error.message)); const { resolvedMembers, list } = result; - if (!list.active) return next(new ldap.NoSuchObjectError(req.dn.toString())); + if (!list.active) return next(new ldap.NoSuchObjectError('List is not active')); // http://ldapwiki.willeke.com/wiki/Original%20Mailgroup%20Schema%20From%20Netscape // members are fully qualified (https://docs.oracle.com/cd/E19444-01/816-6018-10/groups.htm#13356) @@ -433,7 +433,7 @@ async function mailingListSearch(req, res, next) { // ensure all filter values are also lowercase const lowerCaseFilter = safe(function () { return ldap.parseFilter(req.filter.toString().toLowerCase()); }, null); - if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.toString())); + if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.message)); if (lowerCaseFilter.matches(obj.attributes)) { finalSend([ obj ], req, res, next); @@ -501,7 +501,7 @@ async function authenticateSftp(req, res, next) { if (error || !app) return next(new ldap.InvalidCredentialsError(req.dn.toString())); [error] = await safe(users.verifyWithUsername(parts[0], req.credentials, app.id, { relaxedTotpCheck: true })); - if (error) return next(new ldap.InvalidCredentialsError(req.dn.toString())); + if (error) return next(new ldap.InvalidCredentialsError(error.message)); debug('sftp auth: success'); @@ -520,7 +520,7 @@ async function userSearchSftp(req, res, next) { const appFqdn = parts[1]; const [error, app] = await safe(apps.getByFqdn(appFqdn)); - if (error) return next(new ldap.OperationsError(error.toString())); + if (error) return next(new ldap.OperationsError(error.message)); // only allow apps which specify "ftp" support in the localstorage addon if (!safe.query(app.manifest.addons, 'localstorage.ftp.uid')) return next(new ldap.UnavailableError('Not supported')); @@ -529,7 +529,7 @@ async function userSearchSftp(req, res, next) { const uidNumber = app.manifest.addons.localstorage.ftp.uid; const [userGetError, user] = await safe(users.getByUsername(username)); - if (userGetError) return next(new ldap.OperationsError(userGetError.toString())); + if (userGetError) return next(new ldap.OperationsError(userGetError.message)); if (!user) return next(new ldap.OperationsError('Invalid username')); if (!apps.isOperator(app, user)) return next(new ldap.InsufficientAccessRightsError('Not authorized')); @@ -595,13 +595,13 @@ async function authenticateService(serviceId, dn, req, res, next) { const [appPasswordError] = await safe(verifyAppMailboxPassword(serviceId, email, req.credentials || '')); if (!appPasswordError) return res.end(); // validated as app - if (appPasswordError.reason === BoxError.INVALID_CREDENTIALS) return next(new ldap.InvalidCredentialsError(dn.toString())); + if (appPasswordError.reason === BoxError.INVALID_CREDENTIALS) return next(new ldap.InvalidCredentialsError(appPasswordError.message)); if (appPasswordError.reason !== BoxError.NOT_FOUND) return next(new ldap.OperationsError(appPasswordError.message)); if (!mailbox || !mailbox.active) return next(new ldap.NoSuchObjectError(dn.toString())); // user auth requires active mailbox const [verifyError, result] = await safe(verifyMailboxPassword(mailbox, req.credentials || '')); - if (verifyError && verifyError.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(dn.toString())); - if (verifyError && verifyError.reason === BoxError.INVALID_CREDENTIALS) return next(new ldap.InvalidCredentialsError(dn.toString())); + if (verifyError && verifyError.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(verifyError.message)); + if (verifyError && verifyError.reason === BoxError.INVALID_CREDENTIALS) return next(new ldap.InvalidCredentialsError(verifyError.message)); if (verifyError) return next(new ldap.OperationsError(verifyError.message)); eventlog.upsertLoginEvent(result.ghost ? eventlog.ACTION_USER_LOGIN_GHOST : eventlog.ACTION_USER_LOGIN, AuditSource.MAIL, { mailboxId: email, userId: result.id, user: users.removePrivateFields(result) });