diff --git a/lib/html_filter.php b/lib/html_filter.php index 6082a7b0e0..24c72b5ad6 100644 --- a/lib/html_filter.php +++ b/lib/html_filter.php @@ -146,6 +146,12 @@ public function filter_render() { return true; } + public function filter_sanitize() { + $this->sanitize_filter_variables(); + + return true; + } + private function create_filter() { if (!cacti_sizeof($this->filter_array)) { $this->filter_array = $this->default_filter; diff --git a/support.php b/support.php new file mode 100644 index 0000000000..de306cfadd --- /dev/null +++ b/support.php @@ -0,0 +1,1755 @@ + session_id(), 'time' => time()])); + } else { + raise_message('lockout', __('Cacti maintenance lockout has been cleared by \'%s\'. Press the button again after Cacti maintenance is over.', get_username($admin)), MESSAGE_LEVEL_INFO); + cacti_log('WARNING: Cacti maintenance lockout has been cleared by the primary administrator!'); + set_config_option('cacti_lockout_status', ''); + } + } + + header('Location: support.php?tab=summary'); + + exit; +} + +function support_view_tech() : void { + global $database_hostname, $poller_options, $input_types, $local_db_cnn_id; + + // ================= input validation ================= + gfrv('tab', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^([a-z_A-Z]+)$/']]); + // ==================================================== + + // present a tabbed interface + $tabs = [ + 'summary' => [ + 'display' => __('Summary'), + 'header' => true + ], + 'database' => [ + 'display' => __('Database Tables'), + 'header' => true + ], + 'dbsettings' => [ + 'display' => __('Database Settings'), + 'header' => true + ], + 'dbstatus' => [ + 'display' => __('Database Status'), + 'header' => true + ], + 'dbperms' => [ + 'display' => __('Database Permissions'), + 'header' => true + ], + 'processes' => [ + 'display' => __('Database Queries'), + 'header' => false + ], + 'background' => [ + 'display' => __('Background Processes'), + 'header' => false + ], + 'poller' => [ + 'display' => __('Poller Stats'), + 'header' => true + ], + 'phpinfo' => [ + 'display' => __('PHP Info'), + 'header' => true + ], + 'changelog' => [ + 'display' => __('ChangeLog'), + 'header' => true + ], + ]; + + // set the default tab + load_current_session_value('tab', 'sess_ts_tabs', 'summary'); + $current_tab = gnrv('tab'); + + // the processes and background will set their own timeouts + $page = 'support.php?tab=' . $current_tab; + + if ($current_tab != 'processes' && $current_tab != 'background') { + $refresh = [ + 'seconds' => 999999, + 'page' => $page, + 'logout' => 'false' + ]; + + set_page_refresh($refresh); + } + + $header_label = __esc('Technical Support [ %s ]', $tabs[$current_tab]['display']); + + top_header(); + + if (cacti_sizeof($tabs)) { + // draw the tabs + print "
'; + } + + // Display tech information + if (!isset($tabs[$current_tab]['header']) || $tabs[$current_tab]['header'] === true) { + html_start_box($header_label, '100%', false, 3, 'center', ''); + } + + switch (grv('tab')) { + case 'summary': + show_tech_summary(); + + break; + case 'dbstatus': + show_database_status(); + + break; + case 'dbperms': + show_database_permissions(); + + break; + case 'dbsettings': + show_database_settings(); + + break; + case 'changelog': + show_cacti_changelog(); + + break; + case 'database': + show_database_tables(); + + break; + case 'poller': + show_cacti_poller(); + + break; + case 'phpinfo': + show_php_modules(); + + break; + case 'processes': + show_database_processes(); + + break; + case 'background': + show_cacti_processes(); + + break; + } + + if (!isset($tabs[$current_tab]['header']) || $tabs[$current_tab]['header'] === true) { + html_end_box(); + } + + ?> + + __('Any')]; + $none = ['0' => __('None')]; + + $refresh = [ + 1 => __esc('%d Seconds', 1), + 3 => __esc('%d Seconds', 3), + 5 => __esc('%d Seconds', 5), + 10 => __esc('%d Seconds', 10), + 15 => __esc('%d Seconds', 15), + 20 => __esc('%d Seconds', 20) + ]; + + $pollers = [ + '0' => __('No'), + '1' => __('Yes') + ]; + + $chars = [ + 150 => __esc('%d Chars', 150), + 180 => __esc('%d Chars', 180), + 300 => __esc('%d Chars', 300), + 500 => __esc('%d Chars', 500), + 1000 => __esc('%d Chars', 1000), + ]; + + return [ + 'rows' => [ + [ + 'filter' => [ + 'method' => 'textbox', + 'friendly_name' => __('Search'), + 'filter' => FILTER_DEFAULT, + 'placeholder' => __('Enter a search term'), + 'size' => '30', + 'default' => '', + 'pageset' => true, + 'max_length' => '120', + 'value' => '' + ], + 'refresh' => [ + 'method' => 'drop_array', + 'friendly_name' => __('Refresh'), + 'filter' => FILTER_VALIDATE_INT, + 'default' => '5', + 'pageset' => true, + 'array' => $refresh, + 'value' => '5' + ], + 'poller' => [ + 'method' => 'drop_array', + 'friendly_name' => __('Include Poller'), + 'filter' => FILTER_VALIDATE_INT, + 'default' => '0', + 'pageset' => true, + 'array' => $pollers, + 'value' => '0' + ], + 'length' => [ + 'method' => 'drop_array', + 'friendly_name' => __('Template'), + 'filter' => FILTER_VALIDATE_INT, + 'default' => '180', + 'pageset' => true, + 'array' => $chars, + 'value' => '180' + ], + 'rows' => [ + 'method' => 'drop_array', + 'friendly_name' => __('Queries'), + 'filter' => FILTER_VALIDATE_INT, + 'default' => '-1', + 'pageset' => true, + 'array' => $item_rows, + 'value' => '-1' + ] + ] + ], + 'buttons' => [ + 'go' => [ + 'method' => 'submit', + 'display' => __('Go'), + 'title' => __('Apply Filter to Table'), + ], + 'clear' => [ + 'method' => 'button', + 'display' => __('Clear'), + 'title' => __('Reset Filter to Default Values'), + ] + ], + 'sort' => [ + 'sort_column' => 'runtime', + 'sort_direction' => 'DESC' + ], + 'javascript' => [ + 'ready' => "$('#refresh').click(function() { clearTimeout(myRefresh); });" + ] + ]; +} + +function draw_database_process_filter(bool $render = false) : void { + $filters = create_database_process_filter(); + + $header = __('Technical Support [ Database Queries ]'); + + // create the page filter + $pageFilter = new CactiTableFilter($header, 'support.php?tab=processes', 'form_db_stats', 'sess_ts_proc'); + + $pageFilter->set_filter_array($filters); + + if ($render) { + $pageFilter->filter_render(); + } else { + $pageFilter->filter_sanitize(); + } +} + +function show_database_processes() : void { + global $item_rows; + + draw_database_process_filter(true); + + if (grv('rows') == '-1') { + $rows = read_config_option('num_rows_table'); + } else { + $rows = grv('rows'); + } + + $sql_where = 'WHERE info NOT LIKE "%FROM processlist%" AND info != "NULL"'; + $sql_params = []; + + // form the 'where' clause for our main sql query + if (grv('filter') != '') { + $sql_where .= ($sql_where != '' ? ' AND ' : 'WHERE ') . + '(command LIKE ? OR info LIKE ?)'; + + $sql_params[] = '%' . grv('filter') . '%'; + $sql_params[] = '%' . grv('filter') . '%'; + } + + if (grv('poller') == '0') { + $sql_where .= ($sql_where != '' ? ' AND ' : 'WHERE ') . 'info NOT LIKE "%poller_output%" AND ' . + 'info NOT LIKE "%poller_item%" AND info NOT LIKE "%SQL_NO_CACHE%"'; + } + + $total_rows = db_fetch_cell_prepared("SELECT COUNT(*) + FROM information_schema.processlist + $sql_where", + $sql_params); + + $sql_order = get_order_string(); + $sql_limit = ' LIMIT ' . ($rows * (grv('page') - 1)) . ',' . $rows; + $info_len = grv('length'); + + $version = db_get_global_variable('innodb_version'); + + if (db_column_exists('information_schema`.`processlist', 'query_id')) { + $query_id = 'query_id'; + $time_ms = 'ROUND(time_ms/1000,2) AS runtime'; + } else { + $query_id = "'N/A' AS query_id"; + $time_ms = '`time` AS runtime'; + } + + $processes = db_fetch_assoc_prepared("SELECT id, $query_id, user, state, $time_ms, LENGTH(info) AS query_len, + SUBSTRING(REPLACE(REPLACE(REPLACE(info, '\n', ' '), ',', ', '), '\t', ' '), 1, $info_len) AS info + FROM information_schema.processlist + $sql_where + $sql_order + $sql_limit", + $sql_params); + + $display_text = [ + 'id' => [ + 'display' => __('Process ID'), + 'align' => 'left', + 'sort' => 'ASC', + 'tip' => __('The Connection ID of the running process.') + ], + 'query_id' => [ + 'display' => __('Query ID'), + 'align' => 'left', + 'sort' => 'ASC', + 'tip' => __('The Query ID of the currently running Query.') + ], + 'user' => [ + 'display' => __('User'), + 'align' => 'left', + 'sort' => 'ASC', + 'tip' => __('The MariaDB/MySQL user currently running the Query.') + ], + 'runtime' => [ + 'display' => __('Run Time'), + 'align' => 'right', + 'tip' => __('The Runtime of the current query in seconds.') + ], + 'query_len' => [ + 'display' => __('Query Length'), + 'align' => 'right', + 'tip' => __('The total string length of the Query.') + ], + 'state' => [ + 'display' => __('Query State'), + 'align' => 'center', + 'sort' => 'ASC', + 'tip' => __('The MariaDB/MySQL process state.') + ], + 'info' => [ + 'display' => __('Query Details'), + 'align' => 'left', + 'tip' => __('The Query Details for the current query upto a maximum string length.') + ] + ]; + + $nav = html_nav_bar('support.php?tab=processes', MAX_DISPLAY_PAGES, grv('page'), $rows, $total_rows, 7, __('Queries'), 'page', 'main'); + + print $nav; + + html_start_box('', '100%', false, 3, 'center', ''); + + html_header_sort($display_text, grv('sort_column'), grv('sort_direction'), 1, 'support.php?tab=processes', 'main'); + + if (cacti_sizeof($processes)) { + foreach ($processes as $p) { + form_alternate_row('line' . $p['id'], false); + + form_selectable_cell($p['id'], $p['id']); + form_selectable_cell($p['query_id'], $p['id']); + form_selectable_ecell($p['user'], $p['id']); + form_selectable_cell(number_format_i18n($p['runtime'], 2), $p['id'], '', 'right'); + form_selectable_cell(number_format_i18n($p['query_len']), $p['id'], '', 'right'); + form_selectable_ecell($p['state'], $p['id'], '', 'center'); + form_selectable_ecell($p['info'], $p['id'], '', 'white-space:pre-wrap'); + + form_end_row(); + } + } else { + print "| " . __('Description') . ' | '; + print "" . __('ID') . ' | '; + print "" . __('Avg Polling Time') . ' | '; + print "" . __('Actual Polling Time') . ' | '; + print '' . htmle($host['description']) . ' | '; + print '' . $host['id'] . ' | '; + print '' . number_format_i18n($host['avg_time'],3) . ' | '; + print '' . number_format_i18n($host['polling_time'],3) . ' | '; + form_end_row(); + } + + print '
|---|
| " . __('Description') . ' | '; + print "" . __('ID') . ' | '; + print "" . __('Failed/Total polls') . ' | '; + print '' . htmle($host['description']) . ' | '; + print '' . $host['id'] . ' | '; + print '' . number_format_i18n($host['ratio'],3) . ' | '; + form_end_row(); + } + + print '
|---|
| " . __('Name') . ' | '; + print "" . __('Engine') . ' | '; + print "" . __('Rows') . ' | '; + print "" . __('Avg Row Length') . ' | '; + print "" . __('Data Length') . ' | '; + print "" . __('Index Length') . ' | '; + print "" . __('Collation') . ' | '; + print "" . __('Row Format') . ' | '; + print "" . __('Comment') . ' | '; + print '' . $table['TABLE_NAME'] . ' | '; + print '' . $table['ENGINE'] . ' | '; + print '' . number_format_i18n($table['TABLE_ROWS'], -1) . ' | '; + print '' . number_format_i18n($table['AVG_ROW_LENGTH'], -1) . ' | '; + print '' . number_format_i18n($table['DATA_LENGTH'], -1) . ' | '; + print '' . number_format_i18n($table['INDEX_LENGTH'], -1) . ' | '; + print '' . $table['TABLE_COLLATION'] . ' | '; + print '' . $table['ROW_FORMAT'] . ' | '; + print '' . $table['TABLE_COMMENT'] . ' | '; + form_end_row(); + } + + print '
|---|
| " . __('Variable Name') . ' | '; + print "" . __('Value') . ' | '; + print '' . htmle($s['Variable_name']) . ' | '; + + if (strlen($s['Value']) > 70) { + $s['Value'] = str_replace(',', ', ', $s['Value']); + } + + print '' . (is_numeric($s['Value']) ? number_format_i18n($s['Value'], -1) : htmle($s['Value'])) . ' | '; + form_end_row(); + } +} + +function show_database_permissions() : void { + $status = db_get_permissions(true); + + $display_text = [ + __('Permission Name'), __('Database'), __('Value'), + __('Permission Name'), __('Database'), __('Value') + ]; + + html_header($display_text); + + $r = 0; + $j = 1; + + foreach ($status as $database => $perms) { + $first = true; + $r = 0; + + foreach ($perms as $key => $value) { + if (($r % 2) == 0 || $first) { + form_alternate_row("line$j"); + } + + print '' . $key . ' | '; + print '' . $database . ' | '; + print '' . ($value ? __('Yes') : __('No')) . ' | '; + + if (($r % 2) == 1) { + form_end_row(); + } + + $r++; + $first = false; + } + + if (($r % 2) == 1) { + print ''; + print ' | '; + print ' | '; + form_end_row(); + $j++; + } + } +} + +function show_database_status() : void { + $status = db_fetch_assoc('show global status'); + + print " |
|---|
| " . __('Variable Name') . ' | '; + print "" . __('Value') . ' | '; + print '' . htmle($s['Variable_name']) . ' | '; + print '' . (is_numeric($s['Value']) ? number_format_i18n($s['Value'], -1) : htmle($s['Value'])) . ' | '; + form_end_row(); + } +} + +function show_tech_summary() : void { + global $database_hostname, $poller_options, $input_types, $local_db_cnn_id; + + // Get poller stats + $poller_item = db_fetch_assoc('SELECT action, count(action) AS total + FROM poller_item + GROUP BY action'); + + // Get system stats + $host_count = db_fetch_cell('SELECT COUNT(*) FROM host WHERE deleted = ""'); + $graph_count = db_fetch_cell('SELECT COUNT(*) FROM graph_local'); + $data_count = db_fetch_assoc('SELECT i.type_id, COUNT(i.type_id) AS total + FROM data_template_data AS d, data_input AS i + WHERE d.data_input_id = i.id + AND local_data_id > 0 + GROUP BY i.type_id'); + + // Get RRDtool version + $rrdtool_version = __('Unknown'); + $rrdtool_release = __('Unknown'); + $storage_location = read_config_option('storage_location'); + + $out_array = []; + + if ($storage_location == 0) { + if ((file_exists(read_config_option('path_rrdtool'))) && ((function_exists('is_executable')) && (is_executable(read_config_option('path_rrdtool'))))) { + cacti_exec(read_config_option('path_rrdtool'), array(), $out_array); + } + } else { + $rrdtool_pipe = rrd_init(); + $out_array[] = rrdtool_execute('info', false, RRDTOOL_OUTPUT_STDOUT, $rrdtool_pipe, 'WEBLOG'); + rrd_close($rrdtool_pipe); + } + + if (cacti_sizeof($out_array) > 0) { + if (preg_match('/^RRDtool ([0-9.]+)/', $out_array[0], $m)) { + preg_match('/^([0-9]+\.[0-9]+\.[0.9]+)/', $m[1], $m2); + $rrdtool_release = $m[1]; + $rrdtool_version = $rrdtool_release; + } + } + + // Get SNMP cli version + if ((file_exists(read_config_option('path_snmpget'))) && ((function_exists('is_executable')) && (is_executable(read_config_option('path_snmpget'))))) { + $out = array(); + cacti_exec(read_config_option('path_snmpget'), array('-V'), $out); + $snmp_version = implode("\n", $out); + } else { + $snmp_version = "" . __('NET-SNMP Not Installed or its paths are not set. Please install if you wish to monitor SNMP enabled devices.') . ''; + } + + // Check RRDtool issues + $rrdtool_errors = array(); + + if (cacti_version_compare($rrdtool_version, get_rrdtool_version(), '<')) { + $rrdtool_errors[] = "" . __('ERROR: Installed RRDtool version does not exceed configured version.' . __('Cacti Lockout Status') . ' | '; + + if ($enabled >= 0) { + if ($lockout != '') { + $lockout = json_decode($lockout, true); + + if (is_array($lockout) && isset($lockout['time'])) { + $unlock_time = $lockout['time'] + (30 * 60); + } else { + $unlock_time = time() + (30 * 60); + } + + $unlock_hms = date('H:i', $unlock_time); + + print ''; + } else { + print ' | '; + } + } else { + print ' | '; + } + form_end_row(); + + form_alternate_row(); + print ' | ' . __('Date') . ' | '; + print '' . date('r') . ' | '; + form_end_row(); + + api_plugin_hook_function('custom_version_info'); + + form_alternate_row(); + print '' . __('Cacti Version') . ' | '; + print '' . CACTI_VERSION . ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('Cacti OS') . ' | '; + print '' . CACTI_SERVER_OS . ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('RSA Fingerprint') . ' | '; + print '' . read_config_option('rsa_fingerprint') . ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('NET-SNMP Version') . ' | '; + print '' . $snmp_version . ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('RRDtool Version') . ' ' . __('Configured') . ' | '; + print '' . get_rrdtool_version() . '+ | '; + form_end_row(); + + form_alternate_row(); + print '' . __('RRDtool Version') . ' ' . __('Found') . ' | '; + print '' . $rrdtool_release . ' | '; + form_end_row(); + + if (!empty($rrdtool_errors)) { + form_alternate_row(); + print ''; + $br = ''; + print ' | ';
+
+ foreach ($rrdtool_errors as $rrdtool_error) {
+ print $br . $rrdtool_error;
+ $br = ' '; + } + print ' | ';
+ form_end_row();
+ }
+
+ form_alternate_row();
+ print '' . __('Devices') . ' | '; + print '' . number_format_i18n($host_count, -1) . ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('Graphs') . ' | '; + print '' . number_format_i18n($graph_count, -1) . ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('Data Sources') . ' | '; + print '';
+ $data_total = 0;
+
+ if (cacti_sizeof($data_count)) {
+ foreach ($data_count as $item) {
+ print $input_types[$item['type_id']] . ': ' . number_format_i18n($item['total'], -1) . ' '; + $data_total += $item['total']; + } + print __('Total: %s', number_format_i18n($data_total, -1)); + } else { + print "0"; + } + print ' | ';
+ form_end_row();
+
+ html_section_header(__('Poller Information'), 2);
+
+ form_alternate_row();
+ print '' . __('Interval') . ' | '; + print '' . read_config_option('poller_interval') . ' | '; + + if (file_exists(read_config_option('path_spine')) && $poller_options[read_config_option('poller_type')] == 'spine') { + $type = $spine_version; + + if (!strpos($spine_version, CACTI_VERSION)) { + $type .= ' (' . __('Different version of Cacti and Spine!') . ')'; + } + } else { + $type = $poller_options[read_config_option('poller_type')]; + } + form_end_row(); + + form_alternate_row(); + print '' . __('Type') . ' | '; + print '' . $type . ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('Items') . ' | '; + print '';
+ $total = 0;
+
+ if (cacti_sizeof($poller_item)) {
+ foreach ($poller_item as $item) {
+ print __('Action[%s]', $item['action']) . ': ' . number_format_i18n($item['total'], -1) . ' '; + $total += $item['total']; + } + print __('Total: %s', number_format_i18n($total, -1)); + } else { + print "" . __('No items to poll') . ''; + } + print ' | ';
+ form_end_row();
+
+ $processes = db_fetch_cell('SELECT
+ GROUP_CONCAT(
+ CONCAT("' . __('Name: ') . '", name, ", ' . __('Procs: ') . '", processes) SEPARATOR "' . __('Concurrent Processes') . ' | '; + print '' . $processes . ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('Max Threads') . ' | '; + print '' . $threads . ' | '; + form_end_row(); + + $script_servers = read_config_option('php_servers'); + + form_alternate_row(); + print '' . __('PHP Servers') . ' | '; + print '' . htmle($script_servers) . ' | '; + form_end_row(); + + if (POLLER_ID == 1) { + $max_connections = db_get_global_variable('max_connections'); + $max_local_connections = 0; + } elseif (CACTI_CONNECTION == 'online') { + $max_connections = db_get_global_variable('max_connections'); + $max_local_connections = db_get_global_variable('max_connections', $local_db_cnn_id); + } else { + $max_connections = 0; + $max_local_connections = db_get_global_variable('max_connections'); + } + + $total_dc_threads = db_fetch_cell("SELECT + SUM((processes * threads) + (processes * $script_servers)) AS threads + FROM poller + WHERE disabled = ''"); + + $recommend_mc = $total_dc_threads + 100; + + if ($recommend_mc > $max_connections) { + if (POLLER_ID == 1) { + $db_connections = '' . __('Main Server: Current: %s, Min Required: %s', $max_connections, $recommend_mc) . ''; + } elseif (CACTI_CONNECTION == 'online') { + $db_connections = '' . __('Main Server: Current: %s, Min Required: %s', $max_connections, $recommend_mc) . ''; + } else { + $db_connections = ''; + } + } else { + if (POLLER_ID == 1) { + $db_connections = '' . __('Main Server: Current: %s, Min Required: %s', $max_connections, $recommend_mc) . ''; + } elseif (CACTI_CONNECTION == 'online') { + $db_connections = '' . __('Main Server: Current: %s, Min Required: %s', $max_connections, $recommend_mc) . ''; + } else { + $db_connections = ''; + } + } + + if (POLLER_ID > 1) { + if ($recommend_mc > $max_local_connections) { + $db_connections .= '' . __('Minimum Connections:') . ' | '; + print '' . $db_connections . ' ' . + __('Assumes 100 spare connections for Web page users and other various connections.') . ' ' . + __('The minimum required can vary greatly if there is heavy user Graph viewing activity.') . ' ' . + __('Each browser tab can use upto 10 connections depending on the browser.') . ' | ';
+ form_end_row();
+
+ form_alternate_row();
+ print '' . __('Script Timeout') . ' | '; + print '' . read_config_option('script_timeout') . ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('Max OID') . ' | '; + print '' . read_config_option('max_get_size') . ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('Last Run Statistics') . ' | '; + print '' . read_config_option('stats_poller') . ' | '; + form_end_row(); + + // Get System Memory + $memInfo = utilities_get_system_memory(); + + // print '$name | "; + print '' . number_format_i18n($value / 1000, 2) . ' MB | '; + form_end_row(); + } else { + switch($name) { + case 'SwapTotal': + case 'SwapFree': + case 'Cached': + case 'MemTotal': + case 'MemFree': + case 'MemAvailable': + case 'Buffers': + case 'Active': + case 'Inactive': + // Convert to GBi + $value /= (1000 * 1000 * 1000); + + form_alternate_row(); + print "$name | "; + print '' . __('%s GB', number_format_i18n($value, 2, 1000)) . ' | '; + form_end_row(); + + if ($name == 'MemTotal') { + $total_memory = $value; + } + } + } + } + + form_end_row(); + } + + $mysql_info = get_mysql_info(POLLER_ID); + + $database = $mysql_info['database']; + $version = $mysql_info['version']; + $link_ver = $mysql_info['link_ver']; + $variables = $mysql_info['variables']; + $myhost = php_uname('n'); + $dbhost = $database_hostname; + + if ($dbhost == 'localhost' || $myhost == $dbhost) { + $local_db = true; + } else { + $local_db = false; + } + + // Get Maximum Memory in GB for MySQL/MariaDB + if (POLLER_ID == 1) { + if (($database == 'MySQL' && version_compare($version, '8.0', '<')) || $database == 'MariaDB') { + $systemMemory = db_fetch_cell('SELECT + (@@GLOBAL.key_buffer_size + + @@GLOBAL.query_cache_size + + @@GLOBAL.tmp_table_size + + @@GLOBAL.innodb_buffer_pool_size + + @@GLOBAL.innodb_log_buffer_size) / 1024 / 1024 / 1024'); + + $maxPossibleMyMemory = db_fetch_cell('SELECT ( + (@@GLOBAL.key_buffer_size + + @@GLOBAL.query_cache_size + + @@GLOBAL.tmp_table_size + + @@GLOBAL.innodb_buffer_pool_size + + @@GLOBAL.innodb_log_buffer_size + + @@GLOBAL.max_connections * ( + @@GLOBAL.sort_buffer_size + + @@GLOBAL.read_buffer_size + + @@GLOBAL.read_rnd_buffer_size + + @@GLOBAL.join_buffer_size + + @@GLOBAL.thread_stack + + @@GLOBAL.binlog_cache_size) + ) / 1024 / 1024 / 1024)'); + } else { + $systemMemory = db_fetch_cell('SELECT + (@@GLOBAL.key_buffer_size + + @@GLOBAL.tmp_table_size + + @@GLOBAL.innodb_buffer_pool_size + + @@GLOBAL.innodb_log_buffer_size) / 1024 / 1024 / 1024'); + + $maxPossibleMyMemory = db_fetch_cell('SELECT ( + (@@GLOBAL.key_buffer_size + + @@GLOBAL.tmp_table_size + + @@GLOBAL.innodb_buffer_pool_size + + @@GLOBAL.innodb_log_buffer_size + + @@GLOBAL.max_connections * ( + @@GLOBAL.sort_buffer_size + + @@GLOBAL.read_buffer_size + + @@GLOBAL.read_rnd_buffer_size + + @@GLOBAL.join_buffer_size + + @@GLOBAL.thread_stack + + @@GLOBAL.binlog_cache_size) + ) / 1024 / 1024 / 1024)'); + } + + $clientMemory = db_fetch_cell('SELECT @@GLOBAL.max_connections * ( + @@GLOBAL.sort_buffer_size + + @@GLOBAL.read_buffer_size + + @@GLOBAL.read_rnd_buffer_size + + @@GLOBAL.join_buffer_size + + @@GLOBAL.thread_stack + + @@GLOBAL.binlog_cache_size) / 1024 / 1024 / 1024'); + } else { + if (($database == 'MySQL' && version_compare($version, '8.0', '<')) || $database == 'MariaDB') { + $maxPossibleMyMemory = db_fetch_cell('SELECT ( + (@@GLOBAL.key_buffer_size + + @@GLOBAL.query_cache_size + + @@GLOBAL.tmp_table_size + + @@GLOBAL.innodb_buffer_pool_size + + @@GLOBAL.innodb_log_buffer_size + + @@GLOBAL.max_connections * ( + @@GLOBAL.sort_buffer_size + + @@GLOBAL.read_buffer_size + + @@GLOBAL.read_rnd_buffer_size + + @@GLOBAL.join_buffer_size + + @@GLOBAL.thread_stack + + @@GLOBAL.binlog_cache_size) + ) / 1024 / 1024 / 1024)', '', false, $local_db_cnn_id); + + $systemMemory = db_fetch_cell('SELECT + (@@GLOBAL.key_buffer_size + + @@GLOBAL.query_cache_size + + @@GLOBAL.tmp_table_size + + @@GLOBAL.innodb_buffer_pool_size + + @@GLOBAL.innodb_log_buffer_size) / 1024 / 1024 / 1024', '', false, $local_db_cnn_id); + } else { + $maxPossibleMyMemory = db_fetch_cell('SELECT ( + (@@GLOBAL.key_buffer_size + + @@GLOBAL.tmp_table_size + + @@GLOBAL.innodb_buffer_pool_size + + @@GLOBAL.innodb_log_buffer_size + + @@GLOBAL.max_connections * ( + @@GLOBAL.sort_buffer_size + + @@GLOBAL.read_buffer_size + + @@GLOBAL.read_rnd_buffer_size + + @@GLOBAL.join_buffer_size + + @@GLOBAL.thread_stack + + @@GLOBAL.binlog_cache_size) + ) / 1024 / 1024 / 1024)', '', false, $local_db_cnn_id); + + $systemMemory = db_fetch_cell('SELECT + (@@GLOBAL.key_buffer_size + + @@GLOBAL.tmp_table_size + + @@GLOBAL.innodb_buffer_pool_size + + @@GLOBAL.innodb_log_buffer_size) / 1024 / 1024 / 1024', '', false, $local_db_cnn_id); + } + + $clientMemory = db_fetch_cell('SELECT @@GLOBAL.max_connections * ( + @@GLOBAL.sort_buffer_size + + @@GLOBAL.read_buffer_size + + @@GLOBAL.read_rnd_buffer_size + + @@GLOBAL.join_buffer_size + + @@GLOBAL.thread_stack + + @@GLOBAL.binlog_cache_size) / 1024 / 1024 / 1024', '', false, $local_db_cnn_id); + } + + html_section_header(__('MySQL/MariaDB Memory Statistics (Source: MySQL Tuner)'), 2); + + if ($total_memory > 0 && $local_db) { + if ($maxPossibleMyMemory > ($total_memory * 0.8)) { + form_alternate_row(); + print '' . __('Max Total Memory Possible') . ' | '; + print '' . __('%s GB', number_format_i18n($maxPossibleMyMemory, 2, 1000)) . ' | '; + form_end_row(); + form_alternate_row(); + print ''; + print ' | ' . __('Reduce MySQL/MariaDB Memory to less than 80% of System Memory. Preserve additional Cache Memory for RRDfiles if the Database is on the same system as the RRDfiles. See Core and Client Totals below for explanation of calculation method.') . ' | '; + form_end_row(); + } else { + form_alternate_row(); + print '' . __('Max Total Memory Possible') . ' | '; + print '' . __('%s GB', number_format_i18n($maxPossibleMyMemory, 2, 1000)) . ' | '; + form_end_row(); + } + } else { + form_alternate_row(); + print '' . __('Max Total Memory Possible') . ' | '; + print '' . __('%s GB', number_format_i18n($maxPossibleMyMemory, 2, 1000)) . ' | '; + form_end_row(); + } + + if ($total_memory > 0 && $local_db) { + if ($systemMemory > ($total_memory * 0.8)) { + form_alternate_row(); + print '' . __('Max Core Memory Possible') . ' | '; + print '' . __('%s GB', number_format_i18n($systemMemory, 2, 1000)) . ' (' . __('Reduce Total Core Memory') . ' | '; + form_end_row(); + } else { + form_alternate_row(); + print '' . __('Max Core Memory Possible') . ' | '; + print '' . __('%s GB', number_format_i18n($systemMemory, 2, 1000)) . ' | '; + form_end_row(); + } + + form_alternate_row(); + print '' . __('Calculation Formula') . ' | '; + print 'SELECT @@GLOBAL.key_buffer_size + @@GLOBAL.query_cache_size + @@GLOBAL.tmp_table_size + @@GLOBAL.innodb_buffer_pool_size + @@GLOBAL.innodb_log_buffer_size | ';
+ form_end_row();
+
+ if ($clientMemory > ($total_memory * 0.8)) {
+ form_alternate_row();
+ print '' . __('Max Connection Memory Possible') . ' | '; + print '' . __('%s GB', number_format_i18n($clientMemory, 2, 1000)) . ' (' . __('Reduce Total Client Memory') . ') | '; + form_end_row(); + } else { + form_alternate_row(); + print '' . __('Max Connection Memory Possible') . ' | '; + print '' . __('%s GB', number_format_i18n($clientMemory, 2, 1000)) . ' | '; + form_end_row(); + } + + form_alternate_row(); + print '' . __('Calculation Formula') . ' | '; + print 'SELECT @@GLOBAL.max_connections * ( @@GLOBAL.sort_buffer_size + @@GLOBAL.read_buffer_size + @@GLOBAL.read_rnd_buffer_size + @@GLOBAL.join_buffer_size + @@GLOBAL.thread_stack + @@GLOBAL.binlog_cache_size) | ';
+ form_end_row();
+ } else {
+ form_alternate_row();
+ print '' . __('Max Core Memory Possible') . ' | '; + print '' . __('%s GB', number_format_i18n($systemMemory, 2, 1000)) . ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('Calculation Formula') . ' | '; + print 'SELECT @@GLOBAL.key_buffer_size + @@GLOBAL.query_cache_size + @@GLOBAL.tmp_table_size + @@GLOBAL.innodb_buffer_pool_size + @@GLOBAL.innodb_log_buffer_size | ';
+ form_end_row();
+
+ form_alternate_row();
+ print '' . __('Max Connection Memory Possible') . ' | '; + print '' . __('%s GB', number_format_i18n($clientMemory, 2, 1000)) . ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('Calculation Formula') . ' | '; + print 'SELECT @@GLOBAL.max_connections * ( @@GLOBAL.sort_buffer_size + @@GLOBAL.read_buffer_size + @@GLOBAL.read_rnd_buffer_size + @@GLOBAL.join_buffer_size + @@GLOBAL.thread_stack + @@GLOBAL.binlog_cache_size) | ';
+ form_end_row();
+ }
+
+ html_section_header(__('PHP Information'), 2);
+
+ form_alternate_row();
+ print '' . __('PHP Version') . ' | '; + print '' . PHP_VERSION . ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('PHP OS') . ' | '; + print '' . PHP_OS . ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('PHP uname') . ' | '; + print ''; + + if (function_exists('php_uname')) { + print php_uname(); + } else { + print __('N/A'); + } + print ' | '; + form_end_row(); + + form_alternate_row(); + print '' . __('PHP SNMP') . ' | '; + print ''; + + if (function_exists('snmpget')) { + print __('Installed. Note: If you are planning on using SNMPv3, you must remove php-snmp and use the Net-SNMP toolset.'); + } else { + print __('Not Installed'); + } + print ' | '; + form_end_row(); + + form_alternate_row(); + print 'max_execution_time | '; + print '' . ini_get('max_execution_time') . ' | '; + form_end_row(); + + form_alternate_row(); + print 'memory_limit | '; + print '' . ini_get('memory_limit');
+
+ // Calculate memory suggestion based off of data source count
+ $memory_suggestion = $data_total * 32768;
+
+ // Set minimum - 16M
+ if ($memory_suggestion < 16777216) {
+ $memory_suggestion = 16777216;
+ }
+
+ // Set maximum - 512M
+ if ($memory_suggestion > 536870912) {
+ $memory_suggestion = 536870912;
+ }
+
+ // Suggest values in 8M increments
+ $memory_suggestion = round($memory_suggestion / 8388608) * 8388608;
+
+ if (memory_bytes(ini_get('memory_limit')) < $memory_suggestion) {
+ print " "; + + if ((ini_get('memory_limit') == -1)) { + print __("You've set memory limit to 'unlimited'.") . ' '; + } + + print __('It is highly suggested that you alter you php.ini memory_limit to %s or higher.', memory_readable($memory_suggestion)) . ' ' . + __('This suggested memory value is calculated based on the number of data source present and is only to be used as a suggestion, actual values may vary system to system based on requirements.'); + + print ' '; + } + + print ' | ';
+
+ form_end_row();
+
+ utilities_get_mysql_recommendations();
+}
diff --git a/tests/security/baselines/architectural_hotspots.baseline.tsv b/tests/security/baselines/architectural_hotspots.baseline.tsv
index acbca14470..60511f62d4 100644
--- a/tests/security/baselines/architectural_hotspots.baseline.tsv
+++ b/tests/security/baselines/architectural_hotspots.baseline.tsv
@@ -28,13 +28,13 @@ cmd_exec ./lib/functions.php:2249 $output = shell_exec($php . ' -q ' . $scr
cmd_exec ./lib/functions.php:2533 $output = shell_exec($script_path);
cmd_exec ./lib/functions.php:3034 return exec('whoami');
cmd_exec ./lib/functions.php:3693 exec($command_line,$out,$err);
-cmd_exec ./lib/functions.php:6951 $shell = shell_exec(cacti_escapeshellcmd(read_config_option('path_rrdtool')) . ' -v');
-cmd_exec ./lib/functions.php:6953 $shell = shell_exec(cacti_escapeshellcmd(read_config_option('path_rrdtool')) . ' -v 2>&1');
-cmd_exec ./lib/functions.php:7152 exec('id -nu', $o, $r);
-cmd_exec ./lib/functions.php:7162 exec(sprintf('grep :%s: /etc/passwd | cut -d: -f1', (int) $uid), $o, $r);
-cmd_exec ./lib/functions.php:7454 * shell_exec() callers that already assemble the command string.
-cmd_exec ./lib/functions.php:7494 $process = proc_open($argv, $descriptors, $pipes);
-cmd_exec ./lib/functions.php:7566 * shell_exec() and expect a string return value.
+cmd_exec ./lib/functions.php:6947 $shell = shell_exec(cacti_escapeshellcmd(read_config_option('path_rrdtool')) . ' -v');
+cmd_exec ./lib/functions.php:6949 $shell = shell_exec(cacti_escapeshellcmd(read_config_option('path_rrdtool')) . ' -v 2>&1');
+cmd_exec ./lib/functions.php:7148 exec('id -nu', $o, $r);
+cmd_exec ./lib/functions.php:7158 exec(sprintf('grep :%s: /etc/passwd | cut -d: -f1', (int) $uid), $o, $r);
+cmd_exec ./lib/functions.php:7450 * shell_exec() callers that already assemble the command string.
+cmd_exec ./lib/functions.php:7490 $process = proc_open($argv, $descriptors, $pipes);
+cmd_exec ./lib/functions.php:7562 * shell_exec() and expect a string return value.
cmd_exec ./lib/installer.php:3288 $results = shell_exec(cacti_escapeshellcmd(read_config_option('path_php_binary')) . ' -q ' .
cmd_exec ./lib/installer.php:3320 shell_exec(cacti_escapeshellcmd(read_config_option('path_php_binary')) . ' -q ' .
cmd_exec ./lib/installer.php:3376 $results = shell_exec(cacti_escapeshellcmd(read_config_option('path_php_binary')) . ' -q ' .
@@ -70,7 +70,7 @@ cmd_exec ./lib/poller.php:64 * @param (array) $pipes - the array of r/w pip
cmd_exec ./lib/poller.php:65 * @param (resource) $proc_fd - the file descriptor returned from proc_open()
cmd_exec ./lib/rrd.php:317 $process = proc_open(read_config_option('path_rrdtool') . ' - ' . $debug, $descriptorspec, $pipes);
cmd_exec ./lib/rrd.php:91 return popen($command, 'w');
-cmd_exec ./lib/rrd.php:940 $fp = popen($rrdtool_cmd, 'r');
+cmd_exec ./lib/rrd.php:948 $fp = popen($rrdtool_cmd, 'r');
cmd_exec ./lib/rrdcheck.php:798 $process = proc_open($command, $fds, $pipes);
cmd_exec ./lib/snmp.php:214 exec($command, $snmp_value);
cmd_exec ./lib/snmp.php:314 exec($command, $snmp_value);
@@ -89,6 +89,8 @@ cmd_exec ./lib/utility.php:1863 exec('/usr/bin/free', $output, $exit_code);
cmd_exec ./lib/utility.php:1914 $json = shell_exec($php . ' -q ' . $php_file);
cmd_exec ./lib/utility.php:1982 $json = shell_exec($php . ' -q ' . $php_file);
cmd_exec ./lib/utility.php:2114 $json = shell_exec($php . ' -q ' . $php_file);
+cmd_exec ./poc/setup/probe.php:82 $out = shell_exec(
+cmd_exec ./poc/setup/probe.php:95 shell_exec('rrdtool update ' . escapeshellarg($rrd_file) . ' N:42 2>&1');
cmd_exec ./poller_realtime.php:145 shell_exec("$command_string $extra_args");
cmd_exec ./poller_realtime.php:229 shell_exec($command);
cmd_exec ./poller_spikekill.php:247 $response = exec(cacti_escapeshellcmd(read_config_option('path_php_binary')) . ' -q ' .
@@ -368,17 +370,17 @@ dynamic_include ./lib/dsstats.php:1009 include_once($config['library_path'] .
dynamic_include ./lib/dsstats.php:967 include_once($config['base_path'] . '/lib/rrd.php');
dynamic_include ./lib/export.php:465 include_once($config['library_path'] . '/vdef.php');
dynamic_include ./lib/functions.php:421 include_once($config['base_path'] . '/lib/poller.php');
-dynamic_include ./lib/functions.php:4833 include_once($config['base_path'] . '/include/global_session.php');
-dynamic_include ./lib/functions.php:4836 include_once($config['base_path'] . '/include/bottom_footer.php');
-dynamic_include ./lib/functions.php:4861 include_once($config['base_path'] . '/include/top_header.php');
-dynamic_include ./lib/functions.php:4868 include_once($config['base_path'] . '/include/top_graph_header.php');
-dynamic_include ./lib/functions.php:4875 include_once($config['base_path'] . '/include/top_general_header.php');
-dynamic_include ./lib/functions.php:5037 require_once($config['include_path'] . '/vendor/phpmailer/src/Exception.php');
-dynamic_include ./lib/functions.php:5038 require_once($config['include_path'] . '/vendor/phpmailer/src/PHPMailer.php');
-dynamic_include ./lib/functions.php:5039 require_once($config['include_path'] . '/vendor/phpmailer/src/SMTP.php');
-dynamic_include ./lib/functions.php:5526 require_once($config['include_path'] . '/vendor/phpmailer/src/Exception.php');
-dynamic_include ./lib/functions.php:5527 require_once($config['include_path'] . '/vendor/phpmailer/src/PHPMailer.php');
-dynamic_include ./lib/functions.php:5528 require_once($config['include_path'] . '/vendor/phpmailer/src/SMTP.php');
+dynamic_include ./lib/functions.php:4829 include_once($config['base_path'] . '/include/global_session.php');
+dynamic_include ./lib/functions.php:4832 include_once($config['base_path'] . '/include/bottom_footer.php');
+dynamic_include ./lib/functions.php:4857 include_once($config['base_path'] . '/include/top_header.php');
+dynamic_include ./lib/functions.php:4864 include_once($config['base_path'] . '/include/top_graph_header.php');
+dynamic_include ./lib/functions.php:4871 include_once($config['base_path'] . '/include/top_general_header.php');
+dynamic_include ./lib/functions.php:5033 require_once($config['include_path'] . '/vendor/phpmailer/src/Exception.php');
+dynamic_include ./lib/functions.php:5034 require_once($config['include_path'] . '/vendor/phpmailer/src/PHPMailer.php');
+dynamic_include ./lib/functions.php:5035 require_once($config['include_path'] . '/vendor/phpmailer/src/SMTP.php');
+dynamic_include ./lib/functions.php:5522 require_once($config['include_path'] . '/vendor/phpmailer/src/Exception.php');
+dynamic_include ./lib/functions.php:5523 require_once($config['include_path'] . '/vendor/phpmailer/src/PHPMailer.php');
+dynamic_include ./lib/functions.php:5524 require_once($config['include_path'] . '/vendor/phpmailer/src/SMTP.php');
dynamic_include ./lib/graph_variables.php:65 include_once($config['library_path'] . '/rrd.php');
dynamic_include ./lib/html.php:1243 include($config['include_path'] . '/global_arrays.php');
dynamic_include ./lib/html_tree.php:479 include_once($config['base_path'] . '/lib/data_query.php');
@@ -416,19 +418,19 @@ dynamic_include ./lib/reports.php:395 include_once($config['base_path'] . '/lib
dynamic_include ./lib/reports.php:396 include_once($config['base_path'] . '/lib/html_reports.php');
dynamic_include ./lib/reports.php:678 include_once($config['library_path'] . '/html_tree.php');
dynamic_include ./lib/reports.php:755 include_once($config['base_path'] . '/lib/time.php');
-dynamic_include ./lib/rrd.php:1067 include($config['include_path'] . '/global_arrays.php');
-dynamic_include ./lib/rrd.php:1344 include_once($config['library_path'] . '/cdef.php');
-dynamic_include ./lib/rrd.php:1345 include_once($config['library_path'] . '/vdef.php');
-dynamic_include ./lib/rrd.php:1346 include_once($config['library_path'] . '/graph_variables.php');
-dynamic_include ./lib/rrd.php:1347 include_once($config['library_path'] . '/boost.php');
-dynamic_include ./lib/rrd.php:1348 include_once($config['library_path'] . '/xml.php');
-dynamic_include ./lib/rrd.php:1349 include($config['include_path'] . '/global_arrays.php');
-dynamic_include ./lib/rrd.php:2630 include($rrdtheme);
-dynamic_include ./lib/rrd.php:3235 include_once($config['library_path'] . '/time.php');
-dynamic_include ./lib/rrd.php:4006 include($themefile);
-dynamic_include ./lib/rrd.php:590 include ($config['include_path'] . '/global_arrays.php');
-dynamic_include ./lib/rrd.php:909 include($config['include_path'] . '/global_arrays.php');
-dynamic_include ./lib/rrd.php:983 include_once($config['library_path'] . '/boost.php');
+dynamic_include ./lib/rrd.php:1075 include($config['include_path'] . '/global_arrays.php');
+dynamic_include ./lib/rrd.php:1347 include_once($config['library_path'] . '/cdef.php');
+dynamic_include ./lib/rrd.php:1348 include_once($config['library_path'] . '/vdef.php');
+dynamic_include ./lib/rrd.php:1349 include_once($config['library_path'] . '/graph_variables.php');
+dynamic_include ./lib/rrd.php:1350 include_once($config['library_path'] . '/boost.php');
+dynamic_include ./lib/rrd.php:1351 include_once($config['library_path'] . '/xml.php');
+dynamic_include ./lib/rrd.php:1352 include($config['include_path'] . '/global_arrays.php');
+dynamic_include ./lib/rrd.php:2636 include($rrdtheme);
+dynamic_include ./lib/rrd.php:3242 include_once($config['library_path'] . '/time.php');
+dynamic_include ./lib/rrd.php:4019 include($themefile);
+dynamic_include ./lib/rrd.php:598 include ($config['include_path'] . '/global_arrays.php');
+dynamic_include ./lib/rrd.php:917 include($config['include_path'] . '/global_arrays.php');
+dynamic_include ./lib/rrd.php:991 include_once($config['library_path'] . '/boost.php');
dynamic_include ./lib/rrdcheck.php:716 include_once($config['base_path'] . '/lib/rrd.php');
dynamic_include ./lib/rrdcheck.php:746 include_once($config['library_path'] . '/poller.php');
dynamic_include ./lib/snmp.php:49 include_once($config['include_path'] . '/vendor/phpsnmp/extension.php');
diff --git a/tests/security/baselines/sink_inventory.baseline.tsv b/tests/security/baselines/sink_inventory.baseline.tsv
index c0a43ae6bd..0f860ee54b 100644
--- a/tests/security/baselines/sink_inventory.baseline.tsv
+++ b/tests/security/baselines/sink_inventory.baseline.tsv
@@ -422,8 +422,8 @@ dynamic_include ./lib/rrd.php:1350 include_once($config['library_path'] . '/boo
dynamic_include ./lib/rrd.php:1351 include_once($config['library_path'] . '/xml.php');
dynamic_include ./lib/rrd.php:1352 include($config['include_path'] . '/global_arrays.php');
dynamic_include ./lib/rrd.php:2636 include($rrdtheme);
-dynamic_include ./lib/rrd.php:3241 include_once($config['library_path'] . '/time.php');
-dynamic_include ./lib/rrd.php:4012 include($themefile);
+dynamic_include ./lib/rrd.php:3242 include_once($config['library_path'] . '/time.php');
+dynamic_include ./lib/rrd.php:4019 include($themefile);
dynamic_include ./lib/rrd.php:598 include ($config['include_path'] . '/global_arrays.php');
dynamic_include ./lib/rrd.php:917 include($config['include_path'] . '/global_arrays.php');
dynamic_include ./lib/rrd.php:991 include_once($config['library_path'] . '/boost.php');
@@ -937,6 +937,7 @@ header_redirect ./settings.php:303 header('Location: settings.php?tab=' . get_
header_redirect ./sites.php:266 header('Location: sites.php?header=false&action=edit&id=' . (empty($site_id) ? get_nfilter_request_var('id') : $site_id));
header_redirect ./sites.php:347 header('Location: sites.php?header=false');
header_redirect ./sites.php:397 header('Location: sites.php?header=false');
+header_redirect ./support.php:64 header('Location: support.php?tab=summary');
header_redirect ./templates_export.php:72 header('Location: templates_export.php');
header_redirect ./templates_import.php:122 header('Location: templates_import.php');
header_redirect ./templates_import.php:71 header('Location: templates_import.php'); exit;
|---|