Documentation and makefile
This commit is contained in:
parent
e87550ff57
commit
17d2d4e5cb
|
@ -1,3 +1,5 @@
|
|||
node_modules
|
||||
*.log
|
||||
*.ldif
|
||||
*.tar*
|
||||
docs/pkg
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
NAME=ldapjs
|
||||
|
||||
ifeq ($(VERSION), "")
|
||||
@echo "Use gmake"
|
||||
endif
|
||||
|
||||
|
||||
SRC := $(shell pwd)
|
||||
TAR = tar
|
||||
UNAME := $(shell uname)
|
||||
ifeq ($(UNAME), SunOS)
|
||||
TAR = gtar
|
||||
endif
|
||||
|
||||
HAVE_GJSLINT := $(shell which gjslint >/dev/null && echo yes || echo no)
|
||||
NPM := npm_config_tar=$(TAR) npm
|
||||
|
||||
RESTDOWN = ./node_modules/.restdown/bin/restdown
|
||||
RESTDOWN_VERSION=1.2.11
|
||||
DOCPKGDIR = ./docs/pkg
|
||||
|
||||
.PHONY: dep lint test doc clean all
|
||||
|
||||
all:: test doc
|
||||
|
||||
node_modules/.ldapjs.npm.installed:
|
||||
$(NPM) install --dev
|
||||
if [[ ! -d node_modules/.restdown ]]; then \
|
||||
git clone git://github.com/trentm/restdown.git node_modules/.restdown; \
|
||||
else \
|
||||
(cd node_modules/.restdown && git fetch origin); \
|
||||
fi
|
||||
@(cd ./node_modules/.restdown && git checkout $(RESTDOWN_VERSION))
|
||||
@touch ./node_modules/.ldapjs.npm.installed
|
||||
|
||||
dep: ./node_modules/.ldapjs.npm.installed
|
||||
|
||||
gjslint:
|
||||
gjslint --nojsdoc -r lib -r tst
|
||||
|
||||
ifeq ($(HAVE_GJSLINT), yes)
|
||||
lint: gjslint
|
||||
else
|
||||
lint:
|
||||
@echo "* * *"
|
||||
@echo "* Warning: Cannot lint with gjslint. Install it from:"
|
||||
@echo "* http://code.google.com/closure/utilities/docs/linter_howto.html"
|
||||
@echo "* * *"
|
||||
endif
|
||||
|
||||
doc: dep
|
||||
@rm -rf ${DOCPKGDIR}
|
||||
@mkdir -p ${DOCPKGDIR}
|
||||
${RESTDOWN} -m ${DOCPKGDIR} -D mediaroot=media ./docs/guide.md
|
||||
rm docs/*.json
|
||||
mv docs/*.html ${DOCPKGDIR}
|
||||
sed -i '' -e 's|docs/public/media|media|g' ${DOCPKGDIR}/*.html
|
||||
(cd ${DOCPKGDIR} && $(TAR) -czf ${SRC}/${NAME}-docs-`git log -1 --pretty='format:%h'`.tar.gz *)
|
||||
|
||||
|
||||
test: dep lint
|
||||
$(NPM) test
|
||||
|
||||
clean:
|
||||
@rm -fr ${DOCPKGDIR} node_modules *.log
|
350
docs/guide.md
350
docs/guide.md
|
@ -28,12 +28,12 @@ basically breaks down as follows:
|
|||
|
||||
It might be helpful to visualize that:
|
||||
|
||||
o=example
|
||||
/ \
|
||||
ou=users ou=groups
|
||||
/ | | \
|
||||
cn=john cn=jane cn=dudes cn=dudettes
|
||||
/
|
||||
o=example
|
||||
/ \
|
||||
ou=users ou=groups
|
||||
/ | | \
|
||||
cn=john cn=jane cn=dudes cn=dudettes
|
||||
/
|
||||
keyid=foo
|
||||
|
||||
|
||||
|
@ -187,8 +187,8 @@ Blah blah, let's try running the ldap client again, first with a bad password:
|
|||
$ ldapsearch -H ldap://localhost:1389 -x -D cn=root -w foo -b "o=myhost" objectclass=*
|
||||
|
||||
ldap_bind: Invalid credentials (49)
|
||||
matched DN: cn=root
|
||||
additional info: Invalid Credentials
|
||||
matched DN: cn=root
|
||||
additional info: Invalid Credentials
|
||||
|
||||
And again with the correct one:
|
||||
|
||||
|
@ -212,7 +212,7 @@ authorization handler that we'll use in all our subsequent routes:
|
|||
|
||||
function authorize(req, res, next) {
|
||||
if (!req.connection.ldap.bindDN.equals('cn=root'))
|
||||
return next(new ldap.InsufficientAccessRightsError());
|
||||
return next(new ldap.InsufficientAccessRightsError());
|
||||
|
||||
return next();
|
||||
}
|
||||
|
@ -249,35 +249,35 @@ First, let's make a handler that just loads the "user database" for us in a
|
|||
|
||||
function loadPasswdFile(req, res, next) {
|
||||
fs.readFile('/etc/passwd', 'utf8', function(err, data) {
|
||||
if (err)
|
||||
return next(new ldap.OperationsError(err.message));
|
||||
if (err)
|
||||
return next(new ldap.OperationsError(err.message));
|
||||
|
||||
req.users = {};
|
||||
req.users = {};
|
||||
|
||||
var lines = data.split('\n');
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (!lines[i] || /^#/.test(lines[i]))
|
||||
continue;
|
||||
var lines = data.split('\n');
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (!lines[i] || /^#/.test(lines[i]))
|
||||
continue;
|
||||
|
||||
var record = lines[i].split(':');
|
||||
if (!record || !record.length)
|
||||
continue;
|
||||
var record = lines[i].split(':');
|
||||
if (!record || !record.length)
|
||||
continue;
|
||||
|
||||
req.users[record[0]] = {
|
||||
dn: 'cn=' + record[0] + ', ou=users, o=myhost',
|
||||
attributes: {
|
||||
cn: record[0],
|
||||
uid: record[2],
|
||||
gid: record[3],
|
||||
description: record[4],
|
||||
homedirectory: record[5],
|
||||
shell: record[6] || '',
|
||||
objectclass: 'unixUser'
|
||||
}
|
||||
};
|
||||
}
|
||||
req.users[record[0]] = {
|
||||
dn: 'cn=' + record[0] + ', ou=users, o=myhost',
|
||||
attributes: {
|
||||
cn: record[0],
|
||||
uid: record[2],
|
||||
gid: record[3],
|
||||
description: record[4],
|
||||
homedirectory: record[5],
|
||||
shell: record[6] || '',
|
||||
objectclass: 'unixUser'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return next();
|
||||
return next();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -289,8 +289,8 @@ handler to process that:
|
|||
|
||||
server.search('o=myhost', pre, function(req, res, next) {
|
||||
Object.keys(req.users).forEach(function(k) {
|
||||
if (req.filter.matches(req.users[k].attributes))
|
||||
res.send(req.users[k]);
|
||||
if (req.filter.matches(req.users[k].attributes))
|
||||
res.send(req.users[k]);
|
||||
});
|
||||
|
||||
res.end();
|
||||
|
@ -357,13 +357,13 @@ of attributes. So that's why we did this:
|
|||
var entry = {
|
||||
dn: 'cn=' + record[0] + ', ou=users, o=myhost',
|
||||
attributes: {
|
||||
cn: record[0],
|
||||
uid: record[2],
|
||||
gid: record[3],
|
||||
description: record[4],
|
||||
homedirectory: record[5],
|
||||
shell: record[6] || '',
|
||||
objectclass: 'unixUser'
|
||||
cn: record[0],
|
||||
uid: record[2],
|
||||
gid: record[3],
|
||||
description: record[4],
|
||||
homedirectory: record[5],
|
||||
shell: record[6] || '',
|
||||
objectclass: 'unixUser'
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -398,36 +398,36 @@ the following code in as another handler (you'll need a
|
|||
|
||||
server.add('ou=users, o=myhost', pre, function(req, res, next) {
|
||||
if (!req.dn.rdns[0].cn)
|
||||
return next(new ldap.ConstraintViolationError('cn required'));
|
||||
return next(new ldap.ConstraintViolationError('cn required'));
|
||||
|
||||
if (req.users[req.dn.rdns[0].cn])
|
||||
return next(new ldap.EntryAlreadyExistsError(req.dn.toString()));
|
||||
return next(new ldap.EntryAlreadyExistsError(req.dn.toString()));
|
||||
|
||||
var entry = req.toObject().attributes;
|
||||
|
||||
if (entry.objectclass.indexOf('unixUser') === -1)
|
||||
return next(new ldap.ConstraintViolation('entry must be a unixUser'));
|
||||
return next(new ldap.ConstraintViolation('entry must be a unixUser'));
|
||||
|
||||
var opts = ['-m'];
|
||||
if (entry.description) {
|
||||
opts.push('-c');
|
||||
opts.push(entry.description[0]);
|
||||
opts.push('-c');
|
||||
opts.push(entry.description[0]);
|
||||
}
|
||||
if (entry.homedirectory) {
|
||||
opts.push('-d');
|
||||
opts.push(entry.homedirectory[0]);
|
||||
opts.push('-d');
|
||||
opts.push(entry.homedirectory[0]);
|
||||
}
|
||||
if (entry.gid) {
|
||||
opts.push('-g');
|
||||
opts.push(entry.gid[0]);
|
||||
opts.push('-g');
|
||||
opts.push(entry.gid[0]);
|
||||
}
|
||||
if (entry.shell) {
|
||||
opts.push('-s');
|
||||
opts.push(entry.shell[0]);
|
||||
opts.push('-s');
|
||||
opts.push(entry.shell[0]);
|
||||
}
|
||||
if (entry.uid) {
|
||||
opts.push('-u');
|
||||
opts.push(entry.uid[0]);
|
||||
opts.push('-u');
|
||||
opts.push(entry.uid[0]);
|
||||
}
|
||||
opts.push(entry.cn[0]);
|
||||
var useradd = spawn('useradd', opts);
|
||||
|
@ -435,22 +435,22 @@ the following code in as another handler (you'll need a
|
|||
var messages = [];
|
||||
|
||||
useradd.stdout.on('data', function(data) {
|
||||
messages.push(data.toString());
|
||||
messages.push(data.toString());
|
||||
});
|
||||
useradd.stderr.on('data', function(data) {
|
||||
messages.push(data.toString());
|
||||
messages.push(data.toString());
|
||||
});
|
||||
|
||||
useradd.on('exit', function(code) {
|
||||
if (code !== 0) {
|
||||
var msg = '' + code;
|
||||
if (messages.length)
|
||||
msg += ': ' + messages.join();
|
||||
return next(new ldap.OperationsError(msg));
|
||||
}
|
||||
if (code !== 0) {
|
||||
var msg = '' + code;
|
||||
if (messages.length)
|
||||
msg += ': ' + messages.join();
|
||||
return next(new ldap.OperationsError(msg));
|
||||
}
|
||||
|
||||
res.end();
|
||||
return next();
|
||||
res.end();
|
||||
return next();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -485,15 +485,15 @@ As before, here's a breakdown of the code:
|
|||
|
||||
server.add('ou=users, o=myhost', pre, function(req, res, next) {
|
||||
if (!req.dn.rdns[0].cn)
|
||||
return next(new ldap.ConstraintViolationError('cn required'));
|
||||
return next(new ldap.ConstraintViolationError('cn required'));
|
||||
|
||||
if (req.users[req.dn.rdns[0].cn])
|
||||
return next(new ldap.EntryAlreadyExistsError(req.dn.toString()));
|
||||
return next(new ldap.EntryAlreadyExistsError(req.dn.toString()));
|
||||
|
||||
var entry = req.toObject().attributes;
|
||||
|
||||
if (entry.objectclass.indexOf('unixUser') === -1)
|
||||
return next(new ldap.ConstraintViolation('entry must be a unixUser'));
|
||||
return next(new ldap.ConstraintViolation('entry must be a unixUser'));
|
||||
|
||||
Here's a few new things:
|
||||
|
||||
|
@ -530,37 +530,37 @@ Go ahead and add the following code into your source file:
|
|||
|
||||
server.modify('ou=users, o=myhost', pre, function(req, res, next) {
|
||||
if (!req.dn.rdns[0].cn || !req.users[req.dn.rdns[0].cn])
|
||||
return next(new ldap.NoSuchObjectError(req.dn.toString()));
|
||||
return next(new ldap.NoSuchObjectError(req.dn.toString()));
|
||||
|
||||
if (!req.changes.length)
|
||||
return next(new ldap.ProtocolError('changes required'));
|
||||
return next(new ldap.ProtocolError('changes required'));
|
||||
|
||||
var user = req.users[req.dn.rdns[0].cn].attributes;
|
||||
var mod;
|
||||
|
||||
for (var i = 0; i < req.changes.length; i++) {
|
||||
mod = req.changes[i].modification;
|
||||
switch (req.changes[i].operation) {
|
||||
case 'replace':
|
||||
if (mod.type !== 'userpassword' || !mod.vals || !mod.vals.length)
|
||||
return next(new ldap.UnwillingToPerformError('only password updates ' +
|
||||
'allowed'));
|
||||
break;
|
||||
case 'add':
|
||||
case 'delete':
|
||||
return next(new ldap.UnwillingToPerformError('only replace allowed'));
|
||||
}
|
||||
mod = req.changes[i].modification;
|
||||
switch (req.changes[i].operation) {
|
||||
case 'replace':
|
||||
if (mod.type !== 'userpassword' || !mod.vals || !mod.vals.length)
|
||||
return next(new ldap.UnwillingToPerformError('only password updates ' +
|
||||
'allowed'));
|
||||
break;
|
||||
case 'add':
|
||||
case 'delete':
|
||||
return next(new ldap.UnwillingToPerformError('only replace allowed'));
|
||||
}
|
||||
}
|
||||
|
||||
var passwd = spawn('chpasswd', ['-c', 'MD5']);
|
||||
passwd.stdin.end(user.cn + ':' + mod.vals[0], 'utf8');
|
||||
|
||||
passwd.on('exit', function(code) {
|
||||
if (code !== 0)
|
||||
return next(new ldap.OperationsError(code));
|
||||
if (code !== 0)
|
||||
return next(new ldap.OperationsError(code));
|
||||
|
||||
res.end();
|
||||
return next();
|
||||
res.end();
|
||||
return next();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -592,28 +592,28 @@ delete it :). Go ahead and add the following code into your server:
|
|||
|
||||
server.del('ou=users, o=myhost', pre, function(req, res, next) {
|
||||
if (!req.dn.rdns[0].cn || !req.users[req.dn.rdns[0].cn])
|
||||
return next(new ldap.NoSuchObjectError(req.dn.toString()));
|
||||
return next(new ldap.NoSuchObjectError(req.dn.toString()));
|
||||
|
||||
var userdel = spawn('userdel', ['-f', req.dn.rdns[0].cn]);
|
||||
|
||||
var messages = [];
|
||||
userdel.stdout.on('data', function(data) {
|
||||
messages.push(data.toString());
|
||||
messages.push(data.toString());
|
||||
});
|
||||
userdel.stderr.on('data', function(data) {
|
||||
messages.push(data.toString());
|
||||
messages.push(data.toString());
|
||||
});
|
||||
|
||||
userdel.on('exit', function(code) {
|
||||
if (code !== 0) {
|
||||
var msg = '' + code;
|
||||
if (messages.length)
|
||||
msg += ': ' + messages.join();
|
||||
return next(new ldap.OperationsError(msg));
|
||||
}
|
||||
if (code !== 0) {
|
||||
var msg = '' + code;
|
||||
if (messages.length)
|
||||
msg += ': ' + messages.join();
|
||||
return next(new ldap.OperationsError(msg));
|
||||
}
|
||||
|
||||
res.end();
|
||||
return next();
|
||||
res.end();
|
||||
return next();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -638,7 +638,7 @@ the complete implementation for what we went through above:
|
|||
|
||||
function authorize(req, res, next) {
|
||||
if (!req.connection.ldap.bindDN.equals('cn=root'))
|
||||
return next(new ldap.InsufficientAccessRightsError());
|
||||
return next(new ldap.InsufficientAccessRightsError());
|
||||
|
||||
return next();
|
||||
}
|
||||
|
@ -646,35 +646,35 @@ the complete implementation for what we went through above:
|
|||
|
||||
function loadPasswdFile(req, res, next) {
|
||||
fs.readFile('/etc/passwd', 'utf8', function(err, data) {
|
||||
if (err)
|
||||
return next(new ldap.OperationsError(err.message));
|
||||
if (err)
|
||||
return next(new ldap.OperationsError(err.message));
|
||||
|
||||
req.users = {};
|
||||
req.users = {};
|
||||
|
||||
var lines = data.split('\n');
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (!lines[i] || /^#/.test(lines[i]))
|
||||
continue;
|
||||
var lines = data.split('\n');
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (!lines[i] || /^#/.test(lines[i]))
|
||||
continue;
|
||||
|
||||
var record = lines[i].split(':');
|
||||
if (!record || !record.length)
|
||||
continue;
|
||||
var record = lines[i].split(':');
|
||||
if (!record || !record.length)
|
||||
continue;
|
||||
|
||||
req.users[record[0]] = {
|
||||
dn: 'cn=' + record[0] + ', ou=users, o=myhost',
|
||||
attributes: {
|
||||
cn: record[0],
|
||||
uid: record[2],
|
||||
gid: record[3],
|
||||
description: record[4],
|
||||
homedirectory: record[5],
|
||||
shell: record[6] || '',
|
||||
objectclass: 'unixUser'
|
||||
}
|
||||
};
|
||||
}
|
||||
req.users[record[0]] = {
|
||||
dn: 'cn=' + record[0] + ', ou=users, o=myhost',
|
||||
attributes: {
|
||||
cn: record[0],
|
||||
uid: record[2],
|
||||
gid: record[3],
|
||||
description: record[4],
|
||||
homedirectory: record[5],
|
||||
shell: record[6] || '',
|
||||
objectclass: 'unixUser'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return next();
|
||||
return next();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -689,7 +689,7 @@ the complete implementation for what we went through above:
|
|||
|
||||
server.bind('cn=root', function(req, res, next) {
|
||||
if (req.dn.toString() !== 'cn=root' || req.credentials !== 'secret')
|
||||
return next(new ldap.InvalidCredentialsError());
|
||||
return next(new ldap.InvalidCredentialsError());
|
||||
|
||||
res.end();
|
||||
return next();
|
||||
|
@ -698,36 +698,36 @@ the complete implementation for what we went through above:
|
|||
|
||||
server.add('ou=users, o=myhost', pre, function(req, res, next) {
|
||||
if (!req.dn.rdns[0].cn)
|
||||
return next(new ldap.ConstraintViolationError('cn required'));
|
||||
return next(new ldap.ConstraintViolationError('cn required'));
|
||||
|
||||
if (req.users[req.dn.rdns[0].cn])
|
||||
return next(new ldap.EntryAlreadyExistsError(req.dn.toString()));
|
||||
return next(new ldap.EntryAlreadyExistsError(req.dn.toString()));
|
||||
|
||||
var entry = req.toObject().attributes;
|
||||
|
||||
if (entry.objectclass.indexOf('unixUser') === -1)
|
||||
return next(new ldap.ConstraintViolation('entry must be a unixUser'));
|
||||
return next(new ldap.ConstraintViolation('entry must be a unixUser'));
|
||||
|
||||
var opts = ['-m'];
|
||||
if (entry.description) {
|
||||
opts.push('-c');
|
||||
opts.push(entry.description[0]);
|
||||
opts.push('-c');
|
||||
opts.push(entry.description[0]);
|
||||
}
|
||||
if (entry.homedirectory) {
|
||||
opts.push('-d');
|
||||
opts.push(entry.homedirectory[0]);
|
||||
opts.push('-d');
|
||||
opts.push(entry.homedirectory[0]);
|
||||
}
|
||||
if (entry.gid) {
|
||||
opts.push('-g');
|
||||
opts.push(entry.gid[0]);
|
||||
opts.push('-g');
|
||||
opts.push(entry.gid[0]);
|
||||
}
|
||||
if (entry.shell) {
|
||||
opts.push('-s');
|
||||
opts.push(entry.shell[0]);
|
||||
opts.push('-s');
|
||||
opts.push(entry.shell[0]);
|
||||
}
|
||||
if (entry.uid) {
|
||||
opts.push('-u');
|
||||
opts.push(entry.uid[0]);
|
||||
opts.push('-u');
|
||||
opts.push(entry.uid[0]);
|
||||
}
|
||||
opts.push(entry.cn[0]);
|
||||
var useradd = spawn('useradd', opts);
|
||||
|
@ -735,95 +735,95 @@ the complete implementation for what we went through above:
|
|||
var messages = [];
|
||||
|
||||
useradd.stdout.on('data', function(data) {
|
||||
messages.push(data.toString());
|
||||
messages.push(data.toString());
|
||||
});
|
||||
useradd.stderr.on('data', function(data) {
|
||||
messages.push(data.toString());
|
||||
messages.push(data.toString());
|
||||
});
|
||||
|
||||
useradd.on('exit', function(code) {
|
||||
if (code !== 0) {
|
||||
var msg = '' + code;
|
||||
if (messages.length)
|
||||
msg += ': ' + messages.join();
|
||||
return next(new ldap.OperationsError(msg));
|
||||
}
|
||||
if (code !== 0) {
|
||||
var msg = '' + code;
|
||||
if (messages.length)
|
||||
msg += ': ' + messages.join();
|
||||
return next(new ldap.OperationsError(msg));
|
||||
}
|
||||
|
||||
res.end();
|
||||
return next();
|
||||
res.end();
|
||||
return next();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
server.modify('ou=users, o=myhost', pre, function(req, res, next) {
|
||||
if (!req.dn.rdns[0].cn || !req.users[req.dn.rdns[0].cn])
|
||||
return next(new ldap.NoSuchObjectError(req.dn.toString()));
|
||||
return next(new ldap.NoSuchObjectError(req.dn.toString()));
|
||||
|
||||
if (!req.changes.length)
|
||||
return next(new ldap.ProtocolError('changes required'));
|
||||
return next(new ldap.ProtocolError('changes required'));
|
||||
|
||||
var user = req.users[req.dn.rdns[0].cn].attributes;
|
||||
var mod;
|
||||
|
||||
for (var i = 0; i < req.changes.length; i++) {
|
||||
mod = req.changes[i].modification;
|
||||
switch (req.changes[i].operation) {
|
||||
case 'replace':
|
||||
if (mod.type !== 'userpassword' || !mod.vals || !mod.vals.length)
|
||||
return next(new ldap.UnwillingToPerformError('only password updates ' +
|
||||
'allowed'));
|
||||
break;
|
||||
case 'add':
|
||||
case 'delete':
|
||||
return next(new ldap.UnwillingToPerformError('only replace allowed'));
|
||||
}
|
||||
mod = req.changes[i].modification;
|
||||
switch (req.changes[i].operation) {
|
||||
case 'replace':
|
||||
if (mod.type !== 'userpassword' || !mod.vals || !mod.vals.length)
|
||||
return next(new ldap.UnwillingToPerformError('only password updates ' +
|
||||
'allowed'));
|
||||
break;
|
||||
case 'add':
|
||||
case 'delete':
|
||||
return next(new ldap.UnwillingToPerformError('only replace allowed'));
|
||||
}
|
||||
}
|
||||
|
||||
var passwd = spawn('chpasswd', ['-c', 'MD5']);
|
||||
passwd.stdin.end(user.cn + ':' + mod.vals[0], 'utf8');
|
||||
|
||||
passwd.on('exit', function(code) {
|
||||
if (code !== 0)
|
||||
return next(new ldap.OperationsError('' + code));
|
||||
if (code !== 0)
|
||||
return next(new ldap.OperationsError('' + code));
|
||||
|
||||
res.end();
|
||||
return next();
|
||||
res.end();
|
||||
return next();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
server.del('ou=users, o=myhost', pre, function(req, res, next) {
|
||||
if (!req.dn.rdns[0].cn || !req.users[req.dn.rdns[0].cn])
|
||||
return next(new ldap.NoSuchObjectError(req.dn.toString()));
|
||||
return next(new ldap.NoSuchObjectError(req.dn.toString()));
|
||||
|
||||
var userdel = spawn('userdel', ['-f', req.dn.rdns[0].cn]);
|
||||
|
||||
var messages = [];
|
||||
userdel.stdout.on('data', function(data) {
|
||||
messages.push(data.toString());
|
||||
messages.push(data.toString());
|
||||
});
|
||||
userdel.stderr.on('data', function(data) {
|
||||
messages.push(data.toString());
|
||||
messages.push(data.toString());
|
||||
});
|
||||
|
||||
userdel.on('exit', function(code) {
|
||||
if (code !== 0) {
|
||||
var msg = '' + code;
|
||||
if (messages.length)
|
||||
msg += ': ' + messages.join();
|
||||
return next(new ldap.OperationsError(msg));
|
||||
}
|
||||
if (code !== 0) {
|
||||
var msg = '' + code;
|
||||
if (messages.length)
|
||||
msg += ': ' + messages.join();
|
||||
return next(new ldap.OperationsError(msg));
|
||||
}
|
||||
|
||||
res.end();
|
||||
return next();
|
||||
res.end();
|
||||
return next();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
server.search('o=myhost', pre, function(req, res, next) {
|
||||
Object.keys(req.users).forEach(function(k) {
|
||||
if (req.filter.matches(req.users[k].attributes))
|
||||
res.send(req.users[k]);
|
||||
if (req.filter.matches(req.users[k].attributes))
|
||||
res.send(req.users[k]);
|
||||
});
|
||||
|
||||
res.end();
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
"node-uuid": "~1.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"pretest": "which gjslint; if [[ \"$?\" = 0 ]] ; then gjslint --nojsdoc -r lib -r tst; else echo \"Missing gjslint. Skipping lint\"; fi",
|
||||
"test": "./node_modules/.bin/tap ./tst"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue