diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..1bc90b9 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,23 @@ +# Cacti wmi Plugin AI Instructions + +## Project Overview +This is a Cacti plugin. It integrates with the Cacti monitoring platform via the plugin hook architecture. + +## Technology Stack +- PHP 7.4+ (targeting Cacti 1.2.x compatibility) +- MySQL/MariaDB via Cacti's DB abstraction layer +- PSR-12 coding standards + +## Key Rules +- Use prepared statements (db_execute_prepared, db_fetch_row_prepared, etc.) for ALL queries with variables +- Use get_request_var() / get_filter_request_var() for ALL user input, never raw $_REQUEST/$_GET/$_POST +- Use html_escape() / htmlspecialchars() for ALL output of DB/user values in HTML context +- Use cacti_escapeshellarg() for ALL shell command arguments +- No PHP 8.0+ features (str_contains, match, union types, named args) - target PHP 7.4 +- Use ?? and ??= operators (PHP 7.4) instead of isset() ternary patterns +- All unserialize() calls must use allowed_classes => false + +## Testing +- Tests in tests/ directory +- Use Pest PHP or PHPUnit +- php -l lint check required before commit diff --git a/.github/workflows/plugin-ci-workflow.yml b/.github/workflows/plugin-ci-workflow.yml new file mode 100644 index 0000000..7d02124 --- /dev/null +++ b/.github/workflows/plugin-ci-workflow.yml @@ -0,0 +1,225 @@ +# +-------------------------------------------------------------------------+ +# | Copyright (C) 2004-2026 The Cacti Group | +# | | +# | This program is free software; you can redistribute it and/or | +# | modify it under the terms of the GNU General Public License | +# | as published by the Free Software Foundation; either version 2 | +# | of the License, or (at your option) any later version. | +# | | +# | This program is distributed in the hope that it will be useful, | +# | but WITHOUT ANY WARRANTY; without even the implied warranty of | +# | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | +# | GNU General Public License for more details. | +# +-------------------------------------------------------------------------+ +# | Cacti: The Complete RRDtool-based Graphing Solution | +# +-------------------------------------------------------------------------+ +# | This code is designed, written, and maintained by the Cacti Group. See | +# | about.php and/or the AUTHORS file for specific developer information. | +# +-------------------------------------------------------------------------+ +# | http://www.cacti.net/ | +# +-------------------------------------------------------------------------+ + +name: Plugin Integration Tests + +on: + push: + branches: + - main + - develop + pull_request: + branches: + - main + - develop + +jobs: + integration-test: + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + php: ['8.1', '8.2', '8.3', '8.4'] + os: [ubuntu-latest] + + services: + mariadb: + image: mariadb:10.6 + env: + MYSQL_ROOT_PASSWORD: cactiroot + MYSQL_DATABASE: cacti + MYSQL_USER: cactiuser + MYSQL_PASSWORD: cactiuser + ports: + - 3306:3306 + options: >- + --health-cmd="mysqladmin ping" + --health-interval=10s + --health-timeout=5s + --health-retries=3 + + name: PHP ${{ matrix.php }} Integration Test on ${{ matrix.os }} + + steps: + - name: Checkout Cacti + uses: actions/checkout@v4 + with: + repository: Cacti/cacti + path: cacti + + - name: Checkout wmi Plugin + uses: actions/checkout@v4 + with: + path: cacti/plugins/wmi + + - name: Install PHP ${{ matrix.php }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: intl, mysql, gd, ldap, gmp, xml, curl, json, mbstring + ini-values: "post_max_size=256M, max_execution_time=60, date.timezone=America/New_York" + + - name: Check PHP version + run: php -v + + - name: Run apt-get update + run: sudo apt-get update + + - name: Install System Dependencies + run: sudo apt-get install -y apache2 snmp snmpd rrdtool fping + + - name: Start SNMPD Agent and Test + run: | + sudo systemctl start snmpd + sudo snmpwalk -c public -v2c -On localhost .1.3.6.1.2.1.1 + + - name: Setup Permissions + run: | + sudo chown -R www-data:runner ${{ github.workspace }}/cacti + sudo find ${{ github.workspace }}/cacti -type d -exec chmod 775 {} \; + sudo find ${{ github.workspace }}/cacti -type f -exec chmod 664 {} \; + sudo chmod +x ${{ github.workspace }}/cacti/cmd.php + sudo chmod +x ${{ github.workspace }}/cacti/poller.php + + - name: Create MySQL Config + run: | + echo -e "[client]\nuser = root\npassword = cactiroot\nhost = 127.0.0.1\n" > ~/.my.cnf + cat ~/.my.cnf + + - name: Initialize Cacti Database + env: + MYSQL_AUTH_USR: '--defaults-file=~/.my.cnf' + run: | + mysql $MYSQL_AUTH_USR -e 'CREATE DATABASE IF NOT EXISTS cacti;' + mysql $MYSQL_AUTH_USR -e "CREATE USER IF NOT EXISTS 'cactiuser'@'localhost' IDENTIFIED BY 'cactiuser';" + mysql $MYSQL_AUTH_USR -e "GRANT ALL PRIVILEGES ON cacti.* TO 'cactiuser'@'localhost';" + mysql $MYSQL_AUTH_USR -e "GRANT SELECT ON mysql.time_zone_name TO 'cactiuser'@'localhost';" + mysql $MYSQL_AUTH_USR -e "FLUSH PRIVILEGES;" + mysql $MYSQL_AUTH_USR cacti < ${{ github.workspace }}/cacti/cacti.sql + mysql $MYSQL_AUTH_USR -e "INSERT INTO settings (name, value) VALUES ('path_php_binary', '/usr/bin/php')" cacti + + - name: Validate composer files + run: | + cd ${{ github.workspace }}/cacti + if [ -f composer.json ]; then + composer validate --strict || true + fi + + - name: Install Composer Dependencies + run: | + cd ${{ github.workspace }}/cacti + if [ -f composer.json ]; then + sudo composer install --prefer-dist --no-progress + fi + + - name: Create Cacti config.php + run: | + cat ${{ github.workspace }}/cacti/include/config.php.dist | \ + sed -r "s/localhost/127.0.0.1/g" | \ + sed -r "s/'cacti'/'cacti'/g" | \ + sed -r "s/'cactiuser'/'cactiuser'/g" | \ + sed -r "s/'cactiuser'/'cactiuser'/g" > ${{ github.workspace }}/cacti/include/config.php + sudo chmod 664 ${{ github.workspace }}/cacti/include/config.php + + - name: Configure Apache + run: | + cat << 'EOF' | sed 's#GITHUB_WORKSPACE#${{ github.workspace }}#g' > /tmp/cacti.conf + + ServerAdmin webmaster@localhost + DocumentRoot GITHUB_WORKSPACE/cacti + + + Options Indexes FollowSymLinks + AllowOverride All + Require all granted + + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + + EOF + sudo cp /tmp/cacti.conf /etc/apache2/sites-available/000-default.conf + sudo systemctl restart apache2 + + - name: Install Cacti via CLI + run: | + cd ${{ github.workspace }}/cacti + sudo php cli/install_cacti.php --accept-eula --install --force + + - name: Install wmi Plugin + run: | + cd ${{ github.workspace }}/cacti + sudo php cli/plugin_manage.php --plugin=wmi --install --enable + +# - name: import wmi Plugin Sample Data +# run: | +# cd ${{ github.workspace }}/cacti/plugins/wmi +# sudo php cli_import.php --filename=.github/workflows/wmi_sample_data.xml +# if [ $? -ne 0 ]; then +# echo "Failed to import Thold sample data" +# exit 1 +# fi + + - name: Check PHP Syntax for Plugin + run: | + cd ${{ github.workspace }}/cacti/plugins/wmi + if find . -name '*.php' -exec php -l {} 2>&1 \; | grep -iv 'no syntax errors detected'; then + echo "Syntax errors found!" + exit 1 + fi + + - name: Remove the plugins directory exclusion from the .phpstan.neon + run: sed '/plugins/d' -i .phpstan.neon + working-directory: ${{ github.workspace }}/cacti + + - name: Mark composer scripts executable + run: sudo chmod +x ${{ github.workspace }}/cacti/include/vendor/bin/* + + - name: Run Linter on base code + run: composer run-script lint ${{ github.workspace }}/cacti/plugins/wmi + working-directory: ${{ github.workspace }}/cacti + + - name: Checking coding standards on base code + run: composer run-script phpcsfixer ${{ github.workspace }}/cacti/plugins/wmi + working-directory: ${{ github.workspace }}/cacti + +# - name: Run PHPStan at Level 6 on base code outside of Composer due to technical issues +# run: ./include/vendor/bin/phpstan analyze --level 6 ${{ github.workspace }}/cacti/plugins/wmi +# working-directory: ${{ github.workspace }}/cacti + + - name: Run Cacti Poller + run: | + cd ${{ github.workspace }}/cacti + sudo php poller.php --poller=1 --force --debug + if ! grep -q "SYSTEM STATS" log/cacti.log; then + echo "Cacti poller did not finish successfully" + cat log/cacti.log + exit 1 + fi + + - name: View Cacti Logs + if: always() + run: | + if [ -f ${{ github.workspace }}/cacti/log/cacti.log ]; then + echo "=== Cacti Log ===" + sudo cat ${{ github.workspace }}/cacti/log/cacti.log + fi diff --git a/functions.php b/functions.php index 884d7d4..ce66e23 100644 --- a/functions.php +++ b/functions.php @@ -25,30 +25,30 @@ function display_tabs() { global $config; - /* present a tabbed interface */ - $tabs['queries'] = array('url' => 'wmi_queries.php', 'name' => __('Queries', 'wmi')); - $tabs['accounts'] = array('url' => 'wmi_accounts.php', 'name' => __('Authentication', 'wmi')); + // present a tabbed interface + $tabs['queries'] = ['url' => 'wmi_queries.php', 'name' => __('Queries', 'wmi')]; + $tabs['accounts'] = ['url' => 'wmi_accounts.php', 'name' => __('Authentication', 'wmi')]; - /* if they were redirected to the page, let's set that up */ + // if they were redirected to the page, let's set that up if (!isset_request_var('tab')) { $current_tab = 'queries'; } else { $current_tab = get_request_var('tab'); } - /* draw the tabs */ + // draw the tabs print "
"; + print ''; } function plugin_wmi_query_exists($query) { @@ -56,7 +56,7 @@ function plugin_wmi_query_exists($query) { $next_ic = false; $exists = false; - foreach($tokens as $token) { + foreach ($tokens as $token) { if ($next_ic) { $exists = db_fetch_cell("SELECT COUNT(*) FROM wmi_wql_queries WHERE query RLIKE '^FROM\s$token$+'"); } @@ -73,12 +73,13 @@ function plugin_wmi_create_dataquery_xml($id) { include_once($config['base_path'] . '/lib/export.php'); $wmic = db_fetch_row("SELECT * FROM wmi_wql_queries WHERE id = $id"); $data = ''; + if (isset($wmic['id'])) { $data = "\n"; -// Data Query - $hashes['data_query'] = get_hash_version("data_query") . generate_hash(); - $hashes['data_template'] = get_hash_version("data_template") . generate_hash(); + // Data Query + $hashes['data_query'] = get_hash_version('data_query') . generate_hash(); + $hashes['data_template'] = get_hash_version('data_template') . generate_hash(); $data .= "\t\n"; $data .= "\t\t" . $wmic['name'] . "\n"; @@ -86,33 +87,33 @@ function plugin_wmi_create_dataquery_xml($id) { $data .= "\t\t&lt;path_cacti&gt;/resource/script_server/" . $wmic['queryname'] . ".xml\n"; $input = db_fetch_cell("SELECT id FROM data_input WHERE name = 'Get Script Server Data (Indexed)'"); - $data .= "\t\thash_" . get_hash_version("data_input_method") . get_hash_data_input($input) . "\n"; + $data .= "\t\thash_" . get_hash_version('data_input_method') . get_hash_data_input($input) . "\n"; $data .= "\t\t\n"; - $hashes['graphs'] = get_hash_version("data_query_graph") . generate_hash(); + $hashes['graphs'] = get_hash_version('data_query_graph') . generate_hash(); $data .= "\t\t\t\n"; $data .= "\t\t\t\t" . $wmic['name'] . "\n"; $data .= "\t\t\t\t\n"; - $i = 0; + $i = 0; $keys = explode(',', $wmic['querykeys']); if (cacti_sizeof($keys) > 0) { foreach ($keys as $item2) { - $data .= "\t\t\t\t\t\n"; + $data .= "\t\t\t\t\t\n"; $data .= "\t\t\t\t\t\t" . $item2 . "\n"; $data .= "\t\t\t\t\t\thash_" . $hashes['data_template'] . "\n"; - $hashes['data_template_item'][$item2] = get_hash_version("data_template_item") . generate_hash(); + $hashes['data_template_item'][$item2] = get_hash_version('data_template_item') . generate_hash(); $data .= "\t\t\t\t\t\thash_" . $hashes['data_template_item'][$item2] . "\n"; - $data .= "\t\t\t\t\t\n"; + $data .= "\t\t\t\t\t\n"; $i++; } } $data .= "\t\t\t\t\n"; $data .= "\t\t\t\t\n"; - $hashes['graph_sv'] = get_hash_version("data_query_sv_graph") . generate_hash(); - $data .= "\t\t\t\t\t\n"; + $hashes['graph_sv'] = get_hash_version('data_query_sv_graph') . generate_hash(); + $data .= "\t\t\t\t\t\n"; $data .= "\t\t\t\t\t\ttitle\n"; $data .= "\t\t\t\t\t\t2\n"; $data .= "\t\t\t\t\t\t|host_description| - |query_" . $wmic['indexkey'] . "|\n"; @@ -120,7 +121,7 @@ function plugin_wmi_create_dataquery_xml($id) { $data .= "\t\t\t\t\n"; $data .= "\t\t\t\t\n"; - $hashes['query_sv'] = get_hash_version("data_query_sv_data_source") . generate_hash(); + $hashes['query_sv'] = get_hash_version('data_query_sv_data_source') . generate_hash(); $data .= "\t\t\t\t\t\n"; $data .= "\t\t\t\t\t\tname\n"; $data .= "\t\t\t\t\t\thash_" . $hashes['data_template'] . "\n"; @@ -132,154 +133,143 @@ function plugin_wmi_create_dataquery_xml($id) { $data .= "\t\t\t\n"; $data .= "\t\t\n"; $data .= "\t\n"; -// Data Template + // Data Template $data .= "\t\n"; $data .= "\t\t" . $wmic['name'] . "\n"; $data .= "\t\t\n"; $data .= "\t\t\t\n"; $data .= "\t\t\t|host_description| - |query_" . $wmic['indexkey'] . "|\n"; - $data .= "\t\t\thash_" . get_hash_version("data_input_method") . get_hash_data_input($input) . "\n"; + $data .= "\t\t\thash_" . get_hash_version('data_input_method') . get_hash_data_input($input) . "\n"; $data .= "\t\t\t\n"; $data .= "\t\t\t\n"; $data .= "\t\t\t\n"; $data .= "\t\t\t60\n"; $data .= "\t\t\t\n"; $data .= "\t\t\t"; - // Add RRA Items (hashes); + // Add RRA Items (hashes); $data .= "\n"; $data .= "\t\t\n"; $data .= "\t\t\n"; if (cacti_sizeof($keys) > 0) { foreach ($keys as $item2) { - - $data .= "\t\t\t\n"; - $data .= "\t\t\t\t\n"; - $data .= "\t\t\t\t$item2\n"; - $data .= "\t\t\t\t\n"; - $data .= "\t\t\t\t0\n"; - $data .= "\t\t\t\t\n"; - $data .= "\t\t\t\t0\n"; - $data .= "\t\t\t\t\n"; - $data .= "\t\t\t\t\n"; -// Add correct heartbeat - $data .= "\t\t\t\t120\n"; - $data .= "\t\t\t\t\n"; - $data .= "\t\t\t\t\n"; - $data .= "\t\t\t\t0\n"; - - $data .= "\t\t\t\n"; + $data .= "\t\t\t\n"; + $data .= "\t\t\t\t\n"; + $data .= "\t\t\t\t$item2\n"; + $data .= "\t\t\t\t\n"; + $data .= "\t\t\t\t0\n"; + $data .= "\t\t\t\t\n"; + $data .= "\t\t\t\t0\n"; + $data .= "\t\t\t\t\n"; + $data .= "\t\t\t\t\n"; + // Add correct heartbeat + $data .= "\t\t\t\t120\n"; + $data .= "\t\t\t\t\n"; + $data .= "\t\t\t\t\n"; + $data .= "\t\t\t\t0\n"; + + $data .= "\t\t\t\n"; } } $data .= "\t\t\n"; - $data_input_data = db_fetch_assoc("SELECT * FROM data_input_fields WHERE data_input_fields.data_input_id=$input AND input_output = 'in' ORDER BY id DESC"); + $data_input_data = db_fetch_assoc_prepared("SELECT * FROM data_input_fields WHERE data_input_fields.data_input_id=? AND input_output = 'in' ORDER BY id DESC", [$input]); $data .= "\t\t\n"; $i = 0; + if (cacti_sizeof($data_input_data) > 0) { foreach ($data_input_data as $item) { - $data .= "\t\t\t\n"; - $data .= "\t\t\t\thash_" . get_hash_version("data_input_field") . $item['hash'] . "\n"; + $data .= "\t\t\t\n"; + $data .= "\t\t\t\thash_" . get_hash_version('data_input_field') . $item['hash'] . "\n"; $data .= "\t\t\t\ton\n"; $data .= "\t\t\t\t\n"; - $data .= "\t\t\t\n"; + $data .= "\t\t\t\n"; $i++; } } $data .= "\t\t\n"; - - $data .= "\t\n"; -/* - - Exchange Messages - - - |host_description| - |query_StoreName| - hash_030016332111d8b54ac8ce939af87a7eac0c06 - - - 60 - - on - hash_150016c21df5178e5c955013591239eb0afd46|hash_1500160d9c0af8b8acdc7807943937b3208e29|hash_1500166fc2d038fb42950138b0ce3e9874cc60|hash_150016e36f3adb9f152adfa5dc50fd2b23337e|hash_150016283ea2bf1634d92ce081ec82a634f513 - - - - - MessagesSent - - 0 - - 0 - - 2 - - 120 - - 0 - - - - MessagesDelivered - - 0 - - 0 - - 2 - - 120 - - 0 - - - - - hash_07001631112c85ae4ff821d3b288336288818c - on - - - - hash_07001630fb5d5bcf3d66bb5abe88596f357c26 - on - - - - hash_070016172b4b0eacee4948c6479f587b62e512 - on - - - - -*/ - - - - - - - - - - - - -// Data Input Method + /* + + Exchange Messages + + + |host_description| - |query_StoreName| + hash_030016332111d8b54ac8ce939af87a7eac0c06 + + + 60 + + on + hash_150016c21df5178e5c955013591239eb0afd46|hash_1500160d9c0af8b8acdc7807943937b3208e29|hash_1500166fc2d038fb42950138b0ce3e9874cc60|hash_150016e36f3adb9f152adfa5dc50fd2b23337e|hash_150016283ea2bf1634d92ce081ec82a634f513 + + + + + MessagesSent + + 0 + + 0 + + 2 + + 120 + + 0 + + + + MessagesDelivered + + 0 + + 0 + + 2 + + 120 + + 0 + + + + + hash_07001631112c85ae4ff821d3b288336288818c + on + + + + hash_07001630fb5d5bcf3d66bb5abe88596f357c26 + on + + + + hash_070016172b4b0eacee4948c6479f587b62e512 + on + + + + + */ + + // Data Input Method $data .= "\t" . str_replace("\t", "\t\t", data_input_method_to_xml($input)) . "\n"; $data .= "\n"; } + return $data; } function plugin_wmi_create_resource_xml($id) { $wmic = db_fetch_row("SELECT * FROM wmi_wql_queries WHERE id = $id"); $data = ''; + if (isset($wmic['id'])) { $data = "\n"; $data .= ' ' . $wmic['name'] . "\n"; @@ -305,6 +295,7 @@ function plugin_wmi_create_resource_xml($id) { $data .= ' \n"; $fields = explode(',', $wmic['querykeys']); + if (count($fields)) { foreach ($fields as $f) { $data .= ' <' . $f . ">\n"; @@ -317,6 +308,7 @@ function plugin_wmi_create_resource_xml($id) { $data .= " \n"; $data .= "\n"; } + return $data; } @@ -326,25 +318,25 @@ function run_store_wmi_query($host_id, $wmi_query_id) { $host_info = db_fetch_row_prepared('SELECT * FROM host WHERE id = ?', - array($host_id)); + [$host_id]); // Prepared old entries for removal db_execute_prepared('UPDATE host_wmi_cache SET present = 0 WHERE host_id = ? AND wmi_query_id = ?', - array($host_id, $wmi_query_id)); + [$host_id, $wmi_query_id]); if (cacti_sizeof($host_info)) { $auth_info = db_fetch_row_prepared('SELECT * FROM wmi_user_accounts WHERE id = ?', - array($host_info['wmi_account'])); + [$host_info['wmi_account']]); $wmi_query = db_fetch_row_prepared('SELECT * FROM wmi_wql_queries WHERE id = ?', - array($wmi_query_id)); + [$wmi_query_id]); if (!cacti_sizeof($auth_info)) { return false; @@ -363,13 +355,13 @@ function run_store_wmi_query($host_id, $wmi_query_id) { // Initialize variables $cur_time = date('Y-m-d H:i:s'); - $data = array(); - $indexes = array(); + $data = []; + $indexes = []; if ($config['cacti_server_os'] != 'win32') { include_once($config['base_path'] . '/plugins/wmi/linux_wmi.php'); - $wmi = new Linux_WMI(); + $wmi = new Linux_WMI(); $wmi->hostname = $host; $wmi->username = $username; $wmi->password = $wmi->decode($password); @@ -389,15 +381,15 @@ function run_store_wmi_query($host_id, $wmi_query_id) { $indexes = $wmi->fetch_indexes(); $data = $wmi->fetch_data(); } else { - $indexes = array(); - $data = array(); + $indexes = []; + $data = []; } } else { // Windows version - $wmi = new COM('WbemScripting.SWwebLocator'); - $wmic = $wmi->ConnectServer($host, $namespace, $username, $password); + $wmi = new COM('WbemScripting.SWwebLocator'); + $wmic = $wmi->ConnectServer($host, $namespace, $username, $password); $wmic->Security_->ImpersonationLevel = 3; - $data = $wmic->ExecQuery($command); + $data = $wmic->ExecQuery($command); if (cacti_sizeof($data)) { $indexes = array_keys($data[0]); @@ -405,43 +397,47 @@ function run_store_wmi_query($host_id, $wmi_query_id) { } if (cacti_sizeof($data)) { - $sql = array(); + $sql = []; $pk_index = -1; + if (cacti_sizeof($indexes)) { - foreach($indexes as $index => $value) { + foreach ($indexes as $index => $value) { if ($value == $wmi_query['primary_key']) { $pk_index = $index; + break; } } } if (cacti_sizeof($data)) { - foreach($data as $row) { - $pk = isset($row[$pk_index]) ? $row[$pk_index]:'N/A'; + foreach ($data as $row) { + $pk = isset($row[$pk_index]) ? $row[$pk_index] : 'N/A'; - foreach($row as $index => $value) { + foreach ($row as $index => $value) { if (!isset($indexes[$index])) { continue; - } elseif ($indexes[$index] != 'OEMLogoBitmap') { + } + + if ($indexes[$index] != 'OEMLogoBitmap') { $sql[] = '(' . - $host_id . ',' . - $wmi_query_id . ',' . + $host_id . ',' . + $wmi_query_id . ',' . db_qstr($indexes[$index]) . ',' . - db_qstr($value) . ',' . - db_qstr($pk) . ',' . - '1' . ',' . - db_qstr($cur_time) . ')'; + db_qstr($value) . ',' . + db_qstr($pk) . ',' . + '1' . ',' . + db_qstr($cur_time) . ')'; } else { $sql[] = '(' . - $host_id . ',' . - $wmi_query_id . ',' . + $host_id . ',' . + $wmi_query_id . ',' . db_qstr($indexes[$index]) . ',' . - db_qstr('Not Stored') . ',' . - db_qstr($pk) . ',' . - '1' . ',' . - db_qstr($cur_time) . ')'; + db_qstr('Not Stored') . ',' . + db_qstr($pk) . ',' . + '1' . ',' . + db_qstr($cur_time) . ')'; } } } @@ -449,7 +445,7 @@ function run_store_wmi_query($host_id, $wmi_query_id) { $parts = array_chunk($sql, 200); - foreach($parts as $part) { + foreach ($parts as $part) { db_execute('INSERT INTO host_wmi_cache (host_id, wmi_query_id, field_name, field_value, wmi_index, present, last_updated) VALUES ' . implode(', ', $part) . ' @@ -476,14 +472,15 @@ function run_store_wmi_query($host_id, $wmi_query_id) { WHERE present = 0 AND host_id = ? AND wmi_query_id = ?', - array($host_id, $wmi_query_id)); + [$host_id, $wmi_query_id]); } -/* get_hash_wmi_query - returns the current unique hash for an wmi query - @arg $wmi_query_id - (int) the ID of the wmi_query to return a hash for - @returns - a 128-bit, hexadecimal hash */ +/** get_hash_wmi_query - returns the current unique hash for an wmi query + * @arg $wmi_query_id - (int) the ID of the wmi_query to return a hash for + * @param mixed $wmi_query_id + * @returns - a 128-bit, hexadecimal hash */ function get_hash_wmi_query($wmi_query_id) { - $hash = db_fetch_cell_prepared('SELECT hash FROM wmi_wql_queries WHERE id = ?', array($wmi_query_id)); + $hash = db_fetch_cell_prepared('SELECT hash FROM wmi_wql_queries WHERE id = ?', [$wmi_query_id]); if (preg_match('/[a-fA-F0-9]{32}/', $hash)) { return $hash; @@ -491,4 +488,3 @@ function get_hash_wmi_query($wmi_query_id) { return generate_hash(); } } - diff --git a/index.php b/index.php index 6bdadf9..4e67c6b 100644 --- a/index.php +++ b/index.php @@ -1,4 +1,3 @@ hostid = $hostid; - /* Ensure we have a username / password pair setup for this host */ + // Ensure we have a username / password pair setup for this host $this->retrieve_account(); } } @@ -68,7 +68,7 @@ function __destruct() { } function create_query() { - $this->command = "SELECT "; + $this->command = 'SELECT '; if ($this->keys != '') { if ($this->indexkey != '') { @@ -76,21 +76,22 @@ function create_query() { } $this->command .= $this->keys; - } else if ($this->indexkey != '') { + } elseif ($this->indexkey != '') { $this->command .= $this->indexkey . ','; } else { $this->command = ''; - $this->error = 'ERROR: WMI Keys and Index is Empty!'; + $this->error = 'ERROR: WMI Keys and Index is Empty!'; return false; } $this->command .= ' FROM '; + if ($this->queryclass != '') { $this->command .= $this->queryclass; } else { $this->command = ''; - $this->error = 'ERROR: WMI Query Class is empty!'; + $this->error = 'ERROR: WMI Query Class is empty!'; return false; } @@ -114,14 +115,16 @@ function fetch_key_index($name) { } function fetch_value($keyname, $index) { - $i = $this->fetch_key_index($this->indexkey); - $k = $this->fetch_key_index($keyname); + $i = $this->fetch_key_index($this->indexkey); + $k = $this->fetch_key_index($keyname); $results = $this->results; + if (isset($results[2])) { array_shift($results); array_shift($results); + foreach ($results as $r) { - if (str_replace(array(' ','(', ')'), '', $r[$i]) == $index) { + if (str_replace([' ', '(', ')'], '', $r[$i]) == $index) { return $r[$k]; } } @@ -139,8 +142,9 @@ function print_fetch_key_value_pair($keyname, $index) { if (isset($results[2])) { array_shift($results); array_shift($results); + foreach ($results as $r) { - if (str_replace(array(' ','(', ')'), '', $r[$i]) == $index) { + if (str_replace([' ', '(', ')'], '', $r[$i]) == $index) { print "$keyname!" . $r[$k] . "'" . PHP_EOL; } } @@ -148,15 +152,16 @@ function print_fetch_key_value_pair($keyname, $index) { } function print_indexes() { - $k = $this->fetch_key_index($this->indexkey); + $k = $this->fetch_key_index($this->indexkey); $results = $this->results; + if (isset($results[2])) { array_shift($results); array_shift($results); foreach ($results as $r) { - /* Indexes should not have spaces in their name so we remove them */ - print str_replace(array(' ','(', ')'), '', $r[$k]) . '!' . str_replace(array(' ','(', ')'), '', $r[$k]) . PHP_EOL; + // Indexes should not have spaces in their name so we remove them + print str_replace([' ', '(', ')'], '', $r[$k]) . '!' . str_replace([' ', '(', ')'], '', $r[$k]) . PHP_EOL; } } } @@ -164,7 +169,7 @@ function print_indexes() { function fetch_indexes() { if (isset($this->results[1])) { return $this->results[1]; - }else{ + } else { return false; } } @@ -172,7 +177,7 @@ function fetch_indexes() { function fetch_class() { if (sizeof($this->results)) { return $this->results[0][0]; - }else{ + } else { return false; } } @@ -184,14 +189,15 @@ function fetch_data() { array_shift($new); return $new; - }else{ - return array(); + } else { + return []; } } function fetch() { if ($this->command == '') { $this->error = 'ERROR: WMI Query is empty'; + return false; } @@ -205,7 +211,7 @@ function fetch() { $this->results = $results; return $results; - }else{ + } else { return false; } } @@ -223,7 +229,7 @@ function getcommand() { ' --delimiter=' . $this->separator . ' --user=' . $this->username . ' --password=' . $this->password . - ($this->querynspace != '' ? ' --namespace=' . $this->querynspace:'') . + ($this->querynspace != '' ? ' --namespace=' . $this->querynspace : '') . ' //' . trim($this->hostname) . ' ' . $this->command; } @@ -235,22 +241,26 @@ function exec() { return false; } - //$command .= ' --option="client_ntlmv2_auth"=Yes'; + // $command .= ' --option="client_ntlmv2_auth"=Yes'; $config['cacti_server_os'] = 'unix'; $return_var = 0; - $return_array = array(); + $return_array = []; exec($command, $return_array, $return_var); if ($return_var != 0) { - $this->error = 'ERROR: ' . implode("
", $return_array); + $this->error = 'ERROR: ' . implode('
', $return_array); + return false; - }elseif (!sizeof($return_array)) { + } + + if (!sizeof($return_array)) { $this->error = 'ERROR: WMI Returned no Data'; + return false; - }else{ + } else { return $return_array; } } @@ -258,7 +268,8 @@ function exec() { function clean() { $this->username = cacti_escapeshellarg($this->username); $this->password = cacti_escapeshellarg($this->password); - $this->hostname = trim($this->hostname); + // hostname must be quoted: trim() alone does not neutralise shell metacharacters + $this->hostname = cacti_escapeshellarg(trim($this->hostname)); $this->binary = cacti_escapeshellarg($this->binary); $this->command = cacti_escapeshellarg($this->command); } @@ -266,19 +277,21 @@ function clean() { function retrieve_account() { if ($this->hostid == '') { $this->error = 'ERROR: hostid is not set!'; + return false; } - $info = db_fetch_row_prepared("SELECT pwa.* + $info = db_fetch_row_prepared('SELECT pwa.* FROM wmi_user_accounts AS pwa INNER JOIN host AS h WHERE pwa.id = h.wmi_account - AND h.id = ?", - array($this->hostid)); + AND h.id = ?', + [$this->hostid]); if (isset($info['username'])) { $this->username = $info['username']; $this->password = $this->decode($info['password']); + return true; } @@ -288,20 +301,27 @@ function retrieve_account() { } function decode($info) { - $info = base64_decode($info); - $info = unserialize($info); - $info = $info['password']; + $info = base64_decode($info, true); + + /* + * Legacy records were stored with serialize(). Detect and migrate on + * read so existing credentials survive the format change. New writes + * always use JSON (see encode()). + */ + if (substr($info, 0, strlen('a:')) === 'a:') { + $decoded = @unserialize($info, ['allowed_classes' => false]); + + return is_array($decoded) ? ($decoded['password'] ?? '') : ''; + } + + $decoded = json_decode($info, true); - return $info; + return is_array($decoded) ? ($decoded['password'] ?? '') : ''; } function encode($info) { - $a = array(rand(1,time()) => rand(1,time()),'password' => '', rand(1,time()) => rand(1,time())); - $a['password'] = $info; - $a = serialize($a); - $a = base64_encode($a); + $a = ['password' => $info]; - return $a; + return base64_encode(json_encode($a)); } } - diff --git a/locales/LC_MESSAGES/index.php b/locales/LC_MESSAGES/index.php index 6bdadf9..4e67c6b 100644 --- a/locales/LC_MESSAGES/index.php +++ b/locales/LC_MESSAGES/index.php @@ -1,4 +1,3 @@ 0) { - print "WARNING: Another WMI Collector is still running! Exiting" . PHP_EOL; + print 'WARNING: Another WMI Collector is still running! Exiting' . PHP_EOL; exit(0); } @@ -164,7 +171,7 @@ function process_all_devices() { AND wwq.enabled = 'on' AND wmi_account > 0"); - /* Remove entries from down and disabled devices */ + // Remove entries from down and disabled devices db_execute("DELETE FROM host_wmi_cache WHERE host_id IN( SELECT id @@ -179,16 +186,17 @@ function process_all_devices() { set_config_option('wmi_processes', '10'); } - print "NOTE: Launching Collectors Starting" . PHP_EOL; + print 'NOTE: Launching Collectors Starting' . PHP_EOL; $i = 0; + if (sizeof($devices)) { foreach ($devices as $device) { while (true) { $processes = db_fetch_cell('SELECT COUNT(*) FROM wmi_processes'); if ($processes < $concurrent_processes) { - /* put a placeholder in place to prevent overloads on slow systems */ + // put a placeholder in place to prevent overloads on slow systems $key = rand(); db_execute("INSERT INTO wmi_processes (pid, taskid, started) VALUES ($key, $seed, NOW())"); @@ -206,15 +214,16 @@ function process_all_devices() { } } - print "NOTE: All WMI Devices Launched, proceeding to wait for completion" . PHP_EOL; + print 'NOTE: All WMI Devices Launched, proceeding to wait for completion' . PHP_EOL; - /* wait for all processes to end or max run time */ + // wait for all processes to end or max run time while (true) { $processes_left = db_fetch_cell("SELECT COUNT(*) FROM wmi_processes WHERE taskid = $seed"); - $pl = db_fetch_cell('SELECT COUNT(*) FROM wmi_processes'); + $pl = db_fetch_cell('SELECT COUNT(*) FROM wmi_processes'); if ($processes_left == 0) { - print "NOTE: All Processes Complete, Exiting" . PHP_EOL; + print 'NOTE: All Processes Complete, Exiting' . PHP_EOL; + break; } else { print "NOTE: Waiting on '$processes_left' Processes" . PHP_EOL; @@ -222,11 +231,11 @@ function process_all_devices() { } } } else { - print "NOTE: No Devices found this pass to launch" . PHP_EOL; + print 'NOTE: No Devices found this pass to launch' . PHP_EOL; } if (read_config_option('wmi_autopurge') == 'on') { - print "NOTE: Auto Purging Devices" . PHP_EOL; + print 'NOTE: Auto Purging Devices' . PHP_EOL; $dead_devices = db_fetch_assoc('SELECT host_id FROM host_wmi_cache AS hwc @@ -235,15 +244,15 @@ function process_all_devices() { WHERE host.id IS NULL'); if (sizeof($dead_devices)) { - foreach($dead_devices as $device) { - db_execute('DELETE FROM host_wmi_cache WHERE host_id='. $device['host_id']); - db_execute('DELETE FROM host_wmi_query WHERE host_id='. $device['host_id']); + foreach ($dead_devices as $device) { + db_execute_prepared('DELETE FROM host_wmi_cache WHERE host_id=?', [$device['host_id']]); + db_execute_prepared('DELETE FROM host_wmi_query WHERE host_id=?', [$device['host_id']]); print "Purged WMI Device with ID '" . $device['host_id'] . "'" . PHP_EOL; } } } - /* take time and log performance data */ + // take time and log performance data $end = microtime(true); $cacti_stats = sprintf( @@ -254,11 +263,11 @@ function process_all_devices() { $concurrent_processes, cacti_sizeof($devices)); - /* log to the database */ + // log to the database set_config_option('stats_wmi', $cacti_stats); - /* log to the logfile */ - cacti_log('WMI STATS: ' . $cacti_stats , TRUE, 'SYSTEM'); + // log to the logfile + cacti_log('WMI STATS: ' . $cacti_stats , true, 'SYSTEM'); print "NOTE: Device WMI Polling Completed, $cacti_stats" . PHP_EOL; } @@ -272,8 +281,8 @@ function process_background_device($host_id, $seed, $key) { ' --start=' . $start . ' --seed=' . $seed . ' --key=' . $key . - ($forcerun ? ' --force':'') . - ($debug ? ' --debug':'')); + ($forcerun ? ' --force' : '') . + ($debug ? ' --debug' : '')); } function process_device($host_id) { @@ -293,27 +302,28 @@ function process_device($host_id) { WHERE (UNIX_TIMESTAMP(NOW()) >= UNIX_TIMESTAMP(last_started)+frequency OR last_started IS NULL) AND h.id = ? AND wmi_account > 0', - array($host_id)); + [$host_id]); - /* remove the key process and insert the set a process lock */ + // remove the key process and insert the set a process lock db_execute('REPLACE INTO wmi_processes (pid, taskid) VALUES (' . getmypid() . ", $seed)"); db_execute("DELETE FROM wmi_processes WHERE pid = $key AND taskid = $seed"); $qstart = date('Y-m-d H:i:s'); if (cacti_sizeof($queries_to_run)) { - foreach($queries_to_run AS $q) { + foreach ($queries_to_run as $q) { $qmstart = microtime(true); - cacti_log("NOTE: Executing WMI Query[" . $q['wmi_query_id'] . "] for Device [$host_id].", false, 'WMI', POLLER_VERBOSITY_MEDIUM); + cacti_log('NOTE: Executing WMI Query[' . $q['wmi_query_id'] . "] for Device [$host_id].", false, 'WMI', POLLER_VERBOSITY_MEDIUM); $account = db_fetch_row_prepared('SELECT * FROM wmi_user_accounts WHERE id = ?', - array($q['wmi_account'])); + [$q['wmi_account']]); if (!cacti_sizeof($account)) { - cacti_log("WARNING: WMI Account ID " . $q['wmi_account'] . " not found for WMI Device[$host_id].", false, 'WMI'); + cacti_log('WARNING: WMI Account ID ' . $q['wmi_account'] . " not found for WMI Device[$host_id].", false, 'WMI'); + break; } @@ -321,7 +331,7 @@ function process_device($host_id) { FROM host_wmi_query WHERE host_id = ? AND wmi_query_id = ?', - array($host_id, $q['wmi_query_id'])); + [$host_id, $q['wmi_query_id']]); if (!cacti_sizeof($run_before)) { $last_failed = '0000-00-00 00:00:00'; @@ -339,22 +349,22 @@ function process_device($host_id) { if ($status != 0) { $last_failed = date('Y-m-d H:i:s'); - cacti_log("WARNING: Errored WMI Query[" . $q['wmi_query_id'] . "] for Device [$host_id] in " . round($qmend - $qmstart, 2) . " seconds.", false, 'WMI'); + cacti_log('WARNING: Errored WMI Query[' . $q['wmi_query_id'] . "] for Device [$host_id] in " . round($qmend - $qmstart, 2) . ' seconds.', false, 'WMI'); } else { - cacti_log("NOTE: Finished WMI Query[" . $q['wmi_query_id'] . "] for Device [$host_id] in " . round($qmend -$qmstart, 2) . " seconds.", false, 'WMI', POLLER_VERBOSITY_MEDIUM); + cacti_log('NOTE: Finished WMI Query[' . $q['wmi_query_id'] . "] for Device [$host_id] in " . round($qmend - $qmstart, 2) . ' seconds.', false, 'WMI', POLLER_VERBOSITY_MEDIUM); } db_execute_prepared('REPLACE INTO host_wmi_query (host_id, wmi_query_id, sort_field, title_format, last_started, last_runtime, last_failed) VALUES (?, ?, ?, ?, ?, ?, ?)', - array($host_id, $q['wmi_query_id'], '', '', $qstart, ($qmend - $qmstart), $last_failed) + [$host_id, $q['wmi_query_id'], '', '', $qstart, ($qmend - $qmstart), $last_failed] ); } } else { cacti_log("NOTE: WMI Device[$host_id] had no WMI Queries to run this cycle.", false, 'WMI', POLLER_VERBOSITY_MEDIUM); } - /* remove the process lock */ + // remove the process lock db_execute('DELETE FROM wmi_processes WHERE pid=' . getmypid()); if ($wmi_errors > 0) { @@ -370,16 +380,15 @@ function display_version() { } $info = plugin_wmi_version(); - print "Device WMI Poller Process, Version " . $info['version'] . ", " . COPYRIGHT_YEARS . PHP_EOL; + print 'Device WMI Poller Process, Version ' . $info['version'] . ', ' . COPYRIGHT_YEARS . PHP_EOL; } function display_help() { display_version(); print PHP_EOL; - print "The Device WMI poller process script for Cacti." . PHP_EOL . PHP_EOL; - print "usage:" . PHP_EOL; - print "master process: poller_wmi.php [-M] [-f] [-d]" . PHP_EOL; - print "child process: poller_wmi.php --host-id=N [--seed=N] [-f] [-d]" . PHP_EOL . PHP_EOL; + print 'The Device WMI poller process script for Cacti.' . PHP_EOL . PHP_EOL; + print 'usage:' . PHP_EOL; + print 'master process: poller_wmi.php [-M] [-f] [-d]' . PHP_EOL; + print 'child process: poller_wmi.php --host-id=N [--seed=N] [-f] [-d]' . PHP_EOL . PHP_EOL; } - diff --git a/script/index.php b/script/index.php index 6bdadf9..4e67c6b 100644 --- a/script/index.php +++ b/script/index.php @@ -1,4 +1,3 @@ hostname = $hostname; $wmi->binary = $config['base_path'] . '/plugins/wmi/wmic'; - /* Fetch the info for this WMI query from the database, exit if not found */ - $wmiinfo = db_fetch_row("SELECT * FROM plugin_wmi_queries WHERE queryname = '$wmiquery'", FALSE); + // Fetch the info for this WMI query from the database, exit if not found + $wmiinfo = db_fetch_row_prepared('SELECT * FROM plugin_wmi_queries WHERE queryname = ?', [$wmiquery]); + if (!isset($wmiinfo['queryclass'])) { return ''; } - $wmi->indexkey = $wmiinfo['indexkey']; - $wmi->keys = $wmiinfo['querykeys']; + $wmi->indexkey = $wmiinfo['indexkey']; + $wmi->keys = $wmiinfo['querykeys']; $wmi->queryclass = $wmiinfo['queryclass']; if ($cmd == 'index') { $wmi->create_query(); $results = $wmi->fetch(); - $k = $wmi->fetch_key_index('Name'); + $k = $wmi->fetch_key_index('Name'); if (isset($results[2])) { array_shift($results); array_shift($results); + foreach ($results as $r) { - print str_replace(array(' ','(', ')'), '', $r[$k]) . "\n"; + print str_replace([' ', '(', ')'], '', $r[$k]) . "\n"; } } } elseif ($cmd == 'query') { @@ -75,7 +78,6 @@ function wmi_script($hostname, $host_id, $wmiquery, $cmd = '', $arg1 = '', $arg2 } elseif ($cmd == 'get') { $wmi->create_query(); $results = $wmi->fetch(); - echo $wmi->fetch_value($arg1, $arg2); + print $wmi->fetch_value($arg1, $arg2); } } - diff --git a/setup.php b/setup.php index d5aa4c4..3a113a1 100644 --- a/setup.php +++ b/setup.php @@ -45,7 +45,6 @@ function plugin_wmi_uninstall() { global $config; return true; - include_once($config['base_path'] . '/lib/api_data_source.php'); include_once($config['base_path'] . '/lib/api_graph.php'); @@ -57,7 +56,7 @@ function plugin_wmi_uninstall() { db_execute('DROP TABLE IF EXISTS `host_wmi_query`'); db_execute('DROP TABLE IF EXISTS `host_wmi_cache`'); - /* remove graphs and data sources based upon WMI information */ + // remove graphs and data sources based upon WMI information $id = db_fetch_cell('SELECT GROUP_CONCAT(id) FROM data_input WHERE hash IN("4af550dfe8b451579054d038ad62ba3e","42e584b81075f6ad6556e62afc509179")'); @@ -112,14 +111,14 @@ function plugin_wmi_upgrade() { function plugin_wmi_setup_tables() { api_plugin_db_add_column('wmi', 'host', - array( + [ 'name' => 'wmi_account', 'type' => 'int(10)', 'unsigned' => true, 'NULL' => false, 'default' => '0', 'after' => 'disabled' - ) + ] ); db_execute("CREATE TABLE IF NOT EXISTS `wmi_user_accounts` ( @@ -200,13 +199,14 @@ function plugin_wmi_setup_tables() { COMMENT='Running wmi collector processes';"); $exists = db_fetch_cell('SELECT id FROM data_input WHERE hash="4af550dfe8b451579054d038ad62ba3e"'); + if (!$exists) { - $save = array(); + $save = []; $save['hash'] = '4af550dfe8b451579054d038ad62ba3e'; $save['name'] = 'Get WMI Data'; $save['input_string'] = ''; $save['type_id'] = 7; - $id = sql_save($save, 'data_input'); + $id = sql_save($save, 'data_input'); if ($id) { db_execute("INSERT INTO `data_input_fields` @@ -224,12 +224,12 @@ function plugin_wmi_setup_tables() { WHERE hash="42e584b81075f6ad6556e62afc509179"'); if (!$exists) { - $save = array(); + $save = []; $save['hash'] = '42e584b81075f6ad6556e62afc509179'; $save['name'] = 'Get WMI Data (Indexed)'; $save['input_string'] = ''; $save['type_id'] = 8; - $id = sql_save($save, 'data_input'); + $id = sql_save($save, 'data_input'); if ($id) { db_execute("INSERT INTO `data_input_fields` @@ -255,6 +255,7 @@ function plugin_wmi_version() { global $config; $info = parse_ini_file($config['base_path'] . '/plugins/wmi/INFO', true); + return $info['info']; } @@ -280,12 +281,12 @@ function wmi_config_arrays() { define('DATA_INPUT_TYPE_WMI_QUERY', 8); } - $input_types += array( - DATA_INPUT_TYPE_WMI => __('WMI Data', 'wmi'), + $input_types += [ + DATA_INPUT_TYPE_WMI => __('WMI Data', 'wmi'), DATA_INPUT_TYPE_WMI_QUERY => __('WMI Data Query', 'wmi') - ); + ]; - $wmi_frequencies = array( + $wmi_frequencies = [ '60' => __('%d Minute', 1, 'wmi'), '120' => __('%d Minutes', 2, 'wmi'), '300' => __('%d Minutes', 5, 'wmi'), @@ -296,7 +297,7 @@ function wmi_config_arrays() { '7200' => __('%d Hours', 2, 'wmi'), '14400' => __('%d Hours', 4, 'wmi'), '86400' => __('%d Day', 1, 'wmi') - ); + ]; $fields_data_query_edit['data_input_id']['sql'] = 'SELECT id,name FROM data_input WHERE type_id IN(3,4,6,8) ORDER BY name'; @@ -304,73 +305,73 @@ function wmi_config_arrays() { $menu[__('Data Collection')]['plugins/wmi/wmi_queries.php'] = __('WMI Queries', 'wmi'); if (function_exists('auth_augment_roles')) { - auth_augment_roles(__('Template Editor'), array('wmi_accounts.php', 'wmi_queries.php', 'wmi_tools.php')); + auth_augment_roles(__('Template Editor'), ['wmi_accounts.php', 'wmi_queries.php', 'wmi_tools.php']); } } function wmi_data_input_sql_where($sql_where) { // Exclude special data input methods - $sql_where .= (strlen($sql_where) ? ' AND':'WHERE') . " (di.hash NOT IN ('4af550dfe8b451579054d038ad62ba3e', '42e584b81075f6ad6556e62afc509179'))"; + $sql_where .= (strlen($sql_where) ? ' AND' : 'WHERE') . " (di.hash NOT IN ('4af550dfe8b451579054d038ad62ba3e', '42e584b81075f6ad6556e62afc509179'))"; return $sql_where; } function wmi_draw_navigation_text($nav) { - $nav['wmi_accounts.php:'] = array( - 'title' => __('WMI Autenication', 'wmi'), + $nav['wmi_accounts.php:'] = [ + 'title' => __('WMI Autenication', 'wmi'), 'mapping' => 'index.php:', - 'url' => 'wmi_accounts.php', - 'level' => '1' - ); + 'url' => 'wmi_accounts.php', + 'level' => '1' + ]; - $nav['wmi_accounts.php:edit'] = array( - 'title' => __('(Edit)', 'wmi'), + $nav['wmi_accounts.php:edit'] = [ + 'title' => __('(Edit)', 'wmi'), 'mapping' => 'index.php:wmi_accounts.php:', - 'url' => 'wmi_accounts.php', - 'level' => '2' - ); + 'url' => 'wmi_accounts.php', + 'level' => '2' + ]; - $nav['wmi_accounts.php:actions'] = array( - 'title' => __('WMI Autenication', 'wmi'), + $nav['wmi_accounts.php:actions'] = [ + 'title' => __('WMI Autenication', 'wmi'), 'mapping' => 'index.php:', - 'url' => 'wmi_accounts.php', - 'level' => '1' - ); + 'url' => 'wmi_accounts.php', + 'level' => '1' + ]; - $nav['wmi_queries.php:'] = array( - 'title' => __('WMI Queries', 'wmi'), + $nav['wmi_queries.php:'] = [ + 'title' => __('WMI Queries', 'wmi'), 'mapping' => 'index.php:', - 'url' => 'wmi_queries.php', - 'level' => '1' - ); + 'url' => 'wmi_queries.php', + 'level' => '1' + ]; - $nav['wmi_queries.php:edit'] = array( - 'title' => __('(Edit)', 'wmi'), + $nav['wmi_queries.php:edit'] = [ + 'title' => __('(Edit)', 'wmi'), 'mapping' => 'index.php:,wmi_queries.php:', - 'url' => 'wmi_queries.php', - 'level' => '2' - ); + 'url' => 'wmi_queries.php', + 'level' => '2' + ]; - $nav['wmi_queries.php:actions'] = array( - 'title' => __('WMI Queries', 'wmi'), + $nav['wmi_queries.php:actions'] = [ + 'title' => __('WMI Queries', 'wmi'), 'mapping' => 'index.php:', - 'url' => 'wmi_queries.php', - 'level' => '2' - ); + 'url' => 'wmi_queries.php', + 'level' => '2' + ]; - $nav['wmi_tools.php:'] = array( - 'title' => ('WMI Tools'), + $nav['wmi_tools.php:'] = [ + 'title' => ('WMI Tools'), 'mapping' => 'index.php:', - 'url' => 'wmi_tools.php', - 'level' => '1' - ); + 'url' => 'wmi_tools.php', + 'level' => '1' + ]; - $nav['wmi_tools.php:query'] = array( - 'title' => __('(Query)', 'wmi'), + $nav['wmi_tools.php:query'] = [ + 'title' => __('(Query)', 'wmi'), 'mapping' => 'index.php:wmi_tools.php:', - 'url' => 'wmi_tools.php', - 'level' => '2' - ); + 'url' => 'wmi_tools.php', + 'level' => '2' + ]; return $nav; } @@ -395,33 +396,34 @@ function wmi_config_form() { // } // $fields_host_edit = $fields_host_edit3; - $acc = array('None'); + $acc = ['None']; $accounts = db_fetch_assoc('SELECT id, name FROM wmi_user_accounts ORDER BY name', false); + if (!empty($accounts)) { foreach ($accounts as $a) { $acc[$a['id']] = $a['name']; } } - $fields_host_edit['wmi_spacer'] = array( - 'method' => 'spacer', + $fields_host_edit['wmi_spacer'] = [ + 'method' => 'spacer', 'friendly_name' => __('WMI Account Options', 'wmi') - ); + ]; - $fields_host_edit['wmi_account'] = array( - 'method' => 'drop_array', + $fields_host_edit['wmi_account'] = [ + 'method' => 'drop_array', 'friendly_name' => __('WMI Authentication Account', 'wmi'), - 'description' => __('Choose an account to use when Authenticating via WMI', 'wmi'), - 'value' => '|arg1:wmi_account|', - 'default' => 0, - 'array' => $acc, - ); + 'description' => __('Choose an account to use when Authenticating via WMI', 'wmi'), + 'value' => '|arg1:wmi_account|', + 'default' => 0, + 'array' => $acc, + ]; } -function wmi_config_settings () { +function wmi_config_settings() { global $tabs, $settings, $item_rows, $config; - $wmi_processes = array( + $wmi_processes = [ 1 => __('1 Process', 'wmi'), 2 => __('%d Processes', 2, 'wmi'), 3 => __('%d Processes', 3, 'wmi'), @@ -440,39 +442,39 @@ function wmi_config_settings () { 40 => __('%d Processes', 40, 'wmi'), 45 => __('%d Processes', 45, 'wmi'), 50 => __('%d Processes', 50, 'wmi') - ); + ]; - $temp = array( - 'wmi_header' => array( + $temp = [ + 'wmi_header' => [ 'friendly_name' => __('WMI Settings', 'wmi'), - 'method' => 'spacer', - ), - 'wmi_enabled' => array( + 'method' => 'spacer', + ], + 'wmi_enabled' => [ 'friendly_name' => __('Enable WMI Data Collection', 'wmi'), - 'description' => __('Check this box, if you want the WMI Plugin to query Windows devices.', 'wmi'), - 'method' => 'checkbox', - 'default' => 'on' - ), - 'wmi_processes' => array( + 'description' => __('Check this box, if you want the WMI Plugin to query Windows devices.', 'wmi'), + 'method' => 'checkbox', + 'default' => 'on' + ], + 'wmi_processes' => [ 'friendly_name' => __('Concurrent Processes', 'wmi'), - 'description' => __('How many concurrent WMI queries do you want the system to run?', 'wmi'), - 'method' => 'drop_array', - 'default' => '10', - 'array' => $wmi_processes - ), - 'wmi_autocreate' => array( + 'description' => __('How many concurrent WMI queries do you want the system to run?', 'wmi'), + 'method' => 'drop_array', + 'default' => '10', + 'array' => $wmi_processes + ], + 'wmi_autocreate' => [ 'friendly_name' => __('Auto Create WMI Queries', 'wmi'), - 'description' => __('If selected, when running either automation, or when creating/saving a Device, all WMI Queries associated with the Device Template will be created.', 'wmi'), - 'method' => 'checkbox', - 'default' => 'on' - ) - ); + 'description' => __('If selected, when running either automation, or when creating/saving a Device, all WMI Queries associated with the Device Template will be created.', 'wmi'), + 'method' => 'checkbox', + 'default' => 'on' + ] + ]; $tabs['misc'] = __('Misc', 'wmi'); if (isset($settings['misc'])) { $settings['misc'] = array_merge($settings['misc'], $temp); - }else{ + } else { $settings['misc'] = $temp; } } @@ -493,7 +495,7 @@ function wmi_device_edit_pre_bottom() { $host_template_id = db_fetch_cell_prepared('SELECT host_template_id FROM host WHERE id = ?', - array(get_request_var('id'))); + [get_request_var('id')]); $wmi_queries = db_fetch_assoc_prepared('SELECT wwq.id, wwq.name FROM wmi_wql_queries AS wwq @@ -501,39 +503,40 @@ function wmi_device_edit_pre_bottom() { ON wwq.id=htwq.wmi_query_id WHERE htwq.host_template_id = ? ORDER BY name', - array($host_template_id)); + [$host_template_id]); - html_header(array(__('Name', 'wmi'), __('Status', 'wmi'))); + html_header([__('Name', 'wmi'), __('Status', 'wmi')]); $i = 1; + if (sizeof($wmi_queries)) { foreach ($wmi_queries as $item) { $exists = db_fetch_cell_prepared('SELECT wmi_query_id FROM host_wmi_query WHERE host_id = ? AND wmi_query_id = ?', - array(get_request_var('id'), $item['id'])); + [get_request_var('id'), $item['id']]); if ($exists) { $exists = __('WMI Query Exists', 'wmi'); - }else{ + } else { $exists = __('WMI Query Does Not Exist', 'wmi'); } form_alternate_row("wq$i", true); ?> - ) + ) - + ' . __('No Associated WMI Queries.', 'wmi') . ''; } @@ -547,25 +550,26 @@ function wmi_device_template_edit() { FROM wmi_wql_queries AS wwq INNER JOIN host_template_wmi_query AS htwq ON wwq.id=htwq.wmi_query_id - WHERE htwq.host_template_id = ? ORDER BY name', array(get_request_var('id'))); + WHERE htwq.host_template_id = ? ORDER BY name', [get_request_var('id')]); $i = 1; + if (sizeof($wmi_queries)) { foreach ($wmi_queries as $item) { form_alternate_row("wq$i", true); ?> - ) + ) - ' href=''> + ' href=''> ' . __('No Associated WMI Queries.', 'wmi') . ''; } @@ -574,7 +578,7 @@ function wmi_device_template_edit() { LEFT JOIN host_template_wmi_query AS htwq ON wwq.id=htwq.wmi_query_id WHERE htwq.host_template_id IS NULL OR htwq.host_template_id != ? - ORDER BY wwq.name', array(get_request_var('id'))); + ORDER BY wwq.name', [get_request_var('id')]); if (sizeof($unmapped)) { ?> @@ -583,13 +587,13 @@ function wmi_device_template_edit() {
- + - + - ' id='add_wq' title=''> + ' id='add_wq' title=''>
@@ -616,28 +620,28 @@ function wmi_device_template_edit() { function wmi_device_template_top() { if (get_request_var('action') == 'item_remove_wq_confirm') { - /* ================= input validation ================= */ + // ================= input validation ================= get_filter_request_var('id'); get_filter_request_var('host_template_id'); - /* ==================================================== */ + // ==================================================== form_start('host_templates.php?action=edit&id' . get_request_var('host_template_id')); html_start_box('', '100%', '', '3', 'center', ''); - $query = db_fetch_row_prepared('SELECT * FROM wmi_wql_queries WHERE id = ?', array(get_request_var('id'))); + $query = db_fetch_row_prepared('SELECT * FROM wmi_wql_queries WHERE id = ?', [get_request_var('id')]); ?> -

-

'
+

+

'
- ' onClick='$("#cdialog").dialog("close")' name='cancel'> - ' name='continue' title=''> + ' onClick='$("#cdialog").dialog("close")' name='cancel'> + ' name='continue' title=''> , - id: + host_template_id: , + id: }, function(data) { $('#cdialog').dialog('close'); - loadPageNoHeader('host_templates.php?action=edit&header=false&id='); + loadPageNoHeader('host_templates.php?action=edit&header=false&id='); }); }); __('Delete', 'wmi') -); +]; set_default_action(); @@ -41,78 +41,82 @@ set_request_var('tab', 'accounts'); } -$account_edit = array( - 'name' => array( - 'method' => 'textbox', +$account_edit = [ + 'name' => [ + 'method' => 'textbox', 'friendly_name' => __('Name', 'wmi'), - 'description' => __('Give this account a meaningful name that will be displayed.', 'wmi'), - 'value' => '|arg1:name|', - 'max_length' => '64', - ), - 'username' => array( - 'method' => 'textbox', + 'description' => __('Give this account a meaningful name that will be displayed.', 'wmi'), + 'value' => '|arg1:name|', + 'max_length' => '64', + ], + 'username' => [ + 'method' => 'textbox', 'friendly_name' => __('Username', 'wmi'), - 'description' => __('The username that will be used for authentication. Please also include the domain if necessary.', 'wmi'), - 'value' => '|arg1:username|', - 'max_length' => '64', - ), - 'password' => array( - 'method' => 'textbox_password', + 'description' => __('The username that will be used for authentication. Please also include the domain if necessary.', 'wmi'), + 'value' => '|arg1:username|', + 'max_length' => '64', + ], + 'password' => [ + 'method' => 'textbox_password', 'friendly_name' => __('Password', 'wmi'), - 'description' => __('The password used for authentication.', 'wmi'), - 'value' => '|arg1:password|', - 'default' => '', - 'max_length' => '64', - 'size' => '30' - ), - 'id' => array( + 'description' => __('The password used for authentication.', 'wmi'), + 'value' => '|arg1:password|', + 'default' => '', + 'max_length' => '64', + 'size' => '30' + ], + 'id' => [ 'method' => 'hidden_zero', - 'value' => '|arg1:id|' - ) -); + 'value' => '|arg1:id|' + ] +]; switch (get_request_var('action')) { case 'actions': actions_accounts(); + break; case 'save': - save_accounts (); + save_accounts(); + break; case 'edit': top_header(); - display_tabs (); + display_tabs(); edit_accounts(); bottom_footer(); + break; default: top_header(); - display_tabs (); - show_accounts (); + display_tabs(); + show_accounts(); bottom_footer(); + break; } function actions_accounts() { global $account_actions; - /* ================= input validation ================= */ + // ================= input validation ================= get_filter_request_var('drp_action'); - /* ==================================================== */ + // ==================================================== if (isset_request_var('selected_items')) { $selected_items = sanitize_unserialize_selected_items(get_nfilter_request_var('selected_items')); if ($selected_items != false) { if (get_request_var('drp_action') == '1') { - for ($i=0; $i $val){ + // loop through each of the accounts selected on the previous page and get more info about them + foreach ($_POST as $var => $val) { if (preg_match('/^chk_([0-9]+)$/', $var, $matches)) { - /* ================= input validation ================= */ + // ================= input validation ================= input_validate_input_number($matches[1]); - /* ==================================================== */ + // ==================================================== $account_list .= '

  • ' . db_fetch_cell_prepared('SELECT name FROM wmi_user_accounts WHERE id = ?', - array($matches[1])) . '
  • '; + [$matches[1]]) . ''; $account_array[] = $matches[1]; } @@ -147,20 +150,19 @@ function actions_accounts() { html_start_box($account_actions[get_request_var('drp_action')], '60%', '', '3', 'center', ''); - - if (get_nfilter_request_var('drp_action') == '1') { /* Delete */ + if (get_nfilter_request_var('drp_action') == '1') { // Delete print "

    " . __('Press \'Continue\' to delete the following accounts.', 'wmi') . "

    -
    +
    - "; + '; } if (!isset($account_array)) { - print "" . __('You must select at least one account.', 'wmi') . ""; - $save_html = ""; - }else{ + print "" . __('You must select at least one account.', 'wmi') . ''; + $save_html = ''; + } else { $save_html = ""; } @@ -189,7 +191,7 @@ function save_accounts() { $wmi = new Linux_WMI(); $save['password'] = $wmi->encode(get_nfilter_request_var('password')); - } else if ($save['id'] < 1) { + } elseif ($save['id'] < 1) { raise_message(4); } } else { @@ -211,17 +213,18 @@ function save_accounts() { function edit_accounts() { global $account_edit; - /* ================= input validation ================= */ + // ================= input validation ================= get_filter_request_var('id'); - /* ==================================================== */ + // ==================================================== + + $account = []; - $account = array(); if (!isempty_request_var('id')) { - $account = db_fetch_row_prepared('SELECT * FROM wmi_user_accounts WHERE id = ?', array(get_request_var('id'))); + $account = db_fetch_row_prepared('SELECT * FROM wmi_user_accounts WHERE id = ?', [get_request_var('id')]); $account['password'] = ''; - $header_label = __('Account [edit: %s]', $account['name'], 'wmi'); - }else{ + $header_label = __('Account [edit: %s]', $account['name'], 'wmi'); + } else { $header_label = __('Account [new]', 'wmi'); } @@ -229,10 +232,10 @@ function edit_accounts() { html_start_box($header_label, '100%', '', '3', 'center', ''); draw_edit_form( - array( - 'config' => array('no_form_tag' => true), + [ + 'config' => ['no_form_tag' => true], 'fields' => inject_form_variables($account_edit, $account) - ) + ] ); html_end_box(); @@ -243,7 +246,7 @@ function edit_accounts() { function account_filter() { global $item_rows; - html_start_box( __('WMI Accounts', 'wmi'), '100%', '', '3', 'center', 'wmi_accounts.php?action=edit'); + html_start_box(__('WMI Accounts', 'wmi'), '100%', '', '3', 'center', 'wmi_accounts.php?action=edit'); ?> @@ -251,38 +254,42 @@ function account_filter() {
    - + - '> + '> - + - > + > - ' id='refresh'> + ' id='refresh'> - ' id='clear'> + ' id='clear'>
    - '> + '>