Skip to content

Commit

Permalink
Fix bug #17216 (multi-assignment of privileges)
Browse files Browse the repository at this point in the history
Signed-off-by: Kamil Tekiela <tekiela246@gmail.com>
  • Loading branch information
kamil-tekiela committed Dec 1, 2021
1 parent 2c125f0 commit f4493bb
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 143 deletions.
111 changes: 42 additions & 69 deletions libraries/classes/Server/Privileges.php
Expand Up @@ -21,6 +21,8 @@
use PhpMyAdmin\Util;

use function __;
use function array_filter;
use function array_keys;
use function array_map;
use function array_merge;
use function array_unique;
Expand All @@ -30,7 +32,6 @@
use function implode;
use function in_array;
use function is_array;
use function is_scalar;
use function is_string;
use function json_decode;
use function ksort;
Expand Down Expand Up @@ -2770,6 +2771,7 @@ public function setProperPasswordHashing($authPlugin): void
* Update DB information: DB, Table, isWildcard
*
* @return array
* @psalm-return array{?string, ?string, array|string|null, ?string, ?string, array|string, bool}
*/
public function getDataForDBInfo()
{
Expand All @@ -2778,7 +2780,6 @@ public function getDataForDBInfo()
$dbname = null;
$tablename = null;
$routinename = null;
$returnDb = null;

if (isset($_REQUEST['username'])) {
$username = (string) $_REQUEST['username'];
Expand All @@ -2793,115 +2794,87 @@ public function getDataForDBInfo()
*/
if (
isset($_POST['pred_tablename'])
&& is_scalar($_POST['pred_tablename'])
&& strlen((string) $_POST['pred_tablename']) > 0
&& is_string($_POST['pred_tablename'])
&& $_POST['pred_tablename'] !== ''
) {
$tablename = (string) $_POST['pred_tablename'];
$tablename = $_POST['pred_tablename'];
} elseif (
isset($_REQUEST['tablename'])
&& is_scalar($_REQUEST['tablename'])
&& strlen((string) $_REQUEST['tablename']) > 0
&& is_string($_REQUEST['tablename'])
&& $_REQUEST['tablename'] !== ''
) {
$tablename = (string) $_REQUEST['tablename'];
} else {
unset($tablename);
$tablename = $_REQUEST['tablename'];
}

if (
isset($_POST['pred_routinename'])
&& is_scalar($_POST['pred_routinename'])
&& strlen((string) $_POST['pred_routinename']) > 0
&& is_string($_POST['pred_routinename'])
&& $_POST['pred_routinename'] !== ''
) {
$routinename = (string) $_POST['pred_routinename'];
$routinename = $_POST['pred_routinename'];
} elseif (
isset($_REQUEST['routinename'])
&& is_scalar($_REQUEST['routinename'])
&& strlen((string) $_REQUEST['routinename']) > 0
&& is_string($_REQUEST['routinename'])
&& $_REQUEST['routinename'] !== ''
) {
$routinename = (string) $_REQUEST['routinename'];
} else {
unset($routinename);
$routinename = $_REQUEST['routinename'];
}

if (isset($_POST['pred_dbname'])) {
$isValidPredDbname = true;
foreach ($_POST['pred_dbname'] as $key => $dbName) {
if (! isset($dbName) || ! is_scalar($dbName) || strlen((string) $dbName) === 0) {
$isValidPredDbname = false;
break;
if (isset($_POST['pred_dbname']) && is_array($_POST['pred_dbname'])) {
// Accept only array of non-empty strings
if ($_POST['pred_dbname'] === array_filter($_POST['pred_dbname'])) {
$dbname = $_POST['pred_dbname'];
// If dbname contains only one database.
if (count($dbname) === 1) {
$dbname = (string) $dbname[0];
}
}
}

if (isset($_REQUEST['dbname'])) {
$isValidDbname = true;
if ($dbname === null && isset($_REQUEST['dbname'])) {
if (is_array($_REQUEST['dbname'])) {
foreach ($_REQUEST['dbname'] as $key => $dbName) {
if (! isset($dbName) || ! is_scalar($dbName) || strlen((string) $dbName) === 0) {
$isValidDbname = false;
break;
}
}
} else {
if (
! isset($_REQUEST['dbname'])
|| ! is_scalar($_REQUEST['dbname'])
|| strlen((string) $_REQUEST['dbname']) === 0
) {
$isValidDbname = false;
// Accept only array of non-empty strings
if ($_REQUEST['dbname'] === array_filter($_REQUEST['dbname'])) {
$dbname = $_REQUEST['dbname'];
}
} elseif (
is_string($_REQUEST['dbname'])
&& $_REQUEST['dbname'] !== ''
) {
$dbname = $_REQUEST['dbname'];
}
}

if (isset($isValidPredDbname) && $isValidPredDbname) {
$dbname = $_POST['pred_dbname'];
// If dbname contains only one database.
if (count($dbname) === 1) {
$dbname = $dbname[0];
}
} elseif (isset($isValidDbname) && $isValidDbname) {
$dbname = (string) $_REQUEST['dbname'];
$dbAndTable = '*.*';
if ($dbname === null) {
$tablename = null;
} else {
unset($dbname, $tablename);
}

if (isset($dbname)) {
if (is_array($dbname)) {
$dbAndTable = $dbname;
$returnDb = $dbname;
foreach ($dbAndTable as $key => $dbName) {
$dbAndTable[$key] .= '.';
foreach (array_keys($dbAndTable) as $key) {
$dbAndTable[$key] .= '.*';
}
} else {
$unescapedDb = Util::unescapeMysqlWildcards($dbname);
$dbAndTable = Util::backquote($unescapedDb) . '.';
$returnDb = $dbname;
}

if (isset($tablename) && ! is_array($dbAndTable)) {
$dbAndTable .= Util::backquote($tablename);
} else {
if (is_array($dbAndTable)) {
foreach ($dbAndTable as $key => $dbName) {
$dbAndTable[$key] .= '*';
}
if ($tablename !== null) {
$dbAndTable .= Util::backquote($tablename);
} else {
$dbAndTable .= '*';
}
}
} else {
$dbAndTable = '*.*';
}

// check if given $dbname is a wildcard or not
$databaseNameIsWildcard = ! is_array($dbname ?? '') && preg_match('/(?<!\\\\)(?:_|%)/', $dbname ?? '');
$databaseNameIsWildcard = is_string($dbname) && preg_match('/(?<!\\\\)(?:_|%)/', $dbname);

return [
$username,
$hostname,
$returnDb,
$tablename ?? null,
$routinename ?? null,
$dbname,
$tablename,
$routinename,
$dbAndTable,
$databaseNameIsWildcard,
];
Expand Down

0 comments on commit f4493bb

Please sign in to comment.