From 48366e0746c61c39e9064b5d5e082a0c537bd7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Wed, 13 Jul 2005 12:44:51 +0000 Subject: [PATCH] Show box for creating database only if user has privileges to do so (bug #1167892). --- ChangeLog | 3 + libraries/check_user_privileges.lib.php | 130 +++++++++++++++++++ libraries/display_create_database.lib.php | 35 +++++ main.php | 151 +--------------------- server_databases.php | 18 +-- 5 files changed, 171 insertions(+), 166 deletions(-) create mode 100644 libraries/check_user_privileges.lib.php create mode 100644 libraries/display_create_database.lib.php diff --git a/ChangeLog b/ChangeLog index 8e37bc1b9..e1b89f9a1 100755 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,9 @@ $Source$ * libraries/common.lib.php: Use eval for config file including to catch parse errors (bug #1223319), on error page display config file that actually failed. + * main.php, server_databases.php, libraries/check_user_privileges.lib.php, + libraries/display_create_database.lib.php: Show box for creating + database only if user has privileges to do so (bug #1167892). 2005-07-12 Marc Delisle * sql.php: for Insert row and Export, use post when the query is too big diff --git a/libraries/check_user_privileges.lib.php b/libraries/check_user_privileges.lib.php new file mode 100644 index 000000000..6bebe35db --- /dev/null +++ b/libraries/check_user_privileges.lib.php @@ -0,0 +1,130 @@ += 40102) { + $rs_usr = PMA_DBI_try_query('SHOW GRANTS', $userlink, PMA_DBI_QUERY_STORE); + if ($rs_usr) { + PMA_analyseShowGrant($rs_usr,$is_create_priv, $db_to_create, $is_reload_priv); + PMA_DBI_free_result($rs_usr); + unset($rs_usr); + } +} else { + +// Before MySQL 4.1.2, we first try to find a priv in mysql.user. Hopefuly +// the controluser is correctly defined; but here, $dbh could contain +// $userlink so maybe the SELECT will fail + + if (!$is_create_priv) { + $local_query = 'SELECT Create_priv, Reload_priv FROM mysql.user WHERE ' . PMA_convert_using('User') . ' = ' . PMA_convert_using(PMA_sqlAddslashes($mysql_cur_user), 'quoted') . ' OR ' . PMA_convert_using('User') . ' = ' . PMA_convert_using('', 'quoted') . ';'; + $rs_usr = PMA_DBI_try_query($local_query, $dbh); // Debug: or PMA_mysqlDie('', $local_query, FALSE); + if ($rs_usr) { + while ($result_usr = PMA_DBI_fetch_assoc($rs_usr)) { + if (!$is_create_priv) { + $is_create_priv = ($result_usr['Create_priv'] == 'Y'); + } + if (!$is_reload_priv) { + $is_reload_priv = ($result_usr['Reload_priv'] == 'Y'); + } + } // end while + PMA_DBI_free_result($rs_usr); + unset($rs_usr, $result_usr); + } // end if + } // end if + + // If the user has Create priv on a inexistant db, show him in the dialog + // the first inexistant db name that we find, in most cases it's probably + // the one he just dropped :) + if (!$is_create_priv) { + $local_query = 'SELECT DISTINCT Db FROM mysql.db WHERE ' . PMA_convert_using('Create_priv') . ' = ' . PMA_convert_using('Y', 'quoted') . ' AND (' . PMA_convert_using('User') . ' = ' .PMA_convert_using(PMA_sqlAddslashes($mysql_cur_user), 'quoted') . ' OR ' . PMA_convert_using('User') . ' = ' . PMA_convert_using('', 'quoted') . ');'; + $rs_usr = PMA_DBI_try_query($local_query, $dbh, PMA_DBI_QUERY_STORE); + if ($rs_usr) { + $re0 = '(^|(\\\\\\\\)+|[^\])'; // non-escaped wildcards + $re1 = '(^|[^\])(\\\)+'; // escaped wildcards + while ($row = PMA_DBI_fetch_assoc($rs_usr)) { + if (ereg($re0 . '(%|_)', $row['Db']) + || (!PMA_DBI_try_query('USE ' . ereg_replace($re1 . '(%|_)', '\\1\\3', $row['Db'])) && substr(PMA_DBI_getError(), 1, 4) != 1044)) { + $db_to_create = ereg_replace($re0 . '%', '\\1...', ereg_replace($re0 . '_', '\\1?', $row['Db'])); + $db_to_create = ereg_replace($re1 . '(%|_)', '\\1\\3', $db_to_create); + $is_create_priv = TRUE; + break; + } // end if + } // end while + PMA_DBI_free_result($rs_usr); + unset($rs_usr, $row, $re0, $re1); + } // end if + else { + // Finally, let's try to get the user's privileges by using SHOW + // GRANTS... + // Maybe we'll find a little CREATE priv there :) + $rs_usr = PMA_DBI_try_query('SHOW GRANTS FOR ' . $mysql_cur_user_and_host . ';', $dbh, PMA_DBI_QUERY_STORE); + if (!$rs_usr) { + // OK, now we'd have to guess the user's hostname, but we + // only try out the 'username'@'%' case. + $rs_usr = PMA_DBI_try_query('SHOW GRANTS FOR ' . $mysql_cur_user . ';', $dbh, PMA_DBI_QUERY_STORE); + } + unset($local_query); + if ($rs_usr) { + PMA_analyseShowGrant($rs_usr,$is_create_priv, $db_to_create, $is_reload_priv); + PMA_DBI_free_result($rs_usr); + unset($rs_usr); + } // end if + } // end elseif + } // end if +} // end else (MySQL < 4.1.2) + +// If disabled, don't show it +if (!$cfg['SuggestDBName']) { + $db_to_create = ''; +} + +?> + diff --git a/libraries/display_create_database.lib.php b/libraries/display_create_database.lib.php new file mode 100644 index 000000000..5ac158016 --- /dev/null +++ b/libraries/display_create_database.lib.php @@ -0,0 +1,35 @@ + +
+
+ + + + = 40101) { + require_once('./libraries/mysql_charsets.lib.php'); + echo PMA_generateCharsetDropdownBox(PMA_CSDROPDOWN_COLLATION, 'db_collation', NULL, NULL, TRUE, 5); + } + ?> + +
+ + +
+ ' + . ($cfg['ErrorIconic'] ? '' : '') + . '' . $strNoPrivileges .''; +} // end create db form or message +?> diff --git a/main.php b/main.php index c7ef9d732..30093cd9c 100644 --- a/main.php +++ b/main.php @@ -159,128 +159,8 @@ if (!$cfg['LeftDisplayServers']) { $is_superuser = FALSE; if ($server > 0) { - // Get user's global privileges ($dbh and $userlink are links to MySQL - // defined in the "common.lib.php" library) - // Note: if no controluser is defined, $dbh contains $userlink - $is_create_priv = FALSE; - $is_process_priv = TRUE; - $is_reload_priv = FALSE; - $db_to_create = ''; - -// We were trying to find if user if superuser with 'USE mysql' -// but users with the global priv CREATE TEMPORARY TABLES or LOCK TABLES -// can do a 'USE mysql' (even if they cannot see the tables) - $is_superuser = PMA_DBI_try_query('SELECT COUNT(*) FROM mysql.user', $userlink, PMA_DBI_QUERY_STORE); - -function PMA_analyseShowGrant($rs_usr, &$is_create_priv, &$db_to_create, &$is_reload_priv) { - - $re0 = '(^|(\\\\\\\\)+|[^\])'; // non-escaped wildcards - $re1 = '(^|[^\])(\\\)+'; // escaped wildcards - while ($row = PMA_DBI_fetch_row($rs_usr)) { - $show_grants_dbname = substr($row[0], strpos($row[0], ' ON ') + 4,(strpos($row[0], '.', strpos($row[0], ' ON ')) - strpos($row[0], ' ON ') - 4)); - $show_grants_dbname = ereg_replace('^`(.*)`','\\1', $show_grants_dbname); - $show_grants_str = substr($row[0],6,(strpos($row[0],' ON ')-6)); - if (($show_grants_str == 'ALL') || ($show_grants_str == 'ALL PRIVILEGES') || ($show_grants_str == 'CREATE') || strpos($show_grants_str, 'CREATE')) { - if ($show_grants_dbname == '*') { - $is_create_priv = TRUE; - $is_reload_priv = TRUE; - $db_to_create = ''; - break; - } // end if - else if ( (ereg($re0 . '%|_', $show_grants_dbname) - && !ereg('\\\\%|\\\\_', $show_grants_dbname)) - || (!PMA_DBI_try_query('USE ' . ereg_replace($re1 .'(%|_)', '\\1\\3', $show_grants_dbname)) && substr(PMA_DBI_getError(), 1, 4) != 1044) - ) { - $db_to_create = ereg_replace($re0 . '%', '\\1...', ereg_replace($re0 . '_', '\\1?', $show_grants_dbname)); - $db_to_create = ereg_replace($re1 . '(%|_)', '\\1\\3', $db_to_create); - $is_create_priv = TRUE; - break; - } // end elseif - } // end if - } // end while -} // end function - -// Detection for some CREATE privilege. - -// Since MySQL 4.1.2, we can easily detect current user's grants -// using $userlink (no control user needed) -// and we don't have to try any other method for detection - - if (PMA_MYSQL_INT_VERSION >= 40102) { - $rs_usr = PMA_DBI_try_query('SHOW GRANTS', $userlink, PMA_DBI_QUERY_STORE); - if ($rs_usr) { - PMA_analyseShowGrant($rs_usr,$is_create_priv, $db_to_create, $is_reload_priv); - PMA_DBI_free_result($rs_usr); - unset($rs_usr); - } - } else { - -// Before MySQL 4.1.2, we first try to find a priv in mysql.user. Hopefuly -// the controluser is correctly defined; but here, $dbh could contain -// $userlink so maybe the SELECT will fail - - if (!$is_create_priv) { - $local_query = 'SELECT Create_priv, Reload_priv FROM mysql.user WHERE ' . PMA_convert_using('User') . ' = ' . PMA_convert_using(PMA_sqlAddslashes($mysql_cur_user), 'quoted') . ' OR ' . PMA_convert_using('User') . ' = ' . PMA_convert_using('', 'quoted') . ';'; - $rs_usr = PMA_DBI_try_query($local_query, $dbh); // Debug: or PMA_mysqlDie('', $local_query, FALSE); - if ($rs_usr) { - while ($result_usr = PMA_DBI_fetch_assoc($rs_usr)) { - if (!$is_create_priv) { - $is_create_priv = ($result_usr['Create_priv'] == 'Y'); - } - if (!$is_reload_priv) { - $is_reload_priv = ($result_usr['Reload_priv'] == 'Y'); - } - } // end while - PMA_DBI_free_result($rs_usr); - unset($rs_usr, $result_usr); - } // end if - } // end if - - // If the user has Create priv on a inexistant db, show him in the dialog - // the first inexistant db name that we find, in most cases it's probably - // the one he just dropped :) - if (!$is_create_priv) { - $local_query = 'SELECT DISTINCT Db FROM mysql.db WHERE ' . PMA_convert_using('Create_priv') . ' = ' . PMA_convert_using('Y', 'quoted') . ' AND (' . PMA_convert_using('User') . ' = ' .PMA_convert_using(PMA_sqlAddslashes($mysql_cur_user), 'quoted') . ' OR ' . PMA_convert_using('User') . ' = ' . PMA_convert_using('', 'quoted') . ');'; - $rs_usr = PMA_DBI_try_query($local_query, $dbh, PMA_DBI_QUERY_STORE); - if ($rs_usr) { - $re0 = '(^|(\\\\\\\\)+|[^\])'; // non-escaped wildcards - $re1 = '(^|[^\])(\\\)+'; // escaped wildcards - while ($row = PMA_DBI_fetch_assoc($rs_usr)) { - if (ereg($re0 . '(%|_)', $row['Db']) - || (!PMA_DBI_try_query('USE ' . ereg_replace($re1 . '(%|_)', '\\1\\3', $row['Db'])) && substr(PMA_DBI_getError(), 1, 4) != 1044)) { - $db_to_create = ereg_replace($re0 . '%', '\\1...', ereg_replace($re0 . '_', '\\1?', $row['Db'])); - $db_to_create = ereg_replace($re1 . '(%|_)', '\\1\\3', $db_to_create); - $is_create_priv = TRUE; - break; - } // end if - } // end while - PMA_DBI_free_result($rs_usr); - unset($rs_usr, $row, $re0, $re1); - } // end if - else { - // Finally, let's try to get the user's privileges by using SHOW - // GRANTS... - // Maybe we'll find a little CREATE priv there :) - $rs_usr = PMA_DBI_try_query('SHOW GRANTS FOR ' . $mysql_cur_user_and_host . ';', $dbh, PMA_DBI_QUERY_STORE); - if (!$rs_usr) { - // OK, now we'd have to guess the user's hostname, but we - // only try out the 'username'@'%' case. - $rs_usr = PMA_DBI_try_query('SHOW GRANTS FOR ' . $mysql_cur_user . ';', $dbh, PMA_DBI_QUERY_STORE); - } - unset($local_query); - if ($rs_usr) { - PMA_analyseShowGrant($rs_usr,$is_create_priv, $db_to_create, $is_reload_priv); - PMA_DBI_free_result($rs_usr); - unset($rs_usr); - } // end if - } // end elseif - } // end if - } // end else (MySQL < 4.1.2) - - if (!$cfg['SuggestDBName']) { - $db_to_create = ''; - } + require_once('./libraries/check_user_privileges.lib.php'); $common_url_query = PMA_generate_common_url(); @@ -309,34 +189,7 @@ function PMA_analyseShowGrant($rs_usr, &$is_create_priv, &$db_to_create, &$is_re ?> - -
-
- - - - = 40101) { - require_once('./libraries/mysql_charsets.lib.php'); - echo PMA_generateCharsetDropdownBox(PMA_CSDROPDOWN_COLLATION, 'db_collation', NULL, NULL, TRUE, 5); - } - ?> - -
- - -
- ' - . ($cfg['ErrorIconic'] ? '' : '') - . '' . $strNoPrivileges .''; - } // end create db form or message - ?> + 0) { /** * Create new database. */ -?> - -
-
- - - - = 40101) { - require_once('./libraries/mysql_charsets.lib.php'); - echo PMA_generateCharsetDropdownBox(PMA_CSDROPDOWN_COLLATION, 'db_collation', NULL, NULL, TRUE, 5); -} - ?> - -
- -