Ejemplo n.º 1
0
/**
* Used to test whether we are able to connect to the database the user has specified
* and identify any problems (eg there are already tables with the names we want to use
* @param	array	$dbms should be of the format of an element of the array returned by {@link get_available_dbms get_available_dbms()}
*					necessary extensions should be loaded already
*/
function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix, $dbhost, $dbuser, $dbpasswd, $dbname, $dbport, $prefix_may_exist = false, $load_dbal = true, $unicode_check = true)
{
    global $phpbb_root_path, $phpEx, $config, $lang;
    $dbms = $dbms_details['DRIVER'];
    if ($load_dbal) {
        // Include the DB layer
        include $phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx;
    }
    // Instantiate it and set return on error true
    $sql_db = 'dbal_' . $dbms;
    $db = new $sql_db();
    $db->sql_return_on_error(true);
    // Check that we actually have a database name before going any further.....
    if ($dbms_details['DRIVER'] != 'sqlite' && $dbms_details['DRIVER'] != 'oracle' && $dbname === '') {
        $error[] = $lang['INST_ERR_DB_NO_NAME'];
        return false;
    }
    // Make sure we don't have a daft user who thinks having the SQLite database in the forum directory is a good idea
    if ($dbms_details['DRIVER'] == 'sqlite' && stripos(phpbb_realpath($dbhost), phpbb_realpath('../')) === 0) {
        $error[] = $lang['INST_ERR_DB_FORUM_PATH'];
        return false;
    }
    // Check the prefix length to ensure that index names are not too long and does not contain invalid characters
    switch ($dbms_details['DRIVER']) {
        case 'mysql':
        case 'mysqli':
            if (strspn($table_prefix, '-./\\') !== 0) {
                $error[] = $lang['INST_ERR_PREFIX_INVALID'];
                return false;
            }
            // no break;
        // no break;
        case 'postgres':
            $prefix_length = 36;
            break;
        case 'mssql':
        case 'mssql_odbc':
        case 'mssqlnative':
            $prefix_length = 90;
            break;
        case 'sqlite':
            $prefix_length = 200;
            break;
        case 'firebird':
        case 'oracle':
            $prefix_length = 6;
            break;
    }
    if (strlen($table_prefix) > $prefix_length) {
        $error[] = sprintf($lang['INST_ERR_PREFIX_TOO_LONG'], $prefix_length);
        return false;
    }
    // Try and connect ...
    if (is_array($db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true))) {
        $db_error = $db->sql_error();
        $error[] = $lang['INST_ERR_DB_CONNECT'] . '<br />' . ($db_error['message'] ? $db_error['message'] : $lang['INST_ERR_DB_NO_ERROR']);
    } else {
        // Likely matches for an existing phpBB installation
        if (!$prefix_may_exist) {
            $temp_prefix = strtolower($table_prefix);
            $table_ary = array($temp_prefix . 'attachments', $temp_prefix . 'config', $temp_prefix . 'sessions', $temp_prefix . 'topics', $temp_prefix . 'users');
            $tables = get_tables($db);
            $tables = array_map('strtolower', $tables);
            $table_intersect = array_intersect($tables, $table_ary);
            if (sizeof($table_intersect)) {
                $error[] = $lang['INST_ERR_PREFIX'];
            }
        }
        // Make sure that the user has selected a sensible DBAL for the DBMS actually installed
        switch ($dbms_details['DRIVER']) {
            case 'mysqli':
                if (version_compare(mysqli_get_server_info($db->db_connect_id), '4.1.3', '<')) {
                    $error[] = $lang['INST_ERR_DB_NO_MYSQLI'];
                }
                break;
            case 'sqlite':
                if (version_compare(sqlite_libversion(), '2.8.2', '<')) {
                    $error[] = $lang['INST_ERR_DB_NO_SQLITE'];
                }
                break;
            case 'firebird':
                // check the version of FB, use some hackery if we can't get access to the server info
                if ($db->service_handle !== false && function_exists('ibase_server_info')) {
                    $val = @ibase_server_info($db->service_handle, IBASE_SVC_SERVER_VERSION);
                    preg_match('#V([\\d.]+)#', $val, $match);
                    if ($match[1] < 2) {
                        $error[] = $lang['INST_ERR_DB_NO_FIREBIRD'];
                    }
                    $db_info = @ibase_db_info($db->service_handle, $dbname, IBASE_STS_HDR_PAGES);
                    preg_match('/^\\s*Page size\\s*(\\d+)/m', $db_info, $regs);
                    $page_size = intval($regs[1]);
                    if ($page_size < 8192) {
                        $error[] = $lang['INST_ERR_DB_NO_FIREBIRD_PS'];
                    }
                } else {
                    $sql = "SELECT *\n\t\t\t\t\t\tFROM RDB{$FUNCTIONS}\n\t\t\t\t\t\tWHERE RDB{$SYSTEM_FLAG} IS NULL\n\t\t\t\t\t\t\tAND RDB{$FUNCTION_NAME} = 'CHAR_LENGTH'";
                    $result = $db->sql_query($sql);
                    $row = $db->sql_fetchrow($result);
                    $db->sql_freeresult($result);
                    // if its a UDF, its too old
                    if ($row) {
                        $error[] = $lang['INST_ERR_DB_NO_FIREBIRD'];
                    } else {
                        $sql = 'SELECT 1 FROM RDB$DATABASE
							WHERE BIN_AND(10, 1) = 0';
                        $result = $db->sql_query($sql);
                        if (!$result) {
                            $error[] = $lang['INST_ERR_DB_NO_FIREBIRD'];
                        }
                        $db->sql_freeresult($result);
                    }
                    // Setup the stuff for our random table
                    $char_array = array_merge(range('A', 'Z'), range('0', '9'));
                    $char_len = mt_rand(7, 9);
                    $char_array_len = sizeof($char_array) - 1;
                    $final = '';
                    for ($i = 0; $i < $char_len; $i++) {
                        $final .= $char_array[mt_rand(0, $char_array_len)];
                    }
                    // Create some random table
                    $sql = 'CREATE TABLE ' . $final . " (\n\t\t\t\t\t\tFIELD1 VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE,\n\t\t\t\t\t\tFIELD2 INTEGER DEFAULT 0 NOT NULL);";
                    $db->sql_query($sql);
                    // Create an index that should fail if the page size is less than 8192
                    $sql = 'CREATE INDEX ' . $final . ' ON ' . $final . '(FIELD1, FIELD2);';
                    $db->sql_query($sql);
                    if (ibase_errmsg() !== false) {
                        $error[] = $lang['INST_ERR_DB_NO_FIREBIRD_PS'];
                    } else {
                        // Kill the old table
                        $db->sql_query('DROP TABLE ' . $final . ';');
                    }
                    unset($final);
                }
                break;
            case 'oracle':
                if ($unicode_check) {
                    $sql = "SELECT *\n\t\t\t\t\t\tFROM NLS_DATABASE_PARAMETERS\n\t\t\t\t\t\tWHERE PARAMETER = 'NLS_RDBMS_VERSION'\n\t\t\t\t\t\t\tOR PARAMETER = 'NLS_CHARACTERSET'";
                    $result = $db->sql_query($sql);
                    while ($row = $db->sql_fetchrow($result)) {
                        $stats[$row['parameter']] = $row['value'];
                    }
                    $db->sql_freeresult($result);
                    if (version_compare($stats['NLS_RDBMS_VERSION'], '9.2', '<') && $stats['NLS_CHARACTERSET'] !== 'UTF8') {
                        $error[] = $lang['INST_ERR_DB_NO_ORACLE'];
                    }
                }
                break;
            case 'postgres':
                if ($unicode_check) {
                    $sql = "SHOW server_encoding;";
                    $result = $db->sql_query($sql);
                    $row = $db->sql_fetchrow($result);
                    $db->sql_freeresult($result);
                    if ($row['server_encoding'] !== 'UNICODE' && $row['server_encoding'] !== 'UTF8') {
                        $error[] = $lang['INST_ERR_DB_NO_POSTGRES'];
                    }
                }
                break;
        }
    }
    if ($error_connect && (!isset($error) || !sizeof($error))) {
        return true;
    }
    return false;
}
Ejemplo n.º 2
0
 /**
  * Used to test whether we are able to connect to the database the user has specified
  * and identify any problems (eg there are already tables with the names we want to use
  * @param	array	$dbms should be of the format of an element of the array returned by {@link get_available_dbms get_available_dbms()}
  *					necessary extensions should be loaded already
  */
 function critical_connect_check_db($error_connect, &$error, $dbms_details, $table_prefix, $dbhost, $dbuser, $dbpasswd, $dbname, $dbport, $prefix_may_exist = false, $load_dbal = true, $unicode_check = true)
 {
     // Must be globalized here for when including the DB file
     global $phpbb_root_path, $phpEx;
     $dbms = $dbms_details['DRIVER'];
     if ($load_dbal) {
         // Include the DB layer
         include PHPBB_ROOT_PATH . 'includes/db/' . $dbms . '.' . PHP_EXT;
     }
     // Instantiate it and set return on error true
     $sql_db = 'dbal_' . $dbms;
     $db = new $sql_db();
     $db->sql_return_on_error(true);
     // Check that we actually have a database name before going any further.....
     if ($dbms_details['DRIVER'] != 'sqlite' && $dbms_details['DRIVER'] != 'oracle' && $dbname === '') {
         $error[] = 'No database name specified.';
         return false;
     }
     // Check the prefix length to ensure that index names are not too long and does not contain invalid characters
     switch ($dbms_details['DRIVER']) {
         case 'mysql':
         case 'mysqli':
             if (strspn($table_prefix, '-./\\') !== 0) {
                 $error[] = 'The table prefix you have specified is invalid for your database.';
                 return false;
             }
             // no break;
         // no break;
         case 'postgres':
             $prefix_length = 36;
             break;
         case 'mssql':
         case 'mssql_odbc':
             $prefix_length = 90;
             break;
         case 'sqlite':
             $prefix_length = 200;
             break;
         case 'firebird':
         case 'oracle':
             $prefix_length = 6;
             break;
     }
     if (strlen($table_prefix) > $prefix_length) {
         $error[] = 'The table prefix you have specified is invalid for your database.';
         return false;
     }
     // Try and connect ...
     if (is_array($db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true))) {
         $db_error = $db->sql_error();
         $error[] = 'Could not connect to the database, see error message below.' . '<br />' . ($db_error['message'] ? $db_error['message'] : 'No error message given.');
     } else {
         // Make sure that the user has selected a sensible DBAL for the DBMS actually installed
         switch ($dbms_details['DRIVER']) {
             case 'mysqli':
                 if (version_compare(mysqli_get_server_info($db->db_connect_id), '4.1.3', '<')) {
                     $error[] = 'The version of MySQL installed on this machine is incompatible with the “MySQL with MySQLi Extension” option you have selected. Please try the “MySQL” option instead.';
                 }
                 break;
             case 'sqlite':
                 if (version_compare(sqlite_libversion(), '2.8.2', '<')) {
                     $error[] = 'The version of the SQLite extension you have installed is too old, it must be upgraded to at least 2.8.2.';
                 }
                 break;
             case 'firebird':
                 // check the version of FB, use some hackery if we can't get access to the server info
                 if ($db->service_handle !== false && function_exists('ibase_server_info')) {
                     $val = @ibase_server_info($db->service_handle, IBASE_SVC_SERVER_VERSION);
                     preg_match('#V([\\d.]+)#', $val, $match);
                     if ($match[1] < 2) {
                         $error[] = 'The version of Firebird installed on this machine is older than 2.0, please upgrade to a newer version.';
                     }
                     $db_info = @ibase_db_info($db->service_handle, $dbname, IBASE_STS_HDR_PAGES);
                     preg_match('/^\\s*Page size\\s*(\\d+)/m', $db_info, $regs);
                     $page_size = intval($regs[1]);
                     if ($page_size < 8192) {
                         $error[] = 'The database you selected for Firebird has a page size less than 8192, it must be at least 8192.';
                     }
                 } else {
                     $sql = "SELECT *\n\t\t\t\t\t\t\tFROM RDB{$FUNCTIONS}\n\t\t\t\t\t\t\tWHERE RDB{$SYSTEM_FLAG} IS NULL\n\t\t\t\t\t\t\t\tAND RDB{$FUNCTION_NAME} = 'CHAR_LENGTH'";
                     $result = $db->sql_query($sql);
                     $row = $db->sql_fetchrow($result);
                     $db->sql_freeresult($result);
                     // if its a UDF, its too old
                     if ($row) {
                         $error[] = 'The version of Firebird installed on this machine is older than 2.0, please upgrade to a newer version.';
                     } else {
                         $sql = "SELECT FIRST 0 char_length('')\n\t\t\t\t\t\t\t\tFROM RDB\$DATABASE";
                         $result = $db->sql_query($sql);
                         if (!$result) {
                             $error[] = 'The version of Firebird installed on this machine is older than 2.0, please upgrade to a newer version.';
                         }
                         $db->sql_freeresult($result);
                     }
                     // Setup the stuff for our random table
                     $char_array = array_merge(range('A', 'Z'), range('0', '9'));
                     $char_len = mt_rand(7, 9);
                     $char_array_len = sizeof($char_array) - 1;
                     $final = '';
                     for ($i = 0; $i < $char_len; $i++) {
                         $final .= $char_array[mt_rand(0, $char_array_len)];
                     }
                     // Create some random table
                     $sql = 'CREATE TABLE ' . $final . " (\n\t\t\t\t\t\t\tFIELD1 VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE,\n\t\t\t\t\t\t\tFIELD2 INTEGER DEFAULT 0 NOT NULL);";
                     $db->sql_query($sql);
                     // Create an index that should fail if the page size is less than 8192
                     $sql = 'CREATE INDEX ' . $final . ' ON ' . $final . '(FIELD1, FIELD2);';
                     $db->sql_query($sql);
                     if (ibase_errmsg() !== false) {
                         $error[] = 'The database you selected for Firebird has a page size less than 8192, it must be at least 8192.';
                     } else {
                         // Kill the old table
                         $db->sql_query('DROP TABLE ' . $final . ';');
                     }
                     unset($final);
                 }
                 break;
             case 'oracle':
                 if ($unicode_check) {
                     $sql = "SELECT *\n\t\t\t\t\t\t\tFROM NLS_DATABASE_PARAMETERS\n\t\t\t\t\t\t\tWHERE PARAMETER = 'NLS_RDBMS_VERSION'\n\t\t\t\t\t\t\t\tOR PARAMETER = 'NLS_CHARACTERSET'";
                     $result = $db->sql_query($sql);
                     while ($row = $db->sql_fetchrow($result)) {
                         $stats[$row['parameter']] = $row['value'];
                     }
                     $db->sql_freeresult($result);
                     if (version_compare($stats['NLS_RDBMS_VERSION'], '9.2', '<') && $stats['NLS_CHARACTERSET'] !== 'UTF8') {
                         $error[] = 'The version of Oracle installed on this machine requires you to set the <var>NLS_CHARACTERSET</var> parameter to <var>UTF8</var>. Either upgrade your installation to 9.2+ or change the parameter.';
                     }
                 }
                 break;
             case 'postgres':
                 if ($unicode_check) {
                     $sql = "SHOW server_encoding;";
                     $result = $db->sql_query($sql);
                     $row = $db->sql_fetchrow($result);
                     $db->sql_freeresult($result);
                     if ($row['server_encoding'] !== 'UNICODE' && $row['server_encoding'] !== 'UTF8') {
                         $error[] = 'The database you have selected was not created in <var>UNICODE</var> or <var>UTF8</var> encoding. Try installing with a database in <var>UNICODE</var> or <var>UTF8</var> encoding.';
                     }
                 }
                 break;
         }
         $tables = get_tables($db);
         if (!in_array($table_prefix . 'acl_options', $tables) || !in_array($table_prefix . 'config', $tables) || !in_array($table_prefix . 'forums', $tables)) {
             $error[] = 'phpBB3 tables could not be found on this database with this table prefix.';
         }
     }
     if ($error_connect && empty($error)) {
         return true;
     }
     return false;
 }