From 45b6d8d571caf78acb0837aef01e91433302ec68 Mon Sep 17 00:00:00 2001 From: "Michael Kaufmann (d00p)" Date: Fri, 26 Aug 2016 10:46:15 +0200 Subject: [PATCH] add possibility to allow customers to select a shell for their ftp-users, with great thanks to KAPPER NETWORK-COMMUNICATIONS GmbH - kapper.net Signed-off-by: Michael Kaufmann (d00p) --- actions/admin/settings/210.security.php | 17 +++++++ customer_ftp.php | 48 ++++++++++++++++--- install/froxlor.sql | 4 +- .../updates/froxlor/0.9/update_0.9.inc.php | 10 ++++ .../customer/ftp/formfield.ftp_add.php | 6 +++ .../customer/ftp/formfield.ftp_edit.php | 6 +++ lib/version.inc.php | 2 +- lng/english.lng.php | 8 +++- lng/german.lng.php | 6 +++ templates/Sparkle/customer/ftp/accounts.tpl | 4 +- .../Sparkle/customer/ftp/accounts_account.tpl | 3 ++ 11 files changed, 103 insertions(+), 11 deletions(-) diff --git a/actions/admin/settings/210.security.php b/actions/admin/settings/210.security.php index 4456b6e1..8a08a457 100644 --- a/actions/admin/settings/210.security.php +++ b/actions/admin/settings/210.security.php @@ -63,6 +63,23 @@ return array( 'type' => 'bool', 'default' => false, 'save_method' => 'storeSettingField', + ), + 'system_allow_customer_shell' => array( + 'label' => $lng['serversettings']['allow_allow_customer_shell'], + 'settinggroup' => 'system', + 'varname' => 'allow_customer_shell', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField', + ), + 'system_available_shells' => array( + 'label' => $lng['serversettings']['available_shells'], + 'settinggroup' => 'system', + 'varname' => 'available_shells', + 'type' => 'string', + 'string_emptyallowed' => true, + 'default' => '', + 'save_method' => 'storeSettingField', ) ) ) diff --git a/customer_ftp.php b/customer_ftp.php index f76a5e99..27f90864 100644 --- a/customer_ftp.php +++ b/customer_ftp.php @@ -45,7 +45,7 @@ if ($page == 'overview') { ); $paging = new paging($userinfo, TABLE_FTP_USERS, $fields); - $result_stmt = Database::prepare("SELECT `id`, `username`, `description`, `homedir` FROM `" . TABLE_FTP_USERS . "` + $result_stmt = Database::prepare("SELECT `id`, `username`, `description`, `homedir`, `shell` FROM `" . TABLE_FTP_USERS . "` WHERE `customerid`= :customerid " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit() ); Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'])); @@ -158,6 +158,10 @@ if ($page == 'overview') { $path = validate($_POST['path'], 'path'); $password = validate($_POST['ftp_password'], 'password'); $password = validatePassword($password); + $shell = "/bin/false"; + if (Settings::Get('system.allow_customer_shell') == '1') { + $shell = isset($_POST['shell']) ? validate($_POST['shell'], 'shell') : '/bin/false'; + } $sendinfomail = isset($_POST['sendinfomail']) ? 1 : 0; if ($sendinfomail != 1) { @@ -205,8 +209,8 @@ if ($page == 'overview') { $cryptPassword = makeCryptPassword($password); $stmt = Database::prepare("INSERT INTO `" . TABLE_FTP_USERS . "` - (`customerid`, `username`, `description`, `password`, `homedir`, `login_enabled`, `uid`, `gid`) - VALUES (:customerid, :username, :description, :password, :homedir, 'y', :guid, :guid)" + (`customerid`, `username`, `description`, `password`, `homedir`, `login_enabled`, `uid`, `gid`, `shell`) + VALUES (:customerid, :username, :description, :password, :homedir, 'y', :guid, :guid, :shell)" ); $params = array( "customerid" => $userinfo['customerid'], @@ -214,7 +218,8 @@ if ($page == 'overview') { "description" => $description, "password" => $cryptPassword, "homedir" => $path, - "guid" => $userinfo['guid'] + "guid" => $userinfo['guid'], + "shell" => $shell ); Database::pexecute($stmt, $params); @@ -334,6 +339,18 @@ if ($page == 'overview') { } } + if (Settings::Get('system.allow_customer_shell') == '1') { + $shells = makeoption("/bin/false", "/bin/false", "/bin/false"); + $shells_avail = Settings::Get('system.available_shells'); + if (!empty($shells_avail)) { + $shells_avail = explode(",", $shells_avail); + $shells_avail = array_map("trim", $shells_avail); + foreach ($shells_avail as $_shell) { + $shells .= makeoption($_shell, $_shell, "/bin/false"); + } + } + } + //$sendinfomail = makeyesno('sendinfomail', '1', '0', '0'); $ftp_add_data = include_once dirname(__FILE__).'/lib/formfields/customer/ftp/formfield.ftp_add.php'; @@ -346,7 +363,7 @@ if ($page == 'overview') { } } } elseif ($action == 'edit' && $id != 0) { - $result_stmt = Database::prepare("SELECT `id`, `username`, `description`, `homedir`, `uid`, `gid` FROM `" . TABLE_FTP_USERS . "` + $result_stmt = Database::prepare("SELECT `id`, `username`, `description`, `homedir`, `uid`, `gid`, `shell` FROM `" . TABLE_FTP_USERS . "` WHERE `customerid` = :customerid AND `id` = :id" ); @@ -358,6 +375,11 @@ if ($page == 'overview') { // @FIXME use a good path-validating regex here (refs #1231) $path = validate($_POST['path'], 'path'); + $shell = "/bin/false"; + if (Settings::Get('system.allow_customer_shell') == '1') { + $shell = isset($_POST['shell']) ? validate($_POST['shell'], 'shell') : '/bin/false'; + } + $_setnewpass = false; if (isset($_POST['ftp_password']) && $_POST['ftp_password'] != '') { $password = validate($_POST['ftp_password'], 'password'); @@ -411,11 +433,11 @@ if ($page == 'overview') { $log->logAction(USR_ACTION, LOG_INFO, "edited ftp-account '" . $result['username'] . "'"); $description = validate($_POST['ftp_description'], 'description'); $stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "` - SET `description` = :desc + SET `description` = :desc, `shell` = :shell WHERE `customerid` = :customerid AND `id` = :id" ); - Database::pexecute($stmt, array("desc" => $description, "customerid" => $userinfo['customerid'], "id" => $id)); + Database::pexecute($stmt, array("desc" => $description, "shell" => $shell, "customerid" => $userinfo['customerid'], "id" => $id)); redirectTo($filename, array('page' => $page, 's' => $s)); } else { @@ -441,6 +463,18 @@ if ($page == 'overview') { } } + if (Settings::Get('system.allow_customer_shell') == '1') { + $shells = makeoption("/bin/false", "/bin/false", $result['shell']); + $shells_avail = Settings::Get('system.available_shells'); + if (!empty($shells_avail)) { + $shells_avail = explode(",", $shells_avail); + $shells_avail = array_map("trim", $shells_avail); + foreach ($shells_avail as $_shell) { + $shells .= makeoption($_shell, $_shell, $result['shell']); + } + } + } + $ftp_edit_data = include_once dirname(__FILE__).'/lib/formfields/customer/ftp/formfield.ftp_edit.php'; $ftp_edit_form = htmlform::genHTMLForm($ftp_edit_data); diff --git a/install/froxlor.sql b/install/froxlor.sql index 82141521..87d9e0c7 100644 --- a/install/froxlor.sql +++ b/install/froxlor.sql @@ -530,6 +530,8 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('system', 'dnsenabled', '0'), ('system', 'dns_server', 'bind'), ('system', 'apacheglobaldiropt', ''), + ('system', 'allow_customer_shell', '0'), + ('system', 'available_shells', ''), ('panel', 'decimal_places', '4'), ('panel', 'adminmail', 'admin@SERVERNAME'), ('panel', 'phpmyadmin_url', ''), @@ -561,7 +563,7 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('panel', 'password_special_char_required', '0'), ('panel', 'password_special_char', '!?<>§$%+#=@'), ('panel', 'version', '0.9.37'), - ('panel', 'db_version', '201607210'); + ('panel', 'db_version', '201608260'); DROP TABLE IF EXISTS `panel_tasks`; diff --git a/install/updates/froxlor/0.9/update_0.9.inc.php b/install/updates/froxlor/0.9/update_0.9.inc.php index c71cd9fe..d8fa3a50 100644 --- a/install/updates/froxlor/0.9/update_0.9.inc.php +++ b/install/updates/froxlor/0.9/update_0.9.inc.php @@ -3415,3 +3415,13 @@ if (isFroxlorVersion('0.9.37-rc1')) { showUpdateStep("Updating from 0.9.37-rc1 to 0.9.37 final", false); updateToVersion('0.9.37'); } + +if (isDatabaseVersion('201607210')) { + + showUpdateStep("Adding new settings for customer shell option"); + Settings::AddNew("system.allow_customer_shell", "0"); + Settings::AddNew("system.available_shells", ""); + lastStepStatus(0); + + updateToDbVersion('201608260'); +} diff --git a/lib/formfields/customer/ftp/formfield.ftp_add.php b/lib/formfields/customer/ftp/formfield.ftp_add.php index 6bf224b2..17012537 100644 --- a/lib/formfields/customer/ftp/formfield.ftp_add.php +++ b/lib/formfields/customer/ftp/formfield.ftp_add.php @@ -64,6 +64,12 @@ return array( ), 'value' => array() ), + 'shell' => array( + 'visible' => (Settings::Get('system.allow_customer_shell') == '1' ? true : false), + 'label' => $lng['panel']['shell'], + 'type' => 'select', + 'select_var' => (isset($shells) ? $shells : ""), + ) ) ) ) diff --git a/lib/formfields/customer/ftp/formfield.ftp_edit.php b/lib/formfields/customer/ftp/formfield.ftp_edit.php index ba6fe920..20a2280d 100644 --- a/lib/formfields/customer/ftp/formfield.ftp_edit.php +++ b/lib/formfields/customer/ftp/formfield.ftp_edit.php @@ -51,6 +51,12 @@ return array( 'type' => 'text', 'visible' => (Settings::Get('panel.password_regex') == ''), 'value' => generatePassword(), + ), + 'shell' => array( + 'visible' => (Settings::Get('system.allow_customer_shell') == '1' ? true : false), + 'label' => $lng['panel']['shell'], + 'type' => 'select', + 'select_var' => (isset($shells) ? $shells : ""), ) ) ) diff --git a/lib/version.inc.php b/lib/version.inc.php index 2265248e..ac68d42a 100644 --- a/lib/version.inc.php +++ b/lib/version.inc.php @@ -19,7 +19,7 @@ $version = '0.9.37'; // Database version (YYYYMMDDC where C is a daily counter) -$dbversion = '201607210'; +$dbversion = '201608260'; // Distribution branding-tag (used for Debian etc.) $branding = ''; diff --git a/lng/english.lng.php b/lng/english.lng.php index 26bf7939..c506ba39 100644 --- a/lng/english.lng.php +++ b/lng/english.lng.php @@ -2022,7 +2022,13 @@ $lng['error']['domain_nopunycode'] = 'You must not specify punycode (IDNA). The $lng['admin']['dnsenabled'] = 'Enable DNS editor'; $lng['error']['dns_record_toolong'] = 'Records/labels can only be up to 63 characters'; -// Added in froxlor 0.9.7-rc1 +// Added in froxlor 0.9.37-rc1 $lng['serversettings']['panel_customer_hide_options']['title'] = 'Hide menu items and traffic charts in customer panel'; $lng['serversettings']['panel_customer_hide_options']['description'] = 'Select items to hide in customer panel. To select multiple options, hold down CTRL while selecting.'; +// Added in froxlor 0.9.37.1 +$lng['serversettings']['allow_allow_customer_shell']['title'] = 'Allow customers to enable shell access for ftp-users'; +$lng['serversettings']['allow_allow_customer_shell']['description'] = 'Please note: Shell access allows the user to execute various binaries on your system. Use with extrem caution. Please only activate this if you REALLY know what you are doing!!!'; +$lng['serversettings']['available_shells']['title'] = 'List of available shells'; +$lng['serversettings']['available_shells']['description'] = 'Comma seperated list of shells that are available for the customer to chose from for their ftp-users.

Note that the default shell /bin/false will always be a choice (if enabled), even if this setting is empty. It is the default value for ftp-users in any case'; +$lng['panel']['shell'] = 'Shell'; diff --git a/lng/german.lng.php b/lng/german.lng.php index 20989d1c..cee566c4 100644 --- a/lng/german.lng.php +++ b/lng/german.lng.php @@ -1678,3 +1678,9 @@ $lng['error']['dns_record_toolong'] = 'Records/Labels können maximal 63 Zeichen // Added in froxlor 0.9.37-rc1 $lng['serversettings']['panel_customer_hide_options']['title'] = 'Menüpunkte und Traffic-Charts im Kundenbereich ausblenden'; $lng['serversettings']['panel_customer_hide_options']['description'] = 'Wählen Sie hier die gewünschten Menüpunkte und Traffic-Charts aus, welche im Kundenbereich ausgeblendet werden sollen. Für Mehrfachauswahl, halten Sie während der Auswahl STRG gedrückt.'; + +// Added in froxlor 0.9.37.1 +$lng['serversettings']['allow_allow_customer_shell']['title'] = 'Erlaube Kunden für FTP Benutzer eine Shell auszuwählen'; +$lng['serversettings']['allow_allow_customer_shell']['description'] = 'Bitte beachten: Shell Zugriff gestattet dem Benutzer verschiedene Programme auf Ihrem System auszuführen. Mit großer Vorsicht verwenden. Bitte aktiviere dies nur wenn WIRKLICH bekannt ist, was das bedeutet!!!'; +$lng['serversettings']['available_shells']['title'] = 'Liste der verfügbaren Shells'; +$lng['serversettings']['available_shells']['description'] = 'Komme-getrennte Liste von Shells die der Kunde für seine FTP-Konten wählen kann.

Hinweis: Die Standard-Shell /bin/false wird immer eine Auswahlmöglichkeit sein (wenn aktiviert), auch wenn diese Einstellung leer ist. Sie ist in jedem Fall der Standardwert für alle FTP-Konten'; diff --git a/templates/Sparkle/customer/ftp/accounts.tpl b/templates/Sparkle/customer/ftp/accounts.tpl index e6a2c263..339bfe62 100644 --- a/templates/Sparkle/customer/ftp/accounts.tpl +++ b/templates/Sparkle/customer/ftp/accounts.tpl @@ -30,6 +30,9 @@ {$lng['login']['username']} {$arrowcode['username']} {$lng['panel']['ftpdesc']} {$arrowcode['description']} {$lng['panel']['path']} {$arrowcode['homedir']} + + {$lng['panel']['shell']} + {$lng['panel']['options']} @@ -58,4 +61,3 @@ $footer - diff --git a/templates/Sparkle/customer/ftp/accounts_account.tpl b/templates/Sparkle/customer/ftp/accounts_account.tpl index 8038e719..254894fe 100644 --- a/templates/Sparkle/customer/ftp/accounts_account.tpl +++ b/templates/Sparkle/customer/ftp/accounts_account.tpl @@ -2,6 +2,9 @@ {$row['username']} {$row['description']} {$row['documentroot']} + + {$row['shell']} + {$lng['panel']['edit']}