PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/setup/oci.php

https://github.com/sezuan/core
PHP | 210 lines | 163 code | 21 blank | 26 comment | 29 complexity | 3c9c3eecf970ec05ec71fed65e593541 MD5 | raw file
Possible License(s): AGPL-3.0, AGPL-1.0, MPL-2.0-no-copyleft-exception
  1. <?php
  2. namespace OC\Setup;
  3. class OCI extends AbstractDatabase {
  4. public $dbprettyname = 'Oracle';
  5. protected $dbtablespace;
  6. public function initialize($config) {
  7. parent::initialize($config);
  8. if (array_key_exists('dbtablespace', $config)) {
  9. $this->dbtablespace = $config['dbtablespace'];
  10. } else {
  11. $this->dbtablespace = 'USERS';
  12. }
  13. \OC_Config::setValue('dbtablespace', $this->dbtablespace);
  14. }
  15. public function setupDatabase($username) {
  16. $e_host = addslashes($this->dbhost);
  17. $e_dbname = addslashes($this->dbname);
  18. //check if the database user has admin right
  19. if ($e_host == '') {
  20. $easy_connect_string = $e_dbname; // use dbname as easy connect name
  21. } else {
  22. $easy_connect_string = '//'.$e_host.'/'.$e_dbname;
  23. }
  24. \OC_Log::write('setup oracle', 'connect string: ' . $easy_connect_string, \OC_Log::DEBUG);
  25. $connection = @oci_connect($this->dbuser, $this->dbpassword, $easy_connect_string);
  26. if(!$connection) {
  27. $e = oci_error();
  28. if (is_array ($e) && isset ($e['message'])) {
  29. throw new \DatabaseSetupException($this->trans->t('Oracle connection could not be established'),
  30. $e['message'].' Check environment: ORACLE_HOME='.getenv('ORACLE_HOME')
  31. .' ORACLE_SID='.getenv('ORACLE_SID')
  32. .' LD_LIBRARY_PATH='.getenv('LD_LIBRARY_PATH')
  33. .' NLS_LANG='.getenv('NLS_LANG')
  34. .' tnsnames.ora is '.(is_readable(getenv('ORACLE_HOME').'/network/admin/tnsnames.ora')?'':'not ').'readable');
  35. }
  36. throw new \DatabaseSetupException($this->trans->t('Oracle username and/or password not valid'),
  37. 'Check environment: ORACLE_HOME='.getenv('ORACLE_HOME')
  38. .' ORACLE_SID='.getenv('ORACLE_SID')
  39. .' LD_LIBRARY_PATH='.getenv('LD_LIBRARY_PATH')
  40. .' NLS_LANG='.getenv('NLS_LANG')
  41. .' tnsnames.ora is '.(is_readable(getenv('ORACLE_HOME').'/network/admin/tnsnames.ora')?'':'not ').'readable');
  42. }
  43. //check for roles creation rights in oracle
  44. $query='SELECT count(*) FROM user_role_privs, role_sys_privs'
  45. ." WHERE user_role_privs.granted_role = role_sys_privs.role AND privilege = 'CREATE ROLE'";
  46. $stmt = oci_parse($connection, $query);
  47. if (!$stmt) {
  48. $entry = $this->trans->t('DB Error: "%s"', array(oci_last_error($connection))) . '<br />';
  49. $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />';
  50. \OC_Log::write('setup.oci', $entry, \OC_Log::WARN);
  51. }
  52. $result = oci_execute($stmt);
  53. if($result) {
  54. $row = oci_fetch_row($stmt);
  55. }
  56. if($result and $row[0] > 0) {
  57. //use the admin login data for the new database user
  58. //add prefix to the oracle user name to prevent collisions
  59. $this->dbuser='oc_'.$username;
  60. //create a new password so we don't need to store the admin config in the config file
  61. $this->dbpassword=\OC_Util::generate_random_bytes(30);
  62. //oracle passwords are treated as identifiers:
  63. // must start with aphanumeric char
  64. // needs to be shortened to 30 bytes, as the two " needed to escape the identifier count towards the identifier length.
  65. $this->dbpassword=substr($this->dbpassword, 0, 30);
  66. $this->createDBUser($connection);
  67. \OC_Config::setValue('dbuser', $this->dbusername);
  68. \OC_Config::setValue('dbname', $this->dbusername);
  69. \OC_Config::setValue('dbpassword', $this->dbpassword);
  70. //create the database not neccessary, oracle implies user = schema
  71. //$this->createDatabase($this->dbname, $this->dbusername, $connection);
  72. } else {
  73. \OC_Config::setValue('dbuser', $this->dbuser);
  74. \OC_Config::setValue('dbname', $this->dbname);
  75. \OC_Config::setValue('dbpassword', $this->dbpassword);
  76. //create the database not neccessary, oracle implies user = schema
  77. //$this->createDatabase($this->dbname, $this->dbuser, $connection);
  78. }
  79. //FIXME check tablespace exists: select * from user_tablespaces
  80. // the connection to dbname=oracle is not needed anymore
  81. oci_close($connection);
  82. // connect to the oracle database (schema=$this->dbuser) an check if the schema needs to be filled
  83. $this->dbuser = \OC_Config::getValue('dbuser');
  84. //$this->dbname = \OC_Config::getValue('dbname');
  85. $this->dbpassword = \OC_Config::getValue('dbpassword');
  86. $e_host = addslashes($this->dbhost);
  87. $e_dbname = addslashes($this->dbname);
  88. if ($e_host == '') {
  89. $easy_connect_string = $e_dbname; // use dbname as easy connect name
  90. } else {
  91. $easy_connect_string = '//'.$e_host.'/'.$e_dbname;
  92. }
  93. $connection = @oci_connect($this->dbuser, $this->dbpassword, $easy_connect_string);
  94. if(!$connection) {
  95. throw new \DatabaseSetupException($this->trans->t('Oracle username and/or password not valid'),
  96. $this->trans->t('You need to enter either an existing account or the administrator.'));
  97. }
  98. $query = "SELECT count(*) FROM user_tables WHERE table_name = :un";
  99. $stmt = oci_parse($connection, $query);
  100. $un = $this->dbtableprefix.'users';
  101. oci_bind_by_name($stmt, ':un', $un);
  102. if (!$stmt) {
  103. $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />';
  104. $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />';
  105. \OC_Log::write('setup.oci', $entry, \OC_Log::WARN);
  106. }
  107. $result = oci_execute($stmt);
  108. if($result) {
  109. $row = oci_fetch_row($stmt);
  110. }
  111. if(!$result or $row[0]==0) {
  112. \OC_DB::createDbFromStructure($this->dbDefinitionFile);
  113. }
  114. }
  115. /**
  116. *
  117. * @param String $name
  118. * @param String $password
  119. * @param resource $connection
  120. */
  121. private function createDBUser($connection) {
  122. $name = $this->dbuser;
  123. $password = $this->password;
  124. $query = "SELECT * FROM all_users WHERE USERNAME = :un";
  125. $stmt = oci_parse($connection, $query);
  126. if (!$stmt) {
  127. $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />';
  128. $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />';
  129. \OC_Log::write('setup.oci', $entry, \OC_Log::WARN);
  130. }
  131. oci_bind_by_name($stmt, ':un', $name);
  132. $result = oci_execute($stmt);
  133. if(!$result) {
  134. $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />';
  135. $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />';
  136. \OC_Log::write('setup.oci', $entry, \OC_Log::WARN);
  137. }
  138. if(! oci_fetch_row($stmt)) {
  139. //user does not exists let's create it :)
  140. //password must start with alphabetic character in oracle
  141. $query = 'CREATE USER '.$name.' IDENTIFIED BY "'.$password.'" DEFAULT TABLESPACE '.$this->dbtablespace;
  142. $stmt = oci_parse($connection, $query);
  143. if (!$stmt) {
  144. $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />';
  145. $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />';
  146. \OC_Log::write('setup.oci', $entry, \OC_Log::WARN);
  147. }
  148. //oci_bind_by_name($stmt, ':un', $name);
  149. $result = oci_execute($stmt);
  150. if(!$result) {
  151. $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />';
  152. $entry .= $this->trans->t('Offending command was: "%s", name: %s, password: %s',
  153. array($query, $name, $password)) . '<br />';
  154. \OC_Log::write('setup.oci', $entry, \OC_Log::WARN);
  155. }
  156. } else { // change password of the existing role
  157. $query = "ALTER USER :un IDENTIFIED BY :pw";
  158. $stmt = oci_parse($connection, $query);
  159. if (!$stmt) {
  160. $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />';
  161. $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />';
  162. \OC_Log::write('setup.oci', $entry, \OC_Log::WARN);
  163. }
  164. oci_bind_by_name($stmt, ':un', $name);
  165. oci_bind_by_name($stmt, ':pw', $password);
  166. $result = oci_execute($stmt);
  167. if(!$result) {
  168. $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />';
  169. $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />';
  170. \OC_Log::write('setup.oci', $entry, \OC_Log::WARN);
  171. }
  172. }
  173. // grant necessary roles
  174. $query = 'GRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER, UNLIMITED TABLESPACE TO '.$name;
  175. $stmt = oci_parse($connection, $query);
  176. if (!$stmt) {
  177. $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />';
  178. $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />';
  179. \OC_Log::write('setup.oci', $entry, \OC_Log::WARN);
  180. }
  181. $result = oci_execute($stmt);
  182. if(!$result) {
  183. $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />';
  184. $entry .= $this->trans->t('Offending command was: "%s", name: %s, password: %s',
  185. array($query, $name, $password)) . '<br />';
  186. \OC_Log::write('setup.oci', $entry, \OC_Log::WARN);
  187. }
  188. }
  189. }