diff --git a/bulk-reset-passwords-in-plesk/12377666961303.kb b/bulk-reset-passwords-in-plesk/12377666961303.kb new file mode 100644 index 0000000..e69de29 diff --git a/bulk-reset-passwords-in-plesk/plesk-password-changer.php b/bulk-reset-passwords-in-plesk/plesk-password-changer.php new file mode 100644 index 0000000..c3ab984 --- /dev/null +++ b/bulk-reset-passwords-in-plesk/plesk-password-changer.php @@ -0,0 +1,1110 @@ +pleskDir = $this->util->getPleskRootPath(); + } + + public function changeAllPasswords(string $newAdminPassword = ''): void + { + $this->logToCsv( + 'entity_type', + 'new_password', + 'owner_name', + 'owner_type', + 'owner_login', + 'owner_email', + 'domain', + 'entity_login', + 'entity_id', + ); + + if ($this->options->hasFlag('--resellers', '--exclude-resellers')) { + $this->changeForResellers(); + } + + if ($this->options->hasFlag('--clients', '--exclude-clients')) { + $this->changeForClients(); + } + + if ($this->options->hasFlag('--users')) { + $this->changeForUsers(); + } + + if ($this->options->hasFlag('--domains')) { + $this->changeForDomains(); + } + + if ($this->options->hasFlag('--dbusers')) { + $this->changeForDatabaseUsersAccounts(); + } + + if ($this->options->hasFlag('--additionalftpaccounts')) { + $this->changeForAdditionalFTPaccounts(); + } + + if ($this->options->hasFlag('--mailaccounts')) { + $this->changeForMailAccounts(); + } + + if ($this->options->hasFlag('--webusers')) { + $this->changeForWebUsers(); + } + + if ($this->options->hasFlag('--clean-up-sessions')) { + $this->cleanUpSessions(); + } + + if ($this->options->hasFlag('--additionaladmins')) { + $this->changeForApsc(); + } + + if ($this->options->hasFlag('--admin')) { + $this->changeForAdmin($newAdminPassword); + } + } + + public function changeForClients(): void + { + $this->log->step('Change password for clients...', true); + $sql = <<db->fetchAll($sql) as $client) { + $newPassword = $this->getNewPassword(); + $output = $this->util->execPleskUtility('client', ['-u', $client['login'], '-passwd', ''], [ + 'PSA_PASSWORD' => $newPassword, + ]); + + if ($output['code'] !== 0) { + $this->logExecutionFailure('Update hosting panel user', $output); + continue; + } + + if (isset($client['owner_login'])) { + $this->logToCsv( + 'customer', + $newPassword, + $client['owner_name'], + $client['owner_type'], + $client['owner_login'], + $client['owner_email'], + '', + $client['login'], + $client['id'], + ); + } else { + $this->logToCsv('customer', $newPassword, '', '', '', '', '', $client['login'], $client['id']); + } + + $this->log->info("Client login: {$client['login']} Email: {$client['email']} New password: {$newPassword}"); + } + } + + private function changeForApsc(): void + { + if (! $this->util->isLinux()) { + return; + } + + $this->log->step('Change password for apsc database...', true); + $output = $this->util->execPleskUtility('sw-engine-pleskrun', [ + "{$this->pleskDir}/admin/plib/scripts/check_apsc_connection.php", + ]); + + if ($output['stdout'] === 'connection ok') { + $this->log->info('apsc connection is OK. Skip password changing.'); + return; + } + + $newPassword = $this->getNewPassword(); + $this->db->query("SET PASSWORD FOR 'apsc'@'localhost' = PASSWORD('{$newPassword}')"); + + $output = $this->util->execPleskUtility('sw-engine-pleskrun', [ + "{$this->pleskDir}/admin/plib/scripts/register_apsc_database.php", + '--register', + '-host', + 'localhost', + '-port', + '3306', + '-database', + 'apsc', + '-login', + 'apsc', + '-password', + $newPassword, + ]); + + if (trim($output['stdout']) === 'APSC database has been registered successfully') { + $this->log->info('apsc database login: apsc New password: ' . $newPassword); + return; + } + + $this->logExecutionFailure('update password for apsc database', $output); + } + + private function cleanUpSessions(): void + { + $this->log->step('Clean up all user sessions in Plesk database...', true); + $this->db->query('DELETE FROM sessions'); + } + + private function changeForAdmin(string $newPassword = ''): void + { + if ($newPassword === '') { + $newPassword = $this->getNewPassword(); + } + + $this->log->step('Change password for admin...', true); + $output = $this->util->execPleskUtility('admin', ['--set-admin-password', '-passwd', ''], [ + 'PSA_PASSWORD' => $newPassword, + ]); + + if ($output['code'] !== 0) { + $this->logExecutionFailure('change admin\'s password', $output); + return; + } + + $this->logToCsv('admin', $newPassword, '', '', '', '', '', 'admin', ''); + $this->log->info('New admin password: ' . $newPassword); + $this->options->setNewAdminDbPasswd($newPassword); + } + + private function changeForAdditionalAdmins(): void + { + $this->log->step('Change password for additional administrators accounts...', true); + $sql = <<db->fetchAll($sql) as $addadmin) { + $newPassword = $this->getNewPassword(); + $output = $this->util->execPleskUtility('admin_alias', ['-u', $addadmin['login'], '-passwd', ''], [ + 'PSA_PASSWORD' => $newPassword, + ]); + + if ($output['code'] !== 0) { + $this->logExecutionFailure('update additional administrator', $output); + continue; + } + + $this->logToCsv( + 'additionaladmin', + $newPassword, + '', + '', + '', + '', + '', + $addadmin['login'], + $addadmin['id'], + ); + + $this->log->info( + "Additional administrator login: {$addadmin['login']} Email: {$addadmin['aemail']} New password: {$newPassword}" + ); + } + } + + private function changeForResellers(): void + { + $this->log->step('Change password for resellers...', true); + $sql = <<db->fetchAll($sql) as $reseller) { + $newPassword = $this->getNewPassword(); + $output = $this->util->execPleskUtility('reseller', ['-u', $reseller['login'], '-passwd', ''], [ + 'PSA_PASSWORD' => $newPassword, + ]); + + if ($output['code'] !== 0) { + $this->logExecutionFailure('update reseller', $output); + continue; + } + + $this->logToCsv('reseller', $newPassword, '', '', '', '', '', $reseller['login'], $reseller['id']); + $this->log->info( + "Reseller login: {$reseller['login']} Email: {$reseller['email']} New password: {$newPassword}" + ); + } + } + + private function changeForUsers(): void + { + $this->log->step('Change password for users...', true); + $sql = <<db->fetchAll($sql) as $user) { + $newPassword = $this->getNewPassword(); + $output = $this->util->execPleskUtility('user', ['-u', $user['login'], '-passwd', ''], [ + 'PSA_PASSWORD' => $newPassword, + ]); + + if ($output['code'] !== 0) { + $this->logExecutionFailure('Update hosting panel user', $output); + continue; + } + + $this->logToCsv( + 'hosting panel user', + $newPassword, + $user['owner_name'], + $user['owner_type'], + $user['owner_login'], + $user['owner_email'], + '', + $user['login'], + $user['id'], + ); + + $this->log->info('Hosting Panel User: ' . $user['login'] . ' New password: ' . $newPassword); + } + } + + private function changeForDomains(): void + { + $this->log->step('Change password for FTP users of domains...', true); + $sql = <<db->fetchAll($sql) as $domain) { + $newPassword = $this->getNewPassword(); + $output = $this->util->execPleskUtility('domain', ['-u', $domain['name'], '-passwd', ''], [ + 'PSA_PASSWORD' => $newPassword, + ]); + + if ($output['code'] !== 0) { + $this->logExecutionFailure('Update domain FTP account', $output); + continue; + } + + $this->logToCsv( + 'domain FTP account', + $newPassword, + $domain['owner_name'], + $domain['owner_type'], + $domain['owner_login'], + $domain['owner_email'], + $domain['name'], + $domain['login'], + $domain['id'], + ); + + $this->log->info("FTP user {$domain['login']} for domain {$domain['name']} New password: {$newPassword}"); + } + } + + private function changeForAdditionalFTPaccounts(): void + { + $this->log->step('Change password for additional FTP accounts...', true); + $sql = <<db->fetchAll($sql) as $account) { + $newPassword = $this->getNewPassword(); + $output = $this->util->execPleskUtility('ftpsubaccount', [ + '-u', + $account['login'], + '-passwd', + '', + '-domain', + $account['name'], + ], [ + 'PSA_PASSWORD' => $newPassword, + ]); + + if ($output['code'] !== 0) { + $this->logExecutionFailure('Update additional FTP account', $output); + continue; + } + + $this->logToCsv( + 'additional FTP account', + $newPassword, + $account['owner_name'], + $account['owner_type'], + $account['owner_login'], + $account['owner_email'], + $account['name'], + $account['login'], + $account['id'], + ); + + $this->log->info( + "Domain: {$account['name']} Additional FTP account: {$account['login']} New password: {$newPassword}" + ); + } + } + + private function changeForWebUsers(): void + { + $this->log->step('Change password for web users of domains...', true); + $sql = <<db->fetchAll($sql) as $webuser) { + $newPassword = $this->getNewPassword(); + $output = $this->util->execPleskUtility('webuser', [ + '-u', + $webuser['login'], + '-passwd', + '', + '-domain', + $webuser['name'], + ], [ + 'PSA_PASSWORD' => $newPassword, + ]); + + if ($output['code'] !== 0) { + $this->logExecutionFailure('Update web user', $output); + continue; + } + + $this->logToCsv( + 'web user', + $newPassword, + $webuser['owner_name'], + $webuser['owner_type'], + $webuser['owner_login'], + $webuser['owner_email'], + $webuser['name'], + $webuser['login'], + $webuser['id'], + ); + + $this->log->info("Web user {$webuser['login']} for domain {$webuser['name']} New password: {$newPassword}"); + } + } + + private function changeForMailAccounts(): void + { + $this->log->step('Change password for mail accounts...', true); + $sql = <<db->fetchAll($sql) as $account) { + $newPassword = $this->getNewPassword(); + $output = $this->util->execPleskUtility('mail', [ + '-u', + $account['mail_name'] . '@' . $account['name'], + '-passwd', + '', + ], [ + 'PSA_PASSWORD' => $newPassword, + ]); + + if ($output['code'] !== 0) { + $this->logExecutionFailure('Update mail account', $output); + continue; + } + + $this->logToCsv( + 'mail account', + $newPassword, + $account['owner_name'], + $account['owner_type'], + $account['owner_login'], + $account['owner_email'], + $account['name'], + $account['mail_name'], + $account['id'], + ); + + $this->log->info("Mail account: {$account['mail_name']}@{$account['name']} New password: {$newPassword}"); + } + } + + private function changeForDatabaseUsersAccounts(): void + { + $this->log->step('Change password for database users...', true); + $sql = <<db->fetchAll($sql) as $dbuser) { + $newPassword = $this->getNewPassword(); + $output = $this->util->execPleskUtility('database', [ + '-u', + $dbuser['name'], + '-update_user', + $dbuser['login'], + '-passwd', + '', + ], [ + 'PSA_PASSWORD' => $newPassword, + ]); + + if ($output['code'] !== 0) { + $this->logExecutionFailure('Update database user', $output); + continue; + } + + $this->logToCsv( + 'dbuser', + $newPassword, + $dbuser['owner_name'], + $dbuser['owner_type'], + $dbuser['owner_login'], + $dbuser['owner_email'], + $dbuser['domain_name'], + $dbuser['login'], + $dbuser['id'], + ); + + $this->log->info( + "{$dbuser['type']} database {$dbuser['name']} user on {$dbuser['host']}: " + . "{$dbuser['port']} with login {$dbuser['login']} on domain {$dbuser['domain_name']} New password: {$newPassword}", + ); + } + } + + private function getNewPassword(): string + { + $length = 16; + $patterns = []; + $patterns[] = '1234567890'; + $patterns[] = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $patterns[] = 'abcdefghijklmnopqrstuvwxyz'; + + $passwordString = ''; + foreach ($patterns as $pattern) { + $passwordString .= substr(str_shuffle($pattern), 0, (int)($length / count($patterns))); + } + + $passwordString .= substr(str_shuffle('@#%^*'), 0); + return str_shuffle($passwordString); + } + + private function logToCsv( + string $entityType, + string $newPassword, + mixed $ownerName, + mixed $ownerType, + mixed $ownerLogin, + mixed $ownerEmail, + mixed $domain, + mixed $entityLogin, + mixed $entityId, + ) { + $log = implode(';', [ + (string) $ownerName, + (string) $ownerType, + (string) $ownerLogin, + (string) $ownerEmail, + (string) $domain, + $entityType, + (string) $entityLogin, + (string) $entityId, + $newPassword, + ]) . PHP_EOL; + $this->log->write(__DIR__ . '/new_plesk_passwords.csv', $log); + } + + private function logExecutionFailure(string $action, array $result): void + { + $this->log->warning( + "Failed to {$action} using command {$result['cmd']}: code: [{$result['code']}], stdout: [{$result['stdout']}], stderr: [{$result['stderr']}]", + ); + } +} + +class PleskInstallation +{ + public function __construct( + private readonly Util $util, + private readonly Log $log + ) { + } + + public function validate() + { + if (! $this->isInstalled()) { + $this->log->fatal('Plesk installation is not found.'); + } + + if (version_compare('18.0.50', $this->getVersion(), '>')) { + $this->log->fatal( + 'Currently installed Plesk version is too low. This script only supports Plesk 18.0.50 and newer.' + ); + } + } + + public function isInstalled(): bool + { + $rootPath = $this->util->getPleskRootPath(); + return ! empty($rootPath) && file_exists($rootPath); + } + + public function getVersion(): string + { + return explode(' ', file_get_contents($this->util->getPleskRootPath() . '/version'))[0]; + } +} + +class Log +{ + private const FATAL_ERROR = 'FATAL_ERROR'; + + private const ERROR = 'ERROR'; + + private const WARNING = 'WARNING'; + + private const INFO = 'INFO'; + + private readonly string $logFile; + + private int $errorCount = 0; + + private int $warningCount = 0; + + public function __construct() + { + $this->logFile = __DIR__ . '/mass_password_reset_tool.log'; + @unlink($this->logFile); + } + + public function getErrorCount(): int + { + return $this->errorCount; + } + + public function getWarningCount(): int + { + return $this->warningCount; + } + + public function fatal(string $msg): void + { + $this->log($msg, self::FATAL_ERROR); + } + + public function error(string $msg): void + { + $this->log($msg, self::ERROR); + } + + public function warning(string $msg): void + { + $this->log($msg, self::WARNING); + } + + public function step(string $msg, bool $useNumber = false): void + { + static $step = 1; + + if ($useNumber) { + $msg = '==> STEP ' . $step . ": {$msg}"; + $step++; + } else { + $msg = "==> {$msg}"; + } + + $this->log($msg, self::INFO, PHP_EOL); + } + + public function resultOk(): void + { + $msg = 'Result: OK'; + $this->info($msg); + } + + public function info(string $msg): void + { + $this->log($msg, self::INFO); + } + + public function dumpStatistics(): void + { + $str = 'Found errors: ' . $this->errorCount + . '; Found warnings: ' . $this->warningCount + ; + echo PHP_EOL . $str . PHP_EOL . PHP_EOL; + } + + public function write(string $file, string $content, string $mode = 'a+'): void + { + $fp = fopen($file, $mode); + fwrite($fp, $content); + fclose($fp); + } + + private function log(string $msg, string $type, string $newLine = ''): void + { + $date = date('Y-m-d h:i:s'); + $log = $newLine . "[{$date}][{$type}] {$msg}" . PHP_EOL; + + if ($type === self::ERROR || $type === self::FATAL_ERROR) { + $this->errorCount++; + fwrite(STDERR, $log); + } elseif ($type === self::WARNING) { + $this->warningCount++; + fwrite(STDERR, $log); + } elseif ($type === self::INFO) { + //:INFO: Dump to output and write log to the file + echo $log; + } + + $this->write($this->logFile, $log); + + //:INFO: Terminate the process if have the fatal error + if ($type === self::FATAL_ERROR) { + exit(1); + } + } +} + +class PleskDb +{ + private readonly PDO $db; + + public function __construct( + private readonly Log $log, + private readonly Util $util, + private readonly GetOpt $options, + ) { + $dbParams = $this->getDbParams(); + $this->db = new PDO( + "mysql:host={$dbParams['host']};dbname={$dbParams['db']};port={$dbParams['port']}", + $dbParams['login'], + $dbParams['passwd'], + [ + PDO::ERRMODE_EXCEPTION => true, + ], + ); + } + + public function fetchAll(string $sql): Generator + { + if (DEBUG !== 0) { + $this->log->info($sql); + } + + $query = $this->db->query($sql); + $query->execute(); + while ($row = $query->fetch()) { + yield $row; + } + } + + public function query(string $sql): void + { + $query = $this->db->query($sql); + $query->execute(); + } + + private function getDbParams(): array + { + return [ + 'db' => trim($this->util->getPleskDbName()), + 'port' => $this->util->getPleskDbPort(), + 'login' => trim($this->util->getPleskDbLogin()), + 'passwd' => trim($this->options->getDbPasswd()), + 'host' => trim($this->util->getPleskDbHost()), + ]; + } +} + +class Util +{ + private readonly string $pleskRoot; + + private readonly bool $isWindows; + + private readonly string $osArch; + + public function __construct( + private readonly Log $log, + ) { + $this->isWindows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; + if ($this->isWindows) { + $this->osArch = 'x86_64'; + } + + $this->pleskRoot = $this->isLinux() ? '/usr/local/psa' : $this->regPleskQuery('PRODUCT_ROOT_D', true); + if ($this->isWindows) { + return; + } + + $osInfo = json_decode($this->execPleskUtility('osdetect', isSbin: true)['stdout'], true, 512, JSON_THROW_ON_ERROR); + $this->osArch = $osInfo['arch']; + } + + public function isWindows(): bool + { + return $this->isWindows; + } + + public function isLinux(): bool + { + return ! $this->isWindows; + } + + public function getPleskDbName(): string + { + $dbName = 'psa'; + if ($this->isWindows()) { + $dbName = $this->regPleskQuery('mySQLDBName'); + } + + return $dbName; + } + + public function getPleskDbLogin(): string + { + $dbLogin = 'admin'; + if ($this->isWindows()) { + $dbLogin = $this->regPleskQuery('PLESK_DATABASE_LOGIN'); + } + + return $dbLogin; + } + + public function getPleskDbHost(): string + { + $dbHost = 'localhost'; + if ($this->isWindows()) { + $dbHost = $this->regPleskQuery('MySQL_DB_HOST'); + } + + return $dbHost; + } + + public function getPleskDbPort(): int + { + $dbPort = 3306; + if ($this->isWindows()) { + $dbPort = $this->regPleskQuery('MYSQL_PORT'); + } + + return (int) $dbPort; + } + + public function regPleskQuery(string $key, bool $returnResult = false): string|false + { + $output = $this->exec([ + 'REG', + 'QUERY', + $this->osArch === 'x86_64' + ? 'HKLM\SOFTWARE\Wow6432Node\Plesk\Psa Config\Config' + : 'HKLM\SOFTWARE\Plesk\Psa Config\Config', + '/v', + $key, + ]); + + if ($returnResult && $output['code'] !== 0) { + return false; + } + + if ($output['code'] !== 0) { + $this->log->fatal( + "Unable to get '{$key}' from registry: stdout [{$output['stdout']}] stderr [{$output['stderr']}]" + ); + } + + if (! preg_match("/\w+\s+REG_SZ\s+(.*)/i", trim($output['stdout']), $matches)) { + $this->log->fatal('Unable to macth registry value by key ' . $key . '. Output: ' . trim($output['stdout'])); + } + + return $matches[1]; + } + + public function retrieveAdminMySQLDbPassword(): string + { + if ($this->isLinux()) { + return file_get_contents('/etc/psa/.psa.shadow'); + } + + return $this->exec([ + "{$this->pleskRoot}\\admin\\bin64\\psadb.exe", + '--get-admin-password', + ])['stdout']; + } + + public function getPleskRootPath(): string + { + return $this->pleskRoot; + } + + /** + * @return array{code: int, stdout: string, stderr: string, cmd: string} + */ + public function exec(array $cmd, array $env = []): array + { + if (DEBUG !== 0) { + $this->log->info(implode(', ', $cmd)); + } + + $stdout = tempnam(sys_get_temp_dir(), 'out'); + $stderr = tempnam(sys_get_temp_dir(), 'err'); + $pipes = []; + $descriptors = [ + 0 => ['pipe', 'r'], + 1 => ['file', $stdout, 'w'], + 2 => ['file', $stderr, 'w'], + ]; + + $proc = proc_open(command: $cmd, descriptor_spec: $descriptors, pipes: $pipes, env_vars: $env, options: [ + 'bypass_shell' => true, + 'create_process_group' => true, + ]); + + fclose($pipes[0]); + $data = [ + 'code' => proc_close($proc), + 'stdout' => file_get_contents($stdout), + 'stderr' => file_get_contents($stderr), + 'cmd' => implode(' ', array_map('escapeshellarg', $cmd)), + ]; + + unlink($stdout); + unlink($stderr); + + return $data; + } + + /** + * @return array{code: int, stdout: string, stderr: string, cmd: string} + */ + public function execPleskUtility(string $utility, array $args = [], array $env = [], bool $isSbin = false): array + { + $path = $this->pleskRoot; + if ($this->isWindows) { + if ($isSbin) { + $path .= '\\admin'; + } + + $path .= "\\bin\\{$utility}.exe"; + $env = array_merge(getenv(), $env); + } else { + if ($isSbin) { + $path .= '/admin'; + } + + $path .= "/bin/{$utility}"; + } + + return $this->exec(array_merge([$path], $args), $env); + } +} + +class GetOpt +{ + private array $argv; + + private string $adminDbPasswd; + + private string $newAdminPasswd = ''; + + public function __construct( + private readonly Util $util, + ) { + $this->argv = $_SERVER['argv']; + $this->adminDbPasswd = empty($this->argv[1]) + ? $this->util->retrieveAdminMySQLDbPassword() + : $this->argv[1]; + + if (! empty($this->argv[2]) && ! preg_match('/^--/', (string) $this->argv[2])) { + $this->newAdminPasswd = $this->argv[2]; + } + + if (! strpos(implode(' ', $this->argv), ' --')) { + $this->argv[] = '--all'; // if there is no any arguments like --something, than treat this as --all + } + } + + public function validate(): void + { + if (empty($this->adminDbPasswd)) { + fwrite(STDERR, 'Please, specify Plesk database password'); + $this->helpUsage(); + } + + if (in_array('-h', $this->argv, true) || in_array('--help', $this->argv, true)) { + $this->helpUsage(); + } + } + + public function hasFlag(string $flag, ?string $excludeFlag = null): bool + { + if (in_array('--all', $this->argv, true)) { + return true; + } + + if ($excludeFlag !== null) { + return in_array($flag, $this->argv, true); + } + + return ! in_array($excludeFlag, $this->argv, true) && in_array($flag, $this->argv, true); + } + + public function setNewAdminDbPasswd(string $adminDbPasswd): void + { + $this->adminDbPasswd = $adminDbPasswd; + } + + public function getDbPasswd(): string + { + return $this->adminDbPasswd; + } + + public function getNewAdminPasswd(): string + { + return $this->newAdminPasswd; + } + + public function helpUsage(): never + { + echo PHP_EOL . "Usage: {$this->argv[0]} [new_plesk_db_admin_password] [options]" . PHP_EOL; + echo 'Options: --all - [default] change passwords for all supported entities and clean up sessions table in Plesk database' . PHP_EOL; + echo ' --admin - change password for admin' . PHP_EOL; + echo ' --apsc - change password for apsc database' . PHP_EOL; + echo ' --clean-up-sessions - clean up sessions table in Plesk database' . PHP_EOL; + echo ' --additionaladmins - change passwords for additional administrators accounts' . PHP_EOL; + echo ' --resellers - change passwords for resellers' . PHP_EOL; + echo ' --clients - change passwords for clients' . PHP_EOL; + echo ' --domains - change passwords for main FTP account of domains' . PHP_EOL; + echo ' --users - change passwords for hosting panel users' . PHP_EOL; + echo ' --additionalftpaccounts - change passwords for additional FTP accounts for domains' . PHP_EOL; + echo ' --dbusers - change passwords for database users.' . PHP_EOL; + echo ' --webusers - change passwords for webusers' . PHP_EOL; + echo ' --mailaccounts - change passwords for mail accounts' . PHP_EOL; + exit(1); + } +} + +if (str_starts_with(PHP_SAPI, 'cgi')) { + //:INFO: set max execution time 1hr + @set_time_limit(3600); +} + +date_default_timezone_set(@date_default_timezone_get()); + +$log = new Log(); +$util = new Util($log); +$getopt = new GetOpt($util); +$getopt->validate(); + +//:INFO: Validate Plesk installation +$pleskInstallation = new PleskInstallation($util, $log); +$pleskInstallation->validate(); + +//:INFO: Need to make sure that given db password is valid +$log->step('Validate given db password'); +$db = new PleskDb($log, $util, $getopt); +$log->resultOk(); + +//:INFO: Dump script version +$log->step('Plesk Password Changer version: ' . PRE_UPGRADE_SCRIPT_VERSION); + +$PleskPasswordChanger = new PleskPasswordChanger($getopt, $log, $util, $db); +$PleskPasswordChanger->changeAllPasswords($getopt->getNewAdminPasswd()); + +$log->dumpStatistics(); + +if ($log->getErrorCount() > 0 || $log->getWarningCount() > 0) { + exit(1); +} \ No newline at end of file