From 863a6e24d499c14ffe95185932b59dd1deac1d1e Mon Sep 17 00:00:00 2001 From: Marc Delisle Date: Fri, 30 Sep 2005 19:22:11 +0000 Subject: [PATCH] bug #1307208, detect lack of permission for CREATE TABLE --- ChangeLog | 7 ++ db_details_structure.php | 36 +---------- db_operations.php | 33 +--------- libraries/check_user_privileges.lib.php | 45 ++++++++----- libraries/display_create_database.lib.php | 4 +- libraries/display_create_table.lib.php | 78 +++++++++++++++++++++++ main.php | 2 +- 7 files changed, 119 insertions(+), 86 deletions(-) create mode 100644 libraries/display_create_table.lib.php diff --git a/ChangeLog b/ChangeLog index dafbf9ba2..b15e0cbb2 100755 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,13 @@ phpMyAdmin - Changelog $Id$ $Source$ +2005-09-30 Marc Delisle + * main.php, db_details_structure.php, db_operations.php, + libraries/check_user_privileges.php, /display_create_database.lib.php, + /display_create_table.lib.php: bug #1307208, detect lack of privileges + before showing the "Create new table" dialog. Please test. + TODO: detect escaped wildcard privileges + 2005-09-30 Michal Čihař * libraries/display_export.lib.php, libraries/export/sql.php, db_operations.php, tbl_properties_operations.php: Fix auto increment diff --git a/db_details_structure.php b/db_details_structure.php index 4ec005b6c..a34bb5553 100644 --- a/db_details_structure.php +++ b/db_details_structure.php @@ -632,41 +632,7 @@ if ($num_tables > 0) { } // end if if (PMA_MYSQL_INT_VERSION < 50002 || (PMA_MYSQL_INT_VERSION >= 50002 && $db != 'information_schema')) { -?> - -
- - - '; - echo ' '; - echo ' '; - echo ' '; - echo ' '; - echo ' '; - echo '
'; } - // if you want navigation: - $strDBLink = '' - . htmlspecialchars($GLOBALS['db']) . ''; - // else use - // $strDBLink = htmlspecialchars($db); - echo ' ' . sprintf($strCreateNewTable, $strDBLink) . ': ' . "\n"; - echo '
'; - echo ' ' . $strName . ': ' . "\n"; - echo ' '; - echo ' ' . ''; - echo '  
'; - if (!isset($strNumberOfFields)) { - $strNumberOfFields = $strFields; - } - echo ' ' . $strNumberOfFields . ': ' . "\n"; - echo ' '; - echo ' ' . '' . "\n"; - echo ' '; - echo ' ' . ' ' . "\n"; - echo '
'; - echo '
'; + require('./libraries/display_create_table.lib.php'); } // end if (Create Table dialog) /** diff --git a/db_operations.php b/db_operations.php index eb87c4c4f..13b72e802 100644 --- a/db_operations.php +++ b/db_operations.php @@ -141,39 +141,8 @@ if (PMA_MYSQL_INT_VERSION < 50002 || (PMA_MYSQL_INT_VERSION >= 50002 && $db != ' } if (!$is_information_schema) { -?> - - - - - '; - echo ' '; - echo ' '; - echo ' '; - echo ' '; - echo ' ' . "\n"; - echo ' ' . "\n"; - echo '
'; } - // if you want navigation: - $strDBLink = '' - . htmlspecialchars($GLOBALS['db']) . ''; - // else use - // $strDBLink = htmlspecialchars($db); - echo ' ' . sprintf($strCreateNewTable, $strDBLink) . ': ' . "\n"; - echo '
'; - echo ' ' . $strName . ': ' . "\n"; - echo ' '; - echo ' ' . ''; - echo '  
'; - echo ' ' . $strFields . ': ' . "\n"; - echo ' '; - echo ' ' . '' . "\n"; - echo ' '; - echo ' ' . ' ' . "\n"; - echo '
' . "\n"; + require('./libraries/display_create_table.lib.php'); echo ''; if ($cfgRelation['commwork']) { diff --git a/libraries/check_user_privileges.lib.php b/libraries/check_user_privileges.lib.php index 2f805ff48..cf6138b45 100644 --- a/libraries/check_user_privileges.lib.php +++ b/libraries/check_user_privileges.lib.php @@ -2,21 +2,22 @@ /* $Id$ */ // vim: expandtab sw=4 ts=4 sts=4: -// Get user's global privileges ($dbh and $userlink are links to MySQL -// defined in the "common.lib.php" library) +// Get user's global privileges and some db-specific 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_create_db_priv = FALSE; $is_process_priv = TRUE; $is_reload_priv = FALSE; $db_to_create = ''; +$dbs_where_create_table_allowed = array(); // 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) { +function PMA_analyseShowGrant($rs_usr, &$is_create_db_priv, &$db_to_create, &$is_reload_priv, &$dbs_where_create_table_allowed) { $re0 = '(^|(\\\\\\\\)+|[^\])'; // non-escaped wildcards $re1 = '(^|[^\])(\\\)+'; // escaped wildcards @@ -26,19 +27,32 @@ function PMA_analyseShowGrant($rs_usr, &$is_create_priv, &$db_to_create, &$is_re $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; + // a global CREATE privilege + $is_create_db_priv = TRUE; $is_reload_priv = TRUE; $db_to_create = ''; + $dbs_where_create_table_allowed[] = '*'; break; } // end if - else if ( (ereg($re0 . '%|_', $show_grants_dbname) + else { + // this array may contain wildcards + $dbs_where_create_table_allowed[] = $show_grants_dbname; + + if ( (ereg($re0 . '%|_', $show_grants_dbname) && !ereg('\\\\%|\\\\_', $show_grants_dbname)) + // does this db exist? || (!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; + $is_create_db_priv = TRUE; + + // TODO: collect $db_to_create into an array, to display a drop-down + // in the "Create new database" dialog + // + // now we don't break, we want all possible databases + //break; + } // end if } // end elseif } // end if } // end while @@ -53,7 +67,7 @@ function PMA_analyseShowGrant($rs_usr, &$is_create_priv, &$db_to_create, &$is_re 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_analyseShowGrant($rs_usr,$is_create_db_priv, $db_to_create, $is_reload_priv, $dbs_where_create_table_allowed); PMA_DBI_free_result($rs_usr); unset($rs_usr); } @@ -63,7 +77,7 @@ if (PMA_MYSQL_INT_VERSION >= 40102) { // the controluser is correctly defined; but here, $dbh could contain // $userlink so maybe the SELECT will fail - if (!$is_create_priv) { + if (!$is_create_db_priv) { $res = PMA_DBI_query('SELECT USER();'); list($mysql_cur_user_and_host) = PMA_DBI_fetch_row($res); $mysql_cur_user = substr($mysql_cur_user_and_host, 0, strrpos($mysql_cur_user_and_host, '@')); @@ -72,8 +86,8 @@ if (PMA_MYSQL_INT_VERSION >= 40102) { $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_create_db_priv) { + $is_create_db_priv = ($result_usr['Create_priv'] == 'Y'); } if (!$is_reload_priv) { $is_reload_priv = ($result_usr['Reload_priv'] == 'Y'); @@ -87,7 +101,7 @@ if (PMA_MYSQL_INT_VERSION >= 40102) { // 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) { + if (!$is_create_db_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) { @@ -98,7 +112,7 @@ if (PMA_MYSQL_INT_VERSION >= 40102) { || (!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; + $is_create_db_priv = TRUE; break; } // end if } // end while @@ -117,7 +131,7 @@ if (PMA_MYSQL_INT_VERSION >= 40102) { } unset($local_query); if ($rs_usr) { - PMA_analyseShowGrant($rs_usr,$is_create_priv, $db_to_create, $is_reload_priv); + PMA_analyseShowGrant($rs_usr,$is_create_db_priv, $db_to_create, $is_reload_priv, $dbs_where_create_table_allowed); PMA_DBI_free_result($rs_usr); unset($rs_usr); } // end if @@ -131,4 +145,3 @@ if (!$cfg['SuggestDBName']) { } ?> - diff --git a/libraries/display_create_database.lib.php b/libraries/display_create_database.lib.php index 5ac158016..c75472eb7 100644 --- a/libraries/display_create_database.lib.php +++ b/libraries/display_create_database.lib.php @@ -2,11 +2,11 @@ /* $Id$ */ // vim: expandtab sw=4 ts=4 sts=4: -// Displays form for creating database (if user has priveleges for that) +// Displays form for creating database (if user has privileges for that) require_once('./libraries/check_user_privileges.lib.php'); -if ($is_create_priv) { +if ($is_create_db_priv) { // The user is allowed to create a db ?> diff --git a/libraries/display_create_table.lib.php b/libraries/display_create_table.lib.php new file mode 100644 index 000000000..babb259ed --- /dev/null +++ b/libraries/display_create_table.lib.php @@ -0,0 +1,78 @@ + + + +
+ + '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo '
'; } + // if you want navigation: + $strDBLink = '' + . htmlspecialchars($GLOBALS['db']) . ''; + // else use + // $strDBLink = htmlspecialchars($db); + echo ' ' . sprintf($strCreateNewTable, $strDBLink) . ': ' . "\n"; + echo '
'; + echo ' ' . $strName . ': ' . "\n"; + echo ' '; + echo ' ' . ''; + echo '  
'; + if (!isset($strNumberOfFields)) { + $strNumberOfFields = $strFields; + } + echo ' ' . $strNumberOfFields . ': ' . "\n"; + echo ' '; + echo ' ' . '' . "\n"; + echo ' '; + echo ' ' . ' ' . "\n"; + echo '
'; + echo '' . "\n"; +} else { +?> + + + ' . "\n"; + echo ' ' . "\n"; + echo ' ' . "\n"; + echo ' ' . "\n"; + echo '
' . "\n"; + } + $strDBLink = htmlspecialchars($db); + echo ' ' . sprintf($strCreateNewTable, $strDBLink) . ': ' . "\n"; + echo '
' . "\n"; + echo '' + . ($cfg['ErrorIconic'] ? '' : '') + . '' . $strNoPrivileges .'' . "\n"; + echo '
' . "\n"; + +} // end if +?> diff --git a/main.php b/main.php index e150436fe..a43dcf5a4 100644 --- a/main.php +++ b/main.php @@ -175,7 +175,7 @@ if ($server > 0) { // loic1: Displays the MySQL column only if at least one feature has to be // displayed - if ($is_superuser || $is_create_priv || $is_process_priv || $is_reload_priv + if ($is_superuser || $is_create_db_priv || $is_process_priv || $is_reload_priv || $cfg['ShowMysqlInfo'] || $cfg['ShowMysqlVars'] || $cfg['ShowChgPassword'] || $cfg['Server']['auth_type'] != 'config') { ?>