diff options
author | Thomas Müller <thomas.mueller@tmit.eu> | 2013-09-25 13:36:30 +0200 |
---|---|---|
committer | Thomas Müller <thomas.mueller@tmit.eu> | 2013-09-30 16:36:59 +0200 |
commit | 9c9dc276b7a1d2592c4fb0a887888632dc1f1e29 (patch) | |
tree | bbe3aed3e09c31c68806bdb8acffef70ba08f51c /lib/private/setup | |
parent | a711399e62d5a9f14d4b748efe4354ee37e61f13 (diff) | |
download | nextcloud-server-9c9dc276b7a1d2592c4fb0a887888632dc1f1e29.tar.gz nextcloud-server-9c9dc276b7a1d2592c4fb0a887888632dc1f1e29.zip |
move the private namespace OC into lib/private - OCP will stay in lib/public
Conflicts:
lib/private/vcategories.php
Diffstat (limited to 'lib/private/setup')
-rw-r--r-- | lib/private/setup/abstractdatabase.php | 50 | ||||
-rw-r--r-- | lib/private/setup/mssql.php | 182 | ||||
-rw-r--r-- | lib/private/setup/mysql.php | 95 | ||||
-rw-r--r-- | lib/private/setup/oci.php | 210 | ||||
-rw-r--r-- | lib/private/setup/postgresql.php | 140 | ||||
-rw-r--r-- | lib/private/setup/sqlite.php | 26 |
6 files changed, 703 insertions, 0 deletions
diff --git a/lib/private/setup/abstractdatabase.php b/lib/private/setup/abstractdatabase.php new file mode 100644 index 00000000000..0beada7bd29 --- /dev/null +++ b/lib/private/setup/abstractdatabase.php @@ -0,0 +1,50 @@ +<?php + +namespace OC\Setup; + +abstract class AbstractDatabase { + protected $trans; + protected $dbDefinitionFile; + protected $dbuser; + protected $dbpassword; + protected $dbname; + protected $dbhost; + protected $tableprefix; + + public function __construct($trans, $dbDefinitionFile) { + $this->trans = $trans; + $this->dbDefinitionFile = $dbDefinitionFile; + } + + 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 = !empty($config['dbhost']) ? $config['dbhost'] : 'localhost'; + $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 = $dbtableprefix; + } +} diff --git a/lib/private/setup/mssql.php b/lib/private/setup/mssql.php new file mode 100644 index 00000000000..b8329f99079 --- /dev/null +++ b/lib/private/setup/mssql.php @@ -0,0 +1,182 @@ +<?php + +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); + + $masterConnection = @sqlsrv_connect($this->dbhost, $masterConnectionInfo); + if(!$masterConnection) { + $entry = null; + if( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + 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', $this->dbuser); + \OC_Config::setValue('dbpassword', $this->dbpassword); + + $this->createDBLogin($masterConnection); + + $this->createDatabase($masterConnection); + + $this->createDBUser($masterConnection); + + sqlsrv_close($masterConnection); + + $this->createDatabaseStructure(); + } + + 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) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \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()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + if ($row == null) { + $query = "CREATE LOGIN [".$this->dbuser."] WITH PASSWORD = '".$this->dbpassword."';"; + $result = sqlsrv_query($connection, $query); + if (!$result or $result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } + } + } + } + } + + 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) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \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()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + if ($row == null) { + $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) { + $entry = 'DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } + } + + $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) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } + } + } + } + + private function createDatabase($connection) { + $query = "CREATE DATABASE [".$this->dbname."];"; + $result = sqlsrv_query($connection, $query); + if (!$result || $result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } + } + + private function createDatabaseStructure() { + $connectionInfo = array( "Database" => $this->dbname, "UID" => $this->dbuser, "PWD" => $this->dbpassword); + + $connection = @sqlsrv_connect($this->dbhost, $connectionInfo); + + //fill the database if needed + $query = "SELECT * FROM INFORMATION_SCHEMA.TABLES" + ." WHERE TABLE_SCHEMA = '".$this->dbname."'" + ." AND TABLE_NAME = '".$this->tableprefix."users'"; + $result = sqlsrv_query($connection, $query); + if ($result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \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()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + if ($row == null) { + \OC_DB::createDbFromStructure($this->dbDefinitionFile); + } + } + } + + sqlsrv_close($connection); + } +} diff --git a/lib/private/setup/mysql.php b/lib/private/setup/mysql.php new file mode 100644 index 00000000000..d97b6d2602f --- /dev/null +++ b/lib/private/setup/mysql.php @@ -0,0 +1,95 @@ +<?php + +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); + if(!$connection) { + 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='$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 + $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::generateRandomBytes(30); + + $this->createDBUser($connection); + + \OC_Config::setValue('dbuser', $this->dbuser); + \OC_Config::setValue('dbpassword', $this->dbpassword); + } + + //create the database + $this->createDatabase($connection); + } + else { + if($this->dbuser!=$oldUser) { + \OC_Config::setValue('dbuser', $this->dbuser); + \OC_Config::setValue('dbpassword', $this->dbpassword); + } + + //create the database + $this->createDatabase($connection); + } + + //fill the database if needed + $query='select count(*) from information_schema.tables' + ." where table_schema='".$this->dbname."' AND table_name = '".$this->tableprefix."users';"; + $result = mysql_query($query, $connection); + if($result) { + $row=mysql_fetch_row($result); + } + if(!$result or $row[0]==0) { + \OC_DB::createDbFromStructure($this->dbDefinitionFile); + } + mysql_close($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. + $query = "CREATE DATABASE IF NOT EXISTS `$name`"; + $result = mysql_query($query, $connection); + if(!$result) { + $entry = $this->trans->t('DB Error: "%s"', array(mysql_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + \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 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. + $query = "CREATE USER '$name'@'localhost' IDENTIFIED BY '$password'"; + $result = mysql_query($query, $connection); + if (!$result) { + 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($this->trans->t("MySQL user '%s'@'%%' already exists", array($name)), + $this->trans->t("Drop this user from MySQL.")); + } + } +} diff --git a/lib/private/setup/oci.php b/lib/private/setup/oci.php new file mode 100644 index 00000000000..326d7a00531 --- /dev/null +++ b/lib/private/setup/oci.php @@ -0,0 +1,210 @@ +<?php + +namespace OC\Setup; + +class OCI extends AbstractDatabase { + public $dbprettyname = 'Oracle'; + + protected $dbtablespace; + + public function initialize($config) { + parent::initialize($config); + if (array_key_exists('dbtablespace', $config)) { + $this->dbtablespace = $config['dbtablespace']; + } else { + $this->dbtablespace = 'USERS'; + } + \OC_Config::setValue('dbtablespace', $this->dbtablespace); + } + + public function setupDatabase($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 + } else { + $easy_connect_string = '//'.$e_host.'/'.$e_dbname; + } + \OC_Log::write('setup oracle', 'connect string: ' . $easy_connect_string, \OC_Log::DEBUG); + $connection = @oci_connect($this->dbuser, $this->dbpassword, $easy_connect_string); + if(!$connection) { + $e = oci_error(); + if (is_array ($e) && isset ($e['message'])) { + throw new \DatabaseSetupException($this->trans->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($this->trans->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 = $this->trans->t('DB Error: "%s"', array(oci_last_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + \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 + $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::generateRandomBytes(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($connection); + + \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 + //$this->createDatabase($this->dbname, $this->dbusername, $connection); + } else { + + \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 + //$this->createDatabase($this->dbname, $this->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=$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($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($this->dbuser, $this->dbpassword, $easy_connect_string); + if(!$connection) { + 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 = $this->dbtableprefix.'users'; + oci_bind_by_name($stmt, ':un', $un); + if (!$stmt) { + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + \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($this->dbDefinitionFile); + } + } + + /** + * + * @param String $name + * @param String $password + * @param resource $connection + */ + private function createDBUser($connection) { + $name = $this->dbuser; + $password = $this->password; + $query = "SELECT * FROM all_users WHERE USERNAME = :un"; + $stmt = oci_parse($connection, $query); + if (!$stmt) { + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); + } + oci_bind_by_name($stmt, ':un', $name); + $result = oci_execute($stmt); + if(!$result) { + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + \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 '.$this->dbtablespace; + $stmt = oci_parse($connection, $query); + if (!$stmt) { + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); + } + //oci_bind_by_name($stmt, ':un', $name); + $result = oci_execute($stmt); + if(!$result) { + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s", name: %s, password: %s', + array($query, $name, $password)) . '<br />'; + \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 = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + \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 = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + \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 = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); + } + $result = oci_execute($stmt); + if(!$result) { + $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s", name: %s, password: %s', + array($query, $name, $password)) . '<br />'; + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); + } + } +} diff --git a/lib/private/setup/postgresql.php b/lib/private/setup/postgresql.php new file mode 100644 index 00000000000..89d328ada19 --- /dev/null +++ b/lib/private/setup/postgresql.php @@ -0,0 +1,140 @@ +<?php + +namespace OC\Setup; + +class PostgreSQL extends AbstractDatabase { + public $dbprettyname = 'PostgreSQL'; + + 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($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($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($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); + 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 + $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::generateRandomBytes(30); + + $this->createDBUser($connection); + + \OC_Config::setValue('dbuser', $this->dbuser); + \OC_Config::setValue('dbpassword', $this->dbpassword); + + //create the database + $this->createDatabase($connection); + } + else { + \OC_Config::setValue('dbuser', $this->dbuser); + \OC_Config::setValue('dbpassword', $this->dbpassword); + + //create the database + $this->createDatabase($connection); + } + + // the connection to dbname=postgres is not needed anymore + pg_close($connection); + + // 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($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($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->tableprefix."users' limit 1"; + $result = pg_query($connection, $query); + if($result) { + $row = pg_fetch_row($result); + } + if(!$result or $row[0]==0) { + \OC_DB::createDbFromStructure($this->dbDefinitionFile); + } + } + + private function createDatabase($connection) { + //we cant use OC_BD functions here because we need to connect as the administrative 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 = $this->trans->t('DB Error: "%s"', array(pg_last_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + \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 = $this->trans->t('DB Error: "%s"', array(pg_last_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + \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 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 = $this->trans->t('DB Error: "%s"', array(pg_last_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + \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 = $this->trans->t('DB Error: "%s"', array(pg_last_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + \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 = $this->trans->t('DB Error: "%s"', array(pg_last_error($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); + } + } + } +} diff --git a/lib/private/setup/sqlite.php b/lib/private/setup/sqlite.php new file mode 100644 index 00000000000..fd4df792d62 --- /dev/null +++ b/lib/private/setup/sqlite.php @@ -0,0 +1,26 @@ +<?php + +namespace OC\Setup; + +class Sqlite extends AbstractDatabase { + public $dbprettyname = 'Sqlite'; + + public function validate($config) { + return array(); + } + + public function initialize($config) { + } + + public function setupDatabase($username) { + $datadir = \OC_Config::getValue('datadirectory'); + + //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($this->dbDefinitionFile); + } +} |