#!/usr/bin/env node // -*- mode: js -*- // Copyright 2011 Mark Cavage. All rights reserved. var path = require('path'); var dashdash = require('dashdash'); var ldap = require('../lib/index'); var Logger = require('bunyan'); ///--- Globals dashdash.addOptionType({ name: 'ldap.DN', takesArg: true, helpArg: 'LDAP_DN', parseArg: function (option, optstr, arg) { return ldap.parseDN(arg); } }); dashdash.addOptionType({ name: 'ldap.Filter', takesArg: true, helpArg: 'LDAP_FILTER', parseArg: function (option, optstr, arg) { return ldap.parseFilter(arg); } }); dashdash.addOptionType({ name: 'ldap.scope', takesArg: true, helpArg: 'SCOPE', parseArg: function (option, optstr, arg) { if (!/^base|one|sub$/.test(arg)) { throw new TypeError('Scope must be '); } return arg; } }); var opts = [ { names: ['base', 'b'], type: 'ldap.DN', help: 'Base DN of search', default: '' }, { names: ['scope', 's'], type: 'ldap.scope', help: 'Search scope ', helpArg: 'SCOPE', default: 'sub' }, { names: ['timeout', 't'], type: 'integer', help: 'Search timeout', helpArg: 'SECS' }, { names: ['persistent', 'p'], type: 'bool', help: 'Enable persistent search control', default: false }, { names: ['paged', 'g'], type: 'number', help: 'Enable paged search result control', helpArg: 'PAGE_SIZE' }, { names: ['control', 'c'], type: 'arrayOfString', help: 'Send addition control OID', helpArg: 'OID', default: [] }, { group: 'General Options' }, { names: ['help', 'h'], type: 'bool', help: 'Print this help and exit.' }, { names: ['debug', 'd'], type: 'integer', help: 'Set debug level <0-2>', helpArg: 'LEVEL' }, { group: 'Connection Options' }, { names: ['url', 'u'], type: 'string', help: 'LDAP server URL', helpArg: 'URL', default: 'ldap://127.0.0.1:389' }, { names: ['binddn', 'D'], type: 'ldap.DN', help: 'Bind DN', default: '' }, { names: ['password', 'w'], type: 'string', help: 'Bind password', helpArg: 'PASSWD', default: '' }, { names: ['insecure', 'i'], type: 'bool', env: 'LDAPJS_TLS_INSECURE', help: 'Disable SSL certificate verification', default: false } ]; var parser = dashdash.createParser({options: opts}); ///--- Helpers function usage(code, message) { var msg = (message ? message + '\n' : '') + 'Usage: ' + path.basename(process.argv[1]) + ' [OPTIONS] FILTER [ATTRIBUTES...]\n\n' + parser.help({includeEnv: true}); 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 = parser.parse(process.argv); } catch (e) { usage(1, e.toString()); } if (parsed.help) usage(0); if (parsed._args.length < 1) usage(1, 'filter required'); try { ldap.parseFilter(parsed._args[0]); } catch (e) { usage(1, e.message); } var logLevel = 'info'; if (parsed.debug) logLevel = (parsed.debug > 1 ? 'trace' : 'debug'); 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, tlsOptions: { rejectUnauthorized: !parsed.insecure } }); 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._args[0], attributes: parsed._args.length > 1 ? parsed._args.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; }); }); }); });