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.

475 lines
14 KiB

  1. <?php
  2. /**
  3. * Postfix Admin
  4. *
  5. * LICENSE
  6. * This source file is subject to the GPL license that is bundled with
  7. * this package in the file LICENSE.TXT.
  8. *
  9. * Further details on the project are available at :
  10. * http://www.postfixadmin.com or http://postfixadmin.sf.net
  11. *
  12. * @version $Id$
  13. * @license GNU GPL v2 or later.
  14. *
  15. * File: setup.php
  16. * Used to help ensure a server is setup appropriately during installation/setup.
  17. * After setup, it should be renamed or removed.
  18. *
  19. * Template File: -none-
  20. *
  21. * Template Variables: -none-
  22. *
  23. * Form POST \ GET Variables: -none-
  24. */
  25. require_once('common.php');
  26. $CONF['show_header_text'] = 'NO';
  27. $CONF['theme_logo'] = 'images/logo-default.png';
  28. $CONF['theme_css'] = 'css/default.css';
  29. require('templates/header.php');
  30. ?>
  31. <div class='setup'>
  32. <h2>Postfix Admin Setup Checker</h2>
  33. <p>Running software:
  34. <ul>
  35. <?php
  36. //
  37. // Check for availablilty functions
  38. //
  39. $f_phpversion = function_exists ("phpversion");
  40. $f_apache_get_version = function_exists ("apache_get_version");
  41. $f_get_magic_quotes_gpc = function_exists ("get_magic_quotes_gpc");
  42. $f_mysql_connect = function_exists ("mysql_connect");
  43. $f_mysqli_connect = function_exists ("mysqli_connect");
  44. $f_pg_connect = function_exists ("pg_connect");
  45. $f_session_start = function_exists ("session_start");
  46. $f_preg_match = function_exists ("preg_match");
  47. $f_mb_encode_mimeheader = function_exists ("mb_encode_mimeheader");
  48. $f_imap_open = function_exists ("imap_open");
  49. $file_config = file_exists (realpath ("./config.inc.php"));
  50. $error = 0;
  51. //
  52. // Check for PHP version
  53. //
  54. if ($f_phpversion == 1)
  55. {
  56. if (phpversion() < 5) {
  57. print "<li><b>Error: Depends on: PHP v5</b><br /></li>\n";
  58. $error += 1;
  59. }
  60. if (phpversion() >= 5) {
  61. $phpversion = 5;
  62. print "<li>PHP version " . phpversion () . "</li>\n";
  63. }
  64. }
  65. else
  66. {
  67. print "<li><b>Unable to check for PHP version. (missing function: phpversion())</b></li>\n";
  68. }
  69. //
  70. // Check for Apache version
  71. //
  72. if ($f_apache_get_version == 1)
  73. {
  74. print "<li>" . apache_get_version() . "</li>\n";
  75. }
  76. else
  77. {
  78. # not running on Apache.
  79. # However postfixadmin _is_ running, so obviously we are on a supported webserver ;-))
  80. # No need to confuse the user with a warning.
  81. }
  82. print "</ul>";
  83. print "<p>Checking for dependencies:\n";
  84. print "<ul>\n";
  85. //
  86. // Check for Magic Quotes
  87. //
  88. if ($f_get_magic_quotes_gpc == 1)
  89. {
  90. if (get_magic_quotes_gpc () == 0)
  91. {
  92. print "<li>Magic Quotes: Disabled - OK</li>\n";
  93. }
  94. else
  95. {
  96. print "<li><b>Warning: Magic Quotes: ON (internal workaround used)</b></li>\n";
  97. }
  98. }
  99. else
  100. {
  101. print "<li><b>Unable to check for Magic Quotes. (missing function: get_magic_quotes_gpc())</b></li>\n";
  102. }
  103. //
  104. // Check for config.inc.php
  105. //
  106. $config_loaded = 0;
  107. if ($file_config == 1)
  108. {
  109. print "<li>Depends on: presence config.inc.php - OK</li>\n";
  110. require_once('config.inc.php');
  111. $config_loaded = 1;
  112. require('config.inc.php');
  113. if(isset($CONF['configured'])) {
  114. if($CONF['configured'] == TRUE) {
  115. print "<li>Checking \$CONF['configured'] - OK\n";
  116. } else {
  117. print "<li><b>Warning: \$CONF['configured'] is 'false'.<br>\n";
  118. print "You must edit your config.inc.php and change this to true (this indicates you've created the database and user)</b>\n";
  119. }
  120. }
  121. }
  122. else
  123. {
  124. print "<li><b>Error: Depends on: presence config.inc.php - NOT FOUND</b><br /></li>\n";
  125. print "Create the file, and edit as appropriate (e.g. select database type etc)<br />";
  126. print "For example:<br />\n";
  127. print "<code><pre>cp config.inc.php.sample config.inc.php</pre></code>\n";
  128. $error =+ 1;
  129. }
  130. //
  131. // Check if there is support for at least 1 database
  132. //
  133. if (($f_mysql_connect == 0) and ($f_mysqli_connect == 0) and ($f_pg_connect == 0))
  134. {
  135. print "<li><b>Error: There is no database support in your PHP setup</b><br />\n";
  136. print "To install MySQL 3.23 or 4.0 support on FreeBSD:<br />\n";
  137. print "<pre>% cd /usr/ports/databases/php$phpversion-mysql/\n";
  138. print "% make clean install\n";
  139. print " - or with portupgrade -\n";
  140. print "% portinstall php$phpversion-mysql</pre>\n";
  141. if ($phpversion >= 5)
  142. {
  143. print "To install MySQL 4.1 support on FreeBSD:<br />\n";
  144. print "<pre>% cd /usr/ports/databases/php5-mysqli/\n";
  145. print "% make clean install\n";
  146. print " - or with portupgrade -\n";
  147. print "% portinstall php5-mysqli</pre>\n";
  148. }
  149. print "To install PostgreSQL support on FreeBSD:<br />\n";
  150. print "<pre>% cd /usr/ports/databases/php$phpversion-pgsql/\n";
  151. print "% make clean install\n";
  152. print " - or with portupgrade -\n";
  153. print "% portinstall php$phpversion-pgsql</pre></li>\n";
  154. $error =+ 1;
  155. }
  156. //
  157. // MySQL 3.23, 4.0 functions
  158. //
  159. if ($f_mysql_connect == 1)
  160. {
  161. print "<li>Depends on: MySQL 3.23, 4.0 - OK</li>\n";
  162. }
  163. //
  164. // MySQL 4.1 functions
  165. //
  166. if ($phpversion >= 5)
  167. {
  168. if ($f_mysqli_connect == 1)
  169. {
  170. print "<li>Depends on: MySQL 4.1 - OK\n";
  171. if ( !($config_loaded && $CONF['database_type'] == 'mysqli') ) {
  172. print "(change the database_type to 'mysqli' in config.inc.php!!)\n";
  173. }
  174. print "</li>";
  175. }
  176. }
  177. //
  178. // PostgreSQL functions
  179. //
  180. if ($f_pg_connect == 1)
  181. {
  182. print "<li>Depends on: PostgreSQL - OK \n";
  183. if ( !($config_loaded && $CONF['database_type'] == 'pgsql') ) {
  184. print "(change the database_type to 'pgsql' in config.inc.php!!)\n";
  185. }
  186. print "</li>";
  187. }
  188. //
  189. // Database connection
  190. //
  191. if ($config_loaded) {
  192. list ($link, $error_text) = db_connect(TRUE);
  193. if ($error_text == "") {
  194. print "<li>Testing database connection - OK - {$CONF['database_type']}://{$CONF['database_user']}:xxxxx@{$CONF['database_host']}/{$CONF['database_name']}</li>";
  195. } else {
  196. print "<li><b>Error: Can't connect to database</b><br />\n";
  197. print "Please edit the \$CONF['database_*'] parameters in config.inc.php.\n";
  198. print "$error_text</li>\n";
  199. $error ++;
  200. }
  201. }
  202. //
  203. // Session functions
  204. //
  205. if ($f_session_start == 1)
  206. {
  207. print "<li>Depends on: session - OK</li>\n";
  208. }
  209. else
  210. {
  211. print "<li><b>Error: Depends on: session - NOT FOUND</b><br />\n";
  212. print "To install session support on FreeBSD:<br />\n";
  213. print "<pre>% cd /usr/ports/www/php$phpversion-session/\n";
  214. print "% make clean install\n";
  215. print " - or with portupgrade -\n";
  216. print "% portinstall php$phpversion-session</pre></li>\n";
  217. $error =+ 1;
  218. }
  219. //
  220. // PCRE functions
  221. //
  222. if ($f_preg_match == 1)
  223. {
  224. print "<li>Depends on: pcre - OK</li>\n";
  225. }
  226. else
  227. {
  228. print "<li><b>Error: Depends on: pcre - NOT FOUND</b><br />\n";
  229. print "To install pcre support on FreeBSD:<br />\n";
  230. print "<pre>% cd /usr/ports/devel/php$phpversion-pcre/\n";
  231. print "% make clean install\n";
  232. print " - or with portupgrade -\n";
  233. print "% portinstall php$phpversion-pcre</pre></li>\n";
  234. $error =+ 1;
  235. }
  236. //
  237. // Multibyte functions
  238. //
  239. if ( $f_mb_encode_mimeheader == 1 )
  240. {
  241. print "<li>Depends on: multibyte string - OK</li>\n";
  242. }
  243. else
  244. {
  245. print "<li><b>Error: Depends on: multibyte string - NOT FOUND</b><br />\n";
  246. print "To install multibyte string support, install php$phpversion-mbstring</li>\n";
  247. $error =+ 1;
  248. }
  249. //
  250. // Imap functions
  251. //
  252. if ( $f_imap_open == 1)
  253. {
  254. print "<li>Depends on: IMAP functions - OK</li>\n";
  255. }
  256. else
  257. {
  258. print "<li><b>Warning: Depends on: IMAP functions - NOT FOUND</b><br />\n";
  259. print "To install IMAP support, install php$phpversion-imap<br />\n";
  260. print "Without IMAP support, you won't be able to create subfolders when creating mailboxes.</li>\n";
  261. # $error =+ 1;
  262. }
  263. print "</ul>";
  264. if ($error != 0)
  265. {
  266. print "<p><b>Please fix the errors listed above.</b></p>";
  267. }
  268. else
  269. {
  270. print "<p>Everything seems fine... attempting to create/update database structure</p>\n";
  271. require_once('upgrade.php');
  272. $pAdminCreate_admin_username_text = $PALANG['pAdminCreate_admin_username_text'];
  273. $pAdminCreate_admin_password_text = "";
  274. $tUsername = '';
  275. $tMessage = '';
  276. $lostpw_error = 0;
  277. $setuppw = "";
  278. if (isset($CONF['setup_password'])) $setuppw = $CONF['setup_password'];
  279. if (safepost("form") == "setuppw") {
  280. # "setup password" form submitted
  281. if (safepost('setup_password') != safepost('setup_password2')) {
  282. $tMessage = "The two passwords differ!";
  283. $lostpw_error = 1;
  284. } else {
  285. list ($lostpw_error, $lostpw_result) = check_setup_password(safepost('setup_password'), 1);
  286. $tMessage = $lostpw_result;
  287. $setuppw = "changed";
  288. }
  289. } elseif (safepost("form") == "createadmin") {
  290. # "create admin" form submitted
  291. list ($pw_check_error, $pw_check_result) = check_setup_password(safepost('setup_password'));
  292. if ($pw_check_result != 'pass_OK') {
  293. $error += 1;
  294. $tMessage = $pw_check_result;
  295. }
  296. if($error == 0 && $pw_check_result == 'pass_OK') {
  297. if (isset ($_POST['fUsername'])) $fUsername = escape_string ($_POST['fUsername']);
  298. if (isset ($_POST['fPassword'])) $fPassword = escape_string ($_POST['fPassword']);
  299. if (isset ($_POST['fPassword2'])) $fPassword2 = escape_string ($_POST['fPassword2']);
  300. // XXX need to ensure domains table includes an 'ALL' entry.
  301. $table_domain = table_by_key('domain');
  302. $r = db_query("SELECT * FROM $table_domain WHERE domain = 'ALL'");
  303. if($r['rows'] == 0) {
  304. db_insert($table_domain, array('domain' => 'ALL')); // all other fields should default through the schema.
  305. }
  306. list ($error, $tMessage, $pAdminCreate_admin_username_text, $pAdminCreate_admin_password_text) = create_admin($fUsername, $fPassword, $fPassword2, array('ALL'), TRUE);
  307. if ($error != 0) {
  308. if (isset ($_POST['fUsername'])) $tUsername = escape_string ($_POST['fUsername']);
  309. }
  310. }
  311. }
  312. if ( ($setuppw == "" || $setuppw == "changeme" || safeget("lostpw") == 1 || $lostpw_error != 0) /* && $_SERVER['REQUEST_METHOD'] != "POST" */ ) {
  313. # show "create setup password" form
  314. ?>
  315. <div class="standout"><?php print $tMessage; ?></div>
  316. <div id="edit_form">
  317. <form name="setuppw" method="post" action="setup.php">
  318. <input type="hidden" name="form" value="setuppw" />
  319. <table>
  320. <td colspan="3"><h3>Change setup password</h3></td>
  321. </tr>
  322. <tr>
  323. <td>Setup password</td>
  324. <td><input class="flat" type="password" name="setup_password" value="" /></td>
  325. <td></td>
  326. </tr>
  327. <tr>
  328. <td>Setup password (again)</td>
  329. <td><input class="flat" type="password" name="setup_password2" value="" /></td>
  330. <td></td>
  331. </tr>
  332. <tr>
  333. <td colspan="3" class="hlp_center"><input class="button" type="submit" name="submit" value="Generate password hash" /></td>
  334. </tr>
  335. </table>
  336. </form>
  337. </div>
  338. <?php
  339. } elseif ($_SERVER['REQUEST_METHOD'] == "GET" || $error != 0 || $lostpw_error == 0) {
  340. ?>
  341. <div class="standout"><?php print $tMessage; ?></div>
  342. <div id="edit_form">
  343. <form name="create_admin" method="post">
  344. <input type="hidden" name="form" value="createadmin" />
  345. <table>
  346. <td colspan="3"><h3>Create superadmin account</h3></td>
  347. </tr>
  348. <tr>
  349. <td>Setup password</td>
  350. <td><input class="flat" type="password" name="setup_password" value="" /></td>
  351. <td><a href="setup.php?lostpw=1">Lost password?</a></td>
  352. </tr>
  353. <tr>
  354. <td><?php print $PALANG['pAdminCreate_admin_username'] . ":"; ?></td>
  355. <td><input class="flat" type="text" name="fUsername" value="<?php print $tUsername; ?>" /></td>
  356. <td><?php print $pAdminCreate_admin_username_text; ?></td>
  357. </tr>
  358. <tr>
  359. <td><?php print $PALANG['pAdminCreate_admin_password'] . ":"; ?></td>
  360. <td><input class="flat" type="password" name="fPassword" /></td>
  361. <td><?php print $pAdminCreate_admin_password_text; ?></td>
  362. </tr>
  363. <tr>
  364. <td><?php print $PALANG['pAdminCreate_admin_password2'] . ":"; ?></td>
  365. <td><input class="flat" type="password" name="fPassword2" /></td>
  366. <td>&nbsp;</td>
  367. </tr>
  368. <tr>
  369. <td colspan="3" class="hlp_center"><input class="button" type="submit" name="submit" value="<?php print $PALANG['pAdminCreate_admin_button']; ?>" /></td>
  370. </tr>
  371. </table>
  372. </form>
  373. </div>
  374. <?php
  375. }
  376. print "<b>Since version 2.3 there is no requirement to delete setup.php!</b><br />\n";
  377. print "<b>Check the config.inc.php file for any other settings that you might need to change!<br />\n";
  378. }
  379. ?>
  380. </div>
  381. </body>
  382. </html>
  383. <?php
  384. function generate_setup_password_salt() {
  385. $salt = time() . '*' . $_SERVER['REMOTE_ADDR'] . '*' . mt_rand(0,60000);
  386. $salt = md5($salt);
  387. return $salt;
  388. }
  389. function encrypt_setup_password($password, $salt) {
  390. return $salt . ':' . sha1($salt . ':' . $password);
  391. }
  392. /*
  393. returns: array(
  394. 'error' => 0 (or 1),
  395. 'message => text
  396. )
  397. */
  398. function check_setup_password($password, $lostpw_mode = 0) {
  399. global $CONF;
  400. $error = 1; # be pessimistic
  401. $setuppw = "";
  402. if (isset($CONF['setup_password'])) $setuppw = $CONF['setup_password'];
  403. list($confsalt, $confpass, $trash) = explode(':', $setuppw . '::');
  404. $pass = encrypt_setup_password($password, $confsalt);
  405. if ($password == "" ) { # no password specified?
  406. $result = "Setup password must be specified<br />If you didn't set up a setup password yet, enter the password you want to use.";
  407. } elseif (strlen($password) < $CONF['min_password_length']) { # password too short?
  408. $result = "The setup password you entered is too short. Please choose a better one.";
  409. } elseif ($pass == $setuppw && $lostpw_mode == 0) { # correct passsword (and not asking for a new password)
  410. $result = "pass_OK";
  411. $error = 0;
  412. } else {
  413. $pass = encrypt_setup_password($password, generate_setup_password_salt());
  414. $result = "";
  415. if ($lostpw_mode == 1) {
  416. $error = 0; # non-matching password is expected when the user asks for a new password
  417. } else {
  418. $result = '<p><b>Setup password not specified correctly</b></p>';
  419. }
  420. $result .= '<p>If you want to use the password you entered as setup password, edit config.inc.php and set</p>';
  421. $result .= "<pre>\$CONF['setup_password'] = '$pass';</pre>";
  422. }
  423. return array ($error, $result);
  424. }
  425. /* vim: set expandtab softtabstop=4 tabstop=4 shiftwidth=4: */
  426. ?>