Files
ldap-auth-service/lib/passwordSetter.js
2026-08-20 15:47:13 +05:00

71 lines
2.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict';
const { spawn } = require('child_process');
// Sets a user's password via PowerShell/ADSI (IADsUser.SetPassword).
// On a domain-joined machine ADSI negotiates a Kerberos signed/sealed
// connection, which Active Directory accepts as a "protected channel"
// for unicodePwd — unlike a plain LDAP bind over TCP (AD error 53).
//
// The DN and password are passed via environment variables so they never
// appear in the process command line, and the script body is pure ASCII
// (no encoding issues with Windows PowerShell 5.1). The script itself is
// sent over stdin to avoid temp files.
function setPasswordViaPowerShell(userDN, password, { exe = 'powershell.exe', timeoutMs = 15000 } = {}) {
return new Promise((resolve, reject) => {
const script = [
'$ErrorActionPreference = "Stop"',
'$dn = [Environment]::GetEnvironmentVariable("LDAP_PW_DN")',
'$pw = [Environment]::GetEnvironmentVariable("LDAP_PW_VALUE")',
'$user = [adsi]("LDAP://" + $dn)',
'$user.SetPassword($pw)'
].join('; ');
let child;
try {
child = spawn(exe, ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-Command', '-'], {
env: { ...process.env, LDAP_PW_DN: userDN, LDAP_PW_VALUE: password },
windowsHide: true,
stdio: ['pipe', 'pipe', 'pipe']
});
} catch (err) {
reject(new Error(`Не удалось запустить PowerShell для установки пароля: ${err.message}`));
return;
}
let stdout = '';
let stderr = '';
let timedOut = false;
const timer = setTimeout(() => {
timedOut = true;
try { child.kill(); } catch (_) { /* ignore */ }
}, timeoutMs);
child.stdout.on('data', (d) => { stdout += d; });
child.stderr.on('data', (d) => { stderr += d; });
child.on('error', (err) => {
clearTimeout(timer);
reject(new Error(`Не удалось запустить PowerShell для установки пароля: ${err.message}`));
});
child.on('close', (code) => {
clearTimeout(timer);
if (timedOut) {
reject(new Error('Таймаут при установке пароля через PowerShell'));
return;
}
if (code === 0) {
resolve();
return;
}
const detail = String(stderr || stdout || '').trim();
reject(new Error(`Ошибка установки пароля через PowerShell (код ${code})${detail ? ': ' + detail : ''}`));
});
child.stdin.end(script);
});
}
module.exports = setPasswordViaPowerShell;