Esempio n. 1
0
 protected function LogError($sMsg)
 {
     static $bDebug = null;
     if ($bDebug == null) {
         $bDebug = MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'debug', false);
     }
     IssueLog::Error($sMsg);
     if ($bDebug) {
         echo 'Error: ' . $sMsg . "\n";
     }
 }
 /**
  * Create a new transaction id, store it in the session and return its id
  * @param void
  * @return int The identifier of the new transaction
  */
 public static function GetNewTransactionId()
 {
     $bTransactionsEnabled = MetaModel::GetConfig()->Get('transactions_enabled');
     if (!$bTransactionsEnabled) {
         return 'notransactions';
         // Any value will do
     }
     $sClass = 'privUITransaction' . MetaModel::GetConfig()->Get('transaction_storage');
     if (!class_exists($sClass, false)) {
         IssueLog::Error("Incorrect value '" . MetaModel::GetConfig()->Get('transaction_storage') . "' for 'transaction_storage', the class '{$sClass}' does not exists. Using privUITransactionSession instead for storing sessions.");
         $sClass = 'privUITransactionSession';
     }
     return (string) $sClass::GetNewTransactionId();
 }
Esempio n. 3
0
                    $oAttachment->Set('item_class', $sObjClass);
                    $oAttachment->SetDefaultOrgId();
                    $oAttachment->Set('contents', $oDoc);
                    $iAttId = $oAttachment->DBInsert();
                    $aResult['msg'] = $oDoc->GetFileName();
                    $aResult['icon'] = utils::GetAbsoluteUrlAppRoot() . AttachmentPlugIn::GetFileIcon($oDoc->GetFileName());
                    $aResult['att_id'] = $iAttId;
                    $aResult['preview'] = $oDoc->IsPreviewAvailable() ? 'true' : 'false';
                } catch (FileUploadException $e) {
                    $aResult['error'] = $e->GetMessage();
                }
            }
            $oPage->add(json_encode($aResult));
            break;
        case 'remove':
            $iAttachmentId = utils::ReadParam('att_id', '');
            $oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE id = :id");
            $oSet = new DBObjectSet($oSearch, array(), array('id' => $iAttachmentId));
            while ($oAttachment = $oSet->Fetch()) {
                $oAttachment->DBDelete();
            }
            break;
        default:
            $oPage->p("Missing argument 'operation'");
    }
    $oPage->output();
} catch (Exception $e) {
    // note: transform to cope with XSS attacks
    echo htmlentities($e->GetMessage(), ENT_QUOTES, 'utf-8');
    IssueLog::Error($e->getMessage());
}
 protected function ForgotPwdGo()
 {
     $sAuthUser = utils::ReadParam('auth_user', '', true, 'raw_data');
     try {
         UserRights::Login($sAuthUser);
         // Set the user's language (if possible!)
         $oUser = UserRights::GetUserObject();
         if ($oUser == null) {
             throw new Exception(Dict::Format('UI:ResetPwd-Error-WrongLogin', $sAuthUser));
         }
         if (!MetaModel::IsValidAttCode(get_class($oUser), 'reset_pwd_token')) {
             throw new Exception(Dict::S('UI:ResetPwd-Error-NotPossible'));
         }
         if (!$oUser->CanChangePassword()) {
             throw new Exception(Dict::S('UI:ResetPwd-Error-FixedPwd'));
         }
         $sTo = $oUser->GetResetPasswordEmail();
         // throws Exceptions if not allowed
         if ($sTo == '') {
             throw new Exception(Dict::S('UI:ResetPwd-Error-NoEmail'));
         }
         // This token allows the user to change the password without knowing the previous one
         $sToken = substr(md5(APPROOT . uniqid()), 0, 16);
         $oUser->Set('reset_pwd_token', $sToken);
         CMDBObject::SetTrackInfo('Reset password');
         $oUser->DBUpdate();
         $oEmail = new Email();
         $oEmail->SetRecipientTO($sTo);
         $sFrom = MetaModel::GetConfig()->Get('forgot_password_from');
         if ($sFrom == '') {
             $sFrom = $sTo;
         }
         $oEmail->SetRecipientFrom($sFrom);
         $oEmail->SetSubject(Dict::S('UI:ResetPwd-EmailSubject'));
         $sResetUrl = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?loginop=reset_pwd&auth_user='******'login')) . '&token=' . urlencode($sToken);
         $oEmail->SetBody(Dict::Format('UI:ResetPwd-EmailBody', $sResetUrl));
         $iRes = $oEmail->Send($aIssues, true);
         switch ($iRes) {
             //case EMAIL_SEND_PENDING:
             case EMAIL_SEND_OK:
                 break;
             case EMAIL_SEND_ERROR:
             default:
                 IssueLog::Error('Failed to send the email with the NEW password for ' . $oUser->Get('friendlyname') . ': ' . implode(', ', $aIssues));
                 throw new Exception(Dict::S('UI:ResetPwd-Error-Send'));
         }
         $this->DisplayLoginHeader();
         $this->add("<div id=\"login\">\n");
         $this->add("<h1>" . Dict::S('UI:Login:ForgotPwdForm') . "</h1>\n");
         $this->add("<p>" . Dict::S('UI:ResetPwd-EmailSent') . "</p>");
         $this->add("<form method=\"post\">\n");
         $this->add("<table>\n");
         $this->add("<tr><td colspan=\"2\" class=\"center v-spacer\"><input type=\"button\" onClick=\"window.close();\" value=\"" . Dict::S('UI:Button:Done') . "\" /></td></tr>\n");
         $this->add("</table>\n");
         $this->add("</form>\n");
         $this->add("</div\n");
     } catch (Exception $e) {
         $this->DisplayForgotPwdForm(true, $e->getMessage());
     }
 }
Esempio n. 5
0
    $sFormat = utils::ReadParam('format', null, true);
    $sFileName = utils::ReadParam('filename', '', true, 'string');
    $bInteractive = utils::ReadParam('interactive', false);
    $sMode = utils::ReadParam('mode', '');
    if ($bInteractive) {
        InteractiveShell($sExpression, $sQueryId, $sFormat, $sFileName, $sMode);
    } else {
        $oExporter = CheckParameters($sExpression, $sQueryId, $sFormat);
        $sMimeType = $oExporter->GetMimeType();
        if ($sMimeType == 'text/html') {
            $oP = new NiceWebPage('iTop export');
            $oP->add_style("body { overflow: auto; }");
            $oP->add_ready_script("\$('table.listResults').tablesorter({widgets: ['MyZebra']});");
        } else {
            $oP = new ajax_page('iTop export');
            $oP->SetContentType($oExporter->GetMimeType());
        }
        DoExport($oP, $oExporter, false);
        $oP->output();
    }
} catch (BulkExportMissingParameterException $e) {
    $oP = new ajax_page('iTop Export');
    $oP->add($e->getMessage());
    Usage($oP);
    $oP->output();
} catch (Exception $e) {
    $oP = new WebPage('iTop Export');
    $oP->add('Error: ' . $e->getMessage());
    IssueLog::Error($e->getMessage() . "\n" . $e->getTraceAsString());
    $oP->output();
}
 /**
  * @return boolean True if the task record can be deleted
  */
 public function Process()
 {
     // By default: consider that the task is not completed
     $bRet = false;
     // Attempt to take the ownership
     $iStatus = $this->MarkAsRunning();
     if ($iStatus == self::OK) {
         try {
             $sStatus = $this->DoProcess();
             if ($this->Get('event_id') != 0) {
                 $oEventLog = MetaModel::GetObject('Event', $this->Get('event_id'));
                 $oEventLog->Set('message', $sStatus);
                 $oEventLog->DBUpdate();
             }
             $bRet = true;
         } catch (Exception $e) {
             $iRemaining = $this->Get('remaining_retries');
             if ($iRemaining > 0) {
                 $iRetryDelay = $this->GetRetryDelay();
                 IssueLog::Info('Failed to process async task #' . $this->GetKey() . ' - reason: ' . $e->getMessage() . ' - remaining retries: ' . $iRemaining . ' - next retry in ' . $iRetryDelay . 's');
                 $this->Set('remaining_retries', $iRemaining - 1);
                 $this->Set('status', 'planned');
                 $this->Set('started', null);
                 $this->Set('planned', time() + $iRetryDelay);
                 $this->DBUpdate();
             } else {
                 IssueLog::Error('Failed to process async task #' . $this->GetKey() . ' - reason: ' . $e->getMessage());
             }
         }
     } else {
         // Already done or being handled by another process... skip...
         $bRet = false;
     }
     return $bRet;
 }
 /**
  * Add a 'context' OQL query, specifying extra objects to be marked as 'is_reached'
  * even though they are not part of the sources.
  * @param string $sOQL The OQL query defining the context objects 
  */
 public function AddContextQuery($key, $sOQL)
 {
     if ($sOQL === '') {
         return;
     }
     $oSearch = DBObjectSearch::FromOQL($sOQL);
     $aAliases = $oSearch->GetSelectedClasses();
     if (count($aAliases) < 2) {
         IssueLog::Error("Invalid context query '{$sOQL}'. A context query must contain at least two columns.");
         throw new Exception("Invalid context query '{$sOQL}'. A context query must contain at least two columns. Columns: " . implode(', ', $aAliases) . '. ');
     }
     $aAliasNames = array_keys($aAliases);
     $sClassAlias = $oSearch->GetClassAlias();
     $oCondition = new BinaryExpression(new FieldExpression('id', $aAliasNames[0]), '=', new VariableExpression('id'));
     $oSearch->AddConditionExpression($oCondition);
     $sClass = $oSearch->GetClass();
     if (!array_key_exists($sClass, $this->aContextSearches)) {
         $this->aContextSearches[$sClass] = array();
     }
     $this->aContextSearches[$sClass][] = array('key' => $key, 'search' => $oSearch);
 }
Esempio n. 8
0
 /**
  *	Attempt to acquire the mutex
  *	@returns bool True if the mutex is acquired, false if already locked elsewhere	 
  */
 public function TryLock()
 {
     if ($this->bLocked) {
         return true;
         // Already acquired
     }
     if (self::$aAcquiredLocks[$this->sName] > 0) {
         self::$aAcquiredLocks[$this->sName]++;
         $this->bLocked = true;
         return true;
     }
     $res = $this->QueryToScalar("SELECT GET_LOCK('" . $this->sName . "', 0)");
     if (is_null($res)) {
         throw new Exception("Failed to acquire the lock '" . $this->sName . "'");
     }
     // $res === '1' means I hold the lock
     // $res === '0' means it timed out
     if ($res === '1') {
         $this->bLocked = true;
         self::$aAcquiredLocks[$this->sName]++;
     }
     if ($res !== '1' && $res !== '0') {
         $sMsg = 'GET_LOCK(' . $this->sName . ', 0) returned: ' . var_export($res, true) . '. Expected values are: 0, 1 or null';
         IssueLog::Error($sMsg);
         throw new Exception($sMsg);
     }
     return $res !== '0';
 }
 protected function LogMessage($sMessage, $aData = array())
 {
     if (MetaModel::IsLogEnabledIssue()) {
         if (MetaModel::IsValidClass('EventIssue')) {
             $oLog = new EventIssue();
             $oLog->Set('message', $sMessage);
             $oLog->Set('userinfo', '');
             $oLog->Set('issue', 'LDAP Authentication');
             $oLog->Set('impact', 'User login rejected');
             $oLog->Set('data', $aData);
             $oLog->DBInsertNoReload();
         }
         IssueLog::Error($sMessage);
     }
 }
Esempio n. 10
0
 protected static function IncludeModule($sModuleType, $sToInclude)
 {
     $sFirstChar = substr($sToInclude, 0, 1);
     $sSecondChar = substr($sToInclude, 1, 1);
     if ($sFirstChar != '/' && $sFirstChar != '\\' && $sSecondChar != ':') {
         // It is a relative path, prepend APPROOT
         if (substr($sToInclude, 0, 3) == '../') {
             // Preserve compatibility with config files written before 1.0.1
             // Replace '../' by '<root>/'
             $sFile = APPROOT . '/' . substr($sToInclude, 3);
         } else {
             $sFile = APPROOT . '/' . $sToInclude;
         }
     } else {
         // Leave as is - should be an absolute path
         $sFile = $sToInclude;
     }
     if (!file_exists($sFile)) {
         $sConfigFile = self::$m_oConfig->GetLoadedFile();
         if (strlen($sConfigFile) > 0) {
             throw new CoreException('Include: wrong file name in configuration file', array('config file' => $sConfigFile, 'section' => $sModuleType, 'filename' => $sFile));
         } else {
             // The configuration is in memory only
             throw new CoreException('Include: wrong file name in configuration file (in memory)', array('section' => $sModuleType, 'filename' => $sFile));
         }
     }
     // Note: We do not expect the modules to output characters while loading them.
     //       Therefore, and because unexpected characters can corrupt the output,
     //       they must be trashed here.
     //       Additionnaly, pages aiming at delivering data in their output can call WebPage::TrashUnexpectedOutput()
     //       to get rid of chars that could be generated during the execution of the code
     ob_start();
     require_once $sFile;
     $sPreviousContent = ob_get_clean();
     if (self::$m_oConfig->Get('debug_report_spurious_chars')) {
         if ($sPreviousContent != '') {
             IssueLog::Error("Spurious characters injected by {$sModuleType}/{$sToInclude}");
         }
     }
 }
 protected function LogError($sMsg)
 {
     IssueLog::Error($sMsg);
 }
Esempio n. 12
0
 /**
  * Read the output buffer and deal with its contents:
  * - trash unexpected output if the flag has been set
  * - report unexpected behaviors such as the output buffering being stopped
  * 
  * Possible improvement: I've noticed that several output buffers are stacked,
  * if they are not empty, the output will be corrupted. The solution would
  * consist in unstacking all of them (and concatenate the contents).	 	 
  */
 protected function ob_get_clean_safe()
 {
     $sOutput = ob_get_contents();
     if ($sOutput === false) {
         $sMsg = "Design/integration issue: No output buffer. Some piece of code has called ob_get_clean() or ob_end_clean() without calling ob_start()";
         if ($this->bTrashUnexpectedOutput) {
             IssueLog::Error($sMsg);
             $sOutput = '';
         } else {
             $sOutput = $sMsg;
         }
     } else {
         ob_end_clean();
         // on some versions of PHP doing so when the output buffering is stopped can cause a notice
         if ($this->bTrashUnexpectedOutput) {
             if (trim($sOutput) != '') {
                 if (Utils::GetConfig() && Utils::GetConfig()->Get('debug_report_spurious_chars')) {
                     IssueLog::Error("Trashing unexpected output:'{$s_captured_output}'\n");
                 }
             }
             $sOutput = '';
         }
     }
     return $sOutput;
 }
 /**
  * Get the description of the graph as text string in the XDot format
  * including the positions of the nodes and egdes (requires graphviz
  * to be installed on the machine and the path to dot/dot.exe to be
  * configured in the iTop configuration file)
  * Note: the function creates temporary files in APPROOT/data/tmp
  * @return string
  */
 public function DumpAsXDot()
 {
     $sDotExecutable = MetaModel::GetConfig()->Get('graphviz_path');
     if (file_exists($sDotExecutable)) {
         // create the file with Graphviz
         if (!is_dir(APPROOT . "data")) {
             @mkdir(APPROOT . "data");
         }
         if (!is_dir(APPROOT . "data/tmp")) {
             @mkdir(APPROOT . "data/tmp");
         }
         $sXdotFilePath = tempnam(APPROOT . "data/tmp", 'xdot-');
         $sDotDescription = $this->GetDotDescription(true);
         // true => don't put (localized) labels in the file, since it makes it harder to parse
         $sDotFilePath = tempnam(APPROOT . "data/tmp", 'dot-');
         $rFile = @fopen($sDotFilePath, "w");
         @fwrite($rFile, $sDotDescription);
         @fclose($rFile);
         $aOutput = array();
         $CommandLine = "\"{$sDotExecutable}\" -v -Tdot < {$sDotFilePath} -o{$sXdotFilePath} 2>&1";
         exec($CommandLine, $aOutput, $iRetCode);
         if ($iRetCode != 0) {
             $sHtml = '';
             $sHtml .= "<p><b>Error:</b></p>";
             $sHtml .= "<p>The command: <pre>{$CommandLine}</pre> returned {$iRetCode}</p>";
             $sHtml .= "<p>The output of the command is:<pre>\n" . implode("\n", $aOutput) . "</pre></p>";
             IssueLog::Error($sHtml);
         } else {
             $sHtml = '<pre>' . file_get_contents($sXdotFilePath) . '</pre>';
             @unlink($sXdotFilePath);
         }
         @unlink($sDotFilePath);
     } else {
         throw new Exception('graphviz not found (executable path: ' . $sDotExecutable . ')');
     }
     return $sHtml;
 }
 public static function SetProperty($sName, $sValue, $sComment = '', $sDescription = null)
 {
     try {
         $oSearch = DBObjectSearch::FromOQL('SELECT DBProperty WHERE name = :name');
         $oSet = new DBObjectSet($oSearch, array(), array('name' => $sName));
         if ($oSet->Count() == 0) {
             $oProp = new DBProperty();
             $oProp->Set('name', $sName);
             $oProp->Set('description', $sDescription);
             $oProp->Set('value', $sValue);
             $oProp->Set('change_date', time());
             $oProp->Set('change_comment', $sComment);
             $oProp->DBInsert();
         } elseif ($oSet->Count() == 1) {
             $oProp = $oSet->fetch();
             if (!is_null($sDescription)) {
                 $oProp->Set('description', $sDescription);
             }
             $oProp->Set('value', $sValue);
             $oProp->Set('change_date', time());
             $oProp->Set('change_comment', $sComment);
             $oProp->DBUpdate();
         } else {
             // Houston...
             throw new CoreException('duplicate db property');
         }
     } catch (MySQLException $e) {
         // This might be because the table could not be found,
         // let's check it and discard silently if this is really the case
         if (self::IsInstalled()) {
             throw $e;
         }
         IssueLog::Error('Attempting to write a DBProperty while the module has not been installed');
     }
 }
Esempio n. 15
0
 /**
  * Discard unexpected output data
  * This is a MUST when the Page output is DATA (download of a document, download CSV export, download ...)
  */
 public function TrashUnexpectedOutput()
 {
     // This protection is redundant with a protection implemented in MetaModel::IncludeModule
     // which detects such issues while loading module files
     // Here, the purpose is to detect and discard characters produced by the code execution (echo)
     $sPreviousContent = ob_get_clean();
     if (trim($sPreviousContent) != '') {
         if (Utils::GetConfig() && Utils::GetConfig()->Get('debug_report_spurious_chars')) {
             IssueLog::Error("Output already started before downloading file:\nContent was:'{$sPreviousContent}'\n");
         }
     }
 }
 /**
  * Overridable to extend the behavior in case of error (logging)
  */
 protected function HandleError($sErrorMessage, $iErrorCode)
 {
     if ($this->Get('last_attempt') == '') {
         // First attempt
         $this->Set('remaining_retries', $this->GetMaxRetries($iErrorCode));
     }
     $this->Set('last_error', $sErrorMessage);
     $this->Set('last_error_code', $iErrorCode);
     // Note: can be ZERO !!!
     $this->Set('last_attempt', time());
     $iRemaining = $this->Get('remaining_retries');
     if ($iRemaining > 0) {
         $iRetryDelay = $this->GetRetryDelay($iErrorCode);
         IssueLog::Info('Failed to process async task #' . $this->GetKey() . ' - reason: ' . $sErrorMessage . ' - remaining retries: ' . $iRemaining . ' - next retry in ' . $iRetryDelay . 's');
         $this->Set('remaining_retries', $iRemaining - 1);
         $this->Set('status', 'planned');
         $this->Set('started', null);
         $this->Set('planned', time() + $iRetryDelay);
     } else {
         IssueLog::Error('Failed to process async task #' . $this->GetKey() . ' - reason: ' . $sErrorMessage);
         $this->Set('status', 'error');
         $this->Set('started', null);
         $this->Set('planned', null);
         $this->OnDefinitiveFailure();
     }
     $this->DBUpdate();
 }