diff --git a/src/infra_version.js b/src/infra_version.js index 7e4da8fc2..3a629540a 100644 --- a/src/infra_version.js +++ b/src/infra_version.js @@ -17,7 +17,7 @@ exports = module.exports = { 'postgresql': { repo: 'cloudron/postgresql', tag: 'cloudron/postgresql:0.16.0' }, 'mongodb': { repo: 'cloudron/mongodb', tag: 'cloudron/mongodb:0.12.0' }, 'redis': { repo: 'cloudron/redis', tag: 'cloudron/redis:0.11.0' }, - 'mail': { repo: 'cloudron/mail', tag: 'cloudron/mail:0.30.5' }, + 'mail': { repo: 'cloudron/mail', tag: 'cloudron/mail:0.31.0' }, 'graphite': { repo: 'cloudron/graphite', tag: 'cloudron/graphite:0.11.0' } } }; diff --git a/src/ldap.js b/src/ldap.js index a83997150..418caafd7 100644 --- a/src/ldap.js +++ b/src/ldap.js @@ -6,6 +6,7 @@ exports = module.exports = { }; var assert = require('assert'), + appdb = require('./appdb.js'), apps = require('./apps.js'), async = require('async'), config = require('./config.js'), @@ -318,18 +319,27 @@ function authenticateMailbox(req, res, next) { if (error) return next(new ldap.OperationsError(error.message)); if (mailbox.ownerType === mailboxdb.TYPE_APP) { - if (req.credentials !== mailbox.ownerId) return next(new ldap.NoSuchObjectError(req.dn.toString())); - eventlog.add(eventlog.ACTION_APP_LOGIN, { authType: 'ldap', mailboxId: name }, { appId: mailbox.ownerId }); - return res.end(); + var addonId = req.dn.rdns[1].attrs.ou.value.toLowerCase(); // 'sendmail' or 'recvmail' + var name; + if (addonId === 'sendmail') name = 'MAIL_SMTP_PASSWORD'; + else if (addonId === 'recvmail') name = 'MAIL_IMAP_PASSWORD'; + else return next(new ldap.OperationsError('Invalid DN')); + + appdb.getAddonConfigByName(mailbox.ownerId, addonId, name, function (error, value) { + if (error || req.credentials !== value) return next(new ldap.NoSuchObjectError(req.dn.toString())); + + eventlog.add(eventlog.ACTION_APP_LOGIN, { authType: 'ldap', mailboxId: name }, { appId: mailbox.ownerId, addonId: addonId }); + return res.end(); + }); + } else if (mailbox.ownerType === mailboxdb.TYPE_USER) { + authenticateUser(req, res, function (error) { + if (error) return next(error); + eventlog.add(eventlog.ACTION_USER_LOGIN, { authType: 'ldap', mailboxId: name }, { userId: req.user.username }); + res.end(); + }); + } else { + return next(new ldap.OperationsError('Unknown ownerType for mailbox')); } - - assert.strictEqual(mailbox.ownerType, mailboxdb.TYPE_USER); - - authenticateUser(req, res, function (error) { - if (error) return next(error); - eventlog.add(eventlog.ACTION_USER_LOGIN, { authType: 'ldap', mailboxId: name }, { userId: req.user.username }); - res.end(); - }); }); } @@ -356,7 +366,8 @@ function start(callback) { gServer.search('ou=mailaliases,dc=cloudron', mailAliasSearch); gServer.search('ou=mailinglists,dc=cloudron', mailingListSearch); - gServer.bind('ou=mailboxes,dc=cloudron', authenticateMailbox); + gServer.bind('ou=recvmail,dc=cloudron', authenticateMailbox); + gServer.bind('ou=sendmail,dc=cloudron', authenticateMailbox); // this is the bind for addons (after bind, they might search and authenticate) gServer.bind('ou=addons,dc=cloudron', function(req, res, next) { diff --git a/src/test/ldap-test.js b/src/test/ldap-test.js index 269fe4d84..0ef3e82cd 100644 --- a/src/test/ldap-test.js +++ b/src/test/ldap-test.js @@ -734,11 +734,11 @@ describe('Ldap', function () { }); }); - describe('bind mailbox', function () { + describe('sendmail bind', function () { it('does not allow with invalid password', function (done) { var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + config.get('ldapPort') }); - client.bind('cn=' + USER_0.username + ',ou=mailboxes,dc=cloudron', USER_0.password + 'nope', function (error) { + client.bind('cn=' + USER_0.username + ',ou=sendmail,dc=cloudron', USER_0.password + 'nope', function (error) { expect(error).to.be.a(ldap.InvalidCredentialsError); done(); }); @@ -747,7 +747,7 @@ describe('Ldap', function () { it('allows with valid password', function (done) { var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + config.get('ldapPort') }); - client.bind('cn=' + USER_0.username + ',ou=mailboxes,dc=cloudron', USER_0.password, function (error) { + client.bind('cn=' + USER_0.username + ',ou=sendmail,dc=cloudron', USER_0.password, function (error) { done(error); }); }); @@ -759,7 +759,7 @@ describe('Ldap', function () { var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + config.get('ldapPort') }); - client.bind('cn=' + USER_0.username + '@' + config.fqdn() + ',ou=mailboxes,dc=cloudron', USER_0.password, function (error) { + client.bind('cn=' + USER_0.username + '@' + config.fqdn() + ',ou=sendmail,dc=cloudron', USER_0.password, function (error) { expect(error).not.to.be.ok(); settingsdb.set(settings.MAIL_CONFIG_KEY, JSON.stringify({ enabled: false }), done); @@ -767,4 +767,39 @@ describe('Ldap', function () { }); }); }); + + describe('recvmail bind', function () { + it('does not allow with invalid password', function (done) { + var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + config.get('ldapPort') }); + + client.bind('cn=' + USER_0.username + ',ou=recvmail,dc=cloudron', USER_0.password + 'nope', function (error) { + expect(error).to.be.a(ldap.InvalidCredentialsError); + done(); + }); + }); + + it('allows with valid password', function (done) { + var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + config.get('ldapPort') }); + + client.bind('cn=' + USER_0.username + ',ou=recvmail,dc=cloudron', USER_0.password, function (error) { + done(error); + }); + }); + + it('allows with valid email', function (done) { + // user settingsdb instead of settings, to not trigger further events + settingsdb.set(settings.MAIL_CONFIG_KEY, JSON.stringify({ enabled: true }), function (error) { + expect(error).not.to.be.ok(); + + var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + config.get('ldapPort') }); + + client.bind('cn=' + USER_0.username + '@' + config.fqdn() + ',ou=recvmail,dc=cloudron', USER_0.password, function (error) { + expect(error).not.to.be.ok(); + + settingsdb.set(settings.MAIL_CONFIG_KEY, JSON.stringify({ enabled: false }), done); + }); + }); + }); + }); + });