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.

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