4 * SquirrelMail configtest script
6 * Copyright (c) 2003-2005 The SquirrelMail Project Team
7 * Licensed under the GNU GPL. For full terms see the file COPYING.
10 * @package squirrelmail
14 /************************************************************
15 * NOTE: you do not need to change this script! *
16 * If it throws errors you need to adjust your config. *
17 ************************************************************/
19 // This script could really use some restructuring as it has grown quite rapidly
20 // but is not very 'clean'. Feel free to get some structure into this thing.
22 function do_err($str, $exit = TRUE) {
24 echo '<p>'.$IND.'<font color="red"><b>ERROR:</b></font> ' .$str. "</p>\n";
26 echo '</body></html>';
31 $IND = str_repeat(' ',4);
35 define('SM_PATH', '../');
38 * Load config before output begins. functions/strings.php depends on
39 * functions/globals.php. functions/global.php needs to be run before
40 * any html output starts. If config.php is missing, error will be displayed
43 if (file_exists(SM_PATH
. 'config/config.php')) {
44 include(SM_PATH
. 'config/config.php');
45 include(SM_PATH
. 'functions/strings.php');
47 ?
><!DOCTYPE HTML
PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
50 <title
>SquirrelMail configtest
</title
>
53 <h1
>SquirrelMail configtest
</h1
>
55 <p
>This script will
try to check some aspects of your SquirrelMail configuration
56 and point you to errors whereever it can find them
. You need to go run
<tt
>conf
.pl
</tt
>
57 in the
<tt
>config
/</tt
> directory first before you run this script
.</p
>
62 $included = array_map('basename', get_included_files() );
63 if(!in_array('config.php', $included)) {
64 if(!file_exists(SM_PATH
. 'config/config.php')) {
65 do_err('Config file '.SM_PATH
. 'config/config.php does not exist!<br />'.
66 'You need to run <tt>conf.pl</tt> first.');
68 do_err('Could not read '.SM_PATH
.'config/config.php! Check file permissions.');
70 if(!in_array('strings.php', $included)) {
71 do_err('Could not include '.SM_PATH
.'functions/strings.php!<br />'.
72 'Check permissions on that file.');
75 /* checking PHP specs */
77 echo "<p><table>\n<tr><td>SquirrelMail version:</td><td><b>" . $version . "</b></td></tr>\n" .
78 '<tr><td>Config file version:</td><td><b>' . $config_version . "</b></td></tr>\n" .
79 '<tr><td>Config file last modified:</td><td><b>' .
80 date ('d F Y H:i:s', filemtime(SM_PATH
. 'config/config.php')) .
81 "</b></td></tr>\n</table>\n</p>\n\n";
83 echo "Checking PHP configuration...<br />\n";
85 if(!check_php_version(4,1,0)) {
86 do_err('Insufficient PHP version: '. PHP_VERSION
. '! Minimum required: 4.1.0');
89 echo $IND . 'PHP version ' . PHP_VERSION
. " OK.<br />\n";
91 $php_exts = array('session','pcre');
92 $diff = array_diff($php_exts, get_loaded_extensions());
94 do_err('Required PHP extensions missing: '.implode(', ',$diff) );
97 echo $IND . "PHP extensions OK.<br />\n";
99 /* dangerous php settings */
101 * mbstring.func_overload allows to replace original string and regexp functions
102 * with their equivalents from php mbstring extension. It causes problems when
103 * scripts analyse 8bit strings byte after byte or use 8bit strings in regexp tests.
104 * Setting can be controlled in php.ini (php 4.2.0), webserver config (php 4.2.0)
105 * and .htaccess files (php 4.3.5).
107 if (function_exists('mb_internal_encoding') &&
108 check_php_version(4,2,0) &&
109 (int)ini_get('mbstring.func_overload')!=0) {
110 $mb_error='You have enabled mbstring overloading.'
111 .' It can cause problems with SquirrelMail scripts that rely on single byte string functions.';
117 echo "Checking paths...<br />\n";
119 if(!file_exists($data_dir)) {
120 do_err("Data dir ($data_dir) does not exist!");
122 if(!is_dir($data_dir)) {
123 do_err("Data dir ($data_dir) is not a directory!");
125 // datadir should be executable - but no clean way to test on that
126 if(!is_writable($data_dir)) {
127 do_err("I cannot write to data dir ($data_dir)!");
130 // todo_ornot: actually write something and read it back.
131 echo $IND . "Data dir OK.<br />\n";
134 if($data_dir == $attachment_dir) {
135 echo $IND . "Attachment dir is the same as data dir.<br />\n";
137 if(!file_exists($attachment_dir)) {
138 do_err("Attachment dir ($attachment_dir) does not exist!");
140 if (!is_dir($attachment_dir)) {
141 do_err("Attachment dir ($attachment_dir) is not a directory!");
143 if (!is_writable($attachment_dir)) {
144 do_err("I cannot write to attachment dir ($attachment_dir)!");
146 echo $IND . "Attachment dir OK.<br />\n";
150 /* check plugins and themes */
151 if (isset($plugins[0])) {
152 foreach($plugins as $plugin) {
153 if(!file_exists(SM_PATH
.'plugins/'.$plugin)) {
154 do_err('You have enabled the <i>'.$plugin.'</i> plugin but I cannot find it.', FALSE);
155 } elseif (!is_readable(SM_PATH
.'plugins/'.$plugin.'/setup.php')) {
156 do_err('You have enabled the <i>'.$plugin.'</i> plugin but I cannot read its setup.php file.', FALSE);
159 echo $IND . "Plugins OK.<br />\n";
161 echo $IND . "Plugins are not enabled in config.<br />\n";
163 foreach($theme as $thm) {
164 if(!file_exists($thm['PATH'])) {
165 do_err('You have enabled the <i>'.$thm['NAME'].'</i> theme but I cannot find it ('.$thm['PATH'].').', FALSE);
166 } elseif(!is_readable($thm['PATH'])) {
167 do_err('You have enabled the <i>'.$thm['NAME'].'</i> theme but I cannot read it ('.$thm['PATH'].').', FALSE);
171 echo $IND . "Themes OK.<br />\n";
173 if ( $squirrelmail_default_language != 'en_US' ) {
174 $loc_path = SM_PATH
.'locale/'.$squirrelmail_default_language.'/LC_MESSAGES/squirrelmail.mo';
175 if( ! file_exists( $loc_path ) ) {
176 do_err('You have set <i>' . $squirrelmail_default_language .
177 '</i> as your default language, but I cannot find this translation (should be '.
178 'in <tt>' . $loc_path . '</tt>). Please note that you have to download translations '.
179 'separately from the main SquirrelMail package.', FALSE);
180 } elseif ( ! is_readable( $loc_path ) ) {
181 do_err('You have set <i>' . $squirrelmail_default_language .
182 '</i> as your default language, but I cannot read this translation (file '.
183 'in <tt>' . $loc_path . '</tt> unreadable).', FALSE);
185 echo $IND . "Default language OK.<br />\n";
188 echo $IND . "Default language OK.<br />\n";
191 echo $IND . "Base URL detected as: <tt>" . htmlspecialchars(get_location()) . "</tt><br />\n";
194 /* check outgoing mail */
196 if($use_smtp_tls ||
$use_imap_tls) {
197 if(!check_php_version(4,3,0)) {
198 do_err('You need at least PHP 4.3.0 for SMTP/IMAP TLS!');
200 if(!extension_loaded('openssl')) {
201 do_err('You need the openssl PHP extension to use SMTP/IMAP TLS!');
205 echo "Checking outgoing mail service....<br />\n";
208 // is_executable also checks for existance, but we want to be as precise as possible with the errors
209 if(!file_exists($sendmail_path)) {
210 do_err("Location of sendmail program incorrect ($sendmail_path)!");
212 if(!is_executable($sendmail_path)) {
213 do_err("I cannot execute the sendmail program ($sendmail_path)!");
216 echo $IND . "sendmail OK<br />\n";
218 $stream = fsockopen( ($use_smtp_tls?
'tls://':'').$smtpServerAddress, $smtpPort,
219 $errorNumber, $errorString);
221 do_err("Error connecting to SMTP server \"$smtpServerAddress:$smtpPort\".".
222 "Server error: ($errorNumber) ".htmlspecialchars($errorString));
225 // check for SMTP code; should be 2xx to allow us access
226 $smtpline = fgets($stream, 1024);
227 if(((int) $smtpline{0}) > 3) {
228 do_err("Error connecting to SMTP server. Server error: ".
229 htmlspecialchars($smtpline));
232 fputs($stream, 'QUIT');
234 echo $IND . 'SMTP server OK (<tt><small>'.
235 trim(htmlspecialchars($smtpline))."</small></tt>)<br />\n";
237 /* POP before SMTP */
238 if($pop_before_smtp) {
239 $stream = fsockopen($smtpServerAddress, 110, $err_no, $err_str);
241 do_err("Error connecting to POP Server ($smtpServerAddress:110) "
242 . $err_no . ' : ' . htmlspecialchars($err_str));
245 $tmp = fgets($stream, 1024);
246 if (substr($tmp, 0, 3) != '+OK') {
247 do_err("Error connecting to POP Server ($smtpServerAddress:110)"
248 . ' '.htmlspecialchars($tmp));
250 fputs($stream, 'QUIT');
252 echo $IND . "POP-before-SMTP OK.<br />\n";
257 * Check the IMAP server
259 echo "Checking IMAP service....<br />\n";
261 /** Can we open a connection? */
262 $stream = fsockopen( ($use_imap_tls?
'tls://':'').$imapServerAddress, $imapPort,
263 $errorNumber, $errorString);
265 do_err("Error connecting to IMAP server \"$imapServerAddress:$imapPort\".".
266 "Server error: ($errorNumber) ".
267 htmlspecialchars($errorString));
270 /** Is the first response 'OK'? */
271 $imapline = fgets($stream, 1024);
272 if(substr($imapline, 0,4) != '* OK') {
273 do_err('Error connecting to IMAP server. Server error: '.
274 htmlspecialchars($imapline));
277 echo $IND . 'IMAP server ready (<tt><small>'.
278 htmlspecialchars(trim($imapline))."</small></tt>)<br />\n";
280 /** Check capabilities */
281 fputs($stream, "A001 CAPABILITY\r\n");
282 $capline = fgets($stream, 1024);
284 echo $IND . 'Capabilities: <tt>'.htmlspecialchars($capline)."</tt><br />\n";
286 if($imap_auth_mech == 'login' && stristr($capline, 'LOGINDISABLED') !== FALSE) {
287 do_err('Your server doesn\'t allow plaintext logins. '.
288 'Try enabling another authentication mechanism like CRAM-MD5, DIGEST-MD5 or TLS-encryption '.
289 'in the SquirrelMail configuration.', FALSE);
291 if($use_imap_tls && stristr($capline, 'STARTTLS') === FALSE) {
292 do_err('You have enabled TLS encryption in the config, but the server does not '.
293 'report STARTTLS capability. TLS is probably not supported.', FALSE);
296 /** OK, close connection */
297 fputs($stream, "A002 LOGOUT\r\n");
300 echo "Checking internationalization (i18n) settings...<br />\n";
301 echo "$IND gettext - ";
302 if (function_exists('gettext')) {
303 echo 'Gettext functions are available.'
304 .' On some systems you must have appropriate system locales compiled.'
307 echo 'Gettext functions are unavailable.'
308 .' SquirrelMail will use slower internal gettext functions.'
311 echo "$IND mbstring - ";
312 if (function_exists('mb_detect_encoding')) {
313 echo "Mbstring functions are available.<br />\n";
315 echo 'Mbstring functions are unavailable.'
316 ." Japanese translation won't work.<br />\n";
318 echo "$IND recode - ";
319 if (function_exists('recode')) {
320 echo "Recode functions are available.<br />\n";
321 } elseif ($use_php_recode) {
322 echo "Recode functions are unavailable.<br />\n";
323 do_err('Your configuration requires recode support, but recode support is missing.');
325 echo "Recode functions are unavailable.<br />\n";
327 echo "$IND iconv - ";
328 if (function_exists('iconv')) {
329 echo "Iconv functions are available.<br />\n";
330 } elseif ($use_php_iconv) {
331 echo "Iconv functions are unavailable.<br />\n";
332 do_err('Your configuration requires iconv support, but iconv support is missing.');
334 echo "Iconv functions are unavailable.<br />\n";
336 // same test as in include/validate.php
337 echo "$IND timezone - ";
338 if ( (!ini_get('safe_mode')) ||
339 !strcmp(ini_get('safe_mode_allowed_env_vars'),'') ||
340 preg_match('/^([\w_]+,)*TZ/', ini_get('safe_mode_allowed_env_vars')) ) {
341 echo "Webmail users can change their time zone settings.<br />\n";
343 echo "Webmail users can't change their time zone settings.<br />\n";
348 echo "Checking database functions...<br />\n";
349 if($addrbook_dsn ||
$prefs_dsn ||
$addrbook_global_dsn) {
350 @include_once
('DB.php');
351 if (class_exists('DB')) {
352 echo "$IND PHP Pear DB support is present.<br />\n";
354 'dbase' => 'dbase_open',
355 'fbsql' => 'fbsql_connect',
356 'interbase' => 'ibase_connect',
357 'informix' => 'ifx_connect',
358 'msql' => 'msql_connect',
359 'mssql' => 'mssql_connect',
360 'mysql' => 'mysql_connect',
361 'mysqli' => 'mysqli_connect',
362 'oci8' => 'ocilogon',
363 'odbc' => 'odbc_connect',
364 'pgsql' => 'pgsql_connect',
365 'sqlite' => 'sqlite_open',
366 'sybase' => 'sybase_connect'
371 $dsns['preferences'] = $prefs_dsn;
374 $dsns['addressbook'] = $addrbook_dsn;
376 if($addrbook_global_dsn) {
377 $dsns['global addressbook'] = $addrbook_global_dsn;
380 foreach($dsns as $type => $dsn) {
381 $dbtype = array_shift(explode(':', $dsn));
382 if(isset($db_functions[$dbtype]) && function_exists($db_functions[$dbtype])) {
383 echo "$IND$dbtype database support present.<br />\n";
385 // now, test this interface:
387 $dbh = DB
::connect($dsn, true);
388 if (DB
::isError($dbh)) {
389 do_err('Database error: '. htmlspecialchars(DB
::errorMessage($dbh)) .
390 ' in ' .$type .' DSN.');
393 echo "$IND$type database connect successful.<br />\n";
396 do_err($db.' database support not present!');
400 $db_error='Required PHP PEAR DB support is not available.'
401 .' Is PEAR installed and is the include path set correctly to find <tt>DB.php</tt>?'
402 .' The include path is now:<tt>' . ini_get('include_path') . '</tt>.';
406 echo $IND."not using database functionality.<br />\n";
410 echo "Checking LDAP functions...<br />\n";
411 if( empty($ldap_server) ) {
412 echo $IND."not using LDAP functionality.<br />\n";
414 if ( !function_exists(ldap_connect
) ) {
415 do_err('Required LDAP support is not available.');
417 echo "$IND LDAP support present.<br />\n";
418 foreach ( $ldap_server as $param ) {
420 $linkid = ldap_connect($param['host'], (empty($param['port']) ?
389 : $param['port']) );
423 echo "$IND LDAP connect to ".$param['host']." successful: ".$linkid."<br />\n";
425 if ( !empty($param['protocol']) &&
426 !ldap_set_option($linkid, LDAP_OPT_PROTOCOL_VERSION
, $param['protocol']) ) {
427 do_err('Unable to set LDAP protocol');
430 if ( empty($param['binddn']) ) {
431 $bind = ldap_bind($linkid);
433 $bind = ldap_bind($param['binddn'], $param['bindpw']);
437 echo "$IND LDAP Bind Successful <br />";
439 do_err('Unable to Bind to LDAP Server');
444 do_err('Connection to LDAP failed');
451 <p
>Congratulations
, your SquirrelMail setup looks fine to me
!</p
>
453 <p
><a href
="login.php">Login now
</a
></p
>