-
Notifications
You must be signed in to change notification settings - Fork 473
v3 server.search change scope names #845
Comments
Are you suggesting that the v2 values are not working? They should be according to the tests -- https://github.com/ldapjs/messages/blob/4c82e476d1749cd1b699c49f070dd95b8c0fa3cf/lib/messages/search-request.test.js#L187-L202 |
The v2 values would work. But with v3, server.search receives the v3 values as req.scope. server.search(SUFFIX, authorize, (req, res, next) => {
const dn = req.dn.toString();
...
...
switch (req.scope) {
case 'base':
...
case 'one':
case 'single:
...
case 'sub':
case 'subtree':
...
}
...
... |
I added a demo as attachment: inMem-ex.js.txt
Running with v3.0.0 the output is:
Running with v3.0.0 and implemented single and subtree the output is:
client.search entry: undefined is also a bit strange, but maybe because of the dummy data. example server'use strict';
const ldap = require('ldapjs');
// server part
const server = ldap.createServer();
const SUFFIX = '';
const db = {
"dc=domain,dc=tld": {
"objectClass": "domain",
"dc": "domain",
"entryDN": "dc=domain,dc=tld",
"namingContexts": "dc=domain,dc=tld",
"structuralObjectClass": "domain",
"subschemaSubentry": "cn=subschema",
"creatorsName": "uid=root,cn=users,dc=domain,dc=tld",
"modifiersName": "uid=root,cn=users,dc=domain,dc=tld"
},
"cn=users,dc=domain,dc=tld": {
"objectClass": "organizationalRole",
"cn": "users",
"entryDN": "cn=users,dc=domain,dc=tld",
"hasSubordinates": "TRUE",
"subschemaSubentry": "cn=subschema",
"creatorsName": "uid=root,cn=users,dc=domain,dc=tld",
"modifiersName": "uid=root,cn=users,dc=domain,dc=tld"
}
};
server.bind(SUFFIX, (req, res, next) => {
res.end();
return next();
});
server.search(SUFFIX, (req, res, next) => {
const dn = req.dn.toString().toLowerCase().replace(/ /g, '');
console.log('server.search', 'Search for => DN: ' + dn + '; Scope: ' + req.scope + '; Filter: ' + req.filter + '; Attributes: ' + req.attributes + ';');
if (!db[dn])
return next(new ldap.NoSuchObjectError(dn));
try {
let scopeCheck;
switch (req.scope) {
case 'base':
if (req.filter.matches(db[dn])) {
res.send({
dn: dn,
attributes: db[dn]
});
}
res.end();
return next();
case 'one':
//case 'single':
scopeCheck = (k) => {
if (req.dn.equals(k))
return true;
const parent = ldap.parseDN(k).parent();
return (parent ? parent.equals(req.dn) : false);
};
break;
case 'sub':
//case 'subtree':
scopeCheck = (k) => {
return (req.dn.equals(k) || req.dn.parentOf(k));
};
break;
}
const keys = Object.keys(db);
for (const key of keys) {
if (!scopeCheck(key))
continue;
if (req.filter.matches(db[dn])) {
res.send({
dn: key,
attributes: db[dn]
});
}
}
res.end();
return next();
}
catch (error) {
console.log("server.js", "server.search", error);
}
});
///--- Fire it up
server.listen(1389, "127.0.0.1", () => {
console.log('LDAP server up at: %s', server.url);
});
// Client part
const client = ldap.createClient({ url: ['ldap://127.0.0.1:1389'] });
const opts = {
filter: '(&(objectClass=*))',
scope: 'sub',
attributes: ['dn', 'namingContexts', 'dc']
};
client.search('dc=domain,dc=tld', opts, (err, res) => {
res.on('searchRequest', (searchRequest) => {
console.log('client.search', 'searchRequest: ', searchRequest.messageId);
});
res.on('searchEntry', (entry) => {
console.log('client.search', 'entry: ' + JSON.stringify(entry.object));
});
res.on('searchReference', (referral) => {
console.log('client.search', 'referral: ' + referral.uris.join());
});
res.on('error', (err) => {
console.error('client.search', 'error: ' + err.message);
});
res.on('end', (result) => {
console.log('client.search', 'status: ' + result.status);
});
}); |
This issue resolves issue #845 by updating `@ldapjs/messages` to the latest version and adding a test that shows how the module should be used to evaluate search request scopes.
This issue resolves issue #845 by updating `@ldapjs/messages` to the latest version and adding a test that shows how the module should be used to evaluate search request scopes.
Thank you for the example; it was a big help. I believe the original design was faulty. We replicated it without understanding how it was being used. The fix is shown in the adjusted example server below, and also in the unit test included in PR #847. Basically, such comparisons should be made against the actual scope constants. We changed how You should be able to update to the following releases to get the fixes:
I have also updated the v3.0.0 release notes to note the change in 3.0.0 and the recommended approach with 3.0.1 onward. example patch
modified example server'use strict';
const ldap = require('ldapjs');
const { SearchRequest } = require('@ldapjs/messages');
// server part
const server = ldap.createServer();
const SUFFIX = '';
const db = {
"dc=domain,dc=tld": {
"objectClass": "domain",
"dc": "domain",
"entryDN": "dc=domain,dc=tld",
"namingContexts": "dc=domain,dc=tld",
"structuralObjectClass": "domain",
"subschemaSubentry": "cn=subschema",
"creatorsName": "uid=root,cn=users,dc=domain,dc=tld",
"modifiersName": "uid=root,cn=users,dc=domain,dc=tld"
},
"cn=users,dc=domain,dc=tld": {
"objectClass": "organizationalRole",
"cn": "users",
"entryDN": "cn=users,dc=domain,dc=tld",
"hasSubordinates": "TRUE",
"subschemaSubentry": "cn=subschema",
"creatorsName": "uid=root,cn=users,dc=domain,dc=tld",
"modifiersName": "uid=root,cn=users,dc=domain,dc=tld"
}
};
server.bind(SUFFIX, (req, res, next) => {
res.end();
return next();
});
server.search(SUFFIX, (req, res, next) => {
const dn = req.dn.toString().toLowerCase().replace(/ /g, '');
console.log('server.search', 'Search for => DN: ' + dn + '; Scope: ' + req.scope + '; Filter: ' + req.filter + '; Attributes: ' + req.attributes + ';');
if (!db[dn])
return next(new ldap.NoSuchObjectError(dn));
try {
let scopeCheck;
switch (req.scope) {
case SearchRequest.SCOPE_BASE:
if (req.filter.matches(db[dn])) {
res.send({
dn: dn,
attributes: db[dn]
});
}
res.end();
return next();
case SearchRequest.SCOPE_SINGLE:
//case 'single':
scopeCheck = (k) => {
if (req.dn.equals(k))
return true;
const parent = ldap.parseDN(k).parent();
return (parent ? parent.equals(req.dn) : false);
};
break;
case SearchRequest.SCOPE_SUBTREE:
//case 'subtree':
scopeCheck = (k) => {
return (req.dn.equals(k) || req.dn.parentOf(k));
};
break;
}
const keys = Object.keys(db);
for (const key of keys) {
if (!scopeCheck(key))
continue;
if (req.filter.matches(db[dn])) {
res.send({
dn: key,
attributes: db[dn]
});
}
}
res.end();
return next();
}
catch (error) {
console.log("server.js", "server.search", error);
res.send(error)
}
});
///--- Fire it up
server.listen(1389, "127.0.0.1", () => {
console.log('LDAP server up at: %s', server.url);
}); |
Following the example of an in memory server server.search uses 3 scopes: base, one, sub
With v3 it looks like one is now single and sub is now called subtree. This looks like a breaking change for server implementations to me. The adjustment is of course made very quickly on server side code.
The text was updated successfully, but these errors were encountered: