@@ -163,7 +163,11 @@ function syslog_apply_selected_items_action($selected_items, $drp_action, $actio
163163
164164 if (function_exists ($ action_function )) {
165165 foreach ($ selected_items as $ selected_item ) {
166- $ action_function ($ selected_item );
166+ try {
167+ $ action_function ($ selected_item );
168+ } catch (Exception $ e ) {
169+ cacti_log ("SYSLOG ERROR: Action ' $ action_function' failed for item ' $ selected_item': " . $ e ->getMessage (), false , 'SYSTEM ' );
170+ }
167171 }
168172 } else {
169173 cacti_log ("SYSLOG ERROR: Bulk action function ' $ action_function' not found. " , false , 'SYSTEM ' );
@@ -243,9 +247,9 @@ function syslog_traditional_manage() {
243247
244248 /* determine the oldest date to retain */
245249 if (read_config_option ('syslog_retention ' ) > 0 ) {
246- $ retention = date ('Y-m-d ' , time () - (86400 * read_config_option ('syslog_retention ' )));
250+ $ retention = gmdate ('Y-m-d ' , time () - (86400 * read_config_option ('syslog_retention ' )));
247251 } else {
248- $ retention = date ('Y-m-d ' , time () - (30 * 86400 ));
252+ $ retention = gmdate ('Y-m-d ' , time () - (30 * 86400 ));
249253 set_config_option ('syslog_retention ' , '30 ' );
250254 }
251255
@@ -311,8 +315,8 @@ function syslog_partition_create($table) {
311315
312316 /* determine the format of the table name */
313317 $ time = time ();
314- $ cformat = 'd ' . date ('Ymd ' , $ time );
315- $ lnow = date ('Y-m-d ' , $ time +86400 );
318+ $ cformat = 'd ' . gmdate ('Ymd ' , $ time );
319+ $ lnow = gmdate ('Y-m-d ' , $ time +86400 );
316320
317321 /* validate DDL interpolation values to prevent injection */
318322 if (!preg_match ('/^d\d{8}$/ ' , $ cformat ) || !preg_match ('/^\d{4}-\d{2}-\d{2}$/ ' , $ lnow )) {
@@ -340,6 +344,19 @@ function syslog_partition_create($table) {
340344 return false ;
341345 }
342346
347+ $ recheck = syslog_db_fetch_row_prepared ("SELECT *
348+ FROM `information_schema`.`partitions`
349+ WHERE table_schema = ?
350+ AND partition_name = ?
351+ AND table_name = ?
352+ ORDER BY partition_ordinal_position " ,
353+ array ($ syslogdb_default , $ cformat , $ table )
354+ );
355+
356+ if (cacti_sizeof ($ recheck )) {
357+ return true ;
358+ }
359+
343360 cacti_log ("SYSLOG: Creating new partition ' $ cformat' for table ' $ table' " , false , 'SYSTEM ' );
344361
345362 syslog_debug ("Creating new partition ' $ cformat' for table ' $ table' " );
@@ -353,6 +370,8 @@ function syslog_partition_create($table) {
353370 syslog_db_fetch_cell_prepared ('SELECT RELEASE_LOCK(?) ' , array ($ lock_name ));
354371 }
355372 }
373+
374+ return true ;
356375}
357376
358377/**
@@ -437,7 +456,7 @@ function syslog_partition_check($table) {
437456 );
438457
439458 $ lformat = str_replace ('d ' , '' , $ last_part );
440- $ cformat = date ('Ymd ' );
459+ $ cformat = gmdate ('Ymd ' );
441460
442461 if ($ cformat > $ lformat ) {
443462
@@ -489,7 +508,10 @@ function syslog_remove_items($table, $uniqueID) {
489508 $ column_map = array (
490509 'facility ' => 'facility_id ' ,
491510 'host ' => 'host_id ' ,
492- 'program ' => 'program_id '
511+ 'program ' => 'program_id ' ,
512+ 'messageb ' => $ syslog_incoming_config ['textField ' ],
513+ 'messagec ' => $ syslog_incoming_config ['textField ' ],
514+ 'messagee ' => $ syslog_incoming_config ['textField ' ],
493515 );
494516
495517 if ($ table == 'syslog_incoming ' ) {
@@ -522,9 +544,13 @@ function syslog_remove_items($table, $uniqueID) {
522544 $ params1 = array_merge ($ filter ['params ' ], array ($ uniqueID ));
523545 }
524546
525- $ delete_column = $ column_map [$ remove ['type ' ]] ?? ' message ' ;
547+ $ delete_column = $ column_map [$ remove ['type ' ]] ?? $ syslog_incoming_config [ ' textField ' ] ;
526548 if ($ remove ['type ' ] == 'facility ' ) {
527549 $ delete_column = $ syslog_incoming_config ['facilityField ' ];
550+ } elseif ($ remove ['type ' ] == 'host ' ) {
551+ $ delete_column = $ syslog_incoming_config ['hostField ' ];
552+ } elseif ($ remove ['type ' ] == 'program ' ) {
553+ $ delete_column = $ syslog_incoming_config ['programField ' ];
528554 }
529555 $ delete_filter = syslog_build_match_filter ($ remove ['type ' ], $ remove ['message ' ], $ delete_column );
530556
@@ -874,7 +900,10 @@ function syslog_manage_items($from_table, $to_table) {
874900 $ column_map = array (
875901 'facility ' => 'facility_id ' ,
876902 'host ' => 'host_id ' ,
877- 'program ' => 'program_id '
903+ 'program ' => 'program_id ' ,
904+ 'messageb ' => $ syslog_incoming_config ['textField ' ],
905+ 'messagec ' => $ syslog_incoming_config ['textField ' ],
906+ 'messagee ' => $ syslog_incoming_config ['textField ' ],
878907 );
879908
880909 $ column = $ column_map [$ remove ['type ' ]] ?? 'message ' ;
@@ -1151,51 +1180,49 @@ function syslog_execute_ticket_command($alert, $hostlist, $context) {
11511180}
11521181
11531182function syslog_execute_alert_command ($ alert , $ results , $ hostname ) {
1154- if ($ alert ['execute_command ' ] == 'on ' ) {
1155- $ command = trim ($ alert ['command ' ]);
1183+ $ command = trim ($ alert ['command ' ]);
11561184
1157- if ($ command != '' ) {
1158- $ command = alert_replace_variables ($ alert , $ results , $ hostname );
1185+ if ($ command != '' ) {
1186+ $ command = alert_replace_variables ($ alert , $ results , $ hostname );
11591187
1160- /*
1161- * Extract the executable portion from the command string.
1162- * This allows for quoted paths and additional arguments.
1163- */
1164- $ executable = $ command ;
1165- $ firstChar = substr ($ executable , 0 , 1 );
1188+ /*
1189+ * Extract the executable portion from the command string.
1190+ * This allows for quoted paths and additional arguments.
1191+ */
1192+ $ executable = $ command ;
1193+ $ firstChar = substr ($ executable , 0 , 1 );
11661194
1167- if ($ firstChar === '" ' || $ firstChar === "' " ) {
1168- $ quoteChar = $ firstChar ;
1169- $ closing = strpos ($ executable , $ quoteChar , 1 );
1195+ if ($ firstChar === '" ' || $ firstChar === "' " ) {
1196+ $ quoteChar = $ firstChar ;
1197+ $ closing = strpos ($ executable , $ quoteChar , 1 );
11701198
1171- if ($ closing !== false ) {
1172- $ executable = substr ($ executable , 1 , $ closing - 1 );
1173- } else {
1174- // Unbalanced quotes; fall back to trimming quotes/whitespace.
1175- $ executable = trim ($ executable , " \t\n\r\0\x0B\"' " );
1176- }
1199+ if ($ closing !== false ) {
1200+ $ executable = substr ($ executable , 1 , $ closing - 1 );
11771201 } else {
1178- $ parts = preg_split ('/\s+/ ' , $ executable );
1179- if (is_array ($ parts ) && isset ($ parts [0 ])) {
1180- $ executable = $ parts [0 ];
1181- }
1202+ // Unbalanced quotes; fall back to trimming quotes/whitespace.
11821203 $ executable = trim ($ executable , " \t\n\r\0\x0B\"' " );
11831204 }
1205+ } else {
1206+ $ parts = preg_split ('/\s+/ ' , $ executable );
1207+ if (is_array ($ parts ) && isset ($ parts [0 ])) {
1208+ $ executable = $ parts [0 ];
1209+ }
1210+ $ executable = trim ($ executable , " \t\n\r\0\x0B\"' " );
1211+ }
11841212
1185- if ($ executable !== '' && is_executable ($ executable )) {
1186- $ output = array ();
1187- $ returnCode = 0 ;
1213+ if ($ executable !== '' && is_executable ($ executable )) {
1214+ $ output = array ();
1215+ $ returnCode = 0 ;
11881216
1189- exec ($ command , $ output , $ returnCode );
1217+ exec ($ command , $ output , $ returnCode );
11901218
1191- $ logMessage = "SYSLOG NOTICE: Executing ' $ command' Command return code: $ returnCode " ;
1192- cacti_log ($ logMessage , true , 'SYSTEM ' );
1219+ $ logMessage = "SYSLOG NOTICE: Executing ' $ command' Command return code: $ returnCode " ;
1220+ cacti_log ($ logMessage , true , 'SYSTEM ' );
1221+ } else {
1222+ if (strpos ($ executable , DIRECTORY_SEPARATOR ) === false ) {
1223+ cacti_log (sprintf ('SYSLOG ERROR: Alert Command path \'%s \' is missing absolute path separator ' , $ executable ), false , 'SYSTEM ' );
11931224 } else {
1194- if (strpos ($ executable , DIRECTORY_SEPARATOR ) === false ) {
1195- cacti_log (sprintf ('SYSLOG ERROR: Alert Command path \'%s \' is missing absolute path separator ' , $ executable ), false , 'SYSTEM ' );
1196- } else {
1197- cacti_log (sprintf ('SYSLOG ERROR: Alert Command path \'%s \' is not executable ' , $ executable ), false , 'SYSTEM ' );
1198- }
1225+ cacti_log (sprintf ('SYSLOG ERROR: Alert Command path \'%s \' is not executable ' , $ executable ), false , 'SYSTEM ' );
11991226 }
12001227 }
12011228 }
@@ -1603,6 +1630,12 @@ function syslog_build_match_filter($type, $value, $column = '') {
16031630 $ params [] = '% ' . $ value ;
16041631 break ;
16051632 case 'sql ' :
1633+ /* Admin-configured raw SQL WHERE clause from syslog_remove table.
1634+ Reject values containing statements that should never appear in a filter. */
1635+ if (preg_match ('/\b(DROP|ALTER|TRUNCATE|CREATE|GRANT|REVOKE|INTO\s+OUTFILE|INTO\s+DUMPFILE|LOAD_FILE)\b/i ' , $ value )) {
1636+ cacti_log ('SYSLOG ERROR: Rejected dangerous SQL pattern in removal rule ' , false , 'SYSTEM ' );
1637+ break ;
1638+ }
16061639 $ sql = '( ' . $ value . ') ' ;
16071640 break ;
16081641 }
@@ -1654,52 +1687,63 @@ function syslog_get_alert_sql(&$alert, $uniqueID) {
16541687 * to be left till then ext polling cycle.
16551688 */
16561689function syslog_preprocess_incoming_records () {
1657- global $ syslogdb_default ;
1690+ global $ syslogdb_default, $ syslog_cnn ;
16581691
1659- $ attempts = 0 ;
1692+ $ lock_name = hash ('sha256 ' , $ syslogdb_default . '.preprocess_incoming ' );
1693+ $ locked = syslog_db_fetch_cell_prepared ('SELECT GET_LOCK(?, 10) ' , array ($ lock_name ));
16601694
1661- while (1 ) {
1662- $ uniqueID = rand (1 , 127 );
1695+ if ((int )$ locked !== 1 ) {
1696+ cacti_log ('SYSLOG ERROR: Unable to acquire preprocess lock ' , false , 'SYSTEM ' );
1697+ return array ('uniqueID ' => 0 , 'incoming ' => 0 );
1698+ }
16631699
1664- $ count = syslog_db_fetch_cell_prepared ('SELECT COUNT(*)
1665- FROM ` ' . $ syslogdb_default . '`.`syslog_incoming`
1666- WHERE `status` = ? ' ,
1667- array ($ uniqueID ));
1700+ $ uniqueID = 0 ;
1701+ $ incoming = 0 ;
16681702
1669- if ($ count == 0 ) {
1670- break ;
1671- }
1703+ try {
1704+ $ attempts = 0 ;
1705+ while (1 ) {
1706+ $ uniqueID = rand (1 , 127 );
1707+
1708+ $ count = syslog_db_fetch_cell_prepared ('SELECT COUNT(*)
1709+ FROM ` ' . $ syslogdb_default . '`.`syslog_incoming`
1710+ WHERE `status` = ? ' ,
1711+ array ($ uniqueID ));
1712+
1713+ if ($ count == 0 ) {
1714+ break ;
1715+ }
16721716
1673- $ attempts ++;
1717+ $ attempts ++;
16741718
1675- if ($ attempts >= 256 ) {
1676- cacti_log ('SYSLOG ERROR: Unable to find unused uniqueID after 256 attempts ' , false , 'SYSTEM ' );
1677- return array ('uniqueID ' => 0 , 'incoming ' => 0 );
1719+ if ($ attempts >= 256 ) {
1720+ cacti_log ('SYSLOG ERROR: Unable to find unused uniqueID after 256 attempts ' , false , 'SYSTEM ' );
1721+ return array ('uniqueID ' => 0 , 'incoming ' => 0 );
1722+ }
16781723 }
1679- }
16801724
1681- /* flag all records with the uniqueID prior to moving */
1682- syslog_db_execute_prepared ('UPDATE ` ' . $ syslogdb_default . '`.`syslog_incoming`
1683- SET `status` = ?
1684- WHERE `status` = 0 ' ,
1685- array ($ uniqueID ));
1725+ /* flag all records with the uniqueID prior to moving */
1726+ syslog_db_execute_prepared ('UPDATE ` ' . $ syslogdb_default . '`.`syslog_incoming`
1727+ SET `status` = ?
1728+ WHERE `status` = 0 ' ,
1729+ array ($ uniqueID ));
1730+
1731+ $ incoming = db_affected_rows ($ syslog_cnn );
1732+ } finally {
1733+ syslog_db_fetch_cell_prepared ('SELECT RELEASE_LOCK(?) ' , array ($ lock_name ));
1734+ }
16861735
16871736 syslog_debug ('Unique ID = ' . $ uniqueID );
16881737 syslog_debug ('------------------------------------------------------------------------------------- ' );
16891738
1690- $ syslog_incoming = syslog_db_fetch_cell_prepared ('SELECT COUNT(seq)
1691- FROM ` ' . $ syslogdb_default . '`.`syslog_incoming`
1692- WHERE `status` = ? ' ,
1693- array ($ uniqueID ));
1694-
1695- syslog_debug (sprintf ('Found %5s - New Message(s) to process ' , $ syslog_incoming ));
1739+ syslog_debug (sprintf ('Found %5s - New Message(s) to process ' , $ incoming ));
16961740
16971741 /* strip domains if we have requested to do so */
16981742 syslog_strip_incoming_domains ($ uniqueID );
16991743
17001744 api_plugin_hook ('plugin_syslog_before_processing ' );
17011745
1702- return array ('uniqueID ' => $ uniqueID , 'incoming ' => $ syslog_incoming );
1746+ return array ('uniqueID ' => $ uniqueID , 'incoming ' => $ incoming );
17031747}
17041748
17051749/**
0 commit comments