2011-10-18 20:44:31 +00:00
|
|
|
#!/usr/bin/env node
|
|
|
|
// -*- mode: js -*-
|
|
|
|
// Copyright 2011 Mark Cavage. All rights reserved.
|
|
|
|
|
|
|
|
var fs = require('fs');
|
|
|
|
var path = require('path');
|
|
|
|
|
2014-06-18 22:56:13 +00:00
|
|
|
var dashdash = require('dashdash');
|
2011-10-18 20:44:31 +00:00
|
|
|
|
|
|
|
var ldap = require('../lib/index');
|
2013-04-24 18:45:19 +00:00
|
|
|
var Logger = require('bunyan');
|
2011-10-18 20:44:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
///--- Globals
|
|
|
|
|
2014-06-18 22:56:13 +00:00
|
|
|
dashdash.addOptionType({
|
|
|
|
name: 'ldap.DN',
|
|
|
|
takesArg: true,
|
|
|
|
helpArg: 'LDAP_DN',
|
|
|
|
parseArg: function (option, optstr, arg) {
|
|
|
|
return ldap.parseDN(arg);
|
2011-10-18 20:44:31 +00:00
|
|
|
}
|
2014-06-18 22:56:13 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
var opts = [
|
|
|
|
{
|
|
|
|
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: ['attribute', 'a'],
|
|
|
|
type: 'string',
|
|
|
|
help: 'Attribute to modify',
|
|
|
|
helpArg: 'ATTR'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
names: ['value', 'v'],
|
|
|
|
type: 'string',
|
|
|
|
help: 'Desired value',
|
|
|
|
helpArg: 'VAL'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
names: ['type', 't'],
|
|
|
|
type: 'string',
|
|
|
|
help: 'Attribute type',
|
|
|
|
helpArg: 'TYPE'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
names: ['insecure', 'i'],
|
|
|
|
type: 'bool',
|
|
|
|
env: 'LDAPJS_TLS_INSECURE',
|
|
|
|
help: 'Disable SSL certificate verification',
|
|
|
|
default: false
|
|
|
|
},
|
|
|
|
{
|
|
|
|
names: ['debug', 'd'],
|
|
|
|
type: 'integer',
|
|
|
|
help: 'Set debug level <0-2>',
|
|
|
|
helpArg: 'LEVEL'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
names: ['help', 'h'],
|
|
|
|
type: 'bool',
|
|
|
|
help: 'Print this help and exit.'
|
|
|
|
}
|
|
|
|
];
|
|
|
|
var parser = dashdash.createParser({options: opts});
|
2011-10-18 20:44:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///--- Helpers
|
|
|
|
|
|
|
|
function usage(code, message) {
|
2014-06-18 22:56:13 +00:00
|
|
|
var _opts = parser.help();
|
2011-10-18 20:44:31 +00:00
|
|
|
|
|
|
|
var msg = (message ? message + '\n' : '') +
|
2014-06-18 22:56:13 +00:00
|
|
|
'usage: ' + path.basename(process.argv[1]) + ' <arguments> <DN>\n' + _opts;
|
2011-10-18 20:44:31 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2013-04-24 18:45:19 +00:00
|
|
|
var logLevel = 'info';
|
2011-10-18 20:44:31 +00:00
|
|
|
var parsed;
|
|
|
|
|
|
|
|
try {
|
2014-06-18 22:56:13 +00:00
|
|
|
parsed = parser.parse(process.argv);
|
2011-10-18 20:44:31 +00:00
|
|
|
} catch (e) {
|
|
|
|
usage(1, e.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parsed.help)
|
|
|
|
usage(0);
|
|
|
|
|
2014-06-18 22:56:13 +00:00
|
|
|
if (parsed._args.length < 1)
|
2011-10-18 20:44:31 +00:00
|
|
|
usage(1, 'DN required');
|
|
|
|
try {
|
2014-06-18 22:56:13 +00:00
|
|
|
parsed._args.forEach(function (dn) {
|
2011-10-18 20:44:31 +00:00
|
|
|
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)
|
2013-04-24 18:45:19 +00:00
|
|
|
logLevel = (parsed.debug > 1 ? 'trace' : 'debug');
|
2011-10-18 20:44:31 +00:00
|
|
|
|
2013-04-24 18:45:19 +00:00
|
|
|
var log = new Logger({
|
|
|
|
name: 'ldapjs',
|
|
|
|
component: 'client',
|
|
|
|
stream: process.stderr,
|
|
|
|
level: logLevel
|
|
|
|
});
|
|
|
|
|
2011-10-18 20:44:31 +00:00
|
|
|
var client = ldap.createClient({
|
|
|
|
url: parsed.url,
|
2014-04-23 00:46:14 +00:00
|
|
|
log: log,
|
|
|
|
tlsOptions: {
|
|
|
|
rejectUnauthorized: !parsed.insecure
|
|
|
|
}
|
2011-10-18 20:44:31 +00:00
|
|
|
});
|
|
|
|
|
2014-06-18 22:56:13 +00:00
|
|
|
client.on('error', function (err) {
|
2011-10-18 20:44:31 +00:00
|
|
|
perror(err);
|
|
|
|
});
|
|
|
|
|
2014-06-18 22:56:13 +00:00
|
|
|
client.bind(parsed.binddn, parsed.password, function (err, res) {
|
2011-10-18 20:44:31 +00:00
|
|
|
if (err)
|
|
|
|
perror(err);
|
|
|
|
|
|
|
|
var finished = 0;
|
|
|
|
var mod = {};
|
|
|
|
mod[parsed.attribute] = [];
|
2014-06-18 22:56:13 +00:00
|
|
|
parsed.value.forEach(function (v) {
|
2011-10-18 20:44:31 +00:00
|
|
|
mod[parsed.attribute].push(v);
|
|
|
|
});
|
|
|
|
var change = new ldap.Change({
|
|
|
|
type: parsed.type,
|
|
|
|
modification: mod
|
|
|
|
});
|
|
|
|
|
2011-10-18 20:49:48 +00:00
|
|
|
function callback(err) {
|
2011-10-18 20:44:31 +00:00
|
|
|
if (err)
|
|
|
|
perror(err);
|
|
|
|
|
2014-06-18 22:56:13 +00:00
|
|
|
if (++finished === parsed._args.length) {
|
|
|
|
client.unbind(function () {
|
2011-10-18 20:44:31 +00:00
|
|
|
return;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-18 22:56:13 +00:00
|
|
|
parsed._args.forEach(function (dn) {
|
2011-10-18 20:44:31 +00:00
|
|
|
client.modify(dn, change, callback);
|
|
|
|
});
|
|
|
|
});
|