Skip to content
This repository has been archived by the owner on May 14, 2024. It is now read-only.

Commit

Permalink
Merge pull request #750 from tpretz/fix/anonbind
Browse files Browse the repository at this point in the history
  • Loading branch information
UziTech authored Aug 3, 2021
2 parents b971204 + 4a3113f commit fb6816d
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 1 deletion.
15 changes: 14 additions & 1 deletion lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.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) {
Expand Down
93 changes: 93 additions & 0 deletions test/server.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,99 @@ 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 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())
})
})
})
})
})
})
})

tap.test('strict routing', function (t) {
const testDN = 'cn=valid'
let clt
Expand Down

0 comments on commit fb6816d

Please sign in to comment.