1<?php 2/////////////////////////////////////////////////////////////////////////////// 3// 4// NagiosQL 5// 6/////////////////////////////////////////////////////////////////////////////// 7// 8// (c) 2005-2020 by Martin Willisegger 9// 10// Project : NagiosQL 11// Component : Configuration Class 12// Website : https://sourceforge.net/projects/nagiosql/ 13// Version : 3.4.1 14// GIT Repo : https://gitlab.com/wizonet/NagiosQL 15// 16/////////////////////////////////////////////////////////////////////////////////////////////// 17// 18/////////////////////////////////////////////////////////////////////////////////////////////// 19// 20// Class: Configuration class 21// 22/////////////////////////////////////////////////////////////////////////////////////////////// 23// 24// Includes all functions used for handling configuration files with NagiosQL 25// 26// Name: NagConfigClass 27// 28/////////////////////////////////////////////////////////////////////////////////////////////// 29namespace functions; 30 31class NagConfigClass 32{ 33 // Define class variables 34 /** @var resource $resConnectId */ 35 public $resConnectId; // Connection id for FTP and SSH connections 36 public $resSFTP; // SFTP ressource id 37 38 public $arrSession = array(); // Session content 39 public $strRelTable = ''; // Relation table name 40 public $strErrorMessage = ''; // String including error messages 41 public $strInfoMessage = ''; // String including information messages 42 public $strPicPath = 'none'; // Picture path string 43 public $intNagVersion = 0; // Nagios version id 44 public $intDomainId = 0; // Configuration domain ID 45 // PRIVATE 46 private $arrSettings = array(); // Array includes all global settings 47 private $resConnectServer = ''; // Connection server name for FTP and SSH connections 48 private $resConnectType = 'none'; // Connection type for FTP and SSH connections 49 private $arrRelData = ''; // Relation data 50 // Class includes 51 /** @var MysqliDbClass */ 52 public $myDBClass; // Database class reference 53 /** @var NagDataClass */ 54 public $myDataClass; // Data processing class reference 55 56 /** 57 * NagConfigClass constructor. 58 * @param array $arrSession PHP Session array 59 */ 60 public function __construct($arrSession) 61 { 62 if (isset($arrSession['SETS'])) { 63 // Read global settings 64 $this->arrSettings = $arrSession['SETS']; 65 } 66 if (isset($arrSession['domain'])) { 67 $this->intDomainId = $arrSession['domain']; 68 } 69 $this->arrSession = $arrSession; 70 } 71 72 /** 73 * Get domain configuration parameters. 74 * @param string $strConfigItem Configuration key 75 * @param string $strValue Configuration value (by reference) 76 * @return int 0 = successful / 1 = error 77 */ 78 public function getDomainData($strConfigItem, &$strValue) 79 { 80 // Variable definition 81 $intReturn = 0; 82 // Request domain data from database 83 $strSQL = 'SELECT `' .$strConfigItem. '` FROM `tbl_datadomain` WHERE `id` = ' .$this->intDomainId; 84 $strValue = $this->myDBClass->getFieldData($strSQL); 85 if ($strValue == '') { 86 $intReturn = 1; 87 } 88 return $intReturn; 89 } 90 91 /** 92 * Get last modification date of a database table and any configuration files inside a directory. 93 * @param string $strTableName Name of the database table 94 * @param string $strConfigName Name of the configuration file 95 * @param int $intDataId ID of the dataset for service table 96 * @param array $arrTimeData Array with the timestamps of the files and the DB table (by reference) 97 * @param int $intTimeInfo Time status value (by reference) 98 * 0 = all files are newer than the database item 99 * 1 = some file are older than the database item 100 * 2 = one file is missing 101 * 3 = any files are missing 102 * 4 = no configuration targets defined 103 * @return int 0 = successful / 1 = error 104 * Status messages are stored in class variables 105 */ 106 public function lastModifiedDir($strTableName, $strConfigName, $intDataId, &$arrTimeData, &$intTimeInfo) 107 { 108 // Variable definitions 109 $intReturn = 0; 110 // Create file name 111 $strFileName = $strConfigName. '.cfg'; 112 // Get table times 113 $strActive = 0; 114 $arrTimeData = array(); 115 $arrTimeData['table'] = 'unknown'; 116 // Clear status cache 117 clearstatcache(); 118 // Get last change on dataset 119 if ($strTableName == 'tbl_host') { 120 $strSQL1 = "SELECT DATE_FORMAT(`last_modified`,'%Y-%m-%d %H:%i:%s') FROM `tbl_host` ". 121 "WHERE `host_name`='$strConfigName' AND `config_id`=".$this->intDomainId; 122 $strSQL2 = "SELECT `active` FROM `tbl_host` WHERE `host_name`='$strConfigName' ". 123 'AND `config_id`=' .$this->intDomainId; 124 $arrTimeData['table'] = $this->myDBClass->getFieldData($strSQL1); 125 $strActive = $this->myDBClass->getFieldData($strSQL2); 126 } elseif ($strTableName == 'tbl_service') { 127 $strSQL1 = "SELECT DATE_FORMAT(`last_modified`,'%Y-%m-%d %H:%i:%s') FROM `tbl_service` ". 128 "WHERE `id`='$intDataId' AND `config_id`=".$this->intDomainId; 129 $strSQL2 = "SELECT * FROM `$strTableName` WHERE `config_name`='$strConfigName' ". 130 'AND `config_id`=' .$this->intDomainId." AND `active`='1'"; 131 $arrTimeData['table'] = $this->myDBClass->getFieldData($strSQL1); 132 $intServiceCount = $this->myDBClass->countRows($strSQL2); 133 if ($intServiceCount != 0) { 134 $strActive = 1; 135 } 136 } else { 137 $intReturn = 1; 138 } 139 // Get config sets 140 $arrConfigId = array(); 141 $strTarget = ''; 142 $strBaseDir = ''; 143 $intTimeInfo = -1; 144 $intRetVal2 = $this->getConfigTargets($arrConfigId); 145 if ($intRetVal2 == 0) { 146 foreach ($arrConfigId as $intConfigId) { 147 // Get configuration file data 148 $this->getConfigValues($intConfigId, 'target', $strTarget); 149 // Get last change on dataset 150 if ($strTableName == 'tbl_host') { 151 $this->getConfigValues($intConfigId, 'hostconfig', $strBaseDir); 152 } elseif ($strTableName == 'tbl_service') { 153 $this->getConfigValues($intConfigId, 'serviceconfig', $strBaseDir); 154 } 155 $arrTimeData[$strTarget] = 'unknown'; 156 $intFileStampTemp = -1; 157 // Get time data 158 $intReturn = $this->getFileDate( 159 $intConfigId, 160 $strFileName, 161 $strBaseDir, 162 $intFileStampTemp, 163 $arrTimeData[$strTarget] 164 ); 165 if (($intFileStampTemp == 0) && ($strActive == '1')) { 166 $intTimeInfo = 2; 167 } 168 if (($strActive == '1') && (strtotime($arrTimeData['table']) > $intFileStampTemp)) { 169 $intTimeInfo = 1; 170 } 171 } 172 $intItems = \count($arrTimeData) - 1; 173 $intUnknown = 0; 174 $intUpToDate = 0; 175 foreach ($arrTimeData as $key) { 176 if ($key == 'unknown') { 177 $intUnknown++; 178 } 179 if (strtotime($arrTimeData['table']) < strtotime($key)) { 180 $intUpToDate++; 181 } 182 } 183 if ($intUnknown == $intItems) { 184 $intTimeInfo = 3; 185 } 186 if ($intUpToDate == $intItems) { 187 $intTimeInfo = 0; 188 } 189 } else { 190 $intTimeInfo = 4; 191 } 192 return $intReturn; 193 } 194 195 /** 196 * Get configuration target IDs 197 * @param array $arrConfigId Configuration target IDs (by reference) 198 * @return int 0 = successful / 1 = error 199 */ 200 public function getConfigTargets(&$arrConfigId) 201 { 202 // Variable definition 203 $arrData = array(); 204 $arrConfigId = array(); 205 $intDataCount = 0; 206 $intReturn = 1; 207 // Request target ID 208 $strSQL = 'SELECT `targets` FROM `tbl_datadomain` WHERE `id`=' .$this->intDomainId; 209 $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDataCount); 210 if ($booReturn && ($intDataCount != 0)) { 211 foreach ($arrData as $elem) { 212 $arrConfigId[] = $elem['targets']; 213 } 214 $intReturn = 0; 215 } 216 return $intReturn; 217 } 218 219 /** 220 * Get configuration domain values 221 * @param int $intConfigId Configuration ID 222 * @param string $strConfigKey Configuration key 223 * @param string $strValue Configuration value (by reference) 224 * @return int 0 = successful / 1 = error 225 */ 226 public function getConfigValues($intConfigId, $strConfigKey, &$strValue) 227 { 228 // Define variables 229 $intReturn = 1; 230 // Read database 231 $strSQL = 'SELECT `' .$strConfigKey. '` FROM `tbl_configtarget` WHERE `id`=' .$intConfigId; 232 $strValue = $this->myDBClass->getFieldData($strSQL); 233 if ($strValue != '') { 234 $intReturn = 0; 235 } 236 return $intReturn; 237 } 238 239 /** 240 * Get last modification date of a configuration file. 241 * @param int $intConfigId Configuration ID 242 * @param string $strFile Configuration file name 243 * @param string $strBaseDir Base directory with configuration file 244 * @param int|bool $intFileStamp File timestamp (by reference) 245 * @param string $strTimeData Human readable string of file time stamp (by reference) 246 * @return int 0 = successful / 1 = error 247 */ 248 public function getFileDate($intConfigId, $strFile, $strBaseDir, &$intFileStamp, &$strTimeData) 249 { 250 $strMethod = 1; 251 $intReturn = 0; 252 // Get configuration file data 253 $this->getConfigValues($intConfigId, 'method', $strMethod); 254 $strTimeData = 'unknown'; 255 $intFileStamp = -1; 256 // Lokal file system 257 if (($strMethod == 1) && file_exists($strBaseDir. '/' .$strFile)) { 258 $intFileStamp = filemtime($strBaseDir. '/' .$strFile); 259 $strTimeData = date('Y-m-d H:i:s', $intFileStamp); 260 } elseif ($strMethod == 2) { // FTP file system 261 // Check connection 262 $intReturn = $this->getFTPConnection($intConfigId); 263 if ($intReturn == 0) { 264 $intFileStamp = ftp_mdtm($this->resConnectId, $strBaseDir . '/' . $strFile); 265 if ($intFileStamp != -1) { 266 $strTimeData = date('Y-m-d H:i:s', $intFileStamp); 267 } 268 } 269 } elseif ($strMethod == 3) { // SSH file system 270 // Check connection 271 $intReturn = $this->getSSHConnection($intConfigId); 272 // Check file date 273 $strFilePath = str_replace('//', '/', $strBaseDir.'/'.$strFile); 274 $strCommand = 'ls '.$strFilePath; 275 $arrResult = array(); 276 if (($intReturn == 0) && ($this->sendSSHCommand($strCommand, $arrResult) == 0) && 277 isset($arrResult[0]) && ($arrResult[0] == $strFilePath)) { 278 $arrInfo = ssh2_sftp_stat($this->resSFTP, $strFilePath); 279 $intFileStamp = $arrInfo['mtime']; 280 if ($intFileStamp != -1) { 281 $strTimeData = date('Y-m-d H:i:s', $intFileStamp); 282 } 283 } 284 } 285 return $intReturn; 286 } 287 288 /** 289 * Open an FTP connection 290 * @param int $intConfigID Configuration ID 291 * @return int 0 = successful / 1 = error 292 * Status messages are stored in class variables 293 */ 294 public function getFTPConnection($intConfigID) 295 { 296 // Define variables 297 $intReturn = 0; 298 $arrError = array(); 299 // Already connected? 300 if (empty($this->resConnectId) || !\is_resource($this->resConnectId) || ($this->resConnectType != 'FTP')) { 301 // Define variables 302 $booLogin = false; 303 $this->getConfigValues($intConfigID, 'server', $strServer); 304 $this->getConfigValues($intConfigID, 'ftp_secure', $intFtpSecure); 305 // Set up basic connection 306 $this->resConnectServer = $strServer; 307 $this->resConnectType = 'FTP'; 308 // Secure FTP? 309 if ($intFtpSecure == 1) { 310 $this->resConnectId = ftp_ssl_connect($strServer); 311 } else { 312 $this->resConnectId = ftp_connect($strServer); 313 } 314 // Login with username and password 315 if ($this->resConnectId) { 316 $this->getConfigValues($intConfigID, 'user', $strUser); 317 $this->getConfigValues($intConfigID, 'password', $strPasswd); 318 $intErrorReporting = error_reporting(); 319 error_reporting('0'); 320 $booLogin = ftp_login($this->resConnectId, $strUser, $strPasswd); 321 $arrError = error_get_last(); 322 error_reporting($intErrorReporting); 323 if ($booLogin == false) { 324 ftp_close($this->resConnectId); 325 $this->resConnectServer = ''; 326 $this->resConnectType = 'none'; 327 $this->resConnectId = null; 328 $intReturn = 1; 329 } else { 330 // Change to PASV mode 331 ftp_pasv($this->resConnectId, true); 332 } 333 } 334 // Check connection 335 if ((!$this->resConnectId) || (!$booLogin)) { 336 $this->myDataClass->writeLog(translate('Connection to remote system failed (FTP connection):') . 337 ' ' . $strServer); 338 $this->processClassMessage(translate('Connection to remote system failed (FTP connection):') . 339 ' <b>' . $strServer . '</b>::', $this->strErrorMessage); 340 if ($arrError !== null && ($arrError['message'] != '')) { 341 $this->processClassMessage($arrError['message'] . '::', $this->strErrorMessage); 342 } 343 } 344 } 345 return $intReturn; 346 } 347 348 /** 349 * Open an SSH connection 350 * @param int $intConfigID Configuration ID 351 * @return int 0 = successful / 1 = error 352 * Status messages are stored in class variables 353 */ 354 public function getSSHConnection($intConfigID) 355 { 356 // Define variables 357 $intReturn = 0; 358 $strPasswordNote = ''; 359 // Already connected? 360 if (empty($this->resConnectId) || !\is_resource($this->resConnectId) || ($this->resConnectType != 'SSH')) { 361 // SSH Possible 362 if (!\function_exists('ssh2_connect')) { 363 $this->processClassMessage(translate('SSH module not loaded!'). '::', $this->strErrorMessage); 364 return 1; 365 } 366 // Define variables 367 $booLogin = false; 368 $this->getConfigValues($intConfigID, 'server', $strServer); 369 $this->getConfigValues($intConfigID, 'port', $intPort); 370 $this->resConnectServer = $strServer; 371 $this->resConnectType = 'SSH'; 372 $intPort = (int)$intPort; 373 if ($intPort == 0) { 374 $intPort = 22; 375 } 376 $intErrorReporting = error_reporting(); 377 error_reporting(0); 378 $this->resConnectId = ssh2_connect($strServer, $intPort); 379 $arrError = error_get_last(); 380 error_reporting($intErrorReporting); 381 // Check connection 382 if ($this->resConnectId) { 383 // Login with username and password 384 $this->getConfigValues($intConfigID, 'user', $strUser); 385 $this->getConfigValues($intConfigID, 'password', $strPasswd); 386 $this->getConfigValues($intConfigID, 'ssh_key_path', $strSSHKeyPath); 387 if ($strSSHKeyPath != '') { 388 $strPublicKey = str_replace('//', '/', $strSSHKeyPath.'/id_rsa.pub'); 389 $strPrivatKey = str_replace('//', '/', $strSSHKeyPath.'/id_rsa'); 390 // Check if ssh key file are readable 391 if (!file_exists($strPublicKey) || !is_readable($strPublicKey)) { 392 $this->myDataClass->writeLog(translate('SSH public key does not exist or is not readable') 393 . ' ' . $strSSHKeyPath.$strPublicKey); 394 $this->processClassMessage(translate('SSH public key does not exist or is not readable') 395 . ' <b>' . $strSSHKeyPath.$strPublicKey. '</b>::', $this->strErrorMessage); 396 $intReturn = 1; 397 } 398 if (!file_exists($strPrivatKey) || !is_readable($strPrivatKey)) { 399 $this->myDataClass->writeLog(translate('SSH private key does not exist or is not readable') 400 . ' ' . $strPrivatKey); 401 $this->processClassMessage(translate('SSH private key does not exist or is not readable'). ' ' . 402 $strPrivatKey. '::', $this->strErrorMessage); 403 $intReturn = 1; 404 } 405 $intErrorReporting = error_reporting(); 406 error_reporting(0); 407 if ($strPasswd == '') { 408 $booLogin = ssh2_auth_pubkey_file( 409 $this->resConnectId, 410 $strUser, 411 $strSSHKeyPath. '/id_rsa.pub', 412 $strSSHKeyPath. '/id_rsa' 413 ); 414 } else { 415 $booLogin = ssh2_auth_pubkey_file( 416 $this->resConnectId, 417 $strUser, 418 $strSSHKeyPath. '/id_rsa.pub', 419 $strSSHKeyPath. '/id_rsa', 420 $strPasswd 421 ); 422 } 423 $arrError = error_get_last(); 424 error_reporting($intErrorReporting); 425 } else { 426 $intErrorReporting = error_reporting(); 427 error_reporting(0); 428 $booLogin = ssh2_auth_password($this->resConnectId, $strUser, $strPasswd); 429 $arrError = error_get_last(); 430 $strPasswordNote = 'If you are using ssh2 with user/password - you have to enable ' . 431 'PasswordAuthentication in your sshd_config'; 432 error_reporting($intErrorReporting); 433 } 434 } else { 435 $this->myDataClass->writeLog(translate('Connection to remote system failed (SSH2 connection):'). 436 ' ' .$strServer. ' / ' . translate('port') . ' : ' .$intPort); 437 $this->processClassMessage(translate('Connection to remote system failed (SSH2 connection):'). 438 ' <b>' .$strServer. ' / ' . translate('port') . ' : ' .$intPort. '</b>::', $this->strErrorMessage); 439 if ($arrError['message'] != '') { 440 $this->processClassMessage($arrError['message']. '::', $this->strErrorMessage); 441 } 442 $intReturn = 1; 443 } 444 // Check connection 445 if ((!$this->resConnectId) || (!$booLogin)) { 446 $this->myDataClass->writeLog(translate('Connection to remote system failed (SSH2 connection):'). 447 ' ' .$strServer. ' / ' . translate('port') . ' : ' .$intPort); 448 $this->processClassMessage(translate('Connection to remote system failed (SSH2 connection):') 449 . ' ' .$strServer. ' / ' . translate('port') . ' : ' .$intPort. '::', $this->strErrorMessage); 450 if ($arrError['message'] != '') { 451 $this->processClassMessage($arrError['message']. '::', $this->strErrorMessage); 452 } 453 if ($strPasswordNote !== null) { 454 $this->processClassMessage($strPasswordNote. '::', $this->strErrorMessage); 455 } 456 $this->resConnectServer = ''; 457 $this->resConnectType = 'none'; 458 $this->resConnectId = null; 459 $intReturn = 1; 460 } else { 461 // Etablish an SFTP connection ressource 462 $this->resSFTP = ssh2_sftp($this->resConnectId); 463 } 464 } 465 return $intReturn; 466 } 467 468 /** 469 * Sends a command via SSH and stores the result in an array 470 * @param string $strCommand Command string 471 * @param array $arrResult Output as array (by reference) 472 * @param int $intLines Maximal length of output to read 473 * @return int 0 = successful / 1 = error 474 */ 475 public function sendSSHCommand($strCommand, &$arrResult, $intLines = 100) 476 { 477 // Define variables 478 $intCount1 = 0; // empty lines 479 $intCount2 = 0; // data lines 480 $booBreak = false; 481 $this->getConfigTargets($arrConfigSet); 482 // Check connection 483 $intReturn = $this->getSSHConnection($arrConfigSet[0]); 484 if (\is_resource($this->resConnectId)) { 485 // Send command 486 $resStream = ssh2_exec($this->resConnectId, $strCommand.'; echo __END__'); 487 if ($resStream) { 488 // read result 489 stream_set_blocking($resStream, true); 490 stream_set_timeout($resStream, 2); 491 do { 492 $strLine = stream_get_line($resStream, 1024, "\n"); 493 if ($strLine == '') { 494 $intCount1++; 495 } elseif (substr_count($strLine, '__END__') != 1) { 496 $arrResult[] = $strLine; 497 $intReturn = 0; 498 } elseif (substr_count($strLine, '__END__') == 1) { 499 $booBreak = true; 500 } 501 $intCount2++; 502 $arrStatus = stream_get_meta_data($resStream); 503 } while ($resStream && !feof($resStream) && ($intCount1 <= 10) && ($intCount2 <= $intLines) && 504 ($arrStatus['timed_out'] != true) && $booBreak == false); 505 fclose($resStream); 506 // Close SSH connection because of timing problems 507 unset($this->resConnectId); 508 //sleep(1); 509 } 510 } 511 return $intReturn; 512 } 513 514 /** 515 * Merge message strings and check for duplicate messages 516 * @param string $strNewMessage New message to add 517 * @param string $strOldMessage Modified message string (by reference) 518 */ 519 public function processClassMessage($strNewMessage, &$strOldMessage) 520 { 521 $strNewMessage = str_replace('::::', '::', $strNewMessage); 522 if (($strOldMessage != '') && ($strNewMessage != '') && (substr_count($strOldMessage, $strNewMessage) == 0)) { 523 $strOldMessage .= $strNewMessage; 524 } elseif ($strOldMessage == '') { 525 $strOldMessage .= $strNewMessage; 526 } 527 } 528 529 /** 530 * Get configuration target IDs 531 * @param array $arrConfigId Configuration target IDs (by reference) 532 * @return int 0 = successful / 1 = error 533 */ 534 public function getConfigSets(&$arrConfigId) 535 { 536 // Variable definition 537 $arrData = array(); 538 $arrConfigId = array(); 539 $intDataCount = 0; 540 $intReturn = 1; 541 // Request target ID 542 $strSQL = 'SELECT `targets` FROM `tbl_datadomain` WHERE `id`=' .$this->intDomainId; 543 $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDataCount); 544 if ($booReturn && ($intDataCount != 0)) { 545 foreach ($arrData as $elem) { 546 $arrConfigId[] = $elem['targets']; 547 } 548 $intReturn = 0; 549 } 550 return $intReturn; 551 } 552 553 /** 554 * Moves an existing configuration file to the backup directory and removes then the original file 555 * @param string $strType Type of the configuration file 556 * @param string $strName Name of the configuration file 557 * @param int $intConfigID Configuration target ID 558 * @return int 0 = successful / 1 = error 559 * Status message is stored in message class variables 560 */ 561 public function moveFile($strType, $strName, $intConfigID) 562 { 563 // Variable definitions 564 $strConfigDir = ''; 565 $strBackupDir = ''; 566 $intReturn = 0; 567 // Get directories 568 switch ($strType) { 569 case 'host': 570 $this->getConfigData($intConfigID, 'hostconfig', $strConfigDir); 571 $this->getConfigData($intConfigID, 'hostbackup', $strBackupDir); 572 break; 573 case 'service': 574 $this->getConfigData($intConfigID, 'serviceconfig', $strConfigDir); 575 $this->getConfigData($intConfigID, 'servicebackup', $strBackupDir); 576 break; 577 case 'basic': 578 $this->getConfigData($intConfigID, 'basedir', $strConfigDir); 579 $this->getConfigData($intConfigID, 'backupdir', $strBackupDir); 580 break; 581 case 'nagiosbasic': 582 $this->getConfigData($intConfigID, 'nagiosbasedir', $strConfigDir); 583 $this->getConfigData($intConfigID, 'backupdir', $strBackupDir); 584 break; 585 default: 586 $intReturn = 1; 587 } 588 if ($intReturn == 0) { 589 // Variable definition 590 $intMethod = 1; 591 $strDate = date('YmdHis'); 592 $strSourceFile = $strConfigDir. '/' .$strName; 593 $strDestinationFile = $strBackupDir. '/' .$strName. '_old_' .$strDate; 594 $booRetVal = false; 595 // Get connection method 596 $this->getConfigData($intConfigID, 'method', $intMethod); 597 // Local file system 598 if ($intMethod == 1) { 599 // Save configuration file 600 if (file_exists($strSourceFile)) { 601 if (is_writable($strBackupDir) && is_writable($strConfigDir)) { 602 copy($strSourceFile, $strDestinationFile); 603 unlink($strSourceFile); 604 } else { 605 $this->processClassMessage(translate('Cannot backup the old file because the permissions are ' 606 .'wrong - destination file: ').$strDestinationFile. '::', $this->strErrorMessage); 607 $intReturn = 1; 608 } 609 } else { 610 $this->processClassMessage(translate('Cannot backup the old file because the source file is ' 611 . 'missing - source file: ') . $strSourceFile . '::', $this->strErrorMessage); 612 $intReturn = 1; 613 } 614 } elseif ($intMethod == 2) { // Remote file (FTP) 615 // Check connection 616 $intReturn = $this->getFTPConnection($intConfigID); 617 if ($intReturn == 0) { 618 $strSourceFile = str_replace('//', '/', $strSourceFile); 619 $strDestinationFile = str_replace('//', '/', $strDestinationFile); 620 // Save configuration file 621 $intFileStamp = ftp_mdtm($this->resConnectId, $strSourceFile); 622 if ($intFileStamp > -1) { 623 $intErrorReporting = error_reporting(); 624 error_reporting(0); 625 $booRetVal = ftp_rename($this->resConnectId, $strSourceFile, $strDestinationFile); 626 error_reporting($intErrorReporting); 627 } else { 628 $this->processClassMessage(translate('Cannot backup the old file because the source file is ' 629 .'missing (remote FTP) - source file: '). $strSourceFile. '::', $this->strErrorMessage); 630 $intReturn = 1; 631 } 632 } 633 if (($booRetVal == false) && ($intReturn == 0)) { 634 $this->processClassMessage(translate('Cannot backup the old file because the permissions are ' 635 .'wrong (remote FTP) - destination file: ').$strDestinationFile. '::', $this->strErrorMessage); 636 $intReturn = 1; 637 } 638 } elseif ($intMethod == 3) { // Remote file (SFTP) 639 // Check connection 640 $intReturn = $this->getSSHConnection($intConfigID); 641 // Save configuration file 642 $arrResult = array(); 643 $strSourceFile = str_replace('//', '/', $strSourceFile); 644 $strDestinationFile = str_replace('//', '/', $strDestinationFile); 645 $strCommand = 'ls '.$strSourceFile; 646 if (($intReturn == 0) && ($this->sendSSHCommand($strCommand, $arrResult) == 0)) { 647 if (isset($arrResult[0]) && $arrResult[0] == $strSourceFile) { 648 $arrInfo = ssh2_sftp_stat($this->resSFTP, $strSourceFile); 649 if ($arrInfo['mtime'] > -1) { 650 $booRetVal = ssh2_sftp_rename($this->resSFTP, $strSourceFile, $strDestinationFile); 651 } 652 } else { 653 $this->processClassMessage(translate('Cannot backup the old file because the source file is ' 654 .'missing (remote SFTP) - source file: '). $strSourceFile. '::', $this->strErrorMessage); 655 $intReturn = 1; 656 } 657 } 658 if (($booRetVal == false) && ($intReturn == 0)) { 659 $this->processClassMessage(translate('Cannot backup the old file because the permissions are ' 660 .'wrong (remote SFTP) - destination file: ').$strDestinationFile. '::', $this->strErrorMessage); 661 $intReturn = 1; 662 } 663 } 664 } 665 return $intReturn; 666 } 667 668 /** 669 * Remove a file 670 * @param string $strFileName Filename including path to remove 671 * @param int $intConfigID Configuration target ID 672 * @return int 0 = successful / 1 = error 673 * Status message is stored in message class variables 674 */ 675 public function removeFile($strFileName, $intConfigID) 676 { 677 // Variable definitions 678 $intMethod = 1; 679 $intReturn = 0; 680 $booRetVal = false; 681 // Get connection method 682 $this->getConfigData($intConfigID, 'method', $intMethod); 683 // Local file system 684 if ($intMethod == 1) { 685 // Save configuration file 686 if (file_exists($strFileName)) { 687 if (is_writable($strFileName)) { 688 unlink($strFileName); 689 } else { 690 $this->processClassMessage(translate('Cannot delete the file (wrong permissions)!').'::'. 691 $strFileName. '::', $this->strErrorMessage); 692 $intReturn = 1; 693 } 694 } else { 695 $this->processClassMessage(translate('Cannot delete the file (file does not exist)!').'::'. 696 $strFileName. '::', $this->strErrorMessage); 697 $intReturn = 1; 698 } 699 } elseif ($intMethod == 2) { // Remote file (FTP) 700 // Check connection 701 $intReturn = $this->getFTPConnection($intConfigID); 702 if ($intReturn == 0) { 703 // Save configuration file 704 $intFileStamp = ftp_mdtm($this->resConnectId, $strFileName); 705 if ($intFileStamp > -1) { 706 $intErrorReporting = error_reporting(); 707 error_reporting(0); 708 $booRetVal = ftp_delete($this->resConnectId, $strFileName); 709 error_reporting($intErrorReporting); 710 } else { 711 $this->processClassMessage(translate('Cannot delete file because it does not exists (remote ' 712 . 'FTP)!'). '::', $this->strErrorMessage); 713 $intReturn = 1; 714 } 715 } 716 if ($booRetVal == false) { 717 $this->processClassMessage(translate('Cannot delete file because the permissions are incorrect ' 718 . '(remote FTP)!'). '::', $this->strErrorMessage); 719 $intReturn = 1; 720 } 721 } elseif ($intMethod == 3) { // Remote file (SFTP) 722 // Check connection 723 $intReturn = $this->getSSHConnection($intConfigID); 724 // Save configuration file 725 if (($intReturn == 0) && ($this->sendSSHCommand('ls '.$strFileName, $arrResult) == 0)) { 726 if (isset($arrResult[0])) { 727 $booRetVal = ssh2_sftp_unlink($this->resSFTP, $strFileName); 728 } else { 729 $this->processClassMessage(translate('Cannot delete file because it does not exists (remote ' 730 . 'SSH/SFTP)!'). '::', $this->strErrorMessage); 731 $intReturn = 1; 732 } 733 } 734 if (($intReturn == 0) && ($booRetVal == false)) { 735 $this->processClassMessage(translate('Cannot delete file because the permissions are incorrect ' 736 . '(remote SSH/SFTP)!'). '::', $this->strErrorMessage); 737 $intReturn = 1; 738 } 739 } 740 return $intReturn; 741 } 742 743 /** 744 * Get configuration domain parameters 745 * @param int $intConfigId Configuration ID 746 * @param string $strConfigItem Configuration key 747 * @param string $strValue Configuration value (by reference) 748 * @return int 0 = successful / 1 = error 749 */ 750 public function getConfigData($intConfigId, $strConfigItem, &$strValue) 751 { 752 $intReturn = 1; 753 $strSQL = 'SELECT `' .$strConfigItem. '` FROM `tbl_configtarget` WHERE `id` = ' .$intConfigId; 754 $strValue = $this->myDBClass->getFieldData($strSQL); 755 if ($strValue != '') { 756 $intReturn = 0; 757 } 758 return $intReturn; 759 } 760 761 /** 762 * Check a directory for write access 763 * @param string $strPath Physical path 764 * @return int 0 = successful / 1 = error 765 */ 766 public function isDirWriteable($strPath) 767 { 768 // Define variables 769 $intReturnFile = 1; 770 $intReturnDir = 1; 771 $intReturn = 1; 772 // Is input path a file? 773 if (file_exists($strPath) && is_file($strPath)) { 774 $resFile = fopen($strPath, 'ab'); 775 if ($resFile) { 776 $intReturnFile = 0; 777 } 778 } else { 779 $intReturnFile = 0; 780 } 781 if (is_file($strPath)) { 782 $strDirectory = \dirname($strPath); 783 } else { 784 $strDirectory = $strPath; 785 } 786 $strFile = $strDirectory.'/'.uniqid(mt_rand(), true).'.tmp'; 787 // Check writing in directory directly 788 if (is_dir($strDirectory) && is_writable($strDirectory)) { 789 $resFile = fopen($strFile, 'wb'); 790 if ($resFile) { 791 $intReturnDir = 0; 792 unlink($strFile); 793 } 794 } else { 795 $intReturnDir = 0; 796 } 797 if (($intReturnDir == 0) && ($intReturnFile == 0)) { 798 $intReturn = 0; 799 } 800 return $intReturn; 801 } 802 803 /** 804 * Copy a remote file 805 * @param string $strFileRemote Remote file name 806 * @param int $intConfigID Configuration target id 807 * @param string $strFileLocal Local file name 808 * @param int $intDirection 0 = from remote to local / 1 = from local to remote 809 * @return int 0 = successful / 1 = error 810 * Status message is stored in message class variables 811 */ 812 public function remoteFileCopy($strFileRemote, $intConfigID, $strFileLocal, $intDirection = 0) 813 { 814 // Variable definitions 815 $intMethod = 3; 816 $intReturn = 0; 817 $arrTemp = array(); 818 // Get method 819 $this->getConfigData($intConfigID, 'method', $intMethod); 820 if ($intMethod == 2) { 821 // Check connection 822 $intReturn = $this->getFTPConnection($intConfigID); 823 if (($intReturn == 0) && ($intDirection == 0)) { 824 $intErrorReporting = error_reporting(); 825 error_reporting(0); 826 if (!ftp_get($this->resConnectId, $strFileLocal, $strFileRemote, FTP_ASCII)) { 827 $this->processClassMessage(translate('Cannot get the remote file (it does not exist or is not ' 828 . 'readable) - remote file: '). $strFileRemote. '::', $this->strErrorMessage); 829 $intReturn = 1; 830 } 831 error_reporting($intErrorReporting); 832 } elseif (($intReturn == 0) && ($intDirection == 1)) { 833 $intErrorReporting = error_reporting(); 834 error_reporting(0); 835 if (!ftp_put($this->resConnectId, $strFileRemote, $strFileLocal, FTP_ASCII)) { 836 $this->processClassMessage(translate('Cannot write the remote file (remote file is not writeable)' 837 . '- remote file: ').$strFileRemote. '::', $this->strErrorMessage); 838 $intReturn = 1; 839 } 840 error_reporting($intErrorReporting); 841 } 842 ftp_close($this->resConnectId); 843 } elseif ($intMethod == 3) { // Remote file (SFTP) 844 $intReturn = $this->getSSHConnection($intConfigID); 845 if (($intReturn == 0) && ($intDirection == 0)) { 846 // Copy file 847 $intErrorReporting = error_reporting(); 848 error_reporting(0); 849 if (!ssh2_scp_recv($this->resConnectId, $strFileRemote, $strFileLocal)) { 850 if ($this->sendSSHCommand('ls ' . $strFileRemote, $arrTemp) != 0) { 851 $this->processClassMessage(translate('Cannot get the remote file (it does not exist or is not ' 852 . 'readable) - remote file: ') .$strFileRemote. '::', $this->strErrorMessage); 853 } else { 854 $this->processClassMessage(translate('Remote file is not readable - remote file: ') 855 . $strFileRemote. '::', $this->strErrorMessage); 856 } 857 $intReturn = 1; 858 } 859 error_reporting($intErrorReporting); 860 } elseif (($intReturn == 0) && ($intDirection == 1)) { 861 if (file_exists($strFileLocal) && is_readable($strFileLocal)) { 862 $intErrorReporting = error_reporting(); 863 error_reporting(0); 864 if (!ssh2_scp_send($this->resConnectId, $strFileLocal, $strFileRemote, 0644)) { 865 $this->processClassMessage(translate('Cannot write a remote file (remote file is not writeable)' 866 .' - remote file: '). $strFileRemote . '::', $this->strErrorMessage); 867 $intReturn = 1; 868 } 869 error_reporting($intErrorReporting); 870 } else { 871 $this->processClassMessage(translate('Cannot copy a local file to remote because the local file '. 872 'does not exist or is not readable - local file: '). 873 $strFileLocal . '::', $this->strErrorMessage); 874 $intReturn = 1; 875 } 876 } 877 } 878 return $intReturn; 879 } 880 881 /** 882 * Add files of a given directory to an array 883 * @param string $strSourceDir Source directory 884 * @param string $strIncPattern Include file pattern 885 * @param string $strExcPattern Exclude file pattern 886 * @param array $arrOutput Output array (by reference) 887 * @param string $strErrorMessage Error messages (by reference) 888 */ 889 public function storeDirToArray($strSourceDir, $strIncPattern, $strExcPattern, &$arrOutput, &$strErrorMessage) 890 { 891 // Define variables 892 $arrDir = array(); 893 while (substr($strSourceDir, -1) == '/' or substr($strSourceDir, -1) == "\\") { 894 $strSourceDir = substr($strSourceDir, 0, -1); 895 } 896 $resHandle = opendir($strSourceDir); 897 if ($resHandle === false) { 898 if ($this->intDomainId != 0) { 899 $strErrorMessage .= translate('Could not open directory'). ': ' .$strSourceDir; 900 } 901 } else { 902 $booBreak = true; 903 while ($booBreak) { 904 if (!$arrDir[] = readdir($resHandle)) { 905 $booBreak = false; 906 } 907 } 908 closedir($resHandle); 909 sort($arrDir); 910 /** @var string $file */ 911 foreach ($arrDir as $file) { 912 /** @noinspection StrlenInEmptyStringCheckContextInspection */ 913 if (!preg_match("/^\.{1,2}/", $file) && \strlen($file)) { 914 if (is_dir($strSourceDir. '/' .$file)) { 915 $this->storeDirToArray( 916 $strSourceDir. '/' .$file, 917 $strIncPattern, 918 $strExcPattern, 919 $arrOutput, 920 $strErrorMessage 921 ); 922 } else { 923 if (preg_match('/' .$strIncPattern. '/', $file) && (($strExcPattern == '') || 924 !preg_match('/' .$strExcPattern. '/', $file))) { 925 if (0 === stripos(PHP_OS, 'WIN')) { 926 $strSourceDir=str_replace('/', "\\", $strSourceDir); 927 $arrOutput [] = $strSourceDir."\\".$file; 928 } else { 929 $arrOutput [] = $strSourceDir. '/' .$file; 930 } 931 } 932 } 933 } 934 } 935 } 936 } 937 938 /** 939 * Determines the dates of the last data table change and the last modification to the configuration files 940 * @param string $strTableName Name of the data table 941 * @param array $arrTimeData Array with time data of table and all config files 942 * @param string $strCheckConfig Information string (text message) 943 * @return int 0 = successful / 1 = error 944 * Status message is stored in message class variables 945 */ 946 public function lastModifiedFile($strTableName, &$arrTimeData, &$strCheckConfig) 947 { 948 // Variable definitions 949 $intEnableCommon = 0; 950 $arrDataset = array(); 951 $strFileName = ''; 952 $strCheckConfig = ''; 953 $intReturn = 0; 954 // Get configuration filename based on table name 955 $arrConfigData = $this->getConfData(); 956 if (isset($arrConfigData[$strTableName])) { 957 $strFileName = $arrConfigData[$strTableName]['filename']; 958 } else { 959 $intReturn = 1; 960 } 961 // Get table times 962 $arrTimeData = array(); 963 $arrTimeData['table'] = 'unknown'; 964 // Clear status cache 965 clearstatcache(); 966 $intRetVal1 = $this->getDomainData('enable_common', $intEnableCommon); 967 // Get last change of date table 968 if ($intRetVal1 == 0) { 969 $strSQLAdd = ''; 970 if ($intEnableCommon == 1) { 971 $strSQLAdd = 'OR `domainId`=0'; 972 } 973 $strSQL = 'SELECT `updateTime` FROM `tbl_tablestatus` ' 974 . 'WHERE (`domainId`=' .$this->intDomainId." $strSQLAdd) AND `tableName`='".$strTableName."' " 975 . 'ORDER BY `updateTime` DESC LIMIT 1'; 976 $booReturn = $this->myDBClass->hasSingleDataset($strSQL, $arrDataset); 977 if ($booReturn && isset($arrDataset['updateTime'])) { 978 $arrTimeData['table'] = $arrDataset['updateTime']; 979 } else { 980 $strSQL = 'SELECT `last_modified` FROM `' .$strTableName. '` ' 981 . 'WHERE `config_id`=' .$this->intDomainId. ' ORDER BY `last_modified` DESC LIMIT 1'; 982 $booReturn = $this->myDBClass->hasSingleDataset($strSQL, $arrDataset); 983 if (($booReturn == true) && isset($arrDataset['last_modified'])) { 984 $arrTimeData['table'] = $arrDataset['last_modified']; 985 } 986 } 987 } 988 // Get config sets 989 $arrConfigId = array(); 990 $strTarget = ''; 991 $strBaseDir = ''; 992 $intFileStampTemp = 0; 993 $intRetVal2 = $this->getConfigSets($arrConfigId); 994 if ($intRetVal2 == 0) { 995 foreach ($arrConfigId as $intConfigId) { 996 // Get configuration file data 997 $this->getConfigData($intConfigId, 'target', $strTarget); 998 $this->getConfigData($intConfigId, 'basedir', $strBaseDir); 999 // Get time data 1000 $intReturn = $this->getFileDate( 1001 $intConfigId, 1002 $strFileName, 1003 $strBaseDir, 1004 $intFileStampTemp, 1005 $arrTimeData[$strTarget] 1006 ); 1007 if ($intFileStampTemp != 0 && strtotime($arrTimeData['table']) > $intFileStampTemp) { 1008 $strCheckConfig = translate('Warning: configuration file is out of date!'); 1009 } 1010 if ($arrTimeData[$strTarget] == 'unknown') { 1011 $strCheckConfig = translate('Warning: configuration file is out of date!'); 1012 } 1013 } 1014 } else { 1015 $strCheckConfig = translate('Warning: no configuration target defined!'); 1016 } 1017 return $intReturn; 1018 } 1019 1020 /** 1021 * Writes a configuration file including all datasets of a configuration table or returns the output as a text 1022 * file for download. (Public master function) 1023 * @param string $strTableName Table name 1024 * @param int $intMode 0 = Write file to filesystem 1025 * 1 = Return Textfile for download test 1026 * @return int 0 = successful / 1 = error 1027 * Status message is stored in message class variables 1028 */ 1029 public function createConfig($strTableName, $intMode = 0) 1030 { 1031 // Define Variables 1032 $intReturn = 0; 1033 // Do not create configs in common domain 1034 if ($this->intDomainId == 0) { 1035 $this->processClassMessage(translate('It is not possible to write config files directly from the common ' 1036 . 'domain!'). '::', $this->strErrorMessage); 1037 $intReturn = 1; 1038 } 1039 if ($intReturn == 0) { 1040 // Get configuration targets 1041 $this->getConfigSets($arrConfigID); 1042 if (($arrConfigID != 1) && \is_array($arrConfigID)) { 1043 foreach ($arrConfigID as $intConfigID) { 1044 $intReturn = $this->writeConfTemplate($intConfigID, $strTableName, $intMode); 1045 } 1046 } else { 1047 $this->processClassMessage(translate('Warning: no configuration target defined!'). 1048 '::', $this->strErrorMessage); 1049 $intReturn = 1; 1050 } 1051 } 1052 return $intReturn; 1053 } 1054 1055 /** 1056 * Writes a configuration file including one single datasets of a configuration table or returns the output as 1057 * a text file for download. 1058 * @param string $strTableName Table name 1059 * @param int $intDbId Data ID 1060 * @param int $intMode 0 = Write file to filesystem 1061 * 1 = Return Textfile for download test 1062 * @return int 0 = successful / 1 = error 1063 * Status message is stored in message class variables 1064 */ 1065 public function createConfigSingle($strTableName, $intDbId = 0, $intMode = 0) 1066 { 1067 // Define Variables 1068 $arrData = array(); 1069 $intDataCount = 0; 1070 $setEnableCommon = 0; 1071 $intReturn = 0; 1072 $strDomainWhere = ' (`config_id`=' .$this->intDomainId. ') '; 1073 // Read some settings and informations 1074 $this->getDomainData('enable_common', $setEnableCommon); 1075 // Variable rewritting 1076 if ($setEnableCommon != 0) { 1077 $strDomainWhere = str_replace(')', ' OR `config_id`=0)', $strDomainWhere); 1078 } 1079 // Do not create configs in common domain 1080 if ($this->intDomainId == 0) { 1081 $this->processClassMessage(translate('It is not possible to write config files directly from the common ' 1082 . 'domain!'). '::', $this->strErrorMessage); 1083 $intReturn = 1; 1084 } 1085 if ($intReturn == 0) { 1086 if ($intDbId == 0) { 1087 $strSQL = 'SELECT * FROM `' .$strTableName."` WHERE $strDomainWhere AND `active`='1' ORDER BY `id`"; 1088 } else { 1089 $strSQL = 'SELECT * FROM `' .$strTableName."` WHERE $strDomainWhere AND `active`='1' AND `id`=$intDbId"; 1090 } 1091 $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDataCount); 1092 if (($booReturn != false) && ($intDataCount != 0)) { 1093 /** @noinspection ForeachInvariantsInspection */ 1094 for ($i = 0; $i < $intDataCount; $i++) { 1095 // Process form POST variable 1096 $strChbName = 'chbId_' .$arrData[$i]['id']; 1097 // Check if this POST variable exists or the data ID parameter matches 1098 if ((($intDbId != 0) && ($intDbId == $arrData[$i]['id'])) || 1099 (filter_input(INPUT_POST, $strChbName) !== null)) { 1100 // Get configuration targets 1101 $this->getConfigSets($arrConfigID); 1102 if (($arrConfigID != 1) && \is_array($arrConfigID)) { 1103 foreach ($arrConfigID as $intConfigID) { 1104 $intReturn = $this->writeConfTemplate( 1105 $intConfigID, 1106 $strTableName, 1107 $intMode, 1108 $arrData, 1109 $i 1110 ); 1111 } 1112 } else { 1113 $this->processClassMessage(translate('Warning: no configuration target defined!'). 1114 '::', $this->strErrorMessage); 1115 $intReturn = 1; 1116 } 1117 } 1118 } 1119 } else { 1120 $this->myDataClass->writeLog(translate('Writing of the configuration failed - no dataset or not ' 1121 . 'activated dataset found')); 1122 $this->processClassMessage(translate('Writing of the configuration failed - no dataset or not ' 1123 . 'activated dataset found'). '::', $this->strErrorMessage); 1124 $intReturn = 1; 1125 } 1126 } 1127 return $intReturn; 1128 } 1129 1130 1131 // PRIVATE functions 1132 1133 /** 1134 * Determines the configuration data for each database table 1135 * @return array filename (configuration file name) 1136 * order_field (database order field) 1137 */ 1138 public function getConfData() 1139 { 1140 $arrConfData['tbl_timeperiod'] = array('filename' => 'timeperiods.cfg', 1141 'order_field' => 'timeperiod_name'); 1142 $arrConfData['tbl_command'] = array('filename' => 'commands.cfg', 1143 'order_field' => 'command_name'); 1144 $arrConfData['tbl_contact'] = array('filename' => 'contacts.cfg', 1145 'order_field' => 'contact_name'); 1146 $arrConfData['tbl_contacttemplate'] = array('filename' => 'contacttemplates.cfg', 1147 'order_field' => 'template_name'); 1148 $arrConfData['tbl_contactgroup'] = array('filename' => 'contactgroups.cfg', 1149 'order_field' => 'contactgroup_name'); 1150 $arrConfData['tbl_hosttemplate'] = array('filename' => 'hosttemplates.cfg', 1151 'order_field' => 'template_name'); 1152 $arrConfData['tbl_servicetemplate'] = array('filename' => 'servicetemplates.cfg', 1153 'order_field' => 'template_name'); 1154 $arrConfData['tbl_hostgroup'] = array('filename' => 'hostgroups.cfg', 1155 'order_field' => 'hostgroup_name'); 1156 $arrConfData['tbl_servicegroup'] = array('filename' => 'servicegroups.cfg', 1157 'order_field' => 'servicegroup_name'); 1158 $arrConfData['tbl_hostdependency'] = array('filename' => 'hostdependencies.cfg', 1159 'order_field' => 'dependent_host_name'); 1160 $arrConfData['tbl_servicedependency'] = array('filename' => 'servicedependencies.cfg', 1161 'order_field' => 'config_name'); 1162 $arrConfData['tbl_hostescalation'] = array('filename' => 'hostescalations.cfg', 1163 'order_field' => 'host_name`,`hostgroup_name'); 1164 $arrConfData['tbl_serviceescalation'] = array('filename' => 'serviceescalations.cfg', 1165 'order_field' => 'config_name'); 1166 $arrConfData['tbl_hostextinfo'] = array('filename' => 'hostextinfo.cfg', 1167 'order_field' => 'host_name'); 1168 $arrConfData['tbl_serviceextinfo'] = array('filename' => 'serviceextinfo.cfg', 1169 'order_field' => 'host_name'); 1170 return $arrConfData; 1171 } 1172 1173 /** 1174 * Writes a configuration file including all datasets of a configuration table or returns the output as a text 1175 * file for download. (Private worker function) 1176 * @param int $intConfigID Configuration target ID 1177 * @param string $strTableName Table name 1178 * @param int $intMode 0 = Write file to filesystem 1179 * 1 = Return Textfile for download test 1180 * @param array $arrTableData Dataset array for host and services only 1181 * @param int $intID Key for dataset array 1182 * @return int 0 = successful / 1 = error 1183 * Status message is stored in message class variables 1184 */ 1185 /** @noinspection ArrayTypeOfParameterByDefaultValueInspection */ 1186 private function writeConfTemplate($intConfigID, $strTableName, $intMode, $arrTableData = array(), $intID = 0) 1187 { 1188 // Variable definitions 1189 $strSQL = ''; 1190 $strOrderField = ''; 1191 $strFileString = ''; 1192 $arrTplOptions = array('use_preg' => false); 1193 $strDomainWhere = ' (`config_id`=' . $this->intDomainId . ') '; 1194 $intType = 0; 1195 $intReturn = 0; 1196 // Read some settings and informations 1197 $this->getConfigData($intConfigID, 'utf8_decode', $setUTF8Decode); 1198 $this->getDomainData('enable_common', $setEnableCommon); 1199 $this->getConfigData($intConfigID, 'version', $intNagiosVersion); 1200 $arrConfigData = $this->getConfData(); 1201 if (isset($arrConfigData[$strTableName])) { 1202 $strFileString = str_replace('.cfg', '', $arrConfigData[$strTableName]['filename']); 1203 $strOrderField = $arrConfigData[$strTableName]['order_field']; 1204 } 1205 // Variable rewritting 1206 if ($setEnableCommon != 0) { 1207 $strDomainWhere = str_replace(')', ' OR `config_id`=0)', $strDomainWhere); 1208 } 1209 // Special processing for table host and service 1210 $setTemplate = $strFileString. '.tpl.dat'; 1211 if (($strTableName == 'tbl_host') || ($strTableName == 'tbl_service')) { 1212 // Define variable names based on table name 1213 switch ($strTableName) { 1214 case 'tbl_host': 1215 $strFileString = $arrTableData[$intID]['host_name']; 1216 $intDomainId = $arrTableData[$intID]['config_id']; 1217 $setTemplate = 'hosts.tpl.dat'; 1218 $intType = 1; 1219 $strSQL = 'SELECT * FROM `' . $strTableName . "` WHERE `host_name`='$strFileString' " 1220 . "AND `active`='1' AND `config_id`=$intDomainId"; 1221 break; 1222 case 'tbl_service': 1223 $strFileString = $arrTableData[$intID]['config_name']; 1224 $intDomainId = $arrTableData[$intID]['config_id']; 1225 $setTemplate = 'services.tpl.dat'; 1226 $intType = 2; 1227 $strSQL = 'SELECT * FROM `' . $strTableName . "` WHERE `config_name`='$strFileString' " 1228 . "AND `active`='1' AND `config_id`=$intDomainId ORDER BY `service_description`"; 1229 break; 1230 } 1231 } else { 1232 $strSQL = 'SELECT * FROM `' .$strTableName."` WHERE $strDomainWhere AND `active`='1' ". 1233 'ORDER BY `' .$strOrderField. '`'; 1234 } 1235 $strFile = $strFileString. '.cfg'; 1236 // Load configuration template file 1237 $tplConf = new \HTML_Template_IT($this->arrSettings['path']['base_path']. '/templates/files/'); 1238 $tplConf->loadTemplatefile($setTemplate, true, true); 1239 $tplConf->setOptions($arrTplOptions); 1240 $tplConf->setVariable('CREATE_DATE', date('Y-m-d H:i:s')); 1241 $tplConf->setVariable('NAGIOS_QL_VERSION', $this->arrSettings['db']['version']); 1242 $tplConf->setVariable('VERSION', $this->getVersionString($intConfigID)); 1243 // Write data from configuration table 1244 $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDataCount); 1245 if ($booReturn && ($intDataCount != 0) && ($strFileString != '')) { 1246 // Process every data set 1247 /** @noinspection ForeachInvariantsInspection */ 1248 for ($i = 0; $i < $intDataCount; $i++) { 1249 $intDataId = 0; 1250 /** @noinspection ForeachSourceInspection */ 1251 foreach ($arrData[$i] as $key => $value) { 1252 if ($key == 'id') { 1253 $intDataId = $value; 1254 } 1255 if ($key == 'config_name') { 1256 $key = '#NAGIOSQL_CONFIG_NAME'; 1257 } 1258 // UTF8 decoded vaules 1259 if ($setUTF8Decode == 1) { 1260 $value = utf8_decode($value); 1261 } 1262 // Pass special fields (NagiosQL data fields not used by Nagios itselves) 1263 if ($this->skipEntries($strTableName, $intNagiosVersion, $key, $value) == 1) { 1264 continue; 1265 } 1266 // Get relation data 1267 $intSkip = $this->getRelationData($strTableName, $tplConf, $arrData[$i], $key, $value); 1268 // Rename field names 1269 $this->renameFields($strTableName, $intConfigID, $intDataId, $key, $value, $intSkip); 1270 // Inset data field 1271 if ($intSkip != 1) { 1272 // Insert fill spaces 1273 $strFillLen = (30- \strlen($key)); 1274 $strSpace = ' '; 1275 for ($f = 0; $f < $strFillLen; $f++) { 1276 $strSpace .= ' '; 1277 } 1278 // Write key and value to template 1279 $tplConf->setVariable('ITEM_TITLE', $key.$strSpace); 1280 // Short values 1281 if (($intNagiosVersion != 3) || (\strlen($value) < 800)) { 1282 $tplConf->setVariable('ITEM_VALUE', $value); 1283 $tplConf->parse('configline'); 1284 } else { // Long values 1285 $arrValueTemp = explode(',', $value); 1286 $strValueNew = ''; 1287 $intArrCount = \count($arrValueTemp); 1288 $intCounter = 0; 1289 $strSpace = ' '; 1290 for ($f = 0; $f < 30; $f++) { 1291 $strSpace .= ' '; 1292 } 1293 foreach ($arrValueTemp as $elem) { 1294 if (\strlen($strValueNew) < 800) { 1295 $strValueNew .= $elem. ','; 1296 } else { 1297 if (substr($strValueNew, -1) == ',') { 1298 $strValueNew = substr($strValueNew, 0, -1); 1299 } 1300 if ($intCounter < $intArrCount) { 1301 $strValueNew .= ",\\"; 1302 $tplConf->setVariable('ITEM_VALUE', $strValueNew); 1303 $tplConf->parse('configline'); 1304 $tplConf->setVariable('ITEM_TITLE', $strSpace); 1305 } else { 1306 $tplConf->setVariable('ITEM_VALUE', $strValueNew); 1307 $tplConf->parse('configline'); 1308 $tplConf->setVariable('ITEM_TITLE', $strSpace); 1309 } 1310 $strValueNew = $elem. ','; 1311 } 1312 $intCounter++; 1313 } 1314 if ($strValueNew != '') { 1315 if (substr($strValueNew, -1) == ',') { 1316 $strValueNew = substr($strValueNew, 0, -1); 1317 } 1318 $tplConf->setVariable('ITEM_VALUE', $strValueNew); 1319 $tplConf->parse('configline'); 1320 } 1321 } 1322 } 1323 } 1324 // Special processing for time periods 1325 if ($strTableName == 'tbl_timeperiod') { 1326 $arrDataTime = array(); 1327 $strSQLTime = 'SELECT `definition`, `range` ' 1328 . 'FROM `tbl_timedefinition` WHERE `tipId` = ' .$arrData[$i]['id']; 1329 $booReturn = $this->myDBClass->hasDataArray($strSQLTime, $arrDataTime, $intDataCountTime); 1330 if ($booReturn && $intDataCountTime != 0) { 1331 foreach ($arrDataTime as $data) { 1332 // Skip other values than weekdays in nagios version below 3 1333 if ($intNagiosVersion < 3) { 1334 $arrWeekdays = array('monday','tuesday','wednesday','thursday','friday','saturday', 1335 'sunday'); 1336 if (!\in_array($data['definition'], $arrWeekdays, true)) { 1337 continue; 1338 } 1339 } 1340 // Insert fill spaces 1341 $strFillLen = (30- \strlen($data['definition'])); 1342 $strSpace = ' '; 1343 for ($f = 0; $f < $strFillLen; $f++) { 1344 $strSpace .= ' '; 1345 } 1346 // Write key and value 1347 $tplConf->setVariable('ITEM_TITLE', $data['definition'].$strSpace); 1348 $tplConf->setVariable('ITEM_VALUE', $data['range']); 1349 $tplConf->parse('configline'); 1350 } 1351 } 1352 } 1353 // Write configuration set 1354 $tplConf->parse('configset'); 1355 } 1356 } elseif ($booReturn && ($intDataCount == 0) && ($strFileString != '')) { 1357 $this->processClassMessage(translate('Error while selecting data from database:') 1358 . '::', $this->strErrorMessage); 1359 $this->processClassMessage($this->myDBClass->strErrorMessage, $this->strErrorMessage); 1360 $intReturn = 1; 1361 } else { 1362 $this->myDataClass->writeLog(translate('Writing of the configuration failed - no dataset ' 1363 . 'or not activated dataset found')); 1364 $this->processClassMessage(translate('Writing of the configuration failed - no dataset ' 1365 . 'or not activated dataset found'). '::', $this->strErrorMessage); 1366 $intReturn = 1; 1367 } 1368 if ($intMode == 0) { 1369 $intReturn = $this->getConfigFile($strFile, $intConfigID, $intType, $resCfgFile, $strCfgFile); 1370 if ($intReturn == 0) { 1371 $tplConf->parse(); 1372 $strContent = $tplConf->get(); 1373 $intReturn = $this->writeConfigFile( 1374 $strContent, 1375 $strFile, 1376 $intType, 1377 $intConfigID, 1378 $resCfgFile, 1379 $strCfgFile 1380 ); 1381 } 1382 } elseif ($intMode == 1) { 1383 $tplConf->show(); 1384 } 1385 return $intReturn; 1386 } 1387 1388 /** 1389 * Get Nagios version string 1390 * @param int $intConfigID Configuration target ID 1391 * @return string Version string 1392 */ 1393 private function getVersionString($intConfigID) 1394 { 1395 $arrVersion = array( 1396 'Nagios 2.x config file', 1397 'Nagios 2.9 config file', 1398 'Nagios 3.x config file', 1399 'Nagios 4.x config file' 1400 ); 1401 $this->getConfigData($intConfigID, 'version', $intVersion); 1402 if (($intVersion >= 1) && ($intVersion <= \count($arrVersion))) { 1403 $strVersion = $arrVersion[$intVersion - 1]; 1404 } else { 1405 $strVersion = ''; 1406 } 1407 return $strVersion; 1408 } 1409 1410 /** 1411 * Skip database values based on Nagios version 1412 * @param string $strTableName Table name 1413 * @param int $intVersionValue Nagios version value 1414 * @param string $key Data key 1415 * @param string $value Data value 1416 * @return int 1417 */ 1418 private function skipEntries($strTableName, $intVersionValue, $key, &$value) 1419 { 1420 // Define variables 1421 $arrOption = array(); 1422 $intReturn = 0; 1423 // Skip common fields 1424 $strSpecial = 'id,active,last_modified,access_rights,access_group,config_id,template,nodelete,command_type,'; 1425 $strSpecial .= 'import_hash'; 1426 1427 // Skip fields of special tables 1428 if ($strTableName == 'tbl_hosttemplate') { 1429 $strSpecial .= ',parents_tploptions,hostgroups_tploptions,contacts_tploptions'; 1430 $strSpecial .= ',contact_groups_tploptions,use_template_tploptions'; 1431 } 1432 if ($strTableName == 'tbl_servicetemplate') { 1433 $strSpecial .= ',host_name_tploptions,hostgroup_name_tploptions,parents_tploptions,contacts_tploptions'; 1434 $strSpecial .= ',servicegroups_tploptions,contact_groups_tploptions,use_template_tploptions'; 1435 } 1436 if ($strTableName == 'tbl_contact') { 1437 $strSpecial .= ',use_template_tploptions,contactgroups_tploptions'; 1438 $strSpecial .= ',host_notification_commands_tploptions,service_notification_commands_tploptions'; 1439 } 1440 if ($strTableName == 'tbl_contacttemplate') { 1441 $strSpecial .= ',use_template_tploptions,contactgroups_tploptions'; 1442 $strSpecial .= ',host_notification_commands_tploptions,service_notification_commands_tploptions'; 1443 } 1444 if ($strTableName == 'tbl_host') { 1445 $strSpecial .= ',parents_tploptions,hostgroups_tploptions,contacts_tploptions'; 1446 $strSpecial .= ',contact_groups_tploptions,use_template_tploptions'; 1447 } 1448 if ($strTableName == 'tbl_service') { 1449 $strSpecial .= ',host_name_tploptions,hostgroup_name_tploptions,parents_tploptions'; 1450 $strSpecial .= ',servicegroups_tploptions,contacts_tploptions,contact_groups_tploptions'; 1451 $strSpecial .= ',use_template_tploptions'; 1452 } 1453 if ($strTableName == 'tbl_command') { 1454 $strSpecial .= ',arg1_info,arg2_info,arg3_info,arg4_info,arg5_info,arg6_info,arg7_info,arg8_info'; 1455 } 1456 1457 // Pass fields based on nagios version lower than 3.x 1458 if ($intVersionValue < 3) { 1459 if ($strTableName == 'tbl_timeperiod') { 1460 $strSpecial .= ',use_template,exclude,name'; 1461 } 1462 if (($strTableName == 'tbl_contact') || ($strTableName == 'tbl_contacttemplate')) { 1463 $strSpecial .= ',host_notifications_enabled,service_notifications_enabled,can_submit_commands'; 1464 $strSpecial .= ',retain_status_information,retain_nonstatus_information'; 1465 $arrOption['host_notification_options'] = ',s'; 1466 $arrOption['service_notification_options'] = ',s'; 1467 } 1468 if ($strTableName == 'tbl_contactgroup') { 1469 $strSpecial .= ',contactgroup_members'; 1470 } 1471 if ($strTableName == 'tbl_hostgroup') { 1472 $strSpecial .= ',hostgroup_members,notes,notes_url,action_url'; 1473 } 1474 if ($strTableName == 'tbl_servicegroup') { 1475 $strSpecial .= ',servicegroup_members,notes,notes_url,action_url'; 1476 } 1477 if ($strTableName == 'tbl_hostdependency') { 1478 $strSpecial .= ',dependent_hostgroup_name,hostgroup_name,dependency_period'; 1479 } 1480 if ($strTableName == 'tbl_hostescalation') { 1481 $strSpecial .= ',contacts'; 1482 } 1483 if ($strTableName == 'tbl_servicedependency') { 1484 $strSpecial .= ',dependent_hostgroup_name,hostgroup_name,dependency_period,dependent_servicegroup_name'; 1485 $strSpecial .= ',servicegroup_name'; 1486 } 1487 if ($strTableName == 'tbl_serviceescalation') { 1488 $strSpecial .= ',hostgroup_name,contacts,servicegroup_name'; 1489 } 1490 if (($strTableName == 'tbl_host') || ($strTableName == 'tbl_hosttemplate')) { 1491 $strSpecial .= ',initial_state,flap_detection_options,contacts,notes,notes_url,action_url'; 1492 $strSpecial .= ',icon_image,icon_image_alt,vrml_image,statusmap_image,2d_coords,3d_coords'; 1493 $arrOption['notification_options'] = ',s'; 1494 } 1495 // Services 1496 if (($strTableName == 'tbl_service') || ($strTableName == 'tbl_servicetemplate')) { 1497 $strSpecial .= ',initial_state,flap_detection_options,contacts,notes,notes_url,action_url'; 1498 $strSpecial .= ',icon_image,icon_image_alt'; 1499 $arrOption['notification_options'] = ',s'; 1500 } 1501 } 1502 // Pass fields based on nagios version higher than 2.x 1503 if ($intVersionValue > 2) { 1504 if ($strTableName == 'tbl_servicetemplate') { 1505 $strSpecial .= ',parallelize_check '; 1506 } 1507 if ($strTableName == 'tbl_service') { 1508 $strSpecial .= ',parallelize_check'; 1509 } 1510 } 1511 // Pass fields based on nagios version lower than 4.x 1512 if ($intVersionValue < 4) { 1513 if (($strTableName == 'tbl_contact') || ($strTableName == 'tbl_contacttemplate')) { 1514 $strSpecial .= ',minimum_importance'; 1515 } 1516 if ($strTableName == 'tbl_host') { 1517 $strSpecial .= ',importance'; 1518 } 1519 if (($strTableName == 'tbl_service') || ($strTableName == 'tbl_servicetemplate')) { 1520 $strSpecial .= ',importance,parents'; 1521 } 1522 } 1523 if ($intVersionValue == 1) { 1524 $strSpecial .= ''; 1525 } 1526 // Reduce option values 1527 if (array_key_exists($key, $arrOption) && (\count($arrOption) != 0)) { 1528 $value = str_replace(array($arrOption[$key], str_replace(',', '', $arrOption[$key])), '', $value); 1529 if ($value == '') { 1530 $intReturn = 1; 1531 } 1532 } 1533 if ($intReturn == 0) { 1534 // Skip entries 1535 $arrSpecial = explode(',', $strSpecial); 1536 if (($value == '') || \in_array($key, $arrSpecial, true)) { 1537 $intReturn = 1; 1538 } 1539 } 1540 if ($intReturn == 0) { 1541 // Do not write config data (based on 'skip' option) 1542 $strNoTwo = 'active_checks_enabled,passive_checks_enabled,obsess_over_host,check_freshness,'; 1543 $strNoTwo .= 'event_handler_enabled,flap_detection_enabled,process_perf_data,retain_status_information,'; 1544 $strNoTwo .= 'retain_nonstatus_information,notifications_enabled,parallelize_check,is_volatile,'; 1545 $strNoTwo .= 'host_notifications_enabled,service_notifications_enabled,can_submit_commands,'; 1546 $strNoTwo .= 'obsess_over_service'; 1547 foreach (explode(',', $strNoTwo) as $elem) { 1548 if (($key == $elem) && ($value == '2')) { 1549 $intReturn = 1; 1550 } 1551 if (($intVersionValue < 3) && ($key == $elem) && ($value == '3')) { 1552 $intReturn = 1; 1553 } 1554 } 1555 } 1556 return $intReturn; 1557 } 1558 1559 /** 1560 * Get related data 1561 * @param string $strTableName Table name 1562 * @param \HTML_Template_IT $resTemplate Template ressource 1563 * @param array $arrData Dataset array 1564 * @param string $strDataKey Data key 1565 * @param string $strDataValue Data value 1566 * @return int 0 = use data / 1 = skip data 1567 * Status message is stored in message class variables 1568 */ 1569 private function getRelationData($strTableName, $resTemplate, $arrData, $strDataKey, &$strDataValue) 1570 { 1571 // Define Variables 1572 $intReturn = 0; 1573 $intSkipProc = 0; 1574 $arrRelations = array(); 1575 // Pass function for tbl_command 1576 if ($strTableName == 'tbl_command') { 1577 $intSkipProc = 1; 1578 } 1579 // Get relation info and store the value in a class variable (speedup export) 1580 if (($intSkipProc == 0) && ($this->strRelTable != $strTableName)) { 1581 $intReturn = $this->myDataClass->tableRelations($strTableName, $arrRelations); 1582 $this->strRelTable = $strTableName; 1583 $this->arrRelData = $arrRelations; 1584 } elseif ($intSkipProc == 0) { 1585 $arrRelations = $this->arrRelData; 1586 $intReturn = 0; 1587 } 1588 if (($intSkipProc == 0) && (!\is_array($arrRelations)) && (\count($arrRelations) == 0)) { 1589 $intSkipProc = 1; 1590 $intReturn = 1; 1591 } 1592 if ($intSkipProc == 0) { 1593 // Common domain is enabled? 1594 $this->getDomainData('enable_common', $intCommonEnable); 1595 if ($intCommonEnable == 1) { 1596 $strDomainWhere1 = ' (`config_id`=' . $this->intDomainId . ' OR `config_id`=0) '; 1597 } else { 1598 $strDomainWhere1 = ' `config_id`=' . $this->intDomainId . ' '; 1599 } 1600 // Process relations 1601 foreach ($arrRelations as $elem) { 1602 if ($elem['fieldName'] == $strDataKey) { 1603 // Process normal 1:n relations (1 = only data / 2 = including a * value) 1604 if (($elem['type'] == 2) && (($strDataValue == 1) || ($strDataValue == 2))) { 1605 $intReturn = $this->processRelation1($arrData, $strDataValue, $elem, $strDomainWhere1); 1606 // Process normal 1:1 relations 1607 } elseif ($elem['type'] == 1) { 1608 $intReturn = $this->processRelation2($arrData, $strDataValue, $elem, $strDomainWhere1); 1609 // Process normal 1:n relations with special table and idSort (template tables) 1610 } elseif (($elem['type'] == 3) && ($strDataValue == 1)) { 1611 $intReturn = $this->processRelation3($arrData, $strDataValue, $elem, $strDomainWhere1); 1612 // Process special 1:n:str relations with string values (servicedependencies) 1613 } elseif (($elem['type'] == 6) && (($strDataValue == 1) || ($strDataValue == 2))) { 1614 $intReturn = $this->processRelation4($arrData, $strDataValue, $elem, $strDomainWhere1); 1615 // Process special relations for free variables 1616 } elseif (($elem['type'] == 4) && ($strDataValue == 1) && ($this->intNagVersion >= 3)) { 1617 $intReturn = $this->processRelation5($resTemplate, $arrData, $elem); 1618 // Process special relations for service groups 1619 } elseif (($elem['type'] == 5) && ($strDataValue == 1)) { 1620 $intReturn = $this->processRelation6($arrData, $strDataValue, $elem, $strDomainWhere1); 1621 // Process special relations for service parents 1622 } elseif (($elem['type'] == 7) && ($strDataValue == 1)) { 1623 $intReturn = $this->processRelation7($arrData, $strDataValue, $elem); 1624 // Process "*" 1625 } elseif ($strDataValue == 2) { 1626 $strDataValue = '*'; 1627 } else { 1628 $intReturn = 1; 1629 } 1630 } 1631 } 1632 } 1633 return $intReturn; 1634 } 1635 1636 /** 1637 * Rename field names 1638 * @param string $strTableName Table name 1639 * @param int $intConfigID Configuration target ID 1640 * @param int $intDataId Data ID 1641 * @param string $key Data key (by reference) 1642 * @param string $value Data value (by reference) 1643 * @param int $intSkip Skip value (by reference) 1 = skip / 0 = pass 1644 */ 1645 private function renameFields($strTableName, $intConfigID, $intDataId, &$key, &$value, &$intSkip) 1646 { 1647 if ($this->intNagVersion == 0) { 1648 $this->getConfigData($intConfigID, 'version', $this->intNagVersion); 1649 } 1650 // Picture path 1651 if ($this->strPicPath == 'none') { 1652 $this->getConfigData($intConfigID, 'picturedir', $this->strPicPath); 1653 } 1654 if ($key == 'icon_image') { 1655 $value = $this->strPicPath.$value; 1656 } 1657 if ($key == 'vrml_image') { 1658 $value = $this->strPicPath.$value; 1659 } 1660 if ($key == 'statusmap_image') { 1661 $value = $this->strPicPath.$value; 1662 } 1663 // Tables 1664 if ($strTableName == 'tbl_host') { 1665 if ($key == 'use_template') { 1666 $key = 'use'; 1667 } 1668 $strVIValues = 'active_checks_enabled,passive_checks_enabled,check_freshness,obsess_over_host,'; 1669 $strVIValues .= 'event_handler_enabled,flap_detection_enabled,process_perf_data,retain_status_information,'; 1670 $strVIValues .= 'retain_nonstatus_information,notifications_enabled'; 1671 if (\in_array($key, explode(',', $strVIValues), true)) { 1672 if ($value == -1) { 1673 $value = 'null'; 1674 } 1675 if ($value == 3) { 1676 $value = 'null'; 1677 } 1678 } 1679 if ($key == 'parents') { 1680 $value = $this->checkTpl($value, 'parents_tploptions', 'tbl_host', $intDataId, $intSkip); 1681 } 1682 if ($key == 'hostgroups') { 1683 $value = $this->checkTpl($value, 'hostgroups_tploptions', 'tbl_host', $intDataId, $intSkip); 1684 } 1685 if ($key == 'contacts') { 1686 $value = $this->checkTpl($value, 'contacts_tploptions', 'tbl_host', $intDataId, $intSkip); 1687 } 1688 if ($key == 'contact_groups') { 1689 $value = $this->checkTpl($value, 'contact_groups_tploptions', 'tbl_host', $intDataId, $intSkip); 1690 } 1691 if ($key == 'use') { 1692 $value = $this->checkTpl($value, 'use_template_tploptions', 'tbl_host', $intDataId, $intSkip); 1693 } 1694 if ($key == 'check_command') { 1695 $value = str_replace("\::bang::", "\!", $value); 1696 } 1697 if ($key == 'check_command') { 1698 $value = str_replace('::bang::', "\!", $value); 1699 } 1700 } 1701 if ($strTableName == 'tbl_service') { 1702 if ($key == 'use_template') { 1703 $key = 'use'; 1704 } 1705 if ($this->intNagVersion < 2) { 1706 if ($key == 'check_interval') { 1707 $key = 'normal_check_interval'; 1708 } 1709 if ($key == 'retry_interval') { 1710 $key = 'retry_check_interval'; 1711 } 1712 } 1713 $strVIValues = 'is_volatile,active_checks_enabled,passive_checks_enabled,parallelize_check,'; 1714 $strVIValues .= 'obsess_over_service,check_freshness,event_handler_enabled,flap_detection_enabled,'; 1715 $strVIValues .= 'process_perf_data,retain_status_information,retain_nonstatus_information,'; 1716 $strVIValues .= 'notifications_enabled'; 1717 if (\in_array($key, explode(',', $strVIValues), true)) { 1718 if ($value == -1) { 1719 $value = 'null'; 1720 } 1721 if ($value == 3) { 1722 $value = 'null'; 1723 } 1724 } 1725 if ($key == 'host_name') { 1726 $value = $this->checkTpl($value, 'host_name_tploptions', 'tbl_service', $intDataId, $intSkip); 1727 } 1728 if ($key == 'hostgroup_name') { 1729 $value = $this->checkTpl($value, 'hostgroup_name_tploptions', 'tbl_service', $intDataId, $intSkip); 1730 } 1731 if ($key == 'parents') { 1732 $value = $this->checkTpl($value, 'parents_tploptions', 'tbl_service', $intDataId, $intSkip); 1733 } 1734 if ($key == 'servicegroups') { 1735 $value = $this->checkTpl($value, 'servicegroups_tploptions', 'tbl_service', $intDataId, $intSkip); 1736 } 1737 if ($key == 'contacts') { 1738 $value = $this->checkTpl($value, 'contacts_tploptions', 'tbl_service', $intDataId, $intSkip); 1739 } 1740 if ($key == 'contact_groups') { 1741 $value = $this->checkTpl($value, 'contact_groups_tploptions', 'tbl_service', $intDataId, $intSkip); 1742 } 1743 if ($key == 'use') { 1744 $value = $this->checkTpl($value, 'use_template_tploptions', 'tbl_service', $intDataId, $intSkip); 1745 } 1746 if ($key == 'check_command') { 1747 $value = str_replace("\::bang::", "\!", $value); 1748 } 1749 if ($key == 'check_command') { 1750 $value = str_replace('::bang::', "\!", $value); 1751 } 1752 } 1753 if ($strTableName == 'tbl_hosttemplate') { 1754 if ($key == 'template_name') { 1755 $key = 'name'; 1756 } 1757 if ($key == 'use_template') { 1758 $key = 'use'; 1759 } 1760 $strVIValues = 'active_checks_enabled,passive_checks_enabled,check_freshness,obsess_over_host,'; 1761 $strVIValues .= 'event_handler_enabled,flap_detection_enabled,process_perf_data,retain_status_information,'; 1762 $strVIValues .= 'retain_nonstatus_information,notifications_enabled'; 1763 if (\in_array($key, explode(',', $strVIValues), true)) { 1764 if ($value == -1) { 1765 $value = 'null'; 1766 } 1767 if ($value == 3) { 1768 $value = 'null'; 1769 } 1770 } 1771 if ($key == 'parents') { 1772 $value = $this->checkTpl($value, 'parents_tploptions', 'tbl_hosttemplate', $intDataId, $intSkip); 1773 } 1774 if ($key == 'hostgroups') { 1775 $value = $this->checkTpl($value, 'hostgroups_tploptions', 'tbl_hosttemplate', $intDataId, $intSkip); 1776 } 1777 if ($key == 'contacts') { 1778 $value = $this->checkTpl($value, 'contacts_tploptions', 'tbl_hosttemplate', $intDataId, $intSkip); 1779 } 1780 if ($key == 'contact_groups') { 1781 $value = $this->checkTpl($value, 'contact_groups_tploptions', 'tbl_hosttemplate', $intDataId, $intSkip); 1782 } 1783 if ($key == 'use') { 1784 $value = $this->checkTpl($value, 'use_template_tploptions', 'tbl_hosttemplate', $intDataId, $intSkip); 1785 } 1786 } 1787 if ($strTableName == 'tbl_servicetemplate') { 1788 if ($key == 'template_name') { 1789 $key = 'name'; 1790 } 1791 if ($key == 'use_template') { 1792 $key = 'use'; 1793 } 1794 if ($this->intNagVersion < 2) { 1795 if ($key == 'check_interval') { 1796 $key = 'normal_check_interval'; 1797 } 1798 if ($key == 'retry_interval') { 1799 $key = 'retry_check_interval'; 1800 } 1801 } 1802 $strVIValues = 'is_volatile,active_checks_enabled,passive_checks_enabled,parallelize_check,'; 1803 $strVIValues .= 'obsess_over_service,check_freshness,event_handler_enabled,flap_detection_enabled,'; 1804 $strVIValues .= 'process_perf_data,retain_status_information,retain_nonstatus_information,'; 1805 $strVIValues .= 'notifications_enabled'; 1806 if (\in_array($key, explode(',', $strVIValues), true)) { 1807 if ($value == -1) { 1808 $value = 'null'; 1809 } 1810 if ($value == 3) { 1811 $value = 'null'; 1812 } 1813 } 1814 if ($key == 'host_name') { 1815 $value = $this->checkTpl($value, 'host_name_tploptions', 'tbl_servicetemplate', $intDataId, $intSkip); 1816 } 1817 if ($key == 'hostgroup_name') { 1818 $value = $this->checkTpl( 1819 $value, 1820 'hostgroup_name_tploptions', 1821 'tbl_servicetemplate', 1822 $intDataId, 1823 $intSkip 1824 ); 1825 } 1826 if ($key == 'parents') { 1827 $value = $this->checkTpl($value, 'parents_tploptions', 'tbl_servicetemplate', $intDataId, $intSkip); 1828 } 1829 if ($key == 'servicegroups') { 1830 $value = $this->checkTpl( 1831 $value, 1832 'servicegroups_tploptions', 1833 'tbl_servicetemplate', 1834 $intDataId, 1835 $intSkip 1836 ); 1837 } 1838 if ($key == 'contacts') { 1839 $value = $this->checkTpl($value, 'contacts_tploptions', 'tbl_servicetemplate', $intDataId, $intSkip); 1840 } 1841 if ($key == 'contact_groups') { 1842 $value = $this->checkTpl( 1843 $value, 1844 'contact_groups_tploptions', 1845 'tbl_servicetemplate', 1846 $intDataId, 1847 $intSkip 1848 ); 1849 } 1850 if ($key == 'use') { 1851 $value = $this->checkTpl( 1852 $value, 1853 'use_template_tploptions', 1854 'tbl_servicetemplate', 1855 $intDataId, 1856 $intSkip 1857 ); 1858 } 1859 } 1860 if ($strTableName == 'tbl_contact') { 1861 if ($key == 'use_template') { 1862 $key = 'use'; 1863 } 1864 $strVIValues = 'host_notifications_enabled,service_notifications_enabled,can_submit_commands,'; 1865 $strVIValues .= 'retain_status_information,retain_nonstatus_information'; 1866 if (\in_array($key, explode(',', $strVIValues), true)) { 1867 if ($value == -1) { 1868 $value = 'null'; 1869 } 1870 if ($value == 3) { 1871 $value = 'null'; 1872 } 1873 } 1874 if ($key == 'contactgroups') { 1875 $value = $this->checkTpl($value, 'contactgroups_tploptions', 'tbl_contact', $intDataId, $intSkip); 1876 } 1877 if ($key == 'host_notification_commands') { 1878 $value = $this->checkTpl( 1879 $value, 1880 'host_notification_commands_tploptions', 1881 'tbl_contact', 1882 $intDataId, 1883 $intSkip 1884 ); 1885 } 1886 if ($key == 'service_notification_commands') { 1887 $value = $this->checkTpl( 1888 $value, 1889 'service_notification_commands_tploptions', 1890 'tbl_contact', 1891 $intDataId, 1892 $intSkip 1893 ); 1894 } 1895 if ($key == 'use') { 1896 $value = $this->checkTpl($value, 'use_template_tploptions', 'tbl_contact', $intDataId, $intSkip); 1897 } 1898 } 1899 if ($strTableName == 'tbl_contacttemplate') { 1900 if ($key == 'template_name') { 1901 $key = 'name'; 1902 } 1903 if ($key == 'use_template') { 1904 $key = 'use'; 1905 } 1906 $strVIValues = 'host_notifications_enabled,service_notifications_enabled,can_submit_commands,'; 1907 $strVIValues .= 'retain_status_information,retain_nonstatus_information'; 1908 if (in_array($key, explode(',', $strVIValues), true)) { 1909 if ($value == -1) { 1910 $value = 'null'; 1911 } 1912 if ($value == 3) { 1913 $value = 'null'; 1914 } 1915 } 1916 if ($key == 'contactgroups') { 1917 $value = $this->checkTpl( 1918 $value, 1919 'contactgroups_tploptions', 1920 'tbl_contacttemplate', 1921 $intDataId, 1922 $intSkip 1923 ); 1924 } 1925 if ($key == 'host_notification_commands') { 1926 $value = $this->checkTpl( 1927 $value, 1928 'host_notification_commands_tploptions', 1929 'tbl_contacttemplate', 1930 $intDataId, 1931 $intSkip 1932 ); 1933 } 1934 if ($key == 'service_notification_commands') { 1935 $value = $this->checkTpl( 1936 $value, 1937 'service_notification_commands_tploptions', 1938 'tbl_contacttemplate', 1939 $intDataId, 1940 $intSkip 1941 ); 1942 } 1943 if ($key == 'use') { 1944 $value = $this->checkTpl( 1945 $value, 1946 'use_template_tploptions', 1947 'tbl_contacttemplate', 1948 $intDataId, 1949 $intSkip 1950 ); 1951 } 1952 } 1953 if ((($strTableName == 'tbl_hosttemplate') || ($strTableName == 'tbl_servicetemplate') || 1954 ($strTableName == 'tbl_contacttemplate')) && $key == 'register') { 1955 $value = '0'; 1956 } 1957 if ($strTableName == 'tbl_timeperiod' && $key == 'use_template') { 1958 $key = 'use'; 1959 } 1960 } 1961 1962 /** 1963 * Open configuration file 1964 * @param string $strFile File name 1965 * @param int $intConfigID Configuration ID 1966 * @param int $intType Type ID 1967 * @param resource|bool $resConfigFile Temporary or configuration file ressource (by reference) 1968 * @param string $strConfigFile Configuration file name (by reference) 1969 * @return int 0 = successful / 1 = error 1970 */ 1971 private function getConfigFile($strFile, $intConfigID, $intType, &$resConfigFile, &$strConfigFile) 1972 { 1973 // Variable definitions 1974 $strBaseDir = ''; 1975 $intMethod = 1; 1976 $intReturn = 0; 1977 // Get config data 1978 if ($intType == 1) { 1979 $this->getConfigData($intConfigID, 'hostconfig', $strBaseDir); 1980 $strType = 'host'; 1981 } elseif ($intType == 2) { 1982 $this->getConfigData($intConfigID, 'serviceconfig', $strBaseDir); 1983 $strType = 'service'; 1984 } else { 1985 $this->getConfigData($intConfigID, 'basedir', $strBaseDir); 1986 $strType = 'basic'; 1987 } 1988 $this->getConfigData($intConfigID, 'method', $intMethod); 1989 // Backup config file 1990 $this->moveFile($strType, $strFile, $intConfigID); 1991 // Variable definition 1992 $strConfigFile = $strBaseDir. '/' .$strFile; 1993 // Local file system 1994 if ($intMethod == 1) { 1995 // Save configuration file 1996 if (is_writable($strConfigFile) || (!file_exists($strConfigFile) && is_writable($strBaseDir))) { 1997 $resConfigFile = fopen($strConfigFile, 'wb'); 1998 chmod($strConfigFile, 0644); 1999 } else { 2000 $this->myDataClass->writeLog(translate('Configuration write failed:'). ' ' .$strFile); 2001 $this->processClassMessage(translate('Cannot open/overwrite the configuration file (check the ' 2002 .'permissions)!'). '::', $this->strErrorMessage); 2003 $intReturn = 1; 2004 } 2005 } elseif ($intMethod == 2) { // Remote file (FTP) 2006 // Check connection 2007 if (empty($this->resConnectId) || !\is_resource($this->resConnectId) || 2008 ($this->resConnectType != 'FTP')) { 2009 $intReturn = $this->getFTPConnection($intConfigID); 2010 } 2011 if ($intReturn == 0) { 2012 // Open the config file 2013 if (isset($this->arrSettings['path']) && isset($this->arrSettings['path']['tempdir'])) { 2014 $strConfigFile = tempnam($this->arrSettings['path']['tempdir'], 'nagiosql'); 2015 } else { 2016 $strConfigFile = tempnam(sys_get_temp_dir(), 'nagiosql'); 2017 } 2018 $resConfigFile = fopen($strConfigFile, 'wb'); 2019 } 2020 } elseif ($intMethod == 3) { // Remote file (SFTP) 2021 // Check connection 2022 if (empty($this->resConnectId) || !\is_resource($this->resConnectId) || 2023 ($this->resConnectType != 'SSH')) { 2024 $intReturn = $this->getSSHConnection($intConfigID); 2025 } 2026 if ($intReturn == 0) { 2027 if (isset($this->arrSettings['path']) && isset($this->arrSettings['path']['tempdir'])) { 2028 $strConfigFile = tempnam($this->arrSettings['path']['tempdir'], 'nagiosql'); 2029 } else { 2030 $strConfigFile = tempnam(sys_get_temp_dir(), 'nagiosql'); 2031 } 2032 $resConfigFile = fopen($strConfigFile, 'wb'); 2033 } 2034 } 2035 return $intReturn; 2036 } 2037 2038 /** 2039 * Write configuration file 2040 * @param string $strData Data string 2041 * @param string $strFile File name 2042 * @param int $intType Type ID 2043 * @param int $intConfigID Configuration target ID 2044 * @param resource $resConfigFile Temporary or configuration file ressource 2045 * @param string $strConfigFile Configuration file name 2046 * @return int 0 = successful / 1 = error 2047 */ 2048 private function writeConfigFile($strData, $strFile, $intType, $intConfigID, $resConfigFile, $strConfigFile) 2049 { 2050 // Variable definitions 2051 $intReturn = 0; 2052 // Get config data 2053 if ($intType == 1) { 2054 $this->getConfigData($intConfigID, 'hostconfig', $strBaseDir); 2055 } elseif ($intType == 2) { 2056 $this->getConfigData($intConfigID, 'serviceconfig', $strBaseDir); 2057 } else { 2058 $this->getConfigData($intConfigID, 'basedir', $strBaseDir); 2059 } 2060 $this->getConfigData($intConfigID, 'method', $intMethod); 2061 $strData = str_replace("\r\n", "\n", $strData); 2062 fwrite($resConfigFile, $strData); 2063 // Local filesystem 2064 if ($intMethod == 1) { 2065 fclose($resConfigFile); 2066 } elseif ($intMethod == 2) { // FTP access 2067 // SSH Possible 2068 if (!\function_exists('ftp_put')) { 2069 $this->processClassMessage(translate('FTP module not loaded!'). '::', $this->strErrorMessage); 2070 $intReturn = 1; 2071 } else { 2072 $intErrorReporting = error_reporting(); 2073 error_reporting(0); 2074 if (!ftp_put($this->resConnectId, $strBaseDir . '/' . $strFile, $strConfigFile, FTP_ASCII)) { 2075 $arrError = error_get_last(); 2076 error_reporting($intErrorReporting); 2077 $this->processClassMessage(translate('Cannot open/overwrite the configuration file (FTP connection ' 2078 .'failed)!') . '::', $this->strErrorMessage); 2079 if ($arrError['message'] != '') { 2080 $this->processClassMessage($arrError['message'] . '::', $this->strErrorMessage); 2081 } 2082 $intReturn = 1; 2083 } 2084 error_reporting($intErrorReporting); 2085 ftp_close($this->resConnectId); 2086 fclose($resConfigFile); 2087 } 2088 } elseif ($intMethod == 3) { // SSH access 2089 // SSH Possible 2090 if (!\function_exists('ssh2_scp_send')) { 2091 $this->processClassMessage(translate('SSH module not loaded!'). '::', $this->strErrorMessage); 2092 $intReturn = 1; 2093 } else { 2094 $intErrorReporting = error_reporting(); 2095 error_reporting(0); 2096 if (!ssh2_scp_send($this->resConnectId, $strConfigFile, $strBaseDir . '/' . $strFile, 0644)) { 2097 $arrError = error_get_last(); 2098 error_reporting($intErrorReporting); 2099 $this->processClassMessage(translate('Cannot open/overwrite the configuration file (remote SFTP)!'). 2100 '::', $this->strErrorMessage); 2101 if ($arrError['message'] != '') { 2102 $this->processClassMessage($arrError['message'] . '::', $this->strErrorMessage); 2103 } 2104 $this->resConnectId = null; 2105 $intReturn = 1; 2106 } 2107 error_reporting($intErrorReporting); 2108 fclose($resConfigFile); 2109 unlink($strConfigFile); 2110 $this->resConnectId = null; 2111 } 2112 } 2113 if ($intReturn == 0) { 2114 $this->myDataClass->writeLog(translate('Configuration successfully written:') . ' ' . $strFile); 2115 $this->processClassMessage(translate('Configuration file successfully written!'). 2116 '::', $this->strInfoMessage); 2117 } 2118 return $intReturn; 2119 } 2120 2121 /** 2122 * Process special settings based on template option 2123 * @param string $strValue Original data value 2124 * @param string $strKeyField Template option field name 2125 * @param string $strTable Table name 2126 * @param int $intId Dataset ID 2127 * @param int $intSkip Skip value (by reference) 2128 * @return string Manipulated data value 2129 */ 2130 public function checkTpl($strValue, $strKeyField, $strTable, $intId, &$intSkip) 2131 { 2132 if ($this->intNagVersion < 3) { 2133 return $strValue; 2134 } 2135 $strSQL = 'SELECT `' .$strKeyField. '` FROM `' .$strTable."` WHERE `id` = $intId"; 2136 $intValue = $this->myDBClass->getFieldData($strSQL); 2137 if ($intValue == 0) { 2138 return('+' .$strValue); 2139 } 2140 if ($intValue == 1) { 2141 $intSkip = 0; 2142 return 'null'; 2143 } 2144 return $strValue; 2145 } 2146 2147 /** 2148 * @param array $arrData Dataset array 2149 * @param string $strDataValue Data value 2150 * @param array $elem Relation data array 2151 * @param string $strDomainWhere1 SQL WHERE add-in 2152 * @return int 0 = use data / 1 = skip data 2153 */ 2154 private function processRelation1($arrData, &$strDataValue, $elem, $strDomainWhere1) 2155 { 2156 // Define variables 2157 $arrDataRel = array(); 2158 $intDataCountRel = 0; 2159 $intReturn = 0; 2160 // Get relation data 2161 $strSQLRel = 'SELECT `' . $elem['tableName1'] . '`.`' . $elem['target1'] . '`, `' . $elem['linkTable'] . 2162 '`.`exclude` FROM `' . $elem['linkTable'] . '` LEFT JOIN `' . $elem['tableName1'] . 2163 '` ON `' . $elem['linkTable'] . '`.`idSlave` = `' . $elem['tableName1'] . '`.`id`' . 2164 'WHERE `idMaster`=' . $arrData['id'] . " AND `active`='1' AND $strDomainWhere1" . 2165 'ORDER BY `' . $elem['tableName1'] . '`.`' . $elem['target1'] . '`'; 2166 $booReturn = $this->myDBClass->hasDataArray($strSQLRel, $arrDataRel, $intDataCountRel); 2167 if ($booReturn && ($intDataCountRel != 0)) { 2168 // Rewrite $strDataValue with returned relation data 2169 if ($strDataValue == 2) { 2170 $strDataValue = '*,'; 2171 } else { 2172 $strDataValue = ''; 2173 } 2174 foreach ($arrDataRel as $data) { 2175 if ($data['exclude'] == 0) { 2176 $strDataValue .= $data[$elem['target1']] . ','; 2177 } elseif ($this->intNagVersion >= 3) { 2178 $strDataValue .= '!' . $data[$elem['target1']] . ','; 2179 } 2180 } 2181 $strDataValue = substr($strDataValue, 0, -1); 2182 if ($strDataValue == '') { 2183 $intReturn = 1; 2184 } 2185 } else { 2186 if ($strDataValue == 2) { 2187 $strDataValue = '*'; 2188 } else { 2189 $intReturn = 1; 2190 } 2191 } 2192 return $intReturn; 2193 } 2194 2195 /** 2196 * @param array $arrData Dataset array 2197 * @param string $strDataValue Data value 2198 * @param array $elem Relation data array 2199 * @param string $strDomainWhere1 SQL WHERE add-in 2200 * @return int 0 = use data / 1 = skip data 2201 */ 2202 private function processRelation2($arrData, &$strDataValue, $elem, $strDomainWhere1) 2203 { 2204 // Define variables 2205 $arrDataRel = array(); 2206 $arrField = array(); 2207 $intDataCountRel = 0; 2208 $intReturn = 0; 2209 $strCommand = ''; 2210 // Get relation data 2211 if (($elem['tableName1'] == 'tbl_command') && 2212 (substr_count($arrData[$elem['fieldName']], '!') != 0)) { 2213 $arrField = explode('!', $arrData[$elem['fieldName']]); 2214 $strCommand = strstr($arrData[$elem['fieldName']], '!'); 2215 $strSQLRel = 'SELECT `' . $elem['target1'] . '` FROM `' . $elem['tableName1'] . '`' . 2216 'WHERE `id`=' . $arrField[0] . " AND `active`='1' AND $strDomainWhere1"; 2217 } else { 2218 $strSQLRel = 'SELECT `' . $elem['target1'] . '` FROM `' . $elem['tableName1'] . '`' . 2219 'WHERE `id`=' . $arrData[$elem['fieldName']] . " AND `active`='1' AND $strDomainWhere1"; 2220 } 2221 $booReturn = $this->myDBClass->hasDataArray($strSQLRel, $arrDataRel, $intDataCountRel); 2222 if ($booReturn && ($intDataCountRel != 0)) { 2223 // Rewrite $strDataValue with returned relation data 2224 if (($elem['tableName1'] == 'tbl_command') && (substr_count($strDataValue, '!') != 0)) { 2225 $strDataValue = $arrDataRel[0][$elem['target1']] . $strCommand; 2226 } else { 2227 $strDataValue = $arrDataRel[0][$elem['target1']]; 2228 } 2229 } else { 2230 if (($elem['tableName1'] == 'tbl_command') && (substr_count($strDataValue, '!') != 0) && 2231 ($arrField[0] == -1)) { 2232 $strDataValue = 'null'; 2233 } else { 2234 $intReturn = 1; 2235 } 2236 } 2237 return $intReturn; 2238 } 2239 2240 /** 2241 * @param array $arrData Dataset array 2242 * @param string $strDataValue Data value 2243 * @param array $elem Relation data array 2244 * @param string $strDomainWhere1 SQL WHERE add-in 2245 * @return int 0 = use data / 1 = skip data 2246 */ 2247 private function processRelation3($arrData, &$strDataValue, $elem, $strDomainWhere1) 2248 { 2249 // Define variables 2250 $arrDataRel = array(); 2251 $intDataCountRel = 0; 2252 $intReturn = 0; 2253 // Get relation data 2254 $strSQLRel = 'SELECT * FROM `' .$elem['linkTable']. '` WHERE `idMaster`=' .$arrData['id']. ' ORDER BY idSort'; 2255 $booReturn = $this->myDBClass->hasDataArray($strSQLRel, $arrDataRel, $intDataCountRel); 2256 if ($booReturn && ($intDataCountRel != 0)) { 2257 // Rewrite $strDataValue with returned relation data 2258 $strDataValue = ''; 2259 foreach ($arrDataRel as $data) { 2260 if ($data['idTable'] == 1) { 2261 $strSQLName = 'SELECT `' .$elem['target1']. '` FROM `' .$elem['tableName1']. '`' . 2262 "WHERE `active`='1' AND $strDomainWhere1 AND `id`=".$data['idSlave']; 2263 } else { 2264 $strSQLName = 'SELECT `' .$elem['target2']. '` FROM `' .$elem['tableName2']. '`' . 2265 "WHERE `active`='1' AND $strDomainWhere1 AND `id`=".$data['idSlave']; 2266 } 2267 $strDataValue .= $this->myDBClass->getFieldData($strSQLName) . ','; 2268 } 2269 $strDataValue = substr($strDataValue, 0, -1); 2270 } else { 2271 $intReturn = 1; 2272 } 2273 return $intReturn; 2274 } 2275 2276 /** 2277 * @param array $arrData Dataset array 2278 * @param string $strDataValue Data value 2279 * @param array $elem Relation data array 2280 * @param string $strDomainWhere1 SQL WHERE add-in 2281 * @return int 0 = use data / 1 = skip data 2282 */ 2283 private function processRelation4($arrData, &$strDataValue, $elem, $strDomainWhere1) 2284 { 2285 // Define variables 2286 $arrDataRel = array(); 2287 $intDataCountRel = 0; 2288 $intReturn = 0; 2289 // Get relation data 2290 $strSQLRel = 'SELECT `' .$elem['linkTable']. '`.`strSlave`, `' .$elem['linkTable']. '`.`exclude` ' . 2291 'FROM `' .$elem['linkTable']. '` ' . 2292 'LEFT JOIN `tbl_service` ON `' .$elem['linkTable']. '`.`idSlave`=`tbl_service`.`id` ' . 2293 'WHERE `' .$elem['linkTable']. '`.`idMaster`=' .$arrData['id']." AND `active`='1' AND ". 2294 $strDomainWhere1. ' ' . 2295 'ORDER BY `' .$elem['linkTable']. '`.`strSlave`'; 2296 $booReturn = $this->myDBClass->hasDataArray($strSQLRel, $arrDataRel, $intDataCountRel); 2297 if ($booReturn && ($intDataCountRel != 0)) { 2298 // Rewrite $strDataValue with returned relation data 2299 if ($strDataValue == 2) { 2300 $strDataValue = '*,'; 2301 } else { 2302 $strDataValue = ''; 2303 } 2304 foreach ($arrDataRel as $data) { 2305 if ($data['exclude'] == 0) { 2306 $strDataValue .= $data['strSlave'] . ','; 2307 } elseif ($this->intNagVersion >= 3) { 2308 $strDataValue .= '!' . $data['strSlave'] . ','; 2309 } 2310 } 2311 $strDataValue = substr($strDataValue, 0, -1); 2312 if ($strDataValue == '') { 2313 $intReturn = 1; 2314 } 2315 } else { 2316 if ($strDataValue == 2) { 2317 $strDataValue = '*'; 2318 } else { 2319 $intReturn = 1; 2320 } 2321 } 2322 return $intReturn; 2323 } 2324 2325 /** 2326 * @param \HTML_Template_IT $resTemplate Template object 2327 * @param array $arrData Dataset array 2328 * @param array $elem Relation data array 2329 * @return int 0 = use data / 1 = skip data 2330 */ 2331 private function processRelation5($resTemplate, $arrData, $elem) 2332 { 2333 // Define variables 2334 $arrDataRel = array(); 2335 $intDataCountRel = 0; 2336 $strSQLRel = 'SELECT * FROM `tbl_variabledefinition` LEFT JOIN `' .$elem['linkTable']. '` ' . 2337 'ON `id`=`idSlave` WHERE `idMaster`=' .$arrData['id']. ' ORDER BY `name`'; 2338 $booReturn = $this->myDBClass->hasDataArray($strSQLRel, $arrDataRel, $intDataCountRel); 2339 if ($booReturn && ($intDataCountRel != 0)) { 2340 foreach ($arrDataRel as $vardata) { 2341 // Insert fill spaces 2342 $strFillLen = (30 - \strlen($vardata['name'])); 2343 $strSpace = ' '; 2344 for ($f = 0; $f < $strFillLen; $f++) { 2345 $strSpace .= ' '; 2346 } 2347 $resTemplate->setVariable('ITEM_TITLE', $vardata['name'] . $strSpace); 2348 $resTemplate->setVariable('ITEM_VALUE', html_entity_decode($vardata['value'], ENT_QUOTES | ENT_XML1, 'UTF-8')); 2349 $resTemplate->parse('configline'); 2350 } 2351 } 2352 return 1; 2353 } 2354 2355 /** 2356 * @param array $arrData Dataset array 2357 * @param string $strDataValue Data value 2358 * @param array $elem Relation data array 2359 * @param string $strDomainWhere1 SQL WHERE add-in 2360 * @return int 0 = use data / 1 = skip data 2361 */ 2362 private function processRelation6($arrData, &$strDataValue, $elem, $strDomainWhere1) 2363 { 2364 // Define variables 2365 $arrDataRel = array(); 2366 $arrHG1 = array(); 2367 $arrHG2 = array(); 2368 $intDataCountRel = 0; 2369 $intHG1 = 0; 2370 $intHG2 = 0; 2371 $intReturn = 0; 2372 // Get relation data 2373 $strSQLMaster = 'SELECT * FROM `' . $elem['linkTable'] . '` WHERE `idMaster`=' . $arrData['id']; 2374 $booReturn = $this->myDBClass->hasDataArray($strSQLMaster, $arrDataRel, $intDataCountRel); 2375 if ($booReturn && ($intDataCountRel != 0)) { 2376 // Rewrite $strDataValue with returned relation data 2377 $strDataValue = ''; 2378 foreach ($arrDataRel as $data) { 2379 // Get excluded hosts 2380 $arrExclude = array(); 2381 $strSQLEx = 'SELECT `idSlave` FROM `tbl_lnkServiceToHost` WHERE `exclude`=1 AND `idMaster`=' . 2382 $data['idSlaveS']; 2383 $booReturn = $this->myDBClass->hasDataArray($strSQLEx, $arrEx, $intEx); 2384 if ($booReturn && ($intEx != 0)) { 2385 foreach ($arrEx as $elemEx) { 2386 $arrExclude[] = $elemEx['idSlave']; 2387 } 2388 } 2389 if ($data['idSlaveHG'] != 0) { 2390 // Get Sevices 2391 $strSQLSrv = 'SELECT `' . $elem['target2'] . '` FROM `' . $elem['tableName2'] . 2392 '` WHERE `id`=' . $data['idSlaveS']; 2393 $strService = $this->myDBClass->getFieldData($strSQLSrv); 2394 $strSQLHG1 = 'SELECT `host_name`, `idSlave` FROM `tbl_host` ' . 2395 'LEFT JOIN `tbl_lnkHostgroupToHost` ON `id`=`idSlave` ' . 2396 'WHERE `idMaster`=' . $data['idSlaveHG'] . " AND `active`='1' AND `exclude`=0 " . 2397 "AND $strDomainWhere1"; 2398 $booReturn = $this->myDBClass->hasDataArray($strSQLHG1, $arrHG1, $intHG1); 2399 if ($booReturn && ($intHG1 != 0)) { 2400 foreach ($arrHG1 as $elemHG1) { 2401 if (!in_array($elemHG1['idSlave'], $arrExclude, true) && 2402 substr_count($strDataValue, $elemHG1['host_name'] . ',' . $strService) == 0) { 2403 $strDataValue .= $elemHG1['host_name'] . ',' . $strService . ','; 2404 } 2405 } 2406 } 2407 $strSQLHG2 = 'SELECT `host_name`, `idMaster` FROM `tbl_host` ' . 2408 'LEFT JOIN `tbl_lnkHostToHostgroup` ON `id`=`idMaster` ' . 2409 'WHERE `idSlave`=' . $data['idSlaveHG'] . " AND `active`='1' AND `exclude`=0 " . 2410 "AND $strDomainWhere1"; 2411 $booReturn = $this->myDBClass->hasDataArray($strSQLHG2, $arrHG2, $intHG2); 2412 if ($booReturn && ($intHG2 != 0)) { 2413 foreach ($arrHG2 as $elemHG2) { 2414 if (!in_array($elemHG2['idMaster'], $arrExclude, true) && 2415 substr_count($strDataValue, $elemHG2['host_name'] . ',' . $strService) == 0) { 2416 $strDataValue .= $elemHG2['host_name'] . ',' . $strService . ','; 2417 } 2418 } 2419 } 2420 } else { 2421 $strSQLHost = 'SELECT `' . $elem['target1'] . '` FROM `' . $elem['tableName1'] . '` ' . 2422 'WHERE `id`=' . $data['idSlaveH'] . " AND `active`='1' AND $strDomainWhere1"; 2423 $strHost = $this->myDBClass->getFieldData($strSQLHost); 2424 $strSQLSrv = 'SELECT `' . $elem['target2'] . '` FROM `' . $elem['tableName2'] . '` ' . 2425 'WHERE `id`=' . $data['idSlaveS'] . " AND `active`='1' AND $strDomainWhere1"; 2426 $strService = $this->myDBClass->getFieldData($strSQLSrv); 2427 if (($strHost != '') && ($strService != '') && 2428 substr_count($strDataValue, $strHost . ',' . $strService) == 0 && 2429 !in_array($data['idSlaveH'], $arrExclude, true)) { 2430 $strDataValue .= $strHost . ',' . $strService . ','; 2431 } 2432 } 2433 } 2434 $strDataValue = substr($strDataValue, 0, -1); 2435 if ($strDataValue == '') { 2436 $intReturn = 1; 2437 } 2438 } else { 2439 $intReturn = 1; 2440 } 2441 return $intReturn; 2442 } 2443 2444 /** 2445 * @param array $arrData Dataset array 2446 * @param string $strDataValue Data value 2447 * @param array $elem Relation data array 2448 * @return int 0 = use data / 1 = skip data 2449 */ 2450 private function processRelation7($arrData, &$strDataValue, $elem) 2451 { 2452 $intReturn = 1; 2453 // Get relation data 2454 $strSQLMaster = 'SELECT * FROM `' . $elem['linkTable'] . '` WHERE `idMaster`=' . $arrData['id']; 2455 $booReturn = $this->myDBClass->hasDataArray($strSQLMaster, $arrDataRel, $intDataCountRel); 2456 if ($booReturn && ($intDataCountRel != 0)) { 2457 // Rewrite $strDataValue with returned relation data 2458 $strDataValue = ''; 2459 /** @var array $arrDataRel */ 2460 foreach ($arrDataRel as $data) { 2461 $strSQL = 'SELECT host_name FROM tbl_host WHERE id=' .$data['idHost']; 2462 $strHost = $this->myDBClass->getFieldData($strSQL); 2463 $strSQL = 'SELECT service_description FROM tbl_service WHERE id=' .$data['idSlave']; 2464 $strService = $this->myDBClass->getFieldData($strSQL); 2465 $strDataValue .= $strHost . ',' . $strService . ','; 2466 $intReturn = 0; 2467 } 2468 $strDataValue = substr($strDataValue, 0, -1); 2469 } 2470 return $intReturn; 2471 } 2472} 2473