node-ldapjs/bin/ldapjs-search

204 lines
4.0 KiB
JavaScript
Executable File

#!/usr/bin/env node
// -*- mode: js -*-
// Copyright 2011 Mark Cavage. All rights reserved.
var path = require('path');
var url = require('url');
var nopt = require('nopt');
var ldap = require('../lib/index');
var Logger = require('bunyan');
///--- Globals
nopt.typeDefs.DN = {
type: ldap.DN,
validate: function(data, k, val) {
data[k] = ldap.parseDN(val);
}
};
nopt.typeDefs.Filter = {
type: ldap.Filter,
validate: function(data, k, val) {
data[k] = ldap.parseFilter(val);
}
};
var opts = {
'debug': Number,
'base': ldap.DN,
'binddn': ldap.DN,
'control': Array,
'password': String,
'persistent': Boolean,
'paged': Number,
'scope': String,
'timeout': Number,
'url': url
};
var shortOpts = {
'c': ['--control'],
'd': ['--debug'],
'b': ['--base'],
'D': ['--binddn'],
'w': ['--password'],
'p': ['--persistent'],
'g': ['--paged'],
's': ['--scope'],
't': ['--timeout'],
'u': ['--url']
};
///--- Helpers
function usage(code, message) {
var _opts = '';
Object.keys(shortOpts).forEach(function(k) {
if (!Array.isArray(shortOpts[k]))
return;
var longOpt = shortOpts[k][0].replace('--', '');
var type = opts[longOpt].name || 'string';
if (type && type === 'boolean') type = '';
type = type.toLowerCase();
_opts += ' [--' + longOpt + ' ' + type + ']';
});
_opts += ' filter [attributes...]';
var msg = (message ? message + '\n' : '') +
'usage: ' + path.basename(process.argv[1]) + _opts;
process.stderr.write(msg + '\n');
process.exit(code);
}
function perror(err) {
if (parsed.debug) {
process.stderr.write(err.stack + '\n');
} else {
process.stderr.write(err.message + '\n');
}
process.exit(1);
}
///--- Mainline
var parsed;
try {
parsed = nopt(opts, shortOpts, process.argv, 2);
} catch (e) {
usage(1, e.toString());
}
if (parsed.help)
usage(0);
if (parsed.argv.remain.length < 1)
usage(1, 'filter required');
try {
ldap.parseFilter(parsed.argv.remain[0]);
} catch (e) {
usage(1, e.message);
}
var logLevel = 'info';
if (parsed.debug)
logLevel = (parsed.debug > 1 ? 'trace' : 'debug');
if (!parsed.url)
parsed.url = 'ldap://127.0.0.1:389';
if (!parsed.binddn)
parsed.binddn = '';
if (!parsed.password)
parsed.password = '';
if (!parsed.base)
parsed.base = '';
if (!parsed.control)
parsed.control = [];
if (!parsed.persistent)
parsed.persistent = false;
var log = new Logger({
name: 'ldapjs',
component: 'client',
stream: process.stderr,
level: logLevel
});
var client = ldap.createClient({
url: parsed.url,
log: log,
timeout: parsed.timeout || false
});
client.on('error', function(err) {
perror(err);
});
client.on('timeout', function(req) {
process.stderr.write('Timeout reached\n');
process.exit(1);
});
client.bind(parsed.binddn, parsed.password, function(err, res) {
if (err)
perror(err);
var controls = [];
parsed.control.forEach(function(c) {
controls.push(new ldap.Control({
type: c,
criticality: true
}));
});
if (parsed.persistent) {
var pCtrl = new ldap.PersistentSearchControl({
type: '2.16.840.1.113730.3.4.3',
value: {
changeTypes: 15,
changesOnly: false,
returnECs: true
}
});
controls.push(pCtrl);
}
if (parsed.paged) {
var ctrl = new ldap.PagedResultsControl({ value: { size: parsed.paged } });
controls.push(ctrl);
}
var req = {
scope: parsed.scope || 'sub',
filter: parsed.argv.remain[0],
attributes: parsed.argv.remain.length > 1 ? parsed.argv.remain.slice(1) : []
};
client.search(parsed.base, req, controls, function(err, res) {
if (err)
perror(err);
res.on('searchEntry', function(entry) {
process.stdout.write(JSON.stringify(entry.object, null, 2) + '\n');
});
res.on('error', function(err) {
perror(err);
});
res.on('end', function(res) {
if (res.status !== 0)
process.stderr.write(ldap.getMessage(res.status) + '\n');
client.unbind(function() {
return;
});
});
});
});