diff --git a/core/restservices.class.inc.php b/core/restservices.class.inc.php index b66ed5e09..76661e3d9 100644 --- a/core/restservices.class.inc.php +++ b/core/restservices.class.inc.php @@ -76,6 +76,52 @@ class ObjectResult $this->fields = array(); } + /** + * Creates an ObjectResult from a DBObject. + * + * @param DBObject $oObj The object. + * @param array|null $aFieldSpec An array of class => attribute codes (Cf. RestUtils::GetFieldList). List of the attributes to be reported. + * @param boolean $bExtendedOutput Output all of the link set attributes ? + * @param integer $iCode An error code (RestResult::OK is no issue has been found) + * @param string $sMessage Description of the error if any, an empty string otherwise + * + * @return ObjectResult + */ + public static function FromDBObject(DBObject $oObj, ?array $aFieldSpec = null, $bExtendedOutput = false, $iCode = 0, $sMessage = '') : ObjectResult { + + $oObjRes = new ObjectResult($oObj::class, $oObj->GetKey()); + $oObjRes->code = $iCode; + $oObjRes->message = $sMessage; + + $aFields = null; + if (!is_null($aFieldSpec)) + { + // Enum all classes in the hierarchy, starting with the current one + foreach (MetaModel::EnumParentClasses($oObj::class, ENUM_PARENT_CLASSES_ALL, false) as $sRefClass) + { + if (array_key_exists($sRefClass, $aFieldSpec)) + { + $aFields = $aFieldSpec[$sRefClass]; + break; + } + } + } + if (is_null($aFields)) + { + // No fieldspec given, or not found... + $aFields = array('id', 'friendlyname'); + } + + foreach ($aFields as $sAttCode) + { + $oObjRes->AddField($oObj, $sAttCode, $bExtendedOutput); + } + + return $oObjRes; + + } + + /** * Helper to make an output value for a given attribute * @@ -203,34 +249,7 @@ class RestResultWithObjects extends RestResult */ public function AddObject($iCode, $sMessage, $oObject, $aFieldSpec = null, $bExtendedOutput = false) { - $sClass = get_class($oObject); - $oObjRes = new ObjectResult($sClass, $oObject->GetKey()); - $oObjRes->code = $iCode; - $oObjRes->message = $sMessage; - - $aFields = null; - if (!is_null($aFieldSpec)) - { - // Enum all classes in the hierarchy, starting with the current one - foreach (MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL, false) as $sRefClass) - { - if (array_key_exists($sRefClass, $aFieldSpec)) - { - $aFields = $aFieldSpec[$sRefClass]; - break; - } - } - } - if (is_null($aFields)) - { - // No fieldspec given, or not found... - $aFields = array('id', 'friendlyname'); - } - - foreach ($aFields as $sAttCode) - { - $oObjRes->AddField($oObject, $sAttCode, $bExtendedOutput); - } + $oObjRes = ObjectResult::FromDBObject($oObject, $aFieldSpec, $bExtendedOutput, $iCode, $sMessage); $sObjKey = get_class($oObject).'::'.$oObject->GetKey(); $this->objects[$sObjKey] = $oObjRes; diff --git a/datamodels/2.x/itop-backup/dbrestore.class.inc.php b/datamodels/2.x/itop-backup/dbrestore.class.inc.php index 83a830ea1..ffccc9ade 100644 --- a/datamodels/2.x/itop-backup/dbrestore.class.inc.php +++ b/datamodels/2.x/itop-backup/dbrestore.class.inc.php @@ -53,14 +53,7 @@ class DBRestore extends DBBackup $sUser = self::EscapeShellArg($this->sDBUser); $sPwd = self::EscapeShellArg($this->sDBPwd); $sDBName = self::EscapeShellArg($this->sDBName); - if (empty($this->sMySQLBinDir)) - { - $sMySQLExe = 'mysql'; - } - else - { - $sMySQLExe = '"'.$this->sMySQLBinDir.'/mysql"'; - } + $sMySQLExe = DBBackup::MakeSafeMySQLCommand($this->sMySQLBinDir, 'mysql'); if (is_null($this->iDBPort)) { $sPortOption = ''; diff --git a/datamodels/2.x/itop-backup/status.php b/datamodels/2.x/itop-backup/status.php index f4ab2281a..f9c457ed4 100644 --- a/datamodels/2.x/itop-backup/status.php +++ b/datamodels/2.x/itop-backup/status.php @@ -95,12 +95,7 @@ try { // $sMySQLBinDir = MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'mysql_bindir', ''); $sMySQLBinDir = utils::ReadParam('mysql_bindir', $sMySQLBinDir, true); - if (empty($sMySQLBinDir)) { - $sMySQLDump = 'mysqldump'; - } else { - //echo 'Info - Found mysql_bindir: '.$sMySQLBinDir; - $sMySQLDump = '"'.$sMySQLBinDir.'/mysqldump"'; - } + $sMySQLDump = DBBackup::MakeSafeMySQLCommand($sMySQLBinDir, 'mysqldump'); $sCommand = "$sMySQLDump -V 2>&1"; $aOutput = array(); diff --git a/setup/backup.class.inc.php b/setup/backup.class.inc.php index 4097d2a01..896bf1c8f 100644 --- a/setup/backup.class.inc.php +++ b/setup/backup.class.inc.php @@ -106,6 +106,8 @@ class DBBackup /** @var string */ protected $sDBName; /** @var string */ + protected $sMySQLBinDir = ''; + /** @var string */ protected $sDBSubName; /** @@ -133,7 +135,6 @@ class DBBackup $this->sDBSubName = $oConfig->get('db_subname'); } - protected $sMySQLBinDir = ''; /** * Create a normalized backup name, depending on the current date/time and Database @@ -362,8 +363,9 @@ class DBBackup } $this->LogInfo("Starting backup of $this->sDBHost/$this->sDBName(suffix:'$this->sDBSubName')"); + $sMySQLBinDir = utils::ReadParam('mysql_bindir', $this->sMySQLBinDir, true); - $sMySQLDump = $this->GetMysqldumpCommand(); + $sMySQLDump = $this->MakeSafeMySQLCommand($sMySQLBinDir, 'mysqldump'); // Store the results in a temporary file $sTmpFileName = self::EscapeShellArg($sBackupFileName); @@ -624,20 +626,22 @@ EOF; /** * @return string the command to launch mysqldump (without its params) + * @throws \BackupException */ - private function GetMysqldumpCommand() + public static function MakeSafeMySQLCommand($sMySQLBinDir, string $sCmd) { - $sMySQLBinDir = utils::ReadParam('mysql_bindir', $this->sMySQLBinDir, true); - if (empty($sMySQLBinDir)) - { - $sMysqldumpCommand = 'mysqldump'; + if (empty($sMySQLBinDir)) { + $sMySQLCommand = $sCmd; } - else - { - $sMysqldumpCommand = '"'.$sMySQLBinDir.'/mysqldump"'; + else { + $sMySQLBinDir = escapeshellcmd($sMySQLBinDir); + $sMySQLCommand = '"'.$sMySQLBinDir.'/$sCmd"'; + if (!file_exists($sMySQLCommand)) { + throw new BackupException("$sCmd not found in $sMySQLBinDir"); + } } - return $sMysqldumpCommand; + return $sMySQLCommand; } } diff --git a/setup/setuputils.class.inc.php b/setup/setuputils.class.inc.php index bc027813b..f179d1e75 100644 --- a/setup/setuputils.class.inc.php +++ b/setup/setuputils.class.inc.php @@ -552,14 +552,15 @@ class SetupUtils if (empty($sMySQLBinDir) && null != MetaModel::GetConfig()) { $sMySQLBinDir = MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'mysql_bindir', ''); } - - if (empty($sMySQLBinDir)) { - $sMySQLDump = 'mysqldump'; - } - else { - $aResult[] = new CheckResult(CheckResult::TRACE, 'Info - Found mysql_bindir: '.$sMySQLBinDir); - $sMySQLDump = '"'.$sMySQLBinDir.'/mysqldump"'; + try { + $sMySQLDump = DBBackup::MakeSafeMySQLCommand($sMySQLBinDir, 'mysqldump'); + } catch (Exception $e) { + $aResult[] = new CheckResult(CheckResult::ERROR, $e->getMessage()); + return $aResult; } + if (!empty($sMySQLBinDir)) { + $aResult[] = new CheckResult(CheckResult::TRACE, 'Info - Found mysql_bindir: '.$sMySQLBinDir); + } $sCommand = "$sMySQLDump -V 2>&1"; $aOutput = array();