2 /* vim: set expandtab sw=4 ts=4 sts=4: */
12 require_once './libraries/common.inc.php';
15 * Does the common work
17 $GLOBALS['js_include'][] = 'server_privileges.js';
18 $GLOBALS['js_include'][] = 'functions.js';
19 require './libraries/server_common.inc.php';
23 * Checks if a dropdown box has been used for selecting a database / table
25 if (PMA_isValid($_REQUEST['pred_tablename'])) {
26 $tablename = $_REQUEST['pred_tablename'];
27 unset($pred_tablename);
28 } elseif (PMA_isValid($_REQUEST['tablename'])) {
29 $tablename = $_REQUEST['tablename'];
34 if (PMA_isValid($_REQUEST['pred_dbname'])) {
35 $dbname = $_REQUEST['pred_dbname'];
37 } elseif (PMA_isValid($_REQUEST['dbname'])) {
38 $dbname = $_REQUEST['dbname'];
45 $db_and_table = PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . '.';
46 if (isset($tablename)) {
47 $db_and_table .= PMA_backquote($tablename);
52 $db_and_table = '*.*';
55 // check if given $dbname is a wildcard or not
57 //if (preg_match('/\\\\(?:_|%)/i', $dbname)) {
58 if (preg_match('/(?<!\\\\)(?:_|%)/i', $dbname)) {
59 $dbname_is_wildcard = true;
61 $dbname_is_wildcard = false;
66 * Checks if the user is allowed to do what he tries to...
69 require './libraries/server_links.inc.php';
71 . PMA_getIcon('b_usrlist.png')
72 . __('Privileges') . "\n"
74 PMA_Message
::error(__('No Privileges'))->display();
75 require_once './libraries/footer.inc.php';
79 * Escapes wildcard in a database+table specification
80 * before using it in a GRANT statement.
82 * Escaping a wildcard character in a GRANT is only accepted at the global
83 * or database level, not at table level; this is why I remove
84 * the escaping character. Internally, in mysql.tables_priv.Db there are
85 * no escaping (for example test_db) but in mysql.db you'll see test\_db
86 * for a db-specific privilege.
88 * @param string $db_and_table
89 * @param string $dbname
90 * @param string $tablename
91 * @return string the escaped (if necessary) $db_and_table
93 function PMA_WildcardEscapeForGrant($db_and_table, $dbname, $tablename) {
95 if (! strlen($dbname)) {
96 $db_and_table = '*.*';
98 if (strlen($tablename)) {
99 $db_and_table = PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . '.';
100 $db_and_table .= PMA_backquote($tablename);
102 $db_and_table = PMA_backquote($dbname) . '.';
103 $db_and_table .= '*';
106 return $db_and_table;
110 * Generates a condition on the user name
112 * @param string the user's initial
113 * @return string the generated condition
115 function PMA_RangeOfUsers($initial = '')
117 // strtolower() is used because the User field
118 // might be BINARY, so LIKE would be case sensitive
119 if (!empty($initial)) {
120 $ret = " WHERE `User` LIKE '" . $initial . "%'"
121 . " OR `User` LIKE '" . strtolower($initial) . "%'";
129 * Extracts the privilege information of a priv table row
131 * @param array $row the row
132 * @param boolean $enableHTML add <dfn> tag with tooltips
134 * @global ressource $user_link the database connection
138 function PMA_extractPrivInfo($row = '', $enableHTML = FALSE)
141 array('Select_priv', 'SELECT', __('Allows reading data.')),
142 array('Insert_priv', 'INSERT', __('Allows inserting and replacing data.')),
143 array('Update_priv', 'UPDATE', __('Allows changing data.')),
144 array('Delete_priv', 'DELETE', __('Allows deleting data.')),
145 array('Create_priv', 'CREATE', __('Allows creating new databases and tables.')),
146 array('Drop_priv', 'DROP', __('Allows dropping databases and tables.')),
147 array('Reload_priv', 'RELOAD', __('Allows reloading server settings and flushing the server\'s caches.')),
148 array('Shutdown_priv', 'SHUTDOWN', __('Allows shutting down the server.')),
149 array('Process_priv', 'PROCESS', __('Allows viewing processes of all users')),
150 array('File_priv', 'FILE', __('Allows importing data from and exporting data into files.')),
151 array('References_priv', 'REFERENCES', __('Has no effect in this MySQL version.')),
152 array('Index_priv', 'INDEX', __('Allows creating and dropping indexes.')),
153 array('Alter_priv', 'ALTER', __('Allows altering the structure of existing tables.')),
154 array('Show_db_priv', 'SHOW DATABASES', __('Gives access to the complete list of databases.')),
155 array('Super_priv', '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.')),
156 array('Create_tmp_table_priv', 'CREATE TEMPORARY TABLES', __('Allows creating temporary tables.')),
157 array('Lock_tables_priv', 'LOCK TABLES', __('Allows locking tables for the current thread.')),
158 array('Repl_slave_priv', 'REPLICATION SLAVE', __('Needed for the replication slaves.')),
159 array('Repl_client_priv', 'REPLICATION CLIENT', __('Allows the user to ask where the slaves / masters are.')),
160 array('Create_view_priv', 'CREATE VIEW', __('Allows creating new views.')),
161 array('Event_priv', 'EVENT', __('Allows to set up events for the event scheduler')),
162 array('Trigger_priv', 'TRIGGER', __('Allows creating and dropping triggers')),
164 array('Create View_priv', 'CREATE VIEW', __('Allows creating new views.')),
165 array('Show_view_priv', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')),
167 array('Show view_priv', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')),
168 array('Create_routine_priv', 'CREATE ROUTINE', __('Allows creating stored routines.')),
169 array('Alter_routine_priv', 'ALTER ROUTINE', __('Allows altering and dropping stored routines.')),
170 array('Create_user_priv', 'CREATE USER', __('Allows creating, dropping and renaming user accounts.')),
171 array('Execute_priv', 'EXECUTE', __('Allows executing stored routines.')),
174 if (!empty($row) && isset($row['Table_priv'])) {
175 $row1 = PMA_DBI_fetch_single_row(
176 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
177 'ASSOC', $GLOBALS['userlink']);
178 $av_grants = explode('\',\'', substr($row1['Type'], 5, strlen($row1['Type']) - 7));
180 $users_grants = explode(',', $row['Table_priv']);
181 foreach ($av_grants as $current_grant) {
182 $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ?
'Y' : 'N';
184 unset($current_grant);
186 unset($users_grants);
189 $allPrivileges = TRUE;
190 foreach ($grants as $current_grant) {
191 if ((!empty($row) && isset($row[$current_grant[0]]))
192 ||
(empty($row) && isset($GLOBALS[$current_grant[0]]))) {
193 if ((!empty($row) && $row[$current_grant[0]] == 'Y')
195 && ($GLOBALS[$current_grant[0]] == 'Y'
196 ||
(is_array($GLOBALS[$current_grant[0]])
197 && count($GLOBALS[$current_grant[0]]) == $GLOBALS['column_count']
198 && empty($GLOBALS[$current_grant[0] . '_none'])))))
201 $privs[] = '<dfn title="' . $current_grant[2] . '">' . $current_grant[1] . '</dfn>';
203 $privs[] = $current_grant[1];
205 } elseif (!empty($GLOBALS[$current_grant[0]])
206 && is_array($GLOBALS[$current_grant[0]])
207 && empty($GLOBALS[$current_grant[0] . '_none'])) {
209 $priv_string = '<dfn title="' . $current_grant[2] . '">' . $current_grant[1] . '</dfn>';
211 $priv_string = $current_grant[1];
213 $privs[] = $priv_string . ' (`' . join('`, `', $GLOBALS[$current_grant[0]]) . '`)';
215 $allPrivileges = FALSE;
221 $privs[] = '<dfn title="' . __('No privileges.') . '">USAGE</dfn>';
225 } elseif ($allPrivileges && (!isset($GLOBALS['grant_count']) ||
count($privs) == $GLOBALS['grant_count'])) {
227 $privs = array('<dfn title="' . __('Includes all privileges except GRANT.') . '">ALL PRIVILEGES</dfn>');
229 $privs = array('ALL PRIVILEGES');
233 } // end of the 'PMA_extractPrivInfo()' function
236 * Displays on which column(s) a table-specific privilege is granted
238 function PMA_display_column_privs($columns, $row, $name_for_select,
239 $priv_for_header, $name, $name_for_dfn, $name_for_current)
241 echo ' <div class="item" id="div_item_' . $name . '">' . "\n"
242 . ' <label for="select_' . $name . '_priv">' . "\n"
243 . ' <tt><dfn title="' . $name_for_dfn . '">'
244 . $priv_for_header . '</dfn></tt>' . "\n"
245 . ' </label><br />' . "\n"
246 . ' <select id="select_' . $name . '_priv" name="'
247 . $name_for_select . '[]" multiple="multiple" size="8">' . "\n";
249 foreach ($columns as $current_column => $current_column_privileges) {
250 echo ' <option value="' . htmlspecialchars($current_column) . '"';
251 if ($row[$name_for_select] == 'Y' ||
$current_column_privileges[$name_for_current]) {
252 echo ' selected="selected"';
254 echo '>' . htmlspecialchars($current_column) . '</option>' . "\n";
257 echo ' </select>' . "\n"
258 . ' <i>' . __('Or') . '</i>' . "\n"
259 . ' <label for="checkbox_' . $name_for_select
260 . '_none"><input type="checkbox"'
261 . (empty($GLOBALS['checkall']) ?
'' : ' checked="checked"')
262 . ' name="' . $name_for_select . '_none" id="checkbox_'
263 . $name_for_select . '_none" title="' . _pgettext('None privileges', 'None') . '" />'
264 . _pgettext('None privileges', 'None') . '</label>' . "\n"
270 * Displays the privileges form table
272 * @param string $db the database
273 * @param string $table the table
274 * @param boolean $submit wheather to display the submit button or not
275 * @global array $cfg the phpMyAdmin configuration
276 * @global ressource $user_link the database connection
280 function PMA_displayPrivTable($db = '*', $table = '*', $submit = TRUE)
286 if (isset($GLOBALS['username'])) {
287 $username = $GLOBALS['username'];
288 $hostname = $GLOBALS['hostname'];
291 "SELECT * FROM `mysql`.`user`"
292 ." WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
293 ." AND `Host` = '" . PMA_sqlAddslashes($hostname) . "';";
294 } elseif ($table == '*') {
296 "SELECT * FROM `mysql`.`db`"
297 ." WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
298 ." AND `Host` = '" . PMA_sqlAddslashes($hostname) . "'"
299 ." AND '" . PMA_unescape_mysql_wildcards($db) . "'"
303 "SELECT `Table_priv`"
304 ." FROM `mysql`.`tables_priv`"
305 ." WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
306 ." AND `Host` = '" . PMA_sqlAddslashes($hostname) . "'"
307 ." AND `Db` = '" . PMA_unescape_mysql_wildcards($db) . "'"
308 ." AND `Table_name` = '" . PMA_sqlAddslashes($table) . "';";
310 $row = PMA_DBI_fetch_single_row($sql_query);
315 $sql_query = 'SHOW COLUMNS FROM `mysql`.`user`;';
316 } elseif ($table == '*') {
317 $sql_query = 'SHOW COLUMNS FROM `mysql`.`db`;';
319 $res = PMA_DBI_query($sql_query);
320 while ($row1 = PMA_DBI_fetch_row($res)) {
321 if (substr($row1[0], 0, 4) == 'max_') {
324 $row[$row1[0]] = 'N';
327 PMA_DBI_free_result($res);
329 $row = array('Table_priv' => '');
332 if (isset($row['Table_priv'])) {
333 $row1 = PMA_DBI_fetch_single_row(
334 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
335 'ASSOC', $GLOBALS['userlink']);
336 // note: in MySQL 5.0.3 we get "Create View', 'Show view';
337 // the View for Create is spelled with uppercase V
338 // the view for Show is spelled with lowercase v
339 // and there is a space between the words
341 $av_grants = explode('\',\'', substr($row1['Type'], strpos($row1['Type'], '(') +
2, strpos($row1['Type'], ')') - strpos($row1['Type'], '(') - 3));
343 $users_grants = explode(',', $row['Table_priv']);
345 foreach ($av_grants as $current_grant) {
346 $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ?
'Y' : 'N';
348 unset($row['Table_priv'], $current_grant, $av_grants, $users_grants);
351 $res = PMA_DBI_try_query('SHOW COLUMNS FROM ' . PMA_backquote(PMA_unescape_mysql_wildcards($db)) . '.' . PMA_backquote($table) . ';');
354 while ($row1 = PMA_DBI_fetch_row($res)) {
355 $columns[$row1[0]] = array(
359 'References' => FALSE
362 PMA_DBI_free_result($res);
366 // t a b l e - s p e c i f i c p r i v i l e g e s
367 if (! empty($columns)) {
368 $res = PMA_DBI_query(
369 'SELECT `Column_name`, `Column_priv`'
370 .' FROM `mysql`.`columns_priv`'
372 .' = \'' . PMA_sqlAddslashes($username) . "'"
374 .' = \'' . PMA_sqlAddslashes($hostname) . "'"
376 .' = \'' . PMA_sqlAddslashes(PMA_unescape_mysql_wildcards($db)) . "'"
378 .' = \'' . PMA_sqlAddslashes($table) . '\';');
380 while ($row1 = PMA_DBI_fetch_row($res)) {
381 $row1[1] = explode(',', $row1[1]);
382 foreach ($row1[1] as $current) {
383 $columns[$row1[0]][$current] = TRUE;
386 PMA_DBI_free_result($res);
387 unset($res, $row1, $current);
389 echo '<input type="hidden" name="grant_count" value="' . count($row) . '" />' . "\n"
390 . '<input type="hidden" name="column_count" value="' . count($columns) . '" />' . "\n"
391 . '<fieldset id="fieldset_user_priv">' . "\n"
392 . ' <legend>' . __('Table-specific privileges')
393 . PMA_showHint(__(' Note: MySQL privilege names are expressed in English '))
394 . '</legend>' . "\n";
398 // privs that are attached to a specific column
399 PMA_display_column_privs($columns, $row, 'Select_priv',
400 'SELECT', 'select', __('Allows reading data.'), 'Select');
402 PMA_display_column_privs($columns, $row, 'Insert_priv',
403 'INSERT', 'insert', __('Allows inserting and replacing data.'), 'Insert');
405 PMA_display_column_privs($columns, $row, 'Update_priv',
406 'UPDATE', 'update', __('Allows changing data.'), 'Update');
408 PMA_display_column_privs($columns, $row, 'References_priv',
409 'REFERENCES', 'references', __('Has no effect in this MySQL version.'), 'References');
411 // privs that are not attached to a specific column
413 echo ' <div class="item">' . "\n";
414 foreach ($row as $current_grant => $current_grant_value) {
415 if (in_array(substr($current_grant, 0, (strlen($current_grant) - 5)),
416 array('Select', 'Insert', 'Update', 'References'))) {
419 // make a substitution to match the messages variables;
420 // also we must substitute the grant we get, because we can't generate
421 // a form variable containing blanks (those would get changed to
422 // an underscore when receiving the POST)
423 if ($current_grant == 'Create View_priv') {
424 $tmp_current_grant = 'CreateView_priv';
425 $current_grant = 'Create_view_priv';
426 } elseif ($current_grant == 'Show view_priv') {
427 $tmp_current_grant = 'ShowView_priv';
428 $current_grant = 'Show_view_priv';
430 $tmp_current_grant = $current_grant;
433 echo ' <div class="item">' . "\n"
434 . ' <input type="checkbox"'
435 . (empty($GLOBALS['checkall']) ?
'' : ' checked="checked"')
436 . ' name="' . $current_grant . '" id="checkbox_' . $current_grant
438 . ($current_grant_value == 'Y' ?
'checked="checked" ' : '')
441 echo (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))])
442 ?
$GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))]
443 : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)) . 'Tbl']) . '"/>' . "\n";
445 echo ' <label for="checkbox_' . $current_grant
446 . '"><tt><dfn title="'
447 . (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))])
448 ?
$GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))]
449 : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)) . 'Tbl'])
450 . '">' . strtoupper(substr($current_grant, 0, strlen($current_grant) - 5)) . '</dfn></tt></label>' . "\n"
454 echo ' </div>' . "\n";
456 echo ' <div class="clearfloat"></div>' . "\n";
460 // g l o b a l o r d b - s p e c i f i c
463 $privTable[0] = array(
464 array('Select', 'SELECT', __('Allows reading data.')),
465 array('Insert', 'INSERT', __('Allows inserting and replacing data.')),
466 array('Update', 'UPDATE', __('Allows changing data.')),
467 array('Delete', 'DELETE', __('Allows deleting data.'))
470 $privTable[0][] = array('File', 'FILE', __('Allows importing data from and exporting data into files.'));
474 $privTable[1] = array(
475 array('Create', 'CREATE', ($table == '*' ?
__('Allows creating new databases and tables.') : __('Allows creating new tables.'))),
476 array('Alter', 'ALTER', __('Allows altering the structure of existing tables.')),
477 array('Index', 'INDEX', __('Allows creating and dropping indexes.')),
478 array('Drop', 'DROP', ($table == '*' ?
__('Allows dropping databases and tables.') : __('Allows dropping tables.'))),
479 array('Create_tmp_table', 'CREATE TEMPORARY TABLES', __('Allows creating temporary tables.')),
480 array('Show_view', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')),
481 array('Create_routine', 'CREATE ROUTINE', __('Allows creating stored routines.')),
482 array('Alter_routine', 'ALTER ROUTINE', __('Allows altering and dropping stored routines.')),
483 array('Execute', 'EXECUTE', __('Allows executing stored routines.')),
485 // this one is for a db-specific priv: Create_view_priv
486 if (isset($row['Create_view_priv'])) {
487 $privTable[1][] = array('Create_view', 'CREATE VIEW', __('Allows creating new views.'));
489 // this one is for a table-specific priv: Create View_priv
490 if (isset($row['Create View_priv'])) {
491 $privTable[1][] = array('Create View', 'CREATE VIEW', __('Allows creating new views.'));
493 if (isset($row['Event_priv'])) {
495 $privTable[1][] = array('Event', 'EVENT', __('Allows to set up events for the event scheduler'));
496 $privTable[1][] = array('Trigger', 'TRIGGER', __('Allows creating and dropping triggers'));
499 // a d m i n i s t r a t i o n
500 $privTable[2] = array(
501 array('Grant', 'GRANT', __('Allows adding users and privileges without reloading the privilege tables.')),
504 $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.'));
505 $privTable[2][] = array('Process', 'PROCESS', __('Allows viewing processes of all users'));
506 $privTable[2][] = array('Reload', 'RELOAD', __('Allows reloading server settings and flushing the server\'s caches.'));
507 $privTable[2][] = array('Shutdown', 'SHUTDOWN', __('Allows shutting down the server.'));
508 $privTable[2][] = array('Show_db', 'SHOW DATABASES', __('Gives access to the complete list of databases.'));
510 $privTable[2][] = array('Lock_tables', 'LOCK TABLES', __('Allows locking tables for the current thread.'));
511 $privTable[2][] = array('References', 'REFERENCES', __('Has no effect in this MySQL version.'));
513 $privTable[2][] = array('Repl_client', 'REPLICATION CLIENT', __('Allows the user to ask where the slaves / masters are.'));
514 $privTable[2][] = array('Repl_slave', 'REPLICATION SLAVE', __('Needed for the replication slaves.'));
515 $privTable[2][] = array('Create_user', 'CREATE USER', __('Allows creating, dropping and renaming user accounts.'));
517 echo '<input type="hidden" name="grant_count" value="'
518 . (count($privTable[0]) +
count($privTable[1]) +
count($privTable[2]) - (isset($row['Grant_priv']) ?
1 : 0))
520 . '<fieldset id="fieldset_user_global_rights">' . "\n"
524 ?
__('Global privileges')
526 ?
__('Database-specific privileges')
527 : __('Table-specific privileges'))) . "\n"
528 . ' (<a href="server_privileges.php?'
529 . $GLOBALS['url_query'] . '&checkall=1" onclick="setCheckboxes(\'usersForm\', true); return false;">'
530 . __('Check All') . '</a> /' . "\n"
531 . ' <a href="server_privileges.php?'
532 . $GLOBALS['url_query'] . '" onclick="setCheckboxes(\'usersForm\', false); return false;">'
533 . __('Uncheck All') . '</a>)' . "\n"
534 . ' </legend>' . "\n"
535 . ' <p><small><i>' . __(' Note: MySQL privilege names are expressed in English ') . '</i></small></p>' . "\n"
536 . ' <fieldset>' . "\n"
537 . ' <legend>' . __('Data') . '</legend>' . "\n";
538 foreach ($privTable[0] as $priv)
540 echo ' <div class="item">' . "\n"
541 . ' <input type="checkbox"'
542 . (empty($GLOBALS['checkall']) ?
'' : ' checked="checked"')
543 . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0]
544 . '_priv" value="Y" '
545 . ($row[$priv[0] . '_priv'] == 'Y' ?
'checked="checked" ' : '')
546 . 'title="' . $priv[2] . '"/>' . "\n"
547 . ' <label for="checkbox_' . $priv[0]
548 . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1]
549 . '</dfn></tt></label>' . "\n"
552 echo ' </fieldset>' . "\n"
553 . ' <fieldset>' . "\n"
554 . ' <legend>' . __('Structure') . '</legend>' . "\n";
555 foreach ($privTable[1] as $priv)
557 echo ' <div class="item">' . "\n"
558 . ' <input type="checkbox"'
559 . (empty($GLOBALS['checkall']) ?
'' : ' checked="checked"')
560 . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0]
561 . '_priv" value="Y" '
562 . ($row[$priv[0] . '_priv'] == 'Y' ?
'checked="checked" ' : '')
563 . 'title="' . $priv[2] . '"/>' . "\n"
564 . ' <label for="checkbox_' . $priv[0]
565 . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1]
566 . '</dfn></tt></label>' . "\n"
569 echo ' </fieldset>' . "\n"
570 . ' <fieldset>' . "\n"
571 . ' <legend>' . __('Administration') . '</legend>' . "\n";
572 foreach ($privTable[2] as $priv)
574 echo ' <div class="item">' . "\n"
575 . ' <input type="checkbox"'
576 . (empty($GLOBALS['checkall']) ?
'' : ' checked="checked"')
577 . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0]
578 . '_priv" value="Y" '
579 . ($row[$priv[0] . '_priv'] == 'Y' ?
'checked="checked" ' : '')
580 . 'title="' . $priv[2] . '"/>' . "\n"
581 . ' <label for="checkbox_' . $priv[0]
582 . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1]
583 . '</dfn></tt></label>' . "\n"
587 echo ' </fieldset>' . "\n";
588 // The "Resource limits" box is not displayed for db-specific privs
590 echo ' <fieldset>' . "\n"
591 . ' <legend>' . __('Resource limits') . '</legend>' . "\n"
592 . ' <p><small><i>' . __('Note: Setting these options to 0 (zero) removes the limit.') . '</i></small></p>' . "\n"
593 . ' <div class="item">' . "\n"
594 . ' <label for="text_max_questions"><tt><dfn title="'
595 . __('Limits the number of queries the user may send to the server per hour.') . '">MAX QUERIES PER HOUR</dfn></tt></label>' . "\n"
596 . ' <input type="text" name="max_questions" id="text_max_questions" value="'
597 . $row['max_questions'] . '" size="11" maxlength="11" title="' . __('Limits the number of queries the user may send to the server per hour.') . '" />' . "\n"
599 . ' <div class="item">' . "\n"
600 . ' <label for="text_max_updates"><tt><dfn title="'
601 . __('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"
602 . ' <input type="text" name="max_updates" id="text_max_updates" value="'
603 . $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"
605 . ' <div class="item">' . "\n"
606 . ' <label for="text_max_connections"><tt><dfn title="'
607 . __('Limits the number of new connections the user may open per hour.') . '">MAX CONNECTIONS PER HOUR</dfn></tt></label>' . "\n"
608 . ' <input type="text" name="max_connections" id="text_max_connections" value="'
609 . $row['max_connections'] . '" size="11" maxlength="11" title="' . __('Limits the number of new connections the user may open per hour.') . '" />' . "\n"
611 . ' <div class="item">' . "\n"
612 . ' <label for="text_max_user_connections"><tt><dfn title="'
613 . __('Limits the number of simultaneous connections the user may have.') . '">MAX USER_CONNECTIONS</dfn></tt></label>' . "\n"
614 . ' <input type="text" name="max_user_connections" id="text_max_user_connections" value="'
615 . $row['max_user_connections'] . '" size="11" maxlength="11" title="' . __('Limits the number of simultaneous connections the user may have.') . '" />' . "\n"
617 . ' </fieldset>' . "\n";
620 echo ' <div class="clearfloat"></div>' . "\n";
622 echo '</fieldset>' . "\n";
624 echo '<fieldset id="fieldset_user_privtable_footer" class="tblFooters">' . "\n"
625 . ' <input type="submit" name="update_privs" value="' . __('Go') . '" />' . "\n"
626 . '</fieldset>' . "\n";
628 } // end of the 'PMA_displayPrivTable()' function
632 * Displays the fields used by the "new user" form as well as the
633 * "change login information / copy user" form.
635 * @param string $mode are we creating a new user or are we just
636 * changing one? (allowed values: 'new', 'change')
637 * @global array $cfg the phpMyAdmin configuration
638 * @global ressource $user_link the database connection
642 function PMA_displayLoginInformationFields($mode = 'new')
644 // Get user/host name lengths
645 $fields_info = PMA_DBI_get_fields('mysql', 'user');
646 $username_length = 16;
647 $hostname_length = 41;
648 foreach ($fields_info as $key => $val) {
649 if ($val['Field'] == 'User') {
650 strtok($val['Type'], '()');
653 $username_length = $v;
655 } elseif ($val['Field'] == 'Host') {
656 strtok($val['Type'], '()');
659 $hostname_length = $v;
665 if (isset($GLOBALS['username']) && strlen($GLOBALS['username']) === 0) {
666 $GLOBALS['pred_username'] = 'any';
668 echo '<fieldset id="fieldset_add_user_login">' . "\n"
669 . '<legend>' . __('Login Information') . '</legend>' . "\n"
670 . '<div class="item">' . "\n"
671 . '<label for="select_pred_username">' . "\n"
672 . ' ' . __('User name') . ':' . "\n"
674 . '<span class="options">' . "\n"
675 . ' <select name="pred_username" id="select_pred_username" title="' . __('User name') . '"' . "\n"
676 . ' onchange="if (this.value == \'any\') { username.value = \'\'; } else if (this.value == \'userdefined\') { username.focus(); username.select(); }">' . "\n"
677 . ' <option value="any"' . ((isset($GLOBALS['pred_username']) && $GLOBALS['pred_username'] == 'any') ?
' selected="selected"' : '') . '>' . __('Any user') . '</option>' . "\n"
678 . ' <option value="userdefined"' . ((!isset($GLOBALS['pred_username']) ||
$GLOBALS['pred_username'] == 'userdefined') ?
' selected="selected"' : '') . '>' . __('Use text field') . ':</option>' . "\n"
679 . ' </select>' . "\n"
681 . '<input type="text" name="username" maxlength="'
682 . $username_length . '" title="' . __('User name') . '"'
683 . (empty($GLOBALS['username'])
685 : ' value="' . htmlspecialchars(isset($GLOBALS['new_username'])
686 ?
$GLOBALS['new_username']
687 : $GLOBALS['username']) . '"')
688 . ' onchange="pred_username.value = \'userdefined\';" />' . "\n"
690 . '<div class="item">' . "\n"
691 . '<label for="select_pred_hostname">' . "\n"
692 . ' ' . __('Host') . ':' . "\n"
694 . '<span class="options">' . "\n"
695 . ' <select name="pred_hostname" id="select_pred_hostname" title="' . __('Host') . '"' . "\n";
696 $_current_user = PMA_DBI_fetch_value('SELECT USER();');
697 if (! empty($_current_user)) {
698 $thishost = str_replace("'", '', substr($_current_user, (strrpos($_current_user, '@') +
1)));
699 if ($thishost == 'localhost' ||
$thishost == '127.0.0.1') {
703 echo ' onchange="if (this.value == \'any\') { hostname.value = \'%\'; } else if (this.value == \'localhost\') { hostname.value = \'localhost\'; } '
704 . (empty($thishost) ?
'' : 'else if (this.value == \'thishost\') { hostname.value = \'' . addslashes(htmlspecialchars($thishost)) . '\'; } ')
705 . 'else if (this.value == \'hosttable\') { hostname.value = \'\'; } else if (this.value == \'userdefined\') { hostname.focus(); hostname.select(); }">' . "\n";
706 unset($_current_user);
708 // when we start editing a user, $GLOBALS['pred_hostname'] is not defined
709 if (!isset($GLOBALS['pred_hostname']) && isset($GLOBALS['hostname'])) {
710 switch (strtolower($GLOBALS['hostname'])) {
713 $GLOBALS['pred_hostname'] = 'localhost';
716 $GLOBALS['pred_hostname'] = 'any';
719 $GLOBALS['pred_hostname'] = 'userdefined';
723 echo ' <option value="any"'
724 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'any')
725 ?
' selected="selected"' : '') . '>' . __('Any host')
727 . ' <option value="localhost"'
728 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'localhost')
729 ?
' selected="selected"' : '') . '>' . __('Local')
730 . '</option>' . "\n";
731 if (!empty($thishost)) {
732 echo ' <option value="thishost"'
733 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'thishost')
734 ?
' selected="selected"' : '') . '>' . __('This Host')
735 . '</option>' . "\n";
738 echo ' <option value="hosttable"'
739 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'hosttable')
740 ?
' selected="selected"' : '') . '>' . __('Use Host Table')
742 . ' <option value="userdefined"'
743 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'userdefined')
744 ?
' selected="selected"' : '')
745 . '>' . __('Use text field') . ':</option>' . "\n"
746 . ' </select>' . "\n"
748 . '<input type="text" name="hostname" maxlength="'
749 . $hostname_length . '" value="'
750 . htmlspecialchars(isset($GLOBALS['hostname']) ?
$GLOBALS['hostname'] : '')
751 . '" title="' . __('Host')
752 . '" onchange="pred_hostname.value = \'userdefined\';" />' . "\n"
753 . PMA_showHint(__('When Host table is used, this field is ignored and values stored in Host table are used instead.'))
755 . '<div class="item">' . "\n"
756 . '<label for="select_pred_password">' . "\n"
757 . ' ' . __('Password') . ':' . "\n"
759 . '<span class="options">' . "\n"
760 . ' <select name="pred_password" id="select_pred_password" title="'
761 . __('Password') . '"' . "\n"
762 . ' onchange="if (this.value == \'none\') { pma_pw.value = \'\'; pma_pw2.value = \'\'; } else if (this.value == \'userdefined\') { pma_pw.focus(); pma_pw.select(); }">' . "\n"
763 . ($mode == 'change' ?
' <option value="keep" selected="selected">' . __('Do not change the password') . '</option>' . "\n" : '')
764 . ' <option value="none"';
765 if (isset($GLOBALS['username']) && $mode != 'change') {
766 echo ' selected="selected"';
768 echo '>' . __('No Password') . '</option>' . "\n"
769 . ' <option value="userdefined"' . (isset($GLOBALS['username']) ?
'' : ' selected="selected"') . '>' . __('Use text field') . ':</option>' . "\n"
770 . ' </select>' . "\n"
772 . '<input type="password" id="text_pma_pw" name="pma_pw" title="' . __('Password') . '" onchange="pred_password.value = \'userdefined\';" />' . "\n"
774 . '<div class="item">' . "\n"
775 . '<label for="text_pma_pw2">' . "\n"
776 . ' ' . __('Re-type') . ':' . "\n"
778 . '<span class="options"> </span>' . "\n"
779 . '<input type="password" name="pma_pw2" id="text_pma_pw2" title="' . __('Re-type') . '" onchange="pred_password.value = \'userdefined\';" />' . "\n"
781 . '<div class="item">' . "\n"
782 . '<label for="button_generate_password">' . "\n"
783 . ' ' . __('Generate Password') . ':' . "\n"
785 . '<span class="options">' . "\n"
786 . ' <input type="button" id="button_generate_password" value="' . __('Generate') . '" onclick="suggestPassword(this.form)" />' . "\n"
788 . '<input type="text" name="generated_pw" id="generated_pw" />' . "\n"
790 . '</fieldset>' . "\n";
791 } // end of the 'PMA_displayUserAndHostFields()' function
794 * Changes / copies a user, part I
796 if (isset($_REQUEST['change_copy'])) {
797 $user_host_condition =
799 .' = \'' . PMA_sqlAddslashes($old_username) . "'"
801 .' = \'' . PMA_sqlAddslashes($old_hostname) . '\';';
802 $row = PMA_DBI_fetch_single_row('SELECT * FROM `mysql`.`user` ' . $user_host_condition);
804 PMA_Message
::notice(__('No user found.'))->display();
805 unset($_REQUEST['change_copy']);
807 extract($row, EXTR_OVERWRITE
);
808 // Recent MySQL versions have the field "Password" in mysql.user,
809 // so the previous extract creates $Password but this script
811 if (!isset($password) && isset($Password)) {
812 $password = $Password;
821 * (Changes / copies a user, part II)
823 if (isset($_REQUEST['adduser_submit']) ||
isset($_REQUEST['change_copy'])) {
825 if ($pred_username == 'any') {
828 switch ($pred_hostname) {
833 $hostname = 'localhost';
839 $_user_name = PMA_DBI_fetch_value('SELECT USER()');
840 $hostname = substr($_user_name, (strrpos($_user_name, '@') +
1));
844 $sql = "SELECT '1' FROM `mysql`.`user`"
845 . " WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
846 . " AND `Host` = '" . PMA_sqlAddslashes($hostname) . "';";
847 if (PMA_DBI_fetch_value($sql) == 1) {
848 $message = PMA_Message
::error(__('The user %s already exists!'));
849 $message->addParam('[i]\'' . $username . '\'@\'' . $hostname . '\'[/i]');
850 $_REQUEST['adduser'] = true;
853 $create_user_real = 'CREATE USER \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\'';
856 'GRANT ' . join(', ', PMA_extractPrivInfo()) . ' ON *.* TO \''
857 . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\'';
858 if ($pred_password != 'none' && $pred_password != 'keep') {
859 $sql_query = $real_sql_query . ' IDENTIFIED BY \'***\'';
860 $real_sql_query .= ' IDENTIFIED BY \'' . PMA_sqlAddslashes($pma_pw) . '\'';
861 if (isset($create_user_real)) {
862 $create_user_show = $create_user_real . ' IDENTIFIED BY \'***\'';
863 $create_user_real .= ' IDENTIFIED BY \'' . PMA_sqlAddslashes($pma_pw) . '\'';
866 if ($pred_password == 'keep' && !empty($password)) {
867 $real_sql_query .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
868 if (isset($create_user_real)) {
869 $create_user_real .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
872 $sql_query = $real_sql_query;
873 if (isset($create_user_real)) {
874 $create_user_show = $create_user_real;
878 * @todo similar code appears twice in this script
880 if ((isset($Grant_priv) && $Grant_priv == 'Y')
881 ||
(isset($max_questions) ||
isset($max_connections)
882 ||
isset($max_updates) ||
isset($max_user_connections))) {
883 $real_sql_query .= ' WITH';
884 $sql_query .= ' WITH';
885 if (isset($Grant_priv) && $Grant_priv == 'Y') {
886 $real_sql_query .= ' GRANT OPTION';
887 $sql_query .= ' GRANT OPTION';
889 if (isset($max_questions)) {
890 // avoid negative values
891 $max_questions = max(0, (int)$max_questions);
892 $real_sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
893 $sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
895 if (isset($max_connections)) {
896 $max_connections = max(0, (int)$max_connections);
897 $real_sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
898 $sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
900 if (isset($max_updates)) {
901 $max_updates = max(0, (int)$max_updates);
902 $real_sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
903 $sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
905 if (isset($max_user_connections)) {
906 $max_user_connections = max(0, (int)$max_user_connections);
907 $real_sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
908 $sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
911 if (isset($create_user_real)) {
912 $create_user_real .= ';';
913 $create_user_show .= ';';
915 $real_sql_query .= ';';
917 if (empty($_REQUEST['change_copy'])) {
920 if (isset($create_user_real)) {
921 if (! PMA_DBI_try_query($create_user_real)) {
924 $sql_query = $create_user_show . $sql_query;
927 if ($_error ||
! PMA_DBI_try_query($real_sql_query)) {
928 $_REQUEST['createdb'] = false;
929 $message = PMA_Message
::rawError(PMA_DBI_getError());
931 $message = PMA_Message
::success(__('You have added a new user.'));
934 switch (PMA_ifSetOr($_REQUEST['createdb'], '0')) {
936 // Create database with same name and grant all privileges
937 $q = 'CREATE DATABASE IF NOT EXISTS '
938 . PMA_backquote(PMA_sqlAddslashes($username)) . ';';
940 if (! PMA_DBI_try_query($q)) {
941 $message = PMA_Message
::rawError(PMA_DBI_getError());
944 $GLOBALS['reload'] = TRUE;
945 PMA_reloadNavigation();
947 $q = 'GRANT ALL PRIVILEGES ON '
948 . PMA_backquote(PMA_sqlAddslashes($username)) . '.* TO \''
949 . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
951 if (! PMA_DBI_try_query($q)) {
952 $message = PMA_Message
::rawError(PMA_DBI_getError());
956 // Grant all privileges on wildcard name (username\_%)
957 $q = 'GRANT ALL PRIVILEGES ON '
958 . PMA_backquote(PMA_sqlAddslashes($username) . '\_%') . '.* TO \''
959 . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
961 if (! PMA_DBI_try_query($q)) {
962 $message = PMA_Message
::rawError(PMA_DBI_getError());
966 // Grant all privileges on the specified database to the new user
967 $q = 'GRANT ALL PRIVILEGES ON '
968 . PMA_backquote(PMA_sqlAddslashes($dbname)) . '.* TO \''
969 . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
971 if (! PMA_DBI_try_query($q)) {
972 $message = PMA_Message
::rawError(PMA_DBI_getError());
980 if (isset($create_user_real)) {
981 $queries[] = $create_user_real;
983 $queries[] = $real_sql_query;
984 // we put the query containing the hidden password in
985 // $queries_for_display, at the same position occupied
986 // by the real query in $queries
987 $tmp_count = count($queries);
988 if (isset($create_user_real)) {
989 $queries_for_display[$tmp_count - 2] = $create_user_show;
991 $queries_for_display[$tmp_count - 1] = $sql_query;
993 unset($res, $real_sql_query);
999 * Changes / copies a user, part III
1001 if (isset($_REQUEST['change_copy'])) {
1002 $user_host_condition =
1004 .' = \'' . PMA_sqlAddslashes($old_username) . "'"
1006 .' = \'' . PMA_sqlAddslashes($old_hostname) . '\';';
1007 $res = PMA_DBI_query('SELECT * FROM `mysql`.`db`' . $user_host_condition);
1008 while ($row = PMA_DBI_fetch_assoc($res)) {
1010 'GRANT ' . join(', ', PMA_extractPrivInfo($row))
1011 .' ON ' . PMA_backquote($row['Db']) . '.*'
1012 .' TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\''
1013 . ($row['Grant_priv'] == 'Y' ?
' WITH GRANT OPTION;' : ';');
1015 PMA_DBI_free_result($res);
1016 $res = PMA_DBI_query(
1017 'SELECT `Db`, `Table_name`, `Table_priv`'
1018 .' FROM `mysql`.`tables_priv`' . $user_host_condition,
1019 $GLOBALS['userlink'], PMA_DBI_QUERY_STORE
);
1020 while ($row = PMA_DBI_fetch_assoc($res)) {
1022 $res2 = PMA_DBI_QUERY(
1023 'SELECT `Column_name`, `Column_priv`'
1024 .' FROM `mysql`.`columns_priv`'
1026 .' = \'' . PMA_sqlAddslashes($old_username) . "'"
1028 .' = \'' . PMA_sqlAddslashes($old_hostname) . '\''
1030 .' = \'' . PMA_sqlAddslashes($row['Db']) . "'"
1031 .' AND `Table_name`'
1032 .' = \'' . PMA_sqlAddslashes($row['Table_name']) . "'"
1034 null, PMA_DBI_QUERY_STORE
);
1036 $tmp_privs1 = PMA_extractPrivInfo($row);
1037 $tmp_privs2 = array(
1038 'Select' => array(),
1039 'Insert' => array(),
1040 'Update' => array(),
1041 'References' => array()
1044 while ($row2 = PMA_DBI_fetch_assoc($res2)) {
1045 $tmp_array = explode(',', $row2['Column_priv']);
1046 if (in_array('Select', $tmp_array)) {
1047 $tmp_privs2['Select'][] = $row2['Column_name'];
1049 if (in_array('Insert', $tmp_array)) {
1050 $tmp_privs2['Insert'][] = $row2['Column_name'];
1052 if (in_array('Update', $tmp_array)) {
1053 $tmp_privs2['Update'][] = $row2['Column_name'];
1055 if (in_array('References', $tmp_array)) {
1056 $tmp_privs2['References'][] = $row2['Column_name'];
1060 if (count($tmp_privs2['Select']) > 0 && !in_array('SELECT', $tmp_privs1)) {
1061 $tmp_privs1[] = 'SELECT (`' . join('`, `', $tmp_privs2['Select']) . '`)';
1063 if (count($tmp_privs2['Insert']) > 0 && !in_array('INSERT', $tmp_privs1)) {
1064 $tmp_privs1[] = 'INSERT (`' . join('`, `', $tmp_privs2['Insert']) . '`)';
1066 if (count($tmp_privs2['Update']) > 0 && !in_array('UPDATE', $tmp_privs1)) {
1067 $tmp_privs1[] = 'UPDATE (`' . join('`, `', $tmp_privs2['Update']) . '`)';
1069 if (count($tmp_privs2['References']) > 0 && !in_array('REFERENCES', $tmp_privs1)) {
1070 $tmp_privs1[] = 'REFERENCES (`' . join('`, `', $tmp_privs2['References']) . '`)';
1074 'GRANT ' . join(', ', $tmp_privs1)
1075 . ' ON ' . PMA_backquote($row['Db']) . '.' . PMA_backquote($row['Table_name'])
1076 . ' TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\''
1077 . (in_array('Grant', explode(',', $row['Table_priv'])) ?
' WITH GRANT OPTION;' : ';');
1083 * Updates privileges
1085 if (!empty($update_privs)) {
1086 $db_and_table = PMA_WildcardEscapeForGrant($db_and_table, $dbname, (isset($tablename) ?
$tablename : ''));
1089 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
1090 . ' FROM \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1091 if (!isset($Grant_priv) ||
$Grant_priv != 'Y') {
1093 'REVOKE GRANT OPTION ON ' . $db_and_table
1094 . ' FROM \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1099 // Should not do a GRANT USAGE for a table-specific privilege, it
1100 // causes problems later (cannot revoke it)
1101 if (! (isset($tablename) && 'USAGE' == implode('', PMA_extractPrivInfo()))) {
1103 'GRANT ' . join(', ', PMA_extractPrivInfo())
1104 . ' ON ' . $db_and_table
1105 . ' TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\'';
1108 * @todo similar code appears twice in this script
1110 if ((isset($Grant_priv) && $Grant_priv == 'Y')
1111 ||
(! isset($dbname)
1112 && (isset($max_questions) ||
isset($max_connections)
1113 ||
isset($max_updates) ||
isset($max_user_connections))))
1115 $sql_query2 .= 'WITH';
1116 if (isset($Grant_priv) && $Grant_priv == 'Y') {
1117 $sql_query2 .= ' GRANT OPTION';
1119 if (isset($max_questions)) {
1120 $max_questions = max(0, (int)$max_questions);
1121 $sql_query2 .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
1123 if (isset($max_connections)) {
1124 $max_connections = max(0, (int)$max_connections);
1125 $sql_query2 .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
1127 if (isset($max_updates)) {
1128 $max_updates = max(0, (int)$max_updates);
1129 $sql_query2 .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
1131 if (isset($max_user_connections)) {
1132 $max_user_connections = max(0, (int)$max_user_connections);
1133 $sql_query2 .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
1138 if (! PMA_DBI_try_query($sql_query0)) {
1139 // this query may fail, but this does not matter :o)
1142 if (isset($sql_query1) && !PMA_DBI_try_query($sql_query1)) {
1143 // this one may fail, too...
1146 if (isset($sql_query2)) {
1147 PMA_DBI_query($sql_query2);
1151 $sql_query = $sql_query0 . ' ' . $sql_query1 . ' ' . $sql_query2;
1152 $message = PMA_Message
::success(__('You have updated the privileges for %s.'));
1153 $message->addParam('\'' . $username . '\'@\'' . $hostname . '\'');
1158 * Revokes Privileges
1160 if (isset($_REQUEST['revokeall'])) {
1161 $db_and_table = PMA_WildcardEscapeForGrant($db_and_table, $dbname, isset($tablename) ?
$tablename : '');
1164 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
1165 . ' FROM \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1167 'REVOKE GRANT OPTION ON ' . $db_and_table
1168 . ' FROM \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1170 PMA_DBI_query($sql_query0);
1171 if (! PMA_DBI_try_query($sql_query1)) {
1172 // this one may fail, too...
1175 $sql_query = $sql_query0 . ' ' . $sql_query1;
1176 $message = PMA_Message
::success(__('You have revoked the privileges for %s'));
1177 $message->addParam('\'' . $username . '\'@\'' . $hostname . '\'');
1178 if (! isset($tablename)) {
1187 * Updates the password
1189 if (isset($_REQUEST['change_pw'])) {
1190 // similar logic in user_password.php
1193 if ($nopass == 0 && isset($pma_pw) && isset($pma_pw2)) {
1194 if ($pma_pw != $pma_pw2) {
1195 $message = PMA_Message
::error(__('The passwords aren\'t the same!'));
1196 } elseif (empty($pma_pw) ||
empty($pma_pw2)) {
1197 $message = PMA_Message
::error(__('The password is empty!'));
1201 // here $nopass could be == 1
1202 if (empty($message)) {
1204 $hashing_function = (!empty($pw_hash) && $pw_hash == 'old' ?
'OLD_' : '')
1207 // in $sql_query which will be displayed, hide the password
1208 $sql_query = 'SET PASSWORD FOR \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\' = ' . (($pma_pw == '') ?
'\'\'' : $hashing_function . '(\'' . preg_replace('@.@s', '*', $pma_pw) . '\')');
1209 $local_query = 'SET PASSWORD FOR \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\' = ' . (($pma_pw == '') ?
'\'\'' : $hashing_function . '(\'' . PMA_sqlAddslashes($pma_pw) . '\')');
1210 PMA_DBI_try_query($local_query)
1211 or PMA_mysqlDie(PMA_DBI_getError(), $sql_query, FALSE, $err_url);
1212 $message = PMA_Message
::success(__('The password for %s was changed successfully.'));
1213 $message->addParam('\'' . $username . '\'@\'' . $hostname . '\'');
1220 * (Changes / copies a user, part IV)
1223 if (isset($_REQUEST['delete']) ||
(isset($_REQUEST['change_copy']) && $_REQUEST['mode'] < 4)) {
1224 if (isset($_REQUEST['change_copy'])) {
1225 $selected_usr = array($old_username . '&#27;' . $old_hostname);
1227 $selected_usr = $_REQUEST['selected_usr'];
1230 foreach ($selected_usr as $each_user) {
1231 list($this_user, $this_host) = explode('&#27;', $each_user);
1232 $queries[] = '# ' . sprintf(__('Deleting %s'), '\'' . $this_user . '\'@\'' . $this_host . '\'') . ' ...';
1233 $queries[] = 'DROP USER \'' . PMA_sqlAddslashes($this_user) . '\'@\'' . PMA_sqlAddslashes($this_host) . '\';';
1235 if (isset($_REQUEST['drop_users_db'])) {
1236 $queries[] = 'DROP DATABASE IF EXISTS ' . PMA_backquote($this_user) . ';';
1237 $GLOBALS['reload'] = TRUE;
1238 PMA_reloadNavigation();
1241 if (empty($_REQUEST['change_copy'])) {
1242 if (empty($queries)) {
1243 $message = PMA_Message
::error(__('No users selected for deleting!'));
1245 if ($_REQUEST['mode'] == 3) {
1246 $queries[] = '# ' . __('Reloading the privileges') . ' ...';
1247 $queries[] = 'FLUSH PRIVILEGES;';
1249 $drop_user_error = '';
1250 foreach ($queries as $sql_query) {
1251 if ($sql_query{0} != '#') {
1252 if (! PMA_DBI_try_query($sql_query, $GLOBALS['userlink'])) {
1253 $drop_user_error .= PMA_DBI_getError() . "\n";
1257 $sql_query = join("\n", $queries);
1258 if (! empty($drop_user_error)) {
1259 $message = PMA_Message
::rawError($drop_user_error);
1261 $message = PMA_Message
::success(__('The selected users have been deleted successfully.'));
1270 * Changes / copies a user, part V
1272 if (isset($_REQUEST['change_copy'])) {
1274 foreach ($queries as $sql_query) {
1275 if ($sql_query{0} != '#') {
1276 PMA_DBI_query($sql_query);
1278 // when there is a query containing a hidden password, take it
1279 // instead of the real query sent
1280 if (isset($queries_for_display[$tmp_count])) {
1281 $queries[$tmp_count] = $queries_for_display[$tmp_count];
1285 $message = PMA_Message
::success();
1286 $sql_query = join("\n", $queries);
1291 * Reloads the privilege tables into memory
1293 if (isset($_REQUEST['flush_privileges'])) {
1294 $sql_query = 'FLUSH PRIVILEGES;';
1295 PMA_DBI_query($sql_query);
1296 $message = PMA_Message
::success(__('The privileges were reloaded successfully.'));
1301 * Displays the links
1303 if (isset($viewing_mode) && $viewing_mode == 'db') {
1305 $url_query .= '&goto=db_operations.php';
1307 // Gets the database structure
1308 $sub_part = '_structure';
1309 require './libraries/db_info.inc.php';
1312 require './libraries/server_links.inc.php';
1317 * defines some standard links
1319 $link_edit = '<a href="server_privileges.php?' . $GLOBALS['url_query']
1320 . '&username=%s'
1321 . '&hostname=%s'
1323 . '&tablename=%s">'
1324 . PMA_getIcon('b_usredit.png', __('Edit Privileges'))
1327 $link_revoke = '<a href="server_privileges.php?' . $GLOBALS['url_query']
1328 . '&username=%s'
1329 . '&hostname=%s'
1331 . '&tablename=%s'
1332 . '&revokeall=1">'
1333 . PMA_getIcon('b_usrdrop.png', __('Revoke'))
1336 $link_export = '<a href="server_privileges.php?' . $GLOBALS['url_query']
1337 . '&username=%s'
1338 . '&hostname=%s'
1341 . PMA_getIcon('b_tblexport.png', __('Export'))
1348 // export user definition
1349 if (isset($_REQUEST['export'])) {
1350 echo '<h2>' . __('User') . ' \'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'</h2>';
1351 echo '<textarea cols="' . $GLOBALS['cfg']['TextareaCols'] . '" rows="' . $GLOBALS['cfg']['TextareaRows'] . '">';
1352 $grants = PMA_DBI_fetch_result("SHOW GRANTS FOR '" . PMA_sqlAddslashes($username) . "'@'" . PMA_sqlAddslashes($hostname) . "'");
1353 foreach($grants as $one_grant) {
1354 echo $one_grant . ";\n\n";
1357 unset($username, $hostname, $grants, $one_grant);
1360 if (empty($_REQUEST['adduser']) && (! isset($checkprivs) ||
! strlen($checkprivs))) {
1361 if (! isset($username)) {
1362 // No username is given --> display the overview
1364 . PMA_getIcon('b_usrlist.png')
1365 . __('User overview') . "\n"
1370 " IF(`Password` = _latin1 '', 'N', 'Y') AS 'Password'" .
1371 ' FROM `mysql`.`user`';
1373 $sql_query .= (isset($initial) ?
PMA_RangeOfUsers($initial) : '');
1375 $sql_query .= ' ORDER BY `User` ASC, `Host` ASC;';
1376 $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE
);
1379 // the query failed! This may have two reasons:
1380 // - the user does not have enough privileges
1381 // - the privilege tables use a structure of an earlier version.
1382 // so let's try a more simple query
1384 $sql_query = 'SELECT * FROM `mysql`.`user`';
1385 $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE
);
1388 PMA_Message
::error(__('No Privileges'))->display();
1389 PMA_DBI_free_result($res);
1392 // This message is hardcoded because I will replace it by
1393 // a automatic repair feature soon.
1394 $raw = 'Your privilege table structure seems to be older than'
1395 . ' this MySQL version!<br />'
1396 . 'Please run the <tt>mysql_upgrade</tt> command'
1397 . '(<tt>mysql_fix_privilege_tables</tt> on older systems)'
1398 . ' that should be included in your MySQL server distribution'
1399 . ' to solve this problem!';
1400 PMA_Message
::rawError($raw)->display();
1404 // we also want users not in table `user` but in other table
1405 $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;');
1407 $tables_to_search_for_users = array(
1408 'user', 'db', 'tables_priv', 'columns_priv', 'procs_priv',
1411 $db_rights_sqls = array();
1412 foreach ($tables_to_search_for_users as $table_search_in) {
1413 if (in_array($table_search_in, $tables)) {
1414 $db_rights_sqls[] = 'SELECT DISTINCT `User`, `Host` FROM `mysql`.`' . $table_search_in . '` ' . (isset($initial) ?
PMA_RangeOfUsers($initial) : '');
1418 $user_defaults = array(
1422 'Grant_priv' => 'N',
1423 'privs' => array('USAGE'),
1426 // for all initials, even non A-Z
1427 $array_initials = array();
1429 $db_rights = array();
1431 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
1432 .' ORDER BY `User` ASC, `Host` ASC';
1434 $db_rights_result = PMA_DBI_query($db_rights_sql);
1436 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
1437 $db_rights_row = array_merge($user_defaults, $db_rights_row);
1438 $db_rights[$db_rights_row['User']][$db_rights_row['Host']] =
1441 PMA_DBI_free_result($db_rights_result);
1442 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
1446 * Displays the initials
1449 // initialize to FALSE the letters A-Z
1450 for ($letter_counter = 1; $letter_counter < 27; $letter_counter++
) {
1451 if (! isset($array_initials[chr($letter_counter +
64)])) {
1452 $array_initials[chr($letter_counter +
64)] = FALSE;
1456 $initials = PMA_DBI_try_query('SELECT DISTINCT UPPER(LEFT(`User`,1)) FROM `user` ORDER BY `User` ASC', null, PMA_DBI_QUERY_STORE
);
1457 while (list($tmp_initial) = PMA_DBI_fetch_row($initials)) {
1458 $array_initials[$tmp_initial] = TRUE;
1461 // Display the initials, which can be any characters, not
1462 // just letters. For letters A-Z, we add the non-used letters
1465 uksort($array_initials, "strnatcasecmp");
1467 echo '<table cellspacing="5"><tr>';
1468 foreach ($array_initials as $tmp_initial => $initial_was_found) {
1469 if ($initial_was_found) {
1470 echo '<td><a href="server_privileges.php?' . $GLOBALS['url_query'] . '&initial=' . urlencode($tmp_initial) . '">' . $tmp_initial . '</a></td>' . "\n";
1472 echo '<td>' . $tmp_initial . '</td>';
1475 echo '<td><a href="server_privileges.php?' . $GLOBALS['url_query'] . '&showall=1">[' . __('Show all') . ']</a></td>' . "\n";
1476 echo '</tr></table>';
1479 * Display the user overview
1480 * (if less than 50 users, display them immediately)
1483 if (isset($initial) ||
isset($showall) ||
PMA_DBI_num_rows($res) < 50) {
1485 while ($row = PMA_DBI_fetch_assoc($res)) {
1486 $row['privs'] = PMA_extractPrivInfo($row, true);
1487 $db_rights[$row['User']][$row['Host']] = $row;
1489 @PMA_DBI_free_result
($res);
1492 echo '<form name="usersForm" id="usersForm" action="server_privileges.php" method="post">' . "\n"
1493 . PMA_generate_common_hidden_inputs('', '')
1494 . ' <table id="tableuserrights" class="data">' . "\n"
1496 . ' <tr><th></th>' . "\n"
1497 . ' <th>' . __('User') . '</th>' . "\n"
1498 . ' <th>' . __('Host') . '</th>' . "\n"
1499 . ' <th>' . __('Password') . '</th>' . "\n"
1500 . ' <th>' . __('Global privileges') . ' '
1501 . PMA_showHint(__(' Note: MySQL privilege names are expressed in English ')) . '</th>' . "\n"
1502 . ' <th>' . __('Grant') . '</th>' . "\n"
1503 . ' <th colspan="2">' . __('Action') . '</th>' . "\n";
1504 echo ' </tr>' . "\n";
1505 echo ' </thead>' . "\n";
1506 echo ' <tbody>' . "\n";
1508 $index_checkbox = -1;
1509 foreach ($db_rights as $user) {
1512 foreach ($user as $host) {
1514 echo ' <tr class="' . ($odd_row ?
'odd' : 'even') . '">' . "\n"
1515 . ' <td><input type="checkbox" name="selected_usr[]" id="checkbox_sel_users_'
1516 . $index_checkbox . '" value="'
1517 . htmlspecialchars($host['User'] . '&#27;' . $host['Host'])
1519 . (empty($GLOBALS['checkall']) ?
'' : ' checked="checked"')
1521 . ' <td><label for="checkbox_sel_users_' . $index_checkbox . '">' . (empty($host['User']) ?
'<span style="color: #FF0000">' . __('Any') . '</span>' : htmlspecialchars($host['User'])) . '</label></td>' . "\n"
1522 . ' <td>' . htmlspecialchars($host['Host']) . '</td>' . "\n";
1524 switch ($host['Password']) {
1529 echo '<span style="color: #FF0000">' . __('No') . '</span>';
1531 // this happens if this is a definition not coming from mysql.user
1533 echo '--'; // in future version, replace by "not present"
1537 . ' <td><tt>' . "\n"
1538 . ' ' . implode(',' . "\n" . ' ', $host['privs']) . "\n"
1539 . ' </tt></td>' . "\n"
1540 . ' <td>' . ($host['Grant_priv'] == 'Y' ?
__('Yes') : __('No')) . '</td>' . "\n"
1541 . ' <td align="center">';
1542 printf($link_edit, urlencode($host['User']), urlencode($host['Host']), '', '');
1544 echo '<td align="center">';
1545 printf($link_export, urlencode($host['User']), urlencode($host['Host']), (isset($initial) ?
$initial : ''));
1548 $odd_row = ! $odd_row;
1552 unset($user, $host, $odd_row);
1553 echo ' </tbody></table>' . "\n"
1554 .'<img class="selectallarrow"'
1555 .' src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png"'
1556 .' width="38" height="22"'
1557 .' alt="' . __('With selected:') . '" />' . "\n"
1558 .'<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&checkall=1"'
1559 .' onclick="if (markAllRows(\'usersForm\')) return false;">'
1560 . __('Check All') . '</a>' . "\n"
1562 .'<a href="server_privileges.php?' . $GLOBALS['url_query'] . '"'
1563 .' onclick="if (unMarkAllRows(\'usersForm\')) return false;">'
1564 . __('Uncheck All') . '</a>' . "\n";
1566 // add/delete user fieldset
1567 echo ' <fieldset id="fieldset_add_user">' . "\n"
1568 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&adduser=1">' . "\n"
1569 . PMA_getIcon('b_usradd.png')
1570 . ' ' . __('Add a new User') . '</a>' . "\n"
1571 . ' </fieldset>' . "\n"
1572 . ' <fieldset id="fieldset_delete_user">'
1573 . ' <legend>' . "\n"
1574 . PMA_getIcon('b_usrdrop.png')
1575 . ' ' . __('Remove selected users') . '' . "\n"
1576 . ' </legend>' . "\n"
1577 . ' <input type="hidden" name="mode" value="2" />' . "\n"
1578 . '(' . __('Revoke all active privileges from the users and delete them afterwards.') . ')<br />' . "\n"
1579 . ' <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"
1580 . ' <label for="checkbox_drop_users_db" title="' . __('Drop the databases that have the same names as the users.') . '">' . "\n"
1581 . ' ' . __('Drop the databases that have the same names as the users.') . "\n"
1582 . ' </label>' . "\n"
1583 . ' </fieldset>' . "\n"
1584 . ' <fieldset id="fieldset_delete_user_footer" class="tblFooters">' . "\n"
1585 . ' <input type="submit" name="delete" value="' . __('Go') . '" id="buttonGo" />' . "\n"
1586 . ' </fieldset>' . "\n"
1591 echo ' <fieldset id="fieldset_add_user">' . "\n"
1592 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&adduser=1">' . "\n"
1593 . PMA_getIcon('b_usradd.png')
1594 . ' ' . __('Add a new User') . '</a>' . "\n"
1595 . ' </fieldset>' . "\n";
1596 } // end if (display overview)
1597 $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
);
1598 $flushnote->addParam('<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&flush_privileges=1">', false);
1599 $flushnote->addParam('</a>', false);
1600 $flushnote->display();
1606 // A user was selected -> display the user's properties
1609 . PMA_getIcon('b_usredit.png')
1610 . __('Edit Privileges') . ': '
1613 if (isset($dbname)) {
1614 echo ' <i><a href="server_privileges.php?'
1615 . $GLOBALS['url_query'] . '&username=' . urlencode($username)
1616 . '&hostname=' . urlencode($hostname) . '&dbname=&tablename=">\''
1617 . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname)
1618 . '\'</a></i>' . "\n";
1619 $url_dbname = urlencode(str_replace(array('\_', '\%'), array('_', '%'), $dbname));
1621 echo ' - ' . ($dbname_is_wildcard ?
__('Databases') : __('Database') );
1622 if (isset($tablename)) {
1623 echo ' <i><a href="server_privileges.php?' . $GLOBALS['url_query']
1624 . '&username=' . urlencode($username) . '&hostname=' . urlencode($hostname)
1625 . '&dbname=' . $url_dbname . '&tablename=">' . htmlspecialchars($dbname) . '</a></i>';
1626 echo ' - ' . __('Table') . ' <i>' . htmlspecialchars($tablename) . '</i>';
1628 echo ' <i>' . htmlspecialchars($dbname) . '</i>';
1632 echo ' <i>\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname)
1636 echo '</h2>' . "\n";
1639 $sql = "SELECT '1' FROM `mysql`.`user`"
1640 . " WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
1641 . " AND `Host` = '" . PMA_sqlAddslashes($hostname) . "';";
1642 $user_does_not_exists = (bool) ! PMA_DBI_fetch_value($sql);
1644 if ($user_does_not_exists) {
1645 PMA_Message
::warning(__('The selected user was not found in the privilege table.'))->display();
1646 PMA_displayLoginInformationFields();
1647 //require_once './libraries/footer.inc.php';
1650 echo '<form name="usersForm" id="usersForm" action="server_privileges.php" method="post">' . "\n";
1652 'username' => $username,
1653 'hostname' => $hostname,
1655 if (isset($dbname)) {
1656 $_params['dbname'] = $dbname;
1657 if (isset($tablename)) {
1658 $_params['tablename'] = $tablename;
1661 echo PMA_generate_common_hidden_inputs($_params);
1663 PMA_displayPrivTable(PMA_ifSetOr($dbname, '*', 'length'),
1664 PMA_ifSetOr($tablename, '*', 'length'));
1666 echo '</form>' . "\n";
1668 if (! isset($tablename) && empty($dbname_is_wildcard)) {
1670 // no table name was given, display all table specific rights
1671 // but only if $dbname contains no wildcards
1674 echo '<form action="server_privileges.php" method="post">' . "\n"
1675 . PMA_generate_common_hidden_inputs('', '')
1676 . '<input type="hidden" name="username" value="' . htmlspecialchars($username) . '" />' . "\n"
1677 . '<input type="hidden" name="hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n"
1678 . '<fieldset>' . "\n"
1679 . '<legend>' . (! isset($dbname) ?
__('Database-specific privileges') : __('Table-specific privileges')) . '</legend>' . "\n"
1680 . '<table class="data">' . "\n"
1682 . '<tr><th>' . (! isset($dbname) ?
__('Database') : __('Table')) . '</th>' . "\n"
1683 . ' <th>' . __('Privileges') . '</th>' . "\n"
1684 . ' <th>' . __('Grant') . '</th>' . "\n"
1685 . ' <th>' . (! isset($dbname) ?
__('Table-specific privileges') : __('Column-specific privileges')) . '</th>' . "\n"
1686 . ' <th colspan="2">' . __('Action') . '</th>' . "\n"
1691 $user_host_condition =
1693 . ' = \'' . PMA_sqlAddslashes($username) . "'"
1695 . ' = \'' . PMA_sqlAddslashes($hostname) . "'";
1700 // we also want privielgs for this user not in table `db` but in other table
1701 $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;');
1702 if (! isset($dbname)) {
1704 // no db name given, so we want all privs for the given user
1706 $tables_to_search_for_users = array(
1707 'tables_priv', 'columns_priv',
1710 $db_rights_sqls = array();
1711 foreach ($tables_to_search_for_users as $table_search_in) {
1712 if (in_array($table_search_in, $tables)) {
1713 $db_rights_sqls[] = '
1714 SELECT DISTINCT `Db`
1715 FROM `mysql`.' . PMA_backquote($table_search_in)
1716 . $user_host_condition;
1720 $user_defaults = array(
1722 'Grant_priv' => 'N',
1723 'privs' => array('USAGE'),
1724 'Table_privs' => true,
1728 $db_rights = array();
1730 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
1731 .' ORDER BY `Db` ASC';
1733 $db_rights_result = PMA_DBI_query($db_rights_sql);
1735 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
1736 $db_rights_row = array_merge($user_defaults, $db_rights_row);
1737 // only Db names in the table `mysql`.`db` uses wildcards
1738 // as we are in the db specific rights display we want
1739 // all db names escaped, also from other sources
1740 $db_rights_row['Db'] = PMA_escape_mysql_wildcards(
1741 $db_rights_row['Db']);
1742 $db_rights[$db_rights_row['Db']] = $db_rights_row;
1745 PMA_DBI_free_result($db_rights_result);
1746 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
1748 $sql_query = 'SELECT * FROM `mysql`.`db`' . $user_host_condition . ' ORDER BY `Db` ASC';
1749 $res = PMA_DBI_query($sql_query);
1752 while ($row = PMA_DBI_fetch_assoc($res)) {
1753 if (isset($db_rights[$row['Db']])) {
1754 $db_rights[$row['Db']] = array_merge($db_rights[$row['Db']], $row);
1756 $db_rights[$row['Db']] = $row;
1758 // there are db specific rights for this user
1759 // so we can drop this db rights
1760 $db_rights[$row['Db']]['can_delete'] = true;
1762 PMA_DBI_free_result($res);
1767 // db name was given,
1768 // so we want all user specific rights for this db
1770 $user_host_condition .=
1772 .' LIKE \'' . PMA_sqlAddslashes($dbname) . "'";
1774 $tables_to_search_for_users = array(
1778 $db_rights_sqls = array();
1779 foreach ($tables_to_search_for_users as $table_search_in) {
1780 if (in_array($table_search_in, $tables)) {
1781 $db_rights_sqls[] = '
1782 SELECT DISTINCT `Table_name`
1783 FROM `mysql`.' . PMA_backquote($table_search_in)
1784 . $user_host_condition;
1788 $user_defaults = array(
1790 'Grant_priv' => 'N',
1791 'privs' => array('USAGE'),
1792 'Column_priv' => true,
1796 $db_rights = array();
1798 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
1799 .' ORDER BY `Table_name` ASC';
1801 $db_rights_result = PMA_DBI_query($db_rights_sql);
1803 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
1804 $db_rights_row = array_merge($user_defaults, $db_rights_row);
1805 $db_rights[$db_rights_row['Table_name']] = $db_rights_row;
1807 PMA_DBI_free_result($db_rights_result);
1808 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
1811 'SELECT `Table_name`,'
1813 .' IF(`Column_priv` = _latin1 \'\', 0, 1)'
1814 .' AS \'Column_priv\''
1815 .' FROM `mysql`.`tables_priv`'
1816 . $user_host_condition
1817 .' ORDER BY `Table_name` ASC;';
1818 $res = PMA_DBI_query($sql_query);
1821 while ($row = PMA_DBI_fetch_assoc($res)) {
1822 if (isset($db_rights[$row['Table_name']])) {
1823 $db_rights[$row['Table_name']] = array_merge($db_rights[$row['Table_name']], $row);
1825 $db_rights[$row['Table_name']] = $row;
1828 PMA_DBI_free_result($res);
1834 if (count($db_rights) < 1) {
1835 echo '<tr class="odd">' . "\n"
1836 . ' <td colspan="6"><center><i>' . __('None') . '</i></center></td>' . "\n"
1840 $found_rows = array();
1841 //while ($row = PMA_DBI_fetch_assoc($res)) {
1842 foreach ($db_rights as $row) {
1843 $found_rows[] = (! isset($dbname)) ?
$row['Db'] : $row['Table_name'];
1845 echo '<tr class="' . ($odd_row ?
'odd' : 'even') . '">' . "\n"
1846 . ' <td>' . htmlspecialchars((! isset($dbname)) ?
$row['Db'] : $row['Table_name']) . '</td>' . "\n"
1847 . ' <td><tt>' . "\n"
1848 . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($row, TRUE)) . "\n"
1849 . ' </tt></td>' . "\n"
1850 . ' <td>' . ((((! isset($dbname)) && $row['Grant_priv'] == 'Y') ||
(isset($dbname) && in_array('Grant', explode(',', $row['Table_priv'])))) ?
__('Yes') : __('No')) . '</td>' . "\n"
1852 if (! empty($row['Table_privs']) ||
! empty ($row['Column_priv'])) {
1859 printf($link_edit, urlencode($username),
1860 urlencode($hostname),
1861 urlencode((! isset($dbname)) ?
$row['Db'] : $dbname),
1862 urlencode((! isset($dbname)) ?
'' : $row['Table_name']));
1865 if (! empty($row['can_delete']) ||
isset($row['Table_name']) && strlen($row['Table_name'])) {
1866 printf($link_revoke, urlencode($username),
1867 urlencode($hostname),
1868 urlencode((! isset($dbname)) ?
$row['Db'] : $dbname),
1869 urlencode((! isset($dbname)) ?
'' : $row['Table_name']));
1873 $odd_row = ! $odd_row;
1877 echo '</tbody>' . "\n"
1878 . '</table>' . "\n";
1880 if (! isset($dbname)) {
1882 // no database name was given, display select db
1884 $pred_db_array =PMA_DBI_fetch_result('SHOW DATABASES;');
1886 echo ' <label for="text_dbname">' . __('Add privileges on the following database') . ':</label>' . "\n";
1887 if (!empty($pred_db_array)) {
1888 echo ' <select name="pred_dbname" onchange="this.form.submit();">' . "\n"
1889 . ' <option value="" selected="selected">' . __('Use text field') . ':</option>' . "\n";
1890 foreach ($pred_db_array as $current_db) {
1891 $current_db = PMA_escape_mysql_wildcards($current_db);
1892 // cannot use array_diff() once, outside of the loop,
1893 // because the list of databases has special characters
1894 // already escaped in $found_rows,
1895 // contrary to the output of SHOW DATABASES
1896 if (empty($found_rows) ||
! in_array($current_db, $found_rows)) {
1897 echo ' <option value="' . htmlspecialchars($current_db) . '">'
1898 . htmlspecialchars($current_db) . '</option>' . "\n";
1901 echo ' </select>' . "\n";
1903 echo ' <input type="text" id="text_dbname" name="dbname" />' . "\n"
1904 . PMA_showHint(__('Wildcards % and _ should be escaped with a \ to use them literally'));
1906 echo ' <input type="hidden" name="dbname" value="' . htmlspecialchars($dbname) . '"/>' . "\n"
1907 . ' <label for="text_tablename">' . __('Add privileges on the following table') . ':</label>' . "\n";
1908 if ($res = @PMA_DBI_try_query
('SHOW TABLES FROM ' . PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . ';', null, PMA_DBI_QUERY_STORE
)) {
1909 $pred_tbl_array = array();
1910 while ($row = PMA_DBI_fetch_row($res)) {
1911 if (!isset($found_rows) ||
!in_array($row[0], $found_rows)) {
1912 $pred_tbl_array[] = $row[0];
1915 PMA_DBI_free_result($res);
1917 if (!empty($pred_tbl_array)) {
1918 echo ' <select name="pred_tablename" onchange="this.form.submit();">' . "\n"
1919 . ' <option value="" selected="selected">' . __('Use text field') . ':</option>' . "\n";
1920 foreach ($pred_tbl_array as $current_table) {
1921 echo ' <option value="' . htmlspecialchars($current_table) . '">' . htmlspecialchars($current_table) . '</option>' . "\n";
1923 echo ' </select>' . "\n";
1928 echo ' <input type="text" id="text_tablename" name="tablename" />' . "\n";
1930 echo '</fieldset>' . "\n";
1931 echo '<fieldset class="tblFooters">' . "\n"
1932 . ' <input type="submit" value="' . __('Go') . '" />'
1933 . '</fieldset>' . "\n"
1938 // Provide a line with links to the relevant database and table
1939 if (isset($dbname) && empty($dbname_is_wildcard)) {
1940 echo '[ ' . __('Database')
1941 . ' <a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?'
1942 . $GLOBALS['url_query'] . '&db=' . $url_dbname . '&reload=1">'
1943 . htmlspecialchars($dbname) . ': ' . PMA_getTitleForTarget($GLOBALS['cfg']['DefaultTabDatabase']) . "</a> ]\n";
1945 if (isset($tablename)) {
1946 echo ' [ ' . __('Table') . ' <a href="'
1947 . $GLOBALS['cfg']['DefaultTabTable'] . '?' . $GLOBALS['url_query']
1948 . '&db=' . $url_dbname . '&table=' . urlencode($tablename)
1949 . '&reload=1">' . htmlspecialchars($tablename) . ': '
1950 . PMA_getTitleForTarget($GLOBALS['cfg']['DefaultTabTable'])
1956 if (! isset($dbname) && ! $user_does_not_exists) {
1957 require_once './libraries/display_change_password.lib.php';
1959 echo '<form action="server_privileges.php" method="post" onsubmit="return checkPassword(this);">' . "\n"
1960 . PMA_generate_common_hidden_inputs('', '')
1961 . '<input type="hidden" name="old_username" value="' . htmlspecialchars($username) . '" />' . "\n"
1962 . '<input type="hidden" name="old_hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n"
1963 . '<fieldset id="fieldset_change_copy_user">' . "\n"
1964 . ' <legend>' . __('Change Login Information / Copy User') . '</legend>' . "\n";
1965 PMA_displayLoginInformationFields('change');
1966 echo ' <fieldset>' . "\n"
1967 . ' <legend>' . __('Create a new user with the same privileges and ...') . '</legend>' . "\n";
1969 '4' => __('... keep the old one.'),
1970 '1' => __(' ... delete the old one from the user tables.'),
1971 '2' => __(' ... revoke all active privileges from the old one and delete it afterwards.'),
1972 '3' => __(' ... delete the old one from the user tables and reload the privileges afterwards.'));
1973 PMA_display_html_radio('mode', $choices, '4', true);
1976 echo ' </fieldset>' . "\n"
1977 . '</fieldset>' . "\n"
1978 . '<fieldset id="fieldset_change_copy_user_footer" class="tblFooters">' . "\n"
1979 . ' <input type="submit" name="change_copy" value="' . __('Go') . '" />' . "\n"
1980 . '</fieldset>' . "\n"
1984 } elseif (isset($_REQUEST['adduser'])) {
1986 $GLOBALS['url_query'] .= '&adduser=1';
1988 . PMA_getIcon('b_usradd.png') . __('Add a new User') . "\n"
1990 . '<form name="usersForm" id="usersForm" action="server_privileges.php" method="post" onsubmit="return checkAddUser(this);">' . "\n"
1991 . PMA_generate_common_hidden_inputs('', '');
1992 PMA_displayLoginInformationFields('new');
1993 echo '<fieldset id="fieldset_add_user_database">' . "\n"
1994 . '<legend>' . __('Database for user') . '</legend>' . "\n";
1996 $default_choice = 0;
1998 '0' => _pgettext('Create none database for user', 'None'),
1999 '1' => __('Create database with same name and grant all privileges'),
2000 '2' => __('Grant all privileges on wildcard name (username\\_%)'));
2002 if ( !empty($dbname) ) {
2003 $choices['3'] = sprintf( __('Grant all privileges on database "%s"'), htmlspecialchars($dbname));
2004 $default_choice = 3;
2005 echo '<input type="hidden" name="dbname" value="' . htmlspecialchars($dbname) . '" />' . "\n";
2008 // 4th parameter set to true to add line breaks
2009 // 5th parameter set to false to avoid htmlspecialchars() escaping in the label
2010 // since we have some HTML in some labels
2011 PMA_display_html_radio('createdb', $choices, $default_choice, true, false);
2013 unset($default_choice);
2015 echo '</fieldset>' . "\n";
2016 PMA_displayPrivTable('*', '*', FALSE);
2017 echo ' <fieldset id="fieldset_add_user_footer" class="tblFooters">' . "\n"
2018 . ' <input type="submit" name="adduser_submit" value="' . __('Go') . '" />' . "\n"
2019 . ' </fieldset>' . "\n"
2022 // check the privileges for a particular database.
2023 echo '<table id="tablespecificuserrights" class="data">' . "\n"
2024 . '<caption class="tblHeaders">' . "\n"
2025 . PMA_getIcon('b_usrcheck.png')
2026 . ' ' . sprintf(__('Users having access to "%s"'), '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?' . PMA_generate_common_url($checkprivs) . '">' . htmlspecialchars($checkprivs) . '</a>') . "\n"
2027 . '</caption>' . "\n"
2029 . ' <tr><th>' . __('User') . '</th>' . "\n"
2030 . ' <th>' . __('Host') . '</th>' . "\n"
2031 . ' <th>' . __('Type') . '</th>' . "\n"
2032 . ' <th>' . __('Privileges') . '</th>' . "\n"
2033 . ' <th>' . __('Grant') . '</th>' . "\n"
2034 . ' <th>' . __('Action') . '</th>' . "\n"
2039 unset($row, $row1, $row2);
2041 // now, we build the table...
2042 $list_of_privileges =
2054 . '`References_priv`, '
2055 . '`Create_tmp_table_priv`, '
2056 . '`Lock_tables_priv`, '
2057 . '`Create_view_priv`, '
2058 . '`Show_view_priv`, '
2059 . '`Create_routine_priv`, '
2060 . '`Alter_routine_priv`, '
2063 $list_of_compared_privileges =
2064 '`Select_priv` = \'N\''
2065 . ' AND `Insert_priv` = \'N\''
2066 . ' AND `Update_priv` = \'N\''
2067 . ' AND `Delete_priv` = \'N\''
2068 . ' AND `Create_priv` = \'N\''
2069 . ' AND `Drop_priv` = \'N\''
2070 . ' AND `Grant_priv` = \'N\''
2071 . ' AND `References_priv` = \'N\''
2072 . ' AND `Create_tmp_table_priv` = \'N\''
2073 . ' AND `Lock_tables_priv` = \'N\''
2074 . ' AND `Create_view_priv` = \'N\''
2075 . ' AND `Show_view_priv` = \'N\''
2076 . ' AND `Create_routine_priv` = \'N\''
2077 . ' AND `Alter_routine_priv` = \'N\''
2078 . ' AND `Execute_priv` = \'N\'';
2080 if (PMA_MYSQL_INT_VERSION
>= 50106) {
2081 $list_of_privileges .=
2084 $list_of_compared_privileges .=
2085 ' AND `Event_priv` = \'N\''
2086 . ' AND `Trigger_priv` = \'N\'';
2090 '(SELECT ' . $list_of_privileges . ', `Db`'
2091 .' FROM `mysql`.`db`'
2092 .' WHERE \'' . PMA_sqlAddslashes($checkprivs) . "'"
2094 .' AND NOT (' . $list_of_compared_privileges. ')) '
2096 .'(SELECT ' . $list_of_privileges . ', \'*\' AS `Db`'
2097 .' FROM `mysql`.`user` '
2098 .' WHERE NOT (' . $list_of_compared_privileges . ')) '
2099 .' ORDER BY `User` ASC,'
2102 $res = PMA_DBI_query($sql_query);
2103 $row = PMA_DBI_fetch_assoc($res);
2110 // prepare the current user
2111 $current_privileges = array();
2112 $current_user = $row['User'];
2113 $current_host = $row['Host'];
2114 while ($row && $current_user == $row['User'] && $current_host == $row['Host']) {
2115 $current_privileges[] = $row;
2116 $row = PMA_DBI_fetch_assoc($res);
2118 echo ' <tr class="' . ($odd_row ?
'odd' : 'even') . '">' . "\n"
2120 if (count($current_privileges) > 1) {
2121 echo ' rowspan="' . count($current_privileges) . '"';
2123 echo '>' . (empty($current_user) ?
'<span style="color: #FF0000">' . __('Any') . '</span>' : htmlspecialchars($current_user)) . "\n"
2126 if (count($current_privileges) > 1) {
2127 echo ' rowspan="' . count($current_privileges) . '"';
2129 echo '>' . htmlspecialchars($current_host) . '</td>' . "\n";
2130 foreach ($current_privileges as $current) {
2133 if (!isset($current['Db']) ||
$current['Db'] == '*') {
2135 } elseif ($current['Db'] == PMA_escape_mysql_wildcards($checkprivs)) {
2136 echo __('database-specific');
2138 echo __('wildcard'), ': <tt>' . htmlspecialchars($current['Db']) . '</tt>';
2144 . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($current, TRUE)) . "\n"
2148 . ' ' . ($current['Grant_priv'] == 'Y' ?
__('Yes') : __('No')) . "\n"
2151 printf($link_edit, urlencode($current_user),
2152 urlencode($current_host),
2153 urlencode(! isset($current['Db']) ||
$current['Db'] == '*' ?
'' : $current['Db']),
2158 if (empty($row) && empty($row1) && empty($row2)) {
2161 $odd_row = ! $odd_row;
2164 echo ' <tr class="odd">' . "\n"
2165 . ' <td colspan="6">' . "\n"
2166 . ' ' . __('No user found.') . "\n"
2170 echo '</tbody>' . "\n"
2171 . '</table>' . "\n";
2173 // Offer to create a new user for the current database
2174 echo '<fieldset id="fieldset_add_user">' . "\n"
2175 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&adduser=1&dbname=' . $checkprivs .'">' . "\n"
2176 . PMA_getIcon('b_usradd.png')
2177 . ' ' . __('Add a new User') . '</a>' . "\n"
2178 . '</fieldset>' . "\n";
2180 } // end if (empty($_REQUEST['adduser']) && empty($checkprivs)) ... elseif ... else ...
2184 * Displays the footer
2187 require_once './libraries/footer.inc.php';