2007-03-24 08:27:00 +01:00
< ? php
2017-02-14 10:23:17 +01:00
/**
* Postfix Admin
*
* LICENSE
* This source file is subject to the GPL license that is bundled with
* this package in the file LICENSE . TXT .
*
* Further details on the project are available at http :// postfixadmin . sf . net
*
* @ version $Id $
* @ license GNU GPL v2 or later .
*
2007-09-30 17:53:54 +02:00
* File : setup . php
* Used to help ensure a server is setup appropriately during installation / setup .
*/
2007-10-07 19:23:29 +02:00
2009-10-20 21:25:20 +02:00
define ( 'POSTFIXADMIN' , 1 ); # by defining it here, common.php will not start a session.
2019-08-13 10:00:21 +02:00
require_once ( dirname ( __FILE__ ) . '/common.php' ); # make sure correct common.php is used.
2007-10-07 19:23:29 +02:00
$CONF [ 'show_header_text' ] = 'NO' ;
2019-10-19 17:33:18 +02:00
$CONF [ 'theme_favicon' ] = 'images/favicon.ico' ;
2008-04-07 01:33:48 +02:00
$CONF [ 'theme_logo' ] = 'images/logo-default.png' ;
$CONF [ 'theme_css' ] = 'css/default.css' ;
2018-01-25 21:27:09 +01:00
require ( dirname ( __FILE__ ) . '/../templates/header.php' );
2007-03-24 08:27:00 +01:00
?>
2007-10-07 19:23:29 +02:00
< div class = 'setup' >
2019-08-13 10:00:21 +02:00
< h2 > Postfix Admin Setup Checker </ h2 >
< p > Running software :
< ul >
< ? php
//
// Check for availability functions
//
$f_phpversion = function_exists ( " phpversion " );
$f_apache_get_version = function_exists ( " apache_get_version " );
2020-04-10 23:30:48 +02:00
$m_pdo = extension_loaded ( " PDO " );
$m_pdo_mysql = extension_loaded ( " pdo_mysql " );
$m_pdo_pgsql = extension_loaded ( 'pdo_pgsql' );
$m_pdo_sqlite = extension_loaded ( " pdo_sqlite " );
2019-08-13 10:00:21 +02:00
$f_session_start = function_exists ( " session_start " );
$f_preg_match = function_exists ( " preg_match " );
$f_mb_encode_mimeheader = function_exists ( " mb_encode_mimeheader " );
$f_imap_open = function_exists ( " imap_open " );
$file_config = file_exists ( realpath ( " ./../config.inc.php " ));
$file_local_config = file_exists ( realpath ( " ./../config.local.php " ));
// Fall back to looking in /etc/postfixadmin for config.local.php (Debian etc)
if ( ! $file_local_config && is_dir ( '/etc/postfixadmin' )) {
$file_local_config = file_exists ( '/etc/postfixadmin/config.local.php' );
}
2019-01-01 21:38:51 +01:00
2019-08-13 10:00:21 +02:00
$error = 0 ;
$errormsg = array ();
//
// Check for PHP version
//
$phpversion = 'unknown-version' ;
if ( $f_phpversion == 1 ) {
if ( version_compare ( phpversion (), '5' , '<' )) {
print " <li><b>Error: Depends on: PHP v5+</b><br /></li> \n " ;
$error += 1 ;
} elseif ( version_compare ( phpversion (), '7.0' ) < 0 ) {
$phpversion = 5 ;
print " <li><b>Recommended PHP version: >= 7.0, you have " . phpversion () . " ; you should upgrade.</b></li> \n " ;
} else {
print " <li>PHP version " . phpversion () . " - Good</li> \n " ;
}
} else {
print " <li><b style='color: red'>DANGER</b> Unable to check for PHP version. (missing function: phpversion())</b></li> \n " ;
$error ++ ;
}
2007-03-24 08:27:00 +01:00
2019-08-13 10:00:21 +02:00
//
// Check for Apache version
//
if ( $f_apache_get_version == 1 ) {
print " <li> " . apache_get_version () . " </li> \n " ;
} else {
# not running on Apache.
# However postfixadmin _is_ running, so obviously we are on a supported webserver ;-))
# No need to confuse the user with a warning.
}
2007-10-07 19:23:29 +02:00
2019-08-13 10:00:21 +02:00
print " </ul> " ;
print " <p>Checking environment: \n " ;
print " <ul> \n " ;
//
// Check for config.local.php
//
if ( $file_local_config == 1 ) {
print " <li>Depends on: presence config.local.php - Found</li> \n " ;
} else {
print " <li><b>Warning: config.local.php - NOT FOUND</b><br /></li> \n " ;
print " It's Recommended to store your own settings in config.local.php instead of editing config.inc.php<br /> " ;
print " Create the file, and edit as appropriate (e.g. select database type etc)<br /> " ;
}
2018-12-28 20:15:38 +01:00
2019-08-13 10:00:21 +02:00
// Check if there is support for at least 1 database
2020-11-09 22:15:06 +01:00
if (( $m_pdo == 0 ) and ( $m_pdo_mysql == 0 ) and ( $m_pdo_sqlite == 0 ) and ( $m_pdo_pgsql == 0 ) ) {
2020-04-10 23:30:48 +02:00
print " <li><b>Error: There is no database (PDO) support in your PHP setup</b><br /> \n " ;
print " <span style='color: red'>
You MUST install a suitable PHP PDO extension ( e . g . pdo_pgsql , pdo_mysql or pdo_sqlite ) .
</ span > \n </ li > " ;
2019-08-13 10:00:21 +02:00
$error += 1 ;
}
2007-03-24 08:27:00 +01:00
2020-04-10 23:30:48 +02:00
if ( $m_pdo_mysql == 1 ) {
print " <li>Database - PDO MySQL - Found</li> " ;
2019-08-13 10:00:21 +02:00
} else {
2020-04-10 23:30:48 +02:00
print " <li>Database - MySQL (pdo_mysql) extension not found</li> " ;
2019-08-13 10:00:21 +02:00
}
2007-12-14 01:05:54 +01:00
2019-08-13 10:00:21 +02:00
//
// PostgreSQL functions
//
2020-04-10 23:30:48 +02:00
if ( $m_pdo_pgsql == 1 ) {
print " <li>Database : PDO PostgreSQL - Found \n " ;
2019-08-13 10:00:21 +02:00
if ( Config :: read_string ( 'database_type' ) != 'pgsql' ) {
print " <br>(change the database_type to 'pgsql' in config.local.php if you want to use PostgreSQL) \n " ;
}
print " </li> " ;
} else {
2020-04-10 23:30:48 +02:00
print " <li>Database - PostgreSQL (pdo_pgsql) extension not found</li> " ;
2019-08-13 10:00:21 +02:00
}
2008-06-11 00:34:25 +02:00
2020-04-10 23:30:48 +02:00
if ( $m_pdo_sqlite == 1 ) {
print " <li>Database : PDO SQLite - Found \n " ;
2019-08-13 10:00:21 +02:00
if ( Config :: read_string ( 'database_type' ) != 'sqlite' ) {
print " <br>(change the database_type to 'sqlite' in config.local.php if you want to use SQLite) \n " ;
}
print " </li> " ;
} else {
2020-04-10 23:30:48 +02:00
print " <li>Database - SQLite (pdo_sqlite) extension not found</li> " ;
2019-08-13 10:00:21 +02:00
}
2008-06-11 00:34:25 +02:00
2019-08-13 10:00:21 +02:00
//
// Database connection
//
$link = null ;
$error_text = null ;
2008-06-11 00:34:25 +02:00
2019-08-13 10:00:21 +02:00
try {
$link = db_connect ();
} catch ( Exception $e ) {
$error_text = $e -> getMessage ();
}
2008-06-11 00:34:25 +02:00
2019-08-13 10:00:21 +02:00
if ( ! empty ( $link ) && $error_text == " " ) {
print " <li>Testing database connection (using { $CONF [ 'database_type' ] } ) - Success</li> " ;
} else {
print " <li><b style='color: red'>Error: Can't connect to database</b><br /> \n " ;
print " Please check the \$ CONF['database_*'] parameters in config.local.php.<br /> \n " ;
print " $error_text </li> \n " ;
$error ++ ;
}
2008-06-11 00:34:25 +02:00
2019-08-13 10:00:21 +02:00
//
// Session functions
//
if ( $f_session_start == 1 ) {
print " <li>Depends on: session - OK</li> \n " ;
} else {
print " <li><b>Error: Depends on: session - NOT FOUND</b><br /> \n " ;
print " To install session support on FreeBSD:<br /> \n " ;
print " <pre>% cd /usr/ports/www/php $phpversion -session/ \n " ;
print " % make clean install \n " ;
print " - or with portupgrade - \n " ;
print " % portinstall php $phpversion -session</pre></li> \n " ;
$error += 1 ;
}
2008-06-11 00:34:25 +02:00
2019-08-13 10:00:21 +02:00
//
// PCRE functions
//
if ( $f_preg_match == 1 ) {
print " <li>Depends on: pcre - Found</li> \n " ;
} else {
print " <li><b>Error: Depends on: pcre - NOT FOUND</b><br /> \n " ;
print " To install pcre support on FreeBSD:<br /> \n " ;
print " <pre>% cd /usr/ports/devel/php $phpversion -pcre/ \n " ;
print " % make clean install \n " ;
print " - or with portupgrade - \n " ;
print " % portinstall php $phpversion -pcre</pre></li> \n " ;
$error += 1 ;
}
2008-06-11 00:34:25 +02:00
2019-08-13 10:00:21 +02:00
//
// Multibyte functions
//
if ( $f_mb_encode_mimeheader == 1 ) {
print " <li>Depends on: multibyte string - Found</li> \n " ;
} else {
2020-04-10 23:30:48 +02:00
print " <li><b>Error: Depends on: multibyte string - mbstring extension missing.</b><br /> \n " ;
print " To install multibyte string support, perhaps install php $phpversion -mbstring</li> \n " ;
2019-08-13 10:00:21 +02:00
$error += 1 ;
}
2007-10-07 19:23:29 +02:00
2019-08-13 10:00:21 +02:00
//
// Imap functions
//
if ( $f_imap_open == 1 ) {
print " <li>IMAP functions - Found</li> \n " ;
} else {
2020-04-10 23:30:48 +02:00
print " <li><b>Warning: Optional dependency 'imap' extension missing</b><br /> \n " ;
print " To install IMAP support, perhaps install php $phpversion -imap<br /> \n " ;
2019-08-13 10:00:21 +02:00
print " Without IMAP support, you won't be able to create subfolders when creating mailboxes.</li> \n " ;
}
2009-04-08 22:16:05 +02:00
2019-08-13 10:00:21 +02:00
//
// If PHP <7.0, require random_compat works. Currently we bundle it via the Phar extension.
//
2009-04-08 22:16:05 +02:00
2019-08-13 10:00:21 +02:00
if ( version_compare ( phpversion (), " 7.0 " , '<' )
&& ! extension_loaded ( 'Phar' )
&& $CONF [ 'configured' ]
&& $CONF [ 'encrypt' ] == 'php_crypt' ) {
print " <li>PHP before 7.0 requires 'Phar' extension support for <strong>secure</strong> random_int() function fallback " ;
print " <br/>Either enable the 'Phar' extension, or install the random_compat library files from <a href='https://github.com/paragonie/random_compat'>https://github.com/paragonie/random_compat</a> and include/require them from functions.inc.php " ;
print " <br/>PostfixAdmin has bundled lib/random_compat.phar but it's not usable on your installation due to the missing Phar extension.</li> " ;
$error += 1 ;
2009-04-08 22:16:05 +02:00
}
2011-12-20 02:06:49 +01:00
2019-08-13 10:00:21 +02:00
print " </ul> " ;
2011-12-20 02:06:49 +01:00
2009-04-08 22:16:05 +02:00
if ( $error != 0 ) {
2019-08-13 10:00:21 +02:00
print " <p><b>Please fix the errors listed above.</b></p> " ;
2015-05-18 22:18:09 +02:00
} else {
2019-08-13 10:19:22 +02:00
print " <p>Everything seems fine... attempting to create/update database structure</p> \n " ;
require_once ( dirname ( __FILE__ ) . '/upgrade.php' );
2009-04-08 22:16:05 +02:00
2019-08-13 10:19:22 +02:00
$tUsername = '' ;
$setupMessage = '' ;
$lostpw_error = 0 ;
2009-05-02 22:24:58 +02:00
2019-08-13 10:19:22 +02:00
$setuppw = " " ;
if ( isset ( $CONF [ 'setup_password' ])) {
$setuppw = $CONF [ 'setup_password' ];
2019-08-13 10:00:21 +02:00
}
2020-02-23 21:03:35 +01:00
if ( safepost ( " form " ) === " setuppw " ) {
2019-08-13 10:19:22 +02:00
# "setup password" form submitted
if ( safepost ( 'setup_password' ) != safepost ( 'setup_password2' )) {
$setupMessage = " The two passwords differ! " ;
$lostpw_error = 1 ;
} else {
list ( $lostpw_error , $lostpw_result ) = check_setup_password ( safepost ( 'setup_password' ), 1 );
$setupMessage = $lostpw_result ;
$setuppw = " changed " ;
}
} elseif ( safepost ( " form " ) == " createadmin " ) {
# "create admin" form submitted
list ( $pw_check_error , $pw_check_result ) = check_setup_password ( safepost ( 'setup_password' ));
if ( $pw_check_result != 'pass_OK' ) {
$error += 1 ;
$setupMessage = $pw_check_result ;
2019-08-13 10:00:21 +02:00
}
2019-08-13 10:19:22 +02:00
if ( $error == 0 && $pw_check_result == 'pass_OK' ) {
// XXX need to ensure domains table includes an 'ALL' entry.
$table_domain = table_by_key ( 'domain' );
$rows = db_query_all ( " SELECT * FROM $table_domain WHERE domain = 'ALL' " );
if ( empty ( $rows )) {
db_insert ( 'domain' , array ( 'domain' => 'ALL' , 'description' => '' , 'transport' => '' )); // all other fields should default through the schema.
}
$values = array (
'username' => safepost ( 'username' ),
'password' => safepost ( 'password' ),
'password2' => safepost ( 'password2' ),
'superadmin' => 1 ,
'domains' => array (),
'active' => 1 ,
);
list ( $error , $setupMessage , $errormsg ) = create_admin ( $values );
if ( $error != 0 ) {
$tUsername = htmlentities ( $values [ 'username' ]);
} else {
$setupMessage .= " <p>You are done with your basic setup. " ;
$setupMessage .= " <p><b>You can now <a href='login.php'>login to PostfixAdmin</a> using the account you just created.</b> " ;
}
}
}
2019-08-13 10:00:21 +02:00
2019-08-13 10:19:22 +02:00
if ( ! isset ( $_SERVER [ 'HTTPS' ])) {
echo " <h2>Warning: connection not secure, switch to https if possible</h2> " ;
2019-08-13 10:24:30 +02:00
} ?>
2019-08-13 10:00:21 +02:00
< div class = " standout " >< ? php print $setupMessage ; ?> </div>
2019-08-13 10:19:22 +02:00
< ? php
$change = " Change " ;
if ( Config :: read_string ( 'setup_password' ) == '' || Config :: read_string ( 'setup_password' ) == 'changeme' ) {
echo <<< EOF
< p >< strong > For a new installation , you need to generate a 'setup_password' to go into your config . local . php file .</ strong ></ p >
< p > You can use the form below , or run something like < pre > php - r 'echo "somesalt:" . sha1("somesalt:" . "password");' </ pre > in a shell , after changing the salt .< p >
EOF ;
$change = " Generate " ;
2019-08-13 10:24:30 +02:00
} ?>
2019-08-13 10:19:22 +02:00
< h2 >< ? = $change ?> $CONF['setup_password']</h2>
2019-08-13 10:00:21 +02:00
< div id = " edit_form " >
< form name = " setuppw " method = " post " action = " setup.php " >
< input type = " hidden " name = " form " value = " setuppw " />
< table >
< tr >
< td >< label for = " setup_password " > Setup password </ label ></ td >
2019-08-13 10:19:22 +02:00
< td >< input class = " flat " type = " password " name = " setup_password " minlength = 5 id = " setup_password " value = " " /></ td >
2019-08-13 10:00:21 +02:00
< td ></ td >
</ tr >
< tr >
< td >< label for = " setup_password2 " > Setup password ( again ) </ label ></ td >
2019-08-13 10:19:22 +02:00
< td >< input class = " flat " type = " password " name = " setup_password2 " minlength = 5 id = " setup_password2 " value = " " /></ td >
2019-08-13 10:00:21 +02:00
< td ></ td >
</ tr >
< tr >
< td colspan = " 3 " class = " hlp_center " >< input class = " button " type = " submit " name = " submit " value = " Generate password hash " /></ td >
</ tr >
</ table >
</ form >
</ div >
< ? php
2019-08-13 10:19:22 +02:00
if ( $change != 'Generate' ) { ?>
2019-08-13 10:00:21 +02:00
2019-08-13 10:19:22 +02:00
< h2 > Add a SuperAdmin Account </ h2 >
< div id = " edit_form " >
< form name = " create_admin " method = " post " >
< input type = " hidden " name = " form " value = " createadmin " />
< table >
2019-08-13 10:00:21 +02:00
< tr >
2019-08-13 10:19:22 +02:00
< td >< label for = " setup_password " > Setup password </ label ></ td >
< td >< input id = setup_password class = " flat " type = " password " name = " setup_password " value = " " /></ td >
< td >< ? = _error_field ( $errormsg , 'setup_password' ); ?> <?php print $PALANG['setup_password'] ?></td>
2019-08-13 10:00:21 +02:00
</ tr >
2019-08-13 10:19:22 +02:00
< tr >
< td >< label for = " username " >< ? php print $PALANG [ 'admin' ] . " : " ; ?> </label></td>
< td >< input id = " username " class = " flat " type = " text " name = " username " value = " <?php print $tUsername ; ?> " /></ td >
< td >< ? = _error_field ( $errormsg , 'username' ); ?> <?php print $PALANG['email_address'] ?></td>
</ tr >
< tr >
< td >< label for = " password " >< ? php print $PALANG [ 'password' ] . " : " ; ?> </label></td>
2020-02-23 21:03:35 +01:00
< td >< input id = " password " class = " flat " type = " password " name = " password " autocomplete = " new-password " /></ td >
2019-08-13 10:19:22 +02:00
< td >< ? = _error_field ( $errormsg , 'password' ); ?> </td>
</ tr >
< tr >
< td >< label for = " password2 " >< ? php print $PALANG [ 'password_again' ] . " : " ; ?> </label></td>
2020-02-23 21:03:35 +01:00
< td >< input id = " password2 " class = " flat " type = " password " name = " password2 " autocomplete = " new-password " /></ td >
2019-08-13 10:19:22 +02:00
< td >< ? = _error_field ( $errormsg , 'password2' ); ?> </td>
</ tr >
< tr >
< td colspan = " 3 " class = " hlp_center " >< input class = " button " type = " submit " name = " submit " value = " <?php print $PALANG['pAdminCreate_admin_button'] ; ?> " /></ td >
</ tr >
</ table >
</ form >
</ div >
2019-08-13 10:00:21 +02:00
2019-08-13 10:19:22 +02:00
< ? php
}
2019-08-13 10:00:21 +02:00
} ?>
2019-01-01 21:38:51 +01:00
< p > Since version 2.3 there is no requirement to delete setup . php </ p >
< p > Check the config . inc . php file for any other settings that you may need to change .</ p >
2019-08-13 10:19:22 +02:00
2007-10-07 19:23:29 +02:00
</ div >
2007-03-24 08:27:00 +01:00
</ body >
</ html >
2009-02-15 16:02:26 +01:00
< ? php
2009-04-16 01:32:45 +02:00
2019-08-13 10:24:30 +02:00
function _error_field ( $errors , $key ) {
2018-01-26 15:45:57 +01:00
if ( ! isset ( $errors [ $key ])) {
2017-02-14 10:23:17 +01:00
return '' ;
}
return " <span style='color: red'> { $errors [ $key ] } </span> " ;
}
2019-08-13 10:24:30 +02:00
function generate_setup_password_salt () {
2018-01-26 15:45:57 +01:00
$salt = time () . '*' . $_SERVER [ 'REMOTE_ADDR' ] . '*' . mt_rand ( 0 , 60000 );
2009-04-16 01:32:45 +02:00
$salt = md5 ( $salt );
return $salt ;
}
2019-08-13 10:24:30 +02:00
function encrypt_setup_password ( $password , $salt ) {
2009-04-16 01:32:45 +02:00
return $salt . ':' . sha1 ( $salt . ':' . $password );
}
2009-05-02 22:24:58 +02:00
/*
returns : array (
'error' => 0 ( or 1 ),
' message => text
)
*/
2019-08-13 10:24:30 +02:00
function check_setup_password ( $password , $lostpw_mode = 0 ) {
2009-04-16 01:32:45 +02:00
global $CONF ;
2009-05-02 22:24:58 +02:00
$error = 1 ; # be pessimistic
2009-04-16 01:32:45 +02:00
$setuppw = " " ;
2018-01-26 15:45:57 +01:00
if ( isset ( $CONF [ 'setup_password' ])) {
$setuppw = $CONF [ 'setup_password' ];
}
2009-04-16 01:32:45 +02:00
list ( $confsalt , $confpass , $trash ) = explode ( ':' , $setuppw . '::' );
$pass = encrypt_setup_password ( $password , $confsalt );
2009-05-02 22:24:58 +02:00
2011-09-25 20:39:20 +02:00
$validpass = validate_password ( $password );
2018-01-26 15:45:57 +01:00
if ( $password == " " ) { # no password specified?
2009-05-02 22:24:58 +02:00
$result = " Setup password must be specified<br />If you didn't set up a setup password yet, enter the password you want to use. " ;
2011-09-25 20:39:20 +02:00
} elseif ( count ( $validpass ) > 0 ) {
$result = $validpass [ 0 ]; # TODO: honor all error messages, not only the first one
2009-05-02 22:24:58 +02:00
} elseif ( $pass == $setuppw && $lostpw_mode == 0 ) { # correct passsword (and not asking for a new password)
2009-04-16 01:32:45 +02:00
$result = " pass_OK " ;
2009-05-02 22:24:58 +02:00
$error = 0 ;
2009-04-16 01:32:45 +02:00
} else {
$pass = encrypt_setup_password ( $password , generate_setup_password_salt ());
2009-05-02 22:24:58 +02:00
$result = " " ;
if ( $lostpw_mode == 1 ) {
$error = 0 ; # non-matching password is expected when the user asks for a new password
} else {
$result = '<p><b>Setup password not specified correctly</b></p>' ;
}
2011-09-25 20:39:20 +02:00
$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>' ;
2009-04-16 01:32:45 +02:00
$result .= " <pre> \$ CONF['setup_password'] = ' $pass ';</pre> " ;
}
2018-01-26 15:45:57 +01:00
return array ( $error , $result );
2009-04-16 01:32:45 +02:00
}
2019-08-13 10:24:30 +02:00
function create_admin ( $values ) {
2011-12-20 02:06:49 +01:00
DEFINE ( 'POSTFIXADMIN_SETUP' , 1 ); # avoids instant redirect to login.php after creating the admin
$handler = new AdminHandler ( 1 , 'setup.php' );
$formconf = $handler -> webformConfig ();
if ( ! $handler -> init ( $values [ 'username' ])) {
return array ( 1 , " " , $handler -> errormsg );
2017-02-14 10:23:17 +01:00
}
2011-12-20 02:06:49 +01:00
if ( ! $handler -> set ( $values )) {
return array ( 1 , " " , $handler -> errormsg );
}
2020-09-25 22:29:45 +02:00
if ( ! $handler -> save ()) {
2011-12-20 02:06:49 +01:00
return array ( 1 , " " , $handler -> errormsg );
}
return array (
0 ,
2013-11-01 20:08:32 +01:00
$handler -> infomsg [ 'success' ],
2011-12-20 02:06:49 +01:00
array (),
);
}
2009-04-16 01:32:45 +02:00
/* vim: set expandtab softtabstop=4 tabstop=4 shiftwidth=4: */
2009-02-15 16:02:26 +01:00
?>