From a6d07cd512895f9286583b629e03f68101c2db40 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 29 Mar 2013 16:28:48 +0100 Subject: [PATCH 1/8] Split database specific install/setup code to their own class --- lib/setup.php | 784 ++++----------------------------------- lib/setup/mssql.php | 180 +++++++++ lib/setup/mysql.php | 92 +++++ lib/setup/oci.php | 198 ++++++++++ lib/setup/postgresql.php | 142 +++++++ 5 files changed, 690 insertions(+), 706 deletions(-) create mode 100644 lib/setup/mssql.php create mode 100644 lib/setup/mysql.php create mode 100644 lib/setup/oci.php create mode 100644 lib/setup/postgresql.php diff --git a/lib/setup.php b/lib/setup.php index 741a1837cc..d58dece365 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -40,7 +40,7 @@ class OC_Setup { $options['directory'] = OC::$SERVERROOT."/data"; } - if($dbtype == 'mysql' or $dbtype == 'pgsql' or $dbtype == 'oci' or $dbtype == 'mssql') { //mysql and postgresql needs more config options + if($dbtype == 'mysql' or $dbtype == 'pgsql' or $dbtype == 'oci' or $dbtype == 'mssql') { // these needs more config options if($dbtype == 'mysql') $dbprettyname = 'MySQL'; else if($dbtype == 'pgsql') @@ -65,124 +65,62 @@ class OC_Setup { } } - if(count($error) == 0) { //no errors, good - $username = htmlspecialchars_decode($options['adminlogin']); - $password = htmlspecialchars_decode($options['adminpass']); - $datadir = htmlspecialchars_decode($options['directory']); + if(count($error) != 0) { + return $error; + } - if (OC_Util::runningOnWindows()) { - $datadir = rtrim(realpath($datadir), '\\'); - } + //no errors, good + $username = htmlspecialchars_decode($options['adminlogin']); + $password = htmlspecialchars_decode($options['adminpass']); + $datadir = htmlspecialchars_decode($options['directory']); - //use sqlite3 when available, otherise sqlite2 will be used. - if($dbtype=='sqlite' and class_exists('SQLite3')) { - $dbtype='sqlite3'; - } + if (OC_Util::runningOnWindows()) { + $datadir = rtrim(realpath($datadir), '\\'); + } - //generate a random salt that is used to salt the local user passwords - $salt = OC_Util::generate_random_bytes(30); - OC_Config::setValue('passwordsalt', $salt); + //use sqlite3 when available, otherise sqlite2 will be used. + if($dbtype=='sqlite' and class_exists('SQLite3')) { + $dbtype='sqlite3'; + } - //write the config file - OC_Config::setValue('datadirectory', $datadir); - OC_Config::setValue('dbtype', $dbtype); - OC_Config::setValue('version', implode('.', OC_Util::getVersion())); - if($dbtype == 'mysql') { - $dbuser = $options['dbuser']; - $dbpass = $options['dbpass']; - $dbname = $options['dbname']; - $dbhost = $options['dbhost']; - $dbtableprefix = isset($options['dbtableprefix']) ? $options['dbtableprefix'] : 'oc_'; + //generate a random salt that is used to salt the local user passwords + $salt = OC_Util::generate_random_bytes(30); + OC_Config::setValue('passwordsalt', $salt); - OC_Config::setValue('dbname', $dbname); - OC_Config::setValue('dbhost', $dbhost); - OC_Config::setValue('dbtableprefix', $dbtableprefix); + //write the config file + OC_Config::setValue('datadirectory', $datadir); + OC_Config::setValue('dbtype', $dbtype); + OC_Config::setValue('version', implode('.', OC_Util::getVersion())); + if ($dbtype == 'mysql' or $dbtype == 'pgsql' or $dbtype == 'oci' or $dbtype == 'mssql') { // these needs more config options + $dbuser = $options['dbuser']; + $dbpass = $options['dbpass']; + $dbname = $options['dbname']; + $dbhost = isset($options['dbhost']) ? $options['dbhost'] : ''; // dbhost contents is checked above + $dbtableprefix = isset($options['dbtableprefix']) ? $options['dbtableprefix'] : 'oc_'; - try { - self::setupMySQLDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $username); - } catch (DatabaseSetupException $e) { - $error[] = array( - 'error' => $e->getMessage(), - 'hint' => $e->getHint() - ); - return($error); - } + OC_Config::setValue('dbname', $dbname); + OC_Config::setValue('dbhost', $dbhost); + OC_Config::setValue('dbtableprefix', $dbtableprefix); + } + try { + if ($dbtype == 'mysql') { + \OC\Setup\MySQL::setupDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $username); } elseif($dbtype == 'pgsql') { - $dbuser = $options['dbuser']; - $dbpass = $options['dbpass']; - $dbname = $options['dbname']; - $dbhost = $options['dbhost']; - $dbtableprefix = isset($options['dbtableprefix']) ? $options['dbtableprefix'] : 'oc_'; - - OC_Config::setValue('dbname', $dbname); - OC_Config::setValue('dbhost', $dbhost); - OC_Config::setValue('dbtableprefix', $dbtableprefix); - - try { - self::setupPostgreSQLDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $username); - } catch (DatabaseSetupException $e) { - $error[] = array( - 'error' => $l->t('PostgreSQL username and/or password not valid'), - 'hint' => $l->t('You need to enter either an existing account or the administrator.') - ); - return $error; - } + \OC\Setup\PostgreSQL::setupDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $username); } elseif($dbtype == 'oci') { - $dbuser = $options['dbuser']; - $dbpass = $options['dbpass']; - $dbname = $options['dbname']; if (array_key_exists('dbtablespace', $options)) { $dbtablespace = $options['dbtablespace']; } else { $dbtablespace = 'USERS'; } - $dbhost = isset($options['dbhost'])?$options['dbhost']:''; - $dbtableprefix = isset($options['dbtableprefix']) ? $options['dbtableprefix'] : 'oc_'; - - OC_Config::setValue('dbname', $dbname); - OC_Config::setValue('dbhost', $dbhost); - OC_Config::setValue('dbtableprefix', $dbtableprefix); - - try { - self::setupOCIDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $dbtablespace, $username); - } catch (DatabaseSetupException $e) { - $error[] = array( - 'error' => $l->t('Oracle connection could not be established'), - 'hint' => $e->getMessage().' Check environment: ORACLE_HOME='.getenv('ORACLE_HOME') - .' ORACLE_SID='.getenv('ORACLE_SID') - .' LD_LIBRARY_PATH='.getenv('LD_LIBRARY_PATH') - .' NLS_LANG='.getenv('NLS_LANG') - .' tnsnames.ora is '.(is_readable(getenv('ORACLE_HOME').'/network/admin/tnsnames.ora')?'':'not ').'readable' - ); - return $error; - } + \OC\Setup\OCI::setupDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $dbtablespace, $username); } elseif ($dbtype == 'mssql') { - $dbuser = $options['dbuser']; - $dbpass = $options['dbpass']; - $dbname = $options['dbname']; - $dbhost = $options['dbhost']; - $dbtableprefix = isset($options['dbtableprefix']) ? $options['dbtableprefix'] : 'oc_'; - - OC_Config::setValue('dbname', $dbname); - OC_Config::setValue('dbhost', $dbhost); - OC_Config::setValue('dbuser', $dbuser); - OC_Config::setValue('dbpassword', $dbpass); - OC_Config::setValue('dbtableprefix', $dbtableprefix); - - try { - self::setupMSSQLDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix); - } catch (DatabaseSetupException $e) { - $error[] = array( - 'error' => 'MS SQL username and/or password not valid', - 'hint' => 'You need to enter either an existing account or the administrator.' - ); - return $error; - } + \OC\Setup\MSSQL::setupDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix); } - else { + else { // sqlite //delete the old sqlite database first, might cause infinte loops otherwise if(file_exists("$datadir/owncloud.db")) { unlink("$datadir/owncloud.db"); @@ -191,619 +129,53 @@ class OC_Setup { error_log("creating sqlite db"); OC_DB::createDbFromStructure('db_structure.xml'); } + } catch (DatabaseSetupException $e) { + $error[] = array( + 'error' => $e->getMessage(), + 'hint' => $e->getHint() + ); + return($error); + } catch (Exception $e) { + $error[] = array( + 'error' => 'Error while trying to create admin user: ' . $e->getMessage(), + 'hint' => '' + ); + return($error); + } - //create the user and group - try { - OC_User::createUser($username, $password); - } - catch(Exception $exception) { - $error[] = 'Error while trying to create admin user: ' . $exception->getMessage(); + //create the user and group + try { + OC_User::createUser($username, $password); + } + catch(Exception $exception) { + $error[] = $exception->getMessage(); + } + + if(count($error) == 0) { + OC_Appconfig::setValue('core', 'installedat', microtime(true)); + OC_Appconfig::setValue('core', 'lastupdatedat', microtime(true)); + OC_AppConfig::setValue('core', 'remote_core.css', '/core/minimizer.php'); + OC_AppConfig::setValue('core', 'remote_core.js', '/core/minimizer.php'); + + OC_Group::createGroup('admin'); + OC_Group::addToGroup($username, 'admin'); + OC_User::login($username, $password); + + //guess what this does + OC_Installer::installShippedApps(); + + //create htaccess files for apache hosts + if (isset($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) { + self::createHtaccess(); } - if(count($error) == 0) { - OC_Appconfig::setValue('core', 'installedat', microtime(true)); - OC_Appconfig::setValue('core', 'lastupdatedat', microtime(true)); - OC_AppConfig::setValue('core', 'remote_core.css', '/core/minimizer.php'); - OC_AppConfig::setValue('core', 'remote_core.js', '/core/minimizer.php'); - - OC_Group::createGroup('admin'); - OC_Group::addToGroup($username, 'admin'); - OC_User::login($username, $password); - - //guess what this does - OC_Installer::installShippedApps(); - - //create htaccess files for apache hosts - if (isset($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) { - self::createHtaccess(); - } - - //and we are done - OC_Config::setValue('installed', true); - } + //and we are done + OC_Config::setValue('installed', true); } return $error; } - private static function setupMySQLDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $username) { - //check if the database user has admin right - $l = self::getTrans(); - $connection = @mysql_connect($dbhost, $dbuser, $dbpass); - if(!$connection) { - throw new DatabaseSetupException($l->t('MySQL username and/or password not valid'), - $l->t('You need to enter either an existing account or the administrator.')); - } - $oldUser=OC_Config::getValue('dbuser', false); - - //this should be enough to check for admin rights in mysql - $query="SELECT user FROM mysql.user WHERE user='$dbuser'"; - if(mysql_query($query, $connection)) { - //use the admin login data for the new database user - - //add prefix to the mysql user name to prevent collisions - $dbusername=substr('oc_'.$username, 0, 16); - if($dbusername!=$oldUser) { - //hash the password so we don't need to store the admin config in the config file - $dbpassword=OC_Util::generate_random_bytes(30); - - self::createDBUser($dbusername, $dbpassword, $connection); - - OC_Config::setValue('dbuser', $dbusername); - OC_Config::setValue('dbpassword', $dbpassword); - } - - //create the database - self::createMySQLDatabase($dbname, $dbusername, $connection); - } - else { - if($dbuser!=$oldUser) { - OC_Config::setValue('dbuser', $dbuser); - OC_Config::setValue('dbpassword', $dbpass); - } - - //create the database - self::createMySQLDatabase($dbname, $dbuser, $connection); - } - - //fill the database if needed - $query='select count(*) from information_schema.tables' - ." where table_schema='$dbname' AND table_name = '{$dbtableprefix}users';"; - $result = mysql_query($query, $connection); - if($result) { - $row=mysql_fetch_row($result); - } - if(!$result or $row[0]==0) { - OC_DB::createDbFromStructure('db_structure.xml'); - } - mysql_close($connection); - } - - private static function createMySQLDatabase($name, $user, $connection) { - //we cant use OC_BD functions here because we need to connect as the administrative user. - $l = self::getTrans(); - $query = "CREATE DATABASE IF NOT EXISTS `$name`"; - $result = mysql_query($query, $connection); - if(!$result) { - $entry = $l->t('DB Error: "%s"', array(mysql_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; - \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); - } - $query="GRANT ALL PRIVILEGES ON `$name` . * TO '$user'"; - - //this query will fail if there aren't the right permissions, ignore the error - mysql_query($query, $connection); - } - - private static function createDBUser($name, $password, $connection) { - // we need to create 2 accounts, one for global use and one for local user. if we don't specify the local one, - // the anonymous user would take precedence when there is one. - $l = self::getTrans(); - $query = "CREATE USER '$name'@'localhost' IDENTIFIED BY '$password'"; - $result = mysql_query($query, $connection); - if (!$result) { - throw new DatabaseSetupException($l->t("MySQL user '%s'@'localhost' exists already.", - array($name)), $l->t("Drop this user from MySQL", array($name))); - } - $query = "CREATE USER '$name'@'%' IDENTIFIED BY '$password'"; - $result = mysql_query($query, $connection); - if (!$result) { - throw new DatabaseSetupException($l->t("MySQL user '%s'@'%%' already exists", array($name)), - $l->t("Drop this user from MySQL.")); - } - } - - private static function setupPostgreSQLDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $username) { - $e_host = addslashes($dbhost); - $e_user = addslashes($dbuser); - $e_password = addslashes($dbpass); - $l = self::getTrans(); - - //check if the database user has admin rights - $connection_string = "host='$e_host' dbname=postgres user='$e_user' password='$e_password'"; - $connection = @pg_connect($connection_string); - if(!$connection) { - // Try if we can connect to the DB with the specified name - $e_dbname = addslashes($dbname); - $connection_string = "host='$e_host' dbname='$e_dbname' user='$e_user' password='$e_password'"; - $connection = @pg_connect($connection_string); - - if(!$connection) - throw new DatabaseSetupException($l->t('PostgreSQL username and/or password not valid')); - } - $e_user = pg_escape_string($dbuser); - //check for roles creation rights in postgresql - $query="SELECT 1 FROM pg_roles WHERE rolcreaterole=TRUE AND rolname='$e_user'"; - $result = pg_query($connection, $query); - if($result and pg_num_rows($result) > 0) { - //use the admin login data for the new database user - - //add prefix to the postgresql user name to prevent collisions - $dbusername='oc_'.$username; - //create a new password so we don't need to store the admin config in the config file - $dbpassword=OC_Util::generate_random_bytes(30); - - self::pg_createDBUser($dbusername, $dbpassword, $connection); - - OC_Config::setValue('dbuser', $dbusername); - OC_Config::setValue('dbpassword', $dbpassword); - - //create the database - self::pg_createDatabase($dbname, $dbusername, $connection); - } - else { - OC_Config::setValue('dbuser', $dbuser); - OC_Config::setValue('dbpassword', $dbpass); - - //create the database - self::pg_createDatabase($dbname, $dbuser, $connection); - } - - // the connection to dbname=postgres is not needed anymore - pg_close($connection); - - // connect to the ownCloud database (dbname=$dbname) and check if it needs to be filled - $dbuser = OC_Config::getValue('dbuser'); - $dbpass = OC_Config::getValue('dbpassword'); - - $e_host = addslashes($dbhost); - $e_dbname = addslashes($dbname); - $e_user = addslashes($dbuser); - $e_password = addslashes($dbpass); - - $connection_string = "host='$e_host' dbname='$e_dbname' user='$e_user' password='$e_password'"; - $connection = @pg_connect($connection_string); - if(!$connection) { - throw new DatabaseSetupException($l->t('PostgreSQL username and/or password not valid')); - } - $query = "select count(*) FROM pg_class WHERE relname='{$dbtableprefix}users' limit 1"; - $result = pg_query($connection, $query); - if($result) { - $row = pg_fetch_row($result); - } - if(!$result or $row[0]==0) { - OC_DB::createDbFromStructure('db_structure.xml'); - } - } - - private static function pg_createDatabase($name, $user, $connection) { - - //we cant use OC_BD functions here because we need to connect as the administrative user. - $l = self::getTrans(); - $e_name = pg_escape_string($name); - $e_user = pg_escape_string($user); - $query = "select datname from pg_database where datname = '$e_name'"; - $result = pg_query($connection, $query); - if(!$result) { - $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; - \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); - } - if(! pg_fetch_row($result)) { - //The database does not exists... let's create it - $query = "CREATE DATABASE \"$e_name\" OWNER \"$e_user\""; - $result = pg_query($connection, $query); - if(!$result) { - $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; - \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); - } - else { - $query = "REVOKE ALL PRIVILEGES ON DATABASE \"$e_name\" FROM PUBLIC"; - pg_query($connection, $query); - } - } - } - - private static function pg_createDBUser($name, $password, $connection) { - $l = self::getTrans(); - $e_name = pg_escape_string($name); - $e_password = pg_escape_string($password); - $query = "select * from pg_roles where rolname='$e_name';"; - $result = pg_query($connection, $query); - if(!$result) { - $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; - \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); - } - - if(! pg_fetch_row($result)) { - //user does not exists let's create it :) - $query = "CREATE USER \"$e_name\" CREATEDB PASSWORD '$e_password';"; - $result = pg_query($connection, $query); - if(!$result) { - $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; - \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); - } - } - else { // change password of the existing role - $query = "ALTER ROLE \"$e_name\" WITH PASSWORD '$e_password';"; - $result = pg_query($connection, $query); - if(!$result) { - $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; - \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); - } - } - } - - private static function setupOCIDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $dbtablespace, - $username) { - $l = self::getTrans(); - $e_host = addslashes($dbhost); - $e_dbname = addslashes($dbname); - //check if the database user has admin right - if ($e_host == '') { - $easy_connect_string = $e_dbname; // use dbname as easy connect name - } else { - $easy_connect_string = '//'.$e_host.'/'.$e_dbname; - } - \OC_Log::write('setup oracle', 'connect string: ' . $easy_connect_string, \OC_Log::DEBUG); - $connection = @oci_connect($dbuser, $dbpass, $easy_connect_string); - if(!$connection) { - $e = oci_error(); - if (is_array ($e) && isset ($e['message'])) { - throw new DatabaseSetupException($e['message']); - } - throw new DatabaseSetupException($l->t('Oracle username and/or password not valid')); - } - //check for roles creation rights in oracle - - $query='SELECT count(*) FROM user_role_privs, role_sys_privs' - ." WHERE user_role_privs.granted_role = role_sys_privs.role AND privilege = 'CREATE ROLE'"; - $stmt = oci_parse($connection, $query); - if (!$stmt) { - $entry = $l->t('DB Error: "%s"', array(oci_last_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; - \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); - } - $result = oci_execute($stmt); - if($result) { - $row = oci_fetch_row($stmt); - } - if($result and $row[0] > 0) { - //use the admin login data for the new database user - - //add prefix to the oracle user name to prevent collisions - $dbusername='oc_'.$username; - //create a new password so we don't need to store the admin config in the config file - $dbpassword=OC_Util::generate_random_bytes(30); - - //oracle passwords are treated as identifiers: - // must start with aphanumeric char - // needs to be shortened to 30 bytes, as the two " needed to escape the identifier count towards the identifier length. - $dbpassword=substr($dbpassword, 0, 30); - - self::oci_createDBUser($dbusername, $dbpassword, $dbtablespace, $connection); - - OC_Config::setValue('dbuser', $dbusername); - OC_Config::setValue('dbname', $dbusername); - OC_Config::setValue('dbpassword', $dbpassword); - - //create the database not neccessary, oracle implies user = schema - //self::oci_createDatabase($dbname, $dbusername, $connection); - } else { - - OC_Config::setValue('dbuser', $dbuser); - OC_Config::setValue('dbname', $dbname); - OC_Config::setValue('dbpassword', $dbpass); - - //create the database not neccessary, oracle implies user = schema - //self::oci_createDatabase($dbname, $dbuser, $connection); - } - - //FIXME check tablespace exists: select * from user_tablespaces - - // the connection to dbname=oracle is not needed anymore - oci_close($connection); - - // connect to the oracle database (schema=$dbuser) an check if the schema needs to be filled - $dbuser = OC_Config::getValue('dbuser'); - //$dbname = OC_Config::getValue('dbname'); - $dbpass = OC_Config::getValue('dbpassword'); - - $e_host = addslashes($dbhost); - $e_dbname = addslashes($dbname); - - if ($e_host == '') { - $easy_connect_string = $e_dbname; // use dbname as easy connect name - } else { - $easy_connect_string = '//'.$e_host.'/'.$e_dbname; - } - $connection = @oci_connect($dbuser, $dbpass, $easy_connect_string); - if(!$connection) { - throw new DatabaseSetupException($l->t('Oracle username and/or password not valid')); - } - $query = "SELECT count(*) FROM user_tables WHERE table_name = :un"; - $stmt = oci_parse($connection, $query); - $un = $dbtableprefix.'users'; - oci_bind_by_name($stmt, ':un', $un); - if (!$stmt) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; - \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); - } - $result = oci_execute($stmt); - - if($result) { - $row = oci_fetch_row($stmt); - } - if(!$result or $row[0]==0) { - OC_DB::createDbFromStructure('db_structure.xml'); - } - } - - /** - * - * @param String $name - * @param String $password - * @param String $tablespace - * @param resource $connection - */ - private static function oci_createDBUser($name, $password, $tablespace, $connection) { - $l = self::getTrans(); - $query = "SELECT * FROM all_users WHERE USERNAME = :un"; - $stmt = oci_parse($connection, $query); - if (!$stmt) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; - \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); - } - oci_bind_by_name($stmt, ':un', $name); - $result = oci_execute($stmt); - if(!$result) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; - \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); - } - - if(! oci_fetch_row($stmt)) { - //user does not exists let's create it :) - //password must start with alphabetic character in oracle - $query = 'CREATE USER '.$name.' IDENTIFIED BY "'.$password.'" DEFAULT TABLESPACE '.$tablespace; //TODO set default tablespace - $stmt = oci_parse($connection, $query); - if (!$stmt) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; - \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); - } - //oci_bind_by_name($stmt, ':un', $name); - $result = oci_execute($stmt); - if(!$result) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s", name: %s, password: %s', - array($query, $name, $password)) . '
'; - \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); - } - } else { // change password of the existing role - $query = "ALTER USER :un IDENTIFIED BY :pw"; - $stmt = oci_parse($connection, $query); - if (!$stmt) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; - \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); - } - oci_bind_by_name($stmt, ':un', $name); - oci_bind_by_name($stmt, ':pw', $password); - $result = oci_execute($stmt); - if(!$result) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; - \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); - } - } - // grant necessary roles - $query = 'GRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER, UNLIMITED TABLESPACE TO '.$name; - $stmt = oci_parse($connection, $query); - if (!$stmt) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; - \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); - } - $result = oci_execute($stmt); - if(!$result) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s", name: %s, password: %s', - array($query, $name, $password)) . '
'; - \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); - } - } - - private static function setupMSSQLDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix) { - $l = self::getTrans(); - - //check if the database user has admin right - $masterConnectionInfo = array( "Database" => "master", "UID" => $dbuser, "PWD" => $dbpass); - - $masterConnection = @sqlsrv_connect($dbhost, $masterConnectionInfo); - if(!$masterConnection) { - $entry = null; - if( ($errors = sqlsrv_errors() ) != null) { - $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; - } else { - $entry = ''; - } - throw new DatabaseSetupException($l->t('MS SQL username and/or password not valid: %s', array($entry))); - } - - OC_Config::setValue('dbuser', $dbuser); - OC_Config::setValue('dbpassword', $dbpass); - - self::mssql_createDBLogin($dbuser, $dbpass, $masterConnection); - - self::mssql_createDatabase($dbname, $masterConnection); - - self::mssql_createDBUser($dbuser, $dbname, $masterConnection); - - sqlsrv_close($masterConnection); - - self::mssql_createDatabaseStructure($dbhost, $dbname, $dbuser, $dbpass, $dbtableprefix); - } - - private static function mssql_createDBLogin($name, $password, $connection) { - $query = "SELECT * FROM master.sys.server_principals WHERE name = '".$name."';"; - $result = sqlsrv_query($connection, $query); - if ($result === false) { - if ( ($errors = sqlsrv_errors() ) != null) { - $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; - } else { - $entry = ''; - } - $entry.='Offending command was: '.$query.'
'; - \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); - } else { - $row = sqlsrv_fetch_array($result); - - if ($row === false) { - if ( ($errors = sqlsrv_errors() ) != null) { - $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; - } else { - $entry = ''; - } - $entry.='Offending command was: '.$query.'
'; - \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); - } else { - if ($row == null) { - $query = "CREATE LOGIN [".$name."] WITH PASSWORD = '".$password."';"; - $result = sqlsrv_query($connection, $query); - if (!$result or $result === false) { - if ( ($errors = sqlsrv_errors() ) != null) { - $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; - } else { - $entry = ''; - } - $entry.='Offending command was: '.$query.'
'; - \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); - } - } - } - } - } - - private static function mssql_createDBUser($name, $dbname, $connection) { - $query = "SELECT * FROM [".$dbname."].sys.database_principals WHERE name = '".$name."';"; - $result = sqlsrv_query($connection, $query); - if ($result === false) { - if ( ($errors = sqlsrv_errors() ) != null) { - $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; - } else { - $entry = ''; - } - $entry.='Offending command was: '.$query.'
'; - \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); - } else { - $row = sqlsrv_fetch_array($result); - - if ($row === false) { - if ( ($errors = sqlsrv_errors() ) != null) { - $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; - } else { - $entry = ''; - } - $entry.='Offending command was: '.$query.'
'; - \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); - } else { - if ($row == null) { - $query = "USE [".$dbname."]; CREATE USER [".$name."] FOR LOGIN [".$name."];"; - $result = sqlsrv_query($connection, $query); - if (!$result || $result === false) { - if ( ($errors = sqlsrv_errors() ) != null) { - $entry = 'DB Error: "'.print_r(sqlsrv_errors()).'"
'; - } else { - $entry = ''; - } - $entry.='Offending command was: '.$query.'
'; - \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); - } - } - - $query = "USE [".$dbname."]; EXEC sp_addrolemember 'db_owner', '".$name."';"; - $result = sqlsrv_query($connection, $query); - if (!$result || $result === false) { - if ( ($errors = sqlsrv_errors() ) != null) { - $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; - } else { - $entry = ''; - } - $entry.='Offending command was: '.$query.'
'; - \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); - } - } - } - } - - private static function mssql_createDatabase($dbname, $connection) { - $query = "CREATE DATABASE [".$dbname."];"; - $result = sqlsrv_query($connection, $query); - if (!$result || $result === false) { - if ( ($errors = sqlsrv_errors() ) != null) { - $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; - } else { - $entry = ''; - } - $entry.='Offending command was: '.$query.'
'; - \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); - } - } - - private static function mssql_createDatabaseStructure($dbhost, $dbname, $dbuser, $dbpass, $dbtableprefix) { - $connectionInfo = array( "Database" => $dbname, "UID" => $dbuser, "PWD" => $dbpass); - - $connection = @sqlsrv_connect($dbhost, $connectionInfo); - - //fill the database if needed - $query = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{$dbname}' AND TABLE_NAME = '{$dbtableprefix}users'"; - $result = sqlsrv_query($connection, $query); - if ($result === false) { - if ( ($errors = sqlsrv_errors() ) != null) { - $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; - } else { - $entry = ''; - } - $entry.='Offending command was: '.$query.'
'; - \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); - } else { - $row = sqlsrv_fetch_array($result); - - if ($row === false) { - if ( ($errors = sqlsrv_errors() ) != null) { - $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; - } else { - $entry = ''; - } - $entry.='Offending command was: '.$query.'
'; - \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); - } else { - if ($row == null) { - OC_DB::createDbFromStructure('db_structure.xml'); - } - } - } - - sqlsrv_close($connection); - } - /** * create .htaccess files for apache hosts */ diff --git a/lib/setup/mssql.php b/lib/setup/mssql.php new file mode 100644 index 0000000000..b3e08fb4fa --- /dev/null +++ b/lib/setup/mssql.php @@ -0,0 +1,180 @@ + "master", "UID" => $dbuser, "PWD" => $dbpass); + + $masterConnection = @sqlsrv_connect($dbhost, $masterConnectionInfo); + if(!$masterConnection) { + $entry = null; + if( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; + } else { + $entry = ''; + } + throw new DatabaseSetupException($l->t('MS SQL username and/or password not valid: %s', array($entry)), + $l->t('You need to enter either an existing account or the administrator.')); + } + + \OC_Config::setValue('dbuser', $dbuser); + \OC_Config::setValue('dbpassword', $dbpass); + + self::createDBLogin($dbuser, $dbpass, $masterConnection); + + self::createDatabase($dbname, $masterConnection); + + self::createDBUser($dbuser, $dbname, $masterConnection); + + sqlsrv_close($masterConnection); + + self::createDatabaseStructure($dbhost, $dbname, $dbuser, $dbpass, $dbtableprefix); + } + + private static function createDBLogin($name, $password, $connection) { + $query = "SELECT * FROM master.sys.server_principals WHERE name = '".$name."';"; + $result = sqlsrv_query($connection, $query); + if ($result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'
'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + $row = sqlsrv_fetch_array($result); + + if ($row === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'
'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + if ($row == null) { + $query = "CREATE LOGIN [".$name."] WITH PASSWORD = '".$password."';"; + $result = sqlsrv_query($connection, $query); + if (!$result or $result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'
'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } + } + } + } + } + + private static function createDBUser($name, $dbname, $connection) { + $query = "SELECT * FROM [".$dbname."].sys.database_principals WHERE name = '".$name."';"; + $result = sqlsrv_query($connection, $query); + if ($result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'
'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + $row = sqlsrv_fetch_array($result); + + if ($row === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'
'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + if ($row == null) { + $query = "USE [".$dbname."]; CREATE USER [".$name."] FOR LOGIN [".$name."];"; + $result = sqlsrv_query($connection, $query); + if (!$result || $result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry = 'DB Error: "'.print_r(sqlsrv_errors()).'"
'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'
'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } + } + + $query = "USE [".$dbname."]; EXEC sp_addrolemember 'db_owner', '".$name."';"; + $result = sqlsrv_query($connection, $query); + if (!$result || $result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'
'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } + } + } + } + + private static function createDatabase($dbname, $connection) { + $query = "CREATE DATABASE [".$dbname."];"; + $result = sqlsrv_query($connection, $query); + if (!$result || $result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'
'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } + } + + private static function createDatabaseStructure($dbhost, $dbname, $dbuser, $dbpass, $dbtableprefix) { + $connectionInfo = array( "Database" => $dbname, "UID" => $dbuser, "PWD" => $dbpass); + + $connection = @sqlsrv_connect($dbhost, $connectionInfo); + + //fill the database if needed + $query = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{$dbname}' AND TABLE_NAME = '{$dbtableprefix}users'"; + $result = sqlsrv_query($connection, $query); + if ($result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'
'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + $row = sqlsrv_fetch_array($result); + + if ($row === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"
'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'
'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + if ($row == null) { + \OC_DB::createDbFromStructure('db_structure.xml'); + } + } + } + + sqlsrv_close($connection); + } +} diff --git a/lib/setup/mysql.php b/lib/setup/mysql.php new file mode 100644 index 0000000000..92ed5b4252 --- /dev/null +++ b/lib/setup/mysql.php @@ -0,0 +1,92 @@ +t('MySQL username and/or password not valid'), + $l->t('You need to enter either an existing account or the administrator.')); + } + $oldUser=\OC_Config::getValue('dbuser', false); + + //this should be enough to check for admin rights in mysql + $query="SELECT user FROM mysql.user WHERE user='$dbuser'"; + if(mysql_query($query, $connection)) { + //use the admin login data for the new database user + + //add prefix to the mysql user name to prevent collisions + $dbusername=substr('oc_'.$username, 0, 16); + if($dbusername!=$oldUser) { + //hash the password so we don't need to store the admin config in the config file + $dbpassword=OC_Util::generate_random_bytes(30); + + self::createDBUser($dbusername, $dbpassword, $connection); + + \OC_Config::setValue('dbuser', $dbusername); + \OC_Config::setValue('dbpassword', $dbpassword); + } + + //create the database + self::createDatabase($dbname, $dbusername, $connection); + } + else { + if($dbuser!=$oldUser) { + \OC_Config::setValue('dbuser', $dbuser); + \OC_Config::setValue('dbpassword', $dbpass); + } + + //create the database + self::createDatabase($dbname, $dbuser, $connection); + } + + //fill the database if needed + $query='select count(*) from information_schema.tables' + ." where table_schema='$dbname' AND table_name = '{$dbtableprefix}users';"; + $result = mysql_query($query, $connection); + if($result) { + $row=mysql_fetch_row($result); + } + if(!$result or $row[0]==0) { + \OC_DB::createDbFromStructure('db_structure.xml'); + } + mysql_close($connection); + } + + private static function createDatabase($name, $user, $connection) { + //we cant use OC_BD functions here because we need to connect as the administrative user. + $l = \OC_Setup::getTrans(); + $query = "CREATE DATABASE IF NOT EXISTS `$name`"; + $result = mysql_query($query, $connection); + if(!$result) { + $entry = $l->t('DB Error: "%s"', array(mysql_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } + $query="GRANT ALL PRIVILEGES ON `$name` . * TO '$user'"; + + //this query will fail if there aren't the right permissions, ignore the error + mysql_query($query, $connection); + } + + private static function createDBUser($name, $password, $connection) { + // we need to create 2 accounts, one for global use and one for local user. if we don't specify the local one, + // the anonymous user would take precedence when there is one. + $l = \OC_Setup::getTrans(); + $query = "CREATE USER '$name'@'localhost' IDENTIFIED BY '$password'"; + $result = mysql_query($query, $connection); + if (!$result) { + throw new DatabaseSetupException($l->t("MySQL user '%s'@'localhost' exists already.", array($name)), + $l->t("Drop this user from MySQL", array($name))); + } + $query = "CREATE USER '$name'@'%' IDENTIFIED BY '$password'"; + $result = mysql_query($query, $connection); + if (!$result) { + throw new DatabaseSetupException($l->t("MySQL user '%s'@'%%' already exists", array($name)), + $l->t("Drop this user from MySQL.")); + } + } +} diff --git a/lib/setup/oci.php b/lib/setup/oci.php new file mode 100644 index 0000000000..9694d460dc --- /dev/null +++ b/lib/setup/oci.php @@ -0,0 +1,198 @@ +t('Oracle connection could not be established'), + $e['message'].' Check environment: ORACLE_HOME='.getenv('ORACLE_HOME') + .' ORACLE_SID='.getenv('ORACLE_SID') + .' LD_LIBRARY_PATH='.getenv('LD_LIBRARY_PATH') + .' NLS_LANG='.getenv('NLS_LANG') + .' tnsnames.ora is '.(is_readable(getenv('ORACLE_HOME').'/network/admin/tnsnames.ora')?'':'not ').'readable'); + } + throw new DatabaseSetupException($l->t($l->t('Oracle username and/or password not valid'), + 'Check environment: ORACLE_HOME='.getenv('ORACLE_HOME') + .' ORACLE_SID='.getenv('ORACLE_SID') + .' LD_LIBRARY_PATH='.getenv('LD_LIBRARY_PATH') + .' NLS_LANG='.getenv('NLS_LANG') + .' tnsnames.ora is '.(is_readable(getenv('ORACLE_HOME').'/network/admin/tnsnames.ora')?'':'not ').'readable'); + } + //check for roles creation rights in oracle + + $query='SELECT count(*) FROM user_role_privs, role_sys_privs' + ." WHERE user_role_privs.granted_role = role_sys_privs.role AND privilege = 'CREATE ROLE'"; + $stmt = oci_parse($connection, $query); + if (!$stmt) { + $entry = $l->t('DB Error: "%s"', array(oci_last_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); + } + $result = oci_execute($stmt); + if($result) { + $row = oci_fetch_row($stmt); + } + if($result and $row[0] > 0) { + //use the admin login data for the new database user + + //add prefix to the oracle user name to prevent collisions + $dbusername='oc_'.$username; + //create a new password so we don't need to store the admin config in the config file + $dbpassword=OC_Util::generate_random_bytes(30); + + //oracle passwords are treated as identifiers: + // must start with aphanumeric char + // needs to be shortened to 30 bytes, as the two " needed to escape the identifier count towards the identifier length. + $dbpassword=substr($dbpassword, 0, 30); + + self::createDBUser($dbusername, $dbpassword, $dbtablespace, $connection); + + \OC_Config::setValue('dbuser', $dbusername); + \OC_Config::setValue('dbname', $dbusername); + \OC_Config::setValue('dbpassword', $dbpassword); + + //create the database not neccessary, oracle implies user = schema + //self::createDatabase($dbname, $dbusername, $connection); + } else { + + \OC_Config::setValue('dbuser', $dbuser); + \OC_Config::setValue('dbname', $dbname); + \OC_Config::setValue('dbpassword', $dbpass); + + //create the database not neccessary, oracle implies user = schema + //self::createDatabase($dbname, $dbuser, $connection); + } + + //FIXME check tablespace exists: select * from user_tablespaces + + // the connection to dbname=oracle is not needed anymore + oci_close($connection); + + // connect to the oracle database (schema=$dbuser) an check if the schema needs to be filled + $dbuser = \OC_Config::getValue('dbuser'); + //$dbname = \OC_Config::getValue('dbname'); + $dbpass = \OC_Config::getValue('dbpassword'); + + $e_host = addslashes($dbhost); + $e_dbname = addslashes($dbname); + + if ($e_host == '') { + $easy_connect_string = $e_dbname; // use dbname as easy connect name + } else { + $easy_connect_string = '//'.$e_host.'/'.$e_dbname; + } + $connection = @oci_connect($dbuser, $dbpass, $easy_connect_string); + if(!$connection) { + throw new DatabaseSetupException($l->t('Oracle username and/or password not valid'), + $l->t('You need to enter either an existing account or the administrator.')); + } + $query = "SELECT count(*) FROM user_tables WHERE table_name = :un"; + $stmt = oci_parse($connection, $query); + $un = $dbtableprefix.'users'; + oci_bind_by_name($stmt, ':un', $un); + if (!$stmt) { + $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); + } + $result = oci_execute($stmt); + + if($result) { + $row = oci_fetch_row($stmt); + } + if(!$result or $row[0]==0) { + \OC_DB::createDbFromStructure('db_structure.xml'); + } + } + + /** + * + * @param String $name + * @param String $password + * @param String $tablespace + * @param resource $connection + */ + private static function createDBUser($name, $password, $tablespace, $connection) { + $l = \OC_Setup::getTrans(); + $query = "SELECT * FROM all_users WHERE USERNAME = :un"; + $stmt = oci_parse($connection, $query); + if (!$stmt) { + $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); + } + oci_bind_by_name($stmt, ':un', $name); + $result = oci_execute($stmt); + if(!$result) { + $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); + } + + if(! oci_fetch_row($stmt)) { + //user does not exists let's create it :) + //password must start with alphabetic character in oracle + $query = 'CREATE USER '.$name.' IDENTIFIED BY "'.$password.'" DEFAULT TABLESPACE '.$tablespace; //TODO set default tablespace + $stmt = oci_parse($connection, $query); + if (!$stmt) { + $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); + } + //oci_bind_by_name($stmt, ':un', $name); + $result = oci_execute($stmt); + if(!$result) { + $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s", name: %s, password: %s', + array($query, $name, $password)) . '
'; + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); + } + } else { // change password of the existing role + $query = "ALTER USER :un IDENTIFIED BY :pw"; + $stmt = oci_parse($connection, $query); + if (!$stmt) { + $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); + } + oci_bind_by_name($stmt, ':un', $name); + oci_bind_by_name($stmt, ':pw', $password); + $result = oci_execute($stmt); + if(!$result) { + $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); + } + } + // grant necessary roles + $query = 'GRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER, UNLIMITED TABLESPACE TO '.$name; + $stmt = oci_parse($connection, $query); + if (!$stmt) { + $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); + } + $result = oci_execute($stmt); + if(!$result) { + $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s", name: %s, password: %s', + array($query, $name, $password)) . '
'; + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); + } + } +} diff --git a/lib/setup/postgresql.php b/lib/setup/postgresql.php new file mode 100644 index 0000000000..a86039989e --- /dev/null +++ b/lib/setup/postgresql.php @@ -0,0 +1,142 @@ +t('PostgreSQL username and/or password not valid'), + $l->t('You need to enter either an existing account or the administrator.')); + } + $e_user = pg_escape_string($dbuser); + //check for roles creation rights in postgresql + $query="SELECT 1 FROM pg_roles WHERE rolcreaterole=TRUE AND rolname='$e_user'"; + $result = pg_query($connection, $query); + if($result and pg_num_rows($result) > 0) { + //use the admin login data for the new database user + + //add prefix to the postgresql user name to prevent collisions + $dbusername='oc_'.$username; + //create a new password so we don't need to store the admin config in the config file + $dbpassword=OC_Util::generate_random_bytes(30); + + self::createDBUser($dbusername, $dbpassword, $connection); + + \OC_Config::setValue('dbuser', $dbusername); + \OC_Config::setValue('dbpassword', $dbpassword); + + //create the database + self::createDatabase($dbname, $dbusername, $connection); + } + else { + \OC_Config::setValue('dbuser', $dbuser); + \OC_Config::setValue('dbpassword', $dbpass); + + //create the database + self::createDatabase($dbname, $dbuser, $connection); + } + + // the connection to dbname=postgres is not needed anymore + pg_close($connection); + + // connect to the ownCloud database (dbname=$dbname) and check if it needs to be filled + $dbuser = \OC_Config::getValue('dbuser'); + $dbpass = \OC_Config::getValue('dbpassword'); + + $e_host = addslashes($dbhost); + $e_dbname = addslashes($dbname); + $e_user = addslashes($dbuser); + $e_password = addslashes($dbpass); + + $connection_string = "host='$e_host' dbname='$e_dbname' user='$e_user' password='$e_password'"; + $connection = @pg_connect($connection_string); + if(!$connection) { + throw new DatabaseSetupException($l->t('PostgreSQL username and/or password not valid'), + $l->t('You need to enter either an existing account or the administrator.')); + } + $query = "select count(*) FROM pg_class WHERE relname='{$dbtableprefix}users' limit 1"; + $result = pg_query($connection, $query); + if($result) { + $row = pg_fetch_row($result); + } + if(!$result or $row[0]==0) { + \OC_DB::createDbFromStructure('db_structure.xml'); + } + } + + private static function createDatabase($name, $user, $connection) { + + //we cant use OC_BD functions here because we need to connect as the administrative user. + $l = \OC_Setup::getTrans(); + $e_name = pg_escape_string($name); + $e_user = pg_escape_string($user); + $query = "select datname from pg_database where datname = '$e_name'"; + $result = pg_query($connection, $query); + if(!$result) { + $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); + } + if(! pg_fetch_row($result)) { + //The database does not exists... let's create it + $query = "CREATE DATABASE \"$e_name\" OWNER \"$e_user\""; + $result = pg_query($connection, $query); + if(!$result) { + $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); + } + else { + $query = "REVOKE ALL PRIVILEGES ON DATABASE \"$e_name\" FROM PUBLIC"; + pg_query($connection, $query); + } + } + } + + private static function createDBUser($name, $password, $connection) { + $l = \OC_Setup::getTrans(); + $e_name = pg_escape_string($name); + $e_password = pg_escape_string($password); + $query = "select * from pg_roles where rolname='$e_name';"; + $result = pg_query($connection, $query); + if(!$result) { + $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); + } + + if(! pg_fetch_row($result)) { + //user does not exists let's create it :) + $query = "CREATE USER \"$e_name\" CREATEDB PASSWORD '$e_password';"; + $result = pg_query($connection, $query); + if(!$result) { + $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); + } + } + else { // change password of the existing role + $query = "ALTER ROLE \"$e_name\" WITH PASSWORD '$e_password';"; + $result = pg_query($connection, $query); + if(!$result) { + $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; + $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); + } + } + } +} From e232907698cc1184136a14917548078e781a278a Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Tue, 2 Apr 2013 22:01:23 +0200 Subject: [PATCH 2/8] Convert database setup code to objects --- lib/setup.php | 28 +++----- lib/setup/abstractdatabase.php | 35 ++++++++++ lib/setup/mssql.php | 54 +++++++-------- lib/setup/mysql.php | 63 +++++++++--------- lib/setup/oci.php | 117 ++++++++++++++++++--------------- lib/setup/postgresql.php | 92 +++++++++++++------------- 6 files changed, 210 insertions(+), 179 deletions(-) create mode 100644 lib/setup/abstractdatabase.php diff --git a/lib/setup.php b/lib/setup.php index d58dece365..30975ae8ff 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -91,34 +91,22 @@ class OC_Setup { OC_Config::setValue('datadirectory', $datadir); OC_Config::setValue('dbtype', $dbtype); OC_Config::setValue('version', implode('.', OC_Util::getVersion())); - if ($dbtype == 'mysql' or $dbtype == 'pgsql' or $dbtype == 'oci' or $dbtype == 'mssql') { // these needs more config options - $dbuser = $options['dbuser']; - $dbpass = $options['dbpass']; - $dbname = $options['dbname']; - $dbhost = isset($options['dbhost']) ? $options['dbhost'] : ''; // dbhost contents is checked above - $dbtableprefix = isset($options['dbtableprefix']) ? $options['dbtableprefix'] : 'oc_'; - - OC_Config::setValue('dbname', $dbname); - OC_Config::setValue('dbhost', $dbhost); - OC_Config::setValue('dbtableprefix', $dbtableprefix); - } try { if ($dbtype == 'mysql') { - \OC\Setup\MySQL::setupDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $username); + $db_setup = new \OC\Setup\MySQL(self::getTrans(), $options); + $db_setup->setupDatabase($username); } elseif($dbtype == 'pgsql') { - \OC\Setup\PostgreSQL::setupDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $username); + $db_setup = new \OC\Setup\PostgreSQL(self::getTrans(), $options); + $db_setup->setupDatabase($username); } elseif($dbtype == 'oci') { - if (array_key_exists('dbtablespace', $options)) { - $dbtablespace = $options['dbtablespace']; - } else { - $dbtablespace = 'USERS'; - } - \OC\Setup\OCI::setupDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $dbtablespace, $username); + $db_setup = new \OC\Setup\OCI(self::getTrans(), $options); + $db_setup->setupDatabase($username); } elseif ($dbtype == 'mssql') { - \OC\Setup\MSSQL::setupDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix); + $db_setup = new \OC\Setup\MSSQL(self::getTrans(), $options); + $db_setup->setupDatabase($username); } else { // sqlite //delete the old sqlite database first, might cause infinte loops otherwise diff --git a/lib/setup/abstractdatabase.php b/lib/setup/abstractdatabase.php new file mode 100644 index 0000000000..cef64ee7eb --- /dev/null +++ b/lib/setup/abstractdatabase.php @@ -0,0 +1,35 @@ +trans = $trans; + $this->initialize($config); + } + + public function initialize($config) { + $dbuser = $config['dbuser']; + $dbpass = $config['dbpass']; + $dbname = $config['dbname']; + $dbhost = isset($config['dbhost']) ? $config['dbhost'] : ''; // dbhost contents is checked earlier + $dbtableprefix = isset($config['dbtableprefix']) ? $config['dbtableprefix'] : 'oc_'; + + \OC_Config::setValue('dbname', $dbname); + \OC_Config::setValue('dbhost', $dbhost); + \OC_Config::setValue('dbtableprefix', $dbtableprefix); + + $this->dbuser = $dbuser; + $this->dbpassword = $dbpass; + $this->dbname = $dbname; + $this->dbhost = $dbhost; + $this->tableprefix = $tableprefix; + } +} diff --git a/lib/setup/mssql.php b/lib/setup/mssql.php index b3e08fb4fa..a1414a9ac5 100644 --- a/lib/setup/mssql.php +++ b/lib/setup/mssql.php @@ -2,14 +2,12 @@ namespace OC\Setup; -class MSSQL { - public static function setupDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix) { - $l = \OC_Setup::getTrans(); - +class MSSQL extends AbstractDatabase { + public function setupDatabase() { //check if the database user has admin right - $masterConnectionInfo = array( "Database" => "master", "UID" => $dbuser, "PWD" => $dbpass); + $masterConnectionInfo = array( "Database" => "master", "UID" => $this->dbuser, "PWD" => $this->dbpassword); - $masterConnection = @sqlsrv_connect($dbhost, $masterConnectionInfo); + $masterConnection = @sqlsrv_connect($this->dbhost, $masterConnectionInfo); if(!$masterConnection) { $entry = null; if( ($errors = sqlsrv_errors() ) != null) { @@ -17,26 +15,26 @@ class MSSQL { } else { $entry = ''; } - throw new DatabaseSetupException($l->t('MS SQL username and/or password not valid: %s', array($entry)), - $l->t('You need to enter either an existing account or the administrator.')); + throw new \DatabaseSetupException($this->trans->t('MS SQL username and/or password not valid: %s', array($entry)), + $this->trans->t('You need to enter either an existing account or the administrator.')); } - \OC_Config::setValue('dbuser', $dbuser); - \OC_Config::setValue('dbpassword', $dbpass); + \OC_Config::setValue('dbuser', $this->dbuser); + \OC_Config::setValue('dbpassword', $this->dbpassword); - self::createDBLogin($dbuser, $dbpass, $masterConnection); + $this->createDBLogin($masterConnection); - self::createDatabase($dbname, $masterConnection); + $this->createDatabase($masterConnection); - self::createDBUser($dbuser, $dbname, $masterConnection); + $this->createDBUser($masterConnection); sqlsrv_close($masterConnection); - self::createDatabaseStructure($dbhost, $dbname, $dbuser, $dbpass, $dbtableprefix); + $this->createDatabaseStructure(); } - private static function createDBLogin($name, $password, $connection) { - $query = "SELECT * FROM master.sys.server_principals WHERE name = '".$name."';"; + private function createDBLogin($connection) { + $query = "SELECT * FROM master.sys.server_principals WHERE name = '".$this->dbuser."';"; $result = sqlsrv_query($connection, $query); if ($result === false) { if ( ($errors = sqlsrv_errors() ) != null) { @@ -59,7 +57,7 @@ class MSSQL { \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); } else { if ($row == null) { - $query = "CREATE LOGIN [".$name."] WITH PASSWORD = '".$password."';"; + $query = "CREATE LOGIN [".$this->dbuser."] WITH PASSWORD = '".$this->dbpassword."';"; $result = sqlsrv_query($connection, $query); if (!$result or $result === false) { if ( ($errors = sqlsrv_errors() ) != null) { @@ -75,8 +73,8 @@ class MSSQL { } } - private static function createDBUser($name, $dbname, $connection) { - $query = "SELECT * FROM [".$dbname."].sys.database_principals WHERE name = '".$name."';"; + private function createDBUser($connection) { + $query = "SELECT * FROM [".$this->dbname."].sys.database_principals WHERE name = '".$this->dbuser."';"; $result = sqlsrv_query($connection, $query); if ($result === false) { if ( ($errors = sqlsrv_errors() ) != null) { @@ -99,7 +97,7 @@ class MSSQL { \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); } else { if ($row == null) { - $query = "USE [".$dbname."]; CREATE USER [".$name."] FOR LOGIN [".$name."];"; + $query = "USE [".$this->dbname."]; CREATE USER [".$this->dbuser."] FOR LOGIN [".$this->dbuser."];"; $result = sqlsrv_query($connection, $query); if (!$result || $result === false) { if ( ($errors = sqlsrv_errors() ) != null) { @@ -112,7 +110,7 @@ class MSSQL { } } - $query = "USE [".$dbname."]; EXEC sp_addrolemember 'db_owner', '".$name."';"; + $query = "USE [".$this->dbname."]; EXEC sp_addrolemember 'db_owner', '".$this->dbuser."';"; $result = sqlsrv_query($connection, $query); if (!$result || $result === false) { if ( ($errors = sqlsrv_errors() ) != null) { @@ -127,8 +125,8 @@ class MSSQL { } } - private static function createDatabase($dbname, $connection) { - $query = "CREATE DATABASE [".$dbname."];"; + private function createDatabase($connection) { + $query = "CREATE DATABASE [".$this->dbname."];"; $result = sqlsrv_query($connection, $query); if (!$result || $result === false) { if ( ($errors = sqlsrv_errors() ) != null) { @@ -141,13 +139,15 @@ class MSSQL { } } - private static function createDatabaseStructure($dbhost, $dbname, $dbuser, $dbpass, $dbtableprefix) { - $connectionInfo = array( "Database" => $dbname, "UID" => $dbuser, "PWD" => $dbpass); + private function createDatabaseStructure() { + $connectionInfo = array( "Database" => $this->dbname, "UID" => $this->dbuser, "PWD" => $this->dbpassword); - $connection = @sqlsrv_connect($dbhost, $connectionInfo); + $connection = @sqlsrv_connect($this->dbhost, $connectionInfo); //fill the database if needed - $query = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{$dbname}' AND TABLE_NAME = '{$dbtableprefix}users'"; + $query = "SELECT * FROM INFORMATION_SCHEMA.TABLES" + ." WHERE TABLE_SCHEMA = '".$this->dbname."'" + ." AND TABLE_NAME = '".$this->dbtableprefix."users'"; $result = sqlsrv_query($connection, $query); if ($result === false) { if ( ($errors = sqlsrv_errors() ) != null) { diff --git a/lib/setup/mysql.php b/lib/setup/mysql.php index 92ed5b4252..790b8e8225 100644 --- a/lib/setup/mysql.php +++ b/lib/setup/mysql.php @@ -2,50 +2,49 @@ namespace OC\Setup; -class MySQL { - public static function setupDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $username) { +class MySQL extends AbstractDatabase { + public function setupDatabase($username) { //check if the database user has admin right - $l = \OC_Setup::getTrans(); - $connection = @mysql_connect($dbhost, $dbuser, $dbpass); + $connection = @mysql_connect($this->dbhost, $this->dbuser, $this->dbpassword); if(!$connection) { - throw new DatabaseSetupException($l->t('MySQL username and/or password not valid'), - $l->t('You need to enter either an existing account or the administrator.')); + throw new \DatabaseSetupException($this->trans->t('MySQL username and/or password not valid'), + $this->trans->t('You need to enter either an existing account or the administrator.')); } $oldUser=\OC_Config::getValue('dbuser', false); //this should be enough to check for admin rights in mysql - $query="SELECT user FROM mysql.user WHERE user='$dbuser'"; + $query="SELECT user FROM mysql.user WHERE user='$this->dbuser'"; if(mysql_query($query, $connection)) { //use the admin login data for the new database user //add prefix to the mysql user name to prevent collisions - $dbusername=substr('oc_'.$username, 0, 16); - if($dbusername!=$oldUser) { + $this->dbuser=substr('oc_'.$username, 0, 16); + if($this->dbuser!=$oldUser) { //hash the password so we don't need to store the admin config in the config file - $dbpassword=OC_Util::generate_random_bytes(30); + $this->dbpassword=OC_Util::generate_random_bytes(30); - self::createDBUser($dbusername, $dbpassword, $connection); + $this->createDBUser($connection); - \OC_Config::setValue('dbuser', $dbusername); - \OC_Config::setValue('dbpassword', $dbpassword); + \OC_Config::setValue('dbuser', $this->dbuser); + \OC_Config::setValue('dbpassword', $this->dbpassword); } //create the database - self::createDatabase($dbname, $dbusername, $connection); + $this->createDatabase($connection); } else { - if($dbuser!=$oldUser) { - \OC_Config::setValue('dbuser', $dbuser); - \OC_Config::setValue('dbpassword', $dbpass); + if($this->dbuser!=$oldUser) { + \OC_Config::setValue('dbuser', $this->dbuser); + \OC_Config::setValue('dbpassword', $this->dbpassword); } //create the database - self::createDatabase($dbname, $dbuser, $connection); + $this->createDatabase($connection); } //fill the database if needed $query='select count(*) from information_schema.tables' - ." where table_schema='$dbname' AND table_name = '{$dbtableprefix}users';"; + ." where table_schema='".$this->dbname."' AND table_name = '".$this->dbtableprefix."users';"; $result = mysql_query($query, $connection); if($result) { $row=mysql_fetch_row($result); @@ -56,37 +55,39 @@ class MySQL { mysql_close($connection); } - private static function createDatabase($name, $user, $connection) { + private function createDatabase($connection) { + $name = $this->dbname; + $user = $this->dbuser; //we cant use OC_BD functions here because we need to connect as the administrative user. - $l = \OC_Setup::getTrans(); - $query = "CREATE DATABASE IF NOT EXISTS `$name`"; + $query = "CREATE DATABASE IF NOT EXISTS `$name`"; $result = mysql_query($query, $connection); if(!$result) { - $entry = $l->t('DB Error: "%s"', array(mysql_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + $entry = $this->trans->t('DB Error: "%s"', array(mysql_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '
'; \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); } - $query="GRANT ALL PRIVILEGES ON `$name` . * TO '$user'"; + $query="GRANT ALL PRIVILEGES ON `$name` . * TO '$user'"; //this query will fail if there aren't the right permissions, ignore the error mysql_query($query, $connection); } - private static function createDBUser($name, $password, $connection) { + private function createDBUser($connection) { + $name = $this->dbuser; + $password = $this->dbpassword; // we need to create 2 accounts, one for global use and one for local user. if we don't specify the local one, // the anonymous user would take precedence when there is one. - $l = \OC_Setup::getTrans(); $query = "CREATE USER '$name'@'localhost' IDENTIFIED BY '$password'"; $result = mysql_query($query, $connection); if (!$result) { - throw new DatabaseSetupException($l->t("MySQL user '%s'@'localhost' exists already.", array($name)), - $l->t("Drop this user from MySQL", array($name))); + throw new \DatabaseSetupException($this->trans->t("MySQL user '%s'@'localhost' exists already.", array($name)), + $this->trans->t("Drop this user from MySQL", array($name))); } $query = "CREATE USER '$name'@'%' IDENTIFIED BY '$password'"; $result = mysql_query($query, $connection); if (!$result) { - throw new DatabaseSetupException($l->t("MySQL user '%s'@'%%' already exists", array($name)), - $l->t("Drop this user from MySQL.")); + throw new \DatabaseSetupException($this->trans->t("MySQL user '%s'@'%%' already exists", array($name)), + $this->trans->t("Drop this user from MySQL.")); } } } diff --git a/lib/setup/oci.php b/lib/setup/oci.php index 9694d460dc..3bb625c557 100644 --- a/lib/setup/oci.php +++ b/lib/setup/oci.php @@ -2,12 +2,22 @@ namespace OC\Setup; -class OCI { - public static function setupDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $dbtablespace, - $username) { - $l = \OC_Setup::getTrans(); - $e_host = addslashes($dbhost); - $e_dbname = addslashes($dbname); +class OCI extends AbstractDatabase { + protected $dbtablespace; + + public function initialize($config) { + parent::initialize($config); + if (array_key_exists('dbtablespace', $options)) { + $this->dbtablespace = $options['dbtablespace']; + } else { + $this->dbtablespace = 'USERS'; + } + \OC_Config::setValue('dbtablespace', $this->dbtablespace); + } + + public function setupDatabase($dbtablespace, $username) { + $e_host = addslashes($this->dbhost); + $e_dbname = addslashes($this->dbname); //check if the database user has admin right if ($e_host == '') { $easy_connect_string = $e_dbname; // use dbname as easy connect name @@ -15,7 +25,7 @@ class OCI { $easy_connect_string = '//'.$e_host.'/'.$e_dbname; } \OC_Log::write('setup oracle', 'connect string: ' . $easy_connect_string, \OC_Log::DEBUG); - $connection = @oci_connect($dbuser, $dbpass, $easy_connect_string); + $connection = @oci_connect($this->dbuser, $this->dbpassword, $easy_connect_string); if(!$connection) { $e = oci_error(); if (is_array ($e) && isset ($e['message'])) { @@ -26,7 +36,7 @@ class OCI { .' NLS_LANG='.getenv('NLS_LANG') .' tnsnames.ora is '.(is_readable(getenv('ORACLE_HOME').'/network/admin/tnsnames.ora')?'':'not ').'readable'); } - throw new DatabaseSetupException($l->t($l->t('Oracle username and/or password not valid'), + throw new DatabaseSetupException($l->t('Oracle username and/or password not valid'), 'Check environment: ORACLE_HOME='.getenv('ORACLE_HOME') .' ORACLE_SID='.getenv('ORACLE_SID') .' LD_LIBRARY_PATH='.getenv('LD_LIBRARY_PATH') @@ -39,8 +49,8 @@ class OCI { ." WHERE user_role_privs.granted_role = role_sys_privs.role AND privilege = 'CREATE ROLE'"; $stmt = oci_parse($connection, $query); if (!$stmt) { - $entry = $l->t('DB Error: "%s"', array(oci_last_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + $entry = $this->trans->t('DB Error: "%s"', array(oci_last_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '
'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } $result = oci_execute($stmt); @@ -51,31 +61,31 @@ class OCI { //use the admin login data for the new database user //add prefix to the oracle user name to prevent collisions - $dbusername='oc_'.$username; + $this->dbuser='oc_'.$username; //create a new password so we don't need to store the admin config in the config file - $dbpassword=OC_Util::generate_random_bytes(30); + $this->dbpassword=OC_Util::generate_random_bytes(30); //oracle passwords are treated as identifiers: // must start with aphanumeric char // needs to be shortened to 30 bytes, as the two " needed to escape the identifier count towards the identifier length. - $dbpassword=substr($dbpassword, 0, 30); + $this->dbpassword=substr($this->dbpassword, 0, 30); - self::createDBUser($dbusername, $dbpassword, $dbtablespace, $connection); + $this->createDBUser($dbtablespace, $connection); - \OC_Config::setValue('dbuser', $dbusername); - \OC_Config::setValue('dbname', $dbusername); - \OC_Config::setValue('dbpassword', $dbpassword); + \OC_Config::setValue('dbuser', $this->dbusername); + \OC_Config::setValue('dbname', $this->dbusername); + \OC_Config::setValue('dbpassword', $this->dbpassword); //create the database not neccessary, oracle implies user = schema - //self::createDatabase($dbname, $dbusername, $connection); + //$this->createDatabase($this->dbname, $this->dbusername, $connection); } else { - \OC_Config::setValue('dbuser', $dbuser); - \OC_Config::setValue('dbname', $dbname); - \OC_Config::setValue('dbpassword', $dbpass); + \OC_Config::setValue('dbuser', $this->dbuser); + \OC_Config::setValue('dbname', $this->dbname); + \OC_Config::setValue('dbpassword', $this->dbpassword); //create the database not neccessary, oracle implies user = schema - //self::createDatabase($dbname, $dbuser, $connection); + //$this->createDatabase($this->dbname, $this->dbuser, $connection); } //FIXME check tablespace exists: select * from user_tablespaces @@ -83,31 +93,31 @@ class OCI { // the connection to dbname=oracle is not needed anymore oci_close($connection); - // connect to the oracle database (schema=$dbuser) an check if the schema needs to be filled - $dbuser = \OC_Config::getValue('dbuser'); - //$dbname = \OC_Config::getValue('dbname'); - $dbpass = \OC_Config::getValue('dbpassword'); + // connect to the oracle database (schema=$this->dbuser) an check if the schema needs to be filled + $this->dbuser = \OC_Config::getValue('dbuser'); + //$this->dbname = \OC_Config::getValue('dbname'); + $this->dbpassword = \OC_Config::getValue('dbpassword'); - $e_host = addslashes($dbhost); - $e_dbname = addslashes($dbname); + $e_host = addslashes($this->dbhost); + $e_dbname = addslashes($this->dbname); if ($e_host == '') { $easy_connect_string = $e_dbname; // use dbname as easy connect name } else { $easy_connect_string = '//'.$e_host.'/'.$e_dbname; } - $connection = @oci_connect($dbuser, $dbpass, $easy_connect_string); + $connection = @oci_connect($this->dbuser, $this->dbpassword, $easy_connect_string); if(!$connection) { - throw new DatabaseSetupException($l->t('Oracle username and/or password not valid'), - $l->t('You need to enter either an existing account or the administrator.')); + throw new \DatabaseSetupException($this->trans->t('Oracle username and/or password not valid'), + $this->trans->t('You need to enter either an existing account or the administrator.')); } $query = "SELECT count(*) FROM user_tables WHERE table_name = :un"; $stmt = oci_parse($connection, $query); - $un = $dbtableprefix.'users'; + $un = $this->dbtableprefix.'users'; oci_bind_by_name($stmt, ':un', $un); if (!$stmt) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '
'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } $result = oci_execute($stmt); @@ -127,38 +137,39 @@ class OCI { * @param String $tablespace * @param resource $connection */ - private static function createDBUser($name, $password, $tablespace, $connection) { - $l = \OC_Setup::getTrans(); + private function createDBUser($tablespace, $connection) { + $name = $this->dbuser; + $password = $this->password; $query = "SELECT * FROM all_users WHERE USERNAME = :un"; $stmt = oci_parse($connection, $query); if (!$stmt) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '
'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } oci_bind_by_name($stmt, ':un', $name); $result = oci_execute($stmt); if(!$result) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '
'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } if(! oci_fetch_row($stmt)) { //user does not exists let's create it :) //password must start with alphabetic character in oracle - $query = 'CREATE USER '.$name.' IDENTIFIED BY "'.$password.'" DEFAULT TABLESPACE '.$tablespace; //TODO set default tablespace + $query = 'CREATE USER '.$name.' IDENTIFIED BY "'.$password.'" DEFAULT TABLESPACE '.$this->dbtablespace; $stmt = oci_parse($connection, $query); if (!$stmt) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '
'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } //oci_bind_by_name($stmt, ':un', $name); $result = oci_execute($stmt); if(!$result) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s", name: %s, password: %s', + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s", name: %s, password: %s', array($query, $name, $password)) . '
'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } @@ -166,16 +177,16 @@ class OCI { $query = "ALTER USER :un IDENTIFIED BY :pw"; $stmt = oci_parse($connection, $query); if (!$stmt) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '
'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } oci_bind_by_name($stmt, ':un', $name); oci_bind_by_name($stmt, ':pw', $password); $result = oci_execute($stmt); if(!$result) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '
'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } } @@ -183,14 +194,14 @@ class OCI { $query = 'GRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER, UNLIMITED TABLESPACE TO '.$name; $stmt = oci_parse($connection, $query); if (!$stmt) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '
'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } $result = oci_execute($stmt); if(!$result) { - $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s", name: %s, password: %s', + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s", name: %s, password: %s', array($query, $name, $password)) . '
'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } diff --git a/lib/setup/postgresql.php b/lib/setup/postgresql.php index a86039989e..3fb1e6b878 100644 --- a/lib/setup/postgresql.php +++ b/lib/setup/postgresql.php @@ -2,27 +2,26 @@ namespace OC\Setup; -class PostgreSQL { - public static function setupDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $username) { - $e_host = addslashes($dbhost); - $e_user = addslashes($dbuser); - $e_password = addslashes($dbpass); - $l = \OC_Setup::getTrans(); +class PostgreSQL extends AbstractDatabase { + public function setupDatabase($username) { + $e_host = addslashes($this->dbhost); + $e_user = addslashes($this->dbuser); + $e_password = addslashes($this->dbpassword); //check if the database user has admin rights $connection_string = "host='$e_host' dbname=postgres user='$e_user' password='$e_password'"; $connection = @pg_connect($connection_string); if(!$connection) { // Try if we can connect to the DB with the specified name - $e_dbname = addslashes($dbname); + $e_dbname = addslashes($this->dbname); $connection_string = "host='$e_host' dbname='$e_dbname' user='$e_user' password='$e_password'"; $connection = @pg_connect($connection_string); if(!$connection) - throw new DatabaseSetupException($l->t('PostgreSQL username and/or password not valid'), - $l->t('You need to enter either an existing account or the administrator.')); + throw new \DatabaseSetupException($this->trans->t('PostgreSQL username and/or password not valid'), + $this->trans->t('You need to enter either an existing account or the administrator.')); } - $e_user = pg_escape_string($dbuser); + $e_user = pg_escape_string($this->dbuser); //check for roles creation rights in postgresql $query="SELECT 1 FROM pg_roles WHERE rolcreaterole=TRUE AND rolname='$e_user'"; $result = pg_query($connection, $query); @@ -30,45 +29,45 @@ class PostgreSQL { //use the admin login data for the new database user //add prefix to the postgresql user name to prevent collisions - $dbusername='oc_'.$username; + $this->dbuser='oc_'.$username; //create a new password so we don't need to store the admin config in the config file - $dbpassword=OC_Util::generate_random_bytes(30); + $this->dbpassword=OC_Util::generate_random_bytes(30); - self::createDBUser($dbusername, $dbpassword, $connection); + $this->createDBUser($connection); - \OC_Config::setValue('dbuser', $dbusername); - \OC_Config::setValue('dbpassword', $dbpassword); + \OC_Config::setValue('dbuser', $this->dbuser); + \OC_Config::setValue('dbpassword', $this->dbpassword); //create the database - self::createDatabase($dbname, $dbusername, $connection); + $this->createDatabase($connection); } else { - \OC_Config::setValue('dbuser', $dbuser); - \OC_Config::setValue('dbpassword', $dbpass); + \OC_Config::setValue('dbuser', $this->dbuser); + \OC_Config::setValue('dbpassword', $this->dbpassword); //create the database - self::createDatabase($dbname, $dbuser, $connection); + $this->createDatabase($connection); } // the connection to dbname=postgres is not needed anymore pg_close($connection); - // connect to the ownCloud database (dbname=$dbname) and check if it needs to be filled - $dbuser = \OC_Config::getValue('dbuser'); - $dbpass = \OC_Config::getValue('dbpassword'); + // connect to the ownCloud database (dbname=$this->dbname) and check if it needs to be filled + $this->dbuser = \OC_Config::getValue('dbuser'); + $this->dbpassword = \OC_Config::getValue('dbpassword'); - $e_host = addslashes($dbhost); - $e_dbname = addslashes($dbname); - $e_user = addslashes($dbuser); - $e_password = addslashes($dbpass); + $e_host = addslashes($this->dbhost); + $e_dbname = addslashes($this->dbname); + $e_user = addslashes($this->dbuser); + $e_password = addslashes($this->dbpassword); $connection_string = "host='$e_host' dbname='$e_dbname' user='$e_user' password='$e_password'"; $connection = @pg_connect($connection_string); if(!$connection) { - throw new DatabaseSetupException($l->t('PostgreSQL username and/or password not valid'), - $l->t('You need to enter either an existing account or the administrator.')); + throw new \DatabaseSetupException($this->trans->t('PostgreSQL username and/or password not valid'), + $this->trans->t('You need to enter either an existing account or the administrator.')); } - $query = "select count(*) FROM pg_class WHERE relname='{$dbtableprefix}users' limit 1"; + $query = "select count(*) FROM pg_class WHERE relname='".$this->dbtableprefix."users' limit 1"; $result = pg_query($connection, $query); if($result) { $row = pg_fetch_row($result); @@ -78,17 +77,15 @@ class PostgreSQL { } } - private static function createDatabase($name, $user, $connection) { - + private function createDatabase($connection) { //we cant use OC_BD functions here because we need to connect as the administrative user. - $l = \OC_Setup::getTrans(); - $e_name = pg_escape_string($name); - $e_user = pg_escape_string($user); + $e_name = pg_escape_string($this->dbname); + $e_user = pg_escape_string($this->dbuser); $query = "select datname from pg_database where datname = '$e_name'"; $result = pg_query($connection, $query); if(!$result) { - $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + $entry = $this->trans->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '
'; \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); } if(! pg_fetch_row($result)) { @@ -96,8 +93,8 @@ class PostgreSQL { $query = "CREATE DATABASE \"$e_name\" OWNER \"$e_user\""; $result = pg_query($connection, $query); if(!$result) { - $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + $entry = $this->trans->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '
'; \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); } else { @@ -107,15 +104,14 @@ class PostgreSQL { } } - private static function createDBUser($name, $password, $connection) { - $l = \OC_Setup::getTrans(); - $e_name = pg_escape_string($name); - $e_password = pg_escape_string($password); + private function createDBUser($connection) { + $e_name = pg_escape_string($this->dbuser); + $e_password = pg_escape_string($this->dbpassword); $query = "select * from pg_roles where rolname='$e_name';"; $result = pg_query($connection, $query); if(!$result) { - $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + $entry = $this->trans->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '
'; \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); } @@ -124,8 +120,8 @@ class PostgreSQL { $query = "CREATE USER \"$e_name\" CREATEDB PASSWORD '$e_password';"; $result = pg_query($connection, $query); if(!$result) { - $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + $entry = $this->trans->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '
'; \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); } } @@ -133,8 +129,8 @@ class PostgreSQL { $query = "ALTER ROLE \"$e_name\" WITH PASSWORD '$e_password';"; $result = pg_query($connection, $query); if(!$result) { - $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; - $entry .= $l->t('Offending command was: "%s"', array($query)) . '
'; + $entry = $this->trans->t('DB Error: "%s"', array(pg_last_error($connection))) . '
'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '
'; \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); } } From 2faccaee0d22efa6b23586b65f222e8cc5404366 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 3 Apr 2013 08:31:47 +0200 Subject: [PATCH 3/8] Change database creation to use array to select db setup class --- lib/setup.php | 36 +++++++++++------------------------- lib/setup/sqlite.php | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 25 deletions(-) create mode 100644 lib/setup/sqlite.php diff --git a/lib/setup.php b/lib/setup.php index 30975ae8ff..e73ba6cdf4 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -91,32 +91,18 @@ class OC_Setup { OC_Config::setValue('datadirectory', $datadir); OC_Config::setValue('dbtype', $dbtype); OC_Config::setValue('version', implode('.', OC_Util::getVersion())); + $db_setup_classes = array( + 'mysql' => '\OC\Setup\MySQL', + 'pgsql' => '\OC\Setup\PostgreSQL', + 'oci' => '\OC\Setup\OCI', + 'mssql' => '\OC\Setup\MSSQL', + 'sqlite' => '\OC\Setup\Sqlite', + 'sqlite3' => '\OC\Setup\Sqlite', + ); try { - if ($dbtype == 'mysql') { - $db_setup = new \OC\Setup\MySQL(self::getTrans(), $options); - $db_setup->setupDatabase($username); - } - elseif($dbtype == 'pgsql') { - $db_setup = new \OC\Setup\PostgreSQL(self::getTrans(), $options); - $db_setup->setupDatabase($username); - } - elseif($dbtype == 'oci') { - $db_setup = new \OC\Setup\OCI(self::getTrans(), $options); - $db_setup->setupDatabase($username); - } - elseif ($dbtype == 'mssql') { - $db_setup = new \OC\Setup\MSSQL(self::getTrans(), $options); - $db_setup->setupDatabase($username); - } - else { // sqlite - //delete the old sqlite database first, might cause infinte loops otherwise - if(file_exists("$datadir/owncloud.db")) { - unlink("$datadir/owncloud.db"); - } - //in case of sqlite, we can always fill the database - error_log("creating sqlite db"); - OC_DB::createDbFromStructure('db_structure.xml'); - } + $class = $db_setup_classes[$dbtype]; + $db_setup = new $class(self::getTrans(), $options); + $db_setup->setupDatabase($username); } catch (DatabaseSetupException $e) { $error[] = array( 'error' => $e->getMessage(), diff --git a/lib/setup/sqlite.php b/lib/setup/sqlite.php new file mode 100644 index 0000000000..b1785ce1b0 --- /dev/null +++ b/lib/setup/sqlite.php @@ -0,0 +1,20 @@ + Date: Wed, 3 Apr 2013 17:52:18 +0200 Subject: [PATCH 4/8] Use db setup class for option validation --- lib/setup.php | 48 +++++++++++----------------------- lib/setup/abstractdatabase.php | 17 ++++++++++-- lib/setup/mssql.php | 2 ++ lib/setup/mysql.php | 2 ++ lib/setup/oci.php | 2 ++ lib/setup/postgresql.php | 2 ++ lib/setup/sqlite.php | 5 ++++ 7 files changed, 43 insertions(+), 35 deletions(-) diff --git a/lib/setup.php b/lib/setup.php index e73ba6cdf4..11c6cc76b6 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -19,6 +19,14 @@ class DatabaseSetupException extends Exception } class OC_Setup { + static $db_setup_classes = array( + 'mysql' => '\OC\Setup\MySQL', + 'pgsql' => '\OC\Setup\PostgreSQL', + 'oci' => '\OC\Setup\OCI', + 'mssql' => '\OC\Setup\MSSQL', + 'sqlite' => '\OC\Setup\Sqlite', + 'sqlite3' => '\OC\Setup\Sqlite', + ); public static function getTrans(){ return OC_L10N::get('lib'); @@ -40,31 +48,14 @@ class OC_Setup { $options['directory'] = OC::$SERVERROOT."/data"; } - if($dbtype == 'mysql' or $dbtype == 'pgsql' or $dbtype == 'oci' or $dbtype == 'mssql') { // these needs more config options - if($dbtype == 'mysql') - $dbprettyname = 'MySQL'; - else if($dbtype == 'pgsql') - $dbprettyname = 'PostgreSQL'; - else if ($dbtype == 'mssql') - $dbprettyname = 'MS SQL Server'; - else - $dbprettyname = 'Oracle'; - - - if(empty($options['dbuser'])) { - $error[] = $l->t("%s enter the database username.", array($dbprettyname)); - } - if(empty($options['dbname'])) { - $error[] = $l->t("%s enter the database name.", array($dbprettyname)); - } - if(substr_count($options['dbname'], '.') >= 1) { - $error[] = $l->t("%s you may not use dots in the database name", array($dbprettyname)); - } - if($dbtype != 'oci' && empty($options['dbhost'])) { - $options['dbhost'] = 'localhost'; - } + if (!isset(self::$db_setup_classes[$dbtype])) { + $dbtype = 'sqlite'; } + $class = self::$db_setup_classes[$dbtype]; + $db_setup = new $class(self::getTrans()); + $error = array_merge($error, $db_setup->validate($options)); + if(count($error) != 0) { return $error; } @@ -91,17 +82,8 @@ class OC_Setup { OC_Config::setValue('datadirectory', $datadir); OC_Config::setValue('dbtype', $dbtype); OC_Config::setValue('version', implode('.', OC_Util::getVersion())); - $db_setup_classes = array( - 'mysql' => '\OC\Setup\MySQL', - 'pgsql' => '\OC\Setup\PostgreSQL', - 'oci' => '\OC\Setup\OCI', - 'mssql' => '\OC\Setup\MSSQL', - 'sqlite' => '\OC\Setup\Sqlite', - 'sqlite3' => '\OC\Setup\Sqlite', - ); try { - $class = $db_setup_classes[$dbtype]; - $db_setup = new $class(self::getTrans(), $options); + $db_setup->initialize($options); $db_setup->setupDatabase($username); } catch (DatabaseSetupException $e) { $error[] = array( diff --git a/lib/setup/abstractdatabase.php b/lib/setup/abstractdatabase.php index cef64ee7eb..07a679f211 100644 --- a/lib/setup/abstractdatabase.php +++ b/lib/setup/abstractdatabase.php @@ -12,14 +12,27 @@ abstract class AbstractDatabase { public function __construct($trans, $config) { $this->trans = $trans; - $this->initialize($config); + } + + public function validate($config) { + $errors = array(); + if(empty($config['dbuser'])) { + $errors[] = $this->trans->t("%s enter the database username.", array($this->dbprettyname)); + } + if(empty($config['dbname'])) { + $errors[] = $this->trans->t("%s enter the database name.", array($this->dbprettyname)); + } + if(substr_count($config['dbname'], '.') >= 1) { + $errors[] = $this->trans->t("%s you may not use dots in the database name", array($this->dbprettyname)); + } + return $errors; } public function initialize($config) { $dbuser = $config['dbuser']; $dbpass = $config['dbpass']; $dbname = $config['dbname']; - $dbhost = isset($config['dbhost']) ? $config['dbhost'] : ''; // dbhost contents is checked earlier + $dbhost = !empty($config['dbhost']) ? $config['dbhost'] : 'localhost'; $dbtableprefix = isset($config['dbtableprefix']) ? $config['dbtableprefix'] : 'oc_'; \OC_Config::setValue('dbname', $dbname); diff --git a/lib/setup/mssql.php b/lib/setup/mssql.php index a1414a9ac5..74ac8f294a 100644 --- a/lib/setup/mssql.php +++ b/lib/setup/mssql.php @@ -3,6 +3,8 @@ namespace OC\Setup; class MSSQL extends AbstractDatabase { + public $dbprettyname = 'MS SQL Server'; + public function setupDatabase() { //check if the database user has admin right $masterConnectionInfo = array( "Database" => "master", "UID" => $this->dbuser, "PWD" => $this->dbpassword); diff --git a/lib/setup/mysql.php b/lib/setup/mysql.php index 790b8e8225..aa0344f686 100644 --- a/lib/setup/mysql.php +++ b/lib/setup/mysql.php @@ -3,6 +3,8 @@ namespace OC\Setup; class MySQL extends AbstractDatabase { + public $dbprettyname = 'MySQL'; + public function setupDatabase($username) { //check if the database user has admin right $connection = @mysql_connect($this->dbhost, $this->dbuser, $this->dbpassword); diff --git a/lib/setup/oci.php b/lib/setup/oci.php index 3bb625c557..a3e2ccc8da 100644 --- a/lib/setup/oci.php +++ b/lib/setup/oci.php @@ -3,6 +3,8 @@ namespace OC\Setup; class OCI extends AbstractDatabase { + public $dbprettyname = 'Oracle'; + protected $dbtablespace; public function initialize($config) { diff --git a/lib/setup/postgresql.php b/lib/setup/postgresql.php index 3fb1e6b878..67e4f901a9 100644 --- a/lib/setup/postgresql.php +++ b/lib/setup/postgresql.php @@ -3,6 +3,8 @@ namespace OC\Setup; class PostgreSQL extends AbstractDatabase { + public $dbprettyname = 'PostgreSQL'; + public function setupDatabase($username) { $e_host = addslashes($this->dbhost); $e_user = addslashes($this->dbuser); diff --git a/lib/setup/sqlite.php b/lib/setup/sqlite.php index b1785ce1b0..0b96ec6000 100644 --- a/lib/setup/sqlite.php +++ b/lib/setup/sqlite.php @@ -3,6 +3,11 @@ namespace OC\Setup; class Sqlite extends AbstractDatabase { + public $dbprettyname = 'Sqlite'; + + public function validate($config) { + } + public function initialize($config) { } From bf30e030488a42763c2c8981c969439bb66df91a Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 10 Apr 2013 17:57:58 +0200 Subject: [PATCH 5/8] Remove unsued parameter --- lib/setup/abstractdatabase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/setup/abstractdatabase.php b/lib/setup/abstractdatabase.php index 07a679f211..c1b611e655 100644 --- a/lib/setup/abstractdatabase.php +++ b/lib/setup/abstractdatabase.php @@ -10,7 +10,7 @@ abstract class AbstractDatabase { protected $dbhost; protected $tableprefix; - public function __construct($trans, $config) { + public function __construct($trans) { $this->trans = $trans; } From 42c44d516568b6a2bea33bcd59dd81cb0654569b Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 10 Apr 2013 20:03:54 +0200 Subject: [PATCH 6/8] Fix OCI setupDatabase parameter --- lib/setup/oci.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/setup/oci.php b/lib/setup/oci.php index a3e2ccc8da..56452c65a5 100644 --- a/lib/setup/oci.php +++ b/lib/setup/oci.php @@ -17,7 +17,7 @@ class OCI extends AbstractDatabase { \OC_Config::setValue('dbtablespace', $this->dbtablespace); } - public function setupDatabase($dbtablespace, $username) { + public function setupDatabase($username) { $e_host = addslashes($this->dbhost); $e_dbname = addslashes($this->dbname); //check if the database user has admin right @@ -72,7 +72,7 @@ class OCI extends AbstractDatabase { // needs to be shortened to 30 bytes, as the two " needed to escape the identifier count towards the identifier length. $this->dbpassword=substr($this->dbpassword, 0, 30); - $this->createDBUser($dbtablespace, $connection); + $this->createDBUser($this->dbtablespace, $connection); \OC_Config::setValue('dbuser', $this->dbusername); \OC_Config::setValue('dbname', $this->dbusername); From e93ce26f27fa8c2c364696a7a7ce5122eb4a91e2 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 11 Apr 2013 00:08:53 +0200 Subject: [PATCH 7/8] Fix found errors --- lib/setup/abstractdatabase.php | 2 +- lib/setup/mssql.php | 2 +- lib/setup/mysql.php | 4 ++-- lib/setup/oci.php | 7 +++---- lib/setup/postgresql.php | 4 ++-- lib/setup/sqlite.php | 1 + 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/setup/abstractdatabase.php b/lib/setup/abstractdatabase.php index c1b611e655..66202251e9 100644 --- a/lib/setup/abstractdatabase.php +++ b/lib/setup/abstractdatabase.php @@ -43,6 +43,6 @@ abstract class AbstractDatabase { $this->dbpassword = $dbpass; $this->dbname = $dbname; $this->dbhost = $dbhost; - $this->tableprefix = $tableprefix; + $this->tableprefix = $dbtableprefix; } } diff --git a/lib/setup/mssql.php b/lib/setup/mssql.php index 74ac8f294a..5ed0d030c7 100644 --- a/lib/setup/mssql.php +++ b/lib/setup/mssql.php @@ -149,7 +149,7 @@ class MSSQL extends AbstractDatabase { //fill the database if needed $query = "SELECT * FROM INFORMATION_SCHEMA.TABLES" ." WHERE TABLE_SCHEMA = '".$this->dbname."'" - ." AND TABLE_NAME = '".$this->dbtableprefix."users'"; + ." AND TABLE_NAME = '".$this->tableprefix."users'"; $result = sqlsrv_query($connection, $query); if ($result === false) { if ( ($errors = sqlsrv_errors() ) != null) { diff --git a/lib/setup/mysql.php b/lib/setup/mysql.php index aa0344f686..1ab1b6ea8a 100644 --- a/lib/setup/mysql.php +++ b/lib/setup/mysql.php @@ -23,7 +23,7 @@ class MySQL extends AbstractDatabase { $this->dbuser=substr('oc_'.$username, 0, 16); if($this->dbuser!=$oldUser) { //hash the password so we don't need to store the admin config in the config file - $this->dbpassword=OC_Util::generate_random_bytes(30); + $this->dbpassword=\OC_Util::generate_random_bytes(30); $this->createDBUser($connection); @@ -46,7 +46,7 @@ class MySQL extends AbstractDatabase { //fill the database if needed $query='select count(*) from information_schema.tables' - ." where table_schema='".$this->dbname."' AND table_name = '".$this->dbtableprefix."users';"; + ." where table_schema='".$this->dbname."' AND table_name = '".$this->tableprefix."users';"; $result = mysql_query($query, $connection); if($result) { $row=mysql_fetch_row($result); diff --git a/lib/setup/oci.php b/lib/setup/oci.php index 56452c65a5..cda7ff7c50 100644 --- a/lib/setup/oci.php +++ b/lib/setup/oci.php @@ -65,14 +65,14 @@ class OCI extends AbstractDatabase { //add prefix to the oracle user name to prevent collisions $this->dbuser='oc_'.$username; //create a new password so we don't need to store the admin config in the config file - $this->dbpassword=OC_Util::generate_random_bytes(30); + $this->dbpassword=\OC_Util::generate_random_bytes(30); //oracle passwords are treated as identifiers: // must start with aphanumeric char // needs to be shortened to 30 bytes, as the two " needed to escape the identifier count towards the identifier length. $this->dbpassword=substr($this->dbpassword, 0, 30); - $this->createDBUser($this->dbtablespace, $connection); + $this->createDBUser($connection); \OC_Config::setValue('dbuser', $this->dbusername); \OC_Config::setValue('dbname', $this->dbusername); @@ -136,10 +136,9 @@ class OCI extends AbstractDatabase { * * @param String $name * @param String $password - * @param String $tablespace * @param resource $connection */ - private function createDBUser($tablespace, $connection) { + private function createDBUser($connection) { $name = $this->dbuser; $password = $this->password; $query = "SELECT * FROM all_users WHERE USERNAME = :un"; diff --git a/lib/setup/postgresql.php b/lib/setup/postgresql.php index 67e4f901a9..d5b135a957 100644 --- a/lib/setup/postgresql.php +++ b/lib/setup/postgresql.php @@ -33,7 +33,7 @@ class PostgreSQL extends AbstractDatabase { //add prefix to the postgresql user name to prevent collisions $this->dbuser='oc_'.$username; //create a new password so we don't need to store the admin config in the config file - $this->dbpassword=OC_Util::generate_random_bytes(30); + $this->dbpassword=\OC_Util::generate_random_bytes(30); $this->createDBUser($connection); @@ -69,7 +69,7 @@ class PostgreSQL extends AbstractDatabase { throw new \DatabaseSetupException($this->trans->t('PostgreSQL username and/or password not valid'), $this->trans->t('You need to enter either an existing account or the administrator.')); } - $query = "select count(*) FROM pg_class WHERE relname='".$this->dbtableprefix."users' limit 1"; + $query = "select count(*) FROM pg_class WHERE relname='".$this->tableprefix."users' limit 1"; $result = pg_query($connection, $query); if($result) { $row = pg_fetch_row($result); diff --git a/lib/setup/sqlite.php b/lib/setup/sqlite.php index 0b96ec6000..4b0a572bb3 100644 --- a/lib/setup/sqlite.php +++ b/lib/setup/sqlite.php @@ -6,6 +6,7 @@ class Sqlite extends AbstractDatabase { public $dbprettyname = 'Sqlite'; public function validate($config) { + return array(); } public function initialize($config) { From 60eb63e35ade1ef53e907a637d746d93ed906feb Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 27 Jun 2013 20:19:51 +0200 Subject: [PATCH 8/8] Fix review items --- lib/setup.php | 14 +++++++------- lib/setup/abstractdatabase.php | 4 +++- lib/setup/mssql.php | 2 +- lib/setup/mysql.php | 2 +- lib/setup/oci.php | 2 +- lib/setup/postgresql.php | 2 +- lib/setup/sqlite.php | 2 +- 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/setup.php b/lib/setup.php index 11c6cc76b6..d8f4cbfbcb 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -19,7 +19,7 @@ class DatabaseSetupException extends Exception } class OC_Setup { - static $db_setup_classes = array( + static $dbSetupClasses = array( 'mysql' => '\OC\Setup\MySQL', 'pgsql' => '\OC\Setup\PostgreSQL', 'oci' => '\OC\Setup\OCI', @@ -48,13 +48,13 @@ class OC_Setup { $options['directory'] = OC::$SERVERROOT."/data"; } - if (!isset(self::$db_setup_classes[$dbtype])) { + if (!isset(self::$dbSetupClasses[$dbtype])) { $dbtype = 'sqlite'; } - $class = self::$db_setup_classes[$dbtype]; - $db_setup = new $class(self::getTrans()); - $error = array_merge($error, $db_setup->validate($options)); + $class = self::$dbSetupClasses[$dbtype]; + $dbSetup = new $class(self::getTrans(), 'db_structure.xml'); + $error = array_merge($error, $dbSetup->validate($options)); if(count($error) != 0) { return $error; @@ -83,8 +83,8 @@ class OC_Setup { OC_Config::setValue('dbtype', $dbtype); OC_Config::setValue('version', implode('.', OC_Util::getVersion())); try { - $db_setup->initialize($options); - $db_setup->setupDatabase($username); + $dbSetup->initialize($options); + $dbSetup->setupDatabase($username); } catch (DatabaseSetupException $e) { $error[] = array( 'error' => $e->getMessage(), diff --git a/lib/setup/abstractdatabase.php b/lib/setup/abstractdatabase.php index 66202251e9..0beada7bd2 100644 --- a/lib/setup/abstractdatabase.php +++ b/lib/setup/abstractdatabase.php @@ -4,14 +4,16 @@ namespace OC\Setup; abstract class AbstractDatabase { protected $trans; + protected $dbDefinitionFile; protected $dbuser; protected $dbpassword; protected $dbname; protected $dbhost; protected $tableprefix; - public function __construct($trans) { + public function __construct($trans, $dbDefinitionFile) { $this->trans = $trans; + $this->dbDefinitionFile = $dbDefinitionFile; } public function validate($config) { diff --git a/lib/setup/mssql.php b/lib/setup/mssql.php index 5ed0d030c7..b8329f9907 100644 --- a/lib/setup/mssql.php +++ b/lib/setup/mssql.php @@ -172,7 +172,7 @@ class MSSQL extends AbstractDatabase { \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); } else { if ($row == null) { - \OC_DB::createDbFromStructure('db_structure.xml'); + \OC_DB::createDbFromStructure($this->dbDefinitionFile); } } } diff --git a/lib/setup/mysql.php b/lib/setup/mysql.php index 1ab1b6ea8a..0cf04fde5a 100644 --- a/lib/setup/mysql.php +++ b/lib/setup/mysql.php @@ -52,7 +52,7 @@ class MySQL extends AbstractDatabase { $row=mysql_fetch_row($result); } if(!$result or $row[0]==0) { - \OC_DB::createDbFromStructure('db_structure.xml'); + \OC_DB::createDbFromStructure($this->dbDefinitionFile); } mysql_close($connection); } diff --git a/lib/setup/oci.php b/lib/setup/oci.php index cda7ff7c50..577948766b 100644 --- a/lib/setup/oci.php +++ b/lib/setup/oci.php @@ -128,7 +128,7 @@ class OCI extends AbstractDatabase { $row = oci_fetch_row($stmt); } if(!$result or $row[0]==0) { - \OC_DB::createDbFromStructure('db_structure.xml'); + \OC_DB::createDbFromStructure($this->dbDefinitionFile); } } diff --git a/lib/setup/postgresql.php b/lib/setup/postgresql.php index d5b135a957..49fcbf0326 100644 --- a/lib/setup/postgresql.php +++ b/lib/setup/postgresql.php @@ -75,7 +75,7 @@ class PostgreSQL extends AbstractDatabase { $row = pg_fetch_row($result); } if(!$result or $row[0]==0) { - \OC_DB::createDbFromStructure('db_structure.xml'); + \OC_DB::createDbFromStructure($this->dbDefinitionFile); } } diff --git a/lib/setup/sqlite.php b/lib/setup/sqlite.php index 4b0a572bb3..fd4df792d6 100644 --- a/lib/setup/sqlite.php +++ b/lib/setup/sqlite.php @@ -21,6 +21,6 @@ class Sqlite extends AbstractDatabase { } //in case of sqlite, we can always fill the database error_log("creating sqlite db"); - \OC_DB::createDbFromStructure('db_structure.xml'); + \OC_DB::createDbFromStructure($this->dbDefinitionFile); } }