Improve empty DN handling
- Use more strict comparisons for client input asserts - Fix baseObject comparison in SearchRequest initialization - Alter default error for server route fallthrough
This commit is contained in:
parent
19f2c16783
commit
ec062d370c
|
@ -407,7 +407,7 @@ Client.prototype.abandon = function abandon(messageID, controls, callback) {
|
||||||
* @throws {TypeError} on invalid input.
|
* @throws {TypeError} on invalid input.
|
||||||
*/
|
*/
|
||||||
Client.prototype.add = function add(name, entry, controls, callback) {
|
Client.prototype.add = function add(name, entry, controls, callback) {
|
||||||
assert.ok(name, 'name');
|
assert.ok(name !== undefined, 'name');
|
||||||
assert.object(entry, 'entry');
|
assert.object(entry, 'entry');
|
||||||
if (typeof (controls) === 'function') {
|
if (typeof (controls) === 'function') {
|
||||||
callback = controls;
|
callback = controls;
|
||||||
|
@ -500,7 +500,7 @@ Client.prototype.compare = function compare(name,
|
||||||
value,
|
value,
|
||||||
controls,
|
controls,
|
||||||
callback) {
|
callback) {
|
||||||
assert.ok(name, 'name');
|
assert.ok(name !== undefined, 'name');
|
||||||
assert.string(attr, 'attr');
|
assert.string(attr, 'attr');
|
||||||
assert.string(value, 'value');
|
assert.string(value, 'value');
|
||||||
if (typeof (controls) === 'function') {
|
if (typeof (controls) === 'function') {
|
||||||
|
@ -536,7 +536,7 @@ Client.prototype.compare = function compare(name,
|
||||||
* @throws {TypeError} on invalid input.
|
* @throws {TypeError} on invalid input.
|
||||||
*/
|
*/
|
||||||
Client.prototype.del = function del(name, controls, callback) {
|
Client.prototype.del = function del(name, controls, callback) {
|
||||||
assert.ok(name, 'name');
|
assert.ok(name !== undefined, 'name');
|
||||||
if (typeof (controls) === 'function') {
|
if (typeof (controls) === 'function') {
|
||||||
callback = controls;
|
callback = controls;
|
||||||
controls = [];
|
controls = [];
|
||||||
|
@ -609,7 +609,7 @@ Client.prototype.exop = function exop(name, value, controls, callback) {
|
||||||
* @throws {TypeError} on invalid input.
|
* @throws {TypeError} on invalid input.
|
||||||
*/
|
*/
|
||||||
Client.prototype.modify = function modify(name, change, controls, callback) {
|
Client.prototype.modify = function modify(name, change, controls, callback) {
|
||||||
assert.ok(name, 'name');
|
assert.ok(name !== undefined, 'name');
|
||||||
assert.object(change, 'change');
|
assert.object(change, 'change');
|
||||||
|
|
||||||
var changes = [];
|
var changes = [];
|
||||||
|
@ -691,7 +691,7 @@ Client.prototype.modifyDN = function modifyDN(name,
|
||||||
newName,
|
newName,
|
||||||
controls,
|
controls,
|
||||||
callback) {
|
callback) {
|
||||||
assert.ok(name, 'name');
|
assert.ok(name !== undefined, 'name');
|
||||||
assert.string(newName, 'newName');
|
assert.string(newName, 'newName');
|
||||||
if (typeof (controls) === 'function') {
|
if (typeof (controls) === 'function') {
|
||||||
callback = controls;
|
callback = controls;
|
||||||
|
@ -750,7 +750,7 @@ Client.prototype.search = function search(base,
|
||||||
controls,
|
controls,
|
||||||
callback,
|
callback,
|
||||||
_bypass) {
|
_bypass) {
|
||||||
assert.ok(base, 'base');
|
assert.ok(base !== undefined, 'search base');
|
||||||
if (Array.isArray(options) || (options instanceof Control)) {
|
if (Array.isArray(options) || (options instanceof Control)) {
|
||||||
controls = options;
|
controls = options;
|
||||||
options = {};
|
options = {};
|
||||||
|
|
|
@ -64,7 +64,11 @@ function SearchRequest(options) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.baseObject = options.baseObject || new DN([ {} ]);
|
if (options.baseObject !== undefined) {
|
||||||
|
this.baseObject = options.baseObject;
|
||||||
|
} else {
|
||||||
|
this.baseObject = dn.parse('');
|
||||||
|
}
|
||||||
this.scope = options.scope || 'base';
|
this.scope = options.scope || 'base';
|
||||||
this.derefAliases = options.derefAliases || Protocol.NEVER_DEREF_ALIASES;
|
this.derefAliases = options.derefAliases || Protocol.NEVER_DEREF_ALIASES;
|
||||||
this.sizeLimit = options.sizeLimit || 0;
|
this.sizeLimit = options.sizeLimit || 0;
|
||||||
|
|
|
@ -867,6 +867,9 @@ Server.prototype._getHandlerChain = function _getHandlerChain(req, res) {
|
||||||
backend: route.backend,
|
backend: route.backend,
|
||||||
handlers: route[op]
|
handlers: route[op]
|
||||||
};
|
};
|
||||||
|
} else {
|
||||||
|
if (suffix === '') {
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
// We found a valid suffix but not a valid operation.
|
// We found a valid suffix but not a valid operation.
|
||||||
// There might be a more generic suffix with a legitimate operation.
|
// There might be a more generic suffix with a legitimate operation.
|
||||||
|
@ -874,6 +877,7 @@ Server.prototype._getHandlerChain = function _getHandlerChain(req, res) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
backend: self,
|
backend: self,
|
||||||
handlers: fallbackHandler
|
handlers: fallbackHandler
|
||||||
|
|
|
@ -231,6 +231,23 @@ test('setup', function (t) {
|
||||||
next(new ldap.BusyError('too much to do'));
|
next(new ldap.BusyError('too much to do'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.search('', function (req, res, next) {
|
||||||
|
if (req.dn.toString() === '') {
|
||||||
|
res.send({
|
||||||
|
dn: '',
|
||||||
|
attributes: {
|
||||||
|
objectclass: ['RootDSE', 'top']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
res.end();
|
||||||
|
} else {
|
||||||
|
// Turn away any other requests (since '' is the fallthrough route)
|
||||||
|
res.errorMessage = 'No tree found for: ' + req.dn.toString();
|
||||||
|
res.end(ldap.LDAP_NO_SUCH_OBJECT);
|
||||||
|
}
|
||||||
|
return next();
|
||||||
|
});
|
||||||
|
|
||||||
server.unbind(function (req, res, next) {
|
server.unbind(function (req, res, next) {
|
||||||
res.end();
|
res.end();
|
||||||
return next();
|
return next();
|
||||||
|
@ -274,6 +291,7 @@ test('simple bind success', function (t) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('simple anonymous bind (empty credentials)', function (t) {
|
test('simple anonymous bind (empty credentials)', function (t) {
|
||||||
client.bind('', '', function (err, res) {
|
client.bind('', '', function (err, res) {
|
||||||
t.ifError(err);
|
t.ifError(err);
|
||||||
|
@ -283,6 +301,7 @@ test('simple anonymous bind (empty credentials)', function (t) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('auto-bind bad credentials', function (t) {
|
test('auto-bind bad credentials', function (t) {
|
||||||
var clt = ldap.createClient({
|
var clt = ldap.createClient({
|
||||||
socketPath: SOCKET,
|
socketPath: SOCKET,
|
||||||
|
@ -710,6 +729,29 @@ test('search referral', function (t) {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test('search rootDSE', function (t) {
|
||||||
|
client.search('', '(objectclass=*)', function (err, res) {
|
||||||
|
t.ifError(err);
|
||||||
|
t.ok(res);
|
||||||
|
res.on('searchEntry', function (entry) {
|
||||||
|
t.ok(entry);
|
||||||
|
t.equal(entry.dn.toString(), '');
|
||||||
|
t.ok(entry.attributes);
|
||||||
|
t.ok(entry.object);
|
||||||
|
});
|
||||||
|
res.on('error', function (err) {
|
||||||
|
t.fail(err);
|
||||||
|
});
|
||||||
|
res.on('end', function (res) {
|
||||||
|
t.ok(res);
|
||||||
|
t.ok(res instanceof ldap.SearchResponse);
|
||||||
|
t.equal(res.status, 0);
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
test('search empty attribute', function (t) {
|
test('search empty attribute', function (t) {
|
||||||
client.search('dc=empty', '(objectclass=*)', function (err, res) {
|
client.search('dc=empty', '(objectclass=*)', function (err, res) {
|
||||||
t.ifError(err);
|
t.ifError(err);
|
||||||
|
|
Loading…
Reference in New Issue