2020-10-30 23:02:27 +00:00
|
|
|
const ldap = require('../../util/ldapjs-extra');
|
|
|
|
const ssh = require('node-ssh');
|
|
|
|
|
|
|
|
module.exports = Self => {
|
|
|
|
Self.remoteMethod('syncAll', {
|
|
|
|
description: 'Synchronizes user database with LDAP and Samba',
|
|
|
|
http: {
|
2020-10-31 02:13:17 +00:00
|
|
|
path: `/sync-all`,
|
2020-10-30 23:02:27 +00:00
|
|
|
verb: 'PATCH'
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
Self.syncAll = async function() {
|
|
|
|
let $ = Self.app.models;
|
|
|
|
let usersToSync = new Set();
|
|
|
|
|
|
|
|
// Database
|
|
|
|
|
|
|
|
let accounts = await $.UserAccount.find({
|
|
|
|
fields: ['id'],
|
|
|
|
include: {
|
|
|
|
relation: 'user',
|
|
|
|
scope: {
|
|
|
|
fields: ['name'],
|
|
|
|
where: {active: true}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-10-30 23:40:54 +00:00
|
|
|
for (let account of accounts) {
|
|
|
|
let user = account.user();
|
|
|
|
if (!user) continue;
|
|
|
|
usersToSync.add(user.name);
|
|
|
|
}
|
2020-10-30 23:02:27 +00:00
|
|
|
|
|
|
|
// LDAP
|
|
|
|
|
|
|
|
let ldapConfig = await $.LdapConfig.findOne({
|
|
|
|
fields: ['host', 'rdn', 'password', 'baseDn']
|
|
|
|
});
|
|
|
|
|
|
|
|
if (ldapConfig) {
|
|
|
|
let ldapClient = ldap.createClient({
|
|
|
|
url: `ldap://${ldapConfig.host}:389`
|
|
|
|
});
|
|
|
|
|
|
|
|
let ldapPassword = Buffer
|
|
|
|
.from(ldapConfig.password, 'base64')
|
|
|
|
.toString('ascii');
|
|
|
|
await ldapClient.bind(ldapConfig.rdn, ldapPassword);
|
|
|
|
|
|
|
|
res = await ldapClient.search(ldapConfig.baseDn, {
|
|
|
|
scope: 'sub',
|
|
|
|
attributes: ['uid'],
|
|
|
|
filter: `uid=*`
|
|
|
|
});
|
|
|
|
|
|
|
|
await new Promise((resolve, reject) => {
|
|
|
|
res.on('error', reject);
|
|
|
|
res.on('searchEntry', e => usersToSync.add(e.object.uid));
|
|
|
|
res.on('end', resolve);
|
|
|
|
});
|
|
|
|
|
|
|
|
// FIXME: Cannot disconnect, hangs on undind() call
|
|
|
|
// await ldapClient.unbind();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Samba
|
|
|
|
|
|
|
|
let sambaConfig = await $.SambaConfig.findOne({
|
|
|
|
fields: ['host', 'sshUser', 'sshPass']
|
|
|
|
});
|
|
|
|
|
|
|
|
if (sambaConfig) {
|
|
|
|
let sshPassword = Buffer
|
|
|
|
.from(sambaConfig.sshPass, 'base64')
|
|
|
|
.toString('ascii');
|
|
|
|
|
|
|
|
let sshClient = new ssh.NodeSSH();
|
|
|
|
await sshClient.connect({
|
|
|
|
host: sambaConfig.host,
|
|
|
|
username: sambaConfig.sshUser,
|
|
|
|
password: sshPassword
|
|
|
|
});
|
|
|
|
|
|
|
|
let res = await sshClient.execCommand('samba-tool user list');
|
|
|
|
let users = res.stdout.split('\n');
|
|
|
|
for (let user of users) usersToSync.add(user.trim());
|
|
|
|
|
|
|
|
await sshClient.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Syncing
|
|
|
|
|
|
|
|
$.RoleInherit.sync();
|
|
|
|
|
|
|
|
let sync = await Self.syncInit();
|
|
|
|
for (let user of usersToSync.values()) {
|
|
|
|
try {
|
|
|
|
await Self.doSync(sync, user);
|
|
|
|
} catch (err) {
|
2020-10-31 02:13:17 +00:00
|
|
|
console.error(`Cannot sync user '${user}':`, err.message);
|
2020-10-30 23:02:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
await Self.syncDeinit(sync);
|
|
|
|
};
|
|
|
|
};
|