PostfixAdmin - web based virtual user administration interface for Postfix mail servers https://postfixadmin.github.io/postfixadmin/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

728 lines
26 KiB

11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
8 months ago
11 months ago
5 years ago
5 years ago
5 years ago
  1. <!DOCTYPE html>
  2. <?php
  3. $PALANG = [];
  4. require_once('common.php');
  5. ?>
  6. <html lang="en">
  7. <head>
  8. <meta charset="utf-8">
  9. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  10. <meta name="viewport" content="width=device-width, initial-scale=1">
  11. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  12. <title>Postfix Admin - Setup</title>
  13. <link rel="shortcut icon" href="images/favicon.ico"/>
  14. <link rel="stylesheet" href="css/bootstrap-3.4.1-dist/css/bootstrap.min.css"/>
  15. <link rel="stylesheet" href="css/bootstrap.css"/>
  16. </head>
  17. <body>
  18. <nav class="navbar navbar-default fixed-top">
  19. <div class="container-fluid">
  20. <div class="navbar-header">
  21. <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
  22. aria-expanded="false" aria-controls="navbar">
  23. <span class="sr-only">Toggle navigation</span>
  24. <span class="icon-bar"></span>
  25. <span class="icon-bar"></span>
  26. <span class="icon-bar"></span>
  27. </button>
  28. <a class="navbar-brand" href='main.php'><img id="login_header_logo" src="images/postbox.png"
  29. alt="Logo"/></a>
  30. </div>
  31. </div>
  32. </nav>
  33. <?php
  34. /**
  35. * Postfix Admin
  36. *
  37. * LICENSE
  38. * This source file is subject to the GPL license that is bundled with
  39. * this package in the file LICENSE.TXT.
  40. *
  41. * Further details on the project are available at https://github.com/postfixadmin/postfixadmin
  42. *
  43. * @version $Id$
  44. * @license GNU GPL v2 or later.
  45. *
  46. * File: setup.php
  47. * Used to help ensure a server is setup appropriately during installation/setup.
  48. */
  49. $configSetupPassword = Config::read_string('setup_password');
  50. $errors = [];
  51. $configSetupDone = false;
  52. $authenticated = false;
  53. $old_setup_password = false;
  54. if (strlen($configSetupPassword) == 73 && strpos($configSetupPassword, ':') == 32) {
  55. $old_setup_password = true;
  56. } elseif ($configSetupPassword != 'changeme' && $configSetupPassword != '') {
  57. $configSetupDone = true;
  58. $pass = safepost('setup_password', 'invalid');
  59. if ($pass != 'invalid') {
  60. if (password_verify(safepost('setup_password', 'invalid'), $configSetupPassword)) {
  61. $authenticated = true;
  62. } else {
  63. error_log("PostfixAdmin setup login failed (ip_address: {$_SERVER['REMOTE_ADDR']})");
  64. $errors['setup_login_password'] = "Password verification failed.";
  65. }
  66. }
  67. }
  68. ?>
  69. <?php
  70. $todo = '<span class="font-weight-bold text-warning">TODO</span>';
  71. $tick = ' ✅ ';
  72. ?>
  73. <div class="container">
  74. <div class="row">
  75. <h1 class="h1">Configure and Setup Postfixadmin</h1>
  76. <p>This page helps you setup PostfixAdmin. For further help see <a
  77. href="https://github.com/postfixadmin/postfixadmin/tree/master/DOCUMENTS">the documentation</a>.
  78. </p>
  79. <?php
  80. if (!isset($_SERVER['HTTPS'])) {
  81. echo "<h2 class='h2 text-danger'>Warning: connection not secure, switch to https if possible</h2>";
  82. } ?>
  83. <div class="col-12">
  84. <ul>
  85. <li>
  86. <?php
  87. if ($configSetupDone) {
  88. echo $tick . " setup_password configured";
  89. } else {
  90. echo $todo . " You need to have a setup_password hash configured in a <code>config.local.php</code> file";
  91. }
  92. ?>
  93. </li>
  94. <li>
  95. <?php
  96. if ($authenticated) {
  97. echo $tick . " You are logged in with the setup_password, some environment and hosting checks are displayed below.";
  98. } else {
  99. echo $todo . " You need to authenticate using the setup_password before you can perform some environment and hosting checks.";
  100. }
  101. ?>
  102. </li>
  103. </ul>
  104. <?php if (!$authenticated) { ?>
  105. <p> One you have logged in with the setup_password, this page will ... </p>
  106. <ul>
  107. <li> run some simple hosting/environment checks which may help identify problems with your
  108. environment
  109. </li>
  110. <li> create/update your database of choice,</li>
  111. <li> allow you to list / add super user accounts</li>
  112. </ul>
  113. <?php } ?>
  114. </div>
  115. </div>
  116. <?php if ($configSetupDone && !$authenticated) { ?>
  117. <div class="row">
  118. <div class="col-12">
  119. <h2 class="h2">Login with setup_password</h2>
  120. <form name="authenticate" class="col-2 form-horizontal" method="post">
  121. <div class="form-group">
  122. <label for="setup_password" class="col-sm-4 control-label">Setup password</label>
  123. <div class="col-sm-4">
  124. <input class="form-control" type="password" name="setup_password" minlength=5
  125. id="setup_password"
  126. value=""/>
  127. <?= _error_field($errors, 'setup_login_password'); ?>
  128. </div>
  129. </div>
  130. <div class="form-group">
  131. <div class="col-sm-offset-4 col-sm-4">
  132. <button class="btn btn-primary" type="submit" name="submit" value="setuppw">Login with
  133. setup_password.
  134. </button>
  135. </div>
  136. </div>
  137. </form>
  138. <p>If you've forgotten your super-admin password, you can generate a new one using the
  139. <em>Generate</em>
  140. form and update your <code>config.local.php</code></p>
  141. </div>
  142. </div>
  143. <?php
  144. } ?>
  145. <div class="row">
  146. <div class="col-12">
  147. <?php
  148. if (!$configSetupDone) {
  149. echo <<<EOF
  150. <p><strong>For a new installation, you must generate a 'setup_password' to go into your config.local.php file.</strong></p>
  151. <p>You can use the form below, or run something like the following in a shell - <code>php -r 'echo password_hash("password", PASSWORD_DEFAULT);'</code><p>
  152. EOF;
  153. }
  154. if ($old_setup_password) {
  155. echo '<p class="text-danger"><strong>Your setup_password is in an obsolete format. As of PostfixAdmin 3.3 it needs regenerating.</strong>';
  156. }
  157. if (!$authenticated || !$configSetupDone) { ?>
  158. <h2>Generate setup_password</h2>
  159. <?php
  160. $form_error = '';
  161. $result = '';
  162. if (safepost('form') === "setuppw") {
  163. $errors = [];
  164. # "setup password" form submitted
  165. if (safepost('setup_password', 'abc') != safepost('setup_password2')) {
  166. $errors['setup_password'] = "The two passwords differ!";
  167. $form_error = 'has-error';
  168. } else {
  169. $msgs = validate_password(safepost('setup_password'));
  170. if (empty($msgs)) {
  171. // form has been submitted; both fields filled in, so generate a new setup password.
  172. $hash = password_hash(safepost('setup_password'), PASSWORD_DEFAULT);
  173. $result = '<p>If you want to use the password you entered as setup password, edit config.inc.php or config.local.php and set</p>';
  174. $result .= "<pre>\$CONF['setup_password'] = '$hash';</pre><p>After adding, refresh this page and log in using it.</p>";
  175. } else {
  176. $form_error = 'has-error';
  177. $errors['setup_password'] = implode(', ', $msgs);
  178. }
  179. }
  180. }
  181. ?>
  182. <form name="setuppw" method="post" class="form-horizontal" action="setup.php">
  183. <input type="hidden" name="form" value="setuppw"/>
  184. <div class="form-group <?= $form_error ?>">
  185. <label for="setup_password" class="col-sm-4 control-label">Setup password</label>
  186. <div class="col-sm-4">
  187. <input class="form-control" type="password" name="setup_password" minlength=5
  188. id="setup_password"
  189. autocomplete="new-password"
  190. value=""/>
  191. <?= _error_field($errors, 'setup_password'); ?>
  192. </div>
  193. </div>
  194. <div class="form-group <?= $form_error ?>">
  195. <label for="setup_password2" class="col-sm-4 control-label">Setup password (again)</label>
  196. <div class="col-sm-4">
  197. <input class="form-control" type="password" name="setup_password2"
  198. minlength=5 id="setup_password2"
  199. autocomplete="new-password"
  200. value=""/>
  201. <?= _error_field($errors, 'setup_password2'); ?>
  202. </div>
  203. </div>
  204. <div class="form-group">
  205. <div class="col-sm-offset-4 col-sm-4">
  206. <button class="btn btn-primary" type="submit" name="submit" value="setuppw">
  207. Generate setup_password hash
  208. </button>
  209. </div>
  210. </div>
  211. </form>
  212. <?= $result ?>
  213. <?php
  214. } // end if(!$authenticated)?>
  215. </div>
  216. </div>
  217. <div class="row">
  218. <div class="col-12">
  219. <h2 class="h2">Hosting Environment Check</h2>
  220. <?php
  221. $check = do_software_environment_check();
  222. if ($authenticated) {
  223. if (!empty($check['info'])) {
  224. echo "<h3>Information</h3><ul>";
  225. foreach ($check['info'] as $msg) {
  226. echo "<li>{$tick} {$msg}</li>";
  227. }
  228. echo "</ul>";
  229. }
  230. if (!empty($check['warn'])) {
  231. echo "<h3>Warnings</h3><ul>";
  232. foreach ($check['warn'] as $msg) {
  233. echo "<li class='text-warning'>⚠ {$msg}</li>";
  234. }
  235. echo "</ul>";
  236. }
  237. if (!empty($check['error'])) {
  238. echo "<h3>Errors (MUST be fixed)</h3><ul>";
  239. foreach ($check['error'] as $msg) {
  240. echo "<li class='text-danger'>⛔{$msg}</li>";
  241. }
  242. echo "</ul>";
  243. }
  244. $php_error_log = ini_get('error_log');
  245. } else {
  246. if (!empty($check['error'])) {
  247. echo '<p class="text-danger">Hosting Environment errors found. Login to see details.</p>';
  248. }
  249. if (!empty($check['warn'])) {
  250. echo '<p class="text-warning">Hosting Environment warnings found. Login to see details.</p>';
  251. }
  252. if (empty($check['warn']) && empty($check['error'])) {
  253. echo "<p> $tick No problems detected.</p>";
  254. }
  255. }
  256. ?>
  257. </div>
  258. </div>
  259. <div class="row">
  260. <div class="col-12">
  261. <h2 class="h2">Database</h2>
  262. <ul>
  263. <?php
  264. $db = false;
  265. try {
  266. $db = db_connect();
  267. } catch (\Exception $e) {
  268. echo "<li class='h3 text-danger'>Something went wrong while trying to connect to the database. A message should be logged - check PHP's error_log (" . ini_get('error_log') . ')</li>';
  269. error_log("Couldn't perform PostfixAdmin database update - failed to connect to db? " . $e->getMessage() . " Trace: " . $e->getTraceAsString());
  270. }
  271. if ($db) {
  272. echo "<li>$tick Database - connection works</li>";
  273. try {
  274. ob_start();
  275. $ret = require_once(dirname(__FILE__) . '/upgrade.php');
  276. $output = ob_get_clean();
  277. if ($ret) {
  278. echo "<li>$tick Database update check - $output </li>";
  279. }
  280. } catch (\Exception $e) {
  281. if ($authenticated) {
  282. echo "<li class='h3 text-danger'>Exception message: {$e->getMessage()} - check logs!</li>";
  283. }
  284. echo "<li class='h3 text-danger'>Something went wrong while trying to apply database updates, a message should be logged - check PHP's error_log (" . ini_get('error_log') . ')</li>';
  285. error_log("Couldn't perform PostfixAdmin database update via upgrade.php - " . $e->getMessage() . " Trace: " . $e->getTraceAsString());
  286. }
  287. } else {
  288. echo "<li class='text-danger'>Could not connect to database to perform updates; check PHP error log.</li>";
  289. }
  290. ?>
  291. </ul>
  292. </div
  293. </div>
  294. </div>
  295. <?php
  296. if ($authenticated) {
  297. $setupMessage = '';
  298. if (safepost("submit") === "createadmin") {
  299. ?>
  300. <div class='row'>
  301. <div class='col-12'>
  302. <?php
  303. # "create admin" form submitted, make sure the correct setup password was specified.
  304. // XXX need to ensure domains table includes an 'ALL' entry.
  305. $table_domain = table_by_key('domain');
  306. $rows = db_query_all("SELECT * FROM $table_domain WHERE domain = 'ALL'");
  307. if (empty($rows)) {
  308. // all other fields should default through the schema.
  309. db_insert('domain', array('domain' => 'ALL', 'description' => '', 'transport' => ''));
  310. }
  311. $values = array(
  312. 'username' => safepost('username'),
  313. 'password' => safepost('password'),
  314. 'password2' => safepost('password2'),
  315. 'superadmin' => 1,
  316. 'domains' => array(),
  317. 'active' => 1,
  318. );
  319. list($error, $setupMessage, $errors) = create_admin($values);
  320. if ($error == 1) {
  321. $tUsername = htmlentities($values['username']);
  322. error_log("failed to add admin - " . json_encode([$error, $setupMessage, $errors]));
  323. echo "<p class='text-danger'>Admin addition failed; check field error messages or server logs.</p>";
  324. } else {
  325. // all good!.
  326. $setupMessage .= "<p>You are done with your basic setup. <b>You can now <a href='login.php'>login to PostfixAdmin</a> using the account you just created.</b></p>";
  327. }
  328. echo "</div></div>";
  329. }
  330. $table_admin = table_by_key('admin');
  331. $bool = db_get_boolean(true);
  332. $admins = db_query_all("SELECT * FROM $table_admin WHERE superadmin = '$bool' AND active = '$bool'");
  333. if (!empty($admins)) { ?>
  334. <div class="row">
  335. <div class="col-12">
  336. <h2 class="h2">Super admins</h2>
  337. <p>The following 'super-admin' accounts have already been added to the database.</p>
  338. <ul>
  339. <?php
  340. foreach ($admins as $row) {
  341. echo "<li>{$row['username']}</li>";
  342. }
  343. ?>
  344. </ul>
  345. </div>
  346. </div>
  347. <?php } ?>
  348. <div class="row">
  349. <div class="col-12">
  350. <h2>Add Superadmin Account</h2>
  351. <form name="create_admin" class="form-horizontal" method="post">
  352. <div class="form-group">
  353. <label for="setup_password" class="col-sm-4 control-label">Setup password</label>
  354. <div class="col-sm-4">
  355. <input class="form-control" type="password" required="required"
  356. name="setup_password"
  357. minlength=5
  358. value=""/>
  359. </div>
  360. </div>
  361. <div class="form-group">
  362. <label for="username" class="col-sm-4 control-label"><?= $PALANG['admin'] ?></label>
  363. <div class="col-sm-4">
  364. <input class="form-control" type="text" required="required" name="username"
  365. minlength=5
  366. id="username"
  367. value=""/>
  368. <?= _error_field($errors, 'username'); ?>
  369. </div>
  370. </div>
  371. <div class="form-group">
  372. <label for="password" class="col-sm-4 control-label"><?= $PALANG['password'] ?></label>
  373. <div class="col-sm-4">
  374. <input class="form-control" type="password" required=required
  375. name="password" minlength=5
  376. id="password" autocomplete="new-password"
  377. value=""/>
  378. <?= _error_field($errors, 'password'); ?>
  379. </div>
  380. </div>
  381. <div class="form-group">
  382. <label for="password2"
  383. class="col-sm-4 control-label"><?= $PALANG['password_again'] ?></label>
  384. <div class="col-sm-4">
  385. <input class="form-control" type="password" required=required
  386. name="password2" minlength=5
  387. id="password2" autocomplete="new-password"
  388. value=""/>
  389. <?= _error_field($errors, 'password2'); ?>
  390. </div>
  391. </div>
  392. <div class="form-group">
  393. <div class="col-sm-offset-4 col-sm-4">
  394. <button class="btn btn-primary" type="submit" name="submit"
  395. value="createadmin"><?= $PALANG['pAdminCreate_admin_button'] ?>
  396. </button>
  397. </div>
  398. </div>
  399. </form>
  400. </div>
  401. </div>
  402. <div class="row">
  403. <div class="col-12">
  404. <p class="text-success"><?= $setupMessage ?></p>
  405. </div>
  406. </div>
  407. <?php
  408. }
  409. ?>
  410. </div>
  411. <footer class="footer mt-5 bg-dark">
  412. <div class="container text-center">
  413. <a target="_blank" rel="noopener"
  414. href="https://github.com/postfixadmin/postfixadmin/blob/master/DOCUMENTS/">Documentation</a>
  415. //
  416. <a target="_blank" rel="noopener"
  417. href="https://github.com/postfixadmin/postfixadmin/">Postfix Admin</a>
  418. </div>
  419. </footer>
  420. </body>
  421. </html>
  422. <?php
  423. function _error_field($errors, $key)
  424. {
  425. if (!isset($errors[$key])) {
  426. return '';
  427. }
  428. return "<span style='color: #ff0000'>{$errors[$key]}</span>";
  429. }
  430. function create_admin($values)
  431. {
  432. define('POSTFIXADMIN_SETUP', 1); # avoids instant redirect to login.php after creating the admin
  433. $handler = new AdminHandler(1, 'setup.php');
  434. $formconf = $handler->webformConfig();
  435. if (!$handler->init($values['username'])) {
  436. return array(1, "", $handler->errormsg);
  437. }
  438. if (!$handler->set($values)) {
  439. return array(1, "", $handler->errormsg);
  440. }
  441. if (!$handler->save()) {
  442. return array(1, "", $handler->errormsg);
  443. }
  444. return array(
  445. 0,
  446. $handler->infomsg['success'],
  447. array(),
  448. );
  449. }
  450. /**
  451. * @return array like: ['info' => string[], 'warn' => string[], 'error' => string[] ]
  452. */
  453. function do_software_environment_check()
  454. {
  455. $CONF = Config::getInstance()->getAll();
  456. $warn = [];
  457. $error = [];
  458. $info = [];
  459. //
  460. // Check for availability functions
  461. //
  462. $f_phpversion = function_exists("phpversion");
  463. $f_apache_get_version = function_exists("apache_get_version");
  464. $m_pdo = extension_loaded("PDO");
  465. $m_pdo_mysql = extension_loaded("pdo_mysql");
  466. $m_pdo_pgsql = extension_loaded('pdo_pgsql');
  467. $m_pdo_sqlite = extension_loaded("pdo_sqlite");
  468. $f_session_start = function_exists("session_start");
  469. $f_preg_match = function_exists("preg_match");
  470. $f_mb_encode_mimeheader = function_exists("mb_encode_mimeheader");
  471. $file_local_config = realpath(__DIR__ . "/../config.local.php");
  472. // Fall back to looking in /etc/postfixadmin for config.local.php (Debian etc)
  473. // this check might produce a false positive if someone has a legacy PostfixAdmin installation.
  474. if (!file_exists($file_local_config) && is_dir('/etc/postfixadmin')) {
  475. if (file_exists('/etc/postfixadmin/config.local.php')) {
  476. $file_local_config = '/etc/postfixadmin/config.local.php';
  477. }
  478. }
  479. // Check for PHP version
  480. $phpversion = 'unknown-version';
  481. if ($f_phpversion) {
  482. if (version_compare(PHP_VERSION, '7.0.0', '<')) {
  483. $error[] = "Error: Depends on: PHP v7.0+. You must upgrade.";
  484. } else {
  485. $info[] = "PHP version - " . phpversion();
  486. }
  487. } else {
  488. $error[] = "Unable to check for PHP version. (PHP_VERSION not found?)";
  489. }
  490. // Check for Apache version
  491. if ($f_apache_get_version) {
  492. $info[] = "Webserver - " . apache_get_version();
  493. }
  494. $info[] = "Postfixadmin public url detected as " . getSiteUrl($_SERVER) . " use \$CONF['site_url'] to override";
  495. $info[] = "Postfixadmin installed at - " . realpath(__DIR__);
  496. $error_log_file = ini_get('error_log');
  497. if (file_exists($error_log_file) && is_writable($error_log_file)) {
  498. $info[] = "PHP Error log (check your php.ini for <code>error_log</code>) is - $error_log_file";
  499. }
  500. if (file_exists($error_log_file) && !is_writeable($error_log_file)) {
  501. $warn[] = "PHP Error log (<code>error_log</code>) is - $error_log_file, but is not writeable. Postfixadmin will be unable to log error(s). <a href='https://www.php.net/manual/en/errorfunc.configuration.php#ini.error-log'>PHP docs on configuring</a>.";
  502. }
  503. if (file_exists($file_local_config)) {
  504. $info[] = "config.local.php file found : " . realpath($file_local_config);
  505. } else {
  506. $warn[] = "Warning: config.local.php - NOT FOUND - It's Recommended to store your own settings in config.local.php instead of editing config.inc.php";
  507. }
  508. // Check if there is support for at least 1 database
  509. if (!($m_pdo && ($m_pdo_mysql || $m_pdo_sqlite || $m_pdo_pgsql))) {
  510. $error[] = "There is no database (PDO) support in your PHP setup, you MUST install a suitable PHP PDO extension (e.g. pdo_pgsql, pdo_mysql or pdo_sqlite).";
  511. }
  512. if (!$m_pdo_mysql && $CONF['database_type'] == 'mysql') {
  513. $error[] = "Database support - MySQL compatible extension (pdo_mysql) not found";
  514. }
  515. if (!$m_pdo_pgsql && $CONF['database_type'] == 'pgsql') {
  516. $error[] = "Database support - PostgreSQL (pdo_pgsql) extension not found";
  517. }
  518. if (!$m_pdo_sqlite && $CONF['database_type'] == 'sqlite') {
  519. $error[] = "Database support - SQLite (pdo_sqlite) PHP extension not found";
  520. }
  521. if (!$m_pdo_mysql && !$m_pdo_sqlite && !$m_pdo_pgsql) {
  522. $error[] = "No database support available (mysql, sqlite or postgresql)";
  523. }
  524. if (empty($CONF['encrypt'])) {
  525. $error[] = 'Password hashing - <code>$CONF["encrypt"]</code> is empty. Please check your config.inc.php / config.local.php file.';
  526. } else {
  527. $info[] = 'Password hashing - <code>$CONF["encrypt"] = ' . $CONF['encrypt'] . "</code>";
  528. try {
  529. $output = pacrypt('foobar');
  530. if ($output == 'foobar') {
  531. $warn[] = "You appear to be using a cleartext <code>\$CONF['encrypt']</code> setting. This is insecure. You have been warned. Your users deserve better";
  532. }
  533. $info[] = 'Password hashing - <code>$CONF["encrypt"]</code> - hash generation OK';
  534. } catch (\Exception $e) {
  535. $error[] = "Password Hashing - attempted to use configured encrypt backend (<code>{$CONF['encrypt']}</code>) triggered an error: " . $e->getMessage();
  536. if (is_writeable($error_log_file)) {
  537. $err = "Possibly helpful error_log messages - " . htmlspecialchars(
  538. implode("",
  539. array_slice(file($error_log_file), -4, 3) // last three lines, might fail miserably if error_log is large.
  540. )
  541. );
  542. $error[] = nl2br($err);
  543. }
  544. $error[] = "You will have problems logging into PostfixAdmin.";
  545. if (preg_match('/^dovecot:/', $CONF['encrypt'])) {
  546. $error[] = "Check out our Dovecot documentation at https://github.com/postfixadmin/postfixadmin/blob/master/DOCUMENTS/DOVECOT.txt, specifically around '3. Permissions'.";
  547. }
  548. }
  549. }
  550. if (empty($CONF['admin_email'])) {
  551. $warn[] = 'Admin Email - From address missing. Please add specify an admin_email in your config.inc.php or config.local.php e.g. <code>$CONF["admin_email"] = "Support Person &lt;support@yourdomain.com&gt;";</code>';
  552. }
  553. $link = null;
  554. $error_text = null;
  555. $dsn = 'Could not generate';
  556. try {
  557. $dsn = db_connection_string();
  558. $info[] = "Database connection configured OK (using PDO <code>$dsn</code>)";
  559. $link = db_connect();
  560. $info[] = "Database connection - Connected OK";
  561. } catch (Exception $e) {
  562. $error[] = "Database connection string : " . $dsn;
  563. $error[] = "Problem connecting to database, check database configuration (\$CONF['database_*'] entries in config.local.php)";
  564. $error[] = $e->getMessage();
  565. }
  566. // Session functions
  567. if ($f_session_start) {
  568. $info[] = "Depends on: PHP session support - OK";
  569. } else {
  570. $error[] = "Error: Depends on: PHP session support - NOT FOUND. (FreeBSD: portinstall php$phpversion-session ?)";
  571. }
  572. // PCRE functions
  573. if ($f_preg_match) {
  574. $info[] = "Depends on: PHP pcre support - OK";
  575. } else {
  576. $error[] = "Error: Depends on: PHP pcre support - NOT FOUND. (FreeBSD: portinstall php$phpversion-pcre)";
  577. }
  578. // Multibyte functions
  579. if ($f_mb_encode_mimeheader) {
  580. $info[] = "Depends on: PHP mbstring support - OK";
  581. } else {
  582. $error[] = "Error: Depends on: PHP mbstring support - NOT FOUND. (FreeBSD: portinstall php$phpversion-mbstring?)";
  583. }
  584. return ['error' => $error, 'warn' => $warn, 'info' => $info];
  585. }