diff --git a/ChangeLog b/ChangeLog index d2464e34f..a158ff0f3 100755 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,9 @@ $Source$ * Documentation.html: Various fixes in documentation, mostly grammmar (patch #1453198, thanks to Isaac Bennetch - ibennetch). * lang/*: Remove *font_family. + * Documentation.html, import.php, querywindow.php, js/functions.js, + libraries/header.inc.php, libraries/import.lib.php: Improve + functionality of limiting DROP DATABASE (bug #1456082). 2006-04-26 Michal Čihař * libraries/plugin_interface.lib.php: diff --git a/Documentation.html b/Documentation.html index 67afb8f9b..0d43f1665 100755 --- a/Documentation.html +++ b/Documentation.html @@ -1028,7 +1028,13 @@ ALTER TABLE `pma_column_comments` delete their own database or not. If set as FALSE, the link "Drop Database" will not be shown, and even a "DROP DATABASE mydatabase" will be rejected. Quite practical for - ISP's with many customers. + ISP's with many + customers.
+ Please note that this limitation of SQL queries is not as strict as + when using MySQL privileges. This is due to nature of SQL queries + which might be quite complicated. So this choice should be viewed as + help to avoid accidental dropping rather than strict privilege + limitation.
$cfg[Confirm] boolean
Whether a warning ("Are your really sure...") should be diff --git a/import.php b/import.php index fcef01e3f..31bcb157e 100644 --- a/import.php +++ b/import.php @@ -19,12 +19,12 @@ if (!empty($sql_query)) { $import_text = $sql_query; $import_type = 'query'; $format = 'sql'; - + // refresh left frame on changes in table or db structure if (preg_match('/^(CREATE|ALTER|DROP)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', $sql_query)) { $GLOBALS['reload'] = true; } - + unset($sql_query); } elseif (!empty($sql_localfile)) { // run SQL file on server @@ -44,7 +44,7 @@ if (!empty($sql_query)) { $format = 'sql'; } -// If we didn't get any parameters, either user called this directly, or +// If we didn't get any parameters, either user called this directly, or // upload limit has been reached, let's assume the second possibility. if ($_POST == array() && $_GET == array()) { require_once('./libraries/header.inc.php'); @@ -137,12 +137,12 @@ if (!empty($id_bookmark)) { if (isset($bookmark_variable) && !empty($bookmark_variable)) { $import_text = preg_replace('|/\*(.*)\[VARIABLE\](.*)\*/|imsU', '${1}' . PMA_sqlAddslashes($bookmark_variable) . '${2}', $import_text); } - + // refresh left frame on changes in table or db structure if (preg_match('/^(CREATE|ALTER|DROP)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', $import_text)) { $GLOBALS['reload'] = true; } - + break; case 1: // bookmarked query that have to be displayed $import_text = PMA_queryBookmarks($db, $cfg['Bookmark'], $id_bookmark); @@ -178,7 +178,7 @@ if (!empty($bkm_label) && !empty($import_text)) { } PMA_addBookmarks($bfields, $cfg['Bookmark'], isset($bkm_all_users)); - + $bookmark_created = TRUE; } // end store bookmarks @@ -239,7 +239,7 @@ if ($import_file != 'none' && !$error) { } } } - + // Handle file compression $compression = PMA_detectCompression($import_file); if ($compression === FALSE) { diff --git a/js/functions.js b/js/functions.js index 2742685f3..7e3f26f2e 100644 --- a/js/functions.js +++ b/js/functions.js @@ -138,7 +138,7 @@ function confirmQuery(theForm1, sqlQuery1) else { // "DROP DATABASE" statement isn't allowed if (noDropDbMsg != '') { - var drop_re = new RegExp('DROP\\s+(IF EXISTS\\s+)?DATABASE\\s', 'i'); + var drop_re = new RegExp('(^|;)\\s*DROP\\s+(IF EXISTS\\s+)?DATABASE\\s', 'i'); if (drop_re.test(sqlQuery1.value)) { alert(noDropDbMsg); theForm1.reset(); diff --git a/libraries/header.inc.php b/libraries/header.inc.php index 88bd301db..450abb79f 100644 --- a/libraries/header.inc.php +++ b/libraries/header.inc.php @@ -66,7 +66,8 @@ if (empty($GLOBALS['is_header_sent'])) { // js form validation stuff var errorMsg0 = ''; var errorMsg1 = ''; - var noDropDbMsg = ''; + var noDropDbMsg = ''; var confirmMsg = ''; var confirmMsgDropDB = ''; //--> diff --git a/libraries/import.lib.php b/libraries/import.lib.php index a99606aa0..287eb2a63 100644 --- a/libraries/import.lib.php +++ b/libraries/import.lib.php @@ -68,7 +68,7 @@ function PMA_detectCompression($filepath) */ function PMA_importRunQuery($sql = '', $full = '') { - global $import_run_buffer, $go_sql, $complete_query, $display_query, $sql_query, $cfg, $my_die, $error, $reload, $finished, $timeout_passed, $skip_queries, $executed_queries, $max_sql_len, $read_multiply, $cfg, $sql_query_disabled, $db, $run_query, $is_superuser; + global $import_run_buffer, $go_sql, $complete_query, $display_query, $sql_query, $cfg, $my_die, $error, $reload, $finished, $timeout_passed, $skip_queries, $executed_queries, $max_sql_len, $read_multiply, $cfg, $sql_query_disabled, $db, $run_query, $is_superuser, $message, $show_error_header; $read_multiply = 1; if (isset($import_run_buffer)) { // Should we skip something? @@ -76,75 +76,75 @@ function PMA_importRunQuery($sql = '', $full = '') $skip_queries--; } else { if (!empty($import_run_buffer['sql']) && trim($import_run_buffer['sql']) != '') { - if (!$cfg['AllowUserDropDatabase'] - && !$is_superuser - && preg_match('@DROP[[:space:]]+(IF EXISTS[[:space:]]+)?DATABASE @i', $import_run_buffer['sql'])) { - $message = $GLOBALS['strNoDropDatabases']; - $show_error_header = TRUE; - $error = TRUE; - return; - } $max_sql_len = max($max_sql_len, strlen($import_run_buffer['sql'])); if (!$sql_query_disabled) { $sql_query .= $import_run_buffer['full']; } - $executed_queries++; - if ($run_query && $finished && empty($sql) && !$error && ( - (!empty($import_run_buffer['sql']) && preg_match('/^[\s]*(SELECT|SHOW)/i', $import_run_buffer['sql'])) || - ($executed_queries == 1) - )) { - $go_sql = TRUE; - if (!$sql_query_disabled) { - $complete_query = $sql_query; - $display_query = $sql_query; - } else { - $complete_query = ''; - $display_query = ''; - } - $sql_query = $import_run_buffer['sql']; - } elseif ($run_query) { - $result = PMA_DBI_try_query($import_run_buffer['sql']); - $msg = '# '; - if ($result === FALSE) { // execution failed - if (!isset($my_die)) { - $my_die = array(); - } - $my_die[] = array('sql' => $import_run_buffer['full'], 'error' => PMA_DBI_getError()); - - if ($cfg['VerboseMultiSubmit']) { - $msg .= $GLOBALS['strError']; - } - - if (!$cfg['IgnoreMultiSubmitErrors']) { - $error = TRUE; - return; - } - } elseif ($cfg['VerboseMultiSubmit']) { - $a_num_rows = (int)@PMA_DBI_num_rows($result); - $a_aff_rows = (int)@PMA_DBI_affected_rows(); - if ($a_num_rows > 0) { - $msg .= $GLOBALS['strRows'] . ': ' . $a_num_rows; - } elseif ($a_aff_rows > 0) { - $a_rows = - $msg .= $GLOBALS['strAffectedRows'] . ' ' . $a_aff_rows; + if (!$cfg['AllowUserDropDatabase'] + && !$is_superuser + && preg_match('@^[[:space:]]*DROP[[:space:]]+(IF EXISTS[[:space:]]+)?DATABASE @i', $import_run_buffer['sql'])) { + $message = $GLOBALS['strNoDropDatabases']; + $show_error_header = TRUE; + $error = TRUE; + } else { + $executed_queries++; + if ($run_query && $finished && empty($sql) && !$error && ( + (!empty($import_run_buffer['sql']) && preg_match('/^[\s]*(SELECT|SHOW)/i', $import_run_buffer['sql'])) || + ($executed_queries == 1) + )) { + $go_sql = TRUE; + if (!$sql_query_disabled) { + $complete_query = $sql_query; + $display_query = $sql_query; } else { - $msg .= $GLOBALS['strEmptyResultSet']; + $complete_query = ''; + $display_query = ''; } - } - if (!$sql_query_disabled) { - $sql_query .= $msg . "\n"; - } + $sql_query = $import_run_buffer['sql']; + } elseif ($run_query) { + $result = PMA_DBI_try_query($import_run_buffer['sql']); + $msg = '# '; + if ($result === FALSE) { // execution failed + if (!isset($my_die)) { + $my_die = array(); + } + $my_die[] = array('sql' => $import_run_buffer['full'], 'error' => PMA_DBI_getError()); - // If a 'USE ' SQL-clause was found and the query succeeded, set our current $db to the new one - if ($result != FALSE && preg_match('@^[\s]*USE[[:space:]]*([\S]+)@i', $import_run_buffer['sql'], $match)) { - $db = trim($match[1]); - $reload = TRUE; - } + if ($cfg['VerboseMultiSubmit']) { + $msg .= $GLOBALS['strError']; + } - if ($result != FALSE && preg_match('@^[\s]*(DROP|CREATE)[\s]+(IF EXISTS[[:space:]]+)?(TABLE|DATABASE)[[:space:]]+(.+)@im', $import_run_buffer['sql'])) { - $reload = TRUE; - } - } // end run query + if (!$cfg['IgnoreMultiSubmitErrors']) { + $error = TRUE; + return; + } + } elseif ($cfg['VerboseMultiSubmit']) { + $a_num_rows = (int)@PMA_DBI_num_rows($result); + $a_aff_rows = (int)@PMA_DBI_affected_rows(); + if ($a_num_rows > 0) { + $msg .= $GLOBALS['strRows'] . ': ' . $a_num_rows; + } elseif ($a_aff_rows > 0) { + $a_rows = + $msg .= $GLOBALS['strAffectedRows'] . ' ' . $a_aff_rows; + } else { + $msg .= $GLOBALS['strEmptyResultSet']; + } + } + if (!$sql_query_disabled) { + $sql_query .= $msg . "\n"; + } + + // If a 'USE ' SQL-clause was found and the query succeeded, set our current $db to the new one + if ($result != FALSE && preg_match('@^[\s]*USE[[:space:]]*([\S]+)@i', $import_run_buffer['sql'], $match)) { + $db = trim($match[1]); + $reload = TRUE; + } + + if ($result != FALSE && preg_match('@^[\s]*(DROP|CREATE)[\s]+(IF EXISTS[[:space:]]+)?(TABLE|DATABASE)[[:space:]]+(.+)@im', $import_run_buffer['sql'])) { + $reload = TRUE; + } + } // end run query + } // end if not DROP DATABASE } // end non empty query elseif (!empty($import_run_buffer['full'])) { if ($go_sql) { @@ -172,7 +172,7 @@ function PMA_importRunQuery($sql = '', $full = '') } } // end do query (no skip) } // end buffer exists - + // Do we have something to push into buffer? if (!empty($sql) || !empty($full)) { $import_run_buffer = array('sql' => $sql, 'full' => $full); @@ -193,7 +193,7 @@ function PMA_importRunQuery($sql = '', $full = '') function PMA_importGetNextChunk($size = 32768) { global $import_file, $import_text, $finished, $compression, $import_handle, $offset, $charset_conversion, $charset_of_file, $charset, $read_multiply, $read_limit; - + // Add some progression while reading large amount of data if ($read_multiply <= 8) { $size *= $read_multiply; @@ -226,7 +226,7 @@ function PMA_importGetNextChunk($size = 32768) return $r; } } - + switch ($compression) { case 'application/bzip2': $result = bzread($import_handle, $size); @@ -247,7 +247,7 @@ function PMA_importGetNextChunk($size = 32768) break; } $offset += $size; - + if ($charset_conversion) { return PMA_convert_string($charset_of_file, $charset, $result); } else { @@ -264,7 +264,7 @@ function PMA_importGetNextChunk($size = 32768) $result = substr($result, 2); } } - return $result; + return $result; } } diff --git a/querywindow.php b/querywindow.php index 13f5bb422..d72dcb0fd 100644 --- a/querywindow.php +++ b/querywindow.php @@ -69,7 +69,7 @@ function query_tab_commit(tab) { /**/ var errorMsg0 = ''; var errorMsg1 = ''; -var noDropDbMsg = ''; var confirmMsg = '';