diff --git a/ANNOUNCE.txt b/ANNOUNCE.txt index 992e3da9b..66a3fdbef 100644 --- a/ANNOUNCE.txt +++ b/ANNOUNCE.txt @@ -23,7 +23,7 @@ Announcement the Web, and is now one of the most popular PHP script used worldwide: more than 3.1 million download in the past year! - SourceForge gave phpMyAdmin the "Project of the Month" award in + SourceForge gave phpMyAdmin the "Project of the Month" award in December: look at the article http://sourceforge.net/pom_1202.php to learn more about the project's history. @@ -145,10 +145,11 @@ Support and Documentation Known bugs ---------- - * Querying UNION SELECTs may result in php errors about undefined variables. - Furthermore, the total number of rows may be not calculated correctly, here. - * Some users reported problems on machines with Zend Accelerator (TM). + * The total number of rows of UNION SELECT is not calculated correctly. + * Some users reported problems on machines running Zend Accelerator (TM). * The MySQL 4.1.x and php 5.0.x branches are not yet supported by phpMyAdmin. + * Displaying large exports may crash Microsoft Internet Explorer. + * When renaming tables or fields the relations set in phpMyAdmin are lost. To be informed about new releases fixing these problems, please subscribe to the news mailing list under diff --git a/ChangeLog b/ChangeLog index acba90d8f..3ab2be784 100755 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,11 @@ phpMyAdmin - Changelog $Id$ $Source$ +2003-02-23 Alexander M. Turek + * server_privileges: Better code for "check privileges"; This should fix + bug #687808 and a few other problems. + * ANNOUNCE.txt: Updated list of known bugs. + 2003-02-22 Marc Delisle * lang/italian update, thanks to Pietro Danesi * lang/slovak update, thanks to Lubos Klokner diff --git a/server_privileges.php3 b/server_privileges.php3 index 431db3b8d..de3bf379c 100644 --- a/server_privileges.php3 +++ b/server_privileges.php3 @@ -1379,14 +1379,19 @@ if (empty($adduser) && empty($checkprivs)) { . ' ' . "\n" . ' ' . "\n"; $useBgcolorOne = TRUE; + unset($row); + unset($row1); + unset($row2); // now, we build the table... if (PMA_MYSQL_INT_VERSION >= 40000) { // Starting with MySQL 4.0.0, we may use UNION SELECTs and this makes // the job much easier here! $sql_query = '(SELECT `User`, `Host`, `Db`, `Select_priv`, `Insert_priv`, `Update_priv`, `Delete_priv`, `Create_priv`, `Drop_priv`, `Grant_priv`, `References_priv` FROM `db` WHERE "' . $checkprivs . '" LIKE `Db` AND NOT (`Select_priv` = "N" AND `Insert_priv` = "N" AND `Update_priv` = "N" AND `Delete_priv` = "N" AND `Create_priv` = "N" AND `Drop_priv` = "N" AND `Grant_priv` = "N" AND `References_priv` = "N")) UNION (SELECT `User`, `Host`, "*" AS "Db", `Select_priv`, `Insert_priv`, `Update_priv`, `Delete_priv`, `Create_priv`, `Drop_priv`, `Grant_priv`, `References_priv` FROM `user` WHERE NOT (`Select_priv` = "N" AND `Insert_priv` = "N" AND `Update_priv` = "N" AND `Delete_priv` = "N" AND `Create_priv` = "N" AND `Drop_priv` = "N" AND `Grant_priv` = "N" AND `References_priv` = "N")) ORDER BY `User` ASC, `Host` ASC, `Db` ASC;'; $res = PMA_mysql_query($sql_query, $userlink) or PMA_mysqlDie(PMA_mysql_error($userlink), $sql_query); - $row1 = PMA_mysql_fetch_array($res, MYSQL_ASSOC); - $row2 = PMA_mysql_fetch_array($res, MYSQL_ASSOC); + $row = PMA_mysql_fetch_array($res, MYSQL_ASSOC); + if ($row) { + $found = TRUE; + } } else { // With MySQL 3, we need 2 seperate queries here. $sql_query = 'SELECT * FROM `user` WHERE NOT (`Select_priv` = "N" AND `Insert_priv` = "N" AND `Update_priv` = "N" AND `Delete_priv` = "N" AND `Create_priv` = "N" AND `Drop_priv` = "N" ' . (PMA_MYSQL_INT_VERSION >= 32211 ? 'AND `Grant_priv` = "N" ' : '') . 'AND `References_priv` = "N") ORDER BY `User` ASC, `Host` ASC;'; @@ -1394,112 +1399,96 @@ if (empty($adduser) && empty($checkprivs)) { $row1 = PMA_mysql_fetch_array($res1, MYSQL_ASSOC); $sql_query = 'SELECT * FROM `db` WHERE "' . $checkprivs . '" LIKE `Db` AND NOT (`Select_priv` = "N" AND `Insert_priv` = "N" AND `Update_priv` = "N" AND `Delete_priv` = "N" AND `Create_priv` = "N" AND `Drop_priv` = "N" ' . (PMA_MYSQL_INT_VERSION >= 32211 ? 'AND `Grant_priv` = "N" ' : '') . 'AND `References_priv` = "N") ORDER BY `User` ASC, `Host` ASC;'; $res2 = PMA_mysql_query($sql_query, $userlink) or PMA_mysqlDie(PMA_mysql_error($userlink), $sql_query); - $row2 = PMA_mysql_fetch_array($res2, MYSQL_ASSOC); + $row2 = PMA_mysql_fetch_array($res1, MYSQL_ASSOC); + if ($row1 || $row2) { + $found = TRUE; + } } // end if (PMA_MYSQL_INT_VERSION >= 40000) ... else ... - while (!empty($row1) || !empty($row2)) { - echo ' ' . "\n"; - if (!empty($row1) && !empty($row2) && $row1['User'] == $row2['User'] && $row1['Host'] == $row2['Host']) { - $useRow1 = $useRow2 = TRUE; - echo ' ' . "\n" - . ' ' . (empty($row1['User']) ? '' . $strAny . '' : htmlspecialchars($row1['User'])) . "\n" - . ' ' . "\n" - . ' ' . "\n" - . ' ' . htmlspecialchars($row1['Host']) . "\n" - . ' ' . "\n"; - } else if (PMA_MYSQL_INT_VERSION >= 40000 || empty($row2) || $row1['User'] < $row2['User'] || ($row1['User'] == $row2['User'] && $row1['Host'] < $row2['Host'])) { - $useRow1 = TRUE; - $useRow2 = FALSE; - echo ' ' . "\n" - . ' ' . (empty($row1['User']) ? '' . $strAny . '' : htmlspecialchars($row1['User'])) . "\n" - . ' ' . "\n" - . ' ' . "\n" - . ' ' . htmlspecialchars($row1['Host']) . "\n" - . ' ' . "\n"; - } else { - $useRow1 = FALSE; - $useRow2 = TRUE; - echo ' ' . "\n" - . ' ' . (empty($row2['User']) ? '' . $strAny . '' : htmlspecialchars($row2['User'])) . "\n" - . ' ' . "\n" - . ' ' . "\n" - . ' ' . htmlspecialchars($row2['Host']) . "\n" - . ' ' . "\n"; - } - if ($useRow1) { - echo ' ' . "\n" - . ' '; - if (!isset($row1['Db']) || $row1['Db'] == '*') { - echo $strGlobal; - } else if ($row1['Db'] == $checkprivs) { - echo $strDbSpecific; + if ($found) { + while (TRUE) { + // prepare the current user + if (PMA_MYSQL_INT_VERSION >= 40000) { + $current_privileges = array(); + $current_user = $row['User']; + $current_host = $row['Host']; + while ($row && $current_user == $row['User'] && $current_host == $row['Host']) { + $current_privileges[] = $row; + $row = PMA_mysql_fetch_array($res, MYSQL_ASSOC); + } } else { - echo $strWildcard, ': ' . htmlspecialchars($row1['Db']) . ''; + $current_privileges = array(); + if ($row1 && (!$row2 || ($row1['User'] < $row2['User'] || ($row1['User'] == $row2['User'] && $row1['Host'] <= $row2['Host'])))) { + $current_user = $row1['User']; + $current_host = $row1['Host']; + $current_privileges = array($row1); + $row1 = PMA_mysql_fetch_array($res1, MYSQL_ASSOC); + } else { + $current_user = $row2['User']; + $current_host = $row2['Host']; + $current_privileges = array(); + } + while ($row2 && $current_user == $row2['User'] && $current_host == $row2['Host']) { + $current_privileges[] = $row2; + $row2 = PMA_mysql_fetch_array($res2, MYSQL_ASSOC); + } } - echo "\n" + echo ' ' . "\n" + . ' 1) { + echo ' rowspan="' . count($current_privileges) . '"'; + } + echo ' bgcolor="' . ($useBgcolorOne ? $cfg['BgcolorOne'] : $cfg['BgcolorTwo']) . '">' . "\n" + . ' ' . (empty($current_user) ? '' . $strAny . '' : htmlspecialchars($current_user)) . "\n" . ' ' . "\n" - . ' ' . "\n" - . ' ' . "\n" - . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($row1, TRUE)) . "\n" - . ' ' . "\n" + . ' 1) { + echo ' rowspan="' . count($current_privileges) . '"'; + } + echo ' bgcolor="' . ($useBgcolorOne ? $cfg['BgcolorOne'] : $cfg['BgcolorTwo']) . '">' . "\n" + . ' ' . htmlspecialchars($current_host) . "\n" . ' ' . "\n"; - if (PMA_MYSQL_INT_VERSION >= 32211) { + while (list(, $current) = each($current_privileges)) { echo ' ' . "\n" - . ' ' . ($row1['Grant_priv'] == 'Y' ? $strYes : $strNo) . "\n" + . ' '; + if (!isset($current['Db']) || $current['Db'] == '*') { + echo $strGlobal; + } else if ($current['Db'] == $checkprivs) { + echo $strDbSpecific; + } else { + echo $strWildcard, ': ' . htmlspecialchars($current['Db']) . ''; + } + echo "\n" + . ' ' . "\n" + . ' ' . "\n" + . ' ' . "\n" + . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($current, TRUE)) . "\n" + . ' ' . "\n" . ' ' . "\n"; - } - echo ' ' . "\n" - . ' ' . "\n" - . ' ' . $strEdit . "\n" - . ' ' . "\n" - . ' ' . "\n" - . ' ' . "\n"; - if (PMA_MYSQL_INT_VERSION < 40000) { - $row1 = PMA_mysql_fetch_array($res1, MYSQL_ASSOC); - } - } - if ($useRow2) { - if ($useRow1) { - echo ' ' . "\n"; - } - echo ' ' . "\n" - . ' '; - if (!isset($row2['Db']) || $row2['Db'] == '*') { - echo $strGlobal; - } else if ($row2['Db'] == $checkprivs) { - echo $strDbSpecific; - } else { - echo $strWildcard, ': ' . htmlspecialchars($row2['Db']) . ''; - } - echo "\n" - . ' ' . "\n" - . ' ' . "\n" - . ' ' . "\n" - . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($row2, TRUE)) . "\n" - . ' ' . "\n" - . ' ' . "\n"; - if (PMA_MYSQL_INT_VERSION >= 32211) { + if (PMA_MYSQL_INT_VERSION >= 32211) { + echo ' ' . "\n" + . ' ' . ($current['Grant_priv'] == 'Y' ? $strYes : $strNo) . "\n" + . ' ' . "\n"; + } echo ' ' . "\n" - . ' ' . ($row2['Grant_priv'] == 'Y' ? $strYes : $strNo) . "\n" - . ' ' . "\n"; + . ' ' . "\n" + . ' ' . $strEdit . "\n" + . ' ' . "\n" + . ' ' . "\n" + . ' ' . "\n"; } - echo ' ' . "\n" - . ' ' . "\n" - . ' ' . $strEdit . "\n" - . ' ' . "\n" - . ' ' . "\n" - . ' ' . "\n"; - if (PMA_MYSQL_INT_VERSION < 40000) { - $row2 = PMA_mysql_fetch_array($res2, MYSQL_ASSOC); - } else { - $row1 = PMA_mysql_fetch_array($res, MYSQL_ASSOC); - $row2 = PMA_mysql_fetch_array($res, MYSQL_ASSOC); + if (empty($row) && empty($row1) && empty($row2)) { + break; } - } else if (PMA_MYSQL_INT_VERSION >= 40000) { - $row1 = $row2; - $row2 = PMA_mysql_fetch_array($res, MYSQL_ASSOC); + $useBgcolorOne = !$useBgcolorOne; } - $useBgcolorOne = !$useBgcolorOne; + } else { + echo ' ' . "\n" + . ' ' . "\n" + . ' ' . $strNoUsersFound . "\n" + . ' ' . "\n" + . ' ' . "\n"; } + echo '' . "\n"; } // end if (empty($adduser) && empty($checkprivs)) ... else if ... else ...