diff --git a/bin/ldapjs-modify b/bin/ldapjs-modify new file mode 100755 index 0000000..00aae3c --- /dev/null +++ b/bin/ldapjs-modify @@ -0,0 +1,160 @@ +#!/usr/bin/env node +// -*- mode: js -*- +// Copyright 2011 Mark Cavage. All rights reserved. + +var fs = require('fs'); +var path = require('path'); +var url = require('url'); + +var log4js = require('log4js'); +var nopt = require('nopt'); + +var ldap = require('../lib/index'); + + + +///--- Globals + +nopt.typeDefs.DN = { + type: ldap.DN, + validate: function(data, k, val) { + data[k] = ldap.parseDN(val); + } +}; + +var opts = { + 'attribute': String, + 'debug': Number, + 'binddn': ldap.DN, + 'file': String, + 'password': String, + 'type': String, + 'url': url, + 'value': Array, +}; + +var shortOpts = { + 'a': ['--attribute'], + 'd': ['--debug'], + 'D': ['--binddn'], + 'f': ['--file'], + 'w': ['--password'], + 't': ['--type'], + 'u': ['--url'], + 'v': ['--value'] +}; + + + +///--- 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 += ' DN'; + + 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 + +log4js.setGlobalLogLevel('INFO'); +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, 'DN required'); +try { + parsed.argv.remain.forEach(function(dn) { + ldap.parseDN(dn); + }); +} catch (e) { + usage(1, e.toString()); +} + +if (!parsed.type) + parsed.type = 'replace'; +if (!parsed.attribute || !Array.isArray(parsed.value)) + usage(1, 'attribute and value required'); + +if (parsed.debug) + log4js.setGlobalLogLevel(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 = ''; + +var client = ldap.createClient({ + url: parsed.url, + log4js: log4js +}); + +client.on('error', function(err) { + perror(err); +}); + +client.bind(parsed.binddn, parsed.password, function(err, res) { + if (err) + perror(err); + + var finished = 0; + var mod = {}; + mod[parsed.attribute] = []; + parsed.value.forEach(function(v) { + mod[parsed.attribute].push(v); + }); + var change = new ldap.Change({ + type: parsed.type, + modification: mod + }); + + function callback() { + if (err) + perror(err); + + if (++finished === parsed.argv.remain.length) { + client.unbind(function() { + return; + }); + } + } + + parsed.argv.remain.forEach(function(dn) { + client.modify(dn, change, callback); + }); +});