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';
18 $GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.16.custom.js';
19 $GLOBALS['js_include'][] = 'codemirror/lib/codemirror.js';
20 $GLOBALS['js_include'][] = 'codemirror/mode/mysql/mysql.js';
21 $_add_user_error = false;
23 require './libraries/server_common.inc.php';
25 if ($GLOBALS['cfg']['AjaxEnable']) {
26 $conditional_class = 'ajax';
28 $conditional_class = '';
32 * Sets globals from $_GET
43 foreach ($get_params as $one_get_param) {
44 if (isset($_GET[$one_get_param])) {
45 $GLOBALS[$one_get_param] = $_GET[$one_get_param];
51 * Messages are built using the message name
53 $strPrivDescAllPrivileges = __('Includes all privileges except GRANT.');
54 $strPrivDescAlter = __('Allows altering the structure of existing tables.');
55 $strPrivDescAlterRoutine = __('Allows altering and dropping stored routines.');
56 $strPrivDescCreateDb = __('Allows creating new databases and tables.');
57 $strPrivDescCreateRoutine = __('Allows creating stored routines.');
58 $strPrivDescCreateTbl = __('Allows creating new tables.');
59 $strPrivDescCreateTmpTable = __('Allows creating temporary tables.');
60 $strPrivDescCreateUser = __('Allows creating, dropping and renaming user accounts.');
61 $strPrivDescCreateView = __('Allows creating new views.');
62 $strPrivDescDelete = __('Allows deleting data.');
63 $strPrivDescDropDb = __('Allows dropping databases and tables.');
64 $strPrivDescDropTbl = __('Allows dropping tables.');
65 $strPrivDescEvent = __('Allows to set up events for the event scheduler');
66 $strPrivDescExecute = __('Allows executing stored routines.');
67 $strPrivDescFile = __('Allows importing data from and exporting data into files.');
68 $strPrivDescGrant = __('Allows adding users and privileges without reloading the privilege tables.');
69 $strPrivDescIndex = __('Allows creating and dropping indexes.');
70 $strPrivDescInsert = __('Allows inserting and replacing data.');
71 $strPrivDescLockTables = __('Allows locking tables for the current thread.');
72 $strPrivDescMaxConnections = __('Limits the number of new connections the user may open per hour.');
73 $strPrivDescMaxQuestions = __('Limits the number of queries the user may send to the server per hour.');
74 $strPrivDescMaxUpdates = __('Limits the number of commands that change any table or database the user may execute per hour.');
75 $strPrivDescMaxUserConnections = __('Limits the number of simultaneous connections the user may have.');
76 $strPrivDescProcess = __('Allows viewing processes of all users');
77 $strPrivDescReferences = __('Has no effect in this MySQL version.');
78 $strPrivDescReload = __('Allows reloading server settings and flushing the server\'s caches.');
79 $strPrivDescReplClient = __('Allows the user to ask where the slaves / masters are.');
80 $strPrivDescReplSlave = __('Needed for the replication slaves.');
81 $strPrivDescSelect = __('Allows reading data.');
82 $strPrivDescShowDb = __('Gives access to the complete list of databases.');
83 $strPrivDescShowView = __('Allows performing SHOW CREATE VIEW queries.');
84 $strPrivDescShutdown = __('Allows shutting down the server.');
85 $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.');
86 $strPrivDescTrigger = __('Allows creating and dropping triggers');
87 $strPrivDescUpdate = __('Allows changing data.');
88 $strPrivDescUsage = __('No privileges.');
91 * Checks if a dropdown box has been used for selecting a database / table
93 if (PMA_isValid($_REQUEST['pred_tablename'])) {
94 $tablename = $_REQUEST['pred_tablename'];
95 unset($pred_tablename);
96 } elseif (PMA_isValid($_REQUEST['tablename'])) {
97 $tablename = $_REQUEST['tablename'];
102 if (PMA_isValid($_REQUEST['pred_dbname'])) {
103 $dbname = $_REQUEST['pred_dbname'];
105 } elseif (PMA_isValid($_REQUEST['dbname'])) {
106 $dbname = $_REQUEST['dbname'];
112 if (isset($dbname)) {
113 $db_and_table = PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . '.';
114 if (isset($tablename)) {
115 $db_and_table .= PMA_backquote($tablename);
117 $db_and_table .= '*';
120 $db_and_table = '*.*';
123 // check if given $dbname is a wildcard or not
124 if (isset($dbname)) {
125 //if (preg_match('/\\\\(?:_|%)/i', $dbname)) {
126 if (preg_match('/(?<!\\\\)(?:_|%)/i', $dbname)) {
127 $dbname_is_wildcard = true;
129 $dbname_is_wildcard = false;
134 * Checks if the user is allowed to do what he tries to...
136 if (! $is_superuser) {
137 include './libraries/server_links.inc.php';
139 . PMA_getIcon('b_usrlist.png')
140 . __('Privileges') . "\n"
142 PMA_Message
::error(__('No Privileges'))->display();
143 include './libraries/footer.inc.php';
146 $random_n = mt_rand(0, 1000000); // a random number that will be appended to the id of the user forms
149 * Escapes wildcard in a database+table specification
150 * before using it in a GRANT statement.
152 * Escaping a wildcard character in a GRANT is only accepted at the global
153 * or database level, not at table level; this is why I remove
154 * the escaping character. Internally, in mysql.tables_priv.Db there are
155 * no escaping (for example test_db) but in mysql.db you'll see test\_db
156 * for a db-specific privilege.
158 * @param string $dbname Database name
159 * @param string $tablename Table name
161 * @return string the escaped (if necessary) database.table
163 function PMA_wildcardEscapeForGrant($dbname, $tablename)
166 if (! strlen($dbname)) {
167 $db_and_table = '*.*';
169 if (strlen($tablename)) {
170 $db_and_table = PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . '.';
171 $db_and_table .= PMA_backquote($tablename);
173 $db_and_table = PMA_backquote($dbname) . '.';
174 $db_and_table .= '*';
177 return $db_and_table;
181 * Generates a condition on the user name
183 * @param string $initial the user's initial
185 * @return string the generated condition
187 function PMA_rangeOfUsers($initial = '')
189 // strtolower() is used because the User field
190 // might be BINARY, so LIKE would be case sensitive
191 if (! empty($initial)) {
192 $ret = " WHERE `User` LIKE '" . PMA_sqlAddSlashes($initial, true) . "%'"
193 . " OR `User` LIKE '" . PMA_sqlAddSlashes(strtolower($initial), true) . "%'";
201 * Extracts the privilege information of a priv table row
203 * @param array $row the row
204 * @param boolean $enableHTML add <dfn> tag with tooltips
206 * @global resource $user_link the database connection
210 function PMA_extractPrivInfo($row = '', $enableHTML = false)
216 __('Allows reading data.')),
220 __('Allows inserting and replacing data.')),
224 __('Allows changing data.')),
228 __('Allows deleting data.')),
232 __('Allows creating new databases and tables.')),
236 __('Allows dropping databases and tables.')),
240 __('Allows reloading server settings and flushing the server\'s caches.')),
244 __('Allows shutting down the server.')),
248 __('Allows viewing processes of all users')),
252 __('Allows importing data from and exporting data into files.')),
256 __('Has no effect in this MySQL version.')),
260 __('Allows creating and dropping indexes.')),
264 __('Allows altering the structure of existing tables.')),
268 __('Gives access to the complete list of databases.')),
272 __('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.')),
274 'Create_tmp_table_priv',
275 'CREATE TEMPORARY TABLES',
276 __('Allows creating temporary tables.')),
280 __('Allows locking tables for the current thread.')),
284 __('Needed for the replication slaves.')),
287 'REPLICATION CLIENT',
288 __('Allows the user to ask where the slaves / masters are.')),
292 __('Allows creating new views.')),
296 __('Allows to set up events for the event scheduler')),
300 __('Allows creating and dropping triggers')),
305 __('Allows creating new views.')),
309 __('Allows performing SHOW CREATE VIEW queries.')),
314 __('Allows performing SHOW CREATE VIEW queries.')),
316 'Create_routine_priv',
318 __('Allows creating stored routines.')),
320 'Alter_routine_priv',
322 __('Allows altering and dropping stored routines.')),
326 __('Allows creating, dropping and renaming user accounts.')),
330 __('Allows executing stored routines.')),
333 if (! empty($row) && isset($row['Table_priv'])) {
334 $row1 = PMA_DBI_fetch_single_row(
335 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
336 'ASSOC', $GLOBALS['userlink']
338 $av_grants = explode('\',\'', substr($row1['Type'], 5, strlen($row1['Type']) - 7));
340 $users_grants = explode(',', $row['Table_priv']);
341 foreach ($av_grants as $current_grant) {
342 $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ?
'Y' : 'N';
344 unset($current_grant);
346 unset($users_grants);
349 $allPrivileges = true;
350 foreach ($grants as $current_grant) {
351 if ((! empty($row) && isset($row[$current_grant[0]]))
352 ||
(empty($row) && isset($GLOBALS[$current_grant[0]]))
354 if ((! empty($row) && $row[$current_grant[0]] == 'Y')
356 && ($GLOBALS[$current_grant[0]] == 'Y'
357 ||
(is_array($GLOBALS[$current_grant[0]])
358 && count($GLOBALS[$current_grant[0]]) == $GLOBALS['column_count']
359 && empty($GLOBALS[$current_grant[0] . '_none']))))
362 $privs[] = '<dfn title="' . $current_grant[2] . '">' . $current_grant[1] . '</dfn>';
364 $privs[] = $current_grant[1];
366 } elseif (! empty($GLOBALS[$current_grant[0]])
367 && is_array($GLOBALS[$current_grant[0]])
368 && empty($GLOBALS[$current_grant[0] . '_none'])) {
370 $priv_string = '<dfn title="' . $current_grant[2] . '">' . $current_grant[1] . '</dfn>';
372 $priv_string = $current_grant[1];
374 $privs[] = $priv_string . ' (`' . join('`, `', $GLOBALS[$current_grant[0]]) . '`)';
376 $allPrivileges = false;
382 $privs[] = '<dfn title="' . __('No privileges.') . '">USAGE</dfn>';
386 } elseif ($allPrivileges && (! isset($GLOBALS['grant_count']) ||
count($privs) == $GLOBALS['grant_count'])) {
388 $privs = array('<dfn title="' . __('Includes all privileges except GRANT.') . '">ALL PRIVILEGES</dfn>');
390 $privs = array('ALL PRIVILEGES');
394 } // end of the 'PMA_extractPrivInfo()' function
397 * Displays on which column(s) a table-specific privilege is granted
399 function PMA_display_column_privs($columns, $row, $name_for_select,
400 $priv_for_header, $name, $name_for_dfn, $name_for_current)
402 echo ' <div class="item" id="div_item_' . $name . '">' . "\n"
403 . ' <label for="select_' . $name . '_priv">' . "\n"
404 . ' <tt><dfn title="' . $name_for_dfn . '">'
405 . $priv_for_header . '</dfn></tt>' . "\n"
406 . ' </label><br />' . "\n"
407 . ' <select id="select_' . $name . '_priv" name="'
408 . $name_for_select . '[]" multiple="multiple" size="8">' . "\n";
410 foreach ($columns as $current_column => $current_column_privileges) {
411 echo ' <option value="' . htmlspecialchars($current_column) . '"';
412 if ($row[$name_for_select] == 'Y' ||
$current_column_privileges[$name_for_current]) {
413 echo ' selected="selected"';
415 echo '>' . htmlspecialchars($current_column) . '</option>' . "\n";
418 echo ' </select>' . "\n"
419 . ' <i>' . __('Or') . '</i>' . "\n"
420 . ' <label for="checkbox_' . $name_for_select
421 . '_none"><input type="checkbox"'
422 . (empty($GLOBALS['checkall']) ?
'' : ' checked="checked"')
423 . ' name="' . $name_for_select . '_none" id="checkbox_'
424 . $name_for_select . '_none" title="' . _pgettext('None privileges', 'None') . '" />'
425 . _pgettext('None privileges', 'None') . '</label>' . "\n"
431 * Displays the privileges form table
433 * @param string $db the database
434 * @param string $table the table
435 * @param boolean $submit wheather to display the submit button or not
437 * @global array $cfg the phpMyAdmin configuration
438 * @global ressource $user_link the database connection
442 function PMA_displayPrivTable($db = '*', $table = '*', $submit = true)
450 if (isset($GLOBALS['username'])) {
451 $username = $GLOBALS['username'];
452 $hostname = $GLOBALS['hostname'];
454 $sql_query = "SELECT * FROM `mysql`.`user`"
455 ." WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'"
456 ." AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "';";
457 } elseif ($table == '*') {
458 $sql_query = "SELECT * FROM `mysql`.`db`"
459 ." WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'"
460 ." AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "'"
461 ." AND '" . PMA_unescape_mysql_wildcards($db) . "'"
464 $sql_query = "SELECT `Table_priv`"
465 ." FROM `mysql`.`tables_priv`"
466 ." WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'"
467 ." AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "'"
468 ." AND `Db` = '" . PMA_unescape_mysql_wildcards($db) . "'"
469 ." AND `Table_name` = '" . PMA_sqlAddSlashes($table) . "';";
471 $row = PMA_DBI_fetch_single_row($sql_query);
476 $sql_query = 'SHOW COLUMNS FROM `mysql`.`user`;';
477 } elseif ($table == '*') {
478 $sql_query = 'SHOW COLUMNS FROM `mysql`.`db`;';
480 $res = PMA_DBI_query($sql_query);
481 while ($row1 = PMA_DBI_fetch_row($res)) {
482 if (substr($row1[0], 0, 4) == 'max_') {
485 $row[$row1[0]] = 'N';
488 PMA_DBI_free_result($res);
490 $row = array('Table_priv' => '');
493 if (isset($row['Table_priv'])) {
494 $row1 = PMA_DBI_fetch_single_row(
495 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
496 'ASSOC', $GLOBALS['userlink']
498 // note: in MySQL 5.0.3 we get "Create View', 'Show view';
499 // the View for Create is spelled with uppercase V
500 // the view for Show is spelled with lowercase v
501 // and there is a space between the words
503 $av_grants = explode('\',\'', substr($row1['Type'], strpos($row1['Type'], '(') +
2, strpos($row1['Type'], ')') - strpos($row1['Type'], '(') - 3));
505 $users_grants = explode(',', $row['Table_priv']);
507 foreach ($av_grants as $current_grant) {
508 $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ?
'Y' : 'N';
510 unset($row['Table_priv'], $current_grant, $av_grants, $users_grants);
513 $res = PMA_DBI_try_query('SHOW COLUMNS FROM ' . PMA_backquote(PMA_unescape_mysql_wildcards($db)) . '.' . PMA_backquote($table) . ';');
516 while ($row1 = PMA_DBI_fetch_row($res)) {
517 $columns[$row1[0]] = array(
521 'References' => false
524 PMA_DBI_free_result($res);
528 // t a b l e - s p e c i f i c p r i v i l e g e s
529 if (! empty($columns)) {
530 $res = PMA_DBI_query(
531 'SELECT `Column_name`, `Column_priv`'
532 .' FROM `mysql`.`columns_priv`'
534 .' = \'' . PMA_sqlAddSlashes($username) . "'"
536 .' = \'' . PMA_sqlAddSlashes($hostname) . "'"
538 .' = \'' . PMA_sqlAddSlashes(PMA_unescape_mysql_wildcards($db)) . "'"
540 .' = \'' . PMA_sqlAddSlashes($table) . '\';'
543 while ($row1 = PMA_DBI_fetch_row($res)) {
544 $row1[1] = explode(',', $row1[1]);
545 foreach ($row1[1] as $current) {
546 $columns[$row1[0]][$current] = true;
549 PMA_DBI_free_result($res);
550 unset($res, $row1, $current);
552 echo '<input type="hidden" name="grant_count" value="' . count($row) . '" />' . "\n"
553 . '<input type="hidden" name="column_count" value="' . count($columns) . '" />' . "\n"
554 . '<fieldset id="fieldset_user_priv">' . "\n"
555 . ' <legend>' . __('Table-specific privileges')
556 . PMA_showHint(__('Note: MySQL privilege names are expressed in English'))
557 . '</legend>' . "\n";
561 // privs that are attached to a specific column
562 PMA_display_column_privs(
563 $columns, $row, 'Select_priv', 'SELECT',
564 'select', __('Allows reading data.'), 'Select'
567 PMA_display_column_privs(
568 $columns, $row, 'Insert_priv', 'INSERT',
569 'insert', __('Allows inserting and replacing data.'), 'Insert'
572 PMA_display_column_privs(
573 $columns, $row, 'Update_priv', 'UPDATE',
574 'update', __('Allows changing data.'), 'Update'
577 PMA_display_column_privs(
578 $columns, $row, 'References_priv', 'REFERENCES', 'references',
579 __('Has no effect in this MySQL version.'), 'References'
582 // privs that are not attached to a specific column
584 echo ' <div class="item">' . "\n";
585 foreach ($row as $current_grant => $current_grant_value) {
586 if (in_array(substr($current_grant, 0, (strlen($current_grant) - 5)),
587 array('Select', 'Insert', 'Update', 'References'))) {
590 // make a substitution to match the messages variables;
591 // also we must substitute the grant we get, because we can't generate
592 // a form variable containing blanks (those would get changed to
593 // an underscore when receiving the POST)
594 if ($current_grant == 'Create View_priv') {
595 $tmp_current_grant = 'CreateView_priv';
596 $current_grant = 'Create_view_priv';
597 } elseif ($current_grant == 'Show view_priv') {
598 $tmp_current_grant = 'ShowView_priv';
599 $current_grant = 'Show_view_priv';
601 $tmp_current_grant = $current_grant;
604 echo ' <div class="item">' . "\n"
605 . ' <input type="checkbox"'
606 . (empty($GLOBALS['checkall']) ?
'' : ' checked="checked"')
607 . ' name="' . $current_grant . '" id="checkbox_' . $current_grant
609 . ($current_grant_value == 'Y' ?
'checked="checked" ' : '')
612 echo (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))])
613 ?
$GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))]
614 : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)) . 'Tbl']) . '"/>' . "\n";
616 echo ' <label for="checkbox_' . $current_grant
617 . '"><tt><dfn title="'
618 . (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))])
619 ?
$GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))]
620 : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)) . 'Tbl'])
621 . '">' . strtoupper(substr($current_grant, 0, strlen($current_grant) - 5)) . '</dfn></tt></label>' . "\n"
625 echo ' </div>' . "\n";
627 echo ' <div class="clearfloat"></div>' . "\n";
631 // g l o b a l o r d b - s p e c i f i c
633 $privTable_names = array(0 => __('Data'), 1 => __('Structure'), 2 => __('Administration'));
636 $privTable[0] = array(
637 array('Select', 'SELECT', __('Allows reading data.')),
638 array('Insert', 'INSERT', __('Allows inserting and replacing data.')),
639 array('Update', 'UPDATE', __('Allows changing data.')),
640 array('Delete', 'DELETE', __('Allows deleting data.'))
643 $privTable[0][] = array('File', 'FILE', __('Allows importing data from and exporting data into files.'));
647 $privTable[1] = array(
648 array('Create', 'CREATE', ($table == '*' ?
__('Allows creating new databases and tables.') : __('Allows creating new tables.'))),
649 array('Alter', 'ALTER', __('Allows altering the structure of existing tables.')),
650 array('Index', 'INDEX', __('Allows creating and dropping indexes.')),
651 array('Drop', 'DROP', ($table == '*' ?
__('Allows dropping databases and tables.') : __('Allows dropping tables.'))),
652 array('Create_tmp_table', 'CREATE TEMPORARY TABLES', __('Allows creating temporary tables.')),
653 array('Show_view', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')),
654 array('Create_routine', 'CREATE ROUTINE', __('Allows creating stored routines.')),
655 array('Alter_routine', 'ALTER ROUTINE', __('Allows altering and dropping stored routines.')),
656 array('Execute', 'EXECUTE', __('Allows executing stored routines.')),
658 // this one is for a db-specific priv: Create_view_priv
659 if (isset($row['Create_view_priv'])) {
660 $privTable[1][] = array('Create_view', 'CREATE VIEW', __('Allows creating new views.'));
662 // this one is for a table-specific priv: Create View_priv
663 if (isset($row['Create View_priv'])) {
664 $privTable[1][] = array('Create View', 'CREATE VIEW', __('Allows creating new views.'));
666 if (isset($row['Event_priv'])) {
668 $privTable[1][] = array('Event', 'EVENT', __('Allows to set up events for the event scheduler'));
669 $privTable[1][] = array('Trigger', 'TRIGGER', __('Allows creating and dropping triggers'));
672 // a d m i n i s t r a t i o n
673 $privTable[2] = array(
674 array('Grant', 'GRANT', __('Allows adding users and privileges without reloading the privilege tables.')),
677 $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.'));
678 $privTable[2][] = array('Process', 'PROCESS', __('Allows viewing processes of all users'));
679 $privTable[2][] = array('Reload', 'RELOAD', __('Allows reloading server settings and flushing the server\'s caches.'));
680 $privTable[2][] = array('Shutdown', 'SHUTDOWN', __('Allows shutting down the server.'));
681 $privTable[2][] = array('Show_db', 'SHOW DATABASES', __('Gives access to the complete list of databases.'));
683 $privTable[2][] = array('Lock_tables', 'LOCK TABLES', __('Allows locking tables for the current thread.'));
684 $privTable[2][] = array('References', 'REFERENCES', __('Has no effect in this MySQL version.'));
686 $privTable[2][] = array('Repl_client', 'REPLICATION CLIENT', __('Allows the user to ask where the slaves / masters are.'));
687 $privTable[2][] = array('Repl_slave', 'REPLICATION SLAVE', __('Needed for the replication slaves.'));
688 $privTable[2][] = array('Create_user', 'CREATE USER', __('Allows creating, dropping and renaming user accounts.'));
690 echo '<input type="hidden" name="grant_count" value="'
691 . (count($privTable[0]) +
count($privTable[1]) +
count($privTable[2]) - (isset($row['Grant_priv']) ?
1 : 0))
693 . '<fieldset id="fieldset_user_global_rights">' . "\n"
697 ?
__('Global privileges')
699 ?
__('Database-specific privileges')
700 : __('Table-specific privileges'))) . "\n"
701 . ' (<a href="server_privileges.php?'
702 . $GLOBALS['url_query'] . '&checkall=1" onclick="setCheckboxes(\'addUsersForm_' . $random_n . '\', true); return false;">'
703 . __('Check All') . '</a> /' . "\n"
704 . ' <a href="server_privileges.php?'
705 . $GLOBALS['url_query'] . '" onclick="setCheckboxes(\'addUsersForm_' . $random_n . '\', false); return false;">'
706 . __('Uncheck All') . '</a>)' . "\n"
707 . ' </legend>' . "\n"
708 . ' <p><small><i>' . __('Note: MySQL privilege names are expressed in English') . '</i></small></p>' . "\n";
710 // Output the Global privilege tables with checkboxes
711 foreach ($privTable as $i => $table) {
712 echo ' <fieldset>' . "\n"
713 . ' <legend>' . __($privTable_names[$i]) . '</legend>' . "\n";
714 foreach ($table as $priv) {
715 echo ' <div class="item">' . "\n"
716 . ' <input type="checkbox"'
717 . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0] . '_priv"'
718 . ' value="Y" title="' . $priv[2] . '"'
719 . ((! empty($GLOBALS['checkall']) ||
$row[$priv[0] . '_priv'] == 'Y') ?
' checked="checked"' : '')
721 . ' <label for="checkbox_' . $priv[0] . '_priv"><tt><dfn title="' . $priv[2] . '">'
722 . $priv[1] . '</dfn></tt></label>' . "\n"
725 echo ' </fieldset>' . "\n";
728 // The "Resource limits" box is not displayed for db-specific privs
730 echo ' <fieldset>' . "\n"
731 . ' <legend>' . __('Resource limits') . '</legend>' . "\n"
732 . ' <p><small><i>' . __('Note: Setting these options to 0 (zero) removes the limit.') . '</i></small></p>' . "\n"
733 . ' <div class="item">' . "\n"
734 . ' <label for="text_max_questions"><tt><dfn title="'
735 . __('Limits the number of queries the user may send to the server per hour.') . '">MAX QUERIES PER HOUR</dfn></tt></label>' . "\n"
736 . ' <input type="text" name="max_questions" id="text_max_questions" value="'
737 . $row['max_questions'] . '" size="11" maxlength="11" title="' . __('Limits the number of queries the user may send to the server per hour.') . '" />' . "\n"
739 . ' <div class="item">' . "\n"
740 . ' <label for="text_max_updates"><tt><dfn title="'
741 . __('Limits the number of commands that change any table or database the user may execute per hour.') . '">MAX UPDATES PER HOUR</dfn></tt></label>' . "\n"
742 . ' <input type="text" name="max_updates" id="text_max_updates" value="'
743 . $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"
745 . ' <div class="item">' . "\n"
746 . ' <label for="text_max_connections"><tt><dfn title="'
747 . __('Limits the number of new connections the user may open per hour.') . '">MAX CONNECTIONS PER HOUR</dfn></tt></label>' . "\n"
748 . ' <input type="text" name="max_connections" id="text_max_connections" value="'
749 . $row['max_connections'] . '" size="11" maxlength="11" title="' . __('Limits the number of new connections the user may open per hour.') . '" />' . "\n"
751 . ' <div class="item">' . "\n"
752 . ' <label for="text_max_user_connections"><tt><dfn title="'
753 . __('Limits the number of simultaneous connections the user may have.') . '">MAX USER_CONNECTIONS</dfn></tt></label>' . "\n"
754 . ' <input type="text" name="max_user_connections" id="text_max_user_connections" value="'
755 . $row['max_user_connections'] . '" size="11" maxlength="11" title="' . __('Limits the number of simultaneous connections the user may have.') . '" />' . "\n"
757 . ' </fieldset>' . "\n";
760 echo ' <div class="clearfloat"></div>' . "\n";
762 echo '</fieldset>' . "\n";
764 echo '<fieldset id="fieldset_user_privtable_footer" class="tblFooters">' . "\n"
765 . ' <input type="submit" name="update_privs" value="' . __('Go') . '" />' . "\n"
766 . '</fieldset>' . "\n";
768 } // end of the 'PMA_displayPrivTable()' function
772 * Displays the fields used by the "new user" form as well as the
773 * "change login information / copy user" form.
775 * @param string $mode are we creating a new user or are we just
776 * changing one? (allowed values: 'new', 'change')
778 * @global array $cfg the phpMyAdmin configuration
779 * @global ressource $user_link the database connection
783 function PMA_displayLoginInformationFields($mode = 'new')
785 // Get user/host name lengths
786 $fields_info = PMA_DBI_get_columns('mysql', 'user', null, true);
787 $username_length = 16;
788 $hostname_length = 41;
789 foreach ($fields_info as $val) {
790 if ($val['Field'] == 'User') {
791 strtok($val['Type'], '()');
794 $username_length = $v;
796 } elseif ($val['Field'] == 'Host') {
797 strtok($val['Type'], '()');
800 $hostname_length = $v;
806 if (isset($GLOBALS['username']) && strlen($GLOBALS['username']) === 0) {
807 $GLOBALS['pred_username'] = 'any';
809 echo '<fieldset id="fieldset_add_user_login">' . "\n"
810 . '<legend>' . __('Login Information') . '</legend>' . "\n"
811 . '<div class="item">' . "\n"
812 . '<label for="select_pred_username">' . "\n"
813 . ' ' . __('User name') . ':' . "\n"
815 . '<span class="options">' . "\n"
816 . ' <select name="pred_username" id="select_pred_username" title="' . __('User name') . '"' . "\n"
817 . ' onchange="if (this.value == \'any\') { username.value = \'\'; } else if (this.value == \'userdefined\') { username.focus(); username.select(); }">' . "\n"
818 . ' <option value="any"' . ((isset($GLOBALS['pred_username']) && $GLOBALS['pred_username'] == 'any') ?
' selected="selected"' : '') . '>' . __('Any user') . '</option>' . "\n"
819 . ' <option value="userdefined"' . ((! isset($GLOBALS['pred_username']) ||
$GLOBALS['pred_username'] == 'userdefined') ?
' selected="selected"' : '') . '>' . __('Use text field') . ':</option>' . "\n"
820 . ' </select>' . "\n"
822 . '<input type="text" name="username" maxlength="'
823 . $username_length . '" title="' . __('User name') . '"'
824 . (empty($GLOBALS['username'])
826 : ' value="' . htmlspecialchars(isset($GLOBALS['new_username'])
827 ?
$GLOBALS['new_username']
828 : $GLOBALS['username']) . '"')
829 . ' onchange="pred_username.value = \'userdefined\';" />' . "\n"
831 . '<div class="item">' . "\n"
832 . '<label for="select_pred_hostname">' . "\n"
833 . ' ' . __('Host') . ':' . "\n"
835 . '<span class="options">' . "\n"
836 . ' <select name="pred_hostname" id="select_pred_hostname" title="' . __('Host') . '"' . "\n";
837 $_current_user = PMA_DBI_fetch_value('SELECT USER();');
838 if (! empty($_current_user)) {
839 $thishost = str_replace("'", '', substr($_current_user, (strrpos($_current_user, '@') +
1)));
840 if ($thishost == 'localhost' ||
$thishost == '127.0.0.1') {
844 echo ' onchange="if (this.value == \'any\') { hostname.value = \'%\'; } else if (this.value == \'localhost\') { hostname.value = \'localhost\'; } '
845 . (empty($thishost) ?
'' : 'else if (this.value == \'thishost\') { hostname.value = \'' . addslashes(htmlspecialchars($thishost)) . '\'; } ')
846 . 'else if (this.value == \'hosttable\') { hostname.value = \'\'; } else if (this.value == \'userdefined\') { hostname.focus(); hostname.select(); }">' . "\n";
847 unset($_current_user);
849 // when we start editing a user, $GLOBALS['pred_hostname'] is not defined
850 if (! isset($GLOBALS['pred_hostname']) && isset($GLOBALS['hostname'])) {
851 switch (strtolower($GLOBALS['hostname'])) {
854 $GLOBALS['pred_hostname'] = 'localhost';
857 $GLOBALS['pred_hostname'] = 'any';
860 $GLOBALS['pred_hostname'] = 'userdefined';
864 echo ' <option value="any"'
865 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'any')
866 ?
' selected="selected"' : '') . '>' . __('Any host')
868 . ' <option value="localhost"'
869 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'localhost')
870 ?
' selected="selected"' : '') . '>' . __('Local')
871 . '</option>' . "\n";
872 if (! empty($thishost)) {
873 echo ' <option value="thishost"'
874 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'thishost')
875 ?
' selected="selected"' : '') . '>' . __('This Host')
876 . '</option>' . "\n";
879 echo ' <option value="hosttable"'
880 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'hosttable')
881 ?
' selected="selected"' : '') . '>' . __('Use Host Table')
883 . ' <option value="userdefined"'
884 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'userdefined')
885 ?
' selected="selected"' : '')
886 . '>' . __('Use text field') . ':</option>' . "\n"
887 . ' </select>' . "\n"
889 . '<input type="text" name="hostname" maxlength="'
890 . $hostname_length . '" value="'
891 . htmlspecialchars(isset($GLOBALS['hostname']) ?
$GLOBALS['hostname'] : '')
892 . '" title="' . __('Host')
893 . '" onchange="pred_hostname.value = \'userdefined\';" />' . "\n"
894 . PMA_showHint(__('When Host table is used, this field is ignored and values stored in Host table are used instead.'))
896 . '<div class="item">' . "\n"
897 . '<label for="select_pred_password">' . "\n"
898 . ' ' . __('Password') . ':' . "\n"
900 . '<span class="options">' . "\n"
901 . ' <select name="pred_password" id="select_pred_password" title="'
902 . __('Password') . '"' . "\n"
903 . ' onchange="if (this.value == \'none\') { pma_pw.value = \'\'; pma_pw2.value = \'\'; } else if (this.value == \'userdefined\') { pma_pw.focus(); pma_pw.select(); }">' . "\n"
904 . ($mode == 'change' ?
' <option value="keep" selected="selected">' . __('Do not change the password') . '</option>' . "\n" : '')
905 . ' <option value="none"';
906 if (isset($GLOBALS['username']) && $mode != 'change') {
907 echo ' selected="selected"';
909 echo '>' . __('No Password') . '</option>' . "\n"
910 . ' <option value="userdefined"' . (isset($GLOBALS['username']) ?
'' : ' selected="selected"') . '>' . __('Use text field') . ':</option>' . "\n"
911 . ' </select>' . "\n"
913 . '<input type="password" id="text_pma_pw" name="pma_pw" title="' . __('Password') . '" onchange="pred_password.value = \'userdefined\';" />' . "\n"
915 . '<div class="item" id="div_element_before_generate_password">' . "\n"
916 . '<label for="text_pma_pw2">' . "\n"
917 . ' ' . __('Re-type') . ':' . "\n"
919 . '<span class="options"> </span>' . "\n"
920 . '<input type="password" name="pma_pw2" id="text_pma_pw2" title="' . __('Re-type') . '" onchange="pred_password.value = \'userdefined\';" />' . "\n"
922 // Generate password added here via jQuery
923 . '</fieldset>' . "\n";
924 } // end of the 'PMA_displayUserAndHostFields()' function
928 * Returns all the grants for a certain user on a certain host
929 * Used in the export privileges for all users section
931 * @param string $user User name
932 * @param string $host Host name
934 * @return string containing all the grants text
936 function PMA_getGrants($user, $host) {
937 $grants = PMA_DBI_fetch_result("SHOW GRANTS FOR '" . PMA_sqlAddSlashes($user) . "'@'" . PMA_sqlAddSlashes($host) . "'");
939 foreach ($grants as $one_grant) {
940 $response .= $one_grant . ";\n\n";
943 } // end of the 'PMA_getGrants()' function
946 * Changes / copies a user, part I
948 if (isset($_REQUEST['change_copy'])) {
949 $user_host_condition = ' WHERE `User`'
950 .' = \'' . PMA_sqlAddSlashes($old_username) . "'"
952 .' = \'' . PMA_sqlAddSlashes($old_hostname) . '\';';
953 $row = PMA_DBI_fetch_single_row('SELECT * FROM `mysql`.`user` ' . $user_host_condition);
955 PMA_Message
::notice(__('No user found.'))->display();
956 unset($_REQUEST['change_copy']);
958 extract($row, EXTR_OVERWRITE
);
959 // Recent MySQL versions have the field "Password" in mysql.user,
960 // so the previous extract creates $Password but this script
962 if (! isset($password) && isset($Password)) {
963 $password = $Password;
972 * (Changes / copies a user, part II)
974 if (isset($_REQUEST['adduser_submit']) ||
isset($_REQUEST['change_copy'])) {
976 if ($pred_username == 'any') {
979 switch ($pred_hostname) {
984 $hostname = 'localhost';
990 $_user_name = PMA_DBI_fetch_value('SELECT USER()');
991 $hostname = substr($_user_name, (strrpos($_user_name, '@') +
1));
995 $sql = "SELECT '1' FROM `mysql`.`user`"
996 . " WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'"
997 . " AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "';";
998 if (PMA_DBI_fetch_value($sql) == 1) {
999 $message = PMA_Message
::error(__('The user %s already exists!'));
1000 $message->addParam('[i]\'' . $username . '\'@\'' . $hostname . '\'[/i]');
1001 $_REQUEST['adduser'] = true;
1002 $_add_user_error = true;
1005 $create_user_real = 'CREATE USER \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\'';
1007 $real_sql_query = 'GRANT ' . join(', ', PMA_extractPrivInfo()) . ' ON *.* TO \''
1008 . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\'';
1009 if ($pred_password != 'none' && $pred_password != 'keep') {
1010 $sql_query = $real_sql_query . ' IDENTIFIED BY \'***\'';
1011 $real_sql_query .= ' IDENTIFIED BY \'' . PMA_sqlAddSlashes($pma_pw) . '\'';
1012 if (isset($create_user_real)) {
1013 $create_user_show = $create_user_real . ' IDENTIFIED BY \'***\'';
1014 $create_user_real .= ' IDENTIFIED BY \'' . PMA_sqlAddSlashes($pma_pw) . '\'';
1017 if ($pred_password == 'keep' && ! empty($password)) {
1018 $real_sql_query .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
1019 if (isset($create_user_real)) {
1020 $create_user_real .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
1023 $sql_query = $real_sql_query;
1024 if (isset($create_user_real)) {
1025 $create_user_show = $create_user_real;
1029 * @todo similar code appears twice in this script
1031 if ((isset($Grant_priv) && $Grant_priv == 'Y')
1032 ||
(isset($max_questions) ||
isset($max_connections)
1033 ||
isset($max_updates) ||
isset($max_user_connections))
1035 $real_sql_query .= ' WITH';
1036 $sql_query .= ' WITH';
1037 if (isset($Grant_priv) && $Grant_priv == 'Y') {
1038 $real_sql_query .= ' GRANT OPTION';
1039 $sql_query .= ' GRANT OPTION';
1041 if (isset($max_questions)) {
1042 // avoid negative values
1043 $max_questions = max(0, (int)$max_questions);
1044 $real_sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
1045 $sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
1047 if (isset($max_connections)) {
1048 $max_connections = max(0, (int)$max_connections);
1049 $real_sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
1050 $sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
1052 if (isset($max_updates)) {
1053 $max_updates = max(0, (int)$max_updates);
1054 $real_sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
1055 $sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
1057 if (isset($max_user_connections)) {
1058 $max_user_connections = max(0, (int)$max_user_connections);
1059 $real_sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
1060 $sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
1063 if (isset($create_user_real)) {
1064 $create_user_real .= ';';
1065 $create_user_show .= ';';
1067 $real_sql_query .= ';';
1069 if (empty($_REQUEST['change_copy'])) {
1072 if (isset($create_user_real)) {
1073 if (! PMA_DBI_try_query($create_user_real)) {
1076 $sql_query = $create_user_show . $sql_query;
1079 if ($_error ||
! PMA_DBI_try_query($real_sql_query)) {
1080 $_REQUEST['createdb-1']
1081 = $_REQUEST['createdb-2']
1082 = $_REQUEST['createdb-3'] = false;
1083 $message = PMA_Message
::rawError(PMA_DBI_getError());
1085 $message = PMA_Message
::success(__('You have added a new user.'));
1088 if (isset($_REQUEST['createdb-1'])) {
1089 // Create database with same name and grant all privileges
1090 $q = 'CREATE DATABASE IF NOT EXISTS '
1091 . PMA_backquote(PMA_sqlAddSlashes($username)) . ';';
1093 if (! PMA_DBI_try_query($q)) {
1094 $message = PMA_Message
::rawError(PMA_DBI_getError());
1100 * If we are not in an Ajax request, we can't reload navigation now
1102 if ($GLOBALS['is_ajax_request'] != true) {
1103 // this is needed in case tracking is on:
1104 $GLOBALS['db'] = $username;
1105 $GLOBALS['reload'] = true;
1106 PMA_reloadNavigation();
1109 $q = 'GRANT ALL PRIVILEGES ON '
1110 . PMA_backquote(PMA_sqlAddSlashes($username)) . '.* TO \''
1111 . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';';
1113 if (! PMA_DBI_try_query($q)) {
1114 $message = PMA_Message
::rawError(PMA_DBI_getError());
1118 if (isset($_REQUEST['createdb-2'])) {
1119 // Grant all privileges on wildcard name (username\_%)
1120 $q = 'GRANT ALL PRIVILEGES ON '
1121 . PMA_backquote(PMA_sqlAddSlashes($username) . '\_%') . '.* TO \''
1122 . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';';
1124 if (! PMA_DBI_try_query($q)) {
1125 $message = PMA_Message
::rawError(PMA_DBI_getError());
1129 if (isset($_REQUEST['createdb-3'])) {
1130 // Grant all privileges on the specified database to the new user
1131 $q = 'GRANT ALL PRIVILEGES ON '
1132 . PMA_backquote(PMA_sqlAddSlashes($dbname)) . '.* TO \''
1133 . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';';
1135 if (! PMA_DBI_try_query($q)) {
1136 $message = PMA_Message
::rawError(PMA_DBI_getError());
1140 if (isset($create_user_real)) {
1141 $queries[] = $create_user_real;
1143 $queries[] = $real_sql_query;
1144 // we put the query containing the hidden password in
1145 // $queries_for_display, at the same position occupied
1146 // by the real query in $queries
1147 $tmp_count = count($queries);
1148 if (isset($create_user_real)) {
1149 $queries_for_display[$tmp_count - 2] = $create_user_show;
1151 $queries_for_display[$tmp_count - 1] = $sql_query;
1153 unset($res, $real_sql_query);
1159 * Changes / copies a user, part III
1161 if (isset($_REQUEST['change_copy'])) {
1162 $user_host_condition = ' WHERE `User`'
1163 .' = \'' . PMA_sqlAddSlashes($old_username) . "'"
1165 .' = \'' . PMA_sqlAddSlashes($old_hostname) . '\';';
1166 $res = PMA_DBI_query('SELECT * FROM `mysql`.`db`' . $user_host_condition);
1167 while ($row = PMA_DBI_fetch_assoc($res)) {
1168 $queries[] = 'GRANT ' . join(', ', PMA_extractPrivInfo($row))
1169 .' ON ' . PMA_backquote($row['Db']) . '.*'
1170 .' TO \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\''
1171 . ($row['Grant_priv'] == 'Y' ?
' WITH GRANT OPTION;' : ';');
1173 PMA_DBI_free_result($res);
1174 $res = PMA_DBI_query(
1175 'SELECT `Db`, `Table_name`, `Table_priv` FROM `mysql`.`tables_priv`' . $user_host_condition,
1176 $GLOBALS['userlink'],
1179 while ($row = PMA_DBI_fetch_assoc($res)) {
1181 $res2 = PMA_DBI_QUERY(
1182 'SELECT `Column_name`, `Column_priv`'
1183 .' FROM `mysql`.`columns_priv`'
1185 .' = \'' . PMA_sqlAddSlashes($old_username) . "'"
1187 .' = \'' . PMA_sqlAddSlashes($old_hostname) . '\''
1189 .' = \'' . PMA_sqlAddSlashes($row['Db']) . "'"
1190 .' AND `Table_name`'
1191 .' = \'' . PMA_sqlAddSlashes($row['Table_name']) . "'"
1197 $tmp_privs1 = PMA_extractPrivInfo($row);
1198 $tmp_privs2 = array(
1199 'Select' => array(),
1200 'Insert' => array(),
1201 'Update' => array(),
1202 'References' => array()
1205 while ($row2 = PMA_DBI_fetch_assoc($res2)) {
1206 $tmp_array = explode(',', $row2['Column_priv']);
1207 if (in_array('Select', $tmp_array)) {
1208 $tmp_privs2['Select'][] = $row2['Column_name'];
1210 if (in_array('Insert', $tmp_array)) {
1211 $tmp_privs2['Insert'][] = $row2['Column_name'];
1213 if (in_array('Update', $tmp_array)) {
1214 $tmp_privs2['Update'][] = $row2['Column_name'];
1216 if (in_array('References', $tmp_array)) {
1217 $tmp_privs2['References'][] = $row2['Column_name'];
1221 if (count($tmp_privs2['Select']) > 0 && ! in_array('SELECT', $tmp_privs1)) {
1222 $tmp_privs1[] = 'SELECT (`' . join('`, `', $tmp_privs2['Select']) . '`)';
1224 if (count($tmp_privs2['Insert']) > 0 && ! in_array('INSERT', $tmp_privs1)) {
1225 $tmp_privs1[] = 'INSERT (`' . join('`, `', $tmp_privs2['Insert']) . '`)';
1227 if (count($tmp_privs2['Update']) > 0 && ! in_array('UPDATE', $tmp_privs1)) {
1228 $tmp_privs1[] = 'UPDATE (`' . join('`, `', $tmp_privs2['Update']) . '`)';
1230 if (count($tmp_privs2['References']) > 0 && ! in_array('REFERENCES', $tmp_privs1)) {
1231 $tmp_privs1[] = 'REFERENCES (`' . join('`, `', $tmp_privs2['References']) . '`)';
1234 $queries[] = 'GRANT ' . join(', ', $tmp_privs1)
1235 . ' ON ' . PMA_backquote($row['Db']) . '.' . PMA_backquote($row['Table_name'])
1236 . ' TO \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\''
1237 . (in_array('Grant', explode(',', $row['Table_priv'])) ?
' WITH GRANT OPTION;' : ';');
1243 * Updates privileges
1245 if (! empty($update_privs)) {
1246 $db_and_table = PMA_wildcardEscapeForGrant($dbname, (isset($tablename) ?
$tablename : ''));
1248 $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
1249 . ' FROM \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';';
1250 if (! isset($Grant_priv) ||
$Grant_priv != 'Y') {
1251 $sql_query1 = 'REVOKE GRANT OPTION ON ' . $db_and_table
1252 . ' FROM \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';';
1257 // Should not do a GRANT USAGE for a table-specific privilege, it
1258 // causes problems later (cannot revoke it)
1259 if (! (isset($tablename) && 'USAGE' == implode('', PMA_extractPrivInfo()))) {
1260 $sql_query2 = 'GRANT ' . join(', ', PMA_extractPrivInfo())
1261 . ' ON ' . $db_and_table
1262 . ' TO \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\'';
1265 * @todo similar code appears twice in this script
1267 if ((isset($Grant_priv) && $Grant_priv == 'Y')
1268 ||
(! isset($dbname)
1269 && (isset($max_questions) ||
isset($max_connections)
1270 ||
isset($max_updates) ||
isset($max_user_connections)))
1272 $sql_query2 .= 'WITH';
1273 if (isset($Grant_priv) && $Grant_priv == 'Y') {
1274 $sql_query2 .= ' GRANT OPTION';
1276 if (isset($max_questions)) {
1277 $max_questions = max(0, (int)$max_questions);
1278 $sql_query2 .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
1280 if (isset($max_connections)) {
1281 $max_connections = max(0, (int)$max_connections);
1282 $sql_query2 .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
1284 if (isset($max_updates)) {
1285 $max_updates = max(0, (int)$max_updates);
1286 $sql_query2 .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
1288 if (isset($max_user_connections)) {
1289 $max_user_connections = max(0, (int)$max_user_connections);
1290 $sql_query2 .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
1295 if (! PMA_DBI_try_query($sql_query0)) {
1296 // This might fail when the executing user does not have ALL PRIVILEGES himself.
1297 // See https://sourceforge.net/tracker/index.php?func=detail&aid=3285929&group_id=23067&atid=377408
1300 if (isset($sql_query1) && ! PMA_DBI_try_query($sql_query1)) {
1301 // this one may fail, too...
1304 if (isset($sql_query2)) {
1305 PMA_DBI_query($sql_query2);
1309 $sql_query = $sql_query0 . ' ' . $sql_query1 . ' ' . $sql_query2;
1310 $message = PMA_Message
::success(__('You have updated the privileges for %s.'));
1311 $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'');
1316 * Revokes Privileges
1318 if (isset($_REQUEST['revokeall'])) {
1319 $db_and_table = PMA_wildcardEscapeForGrant($dbname, isset($tablename) ?
$tablename : '');
1321 $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
1322 . ' FROM \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';';
1323 $sql_query1 = 'REVOKE GRANT OPTION ON ' . $db_and_table
1324 . ' FROM \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';';
1326 PMA_DBI_query($sql_query0);
1327 if (! PMA_DBI_try_query($sql_query1)) {
1328 // this one may fail, too...
1331 $sql_query = $sql_query0 . ' ' . $sql_query1;
1332 $message = PMA_Message
::success(__('You have revoked the privileges for %s'));
1333 $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'');
1334 if (! isset($tablename)) {
1343 * Updates the password
1345 if (isset($_REQUEST['change_pw'])) {
1346 // similar logic in user_password.php
1349 if ($nopass == 0 && isset($pma_pw) && isset($pma_pw2)) {
1350 if ($pma_pw != $pma_pw2) {
1351 $message = PMA_Message
::error(__('The passwords aren\'t the same!'));
1352 } elseif (empty($pma_pw) ||
empty($pma_pw2)) {
1353 $message = PMA_Message
::error(__('The password is empty!'));
1357 // here $nopass could be == 1
1358 if (empty($message)) {
1360 $hashing_function = (! empty($pw_hash) && $pw_hash == 'old' ?
'OLD_' : '')
1363 // in $sql_query which will be displayed, hide the password
1364 $sql_query = 'SET PASSWORD FOR \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\' = ' . (($pma_pw == '') ?
'\'\'' : $hashing_function . '(\'' . preg_replace('@.@s', '*', $pma_pw) . '\')');
1365 $local_query = 'SET PASSWORD FOR \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\' = ' . (($pma_pw == '') ?
'\'\'' : $hashing_function . '(\'' . PMA_sqlAddSlashes($pma_pw) . '\')');
1366 PMA_DBI_try_query($local_query)
1367 or PMA_mysqlDie(PMA_DBI_getError(), $sql_query, false, $err_url);
1368 $message = PMA_Message
::success(__('The password for %s was changed successfully.'));
1369 $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'');
1376 * (Changes / copies a user, part IV)
1379 if (isset($_REQUEST['delete']) ||
(isset($_REQUEST['change_copy']) && $_REQUEST['mode'] < 4)) {
1380 if (isset($_REQUEST['change_copy'])) {
1381 $selected_usr = array($old_username . '&#27;' . $old_hostname);
1383 $selected_usr = $_REQUEST['selected_usr'];
1386 foreach ($selected_usr as $each_user) {
1387 list($this_user, $this_host) = explode('&#27;', $each_user);
1388 $queries[] = '# ' . sprintf(__('Deleting %s'), '\'' . $this_user . '\'@\'' . $this_host . '\'') . ' ...';
1389 $queries[] = 'DROP USER \'' . PMA_sqlAddSlashes($this_user) . '\'@\'' . PMA_sqlAddSlashes($this_host) . '\';';
1391 if (isset($_REQUEST['drop_users_db'])) {
1392 $queries[] = 'DROP DATABASE IF EXISTS ' . PMA_backquote($this_user) . ';';
1393 $GLOBALS['reload'] = true;
1395 if ($GLOBALS['is_ajax_request'] != true) {
1396 PMA_reloadNavigation();
1400 if (empty($_REQUEST['change_copy'])) {
1401 if (empty($queries)) {
1402 $message = PMA_Message
::error(__('No users selected for deleting!'));
1404 if ($_REQUEST['mode'] == 3) {
1405 $queries[] = '# ' . __('Reloading the privileges') . ' ...';
1406 $queries[] = 'FLUSH PRIVILEGES;';
1408 $drop_user_error = '';
1409 foreach ($queries as $sql_query) {
1410 if ($sql_query{0} != '#') {
1411 if (! PMA_DBI_try_query($sql_query, $GLOBALS['userlink'])) {
1412 $drop_user_error .= PMA_DBI_getError() . "\n";
1416 // tracking sets this, causing the deleted db to be shown in navi
1417 unset($GLOBALS['db']);
1419 $sql_query = join("\n", $queries);
1420 if (! empty($drop_user_error)) {
1421 $message = PMA_Message
::rawError($drop_user_error);
1423 $message = PMA_Message
::success(__('The selected users have been deleted successfully.'));
1432 * Changes / copies a user, part V
1434 if (isset($_REQUEST['change_copy'])) {
1436 foreach ($queries as $sql_query) {
1437 if ($sql_query{0} != '#') {
1438 PMA_DBI_query($sql_query);
1440 // when there is a query containing a hidden password, take it
1441 // instead of the real query sent
1442 if (isset($queries_for_display[$tmp_count])) {
1443 $queries[$tmp_count] = $queries_for_display[$tmp_count];
1447 $message = PMA_Message
::success();
1448 $sql_query = join("\n", $queries);
1453 * Reloads the privilege tables into memory
1455 if (isset($_REQUEST['flush_privileges'])) {
1456 $sql_query = 'FLUSH PRIVILEGES;';
1457 PMA_DBI_query($sql_query);
1458 $message = PMA_Message
::success(__('The privileges were reloaded successfully.'));
1462 * defines some standard links
1464 $link_edit = '<a class="edit_user_anchor ' . $conditional_class . '" href="server_privileges.php?' . str_replace('%', '%%', $GLOBALS['url_query'])
1465 . '&username=%s'
1466 . '&hostname=%s'
1468 . '&tablename=%s">'
1469 . PMA_getIcon('b_usredit.png', __('Edit Privileges'))
1472 $link_revoke = '<a href="server_privileges.php?' . str_replace('%', '%%', $GLOBALS['url_query'])
1473 . '&username=%s'
1474 . '&hostname=%s'
1476 . '&tablename=%s'
1477 . '&revokeall=1">'
1478 . PMA_getIcon('b_usrdrop.png', __('Revoke'))
1481 $link_export = '<a class="export_user_anchor ' . $conditional_class . '" href="server_privileges.php?' . str_replace('%', '%%', $GLOBALS['url_query'])
1482 . '&username=%s'
1483 . '&hostname=%s'
1486 . PMA_getIcon('b_tblexport.png', __('Export'))
1489 $link_export_all = '<a class="export_user_anchor ' . $conditional_class . '" href="server_privileges.php?' . str_replace('%', '%%', $GLOBALS['url_query'])
1490 . '&username=%s'
1491 . '&hostname=%s'
1494 . PMA_getIcon('b_tblexport.png', __('Export all'))
1498 * If we are in an Ajax request for Create User/Edit User/Revoke User/
1499 * Flush Privileges, show $message and exit.
1501 if ($GLOBALS['is_ajax_request'] && ! isset($_REQUEST['export']) && (! isset($_REQUEST['adduser']) ||
$_add_user_error) && ! isset($_REQUEST['initial']) && ! isset($_REQUEST['showall']) && ! isset($_REQUEST['edit_user_dialog']) && ! isset($_REQUEST['db_specific'])) {
1503 if (isset($sql_query)) {
1504 $extra_data['sql_query'] = PMA_showMessage(null, $sql_query);
1507 if (isset($_REQUEST['adduser_submit']) ||
isset($_REQUEST['change_copy'])) {
1509 * generate html on the fly for the new user that was just created.
1511 $new_user_string = '<tr>'."\n"
1512 .'<td> <input type="checkbox" name="selected_usr[]" id="checkbox_sel_users_" value="' . htmlspecialchars($username) . '&#27;' . htmlspecialchars($hostname) . '" /> </td>' . "\n"
1513 .'<td><label for="checkbox_sel_users_">' . (empty($username) ?
'<span style="color: #FF0000">' . __('Any') . '</span>' : htmlspecialchars($username) ) . '</label></td>' . "\n"
1514 .'<td>' . htmlspecialchars($hostname) . '</td>' . "\n";
1515 $new_user_string .= '<td>';
1517 if (! empty($password) ||
isset($pma_pw)) {
1518 $new_user_string .= __('Yes');
1520 $new_user_string .= '<span style="color: #FF0000">' . __('No') . '</span>';
1523 $new_user_string .= '</td>'."\n";
1524 $new_user_string .= '<td><tt>' . join(', ', PMA_extractPrivInfo('', true)) . '</tt></td>'; //Fill in privileges here
1525 $new_user_string .= '<td>';
1527 if ((isset($Grant_priv) && $Grant_priv == 'Y')) {
1528 $new_user_string .= __('Yes');
1530 $new_user_string .= __('No');
1533 $new_user_string .='</td>';
1535 $new_user_string .= '<td>' . sprintf($link_edit, urlencode($username), urlencode($hostname), '', '') . '</td>' . "\n";
1536 $new_user_string .= '<td>' . sprintf($link_export, urlencode($username), urlencode($hostname), (isset($initial) ?
$initial : '')) . '</td>' . "\n";
1538 $new_user_string .= '</tr>';
1540 $extra_data['new_user_string'] = $new_user_string;
1543 * Generate the string for this alphabet's initial, to update the user
1546 $new_user_initial = strtoupper(substr($username, 0, 1));
1547 $new_user_initial_string = '<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&initial=' . $new_user_initial
1548 .'">' . $new_user_initial . '</a>';
1549 $extra_data['new_user_initial'] = $new_user_initial;
1550 $extra_data['new_user_initial_string'] = $new_user_initial_string;
1553 if (isset($update_privs)) {
1554 $extra_data['db_specific_privs'] = false;
1555 if (isset($dbname_is_wildcard)) {
1556 $extra_data['db_specific_privs'] = ! $dbname_is_wildcard;
1558 $new_privileges = join(', ', PMA_extractPrivInfo('', true));
1560 $extra_data['new_privileges'] = $new_privileges;
1563 if ($message instanceof PMA_Message
) {
1564 PMA_ajaxResponse($message, $message->isSuccess(), $extra_data);
1569 * Displays the links
1571 if (isset($viewing_mode) && $viewing_mode == 'db') {
1573 $url_query .= '&goto=db_operations.php';
1575 // Gets the database structure
1576 $sub_part = '_structure';
1577 include './libraries/db_info.inc.php';
1580 include './libraries/server_links.inc.php';
1588 // export user definition
1589 if (isset($_REQUEST['export'])) {
1590 $response = '<textarea cols="' . $GLOBALS['cfg']['TextareaCols'] . '" rows="' . $GLOBALS['cfg']['TextareaRows'] . '">';
1591 if ($username == '%') {
1592 // export privileges for all users
1593 $title = __('Privileges for all users');
1594 foreach ($_SESSION['user_host_pairs'] as $pair) {
1595 $response .= PMA_getGrants($pair['user'], $pair['host']);
1599 // export privileges for a single user
1600 $title = __('User') . ' `' . htmlspecialchars($username) . '`@`' . htmlspecialchars($hostname) . '`';
1601 $response .= PMA_getGrants($username, $hostname);
1603 $response .= '</textarea>';
1604 unset($username, $hostname, $grants, $one_grant);
1605 if ($GLOBALS['is_ajax_request']) {
1606 PMA_ajaxResponse($response, 1, array('title' => $title));
1608 echo "<h2>$title</h2>$response";
1612 if (empty($_REQUEST['adduser']) && (! isset($checkprivs) ||
! strlen($checkprivs))) {
1613 if (! isset($username)) {
1614 // No username is given --> display the overview
1616 . PMA_getIcon('b_usrlist.png')
1617 . __('Users overview') . "\n"
1620 $sql_query = 'SELECT *,' .
1621 " IF(`Password` = _latin1 '', 'N', 'Y') AS 'Password'" .
1622 ' FROM `mysql`.`user`';
1624 $sql_query .= (isset($initial) ?
PMA_rangeOfUsers($initial) : '');
1626 $sql_query .= ' ORDER BY `User` ASC, `Host` ASC;';
1627 $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE
);
1630 // the query failed! This may have two reasons:
1631 // - the user does not have enough privileges
1632 // - the privilege tables use a structure of an earlier version.
1633 // so let's try a more simple query
1635 $sql_query = 'SELECT * FROM `mysql`.`user`';
1636 $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE
);
1639 PMA_Message
::error(__('No Privileges'))->display();
1640 PMA_DBI_free_result($res);
1643 // This message is hardcoded because I will replace it by
1644 // a automatic repair feature soon.
1645 $raw = 'Your privilege table structure seems to be older than'
1646 . ' this MySQL version!<br />'
1647 . 'Please run the <tt>mysql_upgrade</tt> command'
1648 . '(<tt>mysql_fix_privilege_tables</tt> on older systems)'
1649 . ' that should be included in your MySQL server distribution'
1650 . ' to solve this problem!';
1651 PMA_Message
::rawError($raw)->display();
1655 // we also want users not in table `user` but in other table
1656 $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;');
1658 $tables_to_search_for_users = array(
1659 'user', 'db', 'tables_priv', 'columns_priv', 'procs_priv',
1662 $db_rights_sqls = array();
1663 foreach ($tables_to_search_for_users as $table_search_in) {
1664 if (in_array($table_search_in, $tables)) {
1665 $db_rights_sqls[] = 'SELECT DISTINCT `User`, `Host` FROM `mysql`.`' . $table_search_in . '` ' . (isset($initial) ?
PMA_rangeOfUsers($initial) : '');
1669 $user_defaults = array(
1673 'Grant_priv' => 'N',
1674 'privs' => array('USAGE'),
1677 // for all initials, even non A-Z
1678 $array_initials = array();
1680 $db_rights = array();
1682 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
1683 .' ORDER BY `User` ASC, `Host` ASC';
1685 $db_rights_result = PMA_DBI_query($db_rights_sql);
1687 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
1688 $db_rights_row = array_merge($user_defaults, $db_rights_row);
1689 $db_rights[$db_rights_row['User']][$db_rights_row['Host']]
1692 PMA_DBI_free_result($db_rights_result);
1693 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
1697 * Displays the initials
1698 * In an Ajax request, we don't need to show this.
1699 * Also not necassary if there is less than 20 privileges
1701 if ($GLOBALS['is_ajax_request'] != true && PMA_DBI_num_rows($res) > 20 ) {
1703 // initialize to false the letters A-Z
1704 for ($letter_counter = 1; $letter_counter < 27; $letter_counter++
) {
1705 if (! isset($array_initials[chr($letter_counter +
64)])) {
1706 $array_initials[chr($letter_counter +
64)] = false;
1710 $initials = PMA_DBI_try_query('SELECT DISTINCT UPPER(LEFT(`User`,1)) FROM `user` ORDER BY `User` ASC', null, PMA_DBI_QUERY_STORE
);
1711 while (list($tmp_initial) = PMA_DBI_fetch_row($initials)) {
1712 $array_initials[$tmp_initial] = true;
1715 // Display the initials, which can be any characters, not
1716 // just letters. For letters A-Z, we add the non-used letters
1719 uksort($array_initials, "strnatcasecmp");
1721 echo '<table id="initials_table" class="' . $conditional_class . '" <cellspacing="5"><tr>';
1722 foreach ($array_initials as $tmp_initial => $initial_was_found) {
1723 if ($initial_was_found) {
1724 echo '<td><a href="server_privileges.php?' . $GLOBALS['url_query'] . '&initial=' . urlencode($tmp_initial) . '">' . $tmp_initial . '</a></td>' . "\n";
1726 echo '<td>' . $tmp_initial . '</td>';
1729 echo '<td><a href="server_privileges.php?' . $GLOBALS['url_query'] . '&showall=1" class="nowrap">[' . __('Show all') . ']</a></td>' . "\n";
1730 echo '</tr></table>';
1734 * Display the user overview
1735 * (if less than 50 users, display them immediately)
1738 if (isset($initial) ||
isset($showall) ||
PMA_DBI_num_rows($res) < 50) {
1740 while ($row = PMA_DBI_fetch_assoc($res)) {
1741 $row['privs'] = PMA_extractPrivInfo($row, true);
1742 $db_rights[$row['User']][$row['Host']] = $row;
1744 @PMA_DBI_free_result
($res);
1747 echo '<form name="usersForm" id="usersForm" action="server_privileges.php" method="post">' . "\n"
1748 . PMA_generate_common_hidden_inputs('', '')
1749 . ' <table id="tableuserrights" class="data">' . "\n"
1751 . ' <tr><th></th>' . "\n"
1752 . ' <th>' . __('User') . '</th>' . "\n"
1753 . ' <th>' . __('Host') . '</th>' . "\n"
1754 . ' <th>' . __('Password') . '</th>' . "\n"
1755 . ' <th>' . __('Global privileges') . ' '
1756 . PMA_showHint(__('Note: MySQL privilege names are expressed in English')) . '</th>' . "\n"
1757 . ' <th>' . __('Grant') . '</th>' . "\n"
1758 . ' <th colspan="2">' . __('Action') . '</th>' . "\n";
1759 echo ' </tr>' . "\n";
1760 echo ' </thead>' . "\n";
1761 echo ' <tbody>' . "\n";
1763 $_SESSION['user_host_pairs'] = array();
1766 $index_checkbox = -1;
1767 foreach ($db_rights as $user) {
1770 foreach ($user as $host) {
1772 echo ' <tr class="' . ($odd_row ?
'odd' : 'even') . '">' . "\n"
1773 . ' <td><input type="checkbox" name="selected_usr[]" id="checkbox_sel_users_'
1774 . $index_checkbox . '" value="'
1775 . htmlspecialchars($host['User'] . '&#27;' . $host['Host'])
1777 . (empty($GLOBALS['checkall']) ?
'' : ' checked="checked"')
1779 . ' <td><label for="checkbox_sel_users_' . $index_checkbox . '">' . (empty($host['User']) ?
'<span style="color: #FF0000">' . __('Any') . '</span>' : htmlspecialchars($host['User'])) . '</label></td>' . "\n"
1780 . ' <td>' . htmlspecialchars($host['Host']) . '</td>' . "\n";
1782 switch ($host['Password']) {
1787 echo '<span style="color: #FF0000">' . __('No') . '</span>';
1789 // this happens if this is a definition not coming from mysql.user
1791 echo '--'; // in future version, replace by "not present"
1795 . ' <td><tt>' . "\n"
1796 . ' ' . implode(',' . "\n" . ' ', $host['privs']) . "\n"
1797 . ' </tt></td>' . "\n"
1798 . ' <td>' . ($host['Grant_priv'] == 'Y' ?
__('Yes') : __('No')) . '</td>' . "\n"
1799 . ' <td align="center">';
1800 printf($link_edit, urlencode($host['User']), urlencode($host['Host']), '', '');
1802 echo '<td align="center">';
1803 printf($link_export, urlencode($host['User']), urlencode($host['Host']), (isset($initial) ?
$initial : ''));
1806 $odd_row = ! $odd_row;
1808 $_SESSION['user_host_pairs'][$pair_count]['user'] = $host['User'];
1809 $_SESSION['user_host_pairs'][$pair_count]['host'] = $host['Host'];
1814 unset($user, $host, $odd_row);
1815 echo ' </tbody></table>' . "\n"
1817 .'<div style="float:left;">'
1818 .'<img class="selectallarrow"'
1819 .' src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png"'
1820 .' width="38" height="22"'
1821 .' alt="' . __('With selected:') . '" />' . "\n"
1822 .'<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&checkall=1"'
1823 .' onclick="if (markAllRows(\'usersForm\')) return false;">'
1824 . __('Check All') . '</a>' . "\n"
1826 .'<a href="server_privileges.php?' . $GLOBALS['url_query'] . '"'
1827 .' onclick="if (unMarkAllRows(\'usersForm\')) return false;">'
1828 . __('Uncheck All') . '</a>' . "\n"
1830 . '<div class="clear_both" style="clear:both"></div>'
1831 . '<div style="float:left; padding-left:10px;">';
1832 printf($link_export_all, urlencode('%'), urlencode('%'), (isset($initial) ?
$initial : ''));
1835 . '<div class="clear_both" style="clear:both"></div>'
1838 // add/delete user fieldset
1839 echo ' <fieldset id="fieldset_add_user">' . "\n"
1840 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&adduser=1" class="' . $conditional_class . '">' . "\n"
1841 . PMA_getIcon('b_usradd.png')
1842 . ' ' . __('Add user') . '</a>' . "\n"
1843 . ' </fieldset>' . "\n"
1844 . ' <fieldset id="fieldset_delete_user">'
1845 . ' <legend>' . "\n"
1846 . PMA_getIcon('b_usrdrop.png')
1847 . ' ' . __('Remove selected users') . '' . "\n"
1848 . ' </legend>' . "\n"
1849 . ' <input type="hidden" name="mode" value="2" />' . "\n"
1850 . '(' . __('Revoke all active privileges from the users and delete them afterwards.') . ')<br />' . "\n"
1851 . ' <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"
1852 . ' <label for="checkbox_drop_users_db" title="' . __('Drop the databases that have the same names as the users.') . '">' . "\n"
1853 . ' ' . __('Drop the databases that have the same names as the users.') . "\n"
1854 . ' </label>' . "\n"
1855 . ' </fieldset>' . "\n"
1856 . ' <fieldset id="fieldset_delete_user_footer" class="tblFooters">' . "\n"
1857 . ' <input type="submit" name="delete" value="' . __('Go') . '" id="buttonGo" class="' . $conditional_class . '"/>' . "\n"
1858 . ' </fieldset>' . "\n"
1863 echo ' <fieldset id="fieldset_add_user">' . "\n"
1864 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&adduser=1" class="' . $conditional_class . '">' . "\n"
1865 . PMA_getIcon('b_usradd.png')
1866 . ' ' . __('Add user') . '</a>' . "\n"
1867 . ' </fieldset>' . "\n";
1868 } // end if (display overview)
1870 if ($GLOBALS['is_ajax_request']) {
1874 $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
);
1875 $flushnote->addParam('<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&flush_privileges=1" id="reload_privileges_anchor" class="' . $conditional_class . '">', false);
1876 $flushnote->addParam('</a>', false);
1877 $flushnote->display();
1883 // A user was selected -> display the user's properties
1885 // In an Ajax request, prevent cached values from showing
1886 if ($GLOBALS['is_ajax_request'] == true) {
1887 header('Cache-Control: no-cache');
1891 . PMA_getIcon('b_usredit.png')
1892 . __('Edit Privileges') . ': '
1895 if (isset($dbname)) {
1896 echo ' <i><a href="server_privileges.php?'
1897 . $GLOBALS['url_query'] . '&username=' . htmlspecialchars(urlencode($username))
1898 . '&hostname=' . htmlspecialchars(urlencode($hostname)) . '&dbname=&tablename=">\''
1899 . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname)
1900 . '\'</a></i>' . "\n";
1901 $url_dbname = urlencode(str_replace(array('\_', '\%'), array('_', '%'), $dbname));
1903 echo ' - ' . ($dbname_is_wildcard ?
__('Databases') : __('Database') );
1904 if (isset($tablename)) {
1905 echo ' <i><a href="server_privileges.php?' . $GLOBALS['url_query']
1906 . '&username=' . htmlspecialchars(urlencode($username)) . '&hostname=' . htmlspecialchars(urlencode($hostname))
1907 . '&dbname=' . htmlspecialchars($url_dbname) . '&tablename=">' . htmlspecialchars($dbname) . '</a></i>';
1908 echo ' - ' . __('Table') . ' <i>' . htmlspecialchars($tablename) . '</i>';
1910 echo ' <i>' . htmlspecialchars($dbname) . '</i>';
1914 echo ' <i>\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname)
1918 echo '</h2>' . "\n";
1921 $sql = "SELECT '1' FROM `mysql`.`user`"
1922 . " WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'"
1923 . " AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "';";
1924 $user_does_not_exists = (bool) ! PMA_DBI_fetch_value($sql);
1926 if ($user_does_not_exists) {
1927 PMA_Message
::error(__('The selected user was not found in the privilege table.'))->display();
1928 PMA_displayLoginInformationFields();
1929 //require './libraries/footer.inc.php';
1932 echo '<form name="usersForm" id="addUsersForm_' . $random_n . '" action="server_privileges.php" method="post">' . "\n";
1934 'username' => $username,
1935 'hostname' => $hostname,
1937 if (isset($dbname)) {
1938 $_params['dbname'] = $dbname;
1939 if (isset($tablename)) {
1940 $_params['tablename'] = $tablename;
1943 echo PMA_generate_common_hidden_inputs($_params);
1945 PMA_displayPrivTable(
1946 PMA_ifSetOr($dbname, '*', 'length'),
1947 PMA_ifSetOr($tablename, '*', 'length')
1950 echo '</form>' . "\n";
1952 if (! isset($tablename) && empty($dbname_is_wildcard)) {
1954 // no table name was given, display all table specific rights
1955 // but only if $dbname contains no wildcards
1958 echo '<form action="server_privileges.php" id="db_or_table_specific_priv" method="post">' . "\n"
1959 . PMA_generate_common_hidden_inputs('', '')
1960 . '<input type="hidden" name="username" value="' . htmlspecialchars($username) . '" />' . "\n"
1961 . '<input type="hidden" name="hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n"
1962 . '<fieldset>' . "\n"
1963 . '<legend>' . (! isset($dbname) ?
__('Database-specific privileges') : __('Table-specific privileges')) . '</legend>' . "\n"
1964 . '<table class="data">' . "\n"
1966 . '<tr><th>' . (! isset($dbname) ?
__('Database') : __('Table')) . '</th>' . "\n"
1967 . ' <th>' . __('Privileges') . '</th>' . "\n"
1968 . ' <th>' . __('Grant') . '</th>' . "\n"
1969 . ' <th>' . (! isset($dbname) ?
__('Table-specific privileges') : __('Column-specific privileges')) . '</th>' . "\n"
1970 . ' <th colspan="2">' . __('Action') . '</th>' . "\n"
1975 $user_host_condition = ' WHERE `User`'
1976 . ' = \'' . PMA_sqlAddSlashes($username) . "'"
1978 . ' = \'' . PMA_sqlAddSlashes($hostname) . "'";
1983 // we also want privielgs for this user not in table `db` but in other table
1984 $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;');
1985 if (! isset($dbname)) {
1987 // no db name given, so we want all privs for the given user
1989 $tables_to_search_for_users = array(
1990 'tables_priv', 'columns_priv',
1993 $db_rights_sqls = array();
1994 foreach ($tables_to_search_for_users as $table_search_in) {
1995 if (in_array($table_search_in, $tables)) {
1996 $db_rights_sqls[] = '
1997 SELECT DISTINCT `Db`
1998 FROM `mysql`.' . PMA_backquote($table_search_in)
1999 . $user_host_condition;
2003 $user_defaults = array(
2005 'Grant_priv' => 'N',
2006 'privs' => array('USAGE'),
2007 'Table_privs' => true,
2011 $db_rights = array();
2013 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
2014 .' ORDER BY `Db` ASC';
2016 $db_rights_result = PMA_DBI_query($db_rights_sql);
2018 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
2019 $db_rights_row = array_merge($user_defaults, $db_rights_row);
2020 // only Db names in the table `mysql`.`db` uses wildcards
2021 // as we are in the db specific rights display we want
2022 // all db names escaped, also from other sources
2023 $db_rights_row['Db'] = PMA_escape_mysql_wildcards(
2024 $db_rights_row['Db']
2026 $db_rights[$db_rights_row['Db']] = $db_rights_row;
2029 PMA_DBI_free_result($db_rights_result);
2030 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
2032 $sql_query = 'SELECT * FROM `mysql`.`db`' . $user_host_condition . ' ORDER BY `Db` ASC';
2033 $res = PMA_DBI_query($sql_query);
2036 while ($row = PMA_DBI_fetch_assoc($res)) {
2037 if (isset($db_rights[$row['Db']])) {
2038 $db_rights[$row['Db']] = array_merge($db_rights[$row['Db']], $row);
2040 $db_rights[$row['Db']] = $row;
2042 // there are db specific rights for this user
2043 // so we can drop this db rights
2044 $db_rights[$row['Db']]['can_delete'] = true;
2046 PMA_DBI_free_result($res);
2051 // db name was given,
2052 // so we want all user specific rights for this db
2054 $user_host_condition .=
2056 .' LIKE \'' . PMA_sqlAddSlashes($dbname, true) . "'";
2058 $tables_to_search_for_users = array(
2062 $db_rights_sqls = array();
2063 foreach ($tables_to_search_for_users as $table_search_in) {
2064 if (in_array($table_search_in, $tables)) {
2065 $db_rights_sqls[] = '
2066 SELECT DISTINCT `Table_name`
2067 FROM `mysql`.' . PMA_backquote($table_search_in)
2068 . $user_host_condition;
2072 $user_defaults = array(
2074 'Grant_priv' => 'N',
2075 'privs' => array('USAGE'),
2076 'Column_priv' => true,
2080 $db_rights = array();
2082 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
2083 .' ORDER BY `Table_name` ASC';
2085 $db_rights_result = PMA_DBI_query($db_rights_sql);
2087 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
2088 $db_rights_row = array_merge($user_defaults, $db_rights_row);
2089 $db_rights[$db_rights_row['Table_name']] = $db_rights_row;
2091 PMA_DBI_free_result($db_rights_result);
2092 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
2094 $sql_query = 'SELECT `Table_name`,'
2096 .' IF(`Column_priv` = _latin1 \'\', 0, 1)'
2097 .' AS \'Column_priv\''
2098 .' FROM `mysql`.`tables_priv`'
2099 . $user_host_condition
2100 .' ORDER BY `Table_name` ASC;';
2101 $res = PMA_DBI_query($sql_query);
2104 while ($row = PMA_DBI_fetch_assoc($res)) {
2105 if (isset($db_rights[$row['Table_name']])) {
2106 $db_rights[$row['Table_name']] = array_merge($db_rights[$row['Table_name']], $row);
2108 $db_rights[$row['Table_name']] = $row;
2111 PMA_DBI_free_result($res);
2117 if (count($db_rights) < 1) {
2118 echo '<tr class="odd">' . "\n"
2119 . ' <td colspan="6"><center><i>' . __('None') . '</i></center></td>' . "\n"
2123 $found_rows = array();
2124 //while ($row = PMA_DBI_fetch_assoc($res)) {
2125 foreach ($db_rights as $row) {
2126 $found_rows[] = (! isset($dbname)) ?
$row['Db'] : $row['Table_name'];
2128 echo '<tr class="' . ($odd_row ?
'odd' : 'even') . '">' . "\n"
2129 . ' <td>' . htmlspecialchars((! isset($dbname)) ?
$row['Db'] : $row['Table_name']) . '</td>' . "\n"
2130 . ' <td><tt>' . "\n"
2131 . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($row, true)) . "\n"
2132 . ' </tt></td>' . "\n"
2133 . ' <td>' . ((((! isset($dbname)) && $row['Grant_priv'] == 'Y') ||
(isset($dbname) && in_array('Grant', explode(',', $row['Table_priv'])))) ?
__('Yes') : __('No')) . '</td>' . "\n"
2135 if (! empty($row['Table_privs']) ||
! empty ($row['Column_priv'])) {
2144 htmlspecialchars(urlencode($username)),
2145 urlencode(htmlspecialchars($hostname)),
2146 urlencode((! isset($dbname)) ?
$row['Db'] : htmlspecialchars($dbname)),
2147 urlencode((! isset($dbname)) ?
'' : $row['Table_name'])
2151 if (! empty($row['can_delete']) ||
isset($row['Table_name']) && strlen($row['Table_name'])) {
2154 htmlspecialchars(urlencode($username)),
2155 urlencode(htmlspecialchars($hostname)),
2156 urlencode((! isset($dbname)) ?
$row['Db'] : htmlspecialchars($dbname)),
2157 urlencode((! isset($dbname)) ?
'' : $row['Table_name'])
2162 $odd_row = ! $odd_row;
2166 echo '</tbody>' . "\n"
2167 . '</table>' . "\n";
2169 if (! isset($dbname)) {
2171 // no database name was given, display select db
2173 $pred_db_array =PMA_DBI_fetch_result('SHOW DATABASES;');
2175 echo ' <label for="text_dbname">' . __('Add privileges on the following database') . ':</label>' . "\n";
2176 if (! empty($pred_db_array)) {
2177 echo ' <select name="pred_dbname" class="autosubmit">' . "\n"
2178 . ' <option value="" selected="selected">' . __('Use text field') . ':</option>' . "\n";
2179 foreach ($pred_db_array as $current_db) {
2180 $current_db = PMA_escape_mysql_wildcards($current_db);
2181 // cannot use array_diff() once, outside of the loop,
2182 // because the list of databases has special characters
2183 // already escaped in $found_rows,
2184 // contrary to the output of SHOW DATABASES
2185 if (empty($found_rows) ||
! in_array($current_db, $found_rows)) {
2186 echo ' <option value="' . htmlspecialchars($current_db) . '">'
2187 . htmlspecialchars($current_db) . '</option>' . "\n";
2190 echo ' </select>' . "\n";
2192 echo ' <input type="text" id="text_dbname" name="dbname" />' . "\n"
2193 . PMA_showHint(__('Wildcards % and _ should be escaped with a \ to use them literally'));
2195 echo ' <input type="hidden" name="dbname" value="' . htmlspecialchars($dbname) . '"/>' . "\n"
2196 . ' <label for="text_tablename">' . __('Add privileges on the following table') . ':</label>' . "\n";
2197 if ($res = @PMA_DBI_try_query
('SHOW TABLES FROM ' . PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . ';', null, PMA_DBI_QUERY_STORE
)) {
2198 $pred_tbl_array = array();
2199 while ($row = PMA_DBI_fetch_row($res)) {
2200 if (! isset($found_rows) ||
! in_array($row[0], $found_rows)) {
2201 $pred_tbl_array[] = $row[0];
2204 PMA_DBI_free_result($res);
2206 if (! empty($pred_tbl_array)) {
2207 echo ' <select name="pred_tablename" class="autosubmit">' . "\n"
2208 . ' <option value="" selected="selected">' . __('Use text field') . ':</option>' . "\n";
2209 foreach ($pred_tbl_array as $current_table) {
2210 echo ' <option value="' . htmlspecialchars($current_table) . '">' . htmlspecialchars($current_table) . '</option>' . "\n";
2212 echo ' </select>' . "\n";
2217 echo ' <input type="text" id="text_tablename" name="tablename" />' . "\n";
2219 echo '</fieldset>' . "\n";
2220 echo '<fieldset class="tblFooters">' . "\n"
2221 . ' <input type="submit" value="' . __('Go') . '" />'
2222 . '</fieldset>' . "\n"
2227 // Provide a line with links to the relevant database and table
2228 if (isset($dbname) && empty($dbname_is_wildcard)) {
2229 echo '[ ' . __('Database')
2230 . ' <a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?'
2231 . $GLOBALS['url_query'] . '&db=' . $url_dbname . '&reload=1">'
2232 . htmlspecialchars($dbname) . ': ' . PMA_getTitleForTarget($GLOBALS['cfg']['DefaultTabDatabase']) . "</a> ]\n";
2234 if (isset($tablename)) {
2235 echo ' [ ' . __('Table') . ' <a href="'
2236 . $GLOBALS['cfg']['DefaultTabTable'] . '?' . $GLOBALS['url_query']
2237 . '&db=' . $url_dbname . '&table=' . htmlspecialchars(urlencode($tablename))
2238 . '&reload=1">' . htmlspecialchars($tablename) . ': '
2239 . PMA_getTitleForTarget($GLOBALS['cfg']['DefaultTabTable'])
2245 if (! isset($dbname) && ! $user_does_not_exists) {
2246 include_once './libraries/display_change_password.lib.php';
2248 echo '<form action="server_privileges.php" method="post" onsubmit="return checkPassword(this);">' . "\n"
2249 . PMA_generate_common_hidden_inputs('', '')
2250 . '<input type="hidden" name="old_username" value="' . htmlspecialchars($username) . '" />' . "\n"
2251 . '<input type="hidden" name="old_hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n"
2252 . '<fieldset id="fieldset_change_copy_user">' . "\n"
2253 . ' <legend>' . __('Change Login Information / Copy User') . '</legend>' . "\n";
2254 PMA_displayLoginInformationFields('change');
2255 echo ' <fieldset>' . "\n"
2256 . ' <legend>' . __('Create a new user with the same privileges and ...') . '</legend>' . "\n";
2258 '4' => __('... keep the old one.'),
2259 '1' => __('... delete the old one from the user tables.'),
2260 '2' => __('... revoke all active privileges from the old one and delete it afterwards.'),
2261 '3' => __('... delete the old one from the user tables and reload the privileges afterwards.'));
2262 PMA_display_html_radio('mode', $choices, '4', true);
2265 echo ' </fieldset>' . "\n"
2266 . '</fieldset>' . "\n"
2267 . '<fieldset id="fieldset_change_copy_user_footer" class="tblFooters">' . "\n"
2268 . ' <input type="submit" name="change_copy" value="' . __('Go') . '" />' . "\n"
2269 . '</fieldset>' . "\n"
2273 } elseif (isset($_REQUEST['adduser'])) {
2276 $GLOBALS['url_query'] .= '&adduser=1';
2278 . PMA_getIcon('b_usradd.png') . __('Add user') . "\n"
2280 . '<form name="usersForm" id="addUsersForm_' . $random_n . '" action="server_privileges.php" method="post">' . "\n"
2281 . PMA_generate_common_hidden_inputs('', '');
2282 PMA_displayLoginInformationFields('new');
2283 echo '<fieldset id="fieldset_add_user_database">' . "\n"
2284 . '<legend>' . __('Database for user') . '</legend>' . "\n";
2286 PMA_display_html_checkbox('createdb-1', __('Create database with same name and grant all privileges'), false, false);
2287 echo '<br />' . "\n";
2288 PMA_display_html_checkbox('createdb-2', __('Grant all privileges on wildcard name (username\\_%)'), false, false);
2289 echo '<br />' . "\n";
2291 if (! empty($dbname) ) {
2292 PMA_display_html_checkbox('createdb-3', sprintf(__('Grant all privileges on database "%s"'), htmlspecialchars($dbname)), true, false);
2293 echo '<input type="hidden" name="dbname" value="' . htmlspecialchars($dbname) . '" />' . "\n";
2294 echo '<br />' . "\n";
2297 echo '</fieldset>' . "\n";
2298 PMA_displayPrivTable('*', '*', false);
2299 echo ' <fieldset id="fieldset_add_user_footer" class="tblFooters">' . "\n"
2300 . ' <input type="submit" name="adduser_submit" value="' . __('Go') . '" />' . "\n"
2301 . ' </fieldset>' . "\n"
2304 // check the privileges for a particular database.
2305 $user_form = '<form id="usersForm" action="server_privileges.php"><fieldset>' . "\n"
2307 . PMA_getIcon('b_usrcheck.png')
2308 . ' ' . sprintf(__('Users having access to "%s"'), '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?' . PMA_generate_common_url($checkprivs) . '">' . htmlspecialchars($checkprivs) . '</a>') . "\n"
2309 . '</legend>' . "\n"
2310 . '<table id="dbspecificuserrights" class="data">' . "\n"
2312 . ' <tr><th>' . __('User') . '</th>' . "\n"
2313 . ' <th>' . __('Host') . '</th>' . "\n"
2314 . ' <th>' . __('Type') . '</th>' . "\n"
2315 . ' <th>' . __('Privileges') . '</th>' . "\n"
2316 . ' <th>' . __('Grant') . '</th>' . "\n"
2317 . ' <th>' . __('Action') . '</th>' . "\n"
2322 unset($row, $row1, $row2);
2324 // now, we build the table...
2337 . '`References_priv`, '
2338 . '`Create_tmp_table_priv`, '
2339 . '`Lock_tables_priv`, '
2340 . '`Create_view_priv`, '
2341 . '`Show_view_priv`, '
2342 . '`Create_routine_priv`, '
2343 . '`Alter_routine_priv`, '
2346 $list_of_compared_privileges
2347 = '`Select_priv` = \'N\''
2348 . ' AND `Insert_priv` = \'N\''
2349 . ' AND `Update_priv` = \'N\''
2350 . ' AND `Delete_priv` = \'N\''
2351 . ' AND `Create_priv` = \'N\''
2352 . ' AND `Drop_priv` = \'N\''
2353 . ' AND `Grant_priv` = \'N\''
2354 . ' AND `References_priv` = \'N\''
2355 . ' AND `Create_tmp_table_priv` = \'N\''
2356 . ' AND `Lock_tables_priv` = \'N\''
2357 . ' AND `Create_view_priv` = \'N\''
2358 . ' AND `Show_view_priv` = \'N\''
2359 . ' AND `Create_routine_priv` = \'N\''
2360 . ' AND `Alter_routine_priv` = \'N\''
2361 . ' AND `Execute_priv` = \'N\'';
2363 if (PMA_MYSQL_INT_VERSION
>= 50106) {
2364 $list_of_privileges .=
2367 $list_of_compared_privileges .=
2368 ' AND `Event_priv` = \'N\''
2369 . ' AND `Trigger_priv` = \'N\'';
2372 $sql_query = '(SELECT ' . $list_of_privileges . ', `Db`'
2373 .' FROM `mysql`.`db`'
2374 .' WHERE \'' . PMA_sqlAddSlashes($checkprivs) . "'"
2376 .' AND NOT (' . $list_of_compared_privileges. ')) '
2378 .'(SELECT ' . $list_of_privileges . ', \'*\' AS `Db`'
2379 .' FROM `mysql`.`user` '
2380 .' WHERE NOT (' . $list_of_compared_privileges . ')) '
2381 .' ORDER BY `User` ASC,'
2384 $res = PMA_DBI_query($sql_query);
2385 $row = PMA_DBI_fetch_assoc($res);
2392 // prepare the current user
2393 $current_privileges = array();
2394 $current_user = $row['User'];
2395 $current_host = $row['Host'];
2396 while ($row && $current_user == $row['User'] && $current_host == $row['Host']) {
2397 $current_privileges[] = $row;
2398 $row = PMA_DBI_fetch_assoc($res);
2400 $user_form .= ' <tr class="noclick ' . ($odd_row ?
'odd' : 'even') . '">' . "\n"
2402 if (count($current_privileges) > 1) {
2403 $user_form .= ' rowspan="' . count($current_privileges) . '"';
2405 $user_form .= '>' . (empty($current_user) ?
'<span style="color: #FF0000">' . __('Any') . '</span>' : htmlspecialchars($current_user)) . "\n"
2408 if (count($current_privileges) > 1) {
2409 $user_form .= ' rowspan="' . count($current_privileges) . '"';
2411 $user_form .= '>' . htmlspecialchars($current_host) . '</td>' . "\n";
2412 for ($i = 0; $i < count($current_privileges); $i++
) {
2413 $current = $current_privileges[$i];
2414 $user_form .= ' <td>' . "\n"
2416 if (! isset($current['Db']) ||
$current['Db'] == '*') {
2417 $user_form .= __('global');
2418 } elseif ($current['Db'] == PMA_escape_mysql_wildcards($checkprivs)) {
2419 $user_form .= __('database-specific');
2421 $user_form .= __('wildcard'). ': <tt>' . htmlspecialchars($current['Db']) . '</tt>';
2427 . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($current, true)) . "\n"
2431 . ' ' . ($current['Grant_priv'] == 'Y' ?
__('Yes') : __('No')) . "\n"
2434 $user_form .= sprintf(
2436 urlencode($current_user),
2437 urlencode($current_host),
2438 urlencode(! isset($current['Db']) ||
$current['Db'] == '*' ?
'' : $current['Db']),
2441 $user_form .= '</td>' . "\n"
2443 if (($i +
1) < count($current_privileges)) {
2444 $user_form .= '<tr class="noclick ' . ($odd_row ?
'odd' : 'even') . '">' . "\n";
2447 if (empty($row) && empty($row1) && empty($row2)) {
2450 $odd_row = ! $odd_row;
2453 $user_form .= ' <tr class="odd">' . "\n"
2454 . ' <td colspan="6">' . "\n"
2455 . ' ' . __('No user found.') . "\n"
2459 $user_form .= '</tbody>' . "\n"
2460 . '</table></fieldset></form>' . "\n";
2462 if ($GLOBALS['is_ajax_request'] == true) {
2463 $extra_data['user_form'] = $user_form;
2464 $message = PMA_Message
::success(__('User has been added.'));
2465 PMA_ajaxResponse($message, $message->isSuccess(), $extra_data);
2467 // Offer to create a new user for the current database
2468 $user_form .= '<fieldset id="fieldset_add_user">' . "\n"
2469 . '<legend>' . __('New') . '</legend>' . "\n"
2470 . ' <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"
2471 . PMA_getIcon('b_usradd.png')
2472 . ' ' . __('Add user') . '</a>' . "\n"
2473 . '</fieldset>' . "\n";
2477 } // end if (empty($_REQUEST['adduser']) && empty($checkprivs)) ... elseif ... else ...
2481 * Displays the footer
2484 require './libraries/footer.inc.php';