From b85c4acb4c2e95aeed27f8ddd477dd5f4de705d8 Mon Sep 17 00:00:00 2001 From: Thomas Pressnell Date: Mon, 12 Jul 2021 16:02:12 +0100 Subject: [PATCH] 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 74f2a67..cbf110b 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 459cfa3..4c6d548 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