diff options
Diffstat (limited to 'lib/private/Setup')
-rw-r--r-- | lib/private/Setup/AbstractDatabase.php | 99 | ||||
-rw-r--r-- | lib/private/Setup/MySQL.php | 175 | ||||
-rw-r--r-- | lib/private/Setup/OCI.php | 265 | ||||
-rw-r--r-- | lib/private/Setup/PostgreSQL.php | 173 | ||||
-rw-r--r-- | lib/private/Setup/Sqlite.php | 45 |
5 files changed, 757 insertions, 0 deletions
diff --git a/lib/private/Setup/AbstractDatabase.php b/lib/private/Setup/AbstractDatabase.php new file mode 100644 index 00000000000..90203b67c1d --- /dev/null +++ b/lib/private/Setup/AbstractDatabase.php @@ -0,0 +1,99 @@ +<?php +/** + * @author Bart Visscher <bartv@thisnet.nl> + * @author Joas Schilling <nickvergessen@owncloud.com> + * @author Thomas Müller <thomas.mueller@tmit.eu> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ +namespace OC\Setup; + +use OCP\IConfig; +use OCP\ILogger; +use OCP\Security\ISecureRandom; + +abstract class AbstractDatabase { + + /** @var \OC_L10N */ + protected $trans; + /** @var string */ + protected $dbDefinitionFile; + /** @var string */ + protected $dbUser; + /** @var string */ + protected $dbPassword; + /** @var string */ + protected $dbName; + /** @var string */ + protected $dbHost; + /** @var string */ + protected $tablePrefix; + /** @var IConfig */ + protected $config; + /** @var ILogger */ + protected $logger; + /** @var ISecureRandom */ + protected $random; + + public function __construct($trans, $dbDefinitionFile, IConfig $config, ILogger $logger, ISecureRandom $random) { + $this->trans = $trans; + $this->dbDefinitionFile = $dbDefinitionFile; + $this->config = $config; + $this->logger = $logger; + $this->random = $random; + } + + public function validate($config) { + $errors = array(); + if(empty($config['dbuser']) && empty($config['dbname'])) { + $errors[] = $this->trans->t("%s enter the database username and name.", array($this->dbprettyname)); + } else if(empty($config['dbuser'])) { + $errors[] = $this->trans->t("%s enter the database username.", array($this->dbprettyname)); + } else 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_'; + + $this->config->setSystemValues([ + 'dbname' => $dbName, + 'dbhost' => $dbHost, + 'dbtableprefix' => $dbTablePrefix, + ]); + + $this->dbUser = $dbUser; + $this->dbPassword = $dbPass; + $this->dbName = $dbName; + $this->dbHost = $dbHost; + $this->tablePrefix = $dbTablePrefix; + } + + /** + * @param string $userName + */ + abstract public function setupDatabase($userName); +} diff --git a/lib/private/Setup/MySQL.php b/lib/private/Setup/MySQL.php new file mode 100644 index 00000000000..18b6dab4ff8 --- /dev/null +++ b/lib/private/Setup/MySQL.php @@ -0,0 +1,175 @@ +<?php +/** + * @author Bart Visscher <bartv@thisnet.nl> + * @author Joas Schilling <nickvergessen@owncloud.com> + * @author Michael Göhler <somebody.here@gmx.de> + * @author Roeland Jago Douma <rullzer@owncloud.com> + * @author Thomas Müller <thomas.mueller@tmit.eu> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ +namespace OC\Setup; + +use OC\DB\ConnectionFactory; +use OCP\IDBConnection; + +class MySQL extends AbstractDatabase { + public $dbprettyname = 'MySQL/MariaDB'; + + public function setupDatabase($username) { + //check if the database user has admin right + $connection = $this->connect(); + + $this->createSpecificUser($username, $connection); + + //create the database + $this->createDatabase($connection); + + //fill the database if needed + $query='select count(*) from information_schema.tables where table_schema=? AND table_name = ?'; + $result = $connection->executeQuery($query, [$this->dbName, $this->tablePrefix.'users']); + $row = $result->fetch(); + if (!$row or $row['count(*)'] === '0') { + \OC_DB::createDbFromStructure($this->dbDefinitionFile); + } + } + + /** + * @param \OC\DB\Connection $connection + */ + private function createDatabase($connection) { + try{ + $name = $this->dbName; + $user = $this->dbUser; + //we can't use OC_BD functions here because we need to connect as the administrative user. + $query = "CREATE DATABASE IF NOT EXISTS `$name` CHARACTER SET utf8 COLLATE utf8_bin;"; + $connection->executeUpdate($query); + + //this query will fail if there aren't the right permissions, ignore the error + $query="GRANT ALL PRIVILEGES ON `$name` . * TO '$user'"; + $connection->executeUpdate($query); + } catch (\Exception $ex) { + $this->logger->error('Database creation failed: {error}', [ + 'app' => 'mysql.setup', + 'error' => $ex->getMessage() + ]); + } + } + + /** + * @param IDBConnection $connection + * @throws \OC\DatabaseSetupException + */ + 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'"; + $connection->executeUpdate($query); + $query = "CREATE USER '$name'@'%' IDENTIFIED BY '$password'"; + $connection->executeUpdate($query); + } + + /** + * @return \OC\DB\Connection + * @throws \OC\DatabaseSetupException + */ + private function connect() { + + $connectionParams = array( + 'host' => $this->dbHost, + 'user' => $this->dbUser, + 'password' => $this->dbPassword, + 'tablePrefix' => $this->tablePrefix, + ); + + // adding port support + if (strpos($this->dbHost, ':')) { + // Host variable may carry a port or socket. + list($host, $portOrSocket) = explode(':', $this->dbHost, 2); + if (ctype_digit($portOrSocket)) { + $connectionParams['port'] = $portOrSocket; + } else { + $connectionParams['unix_socket'] = $portOrSocket; + } + $connectionParams['host'] = $host; + } + + $cf = new ConnectionFactory(); + return $cf->getConnection('mysql', $connectionParams); + } + + /** + * @param $username + * @param IDBConnection $connection + * @return array + */ + private function createSpecificUser($username, $connection) { + try { + //user already specified in config + $oldUser = $this->config->getSystemValue('dbuser', false); + + //we don't have a dbuser specified in config + if ($this->dbUser !== $oldUser) { + //add prefix to the admin username to prevent collisions + $adminUser = substr('oc_' . $username, 0, 16); + + $i = 1; + while (true) { + //this should be enough to check for admin rights in mysql + $query = 'SELECT user FROM mysql.user WHERE user=?'; + $result = $connection->executeQuery($query, [$adminUser]); + + //current dbuser has admin rights + if ($result) { + $data = $result->fetchAll(); + //new dbuser does not exist + if (count($data) === 0) { + //use the admin login data for the new database user + $this->dbUser = $adminUser; + + //create a random password so we don't need to store the admin password in the config file + $this->dbPassword = $this->random->generate(30); + + $this->createDBUser($connection); + + break; + } else { + //repeat with different username + $length = strlen((string)$i); + $adminUser = substr('oc_' . $username, 0, 16 - $length) . $i; + $i++; + } + } else { + break; + } + }; + } + } catch (\Exception $ex) { + $this->logger->error('Specific user creation failed: {error}', [ + 'app' => 'mysql.setup', + 'error' => $ex->getMessage() + ]); + } + + $this->config->setSystemValues([ + 'dbuser' => $this->dbUser, + 'dbpassword' => $this->dbPassword, + ]); + } +} diff --git a/lib/private/Setup/OCI.php b/lib/private/Setup/OCI.php new file mode 100644 index 00000000000..a398876ad16 --- /dev/null +++ b/lib/private/Setup/OCI.php @@ -0,0 +1,265 @@ +<?php +/** + * @author Andreas Fischer <bantu@owncloud.com> + * @author Bart Visscher <bartv@thisnet.nl> + * @author Joas Schilling <nickvergessen@owncloud.com> + * @author Jörn Friedrich Dreyer <jfd@butonic.de> + * @author Morris Jobke <hey@morrisjobke.de> + * @author Roeland Jago Douma <rullzer@owncloud.com> + * @author Thomas Müller <thomas.mueller@tmit.eu> + * @author Victor Dubiniuk <dubiniuk@owncloud.com> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ +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'; + } + // allow empty hostname for oracle + $this->dbHost = $config['dbhost']; + + $this->config->setSystemValues([ + 'dbhost' => $this->dbHost, + 'dbtablespace' => $this->dbtablespace, + ]); + } + + public function validate($config) { + $errors = array(); + if(empty($config['dbuser']) && empty($config['dbname'])) { + $errors[] = $this->trans->t("%s enter the database username and name.", array($this->dbprettyname)); + } else if(empty($config['dbuser'])) { + $errors[] = $this->trans->t("%s enter the database username.", array($this->dbprettyname)); + } else if(empty($config['dbname'])) { + $errors[] = $this->trans->t("%s enter the database name.", array($this->dbprettyname)); + } + return $errors; + } + + 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; + } + $this->logger->debug('connect string: ' . $easy_connect_string, ['app' => 'setup.oci']); + $connection = @oci_connect($this->dbUser, $this->dbPassword, $easy_connect_string); + if(!$connection) { + $errorMessage = $this->getLastError(); + if ($errorMessage) { + throw new \OC\DatabaseSetupException($this->trans->t('Oracle connection could not be established'), + $errorMessage.' 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 \OC\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($this->getLastError($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + $this->logger->warning($entry, ['app' => 'setup.oci']); + } + $result = oci_execute($stmt); + if($result) { + $row = oci_fetch_row($stmt); + + if ($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::$server->getSecureRandom()->generate(30, \OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_DIGITS); + + //oracle passwords are treated as identifiers: + // must start with alphanumeric 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); + } + } + + $this->config->setSystemValues([ + 'dbuser' => $this->dbUser, + 'dbname' => $this->dbName, + 'dbpassword' => $this->dbPassword, + ]); + + //create the database not necessary, 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 = $this->config->getSystemValue('dbuser'); + //$this->dbname = \OC_Config::getValue('dbname'); + $this->dbPassword = $this->config->getSystemValue('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 \OC\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->tablePrefix.'users'; + oci_bind_by_name($stmt, ':un', $un); + if (!$stmt) { + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + $this->logger->warning( $entry, ['app' => 'setup.oci']); + } + $result = oci_execute($stmt); + + if($result) { + $row = oci_fetch_row($stmt); + } + if(!$result or $row[0]==0) { + \OC_DB::createDbFromStructure($this->dbDefinitionFile); + } + } + + /** + * @param resource $connection + */ + private function createDBUser($connection) { + $name = $this->dbUser; + $password = $this->dbPassword; + $query = "SELECT * FROM all_users WHERE USERNAME = :un"; + $stmt = oci_parse($connection, $query); + if (!$stmt) { + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + $this->logger->warning($entry, ['app' => 'setup.oci']); + } + oci_bind_by_name($stmt, ':un', $name); + $result = oci_execute($stmt); + if(!$result) { + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + $this->logger->warning($entry, ['app' => 'setup.oci']); + } + + 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($this->getLastError($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + $this->logger->warning($entry, ['app' => 'setup.oci']); + + } + //oci_bind_by_name($stmt, ':un', $name); + $result = oci_execute($stmt); + if(!$result) { + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s", name: %s, password: %s', + array($query, $name, $password)) . '<br />'; + $this->logger->warning($entry, ['app' => 'setup.oci']); + + } + } 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($this->getLastError($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + $this->logger->warning($entry, ['app' => 'setup.oci']); + } + 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($this->getLastError($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + $this->logger->warning($entry, ['app' => 'setup.oci']); + } + } + // 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($this->getLastError($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; + $this->logger->warning($entry, ['app' => 'setup.oci']); + } + $result = oci_execute($stmt); + if(!$result) { + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; + $entry .= $this->trans->t('Offending command was: "%s", name: %s, password: %s', + array($query, $name, $password)) . '<br />'; + $this->logger->warning($entry, ['app' => 'setup.oci']); + } + } + + /** + * @param resource $connection + * @return string + */ + protected function getLastError($connection = null) { + if ($connection) { + $error = oci_error($connection); + } else { + $error = oci_error(); + } + foreach (array('message', 'code') as $key) { + if (isset($error[$key])) { + return $error[$key]; + } + } + return ''; + } +} diff --git a/lib/private/Setup/PostgreSQL.php b/lib/private/Setup/PostgreSQL.php new file mode 100644 index 00000000000..893999bb0b9 --- /dev/null +++ b/lib/private/Setup/PostgreSQL.php @@ -0,0 +1,173 @@ +<?php +/** + * @author Bart Visscher <bartv@thisnet.nl> + * @author eduardo <eduardo@vnexu.net> + * @author Joas Schilling <nickvergessen@owncloud.com> + * @author Morris Jobke <hey@morrisjobke.de> + * @author Roeland Jago Douma <rullzer@owncloud.com> + * @author Thomas Müller <thomas.mueller@tmit.eu> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ +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); + + // Fix database with port connection + if(strpos($e_host, ':')) { + list($e_host, $port)=explode(':', $e_host, 2); + } else { + $port=false; + } + + //check if the database user has admin rights + $connection_string = "host='$e_host' dbname=postgres user='$e_user' port='$port' 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' port='$port' password='$e_password'"; + $connection = @pg_connect($connection_string); + + if(!$connection) + throw new \OC\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::$server->getSecureRandom()->generate(30, \OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_DIGITS); + + $this->createDBUser($connection); + } + + $systemConfig = \OC::$server->getSystemConfig(); + $systemConfig->setValues([ + 'dbuser' => $this->dbUser, + '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 = $systemConfig->getValue('dbuser'); + $this->dbPassword = $systemConfig->getValue('dbpassword'); + + $e_host = addslashes($this->dbHost); + $e_dbname = addslashes($this->dbName); + $e_user = addslashes($this->dbUser); + $e_password = addslashes($this->dbPassword); + + // Fix database with port connection + if(strpos($e_host, ':')) { + list($e_host, $port)=explode(':', $e_host, 2); + } else { + $port=false; + } + + $connection_string = "host='$e_host' dbname='$e_dbname' user='$e_user' port='$port' password='$e_password'"; + $connection = @pg_connect($connection_string); + if(!$connection) { + throw new \OC\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 can't 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 />'; + \OCP\Util::writeLog('setup.pg', $entry, \OCP\Util::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 />'; + \OCP\Util::writeLog('setup.pg', $entry, \OCP\Util::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 />'; + \OCP\Util::writeLog('setup.pg', $entry, \OCP\Util::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 />'; + \OCP\Util::writeLog('setup.pg', $entry, \OCP\Util::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 />'; + \OCP\Util::writeLog('setup.pg', $entry, \OCP\Util::WARN); + } + } + } +} diff --git a/lib/private/Setup/Sqlite.php b/lib/private/Setup/Sqlite.php new file mode 100644 index 00000000000..61bc501fd75 --- /dev/null +++ b/lib/private/Setup/Sqlite.php @@ -0,0 +1,45 @@ +<?php +/** + * @author Bart Visscher <bartv@thisnet.nl> + * @author Morris Jobke <hey@morrisjobke.de> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ +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::$server->getSystemConfig()->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); + } +} |