129 lines
4.0 KiB
JavaScript
129 lines
4.0 KiB
JavaScript
|
|
||
|
const ldap = require('../util/ldapjs-extra');
|
||
|
const ssh = require('node-ssh');
|
||
|
|
||
|
module.exports = Self => {
|
||
|
Self.getSynchronizer = async function() {
|
||
|
return await Self.findOne({
|
||
|
fields: [
|
||
|
'host',
|
||
|
'adDomain',
|
||
|
'adController',
|
||
|
'adUser',
|
||
|
'adPassword',
|
||
|
'verifyCert'
|
||
|
]
|
||
|
});
|
||
|
};
|
||
|
|
||
|
Object.assign(Self.prototype, {
|
||
|
async init() {
|
||
|
let sshClient = new ssh.NodeSSH();
|
||
|
await sshClient.connect({
|
||
|
host: this.adController,
|
||
|
username: this.adUser,
|
||
|
password: this.adPassword
|
||
|
});
|
||
|
|
||
|
let adUser = `cn=${this.adUser},${this.usersDn()}`;
|
||
|
|
||
|
let adClient = ldap.createClient({
|
||
|
url: `ldaps://${this.adController}:636`,
|
||
|
tlsOptions: {rejectUnauthorized: this.verifyCert}
|
||
|
});
|
||
|
await adClient.bind(adUser, this.adPassword);
|
||
|
|
||
|
Object.assign(this, {
|
||
|
sshClient,
|
||
|
adClient
|
||
|
});
|
||
|
},
|
||
|
|
||
|
async deinit() {
|
||
|
await this.sshClient.dispose();
|
||
|
await this.adClient.unbind();
|
||
|
},
|
||
|
|
||
|
usersDn() {
|
||
|
let dnBase = this.adDomain
|
||
|
.split('.')
|
||
|
.map(part => `dc=${part}`)
|
||
|
.join(',');
|
||
|
return `cn=Users,${dnBase}`;
|
||
|
},
|
||
|
|
||
|
async syncUser(userName, info, password) {
|
||
|
let {sshClient} = this;
|
||
|
|
||
|
if (info.hasAccount) {
|
||
|
try {
|
||
|
await sshClient.exec('samba-tool user create', [
|
||
|
userName,
|
||
|
'--uid-number', `${info.uidNumber}`,
|
||
|
'--mail-address', info.corporateMail,
|
||
|
'--random-password'
|
||
|
]);
|
||
|
await sshClient.exec('samba-tool user setexpiry', [
|
||
|
userName,
|
||
|
'--noexpiry'
|
||
|
]);
|
||
|
await sshClient.exec('mkhomedir_helper', [
|
||
|
userName,
|
||
|
'0027'
|
||
|
]);
|
||
|
} catch (e) {}
|
||
|
|
||
|
await sshClient.exec('samba-tool user enable', [
|
||
|
userName
|
||
|
]);
|
||
|
|
||
|
if (password) {
|
||
|
await sshClient.exec('samba-tool user setpassword', [
|
||
|
userName,
|
||
|
'--newpassword', password
|
||
|
]);
|
||
|
}
|
||
|
} else {
|
||
|
try {
|
||
|
await sshClient.exec('samba-tool user disable', [
|
||
|
userName
|
||
|
]);
|
||
|
console.log(` -> '${userName}' disabled on Samba`);
|
||
|
} catch (e) {}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Gets Samba enabled users.
|
||
|
*
|
||
|
* Summary of userAccountControl flags:
|
||
|
* https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/useraccountcontrol-manipulate-account-properties
|
||
|
*
|
||
|
* @param {Set} usersToSync
|
||
|
*/
|
||
|
async getUsers(usersToSync) {
|
||
|
let {adClient} = this;
|
||
|
let usersDn = this.usersDn();
|
||
|
|
||
|
let opts = {
|
||
|
scope: 'sub',
|
||
|
attributes: ['sAMAccountName'],
|
||
|
filter: '(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))'
|
||
|
};
|
||
|
let res = await adClient.search(usersDn, opts);
|
||
|
|
||
|
await new Promise((resolve, reject) => {
|
||
|
res.on('error', err => {
|
||
|
if (err.name === 'NoSuchObjectError')
|
||
|
err = new Error(`Object '${usersDn}' does not exist`);
|
||
|
reject(err);
|
||
|
});
|
||
|
res.on('searchEntry', e => {
|
||
|
usersToSync.add(e.object.sAMAccountName);
|
||
|
});
|
||
|
res.on('end', resolve);
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
};
|