From b85c4acb4c2e95aeed27f8ddd477dd5f4de705d8 Mon Sep 17 00:00:00 2001 From: Thomas Pressnell Date: Mon, 12 Jul 2021 16:02:12 +0100 Subject: [PATCH 1/3] adding bindDN adjustments --- lib/server.js | 15 +++++++- test/server.test.js | 83 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/lib/server.js b/lib/server.js index 74f2a67e..cbf110bf 100644 --- a/lib/server.js +++ b/lib/server.js @@ -406,7 +406,20 @@ function Server (options) { const next = messageIIFE if (chain.handlers[i]) { return chain.handlers[i++].call(chain.backend, req, res, next) } - if (req.protocolOp === Protocol.LDAP_REQ_BIND && res.status === 0) { conn.ldap.bindDN = req.dn } + if (req.protocolOp === Protocol.LDAP_REQ_BIND && res.status === 0) { + // 0 length == anonymous bind + if (req.dn.rdns.length === 0 && req.credentials === '') { + conn.ldap.bindDN = new DN([new dn.RDN({ cn: 'anonymous' })]) + } else { + conn.ldap.bindDN = req.dn + } + } + + // unbind clear bindDN for safety + // conn should terminate on unbind (RFC4511 4.3) + if (req.protocolOp === Protocol.LDAP_REQ_UNBIND && res.status === 0) { + conn.ldap.bindDN = new DN([new dn.RDN({ cn: 'anonymous' })]) + } return after() } catch (e) { diff --git a/test/server.test.js b/test/server.test.js index 459cfa36..4c6d548a 100644 --- a/test/server.test.js +++ b/test/server.test.js @@ -204,6 +204,89 @@ tap.test('route unbind', function (t) { }) }) +tap.test('bind/unbind identity anonymous', function (t) { + const server = ldap.createServer({ + connectionRouter: function (c) { + server.newConnection(c) + server.emit('testconnection', c) + } + }) + + server.unbind(function (req, res, next) { + t.ok(true, 'server unbind successful') + res.end() + return next() + }) + + server.bind('', function (req, res, next) { + t.ok(true, 'server bind successful') + res.end() + return next() + }) + + const anonDN = ldap.dn.parse('cn=anonymous') + + server.listen(t.context.sock, function () { + t.ok(true, 'server startup') + + const client = ldap.createClient({ socketPath: t.context.sock }) + server.once('testconnection', (c) => { + t.ok(anonDN.equals(c.ldap.bindDN), 'pre bind dn is correct') + client.bind('', '', function (err) { + t.error(err, 'client anon bind error') + t.ok(anonDN.equals(c.ldap.bindDN), 'anon bind dn is correct') + client.unbind(function (err) { + t.error(err, 'client anon unbind error') + t.ok(anonDN.equals(c.ldap.bindDN), 'anon unbind dn is correct') + server.close(() => t.end()) + }) + }) + }) + }) +}) + +tap.test('bind/unbind identity user', function (t) { + const server = ldap.createServer({ + connectionRouter: function (c) { + server.newConnection(c) + server.emit('testconnection', c) + } + }) + + server.unbind(function (req, res, next) { + t.ok(true, 'server unbind successful') + res.end() + return next() + }) + + server.bind('', function (req, res, next) { + t.ok(true, 'server bind successful') + res.end() + return next() + }) + + const anonDN = ldap.dn.parse('cn=anonymous') + const testDN = ldap.dn.parse('cn=anotheruser') + + server.listen(t.context.sock, function () { + t.ok(true, 'server startup') + + const client = ldap.createClient({ socketPath: t.context.sock }) + server.once('testconnection', (c) => { + t.ok(anonDN.equals(c.ldap.bindDN), 'pre bind dn is correct') + client.bind(testDN.toString(), 'somesecret', function (err) { + t.error(err, 'user bind error') + t.ok(testDN.equals(c.ldap.bindDN), 'user unbind dn is correct') + client.unbind(function (err) { + t.error(err, 'user unbind error') + t.ok(anonDN.equals(c.ldap.bindDN), 'user unbind dn is correct') + server.close(() => t.end()) + }) + }) + }) + }) +}) + tap.test('strict routing', function (t) { const testDN = 'cn=valid' let clt From fae35237de19a8462869e3f2e173612e658ff8d1 Mon Sep 17 00:00:00 2001 From: Thomas Pressnell Date: Mon, 12 Jul 2021 16:24:01 +0100 Subject: [PATCH 2/3] adding rebind checks --- test/server.test.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/test/server.test.js b/test/server.test.js index 4c6d548a..a9fa6e47 100644 --- a/test/server.test.js +++ b/test/server.test.js @@ -276,11 +276,21 @@ tap.test('bind/unbind identity user', function (t) { t.ok(anonDN.equals(c.ldap.bindDN), 'pre bind dn is correct') client.bind(testDN.toString(), 'somesecret', function (err) { t.error(err, 'user bind error') - t.ok(testDN.equals(c.ldap.bindDN), 'user unbind dn is correct') - client.unbind(function (err) { - t.error(err, 'user unbind error') - t.ok(anonDN.equals(c.ldap.bindDN), 'user unbind dn is correct') - server.close(() => t.end()) + t.ok(testDN.equals(c.ldap.bindDN), 'user bind dn is correct') + // check rebinds too + client.bind('', '', function (err) { + t.error(err, 'client anon bind error') + t.ok(anonDN.equals(c.ldap.bindDN), 'anon bind dn is correct') + // user rebind + client.bind(testDN.toString(), 'somesecret', function (err) { + t.error(err, 'user bind error') + t.ok(testDN.equals(c.ldap.bindDN), 'user rebind dn is correct') + client.unbind(function (err) { + t.error(err, 'user unbind error') + t.ok(anonDN.equals(c.ldap.bindDN), 'user unbind dn is correct') + server.close(() => t.end()) + }) + }) }) }) }) From 5598feda6dc5786a72cf5e536b5e35c7a0bb1395 Mon Sep 17 00:00:00 2001 From: Thomas Pressnell Date: Mon, 12 Jul 2021 16:32:06 +0100 Subject: [PATCH 3/3] use getter --- lib/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/server.js b/lib/server.js index cbf110bf..c9f6aae6 100644 --- a/lib/server.js +++ b/lib/server.js @@ -408,7 +408,7 @@ function Server (options) { if (req.protocolOp === Protocol.LDAP_REQ_BIND && res.status === 0) { // 0 length == anonymous bind - if (req.dn.rdns.length === 0 && req.credentials === '') { + if (req.dn.length === 0 && req.credentials === '') { conn.ldap.bindDN = new DN([new dn.RDN({ cn: 'anonymous' })]) } else { conn.ldap.bindDN = req.dn