bug #2416418 Escaping special characters (and other problems too)

This commit is contained in:
Marc Delisle
2009-01-04 20:26:23 +00:00
parent f70bee9e2f
commit f606970a1f
2 changed files with 80 additions and 49 deletions

View File

@@ -37,6 +37,7 @@ $HeadURL: https://phpmyadmin.svn.sourceforge.net/svnroot/phpmyadmin/trunk/phpMyA
- bug #2473127 [display] Deleting rows displays tbl structure, not contents - bug #2473127 [display] Deleting rows displays tbl structure, not contents
- patch #2478940 [core] PHP 5.2+ warning does not work, - patch #2478940 [core] PHP 5.2+ warning does not work,
thanks to Jürgen Wind - windkiel thanks to Jürgen Wind - windkiel
- bug #2416418 [privileges] Escaping special characters
3.1.1.0 (2008-12-09) 3.1.1.0 (2008-12-09)
- patch #2242765 [core] Navi panel server links wrong, - patch #2242765 [core] Navi panel server links wrong,

View File

@@ -75,6 +75,37 @@ if (!$is_superuser) {
require_once './libraries/footer.inc.php'; require_once './libraries/footer.inc.php';
} }
/**
* Escapes wildcard in a database+table specification
* before using it in a GRANT statement.
*
* Escaping a wildcard character in a GRANT is only accepted at the global
* or database level, not at table level; this is why I remove
* the escaping character. Internally, in mysql.tables_priv.Db there are
* no escaping (for example test_db) but in mysql.db you'll see test\_db
* for a db-specific privilege.
*
* @param string $db_and_table
* @param string $dbname
* @param string $tablename
* @return string the escaped (if necessary) $db_and_table
*/
function PMA_WildcardEscapeForGrant($db_and_table, $dbname, $tablename) {
if (! strlen($dbname)) {
$db_and_table = '*.*';
} else {
if (strlen($tablename)) {
$db_and_table = PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . '.';
$db_and_table .= PMA_backquote($tablename);
} else {
$db_and_table = PMA_backquote($dbname) . '.';
$db_and_table .= '*';
}
}
return $db_and_table;
}
/** /**
* Generates a condition on the user name * Generates a condition on the user name
* *
@@ -1041,15 +1072,7 @@ if (isset($_REQUEST['change_copy'])) {
* Updates privileges * Updates privileges
*/ */
if (!empty($update_privs)) { if (!empty($update_privs)) {
// escaping a wildcard character in a GRANT is only accepted at the global $db_and_table = PMA_WildcardEscapeForGrant($db_and_table, $dbname, (isset($tablename) ? $tablename : ''));
// or database level, not at table level; this is why I remove
// the escaping character
// Note: in the phpMyAdmin list of Database-specific privileges,
// we will have for example
// test\_db SELECT (this one is for privileges on a db level)
// test_db USAGE (this one is for table-specific privileges)
//
// It looks curious but reflects the way MySQL works
$sql_query0 = $sql_query0 =
'REVOKE ALL PRIVILEGES ON ' . $db_and_table 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
@@ -1061,54 +1084,59 @@ if (!empty($update_privs)) {
} else { } else {
$sql_query1 = ''; $sql_query1 = '';
} }
$sql_query2 =
'GRANT ' . join(', ', PMA_extractPrivInfo())
. ' ON ' . $db_and_table
. ' TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . $hostname . '\'';
/** // Should not do a GRANT USAGE for a table-specific privilege, it
* @todo similar code appears twice in this script // causes problems later (cannot revoke it)
*/ if (! (isset($tablename) && 'USAGE' == implode('', PMA_extractPrivInfo()))) {
if ((isset($Grant_priv) && $Grant_priv == 'Y') $sql_query2 =
|| (! isset($dbname) 'GRANT ' . join(', ', PMA_extractPrivInfo())
&& (isset($max_questions) || isset($max_connections) . ' ON ' . $db_and_table
|| isset($max_updates) || isset($max_user_connections)))) . ' TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . $hostname . '\'';
{
$sql_query2 .= 'WITH'; /**
if (isset($Grant_priv) && $Grant_priv == 'Y') { * @todo similar code appears twice in this script
$sql_query2 .= ' GRANT OPTION'; */
} if ((isset($Grant_priv) && $Grant_priv == 'Y')
if (isset($max_questions)) { || (! isset($dbname)
$max_questions = max(0, (int)$max_questions); && (isset($max_questions) || isset($max_connections)
$sql_query2 .= ' MAX_QUERIES_PER_HOUR ' . $max_questions; || isset($max_updates) || isset($max_user_connections))))
} {
if (isset($max_connections)) { $sql_query2 .= 'WITH';
$max_connections = max(0, (int)$max_connections); if (isset($Grant_priv) && $Grant_priv == 'Y') {
$sql_query2 .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections; $sql_query2 .= ' GRANT OPTION';
} }
if (isset($max_updates)) { if (isset($max_questions)) {
$max_updates = max(0, (int)$max_updates); $max_questions = max(0, (int)$max_questions);
$sql_query2 .= ' MAX_UPDATES_PER_HOUR ' . $max_updates; $sql_query2 .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
} }
if (isset($max_user_connections)) { if (isset($max_connections)) {
$max_user_connections = max(0, (int)$max_user_connections); $max_connections = max(0, (int)$max_connections);
$sql_query2 .= ' MAX_USER_CONNECTIONS ' . $max_user_connections; $sql_query2 .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
}
if (isset($max_updates)) {
$max_updates = max(0, (int)$max_updates);
$sql_query2 .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
}
if (isset($max_user_connections)) {
$max_user_connections = max(0, (int)$max_user_connections);
$sql_query2 .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
}
} }
$sql_query2 .= ';';
} }
$sql_query2 .= ';'; if (! PMA_DBI_try_query($sql_query0)) {
if (!PMA_DBI_try_query($sql_query0)) {
// this query may fail, but this does not matter :o) // this query may fail, but this does not matter :o)
// a case when it can fail is when the admin does not have all
// privileges: he can't do a REVOKE ALL PRIVILEGES !
// so at least we display the error
echo PMA_DBI_getError();
$sql_query0 = ''; $sql_query0 = '';
} }
if (isset($sql_query1) && !PMA_DBI_try_query($sql_query1)) { if (isset($sql_query1) && !PMA_DBI_try_query($sql_query1)) {
// this one may fail, too... // this one may fail, too...
$sql_query1 = ''; $sql_query1 = '';
} }
PMA_DBI_query($sql_query2); if (isset($sql_query2)) {
PMA_DBI_query($sql_query2);
} else {
$sql_query2 = '';
}
$sql_query = $sql_query0 . ' ' . $sql_query1 . ' ' . $sql_query2; $sql_query = $sql_query0 . ' ' . $sql_query1 . ' ' . $sql_query2;
$message = PMA_Message::success('strUpdatePrivMessage'); $message = PMA_Message::success('strUpdatePrivMessage');
$message->addParam('\'' . $username . '\'@\'' . $hostname . '\''); $message->addParam('\'' . $username . '\'@\'' . $hostname . '\'');
@@ -1119,6 +1147,7 @@ if (!empty($update_privs)) {
* Revokes Privileges * Revokes Privileges
*/ */
if (isset($_REQUEST['revokeall'])) { if (isset($_REQUEST['revokeall'])) {
$db_and_table = PMA_WildcardEscapeForGrant($db_and_table, $dbname, isset($tablename) ? $tablename : '');
$sql_query0 = $sql_query0 =
'REVOKE ALL PRIVILEGES ON ' . $db_and_table 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
@@ -1126,8 +1155,9 @@ if (isset($_REQUEST['revokeall'])) {
$sql_query1 = $sql_query1 =
'REVOKE GRANT OPTION ON ' . $db_and_table 'REVOKE GRANT OPTION ON ' . $db_and_table
. ' FROM \'' . $username . '\'@\'' . $hostname . '\';'; . ' FROM \'' . $username . '\'@\'' . $hostname . '\';';
PMA_DBI_query($sql_query0); PMA_DBI_query($sql_query0);
if (!PMA_DBI_try_query($sql_query1)) { if (! PMA_DBI_try_query($sql_query1)) {
// this one may fail, too... // this one may fail, too...
$sql_query1 = ''; $sql_query1 = '';
} }