2 /* vim: set expandtab sw=4 ts=4 sts=4: */
11 require_once 'libraries/common.inc.php';
14 * Does the common work
16 $GLOBALS['js_include'][] = 'server_privileges.js';
17 $GLOBALS['js_include'][] = 'functions.js';
19 if ($GLOBALS['cfg']['CodemirrorEnable']) {
20 $GLOBALS['js_include'][] = 'codemirror/lib/codemirror.js';
21 $GLOBALS['js_include'][] = 'codemirror/mode/mysql/mysql.js';
23 $_add_user_error = false;
26 * Sets globals from $_GET
39 foreach ($get_params as $one_get_param) {
40 if (isset($_GET[$one_get_param])) {
41 $GLOBALS[$one_get_param] = $_GET[$one_get_param];
46 * Sets globals from $_POST
63 foreach ($post_params as $one_post_param) {
64 if (isset($_POST[$one_post_param])) {
65 $GLOBALS[$one_post_param] = $_POST[$one_post_param];
70 * Sets globals from $_POST patterns, for privileges and max_* vars
73 $post_patterns = array(
77 foreach (array_keys($_POST) as $post_key) {
78 foreach ($post_patterns as $one_post_pattern) {
79 if (preg_match($one_post_pattern, $post_key)) {
80 $GLOBALS[$post_key] = $_POST[$post_key];
85 require 'libraries/server_common.inc.php';
87 if ($GLOBALS['cfg']['AjaxEnable']) {
88 $conditional_class = 'ajax';
90 $conditional_class = '';
94 * Messages are built using the message name
96 $strPrivDescAllPrivileges = __('Includes all privileges except GRANT.');
97 $strPrivDescAlter = __('Allows altering the structure of existing tables.');
98 $strPrivDescAlterRoutine = __('Allows altering and dropping stored routines.');
99 $strPrivDescCreateDb = __('Allows creating new databases and tables.');
100 $strPrivDescCreateRoutine = __('Allows creating stored routines.');
101 $strPrivDescCreateTbl = __('Allows creating new tables.');
102 $strPrivDescCreateTmpTable = __('Allows creating temporary tables.');
103 $strPrivDescCreateUser = __('Allows creating, dropping and renaming user accounts.');
104 $strPrivDescCreateView = __('Allows creating new views.');
105 $strPrivDescDelete = __('Allows deleting data.');
106 $strPrivDescDropDb = __('Allows dropping databases and tables.');
107 $strPrivDescDropTbl = __('Allows dropping tables.');
108 $strPrivDescEvent = __('Allows to set up events for the event scheduler');
109 $strPrivDescExecute = __('Allows executing stored routines.');
110 $strPrivDescFile = __('Allows importing data from and exporting data into files.');
111 $strPrivDescGrant = __('Allows adding users and privileges without reloading the privilege tables.');
112 $strPrivDescIndex = __('Allows creating and dropping indexes.');
113 $strPrivDescInsert = __('Allows inserting and replacing data.');
114 $strPrivDescLockTables = __('Allows locking tables for the current thread.');
115 $strPrivDescMaxConnections = __('Limits the number of new connections the user may open per hour.');
116 $strPrivDescMaxQuestions = __('Limits the number of queries the user may send to the server per hour.');
117 $strPrivDescMaxUpdates = __('Limits the number of commands that change any table or database the user may execute per hour.');
118 $strPrivDescMaxUserConnections = __('Limits the number of simultaneous connections the user may have.');
119 $strPrivDescProcess = __('Allows viewing processes of all users');
120 $strPrivDescReferences = __('Has no effect in this MySQL version.');
121 $strPrivDescReload = __('Allows reloading server settings and flushing the server\'s caches.');
122 $strPrivDescReplClient = __('Allows the user to ask where the slaves / masters are.');
123 $strPrivDescReplSlave = __('Needed for the replication slaves.');
124 $strPrivDescSelect = __('Allows reading data.');
125 $strPrivDescShowDb = __('Gives access to the complete list of databases.');
126 $strPrivDescShowView = __('Allows performing SHOW CREATE VIEW queries.');
127 $strPrivDescShutdown = __('Allows shutting down the server.');
128 $strPrivDescSuper = __('Allows connecting, even if maximum number of connections is reached; required for most administrative operations like setting global variables or killing threads of other users.');
129 $strPrivDescTrigger = __('Allows creating and dropping triggers');
130 $strPrivDescUpdate = __('Allows changing data.');
131 $strPrivDescUsage = __('No privileges.');
134 * Checks if a dropdown box has been used for selecting a database / table
136 if (PMA_isValid($_REQUEST['pred_tablename'])) {
137 $tablename = $_REQUEST['pred_tablename'];
138 unset($pred_tablename);
139 } elseif (PMA_isValid($_REQUEST['tablename'])) {
140 $tablename = $_REQUEST['tablename'];
145 if (PMA_isValid($_REQUEST['pred_dbname'])) {
146 $dbname = $_REQUEST['pred_dbname'];
148 } elseif (PMA_isValid($_REQUEST['dbname'])) {
149 $dbname = $_REQUEST['dbname'];
155 if (isset($dbname)) {
156 $db_and_table = PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . '.';
157 if (isset($tablename)) {
158 $db_and_table .= PMA_backquote($tablename);
160 $db_and_table .= '*';
163 $db_and_table = '*.*';
166 // check if given $dbname is a wildcard or not
167 if (isset($dbname)) {
168 //if (preg_match('/\\\\(?:_|%)/i', $dbname)) {
169 if (preg_match('/(?<!\\\\)(?:_|%)/i', $dbname)) {
170 $dbname_is_wildcard = true;
172 $dbname_is_wildcard = false;
177 * Checks if the user is allowed to do what he tries to...
179 if (! $is_superuser) {
180 include 'libraries/server_links.inc.php';
182 . PMA_getIcon('b_usrlist.png')
183 . __('Privileges') . "\n"
185 PMA_Message
::error(__('No Privileges'))->display();
186 include 'libraries/footer.inc.php';
189 // a random number that will be appended to the id of the user forms
190 $random_n = mt_rand(0, 1000000);
193 * Escapes wildcard in a database+table specification
194 * before using it in a GRANT statement.
196 * Escaping a wildcard character in a GRANT is only accepted at the global
197 * or database level, not at table level; this is why I remove
198 * the escaping character. Internally, in mysql.tables_priv.Db there are
199 * no escaping (for example test_db) but in mysql.db you'll see test\_db
200 * for a db-specific privilege.
202 * @param string $dbname Database name
203 * @param string $tablename Table name
205 * @return string the escaped (if necessary) database.table
207 function PMA_wildcardEscapeForGrant($dbname, $tablename)
210 if (! strlen($dbname)) {
211 $db_and_table = '*.*';
213 if (strlen($tablename)) {
215 = PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . '.'
216 . PMA_backquote($tablename);
218 $db_and_table = PMA_backquote($dbname) . '.*';
221 return $db_and_table;
225 * Generates a condition on the user name
227 * @param string $initial the user's initial
229 * @return string the generated condition
231 function PMA_rangeOfUsers($initial = '')
233 // strtolower() is used because the User field
234 // might be BINARY, so LIKE would be case sensitive
235 if (! empty($initial)) {
236 $ret = " WHERE `User` LIKE '"
237 . PMA_sqlAddSlashes($initial, true) . "%'"
238 . " OR `User` LIKE '"
239 . PMA_sqlAddSlashes(strtolower($initial), true) . "%'";
247 * Extracts the privilege information of a priv table row
249 * @param array $row the row
250 * @param boolean $enableHTML add <dfn> tag with tooltips
252 * @global resource $user_link the database connection
256 function PMA_extractPrivInfo($row = '', $enableHTML = false)
262 __('Allows reading data.')),
266 __('Allows inserting and replacing data.')),
270 __('Allows changing data.')),
274 __('Allows deleting data.')),
278 __('Allows creating new databases and tables.')),
282 __('Allows dropping databases and tables.')),
286 __('Allows reloading server settings and flushing the server\'s caches.')),
290 __('Allows shutting down the server.')),
294 __('Allows viewing processes of all users')),
298 __('Allows importing data from and exporting data into files.')),
302 __('Has no effect in this MySQL version.')),
306 __('Allows creating and dropping indexes.')),
310 __('Allows altering the structure of existing tables.')),
314 __('Gives access to the complete list of databases.')),
318 __('Allows connecting, even if maximum number of connections is reached; required for most administrative operations like setting global variables or killing threads of other users.')),
320 'Create_tmp_table_priv',
321 'CREATE TEMPORARY TABLES',
322 __('Allows creating temporary tables.')),
326 __('Allows locking tables for the current thread.')),
330 __('Needed for the replication slaves.')),
333 'REPLICATION CLIENT',
334 __('Allows the user to ask where the slaves / masters are.')),
338 __('Allows creating new views.')),
342 __('Allows to set up events for the event scheduler')),
346 __('Allows creating and dropping triggers')),
351 __('Allows creating new views.')),
355 __('Allows performing SHOW CREATE VIEW queries.')),
360 __('Allows performing SHOW CREATE VIEW queries.')),
362 'Create_routine_priv',
364 __('Allows creating stored routines.')),
366 'Alter_routine_priv',
368 __('Allows altering and dropping stored routines.')),
372 __('Allows creating, dropping and renaming user accounts.')),
376 __('Allows executing stored routines.')),
379 if (! empty($row) && isset($row['Table_priv'])) {
380 $row1 = PMA_DBI_fetch_single_row(
381 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
382 'ASSOC', $GLOBALS['userlink']
384 $av_grants = explode(
386 substr($row1['Type'], 5, strlen($row1['Type']) - 7)
389 $users_grants = explode(',', $row['Table_priv']);
390 foreach ($av_grants as $current_grant) {
391 $row[$current_grant . '_priv']
392 = in_array($current_grant, $users_grants) ?
'Y' : 'N';
394 unset($current_grant);
396 unset($users_grants);
399 $allPrivileges = true;
400 foreach ($grants as $current_grant) {
401 if ((! empty($row) && isset($row[$current_grant[0]]))
402 ||
(empty($row) && isset($GLOBALS[$current_grant[0]]))
404 if ((! empty($row) && $row[$current_grant[0]] == 'Y')
406 && ($GLOBALS[$current_grant[0]] == 'Y'
407 ||
(is_array($GLOBALS[$current_grant[0]])
408 && count($GLOBALS[$current_grant[0]]) == $GLOBALS['column_count']
409 && empty($GLOBALS[$current_grant[0] . '_none']))))
412 $privs[] = '<dfn title="' . $current_grant[2] . '">'
413 . $current_grant[1] . '</dfn>';
415 $privs[] = $current_grant[1];
417 } elseif (! empty($GLOBALS[$current_grant[0]])
418 && is_array($GLOBALS[$current_grant[0]])
419 && empty($GLOBALS[$current_grant[0] . '_none'])) {
421 $priv_string = '<dfn title="' . $current_grant[2] . '">'
422 . $current_grant[1] . '</dfn>';
424 $priv_string = $current_grant[1];
426 $privs[] = $priv_string . ' (`'
427 . join('`, `', $GLOBALS[$current_grant[0]]) . '`)';
429 $allPrivileges = false;
435 $privs[] = '<dfn title="' . __('No privileges.') . '">USAGE</dfn>';
439 } elseif ($allPrivileges
440 && (! isset($GLOBALS['grant_count'])
441 ||
count($privs) == $GLOBALS['grant_count'])
444 $privs = array('<dfn title="'
445 . __('Includes all privileges except GRANT.')
446 . '">ALL PRIVILEGES</dfn>'
449 $privs = array('ALL PRIVILEGES');
453 } // end of the 'PMA_extractPrivInfo()' function
456 * Displays on which column(s) a table-specific privilege is granted
458 * @param array $columns
460 * @param string $name_for_select
461 * @param string $priv_for_header
462 * @param string $name
463 * @param string $name_for_dfn
464 * @param string $name_for_current
468 function PMA_displayColumnPrivs($columns, $row, $name_for_select,
469 $priv_for_header, $name, $name_for_dfn, $name_for_current
471 echo ' <div class="item" id="div_item_' . $name . '">' . "\n"
472 . ' <label for="select_' . $name . '_priv">' . "\n"
473 . ' <code><dfn title="' . $name_for_dfn . '">'
474 . $priv_for_header . '</dfn></code>' . "\n"
475 . ' </label><br />' . "\n"
476 . ' <select id="select_' . $name . '_priv" name="'
477 . $name_for_select . '[]" multiple="multiple" size="8">' . "\n";
479 foreach ($columns as $current_column => $current_column_privileges) {
480 echo ' <option value="' . htmlspecialchars($current_column) . '"';
481 if ($row[$name_for_select] == 'Y' ||
$current_column_privileges[$name_for_current]) {
482 echo ' selected="selected"';
484 echo '>' . htmlspecialchars($current_column) . '</option>' . "\n";
487 echo ' </select>' . "\n"
488 . ' <i>' . __('Or') . '</i>' . "\n"
489 . ' <label for="checkbox_' . $name_for_select
490 . '_none"><input type="checkbox"'
491 . (empty($GLOBALS['checkall']) ?
'' : ' checked="checked"')
492 . ' name="' . $name_for_select . '_none" id="checkbox_'
493 . $name_for_select . '_none" title="'
494 . _pgettext('None privileges', 'None') . '" />'
495 . _pgettext('None privileges', 'None') . '</label>' . "\n"
501 * Displays the privileges form table
503 * @param string $db the database
504 * @param string $table the table
505 * @param boolean $submit wheather to display the submit button or not
507 * @global array $cfg the phpMyAdmin configuration
508 * @global ressource $user_link the database connection
512 function PMA_displayPrivTable($db = '*', $table = '*', $submit = true)
520 if (isset($GLOBALS['username'])) {
521 $username = $GLOBALS['username'];
522 $hostname = $GLOBALS['hostname'];
524 $sql_query = "SELECT * FROM `mysql`.`user`"
525 ." WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'"
526 ." AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "';";
527 } elseif ($table == '*') {
528 $sql_query = "SELECT * FROM `mysql`.`db`"
529 ." WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'"
530 ." AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "'"
531 ." AND '" . PMA_unescape_mysql_wildcards($db) . "'"
534 $sql_query = "SELECT `Table_priv`"
535 ." FROM `mysql`.`tables_priv`"
536 ." WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'"
537 ." AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "'"
538 ." AND `Db` = '" . PMA_unescape_mysql_wildcards($db) . "'"
539 ." AND `Table_name` = '" . PMA_sqlAddSlashes($table) . "';";
541 $row = PMA_DBI_fetch_single_row($sql_query);
546 $sql_query = 'SHOW COLUMNS FROM `mysql`.`user`;';
547 } elseif ($table == '*') {
548 $sql_query = 'SHOW COLUMNS FROM `mysql`.`db`;';
550 $res = PMA_DBI_query($sql_query);
551 while ($row1 = PMA_DBI_fetch_row($res)) {
552 if (substr($row1[0], 0, 4) == 'max_') {
555 $row[$row1[0]] = 'N';
558 PMA_DBI_free_result($res);
560 $row = array('Table_priv' => '');
563 if (isset($row['Table_priv'])) {
564 $row1 = PMA_DBI_fetch_single_row(
565 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
566 'ASSOC', $GLOBALS['userlink']
568 // note: in MySQL 5.0.3 we get "Create View', 'Show view';
569 // the View for Create is spelled with uppercase V
570 // the view for Show is spelled with lowercase v
571 // and there is a space between the words
573 $av_grants = explode(
577 strpos($row1['Type'], '(') +
2,
578 strpos($row1['Type'], ')') - strpos($row1['Type'], '(') - 3
582 $users_grants = explode(',', $row['Table_priv']);
584 foreach ($av_grants as $current_grant) {
585 $row[$current_grant . '_priv']
586 = in_array($current_grant, $users_grants) ?
'Y' : 'N';
588 unset($row['Table_priv'], $current_grant, $av_grants, $users_grants);
591 $res = PMA_DBI_try_query(
593 . PMA_backquote(PMA_unescape_mysql_wildcards($db))
594 . '.' . PMA_backquote($table) . ';'
598 while ($row1 = PMA_DBI_fetch_row($res)) {
599 $columns[$row1[0]] = array(
603 'References' => false
606 PMA_DBI_free_result($res);
610 // t a b l e - s p e c i f i c p r i v i l e g e s
611 if (! empty($columns)) {
612 $res = PMA_DBI_query(
613 'SELECT `Column_name`, `Column_priv`'
614 .' FROM `mysql`.`columns_priv`'
616 .' = \'' . PMA_sqlAddSlashes($username) . "'"
618 .' = \'' . PMA_sqlAddSlashes($hostname) . "'"
620 .' = \'' . PMA_sqlAddSlashes(PMA_unescape_mysql_wildcards($db)) . "'"
622 .' = \'' . PMA_sqlAddSlashes($table) . '\';'
625 while ($row1 = PMA_DBI_fetch_row($res)) {
626 $row1[1] = explode(',', $row1[1]);
627 foreach ($row1[1] as $current) {
628 $columns[$row1[0]][$current] = true;
631 PMA_DBI_free_result($res);
632 unset($res, $row1, $current);
634 echo '<input type="hidden" name="grant_count" value="' . count($row) . '" />' . "\n"
635 . '<input type="hidden" name="column_count" value="' . count($columns) . '" />' . "\n"
636 . '<fieldset id="fieldset_user_priv">' . "\n"
637 . ' <legend>' . __('Table-specific privileges')
638 . PMA_showHint(__('Note: MySQL privilege names are expressed in English'))
639 . '</legend>' . "\n";
643 // privs that are attached to a specific column
644 PMA_displayColumnPrivs(
645 $columns, $row, 'Select_priv', 'SELECT',
646 'select', __('Allows reading data.'), 'Select'
649 PMA_displayColumnPrivs(
650 $columns, $row, 'Insert_priv', 'INSERT',
651 'insert', __('Allows inserting and replacing data.'), 'Insert'
654 PMA_displayColumnPrivs(
655 $columns, $row, 'Update_priv', 'UPDATE',
656 'update', __('Allows changing data.'), 'Update'
659 PMA_displayColumnPrivs(
660 $columns, $row, 'References_priv', 'REFERENCES', 'references',
661 __('Has no effect in this MySQL version.'), 'References'
664 // privs that are not attached to a specific column
666 echo ' <div class="item">' . "\n";
667 foreach ($row as $current_grant => $current_grant_value) {
668 $grant_type = substr($current_grant, 0, (strlen($current_grant) - 5));
669 if (in_array($grant_type, array('Select', 'Insert', 'Update', 'References'))) {
672 // make a substitution to match the messages variables;
673 // also we must substitute the grant we get, because we can't generate
674 // a form variable containing blanks (those would get changed to
675 // an underscore when receiving the POST)
676 if ($current_grant == 'Create View_priv') {
677 $tmp_current_grant = 'CreateView_priv';
678 $current_grant = 'Create_view_priv';
679 } elseif ($current_grant == 'Show view_priv') {
680 $tmp_current_grant = 'ShowView_priv';
681 $current_grant = 'Show_view_priv';
683 $tmp_current_grant = $current_grant;
686 echo ' <div class="item">' . "\n"
687 . ' <input type="checkbox"'
688 . (empty($GLOBALS['checkall']) ?
'' : ' checked="checked"')
689 . ' name="' . $current_grant . '" id="checkbox_' . $current_grant
691 . ($current_grant_value == 'Y' ?
'checked="checked" ' : '')
694 echo (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))])
695 ?
$GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))]
696 : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)) . 'Tbl']) . '"/>' . "\n";
698 echo ' <label for="checkbox_' . $current_grant
699 . '"><code><dfn title="'
700 . (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))])
701 ?
$GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))]
702 : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)) . 'Tbl'])
703 . '">' . strtoupper(substr($current_grant, 0, strlen($current_grant) - 5)) . '</dfn></code></label>' . "\n"
707 echo ' </div>' . "\n";
709 echo ' <div class="clearfloat"></div>' . "\n";
713 // g l o b a l o r d b - s p e c i f i c
715 $privTable_names = array(0 => __('Data'), 1 => __('Structure'), 2 => __('Administration'));
718 $privTable[0] = array(
719 array('Select', 'SELECT', __('Allows reading data.')),
720 array('Insert', 'INSERT', __('Allows inserting and replacing data.')),
721 array('Update', 'UPDATE', __('Allows changing data.')),
722 array('Delete', 'DELETE', __('Allows deleting data.'))
725 $privTable[0][] = array('File', 'FILE', __('Allows importing data from and exporting data into files.'));
729 $privTable[1] = array(
730 array('Create', 'CREATE', ($table == '*' ?
__('Allows creating new databases and tables.') : __('Allows creating new tables.'))),
731 array('Alter', 'ALTER', __('Allows altering the structure of existing tables.')),
732 array('Index', 'INDEX', __('Allows creating and dropping indexes.')),
733 array('Drop', 'DROP', ($table == '*' ?
__('Allows dropping databases and tables.') : __('Allows dropping tables.'))),
734 array('Create_tmp_table', 'CREATE TEMPORARY TABLES', __('Allows creating temporary tables.')),
735 array('Show_view', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')),
736 array('Create_routine', 'CREATE ROUTINE', __('Allows creating stored routines.')),
737 array('Alter_routine', 'ALTER ROUTINE', __('Allows altering and dropping stored routines.')),
738 array('Execute', 'EXECUTE', __('Allows executing stored routines.')),
740 // this one is for a db-specific priv: Create_view_priv
741 if (isset($row['Create_view_priv'])) {
742 $privTable[1][] = array('Create_view', 'CREATE VIEW', __('Allows creating new views.'));
744 // this one is for a table-specific priv: Create View_priv
745 if (isset($row['Create View_priv'])) {
746 $privTable[1][] = array('Create View', 'CREATE VIEW', __('Allows creating new views.'));
748 if (isset($row['Event_priv'])) {
750 $privTable[1][] = array('Event', 'EVENT', __('Allows to set up events for the event scheduler'));
751 $privTable[1][] = array('Trigger', 'TRIGGER', __('Allows creating and dropping triggers'));
754 // a d m i n i s t r a t i o n
755 $privTable[2] = array(
756 array('Grant', 'GRANT', __('Allows adding users and privileges without reloading the privilege tables.')),
759 $privTable[2][] = array('Super', 'SUPER', __('Allows connecting, even if maximum number of connections is reached; required for most administrative operations like setting global variables or killing threads of other users.'));
760 $privTable[2][] = array('Process', 'PROCESS', __('Allows viewing processes of all users'));
761 $privTable[2][] = array('Reload', 'RELOAD', __('Allows reloading server settings and flushing the server\'s caches.'));
762 $privTable[2][] = array('Shutdown', 'SHUTDOWN', __('Allows shutting down the server.'));
763 $privTable[2][] = array('Show_db', 'SHOW DATABASES', __('Gives access to the complete list of databases.'));
765 $privTable[2][] = array('Lock_tables', 'LOCK TABLES', __('Allows locking tables for the current thread.'));
766 $privTable[2][] = array('References', 'REFERENCES', __('Has no effect in this MySQL version.'));
768 $privTable[2][] = array('Repl_client', 'REPLICATION CLIENT', __('Allows the user to ask where the slaves / masters are.'));
769 $privTable[2][] = array('Repl_slave', 'REPLICATION SLAVE', __('Needed for the replication slaves.'));
770 $privTable[2][] = array('Create_user', 'CREATE USER', __('Allows creating, dropping and renaming user accounts.'));
772 echo '<input type="hidden" name="grant_count" value="'
773 . (count($privTable[0]) +
count($privTable[1]) +
count($privTable[2]) - (isset($row['Grant_priv']) ?
1 : 0))
775 . '<fieldset id="fieldset_user_global_rights">' . "\n"
779 ?
__('Global privileges')
781 ?
__('Database-specific privileges')
782 : __('Table-specific privileges'))) . "\n"
783 . ' (<a href="server_privileges.php?'
784 . $GLOBALS['url_query'] . '&checkall=1" onclick="setCheckboxes(\'addUsersForm_' . $random_n . '\', true); return false;">'
785 . __('Check All') . '</a> /' . "\n"
786 . ' <a href="server_privileges.php?'
787 . $GLOBALS['url_query'] . '" onclick="setCheckboxes(\'addUsersForm_' . $random_n . '\', false); return false;">'
788 . __('Uncheck All') . '</a>)' . "\n"
789 . ' </legend>' . "\n"
790 . ' <p><small><i>' . __('Note: MySQL privilege names are expressed in English') . '</i></small></p>' . "\n";
792 // Output the Global privilege tables with checkboxes
793 foreach ($privTable as $i => $table) {
794 echo ' <fieldset>' . "\n"
795 . ' <legend>' . __($privTable_names[$i]) . '</legend>' . "\n";
796 foreach ($table as $priv) {
797 echo ' <div class="item">' . "\n"
798 . ' <input type="checkbox"'
799 . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0] . '_priv"'
800 . ' value="Y" title="' . $priv[2] . '"'
801 . ((! empty($GLOBALS['checkall']) ||
$row[$priv[0] . '_priv'] == 'Y') ?
' checked="checked"' : '')
803 . ' <label for="checkbox_' . $priv[0] . '_priv"><code><dfn title="' . $priv[2] . '">'
804 . $priv[1] . '</dfn></code></label>' . "\n"
807 echo ' </fieldset>' . "\n";
810 // The "Resource limits" box is not displayed for db-specific privs
812 echo ' <fieldset>' . "\n"
813 . ' <legend>' . __('Resource limits') . '</legend>' . "\n"
814 . ' <p><small><i>' . __('Note: Setting these options to 0 (zero) removes the limit.') . '</i></small></p>' . "\n"
815 . ' <div class="item">' . "\n"
816 . ' <label for="text_max_questions"><code><dfn title="'
817 . __('Limits the number of queries the user may send to the server per hour.') . '">MAX QUERIES PER HOUR</dfn></code></label>' . "\n"
818 . ' <input type="text" name="max_questions" id="text_max_questions" value="'
819 . $row['max_questions'] . '" size="11" maxlength="11" title="' . __('Limits the number of queries the user may send to the server per hour.') . '" />' . "\n"
821 . ' <div class="item">' . "\n"
822 . ' <label for="text_max_updates"><code><dfn title="'
823 . __('Limits the number of commands that change any table or database the user may execute per hour.') . '">MAX UPDATES PER HOUR</dfn></code></label>' . "\n"
824 . ' <input type="text" name="max_updates" id="text_max_updates" value="'
825 . $row['max_updates'] . '" size="11" maxlength="11" title="' . __('Limits the number of commands that change any table or database the user may execute per hour.') . '" />' . "\n"
827 . ' <div class="item">' . "\n"
828 . ' <label for="text_max_connections"><code><dfn title="'
829 . __('Limits the number of new connections the user may open per hour.') . '">MAX CONNECTIONS PER HOUR</dfn></code></label>' . "\n"
830 . ' <input type="text" name="max_connections" id="text_max_connections" value="'
831 . $row['max_connections'] . '" size="11" maxlength="11" title="' . __('Limits the number of new connections the user may open per hour.') . '" />' . "\n"
833 . ' <div class="item">' . "\n"
834 . ' <label for="text_max_user_connections"><code><dfn title="'
835 . __('Limits the number of simultaneous connections the user may have.') . '">MAX USER_CONNECTIONS</dfn></code></label>' . "\n"
836 . ' <input type="text" name="max_user_connections" id="text_max_user_connections" value="'
837 . $row['max_user_connections'] . '" size="11" maxlength="11" title="' . __('Limits the number of simultaneous connections the user may have.') . '" />' . "\n"
839 . ' </fieldset>' . "\n";
842 echo ' <div class="clearfloat"></div>' . "\n";
844 echo '</fieldset>' . "\n";
846 echo '<fieldset id="fieldset_user_privtable_footer" class="tblFooters">' . "\n"
847 . ' <input type="submit" name="update_privs" value="' . __('Go') . '" />' . "\n"
848 . '</fieldset>' . "\n";
850 } // end of the 'PMA_displayPrivTable()' function
854 * Displays the fields used by the "new user" form as well as the
855 * "change login information / copy user" form.
857 * @param string $mode are we creating a new user or are we just
858 * changing one? (allowed values: 'new', 'change')
860 * @global array $cfg the phpMyAdmin configuration
861 * @global ressource $user_link the database connection
865 function PMA_displayLoginInformationFields($mode = 'new')
867 // Get user/host name lengths
868 $fields_info = PMA_DBI_get_columns('mysql', 'user', null, true);
869 $username_length = 16;
870 $hostname_length = 41;
871 foreach ($fields_info as $val) {
872 if ($val['Field'] == 'User') {
873 strtok($val['Type'], '()');
876 $username_length = $v;
878 } elseif ($val['Field'] == 'Host') {
879 strtok($val['Type'], '()');
882 $hostname_length = $v;
888 if (isset($GLOBALS['username']) && strlen($GLOBALS['username']) === 0) {
889 $GLOBALS['pred_username'] = 'any';
891 echo '<fieldset id="fieldset_add_user_login">' . "\n"
892 . '<legend>' . __('Login Information') . '</legend>' . "\n"
893 . '<div class="item">' . "\n"
894 . '<label for="select_pred_username">' . "\n"
895 . ' ' . __('User name') . ':' . "\n"
897 . '<span class="options">' . "\n"
898 . ' <select name="pred_username" id="select_pred_username" title="' . __('User name') . '"' . "\n"
899 . ' onchange="if (this.value == \'any\') { username.value = \'\'; } else if (this.value == \'userdefined\') { username.focus(); username.select(); }">' . "\n"
900 . ' <option value="any"' . ((isset($GLOBALS['pred_username']) && $GLOBALS['pred_username'] == 'any') ?
' selected="selected"' : '') . '>' . __('Any user') . '</option>' . "\n"
901 . ' <option value="userdefined"' . ((! isset($GLOBALS['pred_username']) ||
$GLOBALS['pred_username'] == 'userdefined') ?
' selected="selected"' : '') . '>' . __('Use text field') . ':</option>' . "\n"
902 . ' </select>' . "\n"
904 . '<input type="text" name="username" maxlength="'
905 . $username_length . '" title="' . __('User name') . '"'
906 . (empty($GLOBALS['username'])
908 : ' value="' . htmlspecialchars(
909 isset($GLOBALS['new_username'])
910 ?
$GLOBALS['new_username']
911 : $GLOBALS['username']
914 . ' onchange="pred_username.value = \'userdefined\';" autofocus="autofocus" />' . "\n"
916 . '<div class="item">' . "\n"
917 . '<label for="select_pred_hostname">' . "\n"
918 . ' ' . __('Host') . ':' . "\n"
920 . '<span class="options">' . "\n"
921 . ' <select name="pred_hostname" id="select_pred_hostname" title="' . __('Host') . '"' . "\n";
922 $_current_user = PMA_DBI_fetch_value('SELECT USER();');
923 if (! empty($_current_user)) {
924 $thishost = str_replace("'", '', substr($_current_user, (strrpos($_current_user, '@') +
1)));
925 if ($thishost == 'localhost' ||
$thishost == '127.0.0.1') {
929 echo ' onchange="if (this.value == \'any\') { hostname.value = \'%\'; } else if (this.value == \'localhost\') { hostname.value = \'localhost\'; } '
930 . (empty($thishost) ?
'' : 'else if (this.value == \'thishost\') { hostname.value = \'' . addslashes(htmlspecialchars($thishost)) . '\'; } ')
931 . 'else if (this.value == \'hosttable\') { hostname.value = \'\'; } else if (this.value == \'userdefined\') { hostname.focus(); hostname.select(); }">' . "\n";
932 unset($_current_user);
934 // when we start editing a user, $GLOBALS['pred_hostname'] is not defined
935 if (! isset($GLOBALS['pred_hostname']) && isset($GLOBALS['hostname'])) {
936 switch (strtolower($GLOBALS['hostname'])) {
939 $GLOBALS['pred_hostname'] = 'localhost';
942 $GLOBALS['pred_hostname'] = 'any';
945 $GLOBALS['pred_hostname'] = 'userdefined';
949 echo ' <option value="any"'
950 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'any')
951 ?
' selected="selected"' : '') . '>' . __('Any host')
953 . ' <option value="localhost"'
954 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'localhost')
955 ?
' selected="selected"' : '') . '>' . __('Local')
956 . '</option>' . "\n";
957 if (! empty($thishost)) {
958 echo ' <option value="thishost"'
959 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'thishost')
960 ?
' selected="selected"' : '') . '>' . __('This Host')
961 . '</option>' . "\n";
964 echo ' <option value="hosttable"'
965 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'hosttable')
966 ?
' selected="selected"' : '') . '>' . __('Use Host Table')
968 . ' <option value="userdefined"'
969 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'userdefined')
970 ?
' selected="selected"' : '')
971 . '>' . __('Use text field') . ':</option>' . "\n"
972 . ' </select>' . "\n"
974 . '<input type="text" name="hostname" maxlength="'
975 . $hostname_length . '" value="'
976 . htmlspecialchars(isset($GLOBALS['hostname']) ?
$GLOBALS['hostname'] : '')
977 . '" title="' . __('Host')
978 . '" onchange="pred_hostname.value = \'userdefined\';" />' . "\n"
979 . PMA_showHint(__('When Host table is used, this field is ignored and values stored in Host table are used instead.'))
981 . '<div class="item">' . "\n"
982 . '<label for="select_pred_password">' . "\n"
983 . ' ' . __('Password') . ':' . "\n"
985 . '<span class="options">' . "\n"
986 . ' <select name="pred_password" id="select_pred_password" title="'
987 . __('Password') . '"' . "\n"
988 . ' onchange="if (this.value == \'none\') { pma_pw.value = \'\'; pma_pw2.value = \'\'; } else if (this.value == \'userdefined\') { pma_pw.focus(); pma_pw.select(); }">' . "\n"
989 . ($mode == 'change' ?
' <option value="keep" selected="selected">' . __('Do not change the password') . '</option>' . "\n" : '')
990 . ' <option value="none"';
991 if (isset($GLOBALS['username']) && $mode != 'change') {
992 echo ' selected="selected"';
994 echo '>' . __('No Password') . '</option>' . "\n"
995 . ' <option value="userdefined"' . (isset($GLOBALS['username']) ?
'' : ' selected="selected"') . '>' . __('Use text field') . ':</option>' . "\n"
996 . ' </select>' . "\n"
998 . '<input type="password" id="text_pma_pw" name="pma_pw" title="' . __('Password') . '" onchange="pred_password.value = \'userdefined\';" />' . "\n"
1000 . '<div class="item" id="div_element_before_generate_password">' . "\n"
1001 . '<label for="text_pma_pw2">' . "\n"
1002 . ' ' . __('Re-type') . ':' . "\n"
1004 . '<span class="options"> </span>' . "\n"
1005 . '<input type="password" name="pma_pw2" id="text_pma_pw2" title="' . __('Re-type') . '" onchange="pred_password.value = \'userdefined\';" />' . "\n"
1007 // Generate password added here via jQuery
1008 . '</fieldset>' . "\n";
1009 } // end of the 'PMA_displayUserAndHostFields()' function
1013 * Returns all the grants for a certain user on a certain host
1014 * Used in the export privileges for all users section
1016 * @param string $user User name
1017 * @param string $host Host name
1019 * @return string containing all the grants text
1021 function PMA_getGrants($user, $host)
1023 $grants = PMA_DBI_fetch_result("SHOW GRANTS FOR '" . PMA_sqlAddSlashes($user) . "'@'" . PMA_sqlAddSlashes($host) . "'");
1025 foreach ($grants as $one_grant) {
1026 $response .= $one_grant . ";\n\n";
1029 } // end of the 'PMA_getGrants()' function
1032 * Changes / copies a user, part I
1034 if (isset($_REQUEST['change_copy'])) {
1035 $user_host_condition = ' WHERE `User`'
1036 .' = \'' . PMA_sqlAddSlashes($old_username) . "'"
1038 .' = \'' . PMA_sqlAddSlashes($old_hostname) . '\';';
1039 $row = PMA_DBI_fetch_single_row('SELECT * FROM `mysql`.`user` ' . $user_host_condition);
1041 PMA_Message
::notice(__('No user found.'))->display();
1042 unset($_REQUEST['change_copy']);
1044 extract($row, EXTR_OVERWRITE
);
1045 // Recent MySQL versions have the field "Password" in mysql.user,
1046 // so the previous extract creates $Password but this script
1048 if (! isset($password) && isset($Password)) {
1049 $password = $Password;
1058 * (Changes / copies a user, part II)
1060 if (isset($_REQUEST['adduser_submit']) ||
isset($_REQUEST['change_copy'])) {
1062 if ($pred_username == 'any') {
1065 switch ($pred_hostname) {
1070 $hostname = 'localhost';
1076 $_user_name = PMA_DBI_fetch_value('SELECT USER()');
1077 $hostname = substr($_user_name, (strrpos($_user_name, '@') +
1));
1081 $sql = "SELECT '1' FROM `mysql`.`user`"
1082 . " WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'"
1083 . " AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "';";
1084 if (PMA_DBI_fetch_value($sql) == 1) {
1085 $message = PMA_Message
::error(__('The user %s already exists!'));
1086 $message->addParam('[i]\'' . $username . '\'@\'' . $hostname . '\'[/i]');
1087 $_REQUEST['adduser'] = true;
1088 $_add_user_error = true;
1091 $create_user_real = 'CREATE USER \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\'';
1093 $real_sql_query = 'GRANT ' . join(', ', PMA_extractPrivInfo()) . ' ON *.* TO \''
1094 . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\'';
1095 if ($pred_password != 'none' && $pred_password != 'keep') {
1096 $sql_query = $real_sql_query . ' IDENTIFIED BY \'***\'';
1097 $real_sql_query .= ' IDENTIFIED BY \'' . PMA_sqlAddSlashes($pma_pw) . '\'';
1098 if (isset($create_user_real)) {
1099 $create_user_show = $create_user_real . ' IDENTIFIED BY \'***\'';
1100 $create_user_real .= ' IDENTIFIED BY \'' . PMA_sqlAddSlashes($pma_pw) . '\'';
1103 if ($pred_password == 'keep' && ! empty($password)) {
1104 $real_sql_query .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
1105 if (isset($create_user_real)) {
1106 $create_user_real .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
1109 $sql_query = $real_sql_query;
1110 if (isset($create_user_real)) {
1111 $create_user_show = $create_user_real;
1115 * @todo similar code appears twice in this script
1117 if ((isset($Grant_priv) && $Grant_priv == 'Y')
1118 ||
(isset($max_questions) ||
isset($max_connections)
1119 ||
isset($max_updates) ||
isset($max_user_connections))
1121 $real_sql_query .= ' WITH';
1122 $sql_query .= ' WITH';
1123 if (isset($Grant_priv) && $Grant_priv == 'Y') {
1124 $real_sql_query .= ' GRANT OPTION';
1125 $sql_query .= ' GRANT OPTION';
1127 if (isset($max_questions)) {
1128 // avoid negative values
1129 $max_questions = max(0, (int)$max_questions);
1130 $real_sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
1131 $sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
1133 if (isset($max_connections)) {
1134 $max_connections = max(0, (int)$max_connections);
1135 $real_sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
1136 $sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
1138 if (isset($max_updates)) {
1139 $max_updates = max(0, (int)$max_updates);
1140 $real_sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
1141 $sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
1143 if (isset($max_user_connections)) {
1144 $max_user_connections = max(0, (int)$max_user_connections);
1145 $real_sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
1146 $sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
1149 if (isset($create_user_real)) {
1150 $create_user_real .= ';';
1151 $create_user_show .= ';';
1153 $real_sql_query .= ';';
1155 if (empty($_REQUEST['change_copy'])) {
1158 if (isset($create_user_real)) {
1159 if (! PMA_DBI_try_query($create_user_real)) {
1162 $sql_query = $create_user_show . $sql_query;
1165 if ($_error ||
! PMA_DBI_try_query($real_sql_query)) {
1166 $_REQUEST['createdb-1'] = $_REQUEST['createdb-2'] = $_REQUEST['createdb-3'] = false;
1167 $message = PMA_Message
::rawError(PMA_DBI_getError());
1169 $message = PMA_Message
::success(__('You have added a new user.'));
1172 if (isset($_REQUEST['createdb-1'])) {
1173 // Create database with same name and grant all privileges
1174 $q = 'CREATE DATABASE IF NOT EXISTS '
1175 . PMA_backquote(PMA_sqlAddSlashes($username)) . ';';
1177 if (! PMA_DBI_try_query($q)) {
1178 $message = PMA_Message
::rawError(PMA_DBI_getError());
1183 * If we are not in an Ajax request, we can't reload navigation now
1185 if ($GLOBALS['is_ajax_request'] != true) {
1186 // this is needed in case tracking is on:
1187 $GLOBALS['db'] = $username;
1188 $GLOBALS['reload'] = true;
1189 PMA_reloadNavigation();
1192 $q = 'GRANT ALL PRIVILEGES ON '
1193 . PMA_backquote(PMA_escape_mysql_wildcards(PMA_sqlAddSlashes($username))) . '.* TO \''
1194 . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';';
1196 if (! PMA_DBI_try_query($q)) {
1197 $message = PMA_Message
::rawError(PMA_DBI_getError());
1201 if (isset($_REQUEST['createdb-2'])) {
1202 // Grant all privileges on wildcard name (username\_%)
1203 $q = 'GRANT ALL PRIVILEGES ON '
1204 . PMA_backquote(PMA_sqlAddSlashes($username) . '\_%') . '.* TO \''
1205 . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';';
1207 if (! PMA_DBI_try_query($q)) {
1208 $message = PMA_Message
::rawError(PMA_DBI_getError());
1212 if (isset($_REQUEST['createdb-3'])) {
1213 // Grant all privileges on the specified database to the new user
1214 $q = 'GRANT ALL PRIVILEGES ON '
1215 . PMA_backquote(PMA_sqlAddSlashes($dbname)) . '.* TO \''
1216 . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';';
1218 if (! PMA_DBI_try_query($q)) {
1219 $message = PMA_Message
::rawError(PMA_DBI_getError());
1223 if (isset($create_user_real)) {
1224 $queries[] = $create_user_real;
1226 $queries[] = $real_sql_query;
1227 // we put the query containing the hidden password in
1228 // $queries_for_display, at the same position occupied
1229 // by the real query in $queries
1230 $tmp_count = count($queries);
1231 if (isset($create_user_real)) {
1232 $queries_for_display[$tmp_count - 2] = $create_user_show;
1234 $queries_for_display[$tmp_count - 1] = $sql_query;
1236 unset($res, $real_sql_query);
1242 * Changes / copies a user, part III
1244 if (isset($_REQUEST['change_copy'])) {
1245 $user_host_condition = ' WHERE `User`'
1246 .' = \'' . PMA_sqlAddSlashes($old_username) . "'"
1248 .' = \'' . PMA_sqlAddSlashes($old_hostname) . '\';';
1249 $res = PMA_DBI_query('SELECT * FROM `mysql`.`db`' . $user_host_condition);
1250 while ($row = PMA_DBI_fetch_assoc($res)) {
1251 $queries[] = 'GRANT ' . join(', ', PMA_extractPrivInfo($row))
1252 .' ON ' . PMA_backquote($row['Db']) . '.*'
1253 .' TO \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\''
1254 . ($row['Grant_priv'] == 'Y' ?
' WITH GRANT OPTION;' : ';');
1256 PMA_DBI_free_result($res);
1257 $res = PMA_DBI_query(
1258 'SELECT `Db`, `Table_name`, `Table_priv` FROM `mysql`.`tables_priv`' . $user_host_condition,
1259 $GLOBALS['userlink'],
1262 while ($row = PMA_DBI_fetch_assoc($res)) {
1264 $res2 = PMA_DBI_QUERY(
1265 'SELECT `Column_name`, `Column_priv`'
1266 .' FROM `mysql`.`columns_priv`'
1268 .' = \'' . PMA_sqlAddSlashes($old_username) . "'"
1270 .' = \'' . PMA_sqlAddSlashes($old_hostname) . '\''
1272 .' = \'' . PMA_sqlAddSlashes($row['Db']) . "'"
1273 .' AND `Table_name`'
1274 .' = \'' . PMA_sqlAddSlashes($row['Table_name']) . "'"
1280 $tmp_privs1 = PMA_extractPrivInfo($row);
1281 $tmp_privs2 = array(
1282 'Select' => array(),
1283 'Insert' => array(),
1284 'Update' => array(),
1285 'References' => array()
1288 while ($row2 = PMA_DBI_fetch_assoc($res2)) {
1289 $tmp_array = explode(',', $row2['Column_priv']);
1290 if (in_array('Select', $tmp_array)) {
1291 $tmp_privs2['Select'][] = $row2['Column_name'];
1293 if (in_array('Insert', $tmp_array)) {
1294 $tmp_privs2['Insert'][] = $row2['Column_name'];
1296 if (in_array('Update', $tmp_array)) {
1297 $tmp_privs2['Update'][] = $row2['Column_name'];
1299 if (in_array('References', $tmp_array)) {
1300 $tmp_privs2['References'][] = $row2['Column_name'];
1304 if (count($tmp_privs2['Select']) > 0 && ! in_array('SELECT', $tmp_privs1)) {
1305 $tmp_privs1[] = 'SELECT (`' . join('`, `', $tmp_privs2['Select']) . '`)';
1307 if (count($tmp_privs2['Insert']) > 0 && ! in_array('INSERT', $tmp_privs1)) {
1308 $tmp_privs1[] = 'INSERT (`' . join('`, `', $tmp_privs2['Insert']) . '`)';
1310 if (count($tmp_privs2['Update']) > 0 && ! in_array('UPDATE', $tmp_privs1)) {
1311 $tmp_privs1[] = 'UPDATE (`' . join('`, `', $tmp_privs2['Update']) . '`)';
1313 if (count($tmp_privs2['References']) > 0 && ! in_array('REFERENCES', $tmp_privs1)) {
1314 $tmp_privs1[] = 'REFERENCES (`' . join('`, `', $tmp_privs2['References']) . '`)';
1317 $queries[] = 'GRANT ' . join(', ', $tmp_privs1)
1318 . ' ON ' . PMA_backquote($row['Db']) . '.' . PMA_backquote($row['Table_name'])
1319 . ' TO \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\''
1320 . (in_array('Grant', explode(',', $row['Table_priv'])) ?
' WITH GRANT OPTION;' : ';');
1326 * Updates privileges
1328 if (! empty($update_privs)) {
1329 $db_and_table = PMA_wildcardEscapeForGrant($dbname, (isset($tablename) ?
$tablename : ''));
1331 $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
1332 . ' FROM \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';';
1333 if (! isset($Grant_priv) ||
$Grant_priv != 'Y') {
1334 $sql_query1 = 'REVOKE GRANT OPTION ON ' . $db_and_table
1335 . ' FROM \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';';
1340 // Should not do a GRANT USAGE for a table-specific privilege, it
1341 // causes problems later (cannot revoke it)
1342 if (! (isset($tablename) && 'USAGE' == implode('', PMA_extractPrivInfo()))) {
1343 $sql_query2 = 'GRANT ' . join(', ', PMA_extractPrivInfo())
1344 . ' ON ' . $db_and_table
1345 . ' TO \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\'';
1348 * @todo similar code appears twice in this script
1350 if ((isset($Grant_priv) && $Grant_priv == 'Y')
1351 ||
(! isset($dbname)
1352 && (isset($max_questions) ||
isset($max_connections)
1353 ||
isset($max_updates) ||
isset($max_user_connections)))
1355 $sql_query2 .= 'WITH';
1356 if (isset($Grant_priv) && $Grant_priv == 'Y') {
1357 $sql_query2 .= ' GRANT OPTION';
1359 if (isset($max_questions)) {
1360 $max_questions = max(0, (int)$max_questions);
1361 $sql_query2 .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
1363 if (isset($max_connections)) {
1364 $max_connections = max(0, (int)$max_connections);
1365 $sql_query2 .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
1367 if (isset($max_updates)) {
1368 $max_updates = max(0, (int)$max_updates);
1369 $sql_query2 .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
1371 if (isset($max_user_connections)) {
1372 $max_user_connections = max(0, (int)$max_user_connections);
1373 $sql_query2 .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
1378 if (! PMA_DBI_try_query($sql_query0)) {
1379 // This might fail when the executing user does not have ALL PRIVILEGES himself.
1380 // See https://sourceforge.net/tracker/index.php?func=detail&aid=3285929&group_id=23067&atid=377408
1383 if (isset($sql_query1) && ! PMA_DBI_try_query($sql_query1)) {
1384 // this one may fail, too...
1387 if (isset($sql_query2)) {
1388 PMA_DBI_query($sql_query2);
1392 $sql_query = $sql_query0 . ' ' . $sql_query1 . ' ' . $sql_query2;
1393 $message = PMA_Message
::success(__('You have updated the privileges for %s.'));
1394 $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'');
1399 * Revokes Privileges
1401 if (isset($_REQUEST['revokeall'])) {
1402 $db_and_table = PMA_wildcardEscapeForGrant($dbname, isset($tablename) ?
$tablename : '');
1404 $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
1405 . ' FROM \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';';
1406 $sql_query1 = 'REVOKE GRANT OPTION ON ' . $db_and_table
1407 . ' FROM \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';';
1409 PMA_DBI_query($sql_query0);
1410 if (! PMA_DBI_try_query($sql_query1)) {
1411 // this one may fail, too...
1414 $sql_query = $sql_query0 . ' ' . $sql_query1;
1415 $message = PMA_Message
::success(__('You have revoked the privileges for %s'));
1416 $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'');
1417 if (! isset($tablename)) {
1426 * Updates the password
1428 if (isset($_REQUEST['change_pw'])) {
1429 // similar logic in user_password.php
1432 if ($nopass == 0 && isset($pma_pw) && isset($pma_pw2)) {
1433 if ($pma_pw != $pma_pw2) {
1434 $message = PMA_Message
::error(__('The passwords aren\'t the same!'));
1435 } elseif (empty($pma_pw) ||
empty($pma_pw2)) {
1436 $message = PMA_Message
::error(__('The password is empty!'));
1440 // here $nopass could be == 1
1441 if (empty($message)) {
1443 $hashing_function = (! empty($pw_hash) && $pw_hash == 'old' ?
'OLD_' : '')
1446 // in $sql_query which will be displayed, hide the password
1447 $sql_query = 'SET PASSWORD FOR \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\' = ' . (($pma_pw == '') ?
'\'\'' : $hashing_function . '(\'' . preg_replace('@.@s', '*', $pma_pw) . '\')');
1448 $local_query = 'SET PASSWORD FOR \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\' = ' . (($pma_pw == '') ?
'\'\'' : $hashing_function . '(\'' . PMA_sqlAddSlashes($pma_pw) . '\')');
1449 PMA_DBI_try_query($local_query)
1450 or PMA_mysqlDie(PMA_DBI_getError(), $sql_query, false, $err_url);
1451 $message = PMA_Message
::success(__('The password for %s was changed successfully.'));
1452 $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'');
1459 * (Changes / copies a user, part IV)
1462 if (isset($_REQUEST['delete']) ||
(isset($_REQUEST['change_copy']) && $_REQUEST['mode'] < 4)) {
1463 if (isset($_REQUEST['change_copy'])) {
1464 $selected_usr = array($old_username . '&#27;' . $old_hostname);
1466 $selected_usr = $_REQUEST['selected_usr'];
1469 foreach ($selected_usr as $each_user) {
1470 list($this_user, $this_host) = explode('&#27;', $each_user);
1471 $queries[] = '# ' . sprintf(__('Deleting %s'), '\'' . $this_user . '\'@\'' . $this_host . '\'') . ' ...';
1472 $queries[] = 'DROP USER \'' . PMA_sqlAddSlashes($this_user) . '\'@\'' . PMA_sqlAddSlashes($this_host) . '\';';
1474 if (isset($_REQUEST['drop_users_db'])) {
1475 $queries[] = 'DROP DATABASE IF EXISTS ' . PMA_backquote($this_user) . ';';
1476 $GLOBALS['reload'] = true;
1478 if ($GLOBALS['is_ajax_request'] != true) {
1479 PMA_reloadNavigation();
1483 if (empty($_REQUEST['change_copy'])) {
1484 if (empty($queries)) {
1485 $message = PMA_Message
::error(__('No users selected for deleting!'));
1487 if ($_REQUEST['mode'] == 3) {
1488 $queries[] = '# ' . __('Reloading the privileges') . ' ...';
1489 $queries[] = 'FLUSH PRIVILEGES;';
1491 $drop_user_error = '';
1492 foreach ($queries as $sql_query) {
1493 if ($sql_query{0} != '#') {
1494 if (! PMA_DBI_try_query($sql_query, $GLOBALS['userlink'])) {
1495 $drop_user_error .= PMA_DBI_getError() . "\n";
1499 // tracking sets this, causing the deleted db to be shown in navi
1500 unset($GLOBALS['db']);
1502 $sql_query = join("\n", $queries);
1503 if (! empty($drop_user_error)) {
1504 $message = PMA_Message
::rawError($drop_user_error);
1506 $message = PMA_Message
::success(__('The selected users have been deleted successfully.'));
1515 * Changes / copies a user, part V
1517 if (isset($_REQUEST['change_copy'])) {
1519 foreach ($queries as $sql_query) {
1520 if ($sql_query{0} != '#') {
1521 PMA_DBI_query($sql_query);
1523 // when there is a query containing a hidden password, take it
1524 // instead of the real query sent
1525 if (isset($queries_for_display[$tmp_count])) {
1526 $queries[$tmp_count] = $queries_for_display[$tmp_count];
1530 $message = PMA_Message
::success();
1531 $sql_query = join("\n", $queries);
1536 * Reloads the privilege tables into memory
1538 if (isset($_REQUEST['flush_privileges'])) {
1539 $sql_query = 'FLUSH PRIVILEGES;';
1540 PMA_DBI_query($sql_query);
1541 $message = PMA_Message
::success(__('The privileges were reloaded successfully.'));
1545 * defines some standard links
1547 $link_edit = '<a class="edit_user_anchor ' . $conditional_class . '" href="server_privileges.php?' . str_replace('%', '%%', $GLOBALS['url_query'])
1548 . '&username=%s'
1549 . '&hostname=%s'
1551 . '&tablename=%s">'
1552 . PMA_getIcon('b_usredit.png', __('Edit Privileges'))
1555 $link_revoke = '<a href="server_privileges.php?' . str_replace('%', '%%', $GLOBALS['url_query'])
1556 . '&username=%s'
1557 . '&hostname=%s'
1559 . '&tablename=%s'
1560 . '&revokeall=1">'
1561 . PMA_getIcon('b_usrdrop.png', __('Revoke'))
1564 $link_export = '<a class="export_user_anchor ' . $conditional_class . '" href="server_privileges.php?' . str_replace('%', '%%', $GLOBALS['url_query'])
1565 . '&username=%s'
1566 . '&hostname=%s'
1569 . PMA_getIcon('b_tblexport.png', __('Export'))
1572 $link_export_all = '<a class="export_user_anchor ' . $conditional_class . '" href="server_privileges.php?' . str_replace('%', '%%', $GLOBALS['url_query'])
1573 . '&username=%s'
1574 . '&hostname=%s'
1577 . PMA_getIcon('b_tblexport.png', __('Export all'))
1581 * If we are in an Ajax request for Create User/Edit User/Revoke User/
1582 * Flush Privileges, show $message and exit.
1584 if ($GLOBALS['is_ajax_request'] && ! isset($_REQUEST['export']) && (! isset($_REQUEST['submit_mult']) ||
$_REQUEST['submit_mult'] != 'export') && (! isset($_REQUEST['adduser']) ||
$_add_user_error) && (! isset($_REQUEST['initial']) ||
empty($_REQUEST['initial'])) && ! isset($_REQUEST['showall']) && ! isset($_REQUEST['edit_user_dialog']) && ! isset($_REQUEST['db_specific'])) {
1586 if (isset($sql_query)) {
1587 $extra_data['sql_query'] = PMA_showMessage(null, $sql_query);
1590 if (isset($_REQUEST['adduser_submit']) ||
isset($_REQUEST['change_copy'])) {
1592 * generate html on the fly for the new user that was just created.
1594 $new_user_string = '<tr>'."\n"
1595 .'<td> <input type="checkbox" name="selected_usr[]" id="checkbox_sel_users_" value="' . htmlspecialchars($username) . '&#27;' . htmlspecialchars($hostname) . '" /> </td>' . "\n"
1596 .'<td><label for="checkbox_sel_users_">' . (empty($username) ?
'<span style="color: #FF0000">' . __('Any') . '</span>' : htmlspecialchars($username) ) . '</label></td>' . "\n"
1597 .'<td>' . htmlspecialchars($hostname) . '</td>' . "\n";
1598 $new_user_string .= '<td>';
1600 if (! empty($password) ||
isset($pma_pw)) {
1601 $new_user_string .= __('Yes');
1603 $new_user_string .= '<span style="color: #FF0000">' . __('No') . '</span>';
1606 $new_user_string .= '</td>'."\n";
1607 $new_user_string .= '<td><code>' . join(', ', PMA_extractPrivInfo('', true)) . '</code></td>'; //Fill in privileges here
1608 $new_user_string .= '<td>';
1610 if ((isset($Grant_priv) && $Grant_priv == 'Y')) {
1611 $new_user_string .= __('Yes');
1613 $new_user_string .= __('No');
1616 $new_user_string .='</td>';
1618 $new_user_string .= '<td>' . sprintf($link_edit, urlencode($username), urlencode($hostname), '', '') . '</td>' . "\n";
1619 $new_user_string .= '<td>' . sprintf($link_export, urlencode($username), urlencode($hostname), (isset($initial) ?
$initial : '')) . '</td>' . "\n";
1621 $new_user_string .= '</tr>';
1623 $extra_data['new_user_string'] = $new_user_string;
1626 * Generate the string for this alphabet's initial, to update the user
1629 $new_user_initial = strtoupper(substr($username, 0, 1));
1630 $new_user_initial_string = '<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&initial=' . $new_user_initial
1631 .'">' . $new_user_initial . '</a>';
1632 $extra_data['new_user_initial'] = $new_user_initial;
1633 $extra_data['new_user_initial_string'] = $new_user_initial_string;
1636 if (isset($update_privs)) {
1637 $extra_data['db_specific_privs'] = false;
1638 if (isset($dbname_is_wildcard)) {
1639 $extra_data['db_specific_privs'] = ! $dbname_is_wildcard;
1641 $new_privileges = join(', ', PMA_extractPrivInfo('', true));
1643 $extra_data['new_privileges'] = $new_privileges;
1646 if ($message instanceof PMA_Message
) {
1647 PMA_ajaxResponse($message, $message->isSuccess(), $extra_data);
1652 * Displays the links
1654 if (isset($viewing_mode) && $viewing_mode == 'db') {
1656 $url_query .= '&goto=db_operations.php';
1658 // Gets the database structure
1659 $sub_part = '_structure';
1660 include 'libraries/db_info.inc.php';
1663 include 'libraries/server_links.inc.php';
1671 // export user definition
1672 if (isset($_REQUEST['export']) ||
(isset($_REQUEST['submit_mult']) && $_REQUEST['submit_mult'] == 'export')) {
1673 $response = '<textarea class="export" cols="' . $GLOBALS['cfg']['TextareaCols'] . '" rows="' . $GLOBALS['cfg']['TextareaRows'] . '">';
1674 if ($username == '%') {
1675 // export privileges for all users
1676 $title = __('Privileges for all users');
1677 foreach ($_SESSION['user_host_pairs'] as $pair) {
1678 $response .= PMA_getGrants($pair['user'], $pair['host']);
1681 } elseif (isset($_REQUEST['selected_usr'])) {
1682 // export privileges for selected users
1683 $title = __('Privileges');
1684 foreach ($_REQUEST['selected_usr'] as $export_user) {
1685 $export_username = substr($export_user, 0, strpos($export_user, '&'));
1686 $export_hostname = substr($export_user, strrpos($export_user, ';') +
1);
1689 __('Privileges for %s'),
1690 '`' . htmlspecialchars($export_username) . '`@`' . htmlspecialchars($export_hostname) . '`'
1693 $response .= PMA_getGrants($export_username, $export_hostname) . "\n";
1696 // export privileges for a single user
1697 $title = __('User') . ' `' . htmlspecialchars($username) . '`@`' . htmlspecialchars($hostname) . '`';
1698 $response .= PMA_getGrants($username, $hostname);
1700 // remove trailing whitespace
1701 $response = trim($response);
1703 $response .= '</textarea>';
1704 unset($username, $hostname, $grants, $one_grant);
1705 if ($GLOBALS['is_ajax_request']) {
1706 PMA_ajaxResponse($response, 1, array('title' => $title));
1708 echo "<h2>$title</h2>$response";
1712 if (empty($_REQUEST['adduser']) && (! isset($checkprivs) ||
! strlen($checkprivs))) {
1713 if (! isset($username)) {
1714 // No username is given --> display the overview
1716 . PMA_getIcon('b_usrlist.png')
1717 . __('Users overview') . "\n"
1720 $sql_query = 'SELECT *,' .
1721 " IF(`Password` = _latin1 '', 'N', 'Y') AS 'Password'" .
1722 ' FROM `mysql`.`user`';
1724 $sql_query .= (isset($initial) ?
PMA_rangeOfUsers($initial) : '');
1726 $sql_query .= ' ORDER BY `User` ASC, `Host` ASC;';
1727 $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE
);
1730 // the query failed! This may have two reasons:
1731 // - the user does not have enough privileges
1732 // - the privilege tables use a structure of an earlier version.
1733 // so let's try a more simple query
1735 $sql_query = 'SELECT * FROM `mysql`.`user`';
1736 $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE
);
1739 PMA_Message
::error(__('No Privileges'))->display();
1740 PMA_DBI_free_result($res);
1743 // This message is hardcoded because I will replace it by
1744 // a automatic repair feature soon.
1745 $raw = 'Your privilege table structure seems to be older than'
1746 . ' this MySQL version!<br />'
1747 . 'Please run the <code>mysql_upgrade</code> command'
1748 . '(<code>mysql_fix_privilege_tables</code> on older systems)'
1749 . ' that should be included in your MySQL server distribution'
1750 . ' to solve this problem!';
1751 PMA_Message
::rawError($raw)->display();
1755 // we also want users not in table `user` but in other table
1756 $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;');
1758 $tables_to_search_for_users = array(
1759 'user', 'db', 'tables_priv', 'columns_priv', 'procs_priv',
1762 $db_rights_sqls = array();
1763 foreach ($tables_to_search_for_users as $table_search_in) {
1764 if (in_array($table_search_in, $tables)) {
1765 $db_rights_sqls[] = 'SELECT DISTINCT `User`, `Host` FROM `mysql`.`' . $table_search_in . '` ' . (isset($initial) ?
PMA_rangeOfUsers($initial) : '');
1769 $user_defaults = array(
1773 'Grant_priv' => 'N',
1774 'privs' => array('USAGE'),
1777 // for all initials, even non A-Z
1778 $array_initials = array();
1780 $db_rights = array();
1782 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
1783 .' ORDER BY `User` ASC, `Host` ASC';
1785 $db_rights_result = PMA_DBI_query($db_rights_sql);
1787 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
1788 $db_rights_row = array_merge($user_defaults, $db_rights_row);
1789 $db_rights[$db_rights_row['User']][$db_rights_row['Host']]
1792 PMA_DBI_free_result($db_rights_result);
1793 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
1797 * Displays the initials
1798 * In an Ajax request, we don't need to show this.
1799 * Also not necassary if there is less than 20 privileges
1801 if ($GLOBALS['is_ajax_request'] != true && PMA_DBI_num_rows($res) > 20 ) {
1803 // initialize to false the letters A-Z
1804 for ($letter_counter = 1; $letter_counter < 27; $letter_counter++
) {
1805 if (! isset($array_initials[chr($letter_counter +
64)])) {
1806 $array_initials[chr($letter_counter +
64)] = false;
1810 $initials = PMA_DBI_try_query('SELECT DISTINCT UPPER(LEFT(`User`,1)) FROM `user` ORDER BY `User` ASC', null, PMA_DBI_QUERY_STORE
);
1811 while (list($tmp_initial) = PMA_DBI_fetch_row($initials)) {
1812 $array_initials[$tmp_initial] = true;
1815 // Display the initials, which can be any characters, not
1816 // just letters. For letters A-Z, we add the non-used letters
1819 uksort($array_initials, "strnatcasecmp");
1821 echo '<table id="initials_table" class="' . $conditional_class . '" <cellspacing="5"><tr>';
1822 foreach ($array_initials as $tmp_initial => $initial_was_found) {
1823 if ($initial_was_found) {
1824 echo '<td><a href="server_privileges.php?' . $GLOBALS['url_query'] . '&initial=' . urlencode($tmp_initial) . '">' . $tmp_initial . '</a></td>' . "\n";
1826 echo '<td>' . $tmp_initial . '</td>';
1829 echo '<td><a href="server_privileges.php?' . $GLOBALS['url_query'] . '&showall=1" class="nowrap">[' . __('Show all') . ']</a></td>' . "\n";
1830 echo '</tr></table>';
1834 * Display the user overview
1835 * (if less than 50 users, display them immediately)
1838 if (isset($initial) ||
isset($showall) ||
PMA_DBI_num_rows($res) < 50) {
1840 while ($row = PMA_DBI_fetch_assoc($res)) {
1841 $row['privs'] = PMA_extractPrivInfo($row, true);
1842 $db_rights[$row['User']][$row['Host']] = $row;
1844 @PMA_DBI_free_result
($res);
1847 echo '<form name="usersForm" id="usersForm" action="server_privileges.php" method="post">' . "\n"
1848 . PMA_generate_common_hidden_inputs('', '')
1849 . ' <table id="tableuserrights" class="data">' . "\n"
1851 . ' <tr><th></th>' . "\n"
1852 . ' <th>' . __('User') . '</th>' . "\n"
1853 . ' <th>' . __('Host') . '</th>' . "\n"
1854 . ' <th>' . __('Password') . '</th>' . "\n"
1855 . ' <th>' . __('Global privileges') . ' '
1856 . PMA_showHint(__('Note: MySQL privilege names are expressed in English')) . '</th>' . "\n"
1857 . ' <th>' . __('Grant') . '</th>' . "\n"
1858 . ' <th colspan="2">' . __('Action') . '</th>' . "\n";
1859 echo ' </tr>' . "\n";
1860 echo ' </thead>' . "\n";
1861 echo ' <tbody>' . "\n";
1863 $_SESSION['user_host_pairs'] = array();
1866 $index_checkbox = -1;
1867 foreach ($db_rights as $user) {
1870 foreach ($user as $host) {
1872 echo ' <tr class="' . ($odd_row ?
'odd' : 'even') . '">' . "\n"
1873 . ' <td><input type="checkbox" name="selected_usr[]" id="checkbox_sel_users_'
1874 . $index_checkbox . '" value="'
1875 . htmlspecialchars($host['User'] . '&#27;' . $host['Host'])
1877 . (empty($GLOBALS['checkall']) ?
'' : ' checked="checked"')
1879 . ' <td><label for="checkbox_sel_users_' . $index_checkbox . '">' . (empty($host['User']) ?
'<span style="color: #FF0000">' . __('Any') . '</span>' : htmlspecialchars($host['User'])) . '</label></td>' . "\n"
1880 . ' <td>' . htmlspecialchars($host['Host']) . '</td>' . "\n";
1882 switch ($host['Password']) {
1887 echo '<span style="color: #FF0000">' . __('No') . '</span>';
1889 // this happens if this is a definition not coming from mysql.user
1891 echo '--'; // in future version, replace by "not present"
1895 . ' <td><code>' . "\n"
1896 . ' ' . implode(',' . "\n" . ' ', $host['privs']) . "\n"
1897 . ' </code></td>' . "\n"
1898 . ' <td>' . ($host['Grant_priv'] == 'Y' ?
__('Yes') : __('No')) . '</td>' . "\n"
1899 . ' <td class="center">';
1900 printf($link_edit, urlencode($host['User']), urlencode($host['Host']), '', '');
1902 echo '<td class="center">';
1903 printf($link_export, urlencode($host['User']), urlencode($host['Host']), (isset($initial) ?
$initial : ''));
1906 $odd_row = ! $odd_row;
1908 $_SESSION['user_host_pairs'][$pair_count]['user'] = $host['User'];
1909 $_SESSION['user_host_pairs'][$pair_count]['host'] = $host['Host'];
1914 unset($user, $host, $odd_row);
1915 echo ' </tbody></table>' . "\n"
1917 .'<div style="float:left;">'
1918 .'<img class="selectallarrow"'
1919 .' src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png"'
1920 .' width="38" height="22"'
1921 .' alt="' . __('With selected:') . '" />' . "\n"
1922 .'<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&checkall=1"'
1923 .' onclick="if (markAllRows(\'usersForm\')) return false;">'
1924 . __('Check All') . '</a>' . "\n"
1926 .'<a href="server_privileges.php?' . $GLOBALS['url_query'] . '"'
1927 .' onclick="if (unMarkAllRows(\'usersForm\')) return false;">'
1928 . __('Uncheck All') . '</a>' . "\n"
1929 .'<i>' . __('With selected:') . '</i>' . "\n";
1932 'submit_mult', 'mult_submit', 'submit_mult_export',
1933 __('Export'), 'b_tblexport.png', 'export'
1935 echo '<input type="hidden" name="initial" value="' . (isset($initial) ?
$initial : '') . '" />';
1937 . '<div class="clear_both" style="clear:both"></div>'
1938 . '<div style="float:left; padding-left:10px;">';
1939 printf($link_export_all, urlencode('%'), urlencode('%'), (isset($initial) ?
$initial : ''));
1942 . '<div class="clear_both" style="clear:both"></div>';
1944 // add/delete user fieldset
1945 echo ' <fieldset id="fieldset_add_user">' . "\n"
1946 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&adduser=1" class="' . $conditional_class . '">' . "\n"
1947 . PMA_getIcon('b_usradd.png')
1948 . ' ' . __('Add user') . '</a>' . "\n"
1949 . ' </fieldset>' . "\n"
1950 . ' <fieldset id="fieldset_delete_user">'
1951 . ' <legend>' . "\n"
1952 . PMA_getIcon('b_usrdrop.png')
1953 . ' ' . __('Remove selected users') . '' . "\n"
1954 . ' </legend>' . "\n"
1955 . ' <input type="hidden" name="mode" value="2" />' . "\n"
1956 . '(' . __('Revoke all active privileges from the users and delete them afterwards.') . ')<br />' . "\n"
1957 . ' <input type="checkbox" title="' . __('Drop the databases that have the same names as the users.') . '" name="drop_users_db" id="checkbox_drop_users_db" />' . "\n"
1958 . ' <label for="checkbox_drop_users_db" title="' . __('Drop the databases that have the same names as the users.') . '">' . "\n"
1959 . ' ' . __('Drop the databases that have the same names as the users.') . "\n"
1960 . ' </label>' . "\n"
1961 . ' </fieldset>' . "\n"
1962 . ' <fieldset id="fieldset_delete_user_footer" class="tblFooters">' . "\n"
1963 . ' <input type="submit" name="delete" value="' . __('Go') . '" id="buttonGo" class="' . $conditional_class . '"/>' . "\n"
1964 . ' </fieldset>' . "\n"
1969 echo ' <fieldset id="fieldset_add_user">' . "\n"
1970 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&adduser=1" class="' . $conditional_class . '">' . "\n"
1971 . PMA_getIcon('b_usradd.png')
1972 . ' ' . __('Add user') . '</a>' . "\n"
1973 . ' </fieldset>' . "\n";
1974 } // end if (display overview)
1976 if ($GLOBALS['is_ajax_request']) {
1980 $flushnote = new PMA_Message(__('Note: phpMyAdmin gets the users\' privileges directly from MySQL\'s privilege tables. The content of these tables may differ from the privileges the server uses, if they have been changed manually. In this case, you should %sreload the privileges%s before you continue.'), PMA_Message
::NOTICE
);
1981 $flushnote->addParam('<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&flush_privileges=1" id="reload_privileges_anchor" class="' . $conditional_class . '">', false);
1982 $flushnote->addParam('</a>', false);
1983 $flushnote->display();
1989 // A user was selected -> display the user's properties
1991 // In an Ajax request, prevent cached values from showing
1992 if ($GLOBALS['is_ajax_request'] == true) {
1993 header('Cache-Control: no-cache');
1997 . PMA_getIcon('b_usredit.png')
1998 . __('Edit Privileges') . ': '
2001 if (isset($dbname)) {
2002 echo ' <i><a href="server_privileges.php?'
2003 . $GLOBALS['url_query'] . '&username=' . htmlspecialchars(urlencode($username))
2004 . '&hostname=' . htmlspecialchars(urlencode($hostname)) . '&dbname=&tablename=">\''
2005 . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname)
2006 . '\'</a></i>' . "\n";
2007 $url_dbname = urlencode(str_replace(array('\_', '\%'), array('_', '%'), $dbname));
2009 echo ' - ' . ($dbname_is_wildcard ?
__('Databases') : __('Database') );
2010 if (isset($tablename)) {
2011 echo ' <i><a href="server_privileges.php?' . $GLOBALS['url_query']
2012 . '&username=' . htmlspecialchars(urlencode($username)) . '&hostname=' . htmlspecialchars(urlencode($hostname))
2013 . '&dbname=' . htmlspecialchars($url_dbname) . '&tablename=">' . htmlspecialchars($dbname) . '</a></i>';
2014 echo ' - ' . __('Table') . ' <i>' . htmlspecialchars($tablename) . '</i>';
2016 echo ' <i>' . htmlspecialchars($dbname) . '</i>';
2020 echo ' <i>\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname)
2024 echo '</h2>' . "\n";
2027 $sql = "SELECT '1' FROM `mysql`.`user`"
2028 . " WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'"
2029 . " AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "';";
2030 $user_does_not_exists = (bool) ! PMA_DBI_fetch_value($sql);
2032 if ($user_does_not_exists) {
2033 PMA_Message
::error(__('The selected user was not found in the privilege table.'))->display();
2034 PMA_displayLoginInformationFields();
2035 //require 'libraries/footer.inc.php';
2038 echo '<form name="usersForm" id="addUsersForm_' . $random_n . '" action="server_privileges.php" method="post">' . "\n";
2040 'username' => $username,
2041 'hostname' => $hostname,
2043 if (isset($dbname)) {
2044 $_params['dbname'] = $dbname;
2045 if (isset($tablename)) {
2046 $_params['tablename'] = $tablename;
2049 echo PMA_generate_common_hidden_inputs($_params);
2051 PMA_displayPrivTable(
2052 PMA_ifSetOr($dbname, '*', 'length'),
2053 PMA_ifSetOr($tablename, '*', 'length')
2056 echo '</form>' . "\n";
2058 if (! isset($tablename) && empty($dbname_is_wildcard)) {
2060 // no table name was given, display all table specific rights
2061 // but only if $dbname contains no wildcards
2064 echo '<form action="server_privileges.php" id="db_or_table_specific_priv" method="post">' . "\n"
2065 . PMA_generate_common_hidden_inputs('', '')
2066 . '<input type="hidden" name="username" value="' . htmlspecialchars($username) . '" />' . "\n"
2067 . '<input type="hidden" name="hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n"
2068 . '<fieldset>' . "\n"
2069 . '<legend>' . (! isset($dbname) ?
__('Database-specific privileges') : __('Table-specific privileges')) . '</legend>' . "\n"
2070 . '<table class="data">' . "\n"
2072 . '<tr><th>' . (! isset($dbname) ?
__('Database') : __('Table')) . '</th>' . "\n"
2073 . ' <th>' . __('Privileges') . '</th>' . "\n"
2074 . ' <th>' . __('Grant') . '</th>' . "\n"
2075 . ' <th>' . (! isset($dbname) ?
__('Table-specific privileges') : __('Column-specific privileges')) . '</th>' . "\n"
2076 . ' <th colspan="2">' . __('Action') . '</th>' . "\n"
2081 $user_host_condition = ' WHERE `User`'
2082 . ' = \'' . PMA_sqlAddSlashes($username) . "'"
2084 . ' = \'' . PMA_sqlAddSlashes($hostname) . "'";
2089 // we also want privielgs for this user not in table `db` but in other table
2090 $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;');
2091 if (! isset($dbname)) {
2093 // no db name given, so we want all privs for the given user
2095 $tables_to_search_for_users = array(
2096 'tables_priv', 'columns_priv',
2099 $db_rights_sqls = array();
2100 foreach ($tables_to_search_for_users as $table_search_in) {
2101 if (in_array($table_search_in, $tables)) {
2102 $db_rights_sqls[] = '
2103 SELECT DISTINCT `Db`
2104 FROM `mysql`.' . PMA_backquote($table_search_in)
2105 . $user_host_condition;
2109 $user_defaults = array(
2111 'Grant_priv' => 'N',
2112 'privs' => array('USAGE'),
2113 'Table_privs' => true,
2117 $db_rights = array();
2119 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
2120 .' ORDER BY `Db` ASC';
2122 $db_rights_result = PMA_DBI_query($db_rights_sql);
2124 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
2125 $db_rights_row = array_merge($user_defaults, $db_rights_row);
2126 // only Db names in the table `mysql`.`db` uses wildcards
2127 // as we are in the db specific rights display we want
2128 // all db names escaped, also from other sources
2129 $db_rights_row['Db'] = PMA_escape_mysql_wildcards(
2130 $db_rights_row['Db']
2132 $db_rights[$db_rights_row['Db']] = $db_rights_row;
2135 PMA_DBI_free_result($db_rights_result);
2136 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
2138 $sql_query = 'SELECT * FROM `mysql`.`db`' . $user_host_condition . ' ORDER BY `Db` ASC';
2139 $res = PMA_DBI_query($sql_query);
2142 while ($row = PMA_DBI_fetch_assoc($res)) {
2143 if (isset($db_rights[$row['Db']])) {
2144 $db_rights[$row['Db']] = array_merge($db_rights[$row['Db']], $row);
2146 $db_rights[$row['Db']] = $row;
2148 // there are db specific rights for this user
2149 // so we can drop this db rights
2150 $db_rights[$row['Db']]['can_delete'] = true;
2152 PMA_DBI_free_result($res);
2157 // db name was given,
2158 // so we want all user specific rights for this db
2160 $user_host_condition .=
2162 .' LIKE \'' . PMA_sqlAddSlashes($dbname, true) . "'";
2164 $tables_to_search_for_users = array(
2168 $db_rights_sqls = array();
2169 foreach ($tables_to_search_for_users as $table_search_in) {
2170 if (in_array($table_search_in, $tables)) {
2171 $db_rights_sqls[] = '
2172 SELECT DISTINCT `Table_name`
2173 FROM `mysql`.' . PMA_backquote($table_search_in)
2174 . $user_host_condition;
2178 $user_defaults = array(
2180 'Grant_priv' => 'N',
2181 'privs' => array('USAGE'),
2182 'Column_priv' => true,
2186 $db_rights = array();
2188 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
2189 .' ORDER BY `Table_name` ASC';
2191 $db_rights_result = PMA_DBI_query($db_rights_sql);
2193 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
2194 $db_rights_row = array_merge($user_defaults, $db_rights_row);
2195 $db_rights[$db_rights_row['Table_name']] = $db_rights_row;
2197 PMA_DBI_free_result($db_rights_result);
2198 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
2200 $sql_query = 'SELECT `Table_name`,'
2202 .' IF(`Column_priv` = _latin1 \'\', 0, 1)'
2203 .' AS \'Column_priv\''
2204 .' FROM `mysql`.`tables_priv`'
2205 . $user_host_condition
2206 .' ORDER BY `Table_name` ASC;';
2207 $res = PMA_DBI_query($sql_query);
2210 while ($row = PMA_DBI_fetch_assoc($res)) {
2211 if (isset($db_rights[$row['Table_name']])) {
2212 $db_rights[$row['Table_name']] = array_merge($db_rights[$row['Table_name']], $row);
2214 $db_rights[$row['Table_name']] = $row;
2217 PMA_DBI_free_result($res);
2223 if (count($db_rights) < 1) {
2224 echo '<tr class="odd">' . "\n"
2225 . ' <td colspan="6"><center><i>' . __('None') . '</i></center></td>' . "\n"
2229 $found_rows = array();
2230 //while ($row = PMA_DBI_fetch_assoc($res)) {
2231 foreach ($db_rights as $row) {
2232 $found_rows[] = (! isset($dbname)) ?
$row['Db'] : $row['Table_name'];
2234 echo '<tr class="' . ($odd_row ?
'odd' : 'even') . '">' . "\n"
2235 . ' <td>' . htmlspecialchars((! isset($dbname)) ?
$row['Db'] : $row['Table_name']) . '</td>' . "\n"
2236 . ' <td><code>' . "\n"
2237 . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($row, true)) . "\n"
2238 . ' </code></td>' . "\n"
2239 . ' <td>' . ((((! isset($dbname)) && $row['Grant_priv'] == 'Y') ||
(isset($dbname) && in_array('Grant', explode(',', $row['Table_priv'])))) ?
__('Yes') : __('No')) . '</td>' . "\n"
2241 if (! empty($row['Table_privs']) ||
! empty ($row['Column_priv'])) {
2250 htmlspecialchars(urlencode($username)),
2251 urlencode(htmlspecialchars($hostname)),
2252 urlencode((! isset($dbname)) ?
$row['Db'] : htmlspecialchars($dbname)),
2253 urlencode((! isset($dbname)) ?
'' : $row['Table_name'])
2257 if (! empty($row['can_delete']) ||
isset($row['Table_name']) && strlen($row['Table_name'])) {
2260 htmlspecialchars(urlencode($username)),
2261 urlencode(htmlspecialchars($hostname)),
2262 urlencode((! isset($dbname)) ?
$row['Db'] : htmlspecialchars($dbname)),
2263 urlencode((! isset($dbname)) ?
'' : $row['Table_name'])
2268 $odd_row = ! $odd_row;
2272 echo '</tbody>' . "\n"
2273 . '</table>' . "\n";
2275 if (! isset($dbname)) {
2277 // no database name was given, display select db
2279 $pred_db_array =PMA_DBI_fetch_result('SHOW DATABASES;');
2281 echo ' <label for="text_dbname">' . __('Add privileges on the following database') . ':</label>' . "\n";
2282 if (! empty($pred_db_array)) {
2283 echo ' <select name="pred_dbname" class="autosubmit">' . "\n"
2284 . ' <option value="" selected="selected">' . __('Use text field') . ':</option>' . "\n";
2285 foreach ($pred_db_array as $current_db) {
2286 $current_db = PMA_escape_mysql_wildcards($current_db);
2287 // cannot use array_diff() once, outside of the loop,
2288 // because the list of databases has special characters
2289 // already escaped in $found_rows,
2290 // contrary to the output of SHOW DATABASES
2291 if (empty($found_rows) ||
! in_array($current_db, $found_rows)) {
2292 echo ' <option value="' . htmlspecialchars($current_db) . '">'
2293 . htmlspecialchars($current_db) . '</option>' . "\n";
2296 echo ' </select>' . "\n";
2298 echo ' <input type="text" id="text_dbname" name="dbname" />' . "\n"
2299 . PMA_showHint(__('Wildcards % and _ should be escaped with a \ to use them literally'));
2301 echo ' <input type="hidden" name="dbname" value="' . htmlspecialchars($dbname) . '"/>' . "\n"
2302 . ' <label for="text_tablename">' . __('Add privileges on the following table') . ':</label>' . "\n";
2303 if ($res = @PMA_DBI_try_query
('SHOW TABLES FROM ' . PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . ';', null, PMA_DBI_QUERY_STORE
)) {
2304 $pred_tbl_array = array();
2305 while ($row = PMA_DBI_fetch_row($res)) {
2306 if (! isset($found_rows) ||
! in_array($row[0], $found_rows)) {
2307 $pred_tbl_array[] = $row[0];
2310 PMA_DBI_free_result($res);
2312 if (! empty($pred_tbl_array)) {
2313 echo ' <select name="pred_tablename" class="autosubmit">' . "\n"
2314 . ' <option value="" selected="selected">' . __('Use text field') . ':</option>' . "\n";
2315 foreach ($pred_tbl_array as $current_table) {
2316 echo ' <option value="' . htmlspecialchars($current_table) . '">' . htmlspecialchars($current_table) . '</option>' . "\n";
2318 echo ' </select>' . "\n";
2323 echo ' <input type="text" id="text_tablename" name="tablename" />' . "\n";
2325 echo '</fieldset>' . "\n";
2326 echo '<fieldset class="tblFooters">' . "\n"
2327 . ' <input type="submit" value="' . __('Go') . '" />'
2328 . '</fieldset>' . "\n"
2333 // Provide a line with links to the relevant database and table
2334 if (isset($dbname) && empty($dbname_is_wildcard)) {
2335 echo '[ ' . __('Database')
2336 . ' <a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?'
2337 . $GLOBALS['url_query'] . '&db=' . $url_dbname . '&reload=1">'
2338 . htmlspecialchars($dbname) . ': ' . PMA_getTitleForTarget($GLOBALS['cfg']['DefaultTabDatabase']) . "</a> ]\n";
2340 if (isset($tablename)) {
2341 echo ' [ ' . __('Table') . ' <a href="'
2342 . $GLOBALS['cfg']['DefaultTabTable'] . '?' . $GLOBALS['url_query']
2343 . '&db=' . $url_dbname . '&table=' . htmlspecialchars(urlencode($tablename))
2344 . '&reload=1">' . htmlspecialchars($tablename) . ': '
2345 . PMA_getTitleForTarget($GLOBALS['cfg']['DefaultTabTable'])
2351 if (! isset($dbname) && ! $user_does_not_exists) {
2352 include_once 'libraries/display_change_password.lib.php';
2354 echo '<form action="server_privileges.php" method="post" onsubmit="return checkPassword(this);">' . "\n"
2355 . PMA_generate_common_hidden_inputs('', '')
2356 . '<input type="hidden" name="old_username" value="' . htmlspecialchars($username) . '" />' . "\n"
2357 . '<input type="hidden" name="old_hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n"
2358 . '<fieldset id="fieldset_change_copy_user">' . "\n"
2359 . ' <legend>' . __('Change Login Information / Copy User') . '</legend>' . "\n";
2360 PMA_displayLoginInformationFields('change');
2361 echo ' <fieldset>' . "\n"
2362 . ' <legend>' . __('Create a new user with the same privileges and ...') . '</legend>' . "\n";
2364 '4' => __('... keep the old one.'),
2365 '1' => __('... delete the old one from the user tables.'),
2366 '2' => __('... revoke all active privileges from the old one and delete it afterwards.'),
2367 '3' => __('... delete the old one from the user tables and reload the privileges afterwards.'));
2368 PMA_display_html_radio('mode', $choices, '4', true);
2371 echo ' </fieldset>' . "\n"
2372 . '</fieldset>' . "\n"
2373 . '<fieldset id="fieldset_change_copy_user_footer" class="tblFooters">' . "\n"
2374 . ' <input type="submit" name="change_copy" value="' . __('Go') . '" />' . "\n"
2375 . '</fieldset>' . "\n"
2379 } elseif (isset($_REQUEST['adduser'])) {
2382 $GLOBALS['url_query'] .= '&adduser=1';
2384 . PMA_getIcon('b_usradd.png') . __('Add user') . "\n"
2386 . '<form name="usersForm" id="addUsersForm_' . $random_n . '" action="server_privileges.php" method="post">' . "\n"
2387 . PMA_generate_common_hidden_inputs('', '');
2388 PMA_displayLoginInformationFields('new');
2389 echo '<fieldset id="fieldset_add_user_database">' . "\n"
2390 . '<legend>' . __('Database for user') . '</legend>' . "\n";
2392 PMA_display_html_checkbox('createdb-1', __('Create database with same name and grant all privileges'), false, false);
2393 echo '<br />' . "\n";
2394 PMA_display_html_checkbox('createdb-2', __('Grant all privileges on wildcard name (username\\_%)'), false, false);
2395 echo '<br />' . "\n";
2397 if (! empty($dbname) ) {
2398 PMA_display_html_checkbox('createdb-3', sprintf(__('Grant all privileges on database "%s"'), htmlspecialchars($dbname)), true, false);
2399 echo '<input type="hidden" name="dbname" value="' . htmlspecialchars($dbname) . '" />' . "\n";
2400 echo '<br />' . "\n";
2403 echo '</fieldset>' . "\n";
2404 PMA_displayPrivTable('*', '*', false);
2405 echo ' <fieldset id="fieldset_add_user_footer" class="tblFooters">' . "\n"
2406 . ' <input type="submit" name="adduser_submit" value="' . __('Go') . '" />' . "\n"
2407 . ' </fieldset>' . "\n"
2410 // check the privileges for a particular database.
2411 $user_form = '<form id="usersForm" action="server_privileges.php"><fieldset>' . "\n"
2413 . PMA_getIcon('b_usrcheck.png')
2414 . ' ' . sprintf(__('Users having access to "%s"'), '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?' . PMA_generate_common_url($checkprivs) . '">' . htmlspecialchars($checkprivs) . '</a>') . "\n"
2415 . '</legend>' . "\n"
2416 . '<table id="dbspecificuserrights" class="data">' . "\n"
2418 . ' <tr><th>' . __('User') . '</th>' . "\n"
2419 . ' <th>' . __('Host') . '</th>' . "\n"
2420 . ' <th>' . __('Type') . '</th>' . "\n"
2421 . ' <th>' . __('Privileges') . '</th>' . "\n"
2422 . ' <th>' . __('Grant') . '</th>' . "\n"
2423 . ' <th>' . __('Action') . '</th>' . "\n"
2428 unset($row, $row1, $row2);
2430 // now, we build the table...
2443 . '`References_priv`, '
2444 . '`Create_tmp_table_priv`, '
2445 . '`Lock_tables_priv`, '
2446 . '`Create_view_priv`, '
2447 . '`Show_view_priv`, '
2448 . '`Create_routine_priv`, '
2449 . '`Alter_routine_priv`, '
2452 $list_of_compared_privileges
2453 = '`Select_priv` = \'N\''
2454 . ' AND `Insert_priv` = \'N\''
2455 . ' AND `Update_priv` = \'N\''
2456 . ' AND `Delete_priv` = \'N\''
2457 . ' AND `Create_priv` = \'N\''
2458 . ' AND `Drop_priv` = \'N\''
2459 . ' AND `Grant_priv` = \'N\''
2460 . ' AND `References_priv` = \'N\''
2461 . ' AND `Create_tmp_table_priv` = \'N\''
2462 . ' AND `Lock_tables_priv` = \'N\''
2463 . ' AND `Create_view_priv` = \'N\''
2464 . ' AND `Show_view_priv` = \'N\''
2465 . ' AND `Create_routine_priv` = \'N\''
2466 . ' AND `Alter_routine_priv` = \'N\''
2467 . ' AND `Execute_priv` = \'N\'';
2469 if (PMA_MYSQL_INT_VERSION
>= 50106) {
2470 $list_of_privileges .=
2473 $list_of_compared_privileges .=
2474 ' AND `Event_priv` = \'N\''
2475 . ' AND `Trigger_priv` = \'N\'';
2478 $sql_query = '(SELECT ' . $list_of_privileges . ', `Db`'
2479 .' FROM `mysql`.`db`'
2480 .' WHERE \'' . PMA_sqlAddSlashes($checkprivs) . "'"
2482 .' AND NOT (' . $list_of_compared_privileges. ')) '
2484 .'(SELECT ' . $list_of_privileges . ', \'*\' AS `Db`'
2485 .' FROM `mysql`.`user` '
2486 .' WHERE NOT (' . $list_of_compared_privileges . ')) '
2487 .' ORDER BY `User` ASC,'
2490 $res = PMA_DBI_query($sql_query);
2491 $row = PMA_DBI_fetch_assoc($res);
2498 // prepare the current user
2499 $current_privileges = array();
2500 $current_user = $row['User'];
2501 $current_host = $row['Host'];
2502 while ($row && $current_user == $row['User'] && $current_host == $row['Host']) {
2503 $current_privileges[] = $row;
2504 $row = PMA_DBI_fetch_assoc($res);
2506 $user_form .= ' <tr class="noclick ' . ($odd_row ?
'odd' : 'even') . '">' . "\n"
2508 if (count($current_privileges) > 1) {
2509 $user_form .= ' rowspan="' . count($current_privileges) . '"';
2511 $user_form .= '>' . (empty($current_user) ?
'<span style="color: #FF0000">' . __('Any') . '</span>' : htmlspecialchars($current_user)) . "\n"
2514 if (count($current_privileges) > 1) {
2515 $user_form .= ' rowspan="' . count($current_privileges) . '"';
2517 $user_form .= '>' . htmlspecialchars($current_host) . '</td>' . "\n";
2518 for ($i = 0; $i < count($current_privileges); $i++
) {
2519 $current = $current_privileges[$i];
2520 $user_form .= ' <td>' . "\n"
2522 if (! isset($current['Db']) ||
$current['Db'] == '*') {
2523 $user_form .= __('global');
2524 } elseif ($current['Db'] == PMA_escape_mysql_wildcards($checkprivs)) {
2525 $user_form .= __('database-specific');
2527 $user_form .= __('wildcard'). ': <code>' . htmlspecialchars($current['Db']) . '</code>';
2533 . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($current, true)) . "\n"
2537 . ' ' . ($current['Grant_priv'] == 'Y' ?
__('Yes') : __('No')) . "\n"
2540 $user_form .= sprintf(
2542 urlencode($current_user),
2543 urlencode($current_host),
2544 urlencode(! isset($current['Db']) ||
$current['Db'] == '*' ?
'' : $current['Db']),
2547 $user_form .= '</td>' . "\n"
2549 if (($i +
1) < count($current_privileges)) {
2550 $user_form .= '<tr class="noclick ' . ($odd_row ?
'odd' : 'even') . '">' . "\n";
2553 if (empty($row) && empty($row1) && empty($row2)) {
2556 $odd_row = ! $odd_row;
2559 $user_form .= ' <tr class="odd">' . "\n"
2560 . ' <td colspan="6">' . "\n"
2561 . ' ' . __('No user found.') . "\n"
2565 $user_form .= '</tbody>' . "\n"
2566 . '</table></fieldset></form>' . "\n";
2568 if ($GLOBALS['is_ajax_request'] == true) {
2569 $extra_data['user_form'] = $user_form;
2570 $message = PMA_Message
::success(__('User has been added.'));
2571 PMA_ajaxResponse($message, $message->isSuccess(), $extra_data);
2573 // Offer to create a new user for the current database
2574 $user_form .= '<fieldset id="fieldset_add_user">' . "\n"
2575 . '<legend>' . __('New') . '</legend>' . "\n"
2576 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&adduser=1&dbname=' . htmlspecialchars($checkprivs) .'" rel="'.'checkprivs='.htmlspecialchars($checkprivs). '&'.$GLOBALS['url_query'] . '" class="'.$conditional_class.'" name="db_specific">' . "\n"
2577 . PMA_getIcon('b_usradd.png')
2578 . ' ' . __('Add user') . '</a>' . "\n"
2579 . '</fieldset>' . "\n";
2583 } // end if (empty($_REQUEST['adduser']) && empty($checkprivs)) ... elseif ... else ...
2587 * Displays the footer
2590 require 'libraries/footer.inc.php';