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

Commit fb6816d

Browse files
authored
Merge pull request #750 from tpretz/fix/anonbind
2 parents b971204 + 4a3113f commit fb6816d

File tree

2 files changed

+107
-1
lines changed

2 files changed

+107
-1
lines changed

lib/server.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,20 @@ function Server (options) {
406406
const next = messageIIFE
407407
if (chain.handlers[i]) { return chain.handlers[i++].call(chain.backend, req, res, next) }
408408

409-
if (req.protocolOp === Protocol.LDAP_REQ_BIND && res.status === 0) { conn.ldap.bindDN = req.dn }
409+
if (req.protocolOp === Protocol.LDAP_REQ_BIND && res.status === 0) {
410+
// 0 length == anonymous bind
411+
if (req.dn.length === 0 && req.credentials === '') {
412+
conn.ldap.bindDN = new DN([new dn.RDN({ cn: 'anonymous' })])
413+
} else {
414+
conn.ldap.bindDN = req.dn
415+
}
416+
}
417+
418+
// unbind clear bindDN for safety
419+
// conn should terminate on unbind (RFC4511 4.3)
420+
if (req.protocolOp === Protocol.LDAP_REQ_UNBIND && res.status === 0) {
421+
conn.ldap.bindDN = new DN([new dn.RDN({ cn: 'anonymous' })])
422+
}
410423

411424
return after()
412425
} catch (e) {

test/server.test.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,99 @@ tap.test('route unbind', function (t) {
204204
})
205205
})
206206

207+
tap.test('bind/unbind identity anonymous', function (t) {
208+
const server = ldap.createServer({
209+
connectionRouter: function (c) {
210+
server.newConnection(c)
211+
server.emit('testconnection', c)
212+
}
213+
})
214+
215+
server.unbind(function (req, res, next) {
216+
t.ok(true, 'server unbind successful')
217+
res.end()
218+
return next()
219+
})
220+
221+
server.bind('', function (req, res, next) {
222+
t.ok(true, 'server bind successful')
223+
res.end()
224+
return next()
225+
})
226+
227+
const anonDN = ldap.dn.parse('cn=anonymous')
228+
229+
server.listen(t.context.sock, function () {
230+
t.ok(true, 'server startup')
231+
232+
const client = ldap.createClient({ socketPath: t.context.sock })
233+
server.once('testconnection', (c) => {
234+
t.ok(anonDN.equals(c.ldap.bindDN), 'pre bind dn is correct')
235+
client.bind('', '', function (err) {
236+
t.error(err, 'client anon bind error')
237+
t.ok(anonDN.equals(c.ldap.bindDN), 'anon bind dn is correct')
238+
client.unbind(function (err) {
239+
t.error(err, 'client anon unbind error')
240+
t.ok(anonDN.equals(c.ldap.bindDN), 'anon unbind dn is correct')
241+
server.close(() => t.end())
242+
})
243+
})
244+
})
245+
})
246+
})
247+
248+
tap.test('bind/unbind identity user', function (t) {
249+
const server = ldap.createServer({
250+
connectionRouter: function (c) {
251+
server.newConnection(c)
252+
server.emit('testconnection', c)
253+
}
254+
})
255+
256+
server.unbind(function (req, res, next) {
257+
t.ok(true, 'server unbind successful')
258+
res.end()
259+
return next()
260+
})
261+
262+
server.bind('', function (req, res, next) {
263+
t.ok(true, 'server bind successful')
264+
res.end()
265+
return next()
266+
})
267+
268+
const anonDN = ldap.dn.parse('cn=anonymous')
269+
const testDN = ldap.dn.parse('cn=anotheruser')
270+
271+
server.listen(t.context.sock, function () {
272+
t.ok(true, 'server startup')
273+
274+
const client = ldap.createClient({ socketPath: t.context.sock })
275+
server.once('testconnection', (c) => {
276+
t.ok(anonDN.equals(c.ldap.bindDN), 'pre bind dn is correct')
277+
client.bind(testDN.toString(), 'somesecret', function (err) {
278+
t.error(err, 'user bind error')
279+
t.ok(testDN.equals(c.ldap.bindDN), 'user bind dn is correct')
280+
// check rebinds too
281+
client.bind('', '', function (err) {
282+
t.error(err, 'client anon bind error')
283+
t.ok(anonDN.equals(c.ldap.bindDN), 'anon bind dn is correct')
284+
// user rebind
285+
client.bind(testDN.toString(), 'somesecret', function (err) {
286+
t.error(err, 'user bind error')
287+
t.ok(testDN.equals(c.ldap.bindDN), 'user rebind dn is correct')
288+
client.unbind(function (err) {
289+
t.error(err, 'user unbind error')
290+
t.ok(anonDN.equals(c.ldap.bindDN), 'user unbind dn is correct')
291+
server.close(() => t.end())
292+
})
293+
})
294+
})
295+
})
296+
})
297+
})
298+
})
299+
207300
tap.test('strict routing', function (t) {
208301
const testDN = 'cn=valid'
209302
let clt

0 commit comments

Comments
 (0)