Trial Approach to solve Privileges bug for RFE#657

Signed-off-by: Deven Bansod <devenbansod.bits@gmail.com>
This commit is contained in:
Deven Bansod 2015-06-30 23:23:27 +05:30
parent 16c833a816
commit d014dbcc29
13 changed files with 367 additions and 27 deletions

View File

@ -21,6 +21,7 @@ require_once 'libraries/mysql_charsets.inc.php';
/**
* functions implementation for this script
*/
require_once 'libraries/check_user_privileges.lib.php';
require_once 'libraries/operations.lib.php';
// add a javascript file for jQuery functions to handle Ajax actions

View File

@ -16,6 +16,7 @@ require_once 'libraries/mysql_charsets.inc.php';
/**
* Include all other files
*/
require_once 'libraries/check_user_privileges.lib.php';
require_once 'libraries/rte/rte_routines.lib.php';
/**

View File

@ -2065,6 +2065,13 @@ Notes:
*column-related privileges* for the columns inside the table are also adjusted
to the table's new name.
* While adjusting privileges, the user performing the operation **must** have the following
privileges:
* SELECT, INSERT, UPDATE, DELETE privileges on following tables:
`mysql`.`db`, `mysql`.`columns_priv`, `mysql`.`tables_priv`, `mysql`.`procs_priv`
* FLUSH privilege (GLOBAL)
Thus, if you want to replicate the database/table/column/procedure as it is
while renaming/copying/moving these objects, make sure you have checked this option.

View File

@ -14,6 +14,208 @@ if (! defined('PHPMYADMIN')) {
*/
$GLOBALS['is_superuser'] = $GLOBALS['dbi']->isSuperuser();
/**
* Check if user has required privileges for
* performing 'FLUSH PRIVILEGES' operation
*
* @return void
*/
function PMA_checkRequiredPrivilegesForFlushing()
{
$res = $GLOBALS['dbi']->tryQuery(
'FLUSH PRIVILEGES'
);
// Save the value
$GLOBALS['flush_priv'] = $res;
}
/**
* Check if user has required privileges for
* performing 'Adjust Privileges' operations
*
* @return void
*/
function PMA_checkRequiredPrivilgesForAdjust()
{
$privs_available = true;
// FOR DB PRIVS
$select_privs_available = $GLOBALS['dbi']->tryQuery(
'SELECT * FROM `mysql`.`db` LIMIT 1'
);
$privs_available = $select_privs_available && $privs_available;
if ($privs_available) {
$delete_privs_available = $GLOBALS['dbi']->tryQuery(
'DELETE FROM `mysql`.`db` WHERE `host` = "" AND '
. '`Db` = "" AND `User` = "" LIMIT 1;'
);
$privs_available = $delete_privs_available && $privs_available;
}
if ($privs_available) {
$insert_privs_available = $GLOBALS['dbi']->tryQuery(
'INSERT INTO `mysql`.`db`(`host`, `Db`, `User`) VALUES("pma_test_host", '
. '"mysql", "pma_test_user");'
);
// If successful test insert, delete the test row
if ($insert_privs_available) {
$GLOBALS['dbi']->tryQuery(
'DELETE FROM `mysql`.`db` WHERE host = "pma_test_host" AND '
. 'Db = "mysql" AND User = "pma_test_user" LIMIT 1;'
);
}
$privs_available = $insert_privs_available && $privs_available;
}
if ($privs_available) {
$update_privs_available = $GLOBALS['dbi']->tryQuery(
'UPDATE `mysql`.`db` SET `host` = "" WHERE `host` = "" AND '
. '`Db` = "" AND `User` = "" LIMIT 1;'
);
$privs_available = $update_privs_available && $privs_available;
}
// save the value
$GLOBALS['db_priv'] = $privs_available;
// reset the value
$privs_available = true;
// FOR COLUMNS_PRIV
$select_privs_available = $GLOBALS['dbi']->tryQuery(
'SELECT * FROM `mysql`.`columns_priv` LIMIT 1'
);
$privs_available = $select_privs_available && $privs_available;
if ($privs_available) {
$delete_privs_available = $GLOBALS['dbi']->tryQuery(
'DELETE FROM `mysql`.`columns_priv` WHERE `host` = "" AND '
. '`Db` = "" AND `User` = "" LIMIT 1;'
);
$privs_available = $delete_privs_available && $privs_available;
}
if ($privs_available) {
$insert_privs_available = $GLOBALS['dbi']->tryQuery(
'INSERT INTO `mysql`.`columns_priv`(`host`, `Db`, `User`, `Table_name`,'
. ' `Column_name`) VALUES("pma_test_host", '
. '"mysql", "pma_test_user", "", "")'
);
// If successful test insert, delete the test row
if ($insert_privs_available) {
$GLOBALS['dbi']->tryQuery(
'DELETE FROM `mysql`.`columns_priv` WHERE host = "pma_test_host" AND '
. 'Db = "mysql" AND User = "pma_test_user" AND Table_name = ""'
. ' AND Column_name = "" LIMIT 1;'
);
}
$privs_available = $insert_privs_available && $privs_available;
}
if ($privs_available) {
$update_privs_available = $GLOBALS['dbi']->tryQuery(
'UPDATE `mysql`.`columns_priv` SET `host` = "" WHERE `host` = "" AND '
. '`Db` = "" AND `User` = "" AND Column_name = "" AND Table_name = "" LIMIT 1;'
);
$privs_available = $update_privs_available && $privs_available;
}
// Save the value
$GLOBALS['col_priv'] = $privs_available;
// Reset the value
$privs_available = true;
// FOR TABLES_PRIV
$select_privs_available = $GLOBALS['dbi']->tryQuery(
'SELECT * FROM `mysql`.`tables_priv` LIMIT 1'
);
$privs_available = $select_privs_available && $privs_available;
if ($privs_available) {
$delete_privs_available = $GLOBALS['dbi']->tryQuery(
'DELETE FROM `mysql`.`tables_priv` WHERE `host` = "" AND '
. '`Db` = "" AND `User` = "" AND Table_name = "" LIMIT 1;'
);
$privs_available = $delete_privs_available && $privs_available;
}
if ($privs_available) {
$insert_privs_available = $GLOBALS['dbi']->tryQuery(
'INSERT INTO `mysql`.`tables_priv`(`host`, `Db`, `User`, `Table_name`'
. ') VALUES("pma_test_host", '
. '"mysql", "pma_test_user", "")'
);
// If successful test insert, delete the test row
if ($insert_privs_available) {
$GLOBALS['dbi']->tryQuery(
'DELETE FROM `mysql`.`tables_priv` WHERE host = "pma_test_host" AND '
. 'Db = "mysql" AND User = "pma_test_user" AND Table_name = "" LIMIT 1;'
);
}
$privs_available = $insert_privs_available && $privs_available;
}
if ($privs_available) {
$update_privs_available = $GLOBALS['dbi']->tryQuery(
'UPDATE `mysql`.`tables_priv` SET `host` = "" WHERE `host` = "" AND '
. '`Db` = "" AND `User` = "" AND Table_name = "" LIMIT 1;'
);
$privs_available = $update_privs_available && $privs_available;
}
// Save the value
$GLOBALS['table_priv'] = $privs_available;
// Reset the value
$privs_available = true;
// FOR PROCS_PRIV
$select_privs_available = $GLOBALS['dbi']->tryQuery(
'SELECT * FROM `mysql`.`procs_priv` LIMIT 1'
);
$privs_available = $select_privs_available && $privs_available;
if ($privs_available) {
$delete_privs_available = $GLOBALS['dbi']->tryQuery(
'DELETE FROM `mysql`.`procs_priv` WHERE `host` = "" AND '
. '`Db` = "" AND `User` = "" AND `Routine_name` = ""'
. ' AND `Routine_type` = "" LIMIT 1;'
);
$privs_available = $delete_privs_available && $privs_available;
}
if ($privs_available) {
$insert_privs_available = $GLOBALS['dbi']->tryQuery(
'INSERT INTO `mysql`.`procs_priv`(`host`, `Db`, `User`, `Routine_name`,'
. ' `Routine_type`) VALUES("pma_test_host", '
. '"mysql", "pma_test_user", "", "PROCEDURE")'
);
// If successful test insert, delete the test row
if ($insert_privs_available) {
$GLOBALS['dbi']->tryQuery(
'DELETE FROM `mysql`.`procs_priv` WHERE `host` = "pma_test_host" AND '
. '`Db` = "mysql" AND `User` = "pma_test_user" AND `Routine_name` = ""'
. ' AND `Routine_type` = "PROCEDURE" LIMIT 1;'
);
}
$privs_available = $insert_privs_available && $privs_available;
}
if ($privs_available) {
$update_privs_available = $GLOBALS['dbi']->tryQuery(
'UPDATE `mysql`.`procs_priv` SET `host` = "" WHERE `host` = "" AND '
. '`Db` = "" AND `User` = "" AND `Routine_name` = "" LIMIT 1;'
);
$privs_available = $update_privs_available && $privs_available;
}
// Save the value
$GLOBALS['proc_priv'] = $privs_available;
}
/**
* sets privilege information extracted from SHOW GRANTS result
*
@ -185,6 +387,13 @@ if (!PMA_DRIZZLE) {
} else {
PMA_analyseShowGrant();
}
// Check if privileges to 'mysql'.col_privs, 'mysql'.db,
// 'mysql'.table_privs, 'mysql'.proc_privs and privileges for
// flushing the privileges are available
PMA_checkRequiredPrivilegesForFlushing();
PMA_checkRequiredPrivilgesForAdjust();
} else {
// todo: for simple_user_policy only database with user's login can be created
// (unless logged in as root)

View File

@ -559,6 +559,26 @@ $GLOBALS['dummy_queries'] = array(
array(
'query' => "SHOW EVENTS FROM `default`",
'result' => array()
),
array(
'query' => "FLUSH PRIVILEGES",
'result' => array()
),
array(
'query' => "SELECT * FROM `mysql`.`db` LIMIT 1",
'result' => array()
),
array(
'query' => "SELECT * FROM `mysql`.`columns_priv` LIMIT 1",
'result' => array()
),
array(
'query' => "SELECT * FROM `mysql`.`tables_priv` LIMIT 1",
'result' => array()
),
array(
'query' => "SELECT * FROM `mysql`.`procs_priv` LIMIT 1",
'result' => array()
)
);
/**

View File

@ -77,11 +77,26 @@ function PMA_getHtmlForRenameDatabase($db)
$html_output .= '<input id="new_db_name" type="text" name="newname" '
. 'maxlength="64" size="30" class="textfield" value="" '
. 'required="required" />';
$html_output .= '<input type="checkbox" name="adjust_privileges" value="1"'
. 'id="checkbox_adjust_privileges" checked="checked" />';
if (isset($GLOBALS['db_priv']) && $GLOBALS['db_priv']
&& isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv']
) {
$html_output .= '<input type="checkbox" name="adjust_privileges" value="1"'
. 'id="checkbox_adjust_privileges" checked="checked" />';
} else {
$html_output .= '<input type="checkbox" name="adjust_privileges" value="1"'
. 'id="checkbox_adjust_privileges" '
. 'title="' . __(
'You don\'t have sufficient privileges to perform this '
. 'operation; Please refer to the documentation for more details'
)
. '" disabled/>';
}
$html_output .= '<label for="checkbox_adjust_privileges">'
. __('Adjust Privileges') . PMA_Util::showDocu('faq', 'faq6-39')
. '</label><br />';
. __('Adjust Privileges') . PMA_Util::showDocu('faq', 'faq6-39')
. '</label><br />';
$html_output .= ''
. '</fieldset>'
. '<fieldset class="tblFooters">'
@ -205,11 +220,25 @@ function PMA_getHtmlForCopyDatabase($db)
$html_output .= '<label for="checkbox_constraints">'
. __('Add constraints') . '</label><br />';
$html_output .= '<br />';
$html_output .= '<input type="checkbox" name="adjust_privileges" value="1"'
. 'id="checkbox_privileges" checked="checked" />';
if (isset($GLOBALS['db_priv']) && $GLOBALS['db_priv']
&& isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv']
) {
$html_output .= '<input type="checkbox" name="adjust_privileges" value="1"'
. 'id="checkbox_privileges" checked="checked" />';
} else {
$html_output .= '<input type="checkbox" name="adjust_privileges" value="1"'
. 'id="checkbox_privileges"'
. 'title="' . __(
'You don\'t have sufficient privileges to perform this '
. 'operation; Please refer to the documentation for more details'
)
. '" disabled/>';
}
$html_output .= '<label for="checkbox_privileges">'
. __('Adjust Privileges') . PMA_Util::showDocu('faq', 'faq6-39')
. '</label><br />';
$html_output .= '<input type="checkbox" name="switch_to_new" value="true"'
. 'id="checkbox_switch"'
. ((isset($pma_switch_to_new) && $pma_switch_to_new == 'true')
@ -789,10 +818,24 @@ function PMA_getHtmlForMoveTable()
. 'value="1" id="checkbox_auto_increment_mv" checked="checked" />'
. '<label for="checkbox_auto_increment_mv">'
. __('Add AUTO_INCREMENT value')
. '</label><br />'
. '<input type="checkbox" name="adjust_privileges" value="1" '
. 'id="checkbox_privileges_tables_move" checked="checked" />'
. '<label for="checkbox_privileges_tables_move">'
. '</label><br />';
if (isset($GLOBALS['table_priv']) && $GLOBALS['table_priv']
&& isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv']
) {
$html_output .= '<input type="checkbox" name="adjust_privileges" value="1" '
. 'id="checkbox_privileges_tables_move" checked="checked" />';
} else {
$html_output .= '<input type="checkbox" name="adjust_privileges" value="1" '
. 'id="checkbox_privileges_tables_move"'
. 'title="' . __(
'You don\'t have sufficient privileges to perform this '
. 'operation; Please refer to the documentation for more details'
)
. '" disabled/>';
}
$html_output .= '<label for="checkbox_privileges_tables_move">'
. __('Adjust Privileges') . PMA_Util::showDocu('faq', 'faq6-39')
. '</label><br />'
. '</fieldset>';
@ -868,10 +911,23 @@ function PMA_getHtmlForRenameTable()
. 'value="' . htmlspecialchars($GLOBALS['table'])
. '" required="required" />'
. '</td></tr>'
. '<tr><td></td><td>'
. '<input type="checkbox" name="adjust_privileges" value="1" '
. 'id="checkbox_privileges_table_options" checked="checked" />'
. '<label for="checkbox_privileges_table_options">'
. '<tr><td></td><td>';
if (isset($GLOBALS['table_priv']) && $GLOBALS['table_priv']
&& isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv']
) {
$html_output .= '<input type="checkbox" name="adjust_privileges" value="1" '
. 'id="checkbox_privileges_table_options" checked="checked" />';
} else {
$html_output .= '<input type="checkbox" name="adjust_privileges" value="1" '
. 'id="checkbox_privileges_table_options" '
. 'title="' . __(
'You don\'t have sufficient privileges to perform this '
. 'operation; Please refer to the documentation for more details'
)
. '" disabled/>';
}
$html_output .= '<label for="checkbox_privileges_table_options">'
. __('Adjust Privileges') . PMA_Util::showDocu('faq', 'faq6-39')
. '</label>'
. '</td>'
@ -1207,9 +1263,23 @@ function PMA_getHtmlForCopytable()
} // endif
$html_output .= '<br />';
$html_output .= '<input type="checkbox" name="adjust_privileges" value="1"'
. 'id="checkbox_adjust_privileges" checked="checked" />'
. '<label for="checkbox_adjust_privileges">'
if (isset($GLOBALS['table_priv']) && $GLOBALS['table_priv']
&& isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv']
) {
$html_output .= '<input type="checkbox" name="adjust_privileges" value="1"'
. 'id="checkbox_adjust_privileges" checked="checked" />';
} else {
$html_output .= '<input type="checkbox" name="adjust_privileges" value="1"'
. 'id="checkbox_adjust_privileges" '
. 'title="' . __(
'You don\'t have sufficient privileges to perform this '
. 'operation; Please refer to the documentation for more details'
)
. '" disabled/>';
}
$html_output .= '<label for="checkbox_adjust_privileges">'
. __('Adjust Privileges') . PMA_Util::showDocu('faq', 'faq6-39')
. '</label><br />';

View File

@ -1101,10 +1101,23 @@ function PMA_RTN_getEditorForm($mode, $operation, $routine)
$retval .= " <td>" . __('Adjust Privileges');
$retval .= PMA_Util::showDocu('faq', 'faq6-39');
$retval .= "</td>";
$retval .= " <td><input type='checkbox' name='item_adjust_privileges'"
. " value='1' checked /></td>";
if (isset($GLOBALS['proc_priv']) && $GLOBALS['proc_priv']
&& isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv']
) {
$retval .= " <td><input type='checkbox' name='item_adjust_privileges'"
. " value='1' checked /></td>";
} else {
$retval .= " <td><input type='checkbox' name='item_adjust_privileges'"
. " value='1' "
. "title='" . __(
"You do not have sufficient privileges to perform this "
. "operation; Please refer to the documentation for more details"
)
. "' disabled/></td>";
}
$retval .= "</tr>";
}
$retval .= "<tr>";
$retval .= " <td>" . __('Definer') . "</td>";
$retval .= " <td><input type='text' name='item_definer'";

View File

@ -2491,6 +2491,7 @@ function PMA_displayHtmlForColumnChange($db, $table, $selected, $action)
/**
* Form for changing properties.
*/
include_once 'libraries/check_user_privileges.lib.php';
include 'libraries/tbl_columns_definition_form.inc.php';
}

View File

@ -411,7 +411,8 @@ $html = PMA\Template::get('columns_definitions/column_definitions_form')
'mimework' => $cfgRelation['mimework'],
'action' => $action,
'form_params' => $form_params,
'content_cells' => $content_cells
'content_cells' => $content_cells,
'privs_available' => $privs_available
));
unset($form_params);

View File

@ -14,6 +14,7 @@ require_once 'libraries/common.inc.php';
/**
* functions implementation for this script
*/
require_once 'libraries/check_user_privileges.lib.php';
require_once 'libraries/operations.lib.php';
$pma_table = new PMA_Table($GLOBALS['table'], $GLOBALS['db']);

View File

@ -19,6 +19,7 @@ PMA_PageSettings::showGroup('TableStructure');
/**
* Function implementations for this script
*/
require_once 'libraries/check_user_privileges.lib.php';
require_once 'libraries/structure.lib.php';
require_once 'libraries/index.lib.php';
require_once 'libraries/sql.lib.php';

View File

@ -1,6 +1,18 @@
<input name="field_adjust_privileges[<?php echo $columnNumber; ?>]"
id="field_<?php echo $columnNumber; ?>_<?php echo ($ci - $ci_offset); ?>"
checked="checked"
type="checkbox"
value="NULL"
class="allow_null"/>
<?php if ($privs_available) : ?>
<input name="field_adjust_privileges[<?php echo $columnNumber; ?>]"
id="field_<?php echo $columnNumber; ?>_<?php echo ($ci - $ci_offset); ?>"
checked="checked"
type="checkbox"
value="NULL"
class="allow_null"/>
<?php else : ?>
<input name="field_adjust_privileges[<?php echo $columnNumber; ?>]"
id="field_<?php echo $columnNumber; ?>_<?php echo ($ci - $ci_offset); ?>"
disabled
type="checkbox"
value="NULL"
class="allow_null"
title="<?php echo __('You don\'t have sufficient privileges to perform this '
. 'operation; Please refer to the documentation for more details');?>"/>
<?php endif; ?>

View File

@ -87,11 +87,14 @@ $ci_offset = -1;
<?php if (isset($_REQUEST['change_column']) && !empty($_REQUEST['change_column'])): ?>
<!-- column Adjust Privileges, Only for 'Edit' Column(s) -->
<td class="center">
<?php $privs_available = isset($GLOBALS['col_priv']) && $GLOBALS['col_priv']
&& isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv']; ?>
<?php echo PMA\Template::get('columns_definitions/column_adjust_privileges')
->render(array(
'columnNumber' => $columnNumber,
'ci' => $ci++,
'ci_offset' => $ci_offset
'ci_offset' => $ci_offset,
'privs_available' => $privs_available
)); ?>
</td>
<?php endif; ?>