diff --git a/install/dist/lib/fedora.lib.php b/install/dist/lib/fedora.lib.php index 5d578e329e2a1d2d773965dc6a9c7591ab67753b..82303ca78a2bf5890813a5ecb141e526b340d0fc 100644 --- a/install/dist/lib/fedora.lib.php +++ b/install/dist/lib/fedora.lib.php @@ -1076,6 +1076,12 @@ class installer_dist extends installer_base { if(!is_link('/usr/local/bin/ispconfig_update_from_dev.sh')) exec('ln -s /usr/local/ispconfig/server/scripts/ispconfig_update.sh /usr/local/bin/ispconfig_update_from_dev.sh'); if(!is_link('/usr/local/bin/ispconfig_update.sh')) exec('ln -s /usr/local/ispconfig/server/scripts/ispconfig_update.sh /usr/local/bin/ispconfig_update.sh'); + // Install ISPConfig cli command + if(is_file('/usr/local/bin/ispc')) unlink('/usr/local/bin/ispc'); + chown($install_dir.'/server/cli/ispc', 'root'); + chmod($install_dir.'/server/cli/ispc', 0700); + symlink($install_dir.'/server/cli/ispc', '/usr/local/bin/ispc'); + // set the fast cgi starter script to executable // exec('chmod 755 '.$install_dir.'/interface/bin/php-fcgi'); diff --git a/install/dist/lib/gentoo.lib.php b/install/dist/lib/gentoo.lib.php index 574cb10f670910bdbf7d6539fcfa5b18f9843a97..69691a6afd7c34f1ed1baa89ddd0f867e0653499 100644 --- a/install/dist/lib/gentoo.lib.php +++ b/install/dist/lib/gentoo.lib.php @@ -1511,6 +1511,12 @@ class installer extends installer_base if(!is_link('/usr/local/bin/ispconfig_update_from_dev.sh')) symlink($install_dir.'/server/scripts/ispconfig_update.sh', '/usr/local/bin/ispconfig_update_from_dev.sh'); if(!is_link('/usr/local/bin/ispconfig_update.sh')) symlink($install_dir.'/server/scripts/ispconfig_update.sh', '/usr/local/bin/ispconfig_update.sh'); + // Install ISPConfig cli command + if(is_file('/usr/local/bin/ispc')) unlink('/usr/local/bin/ispc'); + chown($install_dir.'/server/cli/ispc', 'root'); + chmod($install_dir.'/server/cli/ispc', 0700); + symlink($install_dir.'/server/cli/ispc', '/usr/local/bin/ispc'); + // Make executable then unlink and symlink letsencrypt pre, post and renew hook scripts chown($install_dir.'/server/scripts/letsencrypt_pre_hook.sh', 'root'); chown($install_dir.'/server/scripts/letsencrypt_post_hook.sh', 'root'); diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 8e6cfca07b494eb3bb07034e164baf0315ca6d37..baf3fd60fe610de9d71e1769791c2a2c43b181e9 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -3811,6 +3811,12 @@ class installer_base extends stdClass { if(!is_link('/usr/local/bin/ispconfig_update_from_dev.sh')) symlink($install_dir.'/server/scripts/ispconfig_update.sh', '/usr/local/bin/ispconfig_update_from_dev.sh'); if(!is_link('/usr/local/bin/ispconfig_update.sh')) symlink($install_dir.'/server/scripts/ispconfig_update.sh', '/usr/local/bin/ispconfig_update.sh'); + // Install ISPConfig cli command + if(is_file('/usr/local/bin/ispc')) unlink('/usr/local/bin/ispc'); + chown($install_dir.'/server/cli/ispc', 'root'); + chmod($install_dir.'/server/cli/ispc', 0700); + symlink($install_dir.'/server/cli/ispc', '/usr/local/bin/ispc'); + // Make executable then unlink and symlink letsencrypt pre, post and renew hook scripts chown($install_dir.'/server/scripts/letsencrypt_pre_hook.sh', 'root'); chown($install_dir.'/server/scripts/letsencrypt_post_hook.sh', 'root'); diff --git a/server/cli/ispc b/server/cli/ispc new file mode 100644 index 0000000000000000000000000000000000000000..d26375167d21273a793d6bd0aeda5036a4234909 --- /dev/null +++ b/server/cli/ispc @@ -0,0 +1,22 @@ +#!/bin/bash + +PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin + +. /etc/profile + +if [ -f /usr/local/ispconfig/server/lib/php.ini ]; then + PHPINIOWNER=`stat -c %U /usr/local/ispconfig/server/lib/php.ini` + if [ $PHPINIOWNER == 'root' ] || [ $PHPINIOWNER == 'ispconfig' ]; then + export PHPRC=/usr/local/ispconfig/server/lib + fi +fi + +cd /usr/local/ispconfig/server/cli +$(which php) -q \ + -d disable_classes= \ + -d disable_functions= \ + -d open_basedir= \ + /usr/local/ispconfig/server/cli/ispc.php "$@"; +RET=$? ; + +exit $RET ; \ No newline at end of file diff --git a/server/cli/ispc.php b/server/cli/ispc.php new file mode 100644 index 0000000000000000000000000000000000000000..cda1f67919ab7b0080dfdf57606ded9536ed9324 --- /dev/null +++ b/server/cli/ispc.php @@ -0,0 +1,59 @@ +setCaller('server'); +$app->load('cli'); + +//* Check input +$module = $argv[1]; +if($module == '-h' || $module == '--help') $module = 'help'; +if(!preg_match("/[a-z0-9]{3,20}/",$module)) die("Invalid commandline option\n"); +//* Check if cli module exists and run it +if(is_file('modules/'.$module.'.inc.php')) { + include_once 'modules/'.$module.'.inc.php'; + $class = $module.'_cli'; + $m = new $class; + $m->process($argv); +} else { + include_once 'modules/help.inc.php'; + $m = new help_cli; + $m->errorShowHelp($argv); +} + + + diff --git a/server/cli/modules/help.inc.php b/server/cli/modules/help.inc.php new file mode 100644 index 0000000000000000000000000000000000000000..ffd7bda151c912a35328a5ee65a75de6ee8d7bb9 --- /dev/null +++ b/server/cli/modules/help.inc.php @@ -0,0 +1,72 @@ +addCmdOpt($cmd_opt); + } + + public function errorShowHelp($arg) { + global $conf; + + $this->swriteln("\nError: Unknown Commandline Option\n"); + $this->showHelp($arg); + } + + public function showHelp($arg) { + global $conf; + + $this->swriteln("---------------------------------"); + $this->swriteln("- Available commandline modules -"); + $this->swriteln("---------------------------------"); + + $module_dir = dirname(__FILE__); + + // loop trough modules + $files = glob($module_dir . '/*.inc.php'); + foreach ($files as $file) { + $filename = basename($file); + $filename = str_replace('.inc.php', '', $filename); + $this->swriteln("\033[1m\033[31mispc ".$filename."\033[0m"); + } + + $this->swriteln("---------------------------------"); + $this->swriteln(); + + + } + +} + diff --git a/server/cli/modules/php.inc.php b/server/cli/modules/php.inc.php new file mode 100644 index 0000000000000000000000000000000000000000..fb62d51e58bca098f5482be7ea370be8d6d85870 --- /dev/null +++ b/server/cli/modules/php.inc.php @@ -0,0 +1,57 @@ +addCmdOpt($cmd_opt); + } + + public function showPHPVersion($arg) { + global $conf; + $this->swriteln("PHP CLI version: ".shell_exec('php --version')); + } + + public function showHelp($arg) { + global $conf; + + $this->swriteln("---------------------------------"); + $this->swriteln("- Available commandline options -"); + $this->swriteln("---------------------------------"); + $this->swriteln("ispc php version - Show the commandline PHP version."); + $this->swriteln("---------------------------------"); + $this->swriteln(); + } + +} + diff --git a/server/cli/modules/update.inc.php b/server/cli/modules/update.inc.php new file mode 100644 index 0000000000000000000000000000000000000000..a32c78d7233e6dda4273c1693f303ca78f3ec8c1 --- /dev/null +++ b/server/cli/modules/update.inc.php @@ -0,0 +1,56 @@ +addCmdOpt($cmd_opt); + } + + public function ispconfigUpdate($arg) { + global $conf; + passthru('/usr/local/bin/ispconfig_update.sh'); + } + + public function showHelp($arg) { + global $conf; + + $this->swriteln("---------------------------------"); + $this->swriteln("- Available commandline options -"); + $this->swriteln("---------------------------------"); + $this->swriteln("ispc update - Start ISPConfig update."); + $this->swriteln("---------------------------------"); + $this->swriteln(); + } + +} + diff --git a/server/cli/modules/user.inc.php b/server/cli/modules/user.inc.php new file mode 100644 index 0000000000000000000000000000000000000000..ebaa787a65e56d731c5ead908282fe26bd03c016 --- /dev/null +++ b/server/cli/modules/user.inc.php @@ -0,0 +1,126 @@ +addCmdOpt($cmd_opt); + } + + public function setPassword($arg) { + global $app, $conf; + + // Get username + $username = $arg[0]; + + // Check empty username + if(empty($username)) { + $this->swriteln(); + $this->swriteln('Error: Username may not be empty.'); + $this->swriteln(); + $this->showHelp($arg); + die(); + } + + // Check for invalid chars + if(!preg_match('/^[\w\.\-\_]{1,64}$/',$username)) { + $this->swriteln(); + $this->swriteln('Error: Username contains invalid characters.'); + $this->swriteln(); + $this->showHelp($arg); + die(); + } + + // Get user from ISPConfig database + $user = $app->db->queryOneRecord("SELECT * FROM `sys_user` WHERE `username` = ?",$username); + + // Check if user exists + if(empty($user)) { + $this->swriteln(); + $this->swriteln('Error: Username does not exist.'); + $this->swriteln(); + $this->showHelp($arg); + die(); + } + + // Include auth class from interface + include_once '/usr/local/ispconfig/interface/lib/classes/auth.inc.php'; + $app->auth = new auth; + + $ok = false; + + while ($ok == false) { + + $ok = true; + // Ask for new password + $min_password_len = $app->auth->get_min_password_length(); + $new_password = $this->free_query('Enter new password for the user '.$username .' or quit', $app->auth->get_random_password($min_password_len)); + + if(strlen($new_password) < $min_password_len) { + $this->swriteln('The minimum password length is '. $min_password_len); + $this->swriteln(); + $ok = false; + } + + if($ok) { + $new_password2 = $this->free_query('Repeat the password', ''); + } + + if($ok && $new_password != $new_password2) { + $this->swriteln('Passwords do not match.'); + $this->swriteln(); + $ok = false; + } + + if($ok) { + $crypted_password = $app->auth->crypt_password($new_password); + $app->db->query("UPDATE `sys_user` SET `passwort` = ? WHERE `username` = ?",$crypted_password,$username); + $this->swriteln('Password for user '.$username.' has been changed.'); + $this->swriteln(); + } + } + } + + public function showHelp($arg) { + global $conf; + + $this->swriteln("---------------------------------"); + $this->swriteln("- Available commandline options -"); + $this->swriteln("---------------------------------"); + $this->swriteln("ispc user set-password - Set a new password for the ISPConfig user ."); + $this->swriteln("---------------------------------"); + $this->swriteln(); + } + +} + diff --git a/server/cli/modules/version.inc.php b/server/cli/modules/version.inc.php new file mode 100644 index 0000000000000000000000000000000000000000..79182765bc08fbc386514eb253084d3299eff2f6 --- /dev/null +++ b/server/cli/modules/version.inc.php @@ -0,0 +1,56 @@ +addCmdOpt($cmd_opt); + } + + public function showVersion($arg) { + global $conf; + $this->swriteln("ISPConfig version: ".ISPC_APP_VERSION); + } + + public function showHelp($arg) { + global $conf; + + $this->swriteln("---------------------------------"); + $this->swriteln("- Available commandline option -"); + $this->swriteln("---------------------------------"); + $this->swriteln("ispc version - Show the ISPConfig version."); + $this->swriteln("---------------------------------"); + $this->swriteln(); + } + +} + diff --git a/server/lib/classes/cli.inc.php b/server/lib/classes/cli.inc.php new file mode 100644 index 0000000000000000000000000000000000000000..29914a3eec0b5cd89c91b69c1e799885ab5d2d96 --- /dev/null +++ b/server/lib/classes/cli.inc.php @@ -0,0 +1,175 @@ +cmd_opt = $cmd_opt; + } + + // Get commandline option map + protected function getCmdOpt() { + return $this->cmd_opt; + } + + // Run command module + public function process($arg) { + $function = ''; + $opt_string = ''; + $last_arg = 1; + for($n = 1; $n < count($arg); $n++) { + $a = ($n > 1)?$a.':'.$arg[$n]:$arg[$n]; + if(isset($this->cmd_opt[$a])) { + $function = $this->cmd_opt[$a]; + $last_arg = $n + 1; + } + } + + // Check function name + if(!preg_match("/[a-z0-9\-]{0,20}/",$function)) die("Invalid commandline option\n"); + + // Build new arg array of the remaining arguments + $new_arg = []; + if($last_arg < count($arg)) { + for($n = $last_arg; $n < count($arg); $n++) { + $new_arg[] = $arg[$n]; + } + } + + if($function != '') { + $this->$function($new_arg); + } else { + $this->showHelp($new_arg); + //$this->error("Invalid option"); + } + } + + // Query function + public function simple_query($query, $answers, $default, $name = '') { + global $autoinstall, $autoupdate; + $finished = false; + do { + if($name != '' && isset($autoinstall[$name]) && $autoinstall[$name] != '') { + if($autoinstall[$name] == 'default') { + $input = $default; + } else { + $input = $autoinstall[$name]; + } + } elseif($name != '' && isset($autoupdate[$name]) && $autoupdate[$name] != '') { + if($autoupdate[$name] == 'default') { + $input = $default; + } else { + $input = $autoupdate[$name]; + } + } else { + $answers_str = implode(',', $answers); + $this->swrite($this->lng($query).' ('.$answers_str.') ['.$default.']: '); + $input = $this->sread(); + } + + //* Stop the installation + if($input == 'quit') { + $this->swriteln($this->lng("Command terminated by user.\n")); + die(); + } + + //* Select the default + if($input == '') { + $answer = $default; + $finished = true; + } + + //* Set answer id valid + if(in_array($input, $answers)) { + $answer = $input; + $finished = true; + } + + } while ($finished == false); + $this->swriteln(); + return $answer; + } + + public function free_query($query, $default, $name = '') { + global $autoinstall, $autoupdate; + if($name != '' && isset($autoinstall[$name]) && $autoinstall[$name] != '') { + if($autoinstall[$name] == 'default') { + $input = $default; + } else { + $input = $autoinstall[$name]; + } + } elseif($name != '' && isset($autoupdate[$name]) && $autoupdate[$name] != '') { + if($autoupdate[$name] == 'default') { + $input = $default; + } else { + $input = $autoupdate[$name]; + } + } else { + $this->swrite($this->lng($query).' ['.$default.']: '); + $input = $this->sread(); + } + + //* Stop the installation + if($input == 'quit') { + $this->swriteln($this->lng("Command terminated by user.\n")); + die(); + } + + $answer = ($input == '') ? $default : $input; + $this->swriteln(); + return $answer; + } + + public function lng($text) { + return $text; + } + + public function sread() { + $input = fgets(STDIN); + return rtrim($input); + } + + public function swrite($text = '') { + echo $text; + } + + public function swriteln($text = '') { + echo $text."\n"; + } + + public function error($msg) { + $this->swriteln($msg); + die(); + } + +}