Fix PHP errors. Thanks to Jacek Kalinski
[squirrelmail.git] / src / configtest.php
CommitLineData
d1ae9d4c 1<?php
134e4174 2
30967a1e 3/**
d1ae9d4c 4 * SquirrelMail configtest script
5 *
1977ab55 6 * @copyright 2003-2010 The SquirrelMail Project Team
4b4abf93 7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
30967a1e 8 * @version $Id$
9 * @package squirrelmail
10 * @subpackage config
d1ae9d4c 11 */
12
13/************************************************************
14 * NOTE: you do not need to change this script! *
15 * If it throws errors you need to adjust your config. *
16 ************************************************************/
17
ebd2391c 18/** This is the configtest page */
19define('PAGE_NAME', 'configtest');
20
df758744 21// This script could really use some restructuring as it has grown quite rapidly
22// but is not very 'clean'. Feel free to get some structure into this thing.
23
8a6b8e1f 24// force verbose error reporting and turn on display of errors, but not before
25// getting their original values
26$php_display_errors_original_value = ini_get('display_errors');
27$php_error_reporting_original_value = ini_get('error_reporting');
dda39a1a 28error_reporting(E_ALL);
29ini_set('display_errors',1);
30
31/** Blockcopy from init.php. Cleans globals. */
32if ((bool) ini_get('register_globals') &&
33 strtolower(ini_get('register_globals'))!='off') {
34 /**
35 * Remove all globals that are not reserved by PHP
36 * 'value' and 'key' are used by foreach. Don't unset them inside foreach.
37 */
38 foreach ($GLOBALS as $key => $value) {
39 switch($key) {
40 case 'HTTP_POST_VARS':
41 case '_POST':
42 case 'HTTP_GET_VARS':
43 case '_GET':
44 case 'HTTP_COOKIE_VARS':
45 case '_COOKIE':
46 case 'HTTP_SERVER_VARS':
47 case '_SERVER':
48 case 'HTTP_ENV_VARS':
49 case '_ENV':
50 case 'HTTP_POST_FILES':
51 case '_FILES':
52 case '_REQUEST':
53 case 'HTTP_SESSION_VARS':
54 case '_SESSION':
55 case 'GLOBALS':
56 case 'key':
57 case 'value':
58 break;
59 default:
60 unset($GLOBALS[$key]);
61 }
62 }
63 // Unset variables used in foreach
64 unset($GLOBALS['key']);
65 unset($GLOBALS['value']);
66}
67
68
69/**
70 * Displays error messages and warnings
71 * @param string $str message
72 * @param boolean $fatal fatal error or only warning
73 */
3a196538 74function do_err($str, $fatal = TRUE) {
f084f987 75 global $IND, $warnings;
76 $level = $fatal ? 'FATAL ERROR:' : 'WARNING:';
3a196538 77 echo '<p>'.$IND.'<font color="red"><b>' . $level . '</b></font> ' .$str. "</p>\n";
78 if($fatal) {
f084f987 79 echo '</body></html>';
80 exit;
3a196538 81 } else {
f084f987 82 $warnings++;
83 }
5b53b7e0 84}
85
5b53b7e0 86ob_implicit_flush();
30967a1e 87/** @ignore */
5b53b7e0 88define('SM_PATH', '../');
dda39a1a 89/** load minimal function set */
b37e457f 90require(SM_PATH . 'include/constants.php');
dda39a1a 91require(SM_PATH . 'functions/global.php');
92require(SM_PATH . 'functions/strings.php');
b578bd7c 93require(SM_PATH . 'functions/files.php');
a895042a 94$SQM_INTERNAL_VERSION = explode('.', SM_VERSION, 3);
b37e457f 95$SQM_INTERNAL_VERSION[2] = intval($SQM_INTERNAL_VERSION[2]);
5b53b7e0 96
dda39a1a 97/** set default value in order to block remote access */
d0184454 98$allow_remote_configtest=false;
99
dda39a1a 100/** Load all configuration files before output begins */
101
102/* load default configuration */
103require(SM_PATH . 'config/config_default.php');
104/* reset arrays in default configuration */
105$ldap_server = array();
106$plugins = array();
107$fontsets = array();
108$theme = array();
109$theme[0]['PATH'] = SM_PATH . 'themes/default_theme.php';
110$theme[0]['NAME'] = 'Default';
111$aTemplateSet = array();
112$aTemplateSet[0]['ID'] = 'default';
113$aTemplateSet[0]['NAME'] = 'Default';
114/* load site configuration */
5b53b7e0 115if (file_exists(SM_PATH . 'config/config.php')) {
dda39a1a 116 require(SM_PATH . 'config/config.php');
5b53b7e0 117}
dda39a1a 118/* load local configuration overrides */
119if (file_exists(SM_PATH . 'config/config_local.php')) {
120 require(SM_PATH . 'config/config_local.php');
121}
122
1dc63862 123/**
124 * Include Compatibility plugin if available.
125 */
126if (!$disable_plugins && file_exists(SM_PATH . 'plugins/compatibility/functions.php'))
127 include_once(SM_PATH . 'plugins/compatibility/functions.php');
128
8459a9bb 129/** Load plugins */
130global $disable_plugins;
131$squirrelmail_plugin_hooks = array();
132if (!$disable_plugins && file_exists(SM_PATH . 'config/plugin_hooks.php')) {
133 require(SM_PATH . 'config/plugin_hooks.php');
134}
135
dda39a1a 136/** Warning counter */
137$warnings = 0;
138
139/** indent */
140$IND = str_repeat('&nbsp;',4);
c772f125 141
69792446 142/**
143 * get_location starts session and must be run before output is started.
144 */
145$test_location = get_location();
146
151562a7 147?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
148 "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
d1ae9d4c 149<html>
150<head>
f084f987 151 <meta name="robots" content="noindex,nofollow">
152 <title>SquirrelMail configtest</title>
d1ae9d4c 153</head>
154<body>
155<h1>SquirrelMail configtest</h1>
156
157<p>This script will try to check some aspects of your SquirrelMail configuration
158and point you to errors whereever it can find them. You need to go run <tt>conf.pl</tt>
d18703d3 159in the <tt>config/</tt> directory first before you run this script.</p>
d1ae9d4c 160
161<?php
162
d1ae9d4c 163$included = array_map('basename', get_included_files() );
164if(!in_array('config.php', $included)) {
165 if(!file_exists(SM_PATH . 'config/config.php')) {
166 do_err('Config file '.SM_PATH . 'config/config.php does not exist!<br />'.
f084f987 167 'You need to run <tt>conf.pl</tt> first.');
d1ae9d4c 168 }
169 do_err('Could not read '.SM_PATH.'config/config.php! Check file permissions.');
170}
171if(!in_array('strings.php', $included)) {
172 do_err('Could not include '.SM_PATH.'functions/strings.php!<br />'.
f084f987 173 'Check permissions on that file.');
d1ae9d4c 174}
175
d0184454 176/* Block remote use of script */
177if (! $allow_remote_configtest) {
178 sqGetGlobalVar('REMOTE_ADDR',$client_ip,SQ_SERVER);
a15f9d93 179 sqGetGlobalVar('SERVER_ADDR',$server_ip,SQ_SERVER);
180
181 if ((! isset($client_ip) || $client_ip!='127.0.0.1') &&
f084f987 182 (! isset($client_ip) || ! isset($server_ip) || $client_ip!=$server_ip)) {
f8a1ed5a 183 do_err('Enable "Allow remote configtest" option in squirrelmail configuration in order to use this script.');
d0184454 184 }
185}
d1ae9d4c 186
b37e457f 187echo "<p><table>\n<tr><td>SquirrelMail version:</td><td><b>" . SM_VERSION . "</b></td></tr>\n" .
f084f987 188 '<tr><td>Config file version:</td><td><b>' . $config_version . "</b></td></tr>\n" .
189 '<tr><td>Config file last modified:</td><td><b>' .
190 date ('d F Y H:i:s', filemtime(SM_PATH . 'config/config.php')) .
191 "</b></td></tr>\n</table>\n</p>\n\n";
d1ae9d4c 192
c3da9f50 193/* check $config_version */
65efa982 194if ($config_version!='1.5.0') {
c3da9f50 195 do_err('Configuration file version does not match required version. Please update your configuration file.');
196}
a15f9d93 197
a1912bbc 198
199/* checking PHP specs */
200
d1ae9d4c 201echo "Checking PHP configuration...<br />\n";
202
abd74f7d 203if(!check_php_version(4,1,0)) {
204 do_err('Insufficient PHP version: '. PHP_VERSION . '! Minimum required: 4.1.0');
d1ae9d4c 205}
206
3a196538 207echo $IND . 'PHP version ' . PHP_VERSION . ' OK. (You have: ' . phpversion() . ". Minimum: 4.1.0)<br />\n";
a1912bbc 208
8a6b8e1f 209echo $IND . 'display_errors: ' . $php_display_errors_original_value . " (overridden with 1 for this page only)<br />\n";
0cc820f9 210
8a6b8e1f 211echo $IND . 'error_reporting: ' . $php_error_reporting_original_value . " (overridden with 2047 for this page only)<br />\n";
0cc820f9 212
ccbde363 213$safe_mode = ini_get('safe_mode');
214if ($safe_mode) {
7777a968 215 //FIXME: should show that safe_mode is off when it is (this only shows the safe_mode setting when it's on) (also might be generally helpful to show things like open_basedir, too or even add phpinfo() output or a link to another script that has phpinfo()
ccbde363 216 echo $IND . 'safe_mode: ' . $safe_mode;
217 if (empty($prefs_dsn) || empty($addrbook_dsn))
218 echo ' (<font color="red">double check data and attachment directory ownership, etc!</font>)';
dc528046 219 if (!empty($addrbook_dsn) || !empty($prefs_dsn) || !empty($addrbook_global_dsn))
ccbde363 220 echo ' (<font color="red">does PHP have access to database interface?</font>)';
221 echo "<br />\n";
222 $safe_mode_exec_dir = ini_get('safe_mode_exec_dir');
223 echo $IND . 'safe_mode_exec_dir: ' . $safe_mode_exec_dir . "<br />\n";
224}
225
a1912bbc 226/* register_globals check: test for boolean false and any string that is not equal to 'off' */
227
dc528046 228if ((bool) ini_get('register_globals') &&
a3b99374 229 strtolower(ini_get('register_globals'))!='off') {
b00dce9b 230 do_err('You have register_globals turned on. This is not an error, but it CAN be a security hazard. Consider turning register_globals off.', false);
c772f125 231}
a1912bbc 232
233
234/* variables_order check */
235
b00dce9b 236// FIXME(?): Hmm, how do we distinguish between when an ini setting is not available (ini_set() returns empty string) and when the administrator set the value to an empty string? The latter is sure to be highly rare, so for now, just assume that empty value means the setting isn't even available (could also check PHP version when this setting was implemented) although, we'll also warn the user if it is empty, with a non-fatal error
47fa8e9b 237$variables_order = strtoupper(ini_get('variables_order'));
238if (empty($variables_order))
b00dce9b 239 do_err('Your variables_order setting seems to be empty. Make sure it is undefined in any PHP ini files, .htaccess files, etc. and not specifically set to an empty value or SquirrelMail may not function correctly', false);
47fa8e9b 240else if (strpos($variables_order, 'G') === FALSE
a1912bbc 241 || strpos($variables_order, 'P') === FALSE
242 || strpos($variables_order, 'C') === FALSE
47fa8e9b 243 || strpos($variables_order, 'S') === FALSE) {
b00dce9b 244 do_err('Your variables_order setting is insufficient for SquirrelMail to function. It needs at least "GPCS", but you have it set to "' . htmlspecialchars($variables_order) . '"', true);
a1912bbc 245} else {
246 echo $IND . "variables_order OK: $variables_order.<br />\n";
247}
248
249
47fa8e9b 250/* gpc_order check (removed from PHP as of v5.0) */
251
252if (!check_php_version(5)) {
b00dce9b 253 // FIXME(?): Hmm, how do we distinguish between when an ini setting is not available (ini_set() returns empty string) and when the administrator set the value to an empty string? The latter is sure to be highly rare, so for now, just assume that empty value means the setting isn't even available (could also check PHP version when this setting was implemented) although, we'll also warn the user if it is empty, with a non-fatal error
47fa8e9b 254 $gpc_order = strtoupper(ini_get('gpc_order'));
255 if (empty($gpc_order))
b00dce9b 256 do_err('Your gpc_order setting seems to be empty. Make sure it is undefined in any PHP ini files, .htaccess files, etc. and not specifically set to an empty value or SquirrelMail may not function correctly', false);
47fa8e9b 257 else if (strpos($gpc_order, 'G') === FALSE
258 || strpos($gpc_order, 'P') === FALSE
259 || strpos($gpc_order, 'C') === FALSE) {
b00dce9b 260 do_err('Your gpc_order setting is insufficient for SquirrelMail to function. It needs to be set to "GPC", but you have it set to "' . htmlspecialchars($gpc_order) . '"', true);
47fa8e9b 261 } else {
262 echo $IND . "gpc_order OK: $gpc_order.<br />\n";
263 }
a1912bbc 264}
265
266
267/* check PHP extensions */
268
d1ae9d4c 269$php_exts = array('session','pcre');
270$diff = array_diff($php_exts, get_loaded_extensions());
271if(count($diff)) {
272 do_err('Required PHP extensions missing: '.implode(', ',$diff) );
273}
274
d053c206 275echo $IND . "PHP extensions OK. Dynamic loading is ";
276
277if (!(bool)ini_get('enable_dl') || (bool)ini_get('safe_mode')) {
278 echo "disabled.<br />\n";
279} else {
280 echo "enabled.<br />\n";
281}
282
d1ae9d4c 283
8f186a2a 284/* dangerous php settings */
285/**
286 * mbstring.func_overload allows to replace original string and regexp functions
287 * with their equivalents from php mbstring extension. It causes problems when
d0184454 288 * scripts analyze 8bit strings byte after byte or use 8bit strings in regexp tests.
9211bcef 289 * Setting can be controlled in php.ini (php 4.2.0), webserver config (php 4.2.0)
8f186a2a 290 * and .htaccess files (php 4.3.5).
291 */
292if (function_exists('mb_internal_encoding') &&
9211bcef 293 check_php_version(4,2,0) &&
8f186a2a 294 (int)ini_get('mbstring.func_overload')!=0) {
295 $mb_error='You have enabled mbstring overloading.'
296 .' It can cause problems with SquirrelMail scripts that rely on single byte string functions.';
297 do_err($mb_error);
298}
d1ae9d4c 299
99c1c0d6 300/**
301 * Do not use SquirrelMail with magic_quotes_* on.
302 */
430a19f3 303if ( (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime()) ||
304 (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc()) ||
99c1c0d6 305 ( (bool) ini_get('magic_quotes_sybase') && ini_get('magic_quotes_sybase') != 'off' )
306 ) {
307 $magic_quotes_warning='You have enabled any one of <tt>magic_quotes_runtime</tt>, '
308 .'<tt>magic_quotes_gpc</tt> or <tt>magic_quotes_sybase</tt> in your PHP '
309 .'configuration. We recommend all those settings to be off. SquirrelMail '
310 .'may work with them on, but when experiencing stray backslashes in your mail '
311 .'or other strange behaviour, it may be advisable to turn them off.';
312 do_err($magic_quotes_warning,false);
313}
314
dc528046 315if (ini_get('short_open_tag') == 0) {
316 $short_open_tag_warning = 'You have configured PHP not to allow short tags '
317 . '(<tt>short_open_tag=off</tt>). This shouldn\'t be a problem with '
318 . 'SquirrelMail or any plugin coded coded according to the '
319 . 'SquirrelMail Coding Guidelines, but if you experience problems with '
320 . 'PHP code being displayed in some of the pages and changing setting '
321 . 'to "on" solves the problem, please file a bug report against the '
322 . 'failing plugin. The correct contact information is most likely '
323 . 'to be found in the plugin documentation.';
324 do_err($short_open_tag_warning, false);
325}
99c1c0d6 326
e45a534b 327
328/* check who the web server is running as if possible */
329
330if ($process_info = get_process_owner_info()) {
331 echo $IND . 'Web server is running as user: ' . $process_info['name'] . ' (' . $process_info['uid'] . ")<br />\n";
332 //echo $IND . 'Web server is running as effective user: ' . $process_info['ename'] . ' (' . $process_info['euid'] . ")<br />\n";
333 echo $IND . 'Web server is running as group: ' . $process_info['group'] . ' (' . $process_info['gid'] . ")<br />\n";
334 //echo $IND . 'Web server is running as effective group: ' . $process_info['egroup'] . ' (' . $process_info['egid'] . ")<br />\n";
335}
336
337
d1ae9d4c 338/* checking paths */
339
340echo "Checking paths...<br />\n";
341
342if(!file_exists($data_dir)) {
d0184454 343 // data_dir is not that important in db_setups.
ccbde363 344 if (!empty($prefs_dsn)) {
d0184454 345 $data_dir_error = "Data dir ($data_dir) does not exist!\n";
346 echo $IND .'<font color="red"><b>ERROR:</b></font> ' . $data_dir_error;
347 } else {
348 do_err("Data dir ($data_dir) does not exist!");
349 }
91e0dccc 350}
d0184454 351// don't check if errors
352if(!isset($data_dir_error) && !is_dir($data_dir)) {
ccbde363 353 if (!empty($prefs_dsn)) {
d0184454 354 $data_dir_error = "Data dir ($data_dir) is not a directory!\n";
355 echo $IND . '<font color="red"><b>ERROR:</b></font> ' . $data_dir_error;
356 } else {
357 do_err("Data dir ($data_dir) is not a directory!");
358 }
91e0dccc 359}
d4eaadbe 360// datadir should be executable - but no clean way to test on that
0a496c76 361if(!isset($data_dir_error) && !sq_is_writable($data_dir)) {
ccbde363 362 if (!empty($prefs_dsn)) {
d0184454 363 $data_dir_error = "Data dir ($data_dir) is not writable!\n";
364 echo $IND . '<font color="red"><b>ERROR:</b></font> ' . $data_dir_error;
365 } else {
366 do_err("Data dir ($data_dir) is not writable!");
367 }
d1ae9d4c 368}
369
d0184454 370if (isset($data_dir_error)) {
371 echo " Some plugins might need access to data directory.<br />\n";
372} else {
373 // todo_ornot: actually write something and read it back.
374 echo $IND . "Data dir OK.<br />\n";
375}
d1ae9d4c 376
377if($data_dir == $attachment_dir) {
378 echo $IND . "Attachment dir is the same as data dir.<br />\n";
d0184454 379 if (isset($data_dir_error)) {
380 do_err($data_dir_error);
381 }
d1ae9d4c 382} else {
383 if(!file_exists($attachment_dir)) {
384 do_err("Attachment dir ($attachment_dir) does not exist!");
91e0dccc 385 }
d1ae9d4c 386 if (!is_dir($attachment_dir)) {
387 do_err("Attachment dir ($attachment_dir) is not a directory!");
91e0dccc 388 }
0a496c76 389 if (!sq_is_writable($attachment_dir)) {
d1ae9d4c 390 do_err("I cannot write to attachment dir ($attachment_dir)!");
391 }
392 echo $IND . "Attachment dir OK.<br />\n";
393}
394
395
646b17e0 396echo "Checking plugins...<br />\n";
397
d1ae9d4c 398/* check plugins and themes */
d17b7894 399//FIXME: check requirements given in plugin _info() function, such as required PHP extensions, Pear packages, other plugins, SM version, etc see development docs for list of returned info from that function
400//FIXME: update this list with most recent contents of the Obsolete category - I think it has changed recently
f084f987 401$bad_plugins = array(
0880efc9 402 'attachment_common', // Integrated into SquirrelMail 1.2 core
eb7bd9b7 403 'auto_prune_sent', // Obsolete: See Proon Automatic Folder Pruning plugin
0880efc9 404 'compose_new_window', // Integrated into SquirrelMail 1.4 core
405 'delete_move_next', // Integrated into SquirrelMail 1.5 core
eb7bd9b7 406 'disk_quota', // Obsolete: See Check Quota plugin
0880efc9 407 'email_priority', // Integrated into SquirrelMail 1.2 core
eb7bd9b7 408 'emoticons', // Obsolete: See HTML Mail plugin
0880efc9 409 'focus_change', // Integrated into SquirrelMail 1.2 core
410 'folder_settings', // Integrated into SquirrelMail 1.5.1 core
411 'global_sql_addressbook', // Integrated into SquirrelMail 1.4 core
eb7bd9b7 412 'hancock', // Not Working: See Random Signature Taglines plugin
0880efc9 413 'msg_flags', // Integrated into SquirrelMail 1.5.1 core
414 'message_source', // Added to SquirrelMail 1.4 Core Plugins (message_details)
415 'motd', // Integrated into SquirrelMail 1.2 core
416 'paginator', // Integrated into SquirrelMail 1.2 core
417 'printer_friendly', // Integrated into SquirrelMail 1.2 core
eb7bd9b7 418 'procfilter', // Obsolete: See Server Side Filter plugin
0880efc9 419 'redhat_php_cgi_fix', // Integrated into SquirrelMail 1.1.1 core
420 'send_to_semicolon', // Integrated into SquirrelMail 1.4.1 core
421 'spamassassin', // Not working beyond SquirrelMail 1.2.7: See Spamassassin SpamFilter (Frontend) v2 plugin
422 'sqcalendar', // Added to SquirrelMail 1.2 Core Plugins (calendar)
423 'sqclock', // Integrated into SquirrelMail 1.2 core
eb7bd9b7 424 'sql_squirrel_logger', // Obsolete: See Squirrel Logger plugin
425 'tmda', // Obsolete: See TMDA Tools plugin
426 'vacation', // Obsolete: See Vacation Local plugin
0880efc9 427 'view_as_html', // Integrated into SquirrelMail 1.5.1 core
428 'xmailer' // Integrated into SquirrelMail 1.2 core
f084f987 429 );
3a196538 430
5b53b7e0 431if (isset($plugins[0])) {
432 foreach($plugins as $plugin) {
433 if(!file_exists(SM_PATH .'plugins/'.$plugin)) {
f084f987 434 do_err('You have enabled the <i>'.$plugin.'</i> plugin, but I cannot find it.', FALSE);
5b53b7e0 435 } elseif (!is_readable(SM_PATH .'plugins/'.$plugin.'/setup.php')) {
1dc63862 436 do_err('You have enabled the <i>'.$plugin.'</i> plugin, but I cannot locate or read its setup.php file.', FALSE);
f084f987 437 } elseif (in_array($plugin, $bad_plugins)) {
438 do_err('You have enabled the <i>'.$plugin.'</i> plugin, which causes problems with this version of SquirrelMail. Please check the ReleaseNotes or other documentation for more information.', false);
439 }
d1ae9d4c 440 }
1dc63862 441
442
69792446 443 // load plugin functions
444 include_once(SM_PATH . 'functions/plugin.php');
1dc63862 445
69792446 446 // turn on output buffering in order to prevent output of new lines
447 ob_start();
448 foreach ($plugins as $name) {
449 use_plugin($name);
1dc63862 450
451 // get output and remove whitespace
452 $output = trim(ob_get_contents());
453
454 // if plugin outputs more than newlines and spacing, stop script execution.
455 if (!empty($output)) {
456 $plugin_load_error = 'Some output was produced when plugin <i>' . $name . '</i> was loaded. Usually this means there is an error in the plugin\'s setup or configuration file. The output was: '.htmlspecialchars($output);
457 do_err($plugin_load_error);
458 }
69792446 459 }
69792446 460 ob_end_clean();
1dc63862 461
462
463 /**
464 * Check the contents of the static plugin hooks array file against
465 * the plugin setup file, which may have changed in an upgrade, etc.
466 * This helps remind admins to re-run the configuration utility when
467 * a plugin has been changed or upgraded.
468 */
469 $static_squirrelmail_plugin_hooks = $squirrelmail_plugin_hooks;
470 $squirrelmail_plugin_hooks = array();
471 foreach ($plugins as $name) {
472 $function = "squirrelmail_plugin_init_$name";
473 if (function_exists($function)) {
474 $function();
475
476 // now iterate through each hook and make sure the
477 // plugin is registered on the correct ones in the
478 // static plugin configuration file
479 //
480 foreach ($squirrelmail_plugin_hooks as $hook_name => $hooked_plugins)
481 foreach ($hooked_plugins as $hooked_plugin => $hooked_function)
482 if ($hooked_plugin == $name
483 && (empty($static_squirrelmail_plugin_hooks[$hook_name][$hooked_plugin])
484 || $static_squirrelmail_plugin_hooks[$hook_name][$hooked_plugin] != $hooked_function))
485 do_err('The plugin <i>' . $name . '</i> is supposed to be registered on the <i>' . $hook_name . '</i> hook, but it is not. You need to re-run the configuration utility and re-save your configuration file.', FALSE);
486 }
69792446 487 }
1dc63862 488 $squirrelmail_plugin_hooks = $static_squirrelmail_plugin_hooks;
489
490
dc528046 491 /**
56f9bb83 492 * Print plugin versions
493 */
56f9bb83 494 echo $IND . "Plugin versions...<br />\n";
495 foreach ($plugins as $name) {
d95b10b3 496 $plugin_version = get_plugin_version($name);
daa0c5b8 497 $english_name = get_plugin_requirement($name, 'english_name');
498 echo $IND . $IND . (empty($english_name) ? $name . ' ' : $english_name . ' (' . $name . ') ') . (empty($plugin_version) ? '??' : $plugin_version) . "<br />\n";
2cbaf68d 499
dc528046 500 // check if this plugin has any other plugin
2cbaf68d 501 // dependencies and if they are satisfied
502 //
503 $failed_dependencies = check_plugin_dependencies($name);
f258865c 504 if ($failed_dependencies === SQ_INCOMPATIBLE) {
03a69f57 505 do_err($name . ' is NOT COMPATIBLE with this version of SquirrelMail', FALSE);
506 }
507 else if (is_array($failed_dependencies)) {
2cbaf68d 508 $missing_plugins = '';
e1a125cd 509 $incompatible_plugins = '';
fc6228e4 510 foreach ($failed_dependencies as $depend_name => $depend_requirements) {
e1a125cd 511 if ($depend_requirements['version'] == SQ_INCOMPATIBLE)
512 $incompatible_plugins .= ', ' . $depend_name;
513 else
514 $missing_plugins .= ', ' . $depend_name . ' (version ' . $depend_requirements['version'] . ', ' . ($depend_requirements['activate'] ? 'must be activated' : 'need not be activated') . ')';
2cbaf68d 515 }
e1a125cd 516 $error_string = (!empty($incompatible_plugins) ? $name . ' cannot be activated at the same time as the following plugins: ' . trim($incompatible_plugins, ', ') : '')
517 . (!empty($missing_plugins) ? (!empty($incompatible_plugins) ? '. ' . $name . ' is also ' : $name . ' is ') . 'missing some dependencies: ' . trim($missing_plugins, ', ') : '');
518 do_err($error_string, FALSE);
2cbaf68d 519 }
520
56f9bb83 521 }
1dc63862 522
523
69792446 524 /**
dc528046 525 * This hook was added in 1.5.2 and 1.4.10. Each plugins should print an error
6e515418 526 * message and return TRUE if there are any errors in its setup/configuration.
69792446 527 */
62fb877b 528 $plugin_err = boolean_hook_function('configtest', $null, 1);
69792446 529 if($plugin_err) {
530 do_err('Some plugin tests failed.');
531 } else {
532 echo $IND . "Plugins OK.<br />\n";
533 }
5b53b7e0 534} else {
535 echo $IND . "Plugins are not enabled in config.<br />\n";
d1ae9d4c 536}
d1ae9d4c 537foreach($theme as $thm) {
538 if(!file_exists($thm['PATH'])) {
539 do_err('You have enabled the <i>'.$thm['NAME'].'</i> theme but I cannot find it ('.$thm['PATH'].').', FALSE);
540 } elseif(!is_readable($thm['PATH'])) {
541 do_err('You have enabled the <i>'.$thm['NAME'].'</i> theme but I cannot read it ('.$thm['PATH'].').', FALSE);
542 }
543}
544
545echo $IND . "Themes OK.<br />\n";
546
07337c9b 547if ( $squirrelmail_default_language != 'en_US' ) {
548 $loc_path = SM_PATH .'locale/'.$squirrelmail_default_language.'/LC_MESSAGES/squirrelmail.mo';
549 if( ! file_exists( $loc_path ) ) {
f8a1ed5a 550 do_err('You have set <i>' . $squirrelmail_default_language .
f084f987 551 '</i> as your default language, but I cannot find this translation (should be '.
552 'in <tt>' . $loc_path . '</tt>). Please note that you have to download translations '.
553 'separately from the main SquirrelMail package.', FALSE);
07337c9b 554 } elseif ( ! is_readable( $loc_path ) ) {
f8a1ed5a 555 do_err('You have set <i>' . $squirrelmail_default_language .
f084f987 556 '</i> as your default language, but I cannot read this translation (file '.
557 'in <tt>' . $loc_path . '</tt> unreadable).', FALSE);
07337c9b 558 } else {
559 echo $IND . "Default language OK.<br />\n";
560 }
561} else {
562 echo $IND . "Default language OK.<br />\n";
563}
564
74530cf4 565echo $IND . "Base URL detected as: <tt>" . htmlspecialchars($test_location) .
566 "</tt> (location base " . (empty($config_location_base) ? 'autodetected' : 'set to <tt>' .
567 htmlspecialchars($config_location_base)."</tt>") . ")<br />\n";
23649466 568
a15f9d93 569/* check minimal requirements for other security options */
d1ae9d4c 570
a15f9d93 571/* imaps or ssmtp */
572if($use_smtp_tls == 1 || $use_imap_tls == 1) {
d1ae9d4c 573 if(!check_php_version(4,3,0)) {
574 do_err('You need at least PHP 4.3.0 for SMTP/IMAP TLS!');
575 }
576 if(!extension_loaded('openssl')) {
577 do_err('You need the openssl PHP extension to use SMTP/IMAP TLS!');
578 }
579}
a15f9d93 580/* starttls extensions */
1c4f110f 581if($use_smtp_tls === 2 || $use_imap_tls === 2) {
a15f9d93 582 if (! function_exists('stream_socket_enable_crypto')) {
583 do_err('If you want to use STARTTLS extension, you need stream_socket_enable_crypto() function from PHP 5.1.0 and newer.');
584 }
585}
586/* digest-md5 */
587if ($smtp_auth_mech=='digest-md5' || $imap_auth_mech =='digest-md5') {
588 if (!extension_loaded('xml')) {
589 do_err('You need the PHP XML extension to use Digest-MD5 authentication!');
590 }
591}
592
593/* check outgoing mail */
d1ae9d4c 594
595echo "Checking outgoing mail service....<br />\n";
596
597if($useSendmail) {
598 // is_executable also checks for existance, but we want to be as precise as possible with the errors
599 if(!file_exists($sendmail_path)) {
600 do_err("Location of sendmail program incorrect ($sendmail_path)!");
91e0dccc 601 }
d1ae9d4c 602 if(!is_executable($sendmail_path)) {
603 do_err("I cannot execute the sendmail program ($sendmail_path)!");
604 }
605
606 echo $IND . "sendmail OK<br />\n";
607} else {
a15f9d93 608 $stream = fsockopen( ($use_smtp_tls==1?'tls://':'').$smtpServerAddress, $smtpPort,
f084f987 609 $errorNumber, $errorString);
d1ae9d4c 610 if(!$stream) {
611 do_err("Error connecting to SMTP server \"$smtpServerAddress:$smtpPort\".".
f084f987 612 "Server error: ($errorNumber) ".htmlspecialchars($errorString));
d1ae9d4c 613 }
614
615 // check for SMTP code; should be 2xx to allow us access
616 $smtpline = fgets($stream, 1024);
617 if(((int) $smtpline{0}) > 3) {
9c941728 618 do_err("Error connecting to SMTP server. Server error: ".
f084f987 619 htmlspecialchars($smtpline));
d1ae9d4c 620 }
621
a15f9d93 622 /* smtp starttls checks */
1c4f110f 623 if ($use_smtp_tls===2) {
a15f9d93 624 // if something breaks, script should close smtp connection on exit.
625
a820ac9d 626
627 // format EHLO argument correctly if needed
628 //
870ffc40 629 if (preg_match('/^\d+\.\d+\.\d+\.\d+$/', $client_ip))
a820ac9d 630 $helohost = '[' . $client_ip . ']';
631 else // some day might add IPv6 here
632 $helohost = $client_ip;
633
634
a15f9d93 635 // say helo
a820ac9d 636 fwrite($stream,"EHLO $helohost\r\n");
a15f9d93 637
638 $ehlo=array();
639 $ehlo_error = false;
640 while ($line=fgets($stream, 1024)){
641 if (preg_match("/^250(-|\s)(\S*)\s+(\S.*)/",$line,$match)||
f084f987 642 preg_match("/^250(-|\s)(\S*)\s+/",$line,$match)) {
a15f9d93 643 if (!isset($match[3])) {
644 // simple one word extension
645 $ehlo[strtoupper($match[2])]='';
646 } else {
647 // ehlo-keyword + ehlo-param
648 $ehlo[strtoupper($match[2])]=trim($match[3]);
649 }
650 if ($match[1]==' ') {
651 $ret = $line;
652 break;
653 }
654 } else {
dc528046 655 //
a15f9d93 656 $ehlo_error = true;
657 $ehlo[]=$line;
658 break;
659 }
660 }
661 if ($ehlo_error) {
662 do_err('SMTP EHLO failed. You need ESMTP support for SMTP STARTTLS');
663 } elseif (!array_key_exists('STARTTLS',$ehlo)) {
664 do_err('STARTTLS support is not declared by SMTP server.');
665 }
666
667 fwrite($stream,"STARTTLS\r\n");
668 $starttls_response=fgets($stream, 1024);
669 if ($starttls_response[0]!=2) {
670 $starttls_cmd_err = 'SMTP STARTTLS failed. Server replied: '
671 .htmlspecialchars($starttls_response);
672 do_err($starttls_cmd_err);
673 } elseif(! stream_socket_enable_crypto($stream,true,STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
674 do_err('Failed to enable encryption on SMTP STARTTLS connection.');
675 } else {
676 echo $IND . "SMTP STARTTLS extension looks OK.<br />\n";
677 }
678 // According to RFC we should second ehlo call here.
679 }
680
d1ae9d4c 681 fputs($stream, 'QUIT');
682 fclose($stream);
9c941728 683 echo $IND . 'SMTP server OK (<tt><small>'.
f084f987 684 trim(htmlspecialchars($smtpline))."</small></tt>)<br />\n";
d1ae9d4c 685
686 /* POP before SMTP */
687 if($pop_before_smtp) {
783e926e 688 if (empty($pop_before_smtp_host)) $pop_before_smtp_host = $smtpServerAddress;
689 $stream = fsockopen($pop_before_smtp_host, 110, $err_no, $err_str);
d1ae9d4c 690 if (!$stream) {
783e926e 691 do_err("Error connecting to POP Server ($pop_before_smtp_host:110) "
f084f987 692 . $err_no . ' : ' . htmlspecialchars($err_str));
d1ae9d4c 693 }
694
695 $tmp = fgets($stream, 1024);
696 if (substr($tmp, 0, 3) != '+OK') {
783e926e 697 do_err("Error connecting to POP Server ($pop_before_smtp_host:110)"
f084f987 698 . ' '.htmlspecialchars($tmp));
d1ae9d4c 699 }
700 fputs($stream, 'QUIT');
701 fclose($stream);
702 echo $IND . "POP-before-SMTP OK.<br />\n";
703 }
704}
705
df758744 706/**
707 * Check the IMAP server
708 */
d1ae9d4c 709echo "Checking IMAP service....<br />\n";
710
df758744 711/** Can we open a connection? */
a15f9d93 712$stream = fsockopen( ($use_imap_tls==1?'tls://':'').$imapServerAddress, $imapPort,
f084f987 713 $errorNumber, $errorString);
d1ae9d4c 714if(!$stream) {
70b71161 715 do_err("Error connecting to IMAP server \"$imapServerAddress:$imapPort\".".
f084f987 716 "Server error: ($errorNumber) ".
717 htmlspecialchars($errorString));
d1ae9d4c 718}
719
df758744 720/** Is the first response 'OK'? */
d1ae9d4c 721$imapline = fgets($stream, 1024);
722if(substr($imapline, 0,4) != '* OK') {
f084f987 723 do_err('Error connecting to IMAP server. Server error: '.
724 htmlspecialchars($imapline));
d1ae9d4c 725}
726
df758744 727echo $IND . 'IMAP server ready (<tt><small>'.
9c941728 728 htmlspecialchars(trim($imapline))."</small></tt>)<br />\n";
d1ae9d4c 729
df758744 730/** Check capabilities */
731fputs($stream, "A001 CAPABILITY\r\n");
a15f9d93 732$capline = '';
733while ($line=fgets($stream, 1024)){
f084f987 734 if (preg_match("/A001.*/",$line)) {
735 break;
736 } else {
737 $capline.=$line;
738 }
a15f9d93 739}
740
741/* don't display capabilities before STARTTLS */
1c4f110f 742if ($use_imap_tls===2 && stristr($capline, 'STARTTLS') === false) {
a15f9d93 743 do_err('Your server doesn\'t support STARTTLS.');
1c4f110f 744} elseif($use_imap_tls===2) {
a15f9d93 745 /* try starting starttls */
746 fwrite($stream,"A002 STARTTLS\r\n");
747 $starttls_line=fgets($stream, 1024);
748 if (! preg_match("/^A002 OK.*/i",$starttls_line)) {
749 $imap_starttls_err = 'IMAP STARTTLS failed. Server replied: '
f084f987 750 .htmlspecialchars($starttls_line);
a15f9d93 751 do_err($imap_starttls_err);
752 } elseif (! stream_socket_enable_crypto($stream,true,STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
753 do_err('Failed to enable encryption on IMAP connection.');
754 } else {
755 echo $IND . "IMAP STARTTLS extension looks OK.<br />\n";
756 }
757
758 // get new capability line
759 fwrite($stream,"A003 CAPABILITY\r\n");
760 $capline='';
761 while ($line=fgets($stream, 1024)){
762 if (preg_match("/A003.*/",$line)) {
763 break;
764 } else {
765 $capline.=$line;
766 }
767 }
768}
df758744 769
770echo $IND . 'Capabilities: <tt>'.htmlspecialchars($capline)."</tt><br />\n";
771
772if($imap_auth_mech == 'login' && stristr($capline, 'LOGINDISABLED') !== FALSE) {
773 do_err('Your server doesn\'t allow plaintext logins. '.
f084f987 774 'Try enabling another authentication mechanism like CRAM-MD5, DIGEST-MD5 or TLS-encryption '.
775 'in the SquirrelMail configuration.', FALSE);
df758744 776}
df758744 777
ceb7ad3c 778if (stristr($capline, 'XMAGICTRASH') !== false) {
779 $magic_trash = 'It looks like IMAP_MOVE_EXPUNGE_TO_TRASH option is turned on '
780 .'in your Courier IMAP configuration. Courier does not provide tools that '
781 .'allow to detect folder used for Trash or commands are not documented. '
782 .'SquirrelMail can\'t detect special trash folder. SquirrelMail manages '
783 .'all message deletion or move operations internally and '
784 .'IMAP_MOVE_EXPUNGE_TO_TRASH option can cause errors in message and '
785 .'folder management operations. Please turn off IMAP_MOVE_EXPUNGE_TO_TRASH '
786 .'option in Courier imapd configuration.';
787 do_err($magic_trash,false);
788}
789
0fa9bde7 790/* add warning about IMAP delivery */
791if (stristr($capline, 'XCOURIEROUTBOX') !== false) {
792 $courier_outbox = 'OUTBOX setting is enabled in your Courier imapd '
793 .'configuration. SquirrelMail uses standard SMTP protocol or sendmail '
794 .'binary to send emails. Courier IMAP delivery method is not supported'
795 .' and can create duplicate email messages.';
796 do_err($courier_outbox,false);
797}
798
df758744 799/** OK, close connection */
a15f9d93 800fputs($stream, "A004 LOGOUT\r\n");
df758744 801fclose($stream);
802
17fca61d 803echo "Checking internationalization (i18n) settings...<br />\n";
0ed3bdc3 804echo "$IND gettext - ";
805if (function_exists('gettext')) {
8f186a2a 806 echo 'Gettext functions are available.'
807 .' On some systems you must have appropriate system locales compiled.'
808 ."<br />\n";
fd72907b 809
810 /* optional setlocale() tests. Should work only on glibc systems. */
811 if (sqgetGlobalVar('testlocales',$testlocales,SQ_GET)) {
867fed37 812 include_once(SM_PATH . 'include/languages.php');
fd72907b 813 echo $IND . $IND . 'Testing translations:<br>';
814 foreach ($languages as $lang_code => $lang_data) {
815 /* don't test aliases */
816 if (isset($lang_data['NAME'])) {
817 /* locale can be $lang_code or $lang_data['LOCALE'] */
818 if (isset($lang_data['LOCALE'])) {
819 $setlocale = $lang_data['LOCALE'];
820 } else {
821 $setlocale = $lang_code;
822 }
823 /* prepare information about tested locales */
824 if (is_array($setlocale)) {
825 $display_locale = implode(', ',$setlocale);
826 $locale_count = count($setlocale);
827 } else {
828 $display_locale = $setlocale;
829 $locale_count = 1;
830 }
831 $tested_locales_msg = 'Tested '.htmlspecialchars($display_locale).' '
832 .($locale_count>1 ? 'locales':'locale'). '.';
833
834 echo $IND . $IND .$IND . $lang_data['NAME'].' (' .$lang_code. ') - ';
835 $retlocale = sq_setlocale(LC_ALL,$setlocale);
836 if (is_bool($retlocale)) {
837 echo '<font color="red">unsupported</font>. ';
838 echo $tested_locales_msg;
839 } else {
840 echo 'supported. '
841 .$tested_locales_msg
842 .' setlocale() returned "'.htmlspecialchars($retlocale).'"';
843 }
844 echo "<br />\n";
845 }
846 }
847 echo $IND . $IND . '<a href="configtest.php">Don\'t test translations</a>';
848 } else {
849 echo $IND . $IND . '<a href="configtest.php?testlocales=1">Test translations</a>. '
850 .'This test is not accurate and might work only on some systems.'
851 ."\n";
852 }
853 echo "<br />\n";
854 /* end of translation tests */
0ed3bdc3 855} else {
8f186a2a 856 echo 'Gettext functions are unavailable.'
857 .' SquirrelMail will use slower internal gettext functions.'
858 ."<br />\n";
0ed3bdc3 859}
860echo "$IND mbstring - ";
861if (function_exists('mb_detect_encoding')) {
862 echo "Mbstring functions are available.<br />\n";
863} else {
8f186a2a 864 echo 'Mbstring functions are unavailable.'
865 ." Japanese translation won't work.<br />\n";
0ed3bdc3 866}
867echo "$IND recode - ";
868if (function_exists('recode')) {
869 echo "Recode functions are available.<br />\n";
ba17b6c7 870} elseif (isset($use_php_recode) && $use_php_recode) {
0ed3bdc3 871 echo "Recode functions are unavailable.<br />\n";
872 do_err('Your configuration requires recode support, but recode support is missing.');
873} else {
874 echo "Recode functions are unavailable.<br />\n";
875}
876echo "$IND iconv - ";
877if (function_exists('iconv')) {
878 echo "Iconv functions are available.<br />\n";
ba17b6c7 879} elseif (isset($use_php_iconv) && $use_php_iconv) {
0ed3bdc3 880 echo "Iconv functions are unavailable.<br />\n";
881 do_err('Your configuration requires iconv support, but iconv support is missing.');
882} else {
883 echo "Iconv functions are unavailable.<br />\n";
884}
867fed37 885// same test as in include/init.php + date_default_timezone_set check
0ed3bdc3 886echo "$IND timezone - ";
867fed37 887if ( (!ini_get('safe_mode')) || function_exists('date_default_timezone_set') ||
f084f987 888 !strcmp(ini_get('safe_mode_allowed_env_vars'),'') ||
889 preg_match('/^([\w_]+,)*TZ/', ini_get('safe_mode_allowed_env_vars')) ) {
fd72907b 890 echo "Webmail users can change their time zone settings. \n";
0ed3bdc3 891} else {
fd72907b 892 echo "Webmail users can't change their time zone settings. \n";
4764a7ff 893}
fd72907b 894if (isset($_ENV['TZ'])) {
895 echo 'Default time zone is '.htmlspecialchars($_ENV['TZ']);
896} else {
897 echo 'Current time zone is '.date('T');
898}
899echo ".<br />\n";
d18703d3 900
4764a7ff 901// Pear DB tests
d18703d3 902echo "Checking database functions...<br />\n";
903if($addrbook_dsn || $prefs_dsn || $addrbook_global_dsn) {
134e4174 904 @include_once('DB.php');
905 if (class_exists('DB')) {
906 echo "$IND PHP Pear DB support is present.<br />\n";
907 $db_functions=array(
f084f987 908 'dbase' => 'dbase_open',
909 'fbsql' => 'fbsql_connect',
910 'interbase' => 'ibase_connect',
911 'informix' => 'ifx_connect',
912 'msql' => 'msql_connect',
913 'mssql' => 'mssql_connect',
914 'mysql' => 'mysql_connect',
915 'mysqli' => 'mysqli_connect',
916 'oci8' => 'ocilogon',
917 'odbc' => 'odbc_connect',
918 'pgsql' => 'pg_connect',
919 'sqlite' => 'sqlite_open',
920 'sybase' => 'sybase_connect'
921 );
134e4174 922
923 $dsns = array();
924 if($prefs_dsn) {
925 $dsns['preferences'] = $prefs_dsn;
926 }
927 if($addrbook_dsn) {
928 $dsns['addressbook'] = $addrbook_dsn;
929 }
930 if($addrbook_global_dsn) {
931 $dsns['global addressbook'] = $addrbook_global_dsn;
932 }
933
934 foreach($dsns as $type => $dsn) {
ba17b6c7 935 $aDsn = explode(':', $dsn);
936 $dbtype = array_shift($aDsn);
d053c206 937
134e4174 938 if(isset($db_functions[$dbtype]) && function_exists($db_functions[$dbtype])) {
939 echo "$IND$dbtype database support present.<br />\n";
d053c206 940 } elseif(!(bool)ini_get('enable_dl') || (bool)ini_get('safe_mode')) {
941 do_err($dbtype.' database support not present!');
942 } else {
943 // Non-fatal error
944 do_err($dbtype.' database support not present or not configured!
945 Trying to dynamically load '.$dbtype.' extension.
946 Please note that it is advisable to not rely on dynamic loading of extensions.', FALSE);
947 }
134e4174 948
134e4174 949
d053c206 950 // now, test this interface:
134e4174 951
d053c206 952 $dbh = DB::connect($dsn, true);
953 if (DB::isError($dbh)) {
954 do_err('Database error: '. htmlspecialchars(DB::errorMessage($dbh)) .
955 ' in ' .$type .' DSN.');
d18703d3 956 }
d053c206 957 $dbh->disconnect();
958 echo "$IND$type database connect successful.<br />\n";
134e4174 959 }
960 } else {
8f186a2a 961 $db_error='Required PHP PEAR DB support is not available.'
962 .' Is PEAR installed and is the include path set correctly to find <tt>DB.php</tt>?'
dc528046 963 .' The include path is now: "<tt>' . ini_get('include_path') . '</tt>".';
8f186a2a 964 do_err($db_error);
134e4174 965 }
4764a7ff 966} else {
d18703d3 967 echo $IND."not using database functionality.<br />\n";
0ed3bdc3 968}
7562c55b 969
970// LDAP DB tests
971echo "Checking LDAP functions...<br />\n";
972if( empty($ldap_server) ) {
134e4174 973 echo $IND."not using LDAP functionality.<br />\n";
7562c55b 974} else {
d0184454 975 if ( !function_exists('ldap_connect') ) {
7562c55b 976 do_err('Required LDAP support is not available.');
977 } else {
134e4174 978 echo "$IND LDAP support present.<br />\n";
7562c55b 979 foreach ( $ldap_server as $param ) {
980
d0184454 981 $linkid = @ldap_connect($param['host'], (empty($param['port']) ? 389 : $param['port']) );
7562c55b 982
983 if ( $linkid ) {
f084f987 984 echo "$IND LDAP connect to ".$param['host']." successful: ".$linkid."<br />\n";
91e0dccc 985
7562c55b 986 if ( !empty($param['protocol']) &&
f084f987 987 !ldap_set_option($linkid, LDAP_OPT_PROTOCOL_VERSION, $param['protocol']) ) {
7562c55b 988 do_err('Unable to set LDAP protocol');
91e0dccc 989 }
7562c55b 990
991 if ( empty($param['binddn']) ) {
d0184454 992 $bind = @ldap_bind($linkid);
7562c55b 993 } else {
eb2ae346 994 $bind = @ldap_bind($linkid, $param['binddn'], $param['bindpw']);
7562c55b 995 }
996
997 if ( $bind ) {
998 echo "$IND LDAP Bind Successful <br />";
999 } else {
1000 do_err('Unable to Bind to LDAP Server');
1001 }
91e0dccc 1002
d0184454 1003 @ldap_close($linkid);
7562c55b 1004 } else {
1005 do_err('Connection to LDAP failed');
1006 }
1007 }
1008 }
1009}
a2b193bc 1010
3a196538 1011echo '<hr width="75%" align="center">';
1012echo '<h2 align="center">Summary</h2>';
1013$footer = '<hr width="75%" align="center">';
1014if ($warnings) {
b00dce9b 1015 echo '<p>No fatal errors were found, but there was at least 1 warning. Please check the flagged issue(s) carefully, as correcting them may prevent erratic, undefined, or incorrect behavior (or flat out breakage).</p>';
f084f987 1016 echo $footer;
3a196538 1017} else {
f084f987 1018 print <<< EOF
d1ae9d4c 1019<p>Congratulations, your SquirrelMail setup looks fine to me!</p>
1020
13721b47 1021<p><a href="login.php">Login now</a></p>
d1ae9d4c 1022
1023</body>
3a196538 1024</html>
1025EOF;
f084f987 1026 echo $footer;
3a196538 1027}