Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/pull/12544' into QA_4_6
Browse files Browse the repository at this point in the history
  • Loading branch information
nijel committed Sep 19, 2016
2 parents 337e575 + 815bf44 commit bccd690
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 33 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Expand Up @@ -36,6 +36,7 @@ phpMyAdmin - ChangeLog
- issue #12272 Adding a new row with default enum goes to no selection when you want to add more then 2 rows
- issue #12487 Drag and drop import prevents file dropping to blob column file selector on the insert tab
- issue #12554 Absence of scrolling makes it impossible to read longer text values in grid editing
- issue #12530 "Edit routine" crashes when the current user is not the definer, even if privileges are adequate

4.6.4 (2016-08-16)
- issue [security] Weaknesses with cookie encryption, see PMASA-2016-29
Expand Down
2 changes: 2 additions & 0 deletions js/messages.php
Expand Up @@ -385,6 +385,8 @@ function () {
$js_messages['MissingReturn']
= __('The definition of a stored function must contain a RETURN statement!');
$js_messages['strExport'] = __('Export');
$js_messages['NoExportable']
= __('No routine is exportable. Required privileges may be lacking.');

/* For ENUM/SET editor*/
$js_messages['enum_editor'] = __('ENUM/SET editor');
Expand Down
6 changes: 6 additions & 0 deletions js/rte.js
Expand Up @@ -128,6 +128,11 @@ RTE.COMMON = {
var count = export_anchors.length;
var returnCount = 0;

// No routine is exportable (due to privilege issues)
if (count === 0) {
PMA_ajaxShowMessage(PMA_messages.NoExportable);
}

export_anchors.each(function () {
$.get($(this).attr('href'), {'ajax_request': true}, function (data) {
returnCount++;
Expand All @@ -149,6 +154,7 @@ RTE.COMMON = {
} else {
$.get($this.attr('href'), {'ajax_request': true}, showExport);
}
PMA_ajaxRemoveMessage($msg);

function showExport(data) {
if (data.success === true) {
Expand Down
5 changes: 3 additions & 2 deletions libraries/DatabaseInterface.php
Expand Up @@ -1824,10 +1824,11 @@ public function getProceduresOrFunctions($db, $which, $link = null)
* @param string $db db name
* @param string $which PROCEDURE | FUNCTION | EVENT | VIEW
* @param string $name the procedure|function|event|view name
* @param object $link MySQL link
*
* @return string the definition
*/
public function getDefinition($db, $which, $name)
public function getDefinition($db, $which, $name, $link = null)
{
$returned_field = array(
'PROCEDURE' => 'Create Procedure',
Expand All @@ -1838,7 +1839,7 @@ public function getDefinition($db, $which, $name)
$query = 'SHOW CREATE ' . $which . ' '
. Util::backquote($db) . '.'
. Util::backquote($name);
return($this->fetchValue($query, 0, $returned_field[$which]));
return($this->fetchValue($query, 0, $returned_field[$which], $link));
}

/**
Expand Down
25 changes: 18 additions & 7 deletions libraries/rte/rte_export.lib.php
Expand Up @@ -44,15 +44,16 @@ function PMA_RTE_handleExport($export_data)
} else {
$_db = htmlspecialchars(PMA\libraries\Util::backquote($db));
$message = __('Error in processing request:') . ' '
. sprintf(PMA_RTE_getWord('not_found'), $item_name, $_db);
$response = Message::error($message);
. sprintf(PMA_RTE_getWord('no_view'), $item_name, $_db);
$message = Message::error($message);

if ($GLOBALS['is_ajax_request'] == true) {
$response = PMA\libraries\Response::getInstance();
$response->setRequestStatus(false);
$response->addJSON('message', $message);
exit;
} else {
$response->display();
$message->display();
}
}
} // end PMA_RTE_handleExport()
Expand All @@ -70,6 +71,9 @@ function PMA_EVN_handleExport()
if (! empty($_GET['export_item']) && ! empty($_GET['item_name'])) {
$item_name = $_GET['item_name'];
$export_data = $GLOBALS['dbi']->getDefinition($db, 'EVENT', $item_name);
if (! $export_data) {
$export_data = false;
}
PMA_RTE_handleExport($export_data);
}
} // end PMA_EVN_handleExport()
Expand All @@ -89,13 +93,20 @@ function PMA_RTN_handleExport()
&& ! empty($_GET['item_type'])
) {
if ($_GET['item_type'] == 'FUNCTION' || $_GET['item_type'] == 'PROCEDURE') {
$export_data = "DELIMITER $$\n"
. $GLOBALS['dbi']->getDefinition(
$rtn_definition
= $GLOBALS['dbi']->getDefinition(
$db,
$_GET['item_type'],
$_GET['item_name']
)
. "$$\nDELIMITER ;\n";
);
if (! $rtn_definition) {
$export_data = false;
} else {
$export_data = "DELIMITER $$\n"
. $rtn_definition
. "$$\nDELIMITER ;\n";
}

PMA_RTE_handleExport($export_data);
}
}
Expand Down
42 changes: 32 additions & 10 deletions libraries/rte/rte_list.lib.php
Expand Up @@ -196,9 +196,24 @@ function PMA_RTN_getRowForList($routine, $rowclass = '')
$retval .= " </strong>\n";
$retval .= " </td>\n";
$retval .= " <td>\n";

// this is for our purpose to decide whether to
// show the edit link or not, so we need the DEFINER for the routine
$where = "ROUTINE_SCHEMA " . PMA\libraries\Util::getCollateForIS() . "="
. "'" . PMA\libraries\Util::sqlAddSlashes($db) . "' "
. "AND SPECIFIC_NAME='" . PMA\libraries\Util::sqlAddSlashes($routine['name']) . "'"
. "AND ROUTINE_TYPE='" . PMA\libraries\Util::sqlAddSlashes($routine['type']) . "'";
$query = "SELECT `DEFINER` FROM INFORMATION_SCHEMA.ROUTINES WHERE $where;";
$routine_definer = $GLOBALS['dbi']->fetchValue($query, 0, 0, $GLOBALS['controllink']);

$curr_user = $GLOBALS['dbi']->getCurrentUser();

// Since editing a procedure involved dropping and recreating, check also for
// CREATE ROUTINE privilege to avoid lost procedures.
if (PMA\libraries\Util::currentUserHasPrivilege('CREATE ROUTINE', $db)) {
if ((PMA\libraries\Util::currentUserHasPrivilege('CREATE ROUTINE', $db)
&& $curr_user == $routine_definer)
|| $GLOBALS['is_superuser']
) {
$retval .= ' <a ' . $ajax_class['edit']
. ' href="db_routines.php'
. $url_query
Expand All @@ -225,7 +240,7 @@ function PMA_RTN_getRowForList($routine, $rowclass = '')
// otherwise we can execute it directly.

$definition = $GLOBALS['dbi']->getDefinition(
$db, $routine['type'], $routine['name']
$db, $routine['type'], $routine['name'], $GLOBALS['controllink']
);
if ($definition !== false) {
$parser = new SqlParser\Parser($definition);
Expand Down Expand Up @@ -263,14 +278,21 @@ function PMA_RTN_getRowForList($routine, $rowclass = '')

$retval .= " </td>\n";
$retval .= " <td>\n";
$retval .= ' <a ' . $ajax_class['export']
. ' href="db_routines.php'
. $url_query
. '&amp;export_item=1'
. '&amp;item_name='
. urlencode($routine['name'])
. '&amp;' . $type_link
. '">' . $titles['Export'] . "</a>\n";
if ((PMA\libraries\Util::currentUserHasPrivilege('CREATE ROUTINE', $db)
&& $curr_user == $routine_definer)
|| $GLOBALS['is_superuser']
) {
$retval .= ' <a ' . $ajax_class['export']
. ' href="db_routines.php'
. $url_query
. '&amp;export_item=1'
. '&amp;item_name='
. urlencode($routine['name'])
. '&amp;' . $type_link
. '">' . $titles['Export'] . "</a>\n";
} else {
$retval .= " {$titles['NoExport']}\n";
}
$retval .= " </td>\n";
$retval .= " <td>\n";
$retval .= ' <a ' . $ajax_class['drop']
Expand Down
42 changes: 28 additions & 14 deletions libraries/rte/rte_routines.lib.php
Expand Up @@ -155,12 +155,13 @@ function PMA_RTN_handleEditor()
} else {
$message = __('Error in processing request:') . ' ';
$message .= sprintf(
PMA_RTE_getWord('not_found'),
PMA_RTE_getWord('no_edit'),
htmlspecialchars(
PMA\libraries\Util::backquote($_REQUEST['item_name'])
),
htmlspecialchars(PMA\libraries\Util::backquote($db))
);

$message = Message::error($message);
if ($GLOBALS['is_ajax_request']) {
$response = PMA\libraries\Response::getInstance();
Expand Down Expand Up @@ -562,16 +563,23 @@ function PMA_RTN_getDataFromRequest()
* This function will generate the values that are required to complete
* the "Edit routine" form given the name of a routine.
*
* @param string $name The name of the routine.
* @param string $type Type of routine (ROUTINE|PROCEDURE)
* @param bool $all Whether to return all data or just
* the info about parameters.
* @param string $name The name of the routine.
* @param string $type Type of routine (ROUTINE|PROCEDURE)
* @param bool $all Whether to return all data or just
* the info about parameters.
* @param bool $control Where to use Controllink to query for
* routine information
*
* @return array Data necessary to create the routine editor.
*/
function PMA_RTN_getDataFromName($name, $type, $all = true)
function PMA_RTN_getDataFromName($name, $type, $all = true, $control = false)
{
global $db;
$link = null;

if ($control) {
$link = $GLOBALS['controllink'];
}

$retval = array();

Expand All @@ -585,7 +593,7 @@ function PMA_RTN_getDataFromName($name, $type, $all = true)
. "AND ROUTINE_TYPE='" . PMA\libraries\Util::sqlAddSlashes($type) . "'";
$query = "SELECT $fields FROM INFORMATION_SCHEMA.ROUTINES WHERE $where;";

$routine = $GLOBALS['dbi']->fetchSingleRow($query);
$routine = $GLOBALS['dbi']->fetchSingleRow($query, 'ASSOC', $link);

if (! $routine) {
return false;
Expand All @@ -595,13 +603,19 @@ function PMA_RTN_getDataFromName($name, $type, $all = true)
$retval['item_name'] = $routine['SPECIFIC_NAME'];
$retval['item_type'] = $routine['ROUTINE_TYPE'];

$parser = new SqlParser\Parser(
$GLOBALS['dbi']->getDefinition(
$definition
= $GLOBALS['dbi']->getDefinition(
$db,
$routine['ROUTINE_TYPE'],
$routine['SPECIFIC_NAME']
)
);
$routine['SPECIFIC_NAME'],
$link
);

if ($definition == NULL) {
return false;
}

$parser = new SqlParser\Parser($definition);

/**
* @var CreateStatement $stmt
Expand Down Expand Up @@ -1283,7 +1297,7 @@ function PMA_RTN_handleExecute()
if (! empty($_REQUEST['execute_routine']) && ! empty($_REQUEST['item_name'])) {
// Build the queries
$routine = PMA_RTN_getDataFromName(
$_REQUEST['item_name'], $_REQUEST['item_type'], false
$_REQUEST['item_name'], $_REQUEST['item_type'], false, true
);
if ($routine === false) {
$message = __('Error in processing request:') . ' ';
Expand Down Expand Up @@ -1481,7 +1495,7 @@ function PMA_RTN_handleExecute()
* Display the execute form for a routine.
*/
$routine = PMA_RTN_getDataFromName(
$_GET['item_name'], $_GET['item_type'], true
$_GET['item_name'], $_GET['item_type'], true, true
);
if ($routine !== false) {
$form = PMA_RTN_getExecuteForm($routine);
Expand Down
8 changes: 8 additions & 0 deletions libraries/rte/rte_words.lib.php
Expand Up @@ -31,6 +31,14 @@ function PMA_RTE_getWord($index)
'no_create' => __(
'You do not have the necessary privileges to create a routine'
),
'no_edit' => __(
'No routine with name %1$s found in database %2$s. '
. 'You might be lacking the necessary privileges to edit this routine'
),
'no_view' => __(
'No routine with name %1$s found in database %2$s. '
. 'You might be lacking the necessary privileges to view/export this routine'
),
'not_found' => __('No routine with name %1$s found in database %2$s'),
'nothing' => __('There are no routines to display.'),
'title' => __('Routines'),
Expand Down

0 comments on commit bccd690

Please sign in to comment.