From 6a001aa768d5a7b9a9a5a638be84cee16df6afe0 Mon Sep 17 00:00:00 2001 From: Till Brehm <tbrehm@ispconfig.org> Date: Fri, 09 May 2014 09:23:50 -0400 Subject: [PATCH] Merge branch 'stable-3.0.5' of git.ispconfig.org:ispconfig/ispconfig3 into stable-3.0.5 --- server/conf/vhost.conf.master | 4 install/lib/installer_base.lib.php | 2 interface/web/admin/templates/directive_snippets_edit.htm | 2 interface/web/index.php | 16 + server/plugins-available/shelluser_jailkit_plugin.inc.php | 125 ++++++++----- interface/web/themes/default/templates/main.tpl.htm | 3 interface/lib/classes/validate_password.inc.php | 10 + interface/web/admin/lib/lang/de_system_config.lng | 2 interface/lib/classes/ispconfig_request.inc.php | 263 +++++++++++++++++++++++++++++ interface/web/js/scrigo.js.php | 101 ++++++++--- 10 files changed, 444 insertions(+), 84 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index cd5b01b..7d6348b 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -690,7 +690,7 @@ if(!is_user($cf['vmail_username'])) caselog("$command &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); //* These postconf commands will be executed on installation and update - $server_ini_rec = $this->db->queryOneRecord("SELECT config FROM server WHERE server_id = ".$conf['server_id']); + $server_ini_rec = $this->db->queryOneRecord("SELECT config FROM `" . $this->db->quote($conf["mysql"]["database"]) . "`.`server` WHERE server_id = ".$conf['server_id']); $server_ini_array = ini_to_array(stripslashes($server_ini_rec['config'])); unset($server_ini_rec); diff --git a/interface/lib/classes/ispconfig_request.inc.php b/interface/lib/classes/ispconfig_request.inc.php new file mode 100644 index 0000000..b29ae23 --- /dev/null +++ b/interface/lib/classes/ispconfig_request.inc.php @@ -0,0 +1,263 @@ +<?php + +/* +Copyright (c) 2013, Marius Cramer, pixcept KG +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +//* The purpose of this library is to provide some general functions. +//* This class is loaded automatically by the ispconfig framework. + +abstract class ISPConfigRequest { + /** + * Get header data and contents from an url + * + * Calls an url and returns an array containing the http header and the page content + * + * @access public + * @param string $url the url to call + * @param string $store_in the file to store the data in instead of returning them + * @return array The array with header data at index 0 and page content at index 1, returns boolean false on error. If $store_in is set only the headers are returned + */ + + + public static function get_with_headers($url, $store_in = null, $follow_redirects = false, $user_agent = false) { + if($follow_redirects === true) $follow_redirects = 5; + elseif($follow_redirects !== false) $follow_redirects--; + + if(!$user_agent) $user_agent = 'pxFW GET proxy'; + + $url_info = parse_url($url); + if(isset($url_info['scheme']) && $url_info['scheme'] == 'https') { + $port = isset($url_info['port']) ? $url_info['port'] : 443; + //@$fp = stream_socket_client('ssl://' . $url_info['host'] . ':' . $port, $errno, $errstr, 10, STREAM_CLIENT_CONNECT, stream_context_create(array('ssl' => array('ciphers' => 'ALL:!AES:!3DES:!RC4:@STRENGTH')))); + @$fp = fsockopen('sslv3://' . $url_info['host'], $port, $errno, $errstr, 10); + } else { + $port = isset($url_info['port']) ? $url_info['port'] : 80; + @$fp = fsockopen($url_info['host'], $port, $errno, $errstr, 10); + } + + if($store_in) { + $outfp = fopen($store_in, 'w'); + if(!$outfp) return false; + } + if($fp) { + stream_set_timeout($fp, 10); + $head = 'GET ' . (isset($url_info['path']) ? $url_info['path'] : '/') . (isset($url_info['query']) ? '?' . $url_info['query'] : ''); + $head .= " HTTP/1.0\r\nHost: " . (isset($url_info['host']) ? $url_info['host'] : '') . "\r\n"; + $head .= "User-Agent: " . $user_agent . "\r\n"; + if(isset($url_info['user'])) { + if(!array_key_exists('pass', $url_info)) $url_info['pass'] = ''; + $head .= "Authorization: basic " . base64_encode($url_info['user'] . ':' . $url_info['pass']) . "\r\n"; + } + $head .= "Connection: Close\r\n"; + $head .= "Accept: */*\r\n\r\n"; + + $data = ''; + $eoheader = false; + fputs($fp, $head); + while(!feof($fp)) { + if($header = fgets($fp, 1024)) { + if($eoheader == true) { + if($store_in) fputs($outfp, $header); + else $data .= $header; + continue; + } + + if ($header == "\r\n") { + $eoheader = true; + continue; + } else { + $header = trim($header); + } + $sc_pos = strpos($header, ':'); + if($sc_pos === false) { + $headers['status'] = $header; + $headers['http_code'] = intval(preg_replace('/^HTTP\/\d+\.\d+\s+(\d+)\s+.*$/', '$1', $header)); + } else { + $label = substr($header, 0, $sc_pos); + $value = substr($header, $sc_pos + 1); + $headers[strtolower($label)] = trim($value); + } + } + } + fclose($fp); + if(isset($headers['http_code']) && isset($headers['location']) && ($headers['http_code'] == 301 || $headers['http_code'] == 302) && $follow_redirects > 0) { + if($store_in) fclose($outfp); + return $self::get_with_headers($headers['location'], $store_in, $follow_redirects); + } + if($store_in) { + fclose($outfp); + + $code = intval(preg_replace('/^HTTP\/\d+\.\d+\s+(\d+)\s+.*$/', '$1', $headers['status'])); + if($code != 200) { + return false; + } + return $headers; + } else { + return array($headers, $data); + } + } else { + if($store_in) { + fclose($outfp); + @unlink($store_in); + } + return false; + } + } + + /** + * Gets the content of an url + * + * Checks for the php function file_get_contents and uses an alternative if not found + * + * @access public + * @param string $url url to get + * @return string url data including headers + * @see file_get_contents + */ + public static function get($url) { + if(function_exists('file_get_contents')) return file_get_contents($url); + + $fp = fopen($url, 'r'); + $data = ''; + while(!feof($fp)) { + $data .= fgets($fp, 8192); + } + fclose($fp); + + return $data; + } + + + /** + * Make a post request and get data + * + * Calls an url with a post request and returns the data - and optionally the header content + * + * @access public + * @param string $url the url to call + * @param string $data the post data to send + * @param bool $get_headers if true, the function will return an array like PXUrl::get_with_headers(), otherwise the content is returned as a string + * @return mixed Content data as string or - if get_headers is true - the array with header data at index 0 and page content at index 1 + * @see get_url_and_headers + */ + public static function post($url, $data, $get_headers = false, $user_agent = false) { + $url_info = parse_url($url); + if((isset($url_info['scheme']) && $url_info['scheme'] == 'https') || $url_info['port'] == 443) { + $port = (!isset($url_info['port']) || !$url_info['port'] || $url_info['port'] == 443 || $url_info['port'] == 80) ? 443 : $url_info['port']; + //@$fp = stream_socket_client('ssl://' . $url_info['host'] . ':' . $port, $errno, $errstr, 10, STREAM_CLIENT_CONNECT, stream_context_create(array('ssl' => array('ciphers' => 'ALL:!AES:!3DES:!RC4:@STRENGTH')))); + @$fp = fsockopen('sslv3://' . $url_info['host'], $port, $errno, $errstr, 10); + } else { + $port = isset($url_info['port']) ? $url_info['port'] : 80; + @$fp = fsockopen($url_info['host'], $port, $errno, $errstr, 10); + } + + if(!$fp) return ''; + + if(!$user_agent) $user_agent = 'pxFW GET proxy'; + + $header = 'POST ' . (isset($url_info['path']) ? $url_info['path'] : '/') . (isset($url_info['query']) ? '?' . @$url_info['query'] : '') . " HTTP/1.1\r\n"; + $header .= "Host: " . @$url_info['host'] . "\r\n"; + $header .= "User-Agent: " . $user_agent . "\r\n"; + if(isset($url_info['user'])) { + if(!array_key_exists('pass', $url_info)) $url_info['pass'] = ''; + $header .= "Authorization: basic " . base64_encode($url_info['user'] . ':' . $url_info['pass']) . "\r\n"; + } + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "Content-Length: " . strlen($data) . "\r\n"; + $header .= "Connection: close\r\n\r\n"; + $header .= $data . "\r\n\r\n"; + + fwrite($fp, $header); + + $response = ''; + $eoheader = false; + $header = ''; + $tmpdata = ''; + $chunked = false; + $chunklen = 0; + + while(!feof($fp)) { + if($header = @fgets($fp, 1024)) { + if($eoheader == true) { + $response .= $header; + continue; + } + + if ($header == "\r\n") { + $eoheader = true; + continue; + } else { + $tmpdata .= $header; + if(preg_match('/Transfer-Encoding:\s+chunked/i', $tmpdata)) $chunked = true; + } + } + } + //var_dump($response, $chunked, $header); + if($chunked == true) { + $lines = explode("\n", $response); + $response = ''; + $chunklen = 0; + foreach($lines as $line) { + $line .= "\n"; + if($chunklen <= 0) { + if(preg_match('/^([0-9a-f]+)\s*$/is', $line, $matches)) { + $chunklen = hexdec($matches[1]); + } + continue; + } + + if(strlen($line) > $chunklen) { + //echo "Warnung: " . strlen($line) . " > " . $chunklen . "\n"; + $line = substr($line, 0, $chunklen); + } + $response .= $line; + $chunklen -= strlen($line); + } + + $start = strpos($response, '<?xml'); + $end = strrpos($response, '>'); + if($start !== false && $end !== false) $response = substr($response, $start, $end - $start + 1); + } + + fclose($fp); + + if($get_headers == true) { + $tmpheaders = explode("\n", $tmpdata); + $headers = array(); + foreach($tmpheaders as $cur) { + if(preg_match('/^(\w+)\:\s*(.*)$/is', $cur, $matches)) { + $headers["$matches[1]"] = trim($matches[2]); + } + } + return array($headers, $response); + } else return $response; + } + +} + +?> diff --git a/interface/lib/classes/validate_password.inc.php b/interface/lib/classes/validate_password.inc.php index 543a90e..998c37c 100644 --- a/interface/lib/classes/validate_password.inc.php +++ b/interface/lib/classes/validate_password.inc.php @@ -38,19 +38,27 @@ return 1; } + $different = 0; + if (preg_match('/[abcdefghijklnmopqrstuvwxyz]/', $password)) { + $different += 1; + } + if (preg_match('/[ABCDEFGHIJKLNMOPQRSTUVWXYZ]/', $password)) { $points += 1; + $different += 1; } if (preg_match('/[0123456789]/', $password)) { $points += 1; + $different += 1; } if (preg_match('/[`~!@#$%^&*()_+|\\=-[]}{\';:\/?.>,<" ]/', $password)) { $points += 1; + $different += 1; } - if ($points == 0) { + if ($points == 0 || $different < 3) { if ($length >= 5 && $length <= 6) { return 1; } else if ($length >= 7 && $length <= 8) { diff --git a/interface/web/admin/lib/lang/de_system_config.lng b/interface/web/admin/lib/lang/de_system_config.lng index 272d312..ab73983 100644 --- a/interface/web/admin/lib/lang/de_system_config.lng +++ b/interface/web/admin/lib/lang/de_system_config.lng @@ -64,7 +64,7 @@ $wb['customer_no_start_txt'] = 'Kundennummer Startwert'; $wb['customer_no_counter_txt'] = 'Kundennummer Zähler'; $wb['session_timeout_txt'] = 'Session-Timeout (Minuten)'; -$wb['session_allow_endless_txt'] = '\\"Eingeloggt bleiben\\" aktivieren'; +$wb['session_allow_endless_txt'] = '"Eingeloggt bleiben" aktivieren'; $wb['No'] = 'Nein'; $wb['min_password_length_txt'] = 'Minimale Passwortlänge'; $wb['min_password_strength_txt'] = 'Minimale Passwortstärke'; diff --git a/interface/web/admin/templates/directive_snippets_edit.htm b/interface/web/admin/templates/directive_snippets_edit.htm index 6522eb1..7a17cb6 100644 --- a/interface/web/admin/templates/directive_snippets_edit.htm +++ b/interface/web/admin/templates/directive_snippets_edit.htm @@ -17,7 +17,7 @@ </div> <div class="ctrlHolder"> <label for="snippet">{tmpl_var name='snippet_txt'}</label> - <textarea name="snippet" id="snippet" rows='10' cols='50' style="width:400px;">{tmpl_var name='snippet'}</textarea><div class="nginx"> {tmpl_var name='variables_txt'}: <a href="javascript:void(0);" class="addPlaceholder">{DOCROOT}</a>, <a href="javascript:void(0);" class="addPlaceholder">{FASTCGIPASS}</a></div> + <textarea name="snippet" id="snippet" rows='10' cols='50' style="width:400px;">{tmpl_var name='snippet'}</textarea><span class="nginx"> {tmpl_var name='variables_txt'}: </span><a href="javascript:void(0);" class="addPlaceholder nginx">{DOCROOT}</a><span class="nginx">, </span><a href="javascript:void(0);" class="addPlaceholder nginx">{FASTCGIPASS}</a> </div> <div class="ctrlHolder"> <p class="label">{tmpl_var name='active_txt'}</p> diff --git a/interface/web/index.php b/interface/web/index.php index c6f0ff3..80eab11 100644 --- a/interface/web/index.php +++ b/interface/web/index.php @@ -60,6 +60,22 @@ unset($_SESSION['show_error_msg']); } +// read js.d files +$js_d = ISPC_WEB_PATH . '/js/js.d'; +$js_d_files = array(); +if(@is_dir($js_d)) { + $dir = opendir($js_d); + while($file = readdir($dir)) { + $filename = $js_d . '/' . $file; + if($file === '.' || $file === '..' || !is_file($filename)) continue; + if(substr($file, -3) !== '.js') continue; + $js_d_files[] = array('file' => $file); + } + closedir($dir); +} + +if (!empty($js_d_files)) $app->tpl->setLoop('js_d_includes', $js_d_files); +unset($js_d_files); $app->tpl_defaults(); $app->tpl->pparse(); diff --git a/interface/web/js/scrigo.js.php b/interface/web/js/scrigo.js.php index 7d15e30..4e51cd5 100644 --- a/interface/web/js/scrigo.js.php +++ b/interface/web/js/scrigo.js.php @@ -18,6 +18,7 @@ var indicatorPaddingH = -1; var indicatorPaddingW = -1; var indicatorCompleted = false; +var registeredHooks = new Array(); redirect = ''; function reportError(request) { @@ -26,6 +27,20 @@ ajax request worked. */ /*alert(request);*/ +} + +function registerHook(name, callback) { + if(!registeredHooks[name]) registeredHooks[name] = new Array(); + var newindex = registeredHooks[name].length; + registeredHooks[name][newindex] = callback; +} + +function callHook(name, params) { + if(!registeredHooks[name]) return; + for(var i = 0; i < registeredHooks[name].length; i++) { + var callback = registeredHooks[name][i]; + callback(name, params); + } } function resetFormChanged() { @@ -73,7 +88,9 @@ } } -function onAfterContentLoad() { +function onAfterContentLoad(url, data) { + if(!data) data = ''; + else data = '&' + data; <?php if($server_config_array['misc']['use_combobox'] == 'y'){ ?> @@ -81,6 +98,7 @@ <?php } ?> + callHook('onAfterContentLoad', {'url': url, 'data': data }); } function loadContentRefresh(pagename) { @@ -96,7 +114,7 @@ success: function(data, textStatus, jqXHR) { hideLoadIndicator(); jQuery('#pageContent').html(jqXHR.responseText); - onAfterContentLoad(); + onAfterContentLoad(pagename, "refresh="+document.getElementById('refreshinterval').value); pageFormChanged = false; }, error: function() { @@ -175,7 +193,7 @@ document.location.href = 'index.php'; } else { jQuery('#pageContent').html(jqXHR.responseText); - onAfterContentLoad(); + onAfterContentLoad('content.php', jQuery('#'+formname).serialize()); pageFormChanged = false; } loadMenus(); @@ -213,7 +231,7 @@ //window.setTimeout('loadContent(redirect)', 1000); } else { jQuery('#pageContent').html(jqXHR.responseText); - onAfterContentLoad(); + onAfterContentLoad(target, jQuery('#'+formname).serialize()); pageFormChanged = false; } hideLoadIndicator(); @@ -252,7 +270,7 @@ //window.setTimeout('loadContent(redirect)', 1000); } else { jQuery('#pageContent').html(jqXHR.responseText); - onAfterContentLoad(); + onAfterContentLoad(target, jQuery('#'+formname).serialize()); pageFormChanged = false; } hideLoadIndicator(); @@ -330,7 +348,7 @@ //jQuery.each(reponseScript, function(idx, val) { eval(val.text); } ); jQuery('#pageContent').html(jqXHR.responseText); - onAfterContentLoad(); + onAfterContentLoad(pagename, (params ? params : null)); pageFormChanged = false; } hideLoadIndicator(); @@ -357,7 +375,7 @@ loadContent(parts[1]); } else { jQuery('#pageContent').html(jqXHR.responseText); - onAfterContentLoad(); + onAfterContentLoad('content.php', "s_mod=login&s_pg=index"); pageFormChanged = false; } hideLoadIndicator(); @@ -561,6 +579,8 @@ pass_message['color'] = "green"; pass_messages[5] = pass_message; +var special_chars = "`~!@#$%^&*()_+|\=-[]}{';:/?.>,<\" "; + function pass_check(password) { var length = password.length; var points = 0; @@ -573,20 +593,29 @@ pass_result(1); return; } - + + var different = 0; + + if (pass_contains(password, "abcdefghijklnmopqrstuvwxyz")) { + different += 1; + } + if (pass_contains(password, "ABCDEFGHIJKLNMOPQRSTUVWXYZ")) { points += 1; + different += 1; } if (pass_contains(password, "0123456789")) { points += 1; + different += 1; } - if (pass_contains(password, "`~!@#$%^&*()_+|\=-[]}{';:/?.>,<\" ")) { + if (pass_contains(password, special_chars)) { points += 1; + different += 1; } - if (points == 0) { + if (points == 0 || different < 3) { if (length >= 5 && length <=6) { pass_result(1); } else if (length >= 7 && length <=8) { @@ -724,27 +753,45 @@ return rv; } -function password(minLength, special){ - var iteration = 0; - var password = ""; - var randomNumber; +function password(minLength, special, num_special){ minLength = minLength || 10; + if(minLength < 8) minLength = 8; var maxLength = minLength + 5; var length = getRandomInt(minLength, maxLength); - if(special == undefined){ - var special = false; + + var alphachars = "abcdefghijklmnopqrstuvwxyz"; + var upperchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + var numchars = "1234567890"; + var specialchars = "!@#_"; + + if(num_special == undefined) num_special = 0; + if(special != undefined && special == true) { + num_special = Math.floor(Math.random() * (length / 4)) + 1; } - while(iteration < length){ - randomNumber = (Math.floor((Math.random() * 100)) % 94) + 33; - if(!special){ - if ((randomNumber >=33) && (randomNumber <=47)) { continue; } - if ((randomNumber >=58) && (randomNumber <=64)) { continue; } - if ((randomNumber >=91) && (randomNumber <=96)) { continue; } - if ((randomNumber >=123) && (randomNumber <=126)) { continue; } - } - iteration++; - password += String.fromCharCode(randomNumber); + var numericlen = getRandomInt(1, 2); + var alphalen = length - num_special - numericlen; + var upperlen = Math.floor(alphalen / 2); + alphalen = alphalen - upperlen; + var password = ""; + + for(i = 0; i < alphalen; i++) { + password += alphachars.charAt(Math.floor(Math.random() * alphachars.length)); } + + for(i = 0; i < upperlen; i++) { + password += upperchars.charAt(Math.floor(Math.random() * upperchars.length)); + } + + for(i = 0; i < num_special; i++) { + password += specialchars.charAt(Math.floor(Math.random() * specialchars.length)); + } + + for(i = 0; i < numericlen; i++) { + password += numchars.charAt(Math.floor(Math.random() * numchars.length)); + } + + password = password.split('').sort(function() { return 0.5 - Math.random(); }).join(''); + return password; } @@ -760,7 +807,7 @@ var newPWField = oldPWField.clone(); newPWField.attr('type', 'text').attr('id', 'tmp'+passwordFieldID).insertBefore(oldPWField); oldPWField.remove(); - var pword = password(<?php echo $min_password_length ?>, false); + var pword = password(<?php echo $min_password_length; ?>, false, 1); jQuery('#'+repeatPasswordFieldID).val(pword); newPWField.attr('id', passwordFieldID).val(pword).trigger('keyup'); } diff --git a/interface/web/themes/default/templates/main.tpl.htm b/interface/web/themes/default/templates/main.tpl.htm index fd38222..9146291 100644 --- a/interface/web/themes/default/templates/main.tpl.htm +++ b/interface/web/themes/default/templates/main.tpl.htm @@ -18,6 +18,9 @@ <script type="text/javascript" src="js/uni-form/uni-form.jquery.js"></script> <script type="text/javascript" src="js/jquery.ispconfigsearch.js"></script> <script type="text/javascript" src="js/jquery.tipsy.js"></script> + <tmpl_loop name="js_d_includes"> + <script type="text/javascript" src="js/js.d/<tmpl_var name='file'>"></script> + </tmpl_loop> <script language="JavaScript" type="text/javascript"> jQuery(document).ready(function() { loadInitContent(); diff --git a/server/conf/vhost.conf.master b/server/conf/vhost.conf.master index f78efe5..5a110cc 100644 --- a/server/conf/vhost.conf.master +++ b/server/conf/vhost.conf.master @@ -335,7 +335,9 @@ RewriteCond %{REQUEST_URI} !^/php5-fcgi/ RewriteCond %{REQUEST_URI} !^<tmpl_var name='rewrite_target'> </tmpl_if> - RewriteRule ^/(.*)$ <tmpl_var name='rewrite_target'><tmpl_if name="rewrite_add_path" op="==" value="y">$1</tmpl_if> <tmpl_var name='rewrite_type'> + + RewriteRule ^/(.*)$ <tmpl_var name='rewrite_target'><tmpl_if name="rewrite_add_path" op="==" value="y">$1</tmpl_if> <tmpl_if name='rewrite_type' value=''><tmpl_if name="rewrite_is_url" op="==" value="n">[PT]</tmpl_if></tmpl_else><tmpl_var name='rewrite_type'></tmpl_if> + </tmpl_loop> </tmpl_if> diff --git a/server/plugins-available/shelluser_jailkit_plugin.inc.php b/server/plugins-available/shelluser_jailkit_plugin.inc.php index 9816b70..90ed677 100755 --- a/server/plugins-available/shelluser_jailkit_plugin.inc.php +++ b/server/plugins-available/shelluser_jailkit_plugin.inc.php @@ -33,6 +33,7 @@ //* $plugin_name and $class_name have to be the same then the name of this class var $plugin_name = 'shelluser_jailkit_plugin'; var $class_name = 'shelluser_jailkit_plugin'; + var $min_uid = 499; //* This function is called during ispconfig installation to determine // if a symlink shall be created for this plugin. @@ -73,50 +74,60 @@ $app->uses('system'); $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$data['new']['parent_domain_id']); - if($app->system->is_user($data['new']['username'])) { + if($app->system->is_user($data['new']['puser'])) { + // Get the UID of the parent user + $uid = intval($app->system->getuid($data['new']['puser'])); + if($uid > $this->min_uid) { + + if($app->system->is_user($data['new']['username'])) { - /** - * Setup Jailkit Chroot System If Enabled - */ + /** + * Setup Jailkit Chroot System If Enabled + */ + + if ($data['new']['chroot'] == "jailkit") + { - if ($data['new']['chroot'] == "jailkit") - { + // load the server configuration options + $app->uses("getconf"); + $this->data = $data; + $this->app = $app; + $this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit'); + $this->_update_website_security_level(); - // load the server configuration options - $app->uses("getconf"); - $this->data = $data; - $this->app = $app; - $this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit'); + $app->system->web_folder_protection($web['document_root'], false); - $this->_update_website_security_level(); + $this->_setup_jailkit_chroot(); - $app->system->web_folder_protection($web['document_root'], false); + $this->_add_jailkit_user(); - $this->_setup_jailkit_chroot(); + //* call the ssh-rsa update function + $this->_setup_ssh_rsa(); - $this->_add_jailkit_user(); + //$command .= 'usermod -s /usr/sbin/jk_chrootsh -U '.escapeshellcmd($data['new']['username']); + //exec($command); + $app->system->usermod($data['new']['username'], 0, 0, '', '/usr/sbin/jk_chrootsh', '', ''); - //* call the ssh-rsa update function - $this->_setup_ssh_rsa(); + //* Unlock user + $command = 'usermod -U '.escapeshellcmd($data['new']['username']).' 2>/dev/null'; + exec($command); - //$command .= 'usermod -s /usr/sbin/jk_chrootsh -U '.escapeshellcmd($data['new']['username']); - //exec($command); - $app->system->usermod($data['new']['username'], 0, 0, '', '/usr/sbin/jk_chrootsh', '', ''); + $this->_update_website_security_level(); + $app->system->web_folder_protection($web['document_root'], true); + } - //* Unlock user - $command = 'usermod -U '.escapeshellcmd($data['new']['username']).' 2>/dev/null'; - exec($command); + $app->log("Jailkit Plugin -> insert username:".$data['new']['username'], LOGLEVEL_DEBUG); - $this->_update_website_security_level(); - $app->system->web_folder_protection($web['document_root'], true); + } else { + $app->log("Jailkit Plugin -> insert username:".$data['new']['username']." skipped, the user does not exist.", LOGLEVEL_WARN); + } + } else { + $app->log("UID = $uid for shelluser:".$data['new']['username']." not allowed.", LOGLEVEL_ERROR); } - - $app->log("Jailkit Plugin -> insert username:".$data['new']['username'], LOGLEVEL_DEBUG); - } else { - $app->log("Jailkit Plugin -> insert username:".$data['new']['username']." skipped, the user does not exist.", LOGLEVEL_WARN); + $app->log("Skipping insertion of user:".$data['new']['username'].", parent user ".$data['new']['puser']." does not exist.", LOGLEVEL_WARN); } } @@ -128,41 +139,51 @@ $app->uses('system'); $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$data['new']['parent_domain_id']); - if($app->system->is_user($data['new']['username'])) { + if($app->system->is_user($data['new']['puser'])) { + // Get the UID of the parent user + $uid = intval($app->system->getuid($data['new']['puser'])); + if($uid > $this->min_uid) { + + + if($app->system->is_user($data['new']['username'])) { + /** + * Setup Jailkit Chroot System If Enabled + */ + if ($data['new']['chroot'] == "jailkit") + { + // load the server configuration options + $app->uses("getconf"); + $this->data = $data; + $this->app = $app; + $this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit'); - /** - * Setup Jailkit Chroot System If Enabled - */ - if ($data['new']['chroot'] == "jailkit") - { + $this->_update_website_security_level(); - // load the server configuration options - $app->uses("getconf"); - $this->data = $data; - $this->app = $app; - $this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit'); + $app->system->web_folder_protection($web['document_root'], false); - $this->_update_website_security_level(); + $this->_setup_jailkit_chroot(); + $this->_add_jailkit_user(); - $app->system->web_folder_protection($web['document_root'], false); + //* call the ssh-rsa update function + $this->_setup_ssh_rsa(); - $this->_setup_jailkit_chroot(); - $this->_add_jailkit_user(); + $this->_update_website_security_level(); - //* call the ssh-rsa update function - $this->_setup_ssh_rsa(); + $app->system->web_folder_protection($web['document_root'], true); + } - $this->_update_website_security_level(); + $app->log("Jailkit Plugin -> update username:".$data['new']['username'], LOGLEVEL_DEBUG); - $app->system->web_folder_protection($web['document_root'], true); + } else { + $app->log("Jailkit Plugin -> update username:".$data['new']['username']." skipped, the user does not exist.", LOGLEVEL_WARN); + } + } else { + $app->log("UID = $uid for shelluser:".$data['new']['username']." not allowed.", LOGLEVEL_ERROR); } - - $app->log("Jailkit Plugin -> update username:".$data['new']['username'], LOGLEVEL_DEBUG); - } else { - $app->log("Jailkit Plugin -> update username:".$data['new']['username']." skipped, the user does not exist.", LOGLEVEL_WARN); + $app->log("Skipping update for user:".$data['new']['username'].", parent user ".$data['new']['puser']." does not exist.", LOGLEVEL_WARN); } } -- Gitblit v1.9.1