[FEATURE][INSTALL] Check MySQL privileges to create new databases
authorSteffen Gebert <steffen.gebert@typo3.org>
Thu, 2 Jun 2011 15:01:27 +0000 (17:01 +0200)
committerAndreas Wolf <andreas.wolf@ikt-werk.de>
Wed, 26 Oct 2011 14:36:26 +0000 (16:36 +0200)
Hide the option to create a new MySQL database within the 1-2-3 wizard,
if the MySQL user has no permissions to do so.

Change-Id: Ia1dac4ff39e9254d91b4b044306dbb6600df1525
Resolves: #27194
Releases: 4.7
Reviewed-on: http://review.typo3.org/2507
Reviewed-by: Andreas Wolf
Tested-by: Andreas Wolf
typo3/sysext/install/Resources/Private/Templates/StepOutput.html
typo3/sysext/install/Resources/Public/Stylesheets/install_123.css
typo3/sysext/install/mod/class.tx_install.php

index 3c339de..d0c94c9 100644 (file)
                                                <input type="hidden" value="###STEP###" name="step" />
                                        </li>
                                        <li>
-                                               <input type="radio" name="TYPO3_INSTALL[db_select_option]" id="t3-install-form-db-select-new" value="NEW" checked="checked" class="radio" />
+                                               <input type="radio" name="TYPO3_INSTALL[db_select_option]" id="t3-install-form-db-select-new" value="NEW" ###FORMFIELDATTRIBUTESNEW### class="radio" />
                                                <div>
                                                        <label for="t3-install-123-newdatabase">###LLOPTION1###</label>
                                                        <p>###LLREMARK1###</p>
-                                                       <input id="t3-install-123-newdatabase" class="t3-install-form-input-text" type="text" name="TYPO3_INSTALL[localconf.php][NEW_DATABASE_NAME]" onfocus="document.getElementById('t3-install-form-db-select-new').checked=true" />
+                                                       <input id="t3-install-123-newdatabase" class="t3-install-form-input-text" type="text" name="TYPO3_INSTALL[localconf.php][NEW_DATABASE_NAME]" ###FORMFIELDATTRIBUTESNEW### onfocus="document.getElementById('t3-install-form-db-select-new').checked=true" />
+                                                       <!-- ###DATABASE_NAME_PATTERNS### begin -->
+                                                       <p>###LL_DB_PATTERN_REMARK### <ul style="list-style:disc;">###LL_DB_PATTERN_LIST###</ul></p>
+                                                       <!-- ###DATABASE_NAME_PATTERNS### end -->
                                                </div>
                                        </li>
                                        <li>
-                                               <input type="radio" name="TYPO3_INSTALL[db_select_option]" id="t3-install-form-db-select-existing" value="EXISTING" class="radio" />
+                                               <input type="radio" name="TYPO3_INSTALL[db_select_option]" id="t3-install-form-db-select-existing" value="EXISTING" ###FORMFIELDATTRIBUTESSELECT### class="radio" />
                                                <div>
                                                        <label for="t3-install-123-database">###LLOPTION2###</label>
                                                        <p>###LLREMARK2###</p>
index ce3cbe7..30338da 100644 (file)
@@ -207,6 +207,7 @@ h3 {
 #t3-install-123-step3 ul li div {
        display: inline-block;
        margin-bottom: 10px;
+       width: 90%;
 }
 
 #t3-install-123-step3 ul li input.radio {
index 16b6f27..9f3eeb2 100644 (file)
@@ -1026,19 +1026,47 @@ REMOTE_ADDR was '".t3lib_div::getIndpEnv('REMOTE_ADDR')."' (".t3lib_div::getIndp
                                                                TRUE
                                                        );
                                                }
+
+                                               $usePatternList = FALSE;
+                                               $createDatabaseAllowed = $this->checkCreateDatabasePrivileges();
+                                               if ($createDatabaseAllowed === TRUE) {
+                                                       $formFieldAttributesNew = 'checked="checked"';
+                                                       $llRemark1 = 'Enter a name for your TYPO3 database.';
+                                               } elseif (is_array($createDatabaseAllowed)) {
+                                                       $llRemark1 = 'Enter a name for your TYPO3 database.';
+                                                       $llDbPatternRemark = 'The name has to match one of these names/patterns (% is a wild card):';
+                                                       $llDbPatternList = '<li>' . implode('</li><li>', $createDatabaseAllowed) . '</li>';
+                                                       $usePatternList = TRUE;
+                                               } else {
+                                                       $formFieldAttributesNew = 'disabled="disabled"';
+                                                       $formFieldAttributesSelect = 'checked="checked"';
+                                                       $llRemark1 = 'You have no permissions to create new databases.';
+                                               }
+
                                                        // Substitute the subpart for the database options
                                                $content = t3lib_parsehtml::substituteSubpart(
                                                        $step3SubPart,
                                                        '###DATABASEOPTIONS###',
                                                        implode(LF, $step3DatabaseOptions)
                                                );
+                                               if ($usePatternList === FALSE) {
+                                                       $content = t3lib_parsehtml::substituteSubpart(
+                                                               $content,
+                                                               '###DATABASE_NAME_PATTERNS###',
+                                                               ''
+                                                       );
+                                               }
                                                        // Define the markers content
                                                $step3SubPartMarkers = array(
                                                        'step' => $this->step + 1,
                                                        'llOptions' => 'You have two options:',
                                                        'action' => htmlspecialchars($this->action),
                                                        'llOption1' => 'Create a new database (recommended):',
-                                                       'llRemark1' => 'Enter a name for your TYPO3 database.',
+                                                       'llRemark1' => $llRemark1,
+                                                       'll_Db_Pattern_Remark' => $llDbPatternRemark,
+                                                       'll_Db_Pattern_List' => $llDbPatternList,
+                                                       'formFieldAttributesNew' => $formFieldAttributesNew,
+                                                       'formFieldAttributesSelect' => $formFieldAttributesSelect,
                                                        'llOption2' => 'Select an EMPTY existing database:',
                                                        'llRemark2' => 'Any tables used by TYPO3 will be overwritten.',
                                                        'continue' => 'Continue'
@@ -8379,9 +8407,74 @@ $out="
 
                $this->errorMessages[] = $messageText;
        }
+
+       /**
+        * Checks whether the mysql user is allowed to create new databases.
+        *
+        * This code is adopted from the phpMyAdmin project
+        * http://www.phpmyadmin.net
+        *
+        * @return boolean
+        */
+       protected function checkCreateDatabasePrivileges() {
+               $createAllowed = FALSE;
+               $allowedPatterns = array();
+
+               $grants = $GLOBALS['TYPO3_DB']->sql_query('SHOW GRANTS');
+
+                       // we get one or more lines like this
+
+                       // insufficent rights:
+                       // GRANT USAGE ON *.* TO 'test'@'localhost' IDENTIFIED BY ...
+                       // GRANT ALL PRIVILEGES ON `test`.* TO 'test'@'localhost'
+
+                       // sufficient rights:
+                       // GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY ...
+
+                       // loop over all result rows
+               while (($row = $GLOBALS['TYPO3_DB']->sql_fetch_row($grants)) !== FALSE) {
+                       $grant = $row[0];
+                       $dbNameOffset = strpos($grant, ' ON ') + 4;
+                       $dbName = substr($grant, $dbNameOffset, strpos($grant, '.', $dbNameOffset) - $dbNameOffset);
+                       $privileges = substr($grant, 6, (strpos($grant, ' ON ') - 6));
+
+                               // we need at least one of the following privileges
+                       if ($privileges === 'ALL'
+                               || $privileges === 'ALL PRIVILEGES'
+                               || $privileges === 'CREATE'
+                               || strpos($privileges, 'CREATE,') !== FALSE) {
+
+
+                                       // and we need this privelege not on a specific DB, but on *
+                               if ($dbName === '*') {
+                                               // user has permissions to create new databases
+                                       $createAllowed = TRUE;
+                                       break;
+                               } else {
+                                       $allowedPatterns[] = str_replace('`', '', $dbName);
+                               }
+                       }
+               }
+
+                       // remove all existing databases from the list of allowed patterns
+               $existingDatabases = $this->getDatabaseList();
+               foreach ($allowedPatterns as $index => $pattern) {
+                       if (strpos($pattern, '%') !== FALSE) continue;
+
+                       if (in_array($pattern, $existingDatabases)) {
+                               unset($allowedPatterns[$index]);
+                       }
+               }
+
+               if (count($allowedPatterns) > 0) {
+                       return $allowedPatterns;
+               } else {
+                       return $createAllowed;
+               }
+       }
 }
 
 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/install/mod/class.tx_install.php'])) {
        include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/install/mod/class.tx_install.php']);
 }
-?>
\ No newline at end of file
+?>