Files
cacti/include/session.php
T
bbe0a59a5b fix: use CACTI_CLI constant instead of inline php_sapi_name() (#6718)
* cleanup: remove unreachable defensive error logs in aggregate graph item validation

* fix: use CACTI_CLI constant instead of inline php_sapi_name() check

Replace php_sapi_name() == 'cli' with the CACTI_CLI constant in
include/session.php. The constant is already defined in global.php
line 41 and session.php is included after that point.

install/cli_test.php and script_server.php are excluded because they
check php_sapi_name() before global.php is loaded.

Includes 3 Pest tests verifying constant definitions and the
session.php replacement.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test: narrow php_sapi_name assertion and add toBeString guard

Address Copilot review feedback: check specific comparison patterns
instead of bare function name, and guard substring assertions with
toBeString().

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* chore: drop unrelated lib/api_aggregate changes

Keep PR scope focused on the issue for this branch.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: TheWitness <thewitness@cacti.net>
2026-03-05 19:46:08 -05:00

156 lines
4.6 KiB
PHP

<?php
/*
+-------------------------------------------------------------------------+
| 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/ |
+-------------------------------------------------------------------------+
*/
/*
* Have Cacti use the database for PHP session storage.
* This allows for easier distribution of Web UI.
*/
// Don't run from the database if using the command line
if (CACTI_CLI) {
return;
}
function cacti_db_session_check() : void {
if (!db_column_exists('sessions', 'user_id')) {
db_execute('ALTER TABLE sessions
ADD COLUMN user_id int unsigned NOT NULL default "0",
ADD COLUMN start_time timestamp NOT NULL default current_timestamp,
ADD COLUMN transactions int unsigned NOT NULL default "1"');
}
if (!db_column_exists('sessions', 'user_agent')) {
db_execute('ALTER TABLE sessions
ADD COLUMN user_agent VARCHAR(128) NOT NULL default "" AFTER user_id');
}
}
function cacti_db_session_open(string $savePath = '', string $sessionName = '') : bool {
// Cacti database is already active
cacti_db_session_check();
return true;
}
function cacti_db_session_close() : bool {
// Cacti database is not closed by sessions
return true;
}
function cacti_db_session_read(string $id) : string {
db_execute_prepared('UPDATE IGNORE sessions
SET access = ?
WHERE id = ?',
[time(), $id]);
$session = db_fetch_cell_prepared('SELECT data
FROM sessions
WHERE id = ?',
[$id]);
// work with PHP 7.1
if (empty($session)) {
$session = '';
}
return $session;
}
function cacti_db_session_write(string $id, string $data) : bool {
$access = time();
cacti_db_session_check();
if (!isset($_SESSION[SESS_USER_ID])) {
session_decode($data);
}
if (isset($_SESSION[SESS_USER_ID])) {
$user_id = $_SESSION[SESS_USER_ID];
} else {
$user_id = 0;
}
$client_addr = get_client_addr();
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
if ($user_id > 0) {
db_execute_prepared('INSERT INTO sessions
(id, remote_addr, access, data, user_id, user_agent)
VALUES (?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
data = VALUES(data),
access = VALUES(access),
user_agent = VALUES(user_agent),
transactions = transactions + 1',
[$id, $client_addr, $access, $data, $user_id, $user_agent]);
} elseif (str_contains($data, 'ses_user_id')) {
db_execute_prepared('INSERT INTO sessions
(id, remote_addr, access, data, user_agent)
VALUES (?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
data = VALUES(data),
access = VALUES(access),
user_agent = VALUES(user_agent),
transactions = transactions + 1',
[$id, $client_addr, $access, $data, $user_agent]);
}
return true;
}
function cacti_db_session_destroy(string $id) : bool {
db_execute_prepared('DELETE FROM sessions
WHERE id = ?',
[$id]);
return true;
}
function cacti_db_session_clean(string $max) : bool {
if (!is_numeric($max)) {
$old = time() - 14400;
} else {
$old = time() - intval($max);
}
db_execute_prepared('DELETE FROM sessions
WHERE access < ?',
[$old]);
return true;
}
// register database session handling
session_set_save_handler(
'cacti_db_session_open',
'cacti_db_session_close',
'cacti_db_session_read',
'cacti_db_session_write',
'cacti_db_session_destroy',
'cacti_db_session_clean'
);
register_shutdown_function('session_write_close');