jquery components should be under js/jquery
[phpmyadmin/dkf.git] / server_privileges.php
blob710151ef346bab50be2161618356105a94f7cf8e
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
5 * @package phpMyAdmin
6 */
8 /**
11 require_once './libraries/common.inc.php';
13 /**
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.custom.js';
20 $GLOBALS['js_include'][] = 'password_generation.js';
21 require './libraries/server_common.inc.php';
23 /**
24 * Messages are built using the message name
26 $strPrivDescAllPrivileges = __('Includes all privileges except GRANT.');
27 $strPrivDescAlter = __('Allows altering the structure of existing tables.');
28 $strPrivDescAlterRoutine = __('Allows altering and dropping stored routines.');
29 $strPrivDescCreateDb = __('Allows creating new databases and tables.');
30 $strPrivDescCreateRoutine = __('Allows creating stored routines.');
31 $strPrivDescCreateTbl = __('Allows creating new tables.');
32 $strPrivDescCreateTmpTable = __('Allows creating temporary tables.');
33 $strPrivDescCreateUser = __('Allows creating, dropping and renaming user accounts.');
34 $strPrivDescCreateView = __('Allows creating new views.');
35 $strPrivDescDelete = __('Allows deleting data.');
36 $strPrivDescDropDb = __('Allows dropping databases and tables.');
37 $strPrivDescDropTbl = __('Allows dropping tables.');
38 $strPrivDescEvent = __('Allows to set up events for the event scheduler');
39 $strPrivDescExecute = __('Allows executing stored routines.');
40 $strPrivDescFile = __('Allows importing data from and exporting data into files.');
41 $strPrivDescGrant = __('Allows adding users and privileges without reloading the privilege tables.');
42 $strPrivDescIndex = __('Allows creating and dropping indexes.');
43 $strPrivDescInsert = __('Allows inserting and replacing data.');
44 $strPrivDescLockTables = __('Allows locking tables for the current thread.');
45 $strPrivDescMaxConnections = __('Limits the number of new connections the user may open per hour.');
46 $strPrivDescMaxQuestions = __('Limits the number of queries the user may send to the server per hour.');
47 $strPrivDescMaxUpdates = __('Limits the number of commands that change any table or database the user may execute per hour.');
48 $strPrivDescMaxUserConnections = __('Limits the number of simultaneous connections the user may have.');
49 $strPrivDescProcess = __('Allows viewing processes of all users');
50 $strPrivDescReferences = __('Has no effect in this MySQL version.');
51 $strPrivDescReload = __('Allows reloading server settings and flushing the server\'s caches.');
52 $strPrivDescReplClient = __('Allows the user to ask where the slaves / masters are.');
53 $strPrivDescReplSlave = __('Needed for the replication slaves.');
54 $strPrivDescSelect = __('Allows reading data.');
55 $strPrivDescShowDb = __('Gives access to the complete list of databases.');
56 $strPrivDescShowView = __('Allows performing SHOW CREATE VIEW queries.');
57 $strPrivDescShutdown = __('Allows shutting down the server.');
58 $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.');
59 $strPrivDescTrigger = __('Allows creating and dropping triggers');
60 $strPrivDescUpdate = __('Allows changing data.');
61 $strPrivDescUsage = __('No privileges.');
63 /**
64 * Checks if a dropdown box has been used for selecting a database / table
66 if (PMA_isValid($_REQUEST['pred_tablename'])) {
67 $tablename = $_REQUEST['pred_tablename'];
68 unset($pred_tablename);
69 } elseif (PMA_isValid($_REQUEST['tablename'])) {
70 $tablename = $_REQUEST['tablename'];
71 } else {
72 unset($tablename);
75 if (PMA_isValid($_REQUEST['pred_dbname'])) {
76 $dbname = $_REQUEST['pred_dbname'];
77 unset($pred_dbname);
78 } elseif (PMA_isValid($_REQUEST['dbname'])) {
79 $dbname = $_REQUEST['dbname'];
80 } else {
81 unset($dbname);
82 unset($tablename);
85 if (isset($dbname)) {
86 $db_and_table = PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . '.';
87 if (isset($tablename)) {
88 $db_and_table .= PMA_backquote($tablename);
89 } else {
90 $db_and_table .= '*';
92 } else {
93 $db_and_table = '*.*';
96 // check if given $dbname is a wildcard or not
97 if (isset($dbname)) {
98 //if (preg_match('/\\\\(?:_|%)/i', $dbname)) {
99 if (preg_match('/(?<!\\\\)(?:_|%)/i', $dbname)) {
100 $dbname_is_wildcard = true;
101 } else {
102 $dbname_is_wildcard = false;
107 * Checks if the user is allowed to do what he tries to...
109 if (!$is_superuser) {
110 require './libraries/server_links.inc.php';
111 echo '<h2>' . "\n"
112 . PMA_getIcon('b_usrlist.png')
113 . __('Privileges') . "\n"
114 . '</h2>' . "\n";
115 PMA_Message::error(__('No Privileges'))->display();
116 require './libraries/footer.inc.php';
120 * Escapes wildcard in a database+table specification
121 * before using it in a GRANT statement.
123 * Escaping a wildcard character in a GRANT is only accepted at the global
124 * or database level, not at table level; this is why I remove
125 * the escaping character. Internally, in mysql.tables_priv.Db there are
126 * no escaping (for example test_db) but in mysql.db you'll see test\_db
127 * for a db-specific privilege.
129 * @param string $db_and_table
130 * @param string $dbname
131 * @param string $tablename
132 * @return string the escaped (if necessary) $db_and_table
134 function PMA_WildcardEscapeForGrant($db_and_table, $dbname, $tablename) {
136 if (! strlen($dbname)) {
137 $db_and_table = '*.*';
138 } else {
139 if (strlen($tablename)) {
140 $db_and_table = PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . '.';
141 $db_and_table .= PMA_backquote($tablename);
142 } else {
143 $db_and_table = PMA_backquote($dbname) . '.';
144 $db_and_table .= '*';
147 return $db_and_table;
151 * Generates a condition on the user name
153 * @param string the user's initial
154 * @return string the generated condition
156 function PMA_RangeOfUsers($initial = '')
158 // strtolower() is used because the User field
159 // might be BINARY, so LIKE would be case sensitive
160 if (!empty($initial)) {
161 $ret = " WHERE `User` LIKE '" . $initial . "%'"
162 . " OR `User` LIKE '" . strtolower($initial) . "%'";
163 } else {
164 $ret = '';
166 return $ret;
167 } // end function
170 * Extracts the privilege information of a priv table row
172 * @param array $row the row
173 * @param boolean $enableHTML add <dfn> tag with tooltips
175 * @global ressource $user_link the database connection
177 * @return array
179 function PMA_extractPrivInfo($row = '', $enableHTML = FALSE)
181 $grants = array(
182 array('Select_priv', 'SELECT', __('Allows reading data.')),
183 array('Insert_priv', 'INSERT', __('Allows inserting and replacing data.')),
184 array('Update_priv', 'UPDATE', __('Allows changing data.')),
185 array('Delete_priv', 'DELETE', __('Allows deleting data.')),
186 array('Create_priv', 'CREATE', __('Allows creating new databases and tables.')),
187 array('Drop_priv', 'DROP', __('Allows dropping databases and tables.')),
188 array('Reload_priv', 'RELOAD', __('Allows reloading server settings and flushing the server\'s caches.')),
189 array('Shutdown_priv', 'SHUTDOWN', __('Allows shutting down the server.')),
190 array('Process_priv', 'PROCESS', __('Allows viewing processes of all users')),
191 array('File_priv', 'FILE', __('Allows importing data from and exporting data into files.')),
192 array('References_priv', 'REFERENCES', __('Has no effect in this MySQL version.')),
193 array('Index_priv', 'INDEX', __('Allows creating and dropping indexes.')),
194 array('Alter_priv', 'ALTER', __('Allows altering the structure of existing tables.')),
195 array('Show_db_priv', 'SHOW DATABASES', __('Gives access to the complete list of databases.')),
196 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.')),
197 array('Create_tmp_table_priv', 'CREATE TEMPORARY TABLES', __('Allows creating temporary tables.')),
198 array('Lock_tables_priv', 'LOCK TABLES', __('Allows locking tables for the current thread.')),
199 array('Repl_slave_priv', 'REPLICATION SLAVE', __('Needed for the replication slaves.')),
200 array('Repl_client_priv', 'REPLICATION CLIENT', __('Allows the user to ask where the slaves / masters are.')),
201 array('Create_view_priv', 'CREATE VIEW', __('Allows creating new views.')),
202 array('Event_priv', 'EVENT', __('Allows to set up events for the event scheduler')),
203 array('Trigger_priv', 'TRIGGER', __('Allows creating and dropping triggers')),
204 // for table privs:
205 array('Create View_priv', 'CREATE VIEW', __('Allows creating new views.')),
206 array('Show_view_priv', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')),
207 // for table privs:
208 array('Show view_priv', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')),
209 array('Create_routine_priv', 'CREATE ROUTINE', __('Allows creating stored routines.')),
210 array('Alter_routine_priv', 'ALTER ROUTINE', __('Allows altering and dropping stored routines.')),
211 array('Create_user_priv', 'CREATE USER', __('Allows creating, dropping and renaming user accounts.')),
212 array('Execute_priv', 'EXECUTE', __('Allows executing stored routines.')),
215 if (!empty($row) && isset($row['Table_priv'])) {
216 $row1 = PMA_DBI_fetch_single_row(
217 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
218 'ASSOC', $GLOBALS['userlink']);
219 $av_grants = explode('\',\'', substr($row1['Type'], 5, strlen($row1['Type']) - 7));
220 unset($row1);
221 $users_grants = explode(',', $row['Table_priv']);
222 foreach ($av_grants as $current_grant) {
223 $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ? 'Y' : 'N';
225 unset($current_grant);
226 unset($av_grants);
227 unset($users_grants);
229 $privs = array();
230 $allPrivileges = TRUE;
231 foreach ($grants as $current_grant) {
232 if ((!empty($row) && isset($row[$current_grant[0]]))
233 || (empty($row) && isset($GLOBALS[$current_grant[0]]))) {
234 if ((!empty($row) && $row[$current_grant[0]] == 'Y')
235 || (empty($row)
236 && ($GLOBALS[$current_grant[0]] == 'Y'
237 || (is_array($GLOBALS[$current_grant[0]])
238 && count($GLOBALS[$current_grant[0]]) == $GLOBALS['column_count']
239 && empty($GLOBALS[$current_grant[0] . '_none'])))))
241 if ($enableHTML) {
242 $privs[] = '<dfn title="' . $current_grant[2] . '">' . $current_grant[1] . '</dfn>';
243 } else {
244 $privs[] = $current_grant[1];
246 } elseif (!empty($GLOBALS[$current_grant[0]])
247 && is_array($GLOBALS[$current_grant[0]])
248 && empty($GLOBALS[$current_grant[0] . '_none'])) {
249 if ($enableHTML) {
250 $priv_string = '<dfn title="' . $current_grant[2] . '">' . $current_grant[1] . '</dfn>';
251 } else {
252 $priv_string = $current_grant[1];
254 $privs[] = $priv_string . ' (`' . join('`, `', $GLOBALS[$current_grant[0]]) . '`)';
255 } else {
256 $allPrivileges = FALSE;
260 if (empty($privs)) {
261 if ($enableHTML) {
262 $privs[] = '<dfn title="' . __('No privileges.') . '">USAGE</dfn>';
263 } else {
264 $privs[] = 'USAGE';
266 } elseif ($allPrivileges && (!isset($GLOBALS['grant_count']) || count($privs) == $GLOBALS['grant_count'])) {
267 if ($enableHTML) {
268 $privs = array('<dfn title="' . __('Includes all privileges except GRANT.') . '">ALL PRIVILEGES</dfn>');
269 } else {
270 $privs = array('ALL PRIVILEGES');
273 return $privs;
274 } // end of the 'PMA_extractPrivInfo()' function
277 * Displays on which column(s) a table-specific privilege is granted
279 function PMA_display_column_privs($columns, $row, $name_for_select,
280 $priv_for_header, $name, $name_for_dfn, $name_for_current)
282 echo ' <div class="item" id="div_item_' . $name . '">' . "\n"
283 . ' <label for="select_' . $name . '_priv">' . "\n"
284 . ' <tt><dfn title="' . $name_for_dfn . '">'
285 . $priv_for_header . '</dfn></tt>' . "\n"
286 . ' </label><br />' . "\n"
287 . ' <select id="select_' . $name . '_priv" name="'
288 . $name_for_select . '[]" multiple="multiple" size="8">' . "\n";
290 foreach ($columns as $current_column => $current_column_privileges) {
291 echo ' <option value="' . htmlspecialchars($current_column) . '"';
292 if ($row[$name_for_select] == 'Y' || $current_column_privileges[$name_for_current]) {
293 echo ' selected="selected"';
295 echo '>' . htmlspecialchars($current_column) . '</option>' . "\n";
298 echo ' </select>' . "\n"
299 . ' <i>' . __('Or') . '</i>' . "\n"
300 . ' <label for="checkbox_' . $name_for_select
301 . '_none"><input type="checkbox"'
302 . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"')
303 . ' name="' . $name_for_select . '_none" id="checkbox_'
304 . $name_for_select . '_none" title="' . _pgettext('None privileges', 'None') . '" />'
305 . _pgettext('None privileges', 'None') . '</label>' . "\n"
306 . ' </div>' . "\n";
307 } // end function
311 * Displays the privileges form table
313 * @param string $db the database
314 * @param string $table the table
315 * @param boolean $submit wheather to display the submit button or not
316 * @global array $cfg the phpMyAdmin configuration
317 * @global ressource $user_link the database connection
319 * @return void
321 function PMA_displayPrivTable($db = '*', $table = '*', $submit = TRUE)
323 if ($db == '*') {
324 $table = '*';
327 if (isset($GLOBALS['username'])) {
328 $username = $GLOBALS['username'];
329 $hostname = $GLOBALS['hostname'];
330 if ($db == '*') {
331 $sql_query =
332 "SELECT * FROM `mysql`.`user`"
333 ." WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
334 ." AND `Host` = '" . PMA_sqlAddslashes($hostname) . "';";
335 } elseif ($table == '*') {
336 $sql_query =
337 "SELECT * FROM `mysql`.`db`"
338 ." WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
339 ." AND `Host` = '" . PMA_sqlAddslashes($hostname) . "'"
340 ." AND '" . PMA_unescape_mysql_wildcards($db) . "'"
341 ." LIKE `Db`;";
342 } else {
343 $sql_query =
344 "SELECT `Table_priv`"
345 ." FROM `mysql`.`tables_priv`"
346 ." WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
347 ." AND `Host` = '" . PMA_sqlAddslashes($hostname) . "'"
348 ." AND `Db` = '" . PMA_unescape_mysql_wildcards($db) . "'"
349 ." AND `Table_name` = '" . PMA_sqlAddslashes($table) . "';";
351 $row = PMA_DBI_fetch_single_row($sql_query);
353 if (empty($row)) {
354 if ($table == '*') {
355 if ($db == '*') {
356 $sql_query = 'SHOW COLUMNS FROM `mysql`.`user`;';
357 } elseif ($table == '*') {
358 $sql_query = 'SHOW COLUMNS FROM `mysql`.`db`;';
360 $res = PMA_DBI_query($sql_query);
361 while ($row1 = PMA_DBI_fetch_row($res)) {
362 if (substr($row1[0], 0, 4) == 'max_') {
363 $row[$row1[0]] = 0;
364 } else {
365 $row[$row1[0]] = 'N';
368 PMA_DBI_free_result($res);
369 } else {
370 $row = array('Table_priv' => '');
373 if (isset($row['Table_priv'])) {
374 $row1 = PMA_DBI_fetch_single_row(
375 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
376 'ASSOC', $GLOBALS['userlink']);
377 // note: in MySQL 5.0.3 we get "Create View', 'Show view';
378 // the View for Create is spelled with uppercase V
379 // the view for Show is spelled with lowercase v
380 // and there is a space between the words
382 $av_grants = explode('\',\'', substr($row1['Type'], strpos($row1['Type'], '(') + 2, strpos($row1['Type'], ')') - strpos($row1['Type'], '(') - 3));
383 unset($row1);
384 $users_grants = explode(',', $row['Table_priv']);
386 foreach ($av_grants as $current_grant) {
387 $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ? 'Y' : 'N';
389 unset($row['Table_priv'], $current_grant, $av_grants, $users_grants);
391 // get collumns
392 $res = PMA_DBI_try_query('SHOW COLUMNS FROM ' . PMA_backquote(PMA_unescape_mysql_wildcards($db)) . '.' . PMA_backquote($table) . ';');
393 $columns = array();
394 if ($res) {
395 while ($row1 = PMA_DBI_fetch_row($res)) {
396 $columns[$row1[0]] = array(
397 'Select' => FALSE,
398 'Insert' => FALSE,
399 'Update' => FALSE,
400 'References' => FALSE
403 PMA_DBI_free_result($res);
405 unset($res, $row1);
407 // t a b l e - s p e c i f i c p r i v i l e g e s
408 if (! empty($columns)) {
409 $res = PMA_DBI_query(
410 'SELECT `Column_name`, `Column_priv`'
411 .' FROM `mysql`.`columns_priv`'
412 .' WHERE `User`'
413 .' = \'' . PMA_sqlAddslashes($username) . "'"
414 .' AND `Host`'
415 .' = \'' . PMA_sqlAddslashes($hostname) . "'"
416 .' AND `Db`'
417 .' = \'' . PMA_sqlAddslashes(PMA_unescape_mysql_wildcards($db)) . "'"
418 .' AND `Table_name`'
419 .' = \'' . PMA_sqlAddslashes($table) . '\';');
421 while ($row1 = PMA_DBI_fetch_row($res)) {
422 $row1[1] = explode(',', $row1[1]);
423 foreach ($row1[1] as $current) {
424 $columns[$row1[0]][$current] = TRUE;
427 PMA_DBI_free_result($res);
428 unset($res, $row1, $current);
430 echo '<input type="hidden" name="grant_count" value="' . count($row) . '" />' . "\n"
431 . '<input type="hidden" name="column_count" value="' . count($columns) . '" />' . "\n"
432 . '<fieldset id="fieldset_user_priv">' . "\n"
433 . ' <legend>' . __('Table-specific privileges')
434 . PMA_showHint(__(' Note: MySQL privilege names are expressed in English '))
435 . '</legend>' . "\n";
439 // privs that are attached to a specific column
440 PMA_display_column_privs($columns, $row, 'Select_priv',
441 'SELECT', 'select', __('Allows reading data.'), 'Select');
443 PMA_display_column_privs($columns, $row, 'Insert_priv',
444 'INSERT', 'insert', __('Allows inserting and replacing data.'), 'Insert');
446 PMA_display_column_privs($columns, $row, 'Update_priv',
447 'UPDATE', 'update', __('Allows changing data.'), 'Update');
449 PMA_display_column_privs($columns, $row, 'References_priv',
450 'REFERENCES', 'references', __('Has no effect in this MySQL version.'), 'References');
452 // privs that are not attached to a specific column
454 echo ' <div class="item">' . "\n";
455 foreach ($row as $current_grant => $current_grant_value) {
456 if (in_array(substr($current_grant, 0, (strlen($current_grant) - 5)),
457 array('Select', 'Insert', 'Update', 'References'))) {
458 continue;
460 // make a substitution to match the messages variables;
461 // also we must substitute the grant we get, because we can't generate
462 // a form variable containing blanks (those would get changed to
463 // an underscore when receiving the POST)
464 if ($current_grant == 'Create View_priv') {
465 $tmp_current_grant = 'CreateView_priv';
466 $current_grant = 'Create_view_priv';
467 } elseif ($current_grant == 'Show view_priv') {
468 $tmp_current_grant = 'ShowView_priv';
469 $current_grant = 'Show_view_priv';
470 } else {
471 $tmp_current_grant = $current_grant;
474 echo ' <div class="item">' . "\n"
475 . ' <input type="checkbox"'
476 . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"')
477 . ' name="' . $current_grant . '" id="checkbox_' . $current_grant
478 . '" value="Y" '
479 . ($current_grant_value == 'Y' ? 'checked="checked" ' : '')
480 . 'title="';
482 echo (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))])
483 ? $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))]
484 : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)) . 'Tbl']) . '"/>' . "\n";
486 echo ' <label for="checkbox_' . $current_grant
487 . '"><tt><dfn title="'
488 . (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))])
489 ? $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))]
490 : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)) . 'Tbl'])
491 . '">' . strtoupper(substr($current_grant, 0, strlen($current_grant) - 5)) . '</dfn></tt></label>' . "\n"
492 . ' </div>' . "\n";
493 } // end foreach ()
495 echo ' </div>' . "\n";
496 // for Safari 2.0.2
497 echo ' <div class="clearfloat"></div>' . "\n";
499 } else {
501 // g l o b a l o r d b - s p e c i f i c
503 // d a t a
504 $privTable[0] = array(
505 array('Select', 'SELECT', __('Allows reading data.')),
506 array('Insert', 'INSERT', __('Allows inserting and replacing data.')),
507 array('Update', 'UPDATE', __('Allows changing data.')),
508 array('Delete', 'DELETE', __('Allows deleting data.'))
510 if ($db == '*') {
511 $privTable[0][] = array('File', 'FILE', __('Allows importing data from and exporting data into files.'));
514 // s t r u c t u r e
515 $privTable[1] = array(
516 array('Create', 'CREATE', ($table == '*' ? __('Allows creating new databases and tables.') : __('Allows creating new tables.'))),
517 array('Alter', 'ALTER', __('Allows altering the structure of existing tables.')),
518 array('Index', 'INDEX', __('Allows creating and dropping indexes.')),
519 array('Drop', 'DROP', ($table == '*' ? __('Allows dropping databases and tables.') : __('Allows dropping tables.'))),
520 array('Create_tmp_table', 'CREATE TEMPORARY TABLES', __('Allows creating temporary tables.')),
521 array('Show_view', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')),
522 array('Create_routine', 'CREATE ROUTINE', __('Allows creating stored routines.')),
523 array('Alter_routine', 'ALTER ROUTINE', __('Allows altering and dropping stored routines.')),
524 array('Execute', 'EXECUTE', __('Allows executing stored routines.')),
526 // this one is for a db-specific priv: Create_view_priv
527 if (isset($row['Create_view_priv'])) {
528 $privTable[1][] = array('Create_view', 'CREATE VIEW', __('Allows creating new views.'));
530 // this one is for a table-specific priv: Create View_priv
531 if (isset($row['Create View_priv'])) {
532 $privTable[1][] = array('Create View', 'CREATE VIEW', __('Allows creating new views.'));
534 if (isset($row['Event_priv'])) {
535 // MySQL 5.1.6
536 $privTable[1][] = array('Event', 'EVENT', __('Allows to set up events for the event scheduler'));
537 $privTable[1][] = array('Trigger', 'TRIGGER', __('Allows creating and dropping triggers'));
540 // a d m i n i s t r a t i o n
541 $privTable[2] = array(
542 array('Grant', 'GRANT', __('Allows adding users and privileges without reloading the privilege tables.')),
544 if ($db == '*') {
545 $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.'));
546 $privTable[2][] = array('Process', 'PROCESS', __('Allows viewing processes of all users'));
547 $privTable[2][] = array('Reload', 'RELOAD', __('Allows reloading server settings and flushing the server\'s caches.'));
548 $privTable[2][] = array('Shutdown', 'SHUTDOWN', __('Allows shutting down the server.'));
549 $privTable[2][] = array('Show_db', 'SHOW DATABASES', __('Gives access to the complete list of databases.'));
551 $privTable[2][] = array('Lock_tables', 'LOCK TABLES', __('Allows locking tables for the current thread.'));
552 $privTable[2][] = array('References', 'REFERENCES', __('Has no effect in this MySQL version.'));
553 if ($db == '*') {
554 $privTable[2][] = array('Repl_client', 'REPLICATION CLIENT', __('Allows the user to ask where the slaves / masters are.'));
555 $privTable[2][] = array('Repl_slave', 'REPLICATION SLAVE', __('Needed for the replication slaves.'));
556 $privTable[2][] = array('Create_user', 'CREATE USER', __('Allows creating, dropping and renaming user accounts.'));
558 echo '<input type="hidden" name="grant_count" value="'
559 . (count($privTable[0]) + count($privTable[1]) + count($privTable[2]) - (isset($row['Grant_priv']) ? 1 : 0))
560 . '" />' . "\n"
561 . '<fieldset id="fieldset_user_global_rights">' . "\n"
562 . ' <legend>' . "\n"
563 . ' '
564 . ($db == '*'
565 ? __('Global privileges')
566 : ($table == '*'
567 ? __('Database-specific privileges')
568 : __('Table-specific privileges'))) . "\n"
569 . ' (<a href="server_privileges.php?'
570 . $GLOBALS['url_query'] . '&amp;checkall=1" onclick="setCheckboxes(\'addUsersForm\', true); return false;">'
571 . __('Check All') . '</a> /' . "\n"
572 . ' <a href="server_privileges.php?'
573 . $GLOBALS['url_query'] . '" onclick="setCheckboxes(\'addUsersForm\', false); return false;">'
574 . __('Uncheck All') . '</a>)' . "\n"
575 . ' </legend>' . "\n"
576 . ' <p><small><i>' . __(' Note: MySQL privilege names are expressed in English ') . '</i></small></p>' . "\n"
577 . ' <fieldset>' . "\n"
578 . ' <legend>' . __('Data') . '</legend>' . "\n";
579 foreach ($privTable[0] as $priv)
581 echo ' <div class="item">' . "\n"
582 . ' <input type="checkbox"'
583 . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"')
584 . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0]
585 . '_priv" value="Y" '
586 . ($row[$priv[0] . '_priv'] == 'Y' ? 'checked="checked" ' : '')
587 . 'title="' . $priv[2] . '"/>' . "\n"
588 . ' <label for="checkbox_' . $priv[0]
589 . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1]
590 . '</dfn></tt></label>' . "\n"
591 . ' </div>' . "\n";
593 echo ' </fieldset>' . "\n"
594 . ' <fieldset>' . "\n"
595 . ' <legend>' . __('Structure') . '</legend>' . "\n";
596 foreach ($privTable[1] as $priv)
598 echo ' <div class="item">' . "\n"
599 . ' <input type="checkbox"'
600 . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"')
601 . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0]
602 . '_priv" value="Y" '
603 . ($row[$priv[0] . '_priv'] == 'Y' ? 'checked="checked" ' : '')
604 . 'title="' . $priv[2] . '"/>' . "\n"
605 . ' <label for="checkbox_' . $priv[0]
606 . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1]
607 . '</dfn></tt></label>' . "\n"
608 . ' </div>' . "\n";
610 echo ' </fieldset>' . "\n"
611 . ' <fieldset>' . "\n"
612 . ' <legend>' . __('Administration') . '</legend>' . "\n";
613 foreach ($privTable[2] as $priv)
615 echo ' <div class="item">' . "\n"
616 . ' <input type="checkbox"'
617 . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"')
618 . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0]
619 . '_priv" value="Y" '
620 . ($row[$priv[0] . '_priv'] == 'Y' ? 'checked="checked" ' : '')
621 . 'title="' . $priv[2] . '"/>' . "\n"
622 . ' <label for="checkbox_' . $priv[0]
623 . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1]
624 . '</dfn></tt></label>' . "\n"
625 . ' </div>' . "\n";
628 echo ' </fieldset>' . "\n";
629 // The "Resource limits" box is not displayed for db-specific privs
630 if ($db == '*') {
631 echo ' <fieldset>' . "\n"
632 . ' <legend>' . __('Resource limits') . '</legend>' . "\n"
633 . ' <p><small><i>' . __('Note: Setting these options to 0 (zero) removes the limit.') . '</i></small></p>' . "\n"
634 . ' <div class="item">' . "\n"
635 . ' <label for="text_max_questions"><tt><dfn title="'
636 . __('Limits the number of queries the user may send to the server per hour.') . '">MAX QUERIES PER HOUR</dfn></tt></label>' . "\n"
637 . ' <input type="text" name="max_questions" id="text_max_questions" value="'
638 . $row['max_questions'] . '" size="11" maxlength="11" title="' . __('Limits the number of queries the user may send to the server per hour.') . '" />' . "\n"
639 . ' </div>' . "\n"
640 . ' <div class="item">' . "\n"
641 . ' <label for="text_max_updates"><tt><dfn title="'
642 . __('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"
643 . ' <input type="text" name="max_updates" id="text_max_updates" value="'
644 . $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"
645 . ' </div>' . "\n"
646 . ' <div class="item">' . "\n"
647 . ' <label for="text_max_connections"><tt><dfn title="'
648 . __('Limits the number of new connections the user may open per hour.') . '">MAX CONNECTIONS PER HOUR</dfn></tt></label>' . "\n"
649 . ' <input type="text" name="max_connections" id="text_max_connections" value="'
650 . $row['max_connections'] . '" size="11" maxlength="11" title="' . __('Limits the number of new connections the user may open per hour.') . '" />' . "\n"
651 . ' </div>' . "\n"
652 . ' <div class="item">' . "\n"
653 . ' <label for="text_max_user_connections"><tt><dfn title="'
654 . __('Limits the number of simultaneous connections the user may have.') . '">MAX USER_CONNECTIONS</dfn></tt></label>' . "\n"
655 . ' <input type="text" name="max_user_connections" id="text_max_user_connections" value="'
656 . $row['max_user_connections'] . '" size="11" maxlength="11" title="' . __('Limits the number of simultaneous connections the user may have.') . '" />' . "\n"
657 . ' </div>' . "\n"
658 . ' </fieldset>' . "\n";
660 // for Safari 2.0.2
661 echo ' <div class="clearfloat"></div>' . "\n";
663 echo '</fieldset>' . "\n";
664 if ($submit) {
665 echo '<fieldset id="fieldset_user_privtable_footer" class="tblFooters">' . "\n"
666 . ' <input type="submit" name="update_privs" value="' . __('Go') . '" />' . "\n"
667 . '</fieldset>' . "\n";
669 } // end of the 'PMA_displayPrivTable()' function
673 * Displays the fields used by the "new user" form as well as the
674 * "change login information / copy user" form.
676 * @param string $mode are we creating a new user or are we just
677 * changing one? (allowed values: 'new', 'change')
678 * @global array $cfg the phpMyAdmin configuration
679 * @global ressource $user_link the database connection
681 * @return void
683 function PMA_displayLoginInformationFields($mode = 'new')
685 // Get user/host name lengths
686 $fields_info = PMA_DBI_get_fields('mysql', 'user');
687 $username_length = 16;
688 $hostname_length = 41;
689 foreach ($fields_info as $key => $val) {
690 if ($val['Field'] == 'User') {
691 strtok($val['Type'], '()');
692 $v = strtok('()');
693 if (is_int($v)) {
694 $username_length = $v;
696 } elseif ($val['Field'] == 'Host') {
697 strtok($val['Type'], '()');
698 $v = strtok('()');
699 if (is_int($v)) {
700 $hostname_length = $v;
704 unset($fields_info);
706 if (isset($GLOBALS['username']) && strlen($GLOBALS['username']) === 0) {
707 $GLOBALS['pred_username'] = 'any';
709 echo '<fieldset id="fieldset_add_user_login">' . "\n"
710 . '<legend>' . __('Login Information') . '</legend>' . "\n"
711 . '<div class="item">' . "\n"
712 . '<label for="select_pred_username">' . "\n"
713 . ' ' . __('User name') . ':' . "\n"
714 . '</label>' . "\n"
715 . '<span class="options">' . "\n"
716 . ' <select name="pred_username" id="select_pred_username" title="' . __('User name') . '"' . "\n"
717 . ' onchange="if (this.value == \'any\') { username.value = \'\'; } else if (this.value == \'userdefined\') { username.focus(); username.select(); }">' . "\n"
718 . ' <option value="any"' . ((isset($GLOBALS['pred_username']) && $GLOBALS['pred_username'] == 'any') ? ' selected="selected"' : '') . '>' . __('Any user') . '</option>' . "\n"
719 . ' <option value="userdefined"' . ((!isset($GLOBALS['pred_username']) || $GLOBALS['pred_username'] == 'userdefined') ? ' selected="selected"' : '') . '>' . __('Use text field') . ':</option>' . "\n"
720 . ' </select>' . "\n"
721 . '</span>' . "\n"
722 . '<input type="text" name="username" maxlength="'
723 . $username_length . '" title="' . __('User name') . '"'
724 . (empty($GLOBALS['username'])
725 ? ''
726 : ' value="' . htmlspecialchars(isset($GLOBALS['new_username'])
727 ? $GLOBALS['new_username']
728 : $GLOBALS['username']) . '"')
729 . ' onchange="pred_username.value = \'userdefined\';" />' . "\n"
730 . '</div>' . "\n"
731 . '<div class="item">' . "\n"
732 . '<label for="select_pred_hostname">' . "\n"
733 . ' ' . __('Host') . ':' . "\n"
734 . '</label>' . "\n"
735 . '<span class="options">' . "\n"
736 . ' <select name="pred_hostname" id="select_pred_hostname" title="' . __('Host') . '"' . "\n";
737 $_current_user = PMA_DBI_fetch_value('SELECT USER();');
738 if (! empty($_current_user)) {
739 $thishost = str_replace("'", '', substr($_current_user, (strrpos($_current_user, '@') + 1)));
740 if ($thishost == 'localhost' || $thishost == '127.0.0.1') {
741 unset($thishost);
744 echo ' onchange="if (this.value == \'any\') { hostname.value = \'%\'; } else if (this.value == \'localhost\') { hostname.value = \'localhost\'; } '
745 . (empty($thishost) ? '' : 'else if (this.value == \'thishost\') { hostname.value = \'' . addslashes(htmlspecialchars($thishost)) . '\'; } ')
746 . 'else if (this.value == \'hosttable\') { hostname.value = \'\'; } else if (this.value == \'userdefined\') { hostname.focus(); hostname.select(); }">' . "\n";
747 unset($_current_user);
749 // when we start editing a user, $GLOBALS['pred_hostname'] is not defined
750 if (!isset($GLOBALS['pred_hostname']) && isset($GLOBALS['hostname'])) {
751 switch (strtolower($GLOBALS['hostname'])) {
752 case 'localhost':
753 case '127.0.0.1':
754 $GLOBALS['pred_hostname'] = 'localhost';
755 break;
756 case '%':
757 $GLOBALS['pred_hostname'] = 'any';
758 break;
759 default:
760 $GLOBALS['pred_hostname'] = 'userdefined';
761 break;
764 echo ' <option value="any"'
765 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'any')
766 ? ' selected="selected"' : '') . '>' . __('Any host')
767 . '</option>' . "\n"
768 . ' <option value="localhost"'
769 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'localhost')
770 ? ' selected="selected"' : '') . '>' . __('Local')
771 . '</option>' . "\n";
772 if (!empty($thishost)) {
773 echo ' <option value="thishost"'
774 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'thishost')
775 ? ' selected="selected"' : '') . '>' . __('This Host')
776 . '</option>' . "\n";
778 unset($thishost);
779 echo ' <option value="hosttable"'
780 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'hosttable')
781 ? ' selected="selected"' : '') . '>' . __('Use Host Table')
782 . '</option>' . "\n"
783 . ' <option value="userdefined"'
784 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'userdefined')
785 ? ' selected="selected"' : '')
786 . '>' . __('Use text field') . ':</option>' . "\n"
787 . ' </select>' . "\n"
788 . '</span>' . "\n"
789 . '<input type="text" name="hostname" maxlength="'
790 . $hostname_length . '" value="'
791 . htmlspecialchars(isset($GLOBALS['hostname']) ? $GLOBALS['hostname'] : '')
792 . '" title="' . __('Host')
793 . '" onchange="pred_hostname.value = \'userdefined\';" />' . "\n"
794 . PMA_showHint(__('When Host table is used, this field is ignored and values stored in Host table are used instead.'))
795 . '</div>' . "\n"
796 . '<div class="item">' . "\n"
797 . '<label for="select_pred_password">' . "\n"
798 . ' ' . __('Password') . ':' . "\n"
799 . '</label>' . "\n"
800 . '<span class="options">' . "\n"
801 . ' <select name="pred_password" id="select_pred_password" title="'
802 . __('Password') . '"' . "\n"
803 . ' onchange="if (this.value == \'none\') { pma_pw.value = \'\'; pma_pw2.value = \'\'; } else if (this.value == \'userdefined\') { pma_pw.focus(); pma_pw.select(); }">' . "\n"
804 . ($mode == 'change' ? ' <option value="keep" selected="selected">' . __('Do not change the password') . '</option>' . "\n" : '')
805 . ' <option value="none"';
806 if (isset($GLOBALS['username']) && $mode != 'change') {
807 echo ' selected="selected"';
809 echo '>' . __('No Password') . '</option>' . "\n"
810 . ' <option value="userdefined"' . (isset($GLOBALS['username']) ? '' : ' selected="selected"') . '>' . __('Use text field') . ':</option>' . "\n"
811 . ' </select>' . "\n"
812 . '</span>' . "\n"
813 . '<input type="password" id="text_pma_pw" name="pma_pw" title="' . __('Password') . '" onchange="pred_password.value = \'userdefined\';" />' . "\n"
814 . '</div>' . "\n"
815 . '<div class="item" id="div_element_before_generate_password">' . "\n"
816 . '<label for="text_pma_pw2">' . "\n"
817 . ' ' . __('Re-type') . ':' . "\n"
818 . '</label>' . "\n"
819 . '<span class="options">&nbsp;</span>' . "\n"
820 . '<input type="password" name="pma_pw2" id="text_pma_pw2" title="' . __('Re-type') . '" onchange="pred_password.value = \'userdefined\';" />' . "\n"
821 . '</div>' . "\n"
822 // Generate password added here via jQuery
823 . '</fieldset>' . "\n";
824 } // end of the 'PMA_displayUserAndHostFields()' function
827 * Changes / copies a user, part I
829 if (isset($_REQUEST['change_copy'])) {
830 $user_host_condition =
831 ' WHERE `User`'
832 .' = \'' . PMA_sqlAddslashes($old_username) . "'"
833 .' AND `Host`'
834 .' = \'' . PMA_sqlAddslashes($old_hostname) . '\';';
835 $row = PMA_DBI_fetch_single_row('SELECT * FROM `mysql`.`user` ' . $user_host_condition);
836 if (! $row) {
837 PMA_Message::notice(__('No user found.'))->display();
838 unset($_REQUEST['change_copy']);
839 } else {
840 extract($row, EXTR_OVERWRITE);
841 // Recent MySQL versions have the field "Password" in mysql.user,
842 // so the previous extract creates $Password but this script
843 // uses $password
844 if (!isset($password) && isset($Password)) {
845 $password = $Password;
847 $queries = array();
853 * Adds a user
854 * (Changes / copies a user, part II)
856 if (isset($_REQUEST['adduser_submit']) || isset($_REQUEST['change_copy'])) {
857 $sql_query = '';
858 if ($pred_username == 'any') {
859 $username = '';
861 switch ($pred_hostname) {
862 case 'any':
863 $hostname = '%';
864 break;
865 case 'localhost':
866 $hostname = 'localhost';
867 break;
868 case 'hosttable':
869 $hostname = '';
870 break;
871 case 'thishost':
872 $_user_name = PMA_DBI_fetch_value('SELECT USER()');
873 $hostname = substr($_user_name, (strrpos($_user_name, '@') + 1));
874 unset($_user_name);
875 break;
877 $sql = "SELECT '1' FROM `mysql`.`user`"
878 . " WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
879 . " AND `Host` = '" . PMA_sqlAddslashes($hostname) . "';";
880 if (PMA_DBI_fetch_value($sql) == 1) {
881 $message = PMA_Message::error(__('The user %s already exists!'));
882 $message->addParam('[i]\'' . $username . '\'@\'' . $hostname . '\'[/i]');
883 $_REQUEST['adduser'] = true;
884 } else {
886 $create_user_real = 'CREATE USER \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\'';
888 $real_sql_query =
889 'GRANT ' . join(', ', PMA_extractPrivInfo()) . ' ON *.* TO \''
890 . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\'';
891 if ($pred_password != 'none' && $pred_password != 'keep') {
892 $sql_query = $real_sql_query . ' IDENTIFIED BY \'***\'';
893 $real_sql_query .= ' IDENTIFIED BY \'' . PMA_sqlAddslashes($pma_pw) . '\'';
894 if (isset($create_user_real)) {
895 $create_user_show = $create_user_real . ' IDENTIFIED BY \'***\'';
896 $create_user_real .= ' IDENTIFIED BY \'' . PMA_sqlAddslashes($pma_pw) . '\'';
898 } else {
899 if ($pred_password == 'keep' && !empty($password)) {
900 $real_sql_query .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
901 if (isset($create_user_real)) {
902 $create_user_real .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
905 $sql_query = $real_sql_query;
906 if (isset($create_user_real)) {
907 $create_user_show = $create_user_real;
911 * @todo similar code appears twice in this script
913 if ((isset($Grant_priv) && $Grant_priv == 'Y')
914 || (isset($max_questions) || isset($max_connections)
915 || isset($max_updates) || isset($max_user_connections))) {
916 $real_sql_query .= ' WITH';
917 $sql_query .= ' WITH';
918 if (isset($Grant_priv) && $Grant_priv == 'Y') {
919 $real_sql_query .= ' GRANT OPTION';
920 $sql_query .= ' GRANT OPTION';
922 if (isset($max_questions)) {
923 // avoid negative values
924 $max_questions = max(0, (int)$max_questions);
925 $real_sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
926 $sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
928 if (isset($max_connections)) {
929 $max_connections = max(0, (int)$max_connections);
930 $real_sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
931 $sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
933 if (isset($max_updates)) {
934 $max_updates = max(0, (int)$max_updates);
935 $real_sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
936 $sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
938 if (isset($max_user_connections)) {
939 $max_user_connections = max(0, (int)$max_user_connections);
940 $real_sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
941 $sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
944 if (isset($create_user_real)) {
945 $create_user_real .= ';';
946 $create_user_show .= ';';
948 $real_sql_query .= ';';
949 $sql_query .= ';';
950 if (empty($_REQUEST['change_copy'])) {
951 $_error = false;
953 if (isset($create_user_real)) {
954 if (! PMA_DBI_try_query($create_user_real)) {
955 $_error = true;
957 $sql_query = $create_user_show . $sql_query;
960 if ($_error || ! PMA_DBI_try_query($real_sql_query)) {
961 $_REQUEST['createdb'] = false;
962 $message = PMA_Message::rawError(PMA_DBI_getError());
963 } else {
964 $message = PMA_Message::success(__('You have added a new user.'));
967 switch (PMA_ifSetOr($_REQUEST['createdb'], '0')) {
968 case '1' :
969 // Create database with same name and grant all privileges
970 $q = 'CREATE DATABASE IF NOT EXISTS '
971 . PMA_backquote(PMA_sqlAddslashes($username)) . ';';
972 $sql_query .= $q;
973 if (! PMA_DBI_try_query($q)) {
974 $message = PMA_Message::rawError(PMA_DBI_getError());
975 break;
980 * If we are not in an Ajax request, we can't reload navigation now
982 if($GLOBALS['is_ajax_request'] != true) {
983 // this is needed in case tracking is on:
984 $GLOBALS['db'] = $username;
985 $GLOBALS['reload'] = TRUE;
986 PMA_reloadNavigation();
989 $q = 'GRANT ALL PRIVILEGES ON '
990 . PMA_backquote(PMA_sqlAddslashes($username)) . '.* TO \''
991 . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
992 $sql_query .= $q;
993 if (! PMA_DBI_try_query($q)) {
994 $message = PMA_Message::rawError(PMA_DBI_getError());
996 break;
997 case '2' :
998 // Grant all privileges on wildcard name (username\_%)
999 $q = 'GRANT ALL PRIVILEGES ON '
1000 . PMA_backquote(PMA_sqlAddslashes($username) . '\_%') . '.* TO \''
1001 . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1002 $sql_query .= $q;
1003 if (! PMA_DBI_try_query($q)) {
1004 $message = PMA_Message::rawError(PMA_DBI_getError());
1006 break;
1007 case '3' :
1008 // Grant all privileges on the specified database to the new user
1009 $q = 'GRANT ALL PRIVILEGES ON '
1010 . PMA_backquote(PMA_sqlAddslashes($dbname)) . '.* TO \''
1011 . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1012 $sql_query .= $q;
1013 if (! PMA_DBI_try_query($q)) {
1014 $message = PMA_Message::rawError(PMA_DBI_getError());
1016 break;
1017 case '0' :
1018 default :
1019 break;
1021 } else {
1022 if (isset($create_user_real)) {
1023 $queries[] = $create_user_real;
1025 $queries[] = $real_sql_query;
1026 // we put the query containing the hidden password in
1027 // $queries_for_display, at the same position occupied
1028 // by the real query in $queries
1029 $tmp_count = count($queries);
1030 if (isset($create_user_real)) {
1031 $queries_for_display[$tmp_count - 2] = $create_user_show;
1033 $queries_for_display[$tmp_count - 1] = $sql_query;
1035 unset($res, $real_sql_query);
1041 * Changes / copies a user, part III
1043 if (isset($_REQUEST['change_copy'])) {
1044 $user_host_condition =
1045 ' WHERE `User`'
1046 .' = \'' . PMA_sqlAddslashes($old_username) . "'"
1047 .' AND `Host`'
1048 .' = \'' . PMA_sqlAddslashes($old_hostname) . '\';';
1049 $res = PMA_DBI_query('SELECT * FROM `mysql`.`db`' . $user_host_condition);
1050 while ($row = PMA_DBI_fetch_assoc($res)) {
1051 $queries[] =
1052 'GRANT ' . join(', ', PMA_extractPrivInfo($row))
1053 .' ON ' . PMA_backquote($row['Db']) . '.*'
1054 .' TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\''
1055 . ($row['Grant_priv'] == 'Y' ? ' WITH GRANT OPTION;' : ';');
1057 PMA_DBI_free_result($res);
1058 $res = PMA_DBI_query(
1059 'SELECT `Db`, `Table_name`, `Table_priv`'
1060 .' FROM `mysql`.`tables_priv`' . $user_host_condition,
1061 $GLOBALS['userlink'], PMA_DBI_QUERY_STORE);
1062 while ($row = PMA_DBI_fetch_assoc($res)) {
1064 $res2 = PMA_DBI_QUERY(
1065 'SELECT `Column_name`, `Column_priv`'
1066 .' FROM `mysql`.`columns_priv`'
1067 .' WHERE `User`'
1068 .' = \'' . PMA_sqlAddslashes($old_username) . "'"
1069 .' AND `Host`'
1070 .' = \'' . PMA_sqlAddslashes($old_hostname) . '\''
1071 .' AND `Db`'
1072 .' = \'' . PMA_sqlAddslashes($row['Db']) . "'"
1073 .' AND `Table_name`'
1074 .' = \'' . PMA_sqlAddslashes($row['Table_name']) . "'"
1075 .';',
1076 null, PMA_DBI_QUERY_STORE);
1078 $tmp_privs1 = PMA_extractPrivInfo($row);
1079 $tmp_privs2 = array(
1080 'Select' => array(),
1081 'Insert' => array(),
1082 'Update' => array(),
1083 'References' => array()
1086 while ($row2 = PMA_DBI_fetch_assoc($res2)) {
1087 $tmp_array = explode(',', $row2['Column_priv']);
1088 if (in_array('Select', $tmp_array)) {
1089 $tmp_privs2['Select'][] = $row2['Column_name'];
1091 if (in_array('Insert', $tmp_array)) {
1092 $tmp_privs2['Insert'][] = $row2['Column_name'];
1094 if (in_array('Update', $tmp_array)) {
1095 $tmp_privs2['Update'][] = $row2['Column_name'];
1097 if (in_array('References', $tmp_array)) {
1098 $tmp_privs2['References'][] = $row2['Column_name'];
1100 unset($tmp_array);
1102 if (count($tmp_privs2['Select']) > 0 && !in_array('SELECT', $tmp_privs1)) {
1103 $tmp_privs1[] = 'SELECT (`' . join('`, `', $tmp_privs2['Select']) . '`)';
1105 if (count($tmp_privs2['Insert']) > 0 && !in_array('INSERT', $tmp_privs1)) {
1106 $tmp_privs1[] = 'INSERT (`' . join('`, `', $tmp_privs2['Insert']) . '`)';
1108 if (count($tmp_privs2['Update']) > 0 && !in_array('UPDATE', $tmp_privs1)) {
1109 $tmp_privs1[] = 'UPDATE (`' . join('`, `', $tmp_privs2['Update']) . '`)';
1111 if (count($tmp_privs2['References']) > 0 && !in_array('REFERENCES', $tmp_privs1)) {
1112 $tmp_privs1[] = 'REFERENCES (`' . join('`, `', $tmp_privs2['References']) . '`)';
1114 unset($tmp_privs2);
1115 $queries[] =
1116 'GRANT ' . join(', ', $tmp_privs1)
1117 . ' ON ' . PMA_backquote($row['Db']) . '.' . PMA_backquote($row['Table_name'])
1118 . ' TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\''
1119 . (in_array('Grant', explode(',', $row['Table_priv'])) ? ' WITH GRANT OPTION;' : ';');
1125 * Updates privileges
1127 if (!empty($update_privs)) {
1128 $db_and_table = PMA_WildcardEscapeForGrant($db_and_table, $dbname, (isset($tablename) ? $tablename : ''));
1130 $sql_query0 =
1131 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
1132 . ' FROM \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1133 if (!isset($Grant_priv) || $Grant_priv != 'Y') {
1134 $sql_query1 =
1135 'REVOKE GRANT OPTION ON ' . $db_and_table
1136 . ' FROM \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1137 } else {
1138 $sql_query1 = '';
1141 // Should not do a GRANT USAGE for a table-specific privilege, it
1142 // causes problems later (cannot revoke it)
1143 if (! (isset($tablename) && 'USAGE' == implode('', PMA_extractPrivInfo()))) {
1144 $sql_query2 =
1145 'GRANT ' . join(', ', PMA_extractPrivInfo())
1146 . ' ON ' . $db_and_table
1147 . ' TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\'';
1150 * @todo similar code appears twice in this script
1152 if ((isset($Grant_priv) && $Grant_priv == 'Y')
1153 || (! isset($dbname)
1154 && (isset($max_questions) || isset($max_connections)
1155 || isset($max_updates) || isset($max_user_connections))))
1157 $sql_query2 .= 'WITH';
1158 if (isset($Grant_priv) && $Grant_priv == 'Y') {
1159 $sql_query2 .= ' GRANT OPTION';
1161 if (isset($max_questions)) {
1162 $max_questions = max(0, (int)$max_questions);
1163 $sql_query2 .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
1165 if (isset($max_connections)) {
1166 $max_connections = max(0, (int)$max_connections);
1167 $sql_query2 .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
1169 if (isset($max_updates)) {
1170 $max_updates = max(0, (int)$max_updates);
1171 $sql_query2 .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
1173 if (isset($max_user_connections)) {
1174 $max_user_connections = max(0, (int)$max_user_connections);
1175 $sql_query2 .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
1178 $sql_query2 .= ';';
1180 if (! PMA_DBI_try_query($sql_query0)) {
1181 // this query may fail, but this does not matter :o)
1182 $sql_query0 = '';
1184 if (isset($sql_query1) && !PMA_DBI_try_query($sql_query1)) {
1185 // this one may fail, too...
1186 $sql_query1 = '';
1188 if (isset($sql_query2)) {
1189 PMA_DBI_query($sql_query2);
1190 } else {
1191 $sql_query2 = '';
1193 $sql_query = $sql_query0 . ' ' . $sql_query1 . ' ' . $sql_query2;
1194 $message = PMA_Message::success(__('You have updated the privileges for %s.'));
1195 $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'');
1200 * Revokes Privileges
1202 if (isset($_REQUEST['revokeall'])) {
1203 $db_and_table = PMA_WildcardEscapeForGrant($db_and_table, $dbname, isset($tablename) ? $tablename : '');
1205 $sql_query0 =
1206 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
1207 . ' FROM \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1208 $sql_query1 =
1209 'REVOKE GRANT OPTION ON ' . $db_and_table
1210 . ' FROM \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1212 PMA_DBI_query($sql_query0);
1213 if (! PMA_DBI_try_query($sql_query1)) {
1214 // this one may fail, too...
1215 $sql_query1 = '';
1217 $sql_query = $sql_query0 . ' ' . $sql_query1;
1218 $message = PMA_Message::success(__('You have revoked the privileges for %s'));
1219 $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'');
1220 if (! isset($tablename)) {
1221 unset($dbname);
1222 } else {
1223 unset($tablename);
1229 * Updates the password
1231 if (isset($_REQUEST['change_pw'])) {
1232 // similar logic in user_password.php
1233 $message = '';
1235 if ($nopass == 0 && isset($pma_pw) && isset($pma_pw2)) {
1236 if ($pma_pw != $pma_pw2) {
1237 $message = PMA_Message::error(__('The passwords aren\'t the same!'));
1238 } elseif (empty($pma_pw) || empty($pma_pw2)) {
1239 $message = PMA_Message::error(__('The password is empty!'));
1241 } // end if
1243 // here $nopass could be == 1
1244 if (empty($message)) {
1246 $hashing_function = (!empty($pw_hash) && $pw_hash == 'old' ? 'OLD_' : '')
1247 . 'PASSWORD';
1249 // in $sql_query which will be displayed, hide the password
1250 $sql_query = 'SET PASSWORD FOR \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\' = ' . (($pma_pw == '') ? '\'\'' : $hashing_function . '(\'' . preg_replace('@.@s', '*', $pma_pw) . '\')');
1251 $local_query = 'SET PASSWORD FOR \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\' = ' . (($pma_pw == '') ? '\'\'' : $hashing_function . '(\'' . PMA_sqlAddslashes($pma_pw) . '\')');
1252 PMA_DBI_try_query($local_query)
1253 or PMA_mysqlDie(PMA_DBI_getError(), $sql_query, FALSE, $err_url);
1254 $message = PMA_Message::success(__('The password for %s was changed successfully.'));
1255 $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'');
1261 * Deletes users
1262 * (Changes / copies a user, part IV)
1265 if (isset($_REQUEST['delete']) || (isset($_REQUEST['change_copy']) && $_REQUEST['mode'] < 4)) {
1266 if (isset($_REQUEST['change_copy'])) {
1267 $selected_usr = array($old_username . '&amp;#27;' . $old_hostname);
1268 } else {
1269 $selected_usr = $_REQUEST['selected_usr'];
1270 $queries = array();
1272 foreach ($selected_usr as $each_user) {
1273 list($this_user, $this_host) = explode('&amp;#27;', $each_user);
1274 $queries[] = '# ' . sprintf(__('Deleting %s'), '\'' . $this_user . '\'@\'' . $this_host . '\'') . ' ...';
1275 $queries[] = 'DROP USER \'' . PMA_sqlAddslashes($this_user) . '\'@\'' . PMA_sqlAddslashes($this_host) . '\';';
1277 if (isset($_REQUEST['drop_users_db'])) {
1278 $queries[] = 'DROP DATABASE IF EXISTS ' . PMA_backquote($this_user) . ';';
1279 $GLOBALS['reload'] = TRUE;
1281 if($GLOBALS['is_ajax_request'] != true) {
1282 PMA_reloadNavigation();
1286 if (empty($_REQUEST['change_copy'])) {
1287 if (empty($queries)) {
1288 $message = PMA_Message::error(__('No users selected for deleting!'));
1289 } else {
1290 if ($_REQUEST['mode'] == 3) {
1291 $queries[] = '# ' . __('Reloading the privileges') . ' ...';
1292 $queries[] = 'FLUSH PRIVILEGES;';
1294 $drop_user_error = '';
1295 foreach ($queries as $sql_query) {
1296 if ($sql_query{0} != '#') {
1297 if (! PMA_DBI_try_query($sql_query, $GLOBALS['userlink'])) {
1298 $drop_user_error .= PMA_DBI_getError() . "\n";
1302 // tracking sets this, causing the deleted db to be shown in navi
1303 unset($GLOBALS['db']);
1305 $sql_query = join("\n", $queries);
1306 if (! empty($drop_user_error)) {
1307 $message = PMA_Message::rawError($drop_user_error);
1308 } else {
1309 $message = PMA_Message::success(__('The selected users have been deleted successfully.'));
1312 unset($queries);
1318 * Changes / copies a user, part V
1320 if (isset($_REQUEST['change_copy'])) {
1321 $tmp_count = 0;
1322 foreach ($queries as $sql_query) {
1323 if ($sql_query{0} != '#') {
1324 PMA_DBI_query($sql_query);
1326 // when there is a query containing a hidden password, take it
1327 // instead of the real query sent
1328 if (isset($queries_for_display[$tmp_count])) {
1329 $queries[$tmp_count] = $queries_for_display[$tmp_count];
1331 $tmp_count++;
1333 $message = PMA_Message::success();
1334 $sql_query = join("\n", $queries);
1339 * Reloads the privilege tables into memory
1341 if (isset($_REQUEST['flush_privileges'])) {
1342 $sql_query = 'FLUSH PRIVILEGES;';
1343 PMA_DBI_query($sql_query);
1344 $message = PMA_Message::success(__('The privileges were reloaded successfully.'));
1348 * defines some standard links
1350 $link_edit = '<a class="edit_user_anchor" href="server_privileges.php?' . $GLOBALS['url_query']
1351 . '&amp;username=%s'
1352 . '&amp;hostname=%s'
1353 . '&amp;dbname=%s'
1354 . '&amp;tablename=%s">'
1355 . PMA_getIcon('b_usredit.png', __('Edit Privileges'))
1356 . '</a>';
1358 $link_revoke = '<a href="server_privileges.php?' . $GLOBALS['url_query']
1359 . '&amp;username=%s'
1360 . '&amp;hostname=%s'
1361 . '&amp;dbname=%s'
1362 . '&amp;tablename=%s'
1363 . '&amp;revokeall=1">'
1364 . PMA_getIcon('b_usrdrop.png', __('Revoke'))
1365 . '</a>';
1367 $link_export = '<a class="export_user_anchor" href="server_privileges.php?' . $GLOBALS['url_query']
1368 . '&amp;username=%s'
1369 . '&amp;hostname=%s'
1370 . '&amp;initial=%s'
1371 . '&amp;export=1">'
1372 . PMA_getIcon('b_tblexport.png', __('Export'))
1373 . '</a>';
1376 * If we are in an Ajax request for Create User/Edit User/Revoke User/Flush Privileges,
1377 * show $message and exit.
1379 if( $GLOBALS['is_ajax_request'] && !isset($_REQUEST['export']) && !isset($_REQUEST['adduser']) && !isset($_REQUEST['initial']) && !isset($_REQUEST['showall']) && !isset($_REQUEST['edit_user_dialog'])) {
1381 if(isset($sql_query)) {
1382 $extra_data['sql_query'] = PMA_showMessage(NULL, $sql_query);
1385 if(isset($_REQUEST['adduser_submit']) || isset($_REQUEST['change_copy'])) {
1387 * generate html on the fly for the new user that was just created.
1389 $new_user_string = '<tr>'."\n"
1390 .'<td> <input type="checkbox" name="selected_usr[]" id="checkbox_sel_users_" value="' . htmlspecialchars($username) . '&amp;#27;' . htmlspecialchars($hostname) . '" /> </td>'."\n"
1391 .'<td><label for="checkbox_sel_users_">' . (empty($username) ? '<span style="color: #FF0000">' . __('Any') . '</span>' : htmlspecialchars($username) ) . '</label></td>' . "\n"
1392 .'<td>' . htmlspecialchars($hostname) . '</td>' . "\n";
1393 $new_user_string .= '<td>';
1395 if(!empty($password) || isset($pma_pw)) {
1396 $new_user_string .= __('Yes');
1398 else {
1399 $new_user_string .= '<span style="color: #FF0000">' . __('No') . '</span>';
1402 $new_user_string .= '</td>'."\n";
1403 $new_user_string .= '<td><tt>' . join(', ', PMA_extractPrivInfo('', true)) . '</tt></td>'; //Fill in privileges here
1404 $new_user_string .= '<td>';
1406 if((isset($Grant_priv) && $Grant_priv == 'Y')) {
1407 $new_user_string .= __('Yes');
1409 else {
1410 $new_user_string .= __('No');
1413 $new_user_string .='</td>';
1415 $new_user_string .= '<td>'.sprintf($link_edit, urlencode($username), urlencode($host), '', '' ).'</td>'."\n";
1416 $new_user_string .= '<td>'.sprintf($link_export, urlencode($username), urlencode($hostname), (isset($initial) ? $initial : '')).'</td>'."\n";
1418 $new_user_string .= '</tr>';
1420 $extra_data['new_user_string'] = $new_user_string;
1423 * Generate the string for this alphabet's initial, to update the user
1424 * pagination
1426 $new_user_initial = strtoupper(substr($username, 0, 1));
1427 $new_user_initial_string = '<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&initial=' . $new_user_initial
1428 .'>' . $new_user_initial . '</a>';
1429 $extra_data['new_user_initial'] = $new_user_initial;
1430 $extra_data['new_user_initial_string'] = $new_user_initial_string;
1433 if(isset($update_privs)) {
1434 $new_privileges = join(', ', PMA_extractPrivInfo('', true));
1436 $extra_data['new_privileges'] = $new_privileges;
1439 PMA_ajaxResponse($message, $message->isSuccess(), $extra_data);
1443 * Displays the links
1445 if (isset($viewing_mode) && $viewing_mode == 'db') {
1446 $db = $checkprivs;
1447 $url_query .= '&amp;goto=db_operations.php';
1449 // Gets the database structure
1450 $sub_part = '_structure';
1451 require './libraries/db_info.inc.php';
1452 echo "\n";
1453 } else {
1454 require './libraries/server_links.inc.php';
1459 * Displays the page
1462 // export user definition
1463 if (isset($_REQUEST['export'])) {
1464 echo '<h2>' . __('User') . ' \'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'</h2>';
1465 echo '<textarea cols="' . $GLOBALS['cfg']['TextareaCols'] . '" rows="' . $GLOBALS['cfg']['TextareaRows'] . '">';
1466 $grants = PMA_DBI_fetch_result("SHOW GRANTS FOR '" . PMA_sqlAddslashes($username) . "'@'" . PMA_sqlAddslashes($hostname) . "'");
1467 foreach($grants as $one_grant) {
1468 echo $one_grant . ";\n\n";
1470 echo '</textarea>';
1471 unset($username, $hostname, $grants, $one_grant);
1472 if( $GLOBALS['is_ajax_request']) {
1473 exit;
1477 if (empty($_REQUEST['adduser']) && (! isset($checkprivs) || ! strlen($checkprivs))) {
1478 if (! isset($username)) {
1479 // No username is given --> display the overview
1480 echo '<h2>' . "\n"
1481 . PMA_getIcon('b_usrlist.png')
1482 . __('User overview') . "\n"
1483 . '</h2>' . "\n";
1485 $sql_query =
1486 'SELECT *,' .
1487 " IF(`Password` = _latin1 '', 'N', 'Y') AS 'Password'" .
1488 ' FROM `mysql`.`user`';
1490 $sql_query .= (isset($initial) ? PMA_RangeOfUsers($initial) : '');
1492 $sql_query .= ' ORDER BY `User` ASC, `Host` ASC;';
1493 $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE);
1495 if (! $res) {
1496 // the query failed! This may have two reasons:
1497 // - the user does not have enough privileges
1498 // - the privilege tables use a structure of an earlier version.
1499 // so let's try a more simple query
1501 $sql_query = 'SELECT * FROM `mysql`.`user`';
1502 $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE);
1504 if (!$res) {
1505 PMA_Message::error(__('No Privileges'))->display();
1506 PMA_DBI_free_result($res);
1507 unset($res);
1508 } else {
1509 // This message is hardcoded because I will replace it by
1510 // a automatic repair feature soon.
1511 $raw = 'Your privilege table structure seems to be older than'
1512 . ' this MySQL version!<br />'
1513 . 'Please run the <tt>mysql_upgrade</tt> command'
1514 . '(<tt>mysql_fix_privilege_tables</tt> on older systems)'
1515 . ' that should be included in your MySQL server distribution'
1516 . ' to solve this problem!';
1517 PMA_Message::rawError($raw)->display();
1519 } else {
1521 // we also want users not in table `user` but in other table
1522 $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;');
1524 $tables_to_search_for_users = array(
1525 'user', 'db', 'tables_priv', 'columns_priv', 'procs_priv',
1528 $db_rights_sqls = array();
1529 foreach ($tables_to_search_for_users as $table_search_in) {
1530 if (in_array($table_search_in, $tables)) {
1531 $db_rights_sqls[] = 'SELECT DISTINCT `User`, `Host` FROM `mysql`.`' . $table_search_in . '` ' . (isset($initial) ? PMA_RangeOfUsers($initial) : '');
1535 $user_defaults = array(
1536 'User' => '',
1537 'Host' => '%',
1538 'Password' => '?',
1539 'Grant_priv' => 'N',
1540 'privs' => array('USAGE'),
1543 // for all initials, even non A-Z
1544 $array_initials = array();
1545 // for the rights
1546 $db_rights = array();
1548 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
1549 .' ORDER BY `User` ASC, `Host` ASC';
1551 $db_rights_result = PMA_DBI_query($db_rights_sql);
1553 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
1554 $db_rights_row = array_merge($user_defaults, $db_rights_row);
1555 $db_rights[$db_rights_row['User']][$db_rights_row['Host']] =
1556 $db_rights_row;
1558 PMA_DBI_free_result($db_rights_result);
1559 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
1560 ksort($db_rights);
1563 * Displays the initials
1564 * In an Ajax request, we don't need to show this
1567 if( $GLOBALS['is_ajax_request'] != true ) {
1569 // initialize to FALSE the letters A-Z
1570 for ($letter_counter = 1; $letter_counter < 27; $letter_counter++) {
1571 if (! isset($array_initials[chr($letter_counter + 64)])) {
1572 $array_initials[chr($letter_counter + 64)] = FALSE;
1576 $initials = PMA_DBI_try_query('SELECT DISTINCT UPPER(LEFT(`User`,1)) FROM `user` ORDER BY `User` ASC', null, PMA_DBI_QUERY_STORE);
1577 while (list($tmp_initial) = PMA_DBI_fetch_row($initials)) {
1578 $array_initials[$tmp_initial] = TRUE;
1581 // Display the initials, which can be any characters, not
1582 // just letters. For letters A-Z, we add the non-used letters
1583 // as greyed out.
1585 uksort($array_initials, "strnatcasecmp");
1587 echo '<table id="initials_table" cellspacing="5"><tr>';
1588 foreach ($array_initials as $tmp_initial => $initial_was_found) {
1589 if ($initial_was_found) {
1590 echo '<td><a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;initial=' . urlencode($tmp_initial) . '">' . $tmp_initial . '</a></td>' . "\n";
1591 } else {
1592 echo '<td>' . $tmp_initial . '</td>';
1595 echo '<td><a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;showall=1">[' . __('Show all') . ']</a></td>' . "\n";
1596 echo '</tr></table>';
1600 * Display the user overview
1601 * (if less than 50 users, display them immediately)
1604 if (isset($initial) || isset($showall) || PMA_DBI_num_rows($res) < 50) {
1606 while ($row = PMA_DBI_fetch_assoc($res)) {
1607 $row['privs'] = PMA_extractPrivInfo($row, true);
1608 $db_rights[$row['User']][$row['Host']] = $row;
1610 @PMA_DBI_free_result($res);
1611 unset($res);
1613 echo '<form name="usersForm" id="usersForm" action="server_privileges.php" method="post">' . "\n"
1614 . PMA_generate_common_hidden_inputs('', '')
1615 . ' <table id="tableuserrights" class="data">' . "\n"
1616 . ' <thead>' . "\n"
1617 . ' <tr><th></th>' . "\n"
1618 . ' <th>' . __('User') . '</th>' . "\n"
1619 . ' <th>' . __('Host') . '</th>' . "\n"
1620 . ' <th>' . __('Password') . '</th>' . "\n"
1621 . ' <th>' . __('Global privileges') . ' '
1622 . PMA_showHint(__(' Note: MySQL privilege names are expressed in English ')) . '</th>' . "\n"
1623 . ' <th>' . __('Grant') . '</th>' . "\n"
1624 . ' <th colspan="2">' . __('Action') . '</th>' . "\n";
1625 echo ' </tr>' . "\n";
1626 echo ' </thead>' . "\n";
1627 echo ' <tbody>' . "\n";
1628 $odd_row = true;
1629 $index_checkbox = -1;
1630 foreach ($db_rights as $user) {
1631 $index_checkbox++;
1632 ksort($user);
1633 foreach ($user as $host) {
1634 $index_checkbox++;
1635 echo ' <tr class="' . ($odd_row ? 'odd' : 'even') . '">' . "\n"
1636 . ' <td><input type="checkbox" name="selected_usr[]" id="checkbox_sel_users_'
1637 . $index_checkbox . '" value="'
1638 . htmlspecialchars($host['User'] . '&amp;#27;' . $host['Host'])
1639 . '"'
1640 . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"')
1641 . ' /></td>' . "\n"
1642 . ' <td><label for="checkbox_sel_users_' . $index_checkbox . '">' . (empty($host['User']) ? '<span style="color: #FF0000">' . __('Any') . '</span>' : htmlspecialchars($host['User'])) . '</label></td>' . "\n"
1643 . ' <td>' . htmlspecialchars($host['Host']) . '</td>' . "\n";
1644 echo ' <td>';
1645 switch ($host['Password']) {
1646 case 'Y':
1647 echo __('Yes');
1648 break;
1649 case 'N':
1650 echo '<span style="color: #FF0000">' . __('No') . '</span>';
1651 break;
1652 // this happens if this is a definition not coming from mysql.user
1653 default:
1654 echo '--'; // in future version, replace by "not present"
1655 break;
1656 } // end switch
1657 echo '</td>' . "\n"
1658 . ' <td><tt>' . "\n"
1659 . ' ' . implode(',' . "\n" . ' ', $host['privs']) . "\n"
1660 . ' </tt></td>' . "\n"
1661 . ' <td>' . ($host['Grant_priv'] == 'Y' ? __('Yes') : __('No')) . '</td>' . "\n"
1662 . ' <td align="center">';
1663 printf($link_edit, urlencode($host['User']), urlencode($host['Host']), '', '');
1664 echo '</td>';
1665 echo '<td align="center">';
1666 printf($link_export, urlencode($host['User']), urlencode($host['Host']), (isset($initial) ? $initial : ''));
1667 echo '</td>';
1668 echo '</tr>';
1669 $odd_row = ! $odd_row;
1673 unset($user, $host, $odd_row);
1674 echo ' </tbody></table>' . "\n"
1675 .'<img class="selectallarrow"'
1676 .' src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png"'
1677 .' width="38" height="22"'
1678 .' alt="' . __('With selected:') . '" />' . "\n"
1679 .'<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;checkall=1"'
1680 .' onclick="if (markAllRows(\'usersForm\')) return false;">'
1681 . __('Check All') . '</a>' . "\n"
1682 .'/' . "\n"
1683 .'<a href="server_privileges.php?' . $GLOBALS['url_query'] . '"'
1684 .' onclick="if (unMarkAllRows(\'usersForm\')) return false;">'
1685 . __('Uncheck All') . '</a>' . "\n";
1687 // add/delete user fieldset
1688 echo ' <fieldset id="fieldset_add_user">' . "\n"
1689 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;adduser=1">' . "\n"
1690 . PMA_getIcon('b_usradd.png')
1691 . ' ' . __('Add a new User') . '</a>' . "\n"
1692 . ' </fieldset>' . "\n"
1693 . ' <fieldset id="fieldset_delete_user">'
1694 . ' <legend>' . "\n"
1695 . PMA_getIcon('b_usrdrop.png')
1696 . ' ' . __('Remove selected users') . '' . "\n"
1697 . ' </legend>' . "\n"
1698 . ' <input type="hidden" name="mode" value="2" />' . "\n"
1699 . '(' . __('Revoke all active privileges from the users and delete them afterwards.') . ')<br />' . "\n"
1700 . ' <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"
1701 . ' <label for="checkbox_drop_users_db" title="' . __('Drop the databases that have the same names as the users.') . '">' . "\n"
1702 . ' ' . __('Drop the databases that have the same names as the users.') . "\n"
1703 . ' </label>' . "\n"
1704 . ' </fieldset>' . "\n"
1705 . ' <fieldset id="fieldset_delete_user_footer" class="tblFooters">' . "\n"
1706 . ' <input type="submit" name="delete" value="' . __('Go') . '" id="buttonGo" />' . "\n"
1707 . ' </fieldset>' . "\n"
1708 . '</form>' . "\n";
1709 } else {
1711 unset ($row);
1712 echo ' <fieldset id="fieldset_add_user">' . "\n"
1713 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;adduser=1">' . "\n"
1714 . PMA_getIcon('b_usradd.png')
1715 . ' ' . __('Add a new User') . '</a>' . "\n"
1716 . ' </fieldset>' . "\n";
1717 } // end if (display overview)
1719 if( $GLOBALS['is_ajax_request'] ) {
1720 exit;
1723 $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);
1724 $flushnote->addParam('<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;flush_privileges=1" id="reload_privileges_anchor">', false);
1725 $flushnote->addParam('</a>', false);
1726 $flushnote->display();
1730 } else {
1732 // A user was selected -> display the user's properties
1734 // In an Ajax request, prevent cached values from showing
1735 if($GLOBALS['is_ajax_request'] == true) {
1736 header('Cache-Control: no-cache');
1739 echo '<h2>' . "\n"
1740 . PMA_getIcon('b_usredit.png')
1741 . __('Edit Privileges') . ': '
1742 . __('User') ;
1744 if (isset($dbname)) {
1745 echo ' <i><a href="server_privileges.php?'
1746 . $GLOBALS['url_query'] . '&amp;username=' . htmlspecialchars(urlencode($username))
1747 . '&amp;hostname=' . htmlspecialchars(urlencode($hostname)) . '&amp;dbname=&amp;tablename=">\''
1748 . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname)
1749 . '\'</a></i>' . "\n";
1750 $url_dbname = urlencode(str_replace(array('\_', '\%'), array('_', '%'), $dbname));
1752 echo ' - ' . ($dbname_is_wildcard ? __('Databases') : __('Database') );
1753 if (isset($tablename)) {
1754 echo ' <i><a href="server_privileges.php?' . $GLOBALS['url_query']
1755 . '&amp;username=' . htmlspecialchars(urlencode($username)) . '&amp;hostname=' . htmlspecialchars(urlencode($hostname))
1756 . '&amp;dbname=' . htmlspecialchars($url_dbname) . '&amp;tablename=">' . htmlspecialchars($dbname) . '</a></i>';
1757 echo ' - ' . __('Table') . ' <i>' . htmlspecialchars($tablename) . '</i>';
1758 } else {
1759 echo ' <i>' . htmlspecialchars($dbname) . '</i>';
1762 } else {
1763 echo ' <i>\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname)
1764 . '\'</i>' . "\n";
1767 echo '</h2>' . "\n";
1770 $sql = "SELECT '1' FROM `mysql`.`user`"
1771 . " WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
1772 . " AND `Host` = '" . PMA_sqlAddslashes($hostname) . "';";
1773 $user_does_not_exists = (bool) ! PMA_DBI_fetch_value($sql);
1774 unset($sql);
1775 if ($user_does_not_exists) {
1776 PMA_Message::warning(__('The selected user was not found in the privilege table.'))->display();
1777 PMA_displayLoginInformationFields();
1778 //require './libraries/footer.inc.php';
1781 echo '<form name="usersForm" id="addUsersForm" action="server_privileges.php" method="post">' . "\n";
1782 $_params = array(
1783 'username' => $username,
1784 'hostname' => $hostname,
1786 if (isset($dbname)) {
1787 $_params['dbname'] = $dbname;
1788 if (isset($tablename)) {
1789 $_params['tablename'] = $tablename;
1792 echo PMA_generate_common_hidden_inputs($_params);
1794 PMA_displayPrivTable(PMA_ifSetOr($dbname, '*', 'length'),
1795 PMA_ifSetOr($tablename, '*', 'length'));
1797 echo '</form>' . "\n";
1799 if (! isset($tablename) && empty($dbname_is_wildcard)) {
1801 // no table name was given, display all table specific rights
1802 // but only if $dbname contains no wildcards
1804 // table header
1805 echo '<form action="server_privileges.php" method="post">' . "\n"
1806 . PMA_generate_common_hidden_inputs('', '')
1807 . '<input type="hidden" name="username" value="' . htmlspecialchars($username) . '" />' . "\n"
1808 . '<input type="hidden" name="hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n"
1809 . '<fieldset>' . "\n"
1810 . '<legend>' . (! isset($dbname) ? __('Database-specific privileges') : __('Table-specific privileges')) . '</legend>' . "\n"
1811 . '<table class="data">' . "\n"
1812 . '<thead>' . "\n"
1813 . '<tr><th>' . (! isset($dbname) ? __('Database') : __('Table')) . '</th>' . "\n"
1814 . ' <th>' . __('Privileges') . '</th>' . "\n"
1815 . ' <th>' . __('Grant') . '</th>' . "\n"
1816 . ' <th>' . (! isset($dbname) ? __('Table-specific privileges') : __('Column-specific privileges')) . '</th>' . "\n"
1817 . ' <th colspan="2">' . __('Action') . '</th>' . "\n"
1818 . '</tr>' . "\n"
1819 . '</thead>' . "\n"
1820 . '<tbody>' . "\n";
1822 $user_host_condition =
1823 ' WHERE `User`'
1824 . ' = \'' . PMA_sqlAddslashes($username) . "'"
1825 . ' AND `Host`'
1826 . ' = \'' . PMA_sqlAddslashes($hostname) . "'";
1828 // table body
1829 // get data
1831 // we also want privielgs for this user not in table `db` but in other table
1832 $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;');
1833 if (! isset($dbname)) {
1835 // no db name given, so we want all privs for the given user
1837 $tables_to_search_for_users = array(
1838 'tables_priv', 'columns_priv',
1841 $db_rights_sqls = array();
1842 foreach ($tables_to_search_for_users as $table_search_in) {
1843 if (in_array($table_search_in, $tables)) {
1844 $db_rights_sqls[] = '
1845 SELECT DISTINCT `Db`
1846 FROM `mysql`.' . PMA_backquote($table_search_in)
1847 . $user_host_condition;
1851 $user_defaults = array(
1852 'Db' => '',
1853 'Grant_priv' => 'N',
1854 'privs' => array('USAGE'),
1855 'Table_privs' => true,
1858 // for the rights
1859 $db_rights = array();
1861 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
1862 .' ORDER BY `Db` ASC';
1864 $db_rights_result = PMA_DBI_query($db_rights_sql);
1866 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
1867 $db_rights_row = array_merge($user_defaults, $db_rights_row);
1868 // only Db names in the table `mysql`.`db` uses wildcards
1869 // as we are in the db specific rights display we want
1870 // all db names escaped, also from other sources
1871 $db_rights_row['Db'] = PMA_escape_mysql_wildcards(
1872 $db_rights_row['Db']);
1873 $db_rights[$db_rights_row['Db']] = $db_rights_row;
1876 PMA_DBI_free_result($db_rights_result);
1877 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
1879 $sql_query = 'SELECT * FROM `mysql`.`db`' . $user_host_condition . ' ORDER BY `Db` ASC';
1880 $res = PMA_DBI_query($sql_query);
1881 $sql_query = '';
1883 while ($row = PMA_DBI_fetch_assoc($res)) {
1884 if (isset($db_rights[$row['Db']])) {
1885 $db_rights[$row['Db']] = array_merge($db_rights[$row['Db']], $row);
1886 } else {
1887 $db_rights[$row['Db']] = $row;
1889 // there are db specific rights for this user
1890 // so we can drop this db rights
1891 $db_rights[$row['Db']]['can_delete'] = true;
1893 PMA_DBI_free_result($res);
1894 unset($row, $res);
1896 } else {
1898 // db name was given,
1899 // so we want all user specific rights for this db
1901 $user_host_condition .=
1902 ' AND `Db`'
1903 .' LIKE \'' . PMA_sqlAddslashes($dbname) . "'";
1905 $tables_to_search_for_users = array(
1906 'columns_priv',
1909 $db_rights_sqls = array();
1910 foreach ($tables_to_search_for_users as $table_search_in) {
1911 if (in_array($table_search_in, $tables)) {
1912 $db_rights_sqls[] = '
1913 SELECT DISTINCT `Table_name`
1914 FROM `mysql`.' . PMA_backquote($table_search_in)
1915 . $user_host_condition;
1919 $user_defaults = array(
1920 'Table_name' => '',
1921 'Grant_priv' => 'N',
1922 'privs' => array('USAGE'),
1923 'Column_priv' => true,
1926 // for the rights
1927 $db_rights = array();
1929 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
1930 .' ORDER BY `Table_name` ASC';
1932 $db_rights_result = PMA_DBI_query($db_rights_sql);
1934 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
1935 $db_rights_row = array_merge($user_defaults, $db_rights_row);
1936 $db_rights[$db_rights_row['Table_name']] = $db_rights_row;
1938 PMA_DBI_free_result($db_rights_result);
1939 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
1941 $sql_query =
1942 'SELECT `Table_name`,'
1943 .' `Table_priv`,'
1944 .' IF(`Column_priv` = _latin1 \'\', 0, 1)'
1945 .' AS \'Column_priv\''
1946 .' FROM `mysql`.`tables_priv`'
1947 . $user_host_condition
1948 .' ORDER BY `Table_name` ASC;';
1949 $res = PMA_DBI_query($sql_query);
1950 $sql_query = '';
1952 while ($row = PMA_DBI_fetch_assoc($res)) {
1953 if (isset($db_rights[$row['Table_name']])) {
1954 $db_rights[$row['Table_name']] = array_merge($db_rights[$row['Table_name']], $row);
1955 } else {
1956 $db_rights[$row['Table_name']] = $row;
1959 PMA_DBI_free_result($res);
1960 unset($row, $res);
1962 ksort($db_rights);
1964 // display rows
1965 if (count($db_rights) < 1) {
1966 echo '<tr class="odd">' . "\n"
1967 . ' <td colspan="6"><center><i>' . __('None') . '</i></center></td>' . "\n"
1968 . '</tr>' . "\n";
1969 } else {
1970 $odd_row = true;
1971 $found_rows = array();
1972 //while ($row = PMA_DBI_fetch_assoc($res)) {
1973 foreach ($db_rights as $row) {
1974 $found_rows[] = (! isset($dbname)) ? $row['Db'] : $row['Table_name'];
1976 echo '<tr class="' . ($odd_row ? 'odd' : 'even') . '">' . "\n"
1977 . ' <td>' . htmlspecialchars((! isset($dbname)) ? $row['Db'] : $row['Table_name']) . '</td>' . "\n"
1978 . ' <td><tt>' . "\n"
1979 . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($row, TRUE)) . "\n"
1980 . ' </tt></td>' . "\n"
1981 . ' <td>' . ((((! isset($dbname)) && $row['Grant_priv'] == 'Y') || (isset($dbname) && in_array('Grant', explode(',', $row['Table_priv'])))) ? __('Yes') : __('No')) . '</td>' . "\n"
1982 . ' <td>';
1983 if (! empty($row['Table_privs']) || ! empty ($row['Column_priv'])) {
1984 echo __('Yes');
1985 } else {
1986 echo __('No');
1988 echo '</td>' . "\n"
1989 . ' <td>';
1990 printf($link_edit, htmlspecialchars(urlencode($username)),
1991 urlencode(htmlspecialchars($hostname)),
1992 urlencode((! isset($dbname)) ? $row['Db'] : htmlspecialchars($dbname)),
1993 urlencode((! isset($dbname)) ? '' : $row['Table_name']));
1994 echo '</td>' . "\n"
1995 . ' <td>';
1996 if (! empty($row['can_delete']) || isset($row['Table_name']) && strlen($row['Table_name'])) {
1997 printf($link_revoke, htmlspecialchars(urlencode($username)),
1998 urlencode(htmlspecialchars($hostname)),
1999 urlencode((! isset($dbname)) ? $row['Db'] : htmlspecialchars($dbname)),
2000 urlencode((! isset($dbname)) ? '' : $row['Table_name']));
2002 echo '</td>' . "\n"
2003 . '</tr>' . "\n";
2004 $odd_row = ! $odd_row;
2005 } // end while
2007 unset($row);
2008 echo '</tbody>' . "\n"
2009 . '</table>' . "\n";
2011 if (! isset($dbname)) {
2013 // no database name was given, display select db
2015 $pred_db_array =PMA_DBI_fetch_result('SHOW DATABASES;');
2017 echo ' <label for="text_dbname">' . __('Add privileges on the following database') . ':</label>' . "\n";
2018 if (!empty($pred_db_array)) {
2019 echo ' <select name="pred_dbname" onchange="this.form.submit();">' . "\n"
2020 . ' <option value="" selected="selected">' . __('Use text field') . ':</option>' . "\n";
2021 foreach ($pred_db_array as $current_db) {
2022 $current_db = PMA_escape_mysql_wildcards($current_db);
2023 // cannot use array_diff() once, outside of the loop,
2024 // because the list of databases has special characters
2025 // already escaped in $found_rows,
2026 // contrary to the output of SHOW DATABASES
2027 if (empty($found_rows) || ! in_array($current_db, $found_rows)) {
2028 echo ' <option value="' . htmlspecialchars($current_db) . '">'
2029 . htmlspecialchars($current_db) . '</option>' . "\n";
2032 echo ' </select>' . "\n";
2034 echo ' <input type="text" id="text_dbname" name="dbname" />' . "\n"
2035 . PMA_showHint(__('Wildcards % and _ should be escaped with a \ to use them literally'));
2036 } else {
2037 echo ' <input type="hidden" name="dbname" value="' . htmlspecialchars($dbname) . '"/>' . "\n"
2038 . ' <label for="text_tablename">' . __('Add privileges on the following table') . ':</label>' . "\n";
2039 if ($res = @PMA_DBI_try_query('SHOW TABLES FROM ' . PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . ';', null, PMA_DBI_QUERY_STORE)) {
2040 $pred_tbl_array = array();
2041 while ($row = PMA_DBI_fetch_row($res)) {
2042 if (!isset($found_rows) || !in_array($row[0], $found_rows)) {
2043 $pred_tbl_array[] = $row[0];
2046 PMA_DBI_free_result($res);
2047 unset($res, $row);
2048 if (!empty($pred_tbl_array)) {
2049 echo ' <select name="pred_tablename" onchange="this.form.submit();">' . "\n"
2050 . ' <option value="" selected="selected">' . __('Use text field') . ':</option>' . "\n";
2051 foreach ($pred_tbl_array as $current_table) {
2052 echo ' <option value="' . htmlspecialchars($current_table) . '">' . htmlspecialchars($current_table) . '</option>' . "\n";
2054 echo ' </select>' . "\n";
2056 } else {
2057 unset($res);
2059 echo ' <input type="text" id="text_tablename" name="tablename" />' . "\n";
2061 echo '</fieldset>' . "\n";
2062 echo '<fieldset class="tblFooters">' . "\n"
2063 . ' <input type="submit" value="' . __('Go') . '" />'
2064 . '</fieldset>' . "\n"
2065 . '</form>' . "\n";
2069 // Provide a line with links to the relevant database and table
2070 if (isset($dbname) && empty($dbname_is_wildcard)) {
2071 echo '[ ' . __('Database')
2072 . ' <a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?'
2073 . $GLOBALS['url_query'] . '&amp;db=' . $url_dbname . '&amp;reload=1">'
2074 . htmlspecialchars($dbname) . ': ' . PMA_getTitleForTarget($GLOBALS['cfg']['DefaultTabDatabase']) . "</a> ]\n";
2076 if (isset($tablename)) {
2077 echo ' [ ' . __('Table') . ' <a href="'
2078 . $GLOBALS['cfg']['DefaultTabTable'] . '?' . $GLOBALS['url_query']
2079 . '&amp;db=' . $url_dbname . '&amp;table=' . htmlspecialchars(urlencode($tablename))
2080 . '&amp;reload=1">' . htmlspecialchars($tablename) . ': '
2081 . PMA_getTitleForTarget($GLOBALS['cfg']['DefaultTabTable'])
2082 . "</a> ]\n";
2084 unset($url_dbname);
2087 if (! isset($dbname) && ! $user_does_not_exists) {
2088 require_once './libraries/display_change_password.lib.php';
2090 echo '<form action="server_privileges.php" method="post" onsubmit="return checkPassword(this);">' . "\n"
2091 . PMA_generate_common_hidden_inputs('', '')
2092 . '<input type="hidden" name="old_username" value="' . htmlspecialchars($username) . '" />' . "\n"
2093 . '<input type="hidden" name="old_hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n"
2094 . '<fieldset id="fieldset_change_copy_user">' . "\n"
2095 . ' <legend>' . __('Change Login Information / Copy User') . '</legend>' . "\n";
2096 PMA_displayLoginInformationFields('change');
2097 echo ' <fieldset>' . "\n"
2098 . ' <legend>' . __('Create a new user with the same privileges and ...') . '</legend>' . "\n";
2099 $choices = array(
2100 '4' => __('... keep the old one.'),
2101 '1' => __(' ... delete the old one from the user tables.'),
2102 '2' => __(' ... revoke all active privileges from the old one and delete it afterwards.'),
2103 '3' => __(' ... delete the old one from the user tables and reload the privileges afterwards.'));
2104 PMA_display_html_radio('mode', $choices, '4', true);
2105 unset($choices);
2107 echo ' </fieldset>' . "\n"
2108 . '</fieldset>' . "\n"
2109 . '<fieldset id="fieldset_change_copy_user_footer" class="tblFooters">' . "\n"
2110 . ' <input type="submit" name="change_copy" value="' . __('Go') . '" />' . "\n"
2111 . '</fieldset>' . "\n"
2112 . '</form>' . "\n";
2115 } elseif (isset($_REQUEST['adduser'])) {
2117 // Add a new user
2118 $GLOBALS['url_query'] .= '&amp;adduser=1';
2119 echo '<h2>' . "\n"
2120 . PMA_getIcon('b_usradd.png') . __('Add a new User') . "\n"
2121 . '</h2>' . "\n"
2122 . '<form name="usersForm" id="addUsersForm" action="server_privileges.php" method="post">' . "\n"
2123 . PMA_generate_common_hidden_inputs('', '');
2124 PMA_displayLoginInformationFields('new');
2125 echo '<fieldset id="fieldset_add_user_database">' . "\n"
2126 . '<legend>' . __('Database for user') . '</legend>' . "\n";
2128 $default_choice = 0;
2129 $choices = array(
2130 '0' => _pgettext('Create none database for user', 'None'),
2131 '1' => __('Create database with same name and grant all privileges'),
2132 '2' => __('Grant all privileges on wildcard name (username\\_%)'));
2134 if ( !empty($dbname) ) {
2135 $choices['3'] = sprintf( __('Grant all privileges on database &quot;%s&quot;'), htmlspecialchars($dbname));
2136 $default_choice = 3;
2137 echo '<input type="hidden" name="dbname" value="' . htmlspecialchars($dbname) . '" />' . "\n";
2140 // 4th parameter set to true to add line breaks
2141 // 5th parameter set to false to avoid htmlspecialchars() escaping in the label
2142 // since we have some HTML in some labels
2143 PMA_display_html_radio('createdb', $choices, $default_choice, true, false);
2144 unset($choices);
2145 unset($default_choice);
2147 echo '</fieldset>' . "\n";
2148 PMA_displayPrivTable('*', '*', FALSE);
2149 echo ' <fieldset id="fieldset_add_user_footer" class="tblFooters">' . "\n"
2150 . ' <input type="submit" name="adduser_submit" value="' . __('Go') . '" />' . "\n"
2151 . ' </fieldset>' . "\n"
2152 . '</form>' . "\n";
2153 } else {
2154 // check the privileges for a particular database.
2155 echo '<table id="tablespecificuserrights" class="data">' . "\n"
2156 . '<caption class="tblHeaders">' . "\n"
2157 . PMA_getIcon('b_usrcheck.png')
2158 . ' ' . sprintf(__('Users having access to &quot;%s&quot;'), '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?' . PMA_generate_common_url($checkprivs) . '">' . htmlspecialchars($checkprivs) . '</a>') . "\n"
2159 . '</caption>' . "\n"
2160 . '<thead>' . "\n"
2161 . ' <tr><th>' . __('User') . '</th>' . "\n"
2162 . ' <th>' . __('Host') . '</th>' . "\n"
2163 . ' <th>' . __('Type') . '</th>' . "\n"
2164 . ' <th>' . __('Privileges') . '</th>' . "\n"
2165 . ' <th>' . __('Grant') . '</th>' . "\n"
2166 . ' <th>' . __('Action') . '</th>' . "\n"
2167 . ' </tr>' . "\n"
2168 . '</thead>' . "\n"
2169 . '<tbody>' . "\n";
2170 $odd_row = TRUE;
2171 unset($row, $row1, $row2);
2173 // now, we build the table...
2174 $list_of_privileges =
2175 '`User`, '
2176 . '`Host`, '
2177 . '`Select_priv`, '
2178 . '`Insert_priv`, '
2179 . '`Update_priv`, '
2180 . '`Delete_priv`, '
2181 . '`Create_priv`, '
2182 . '`Drop_priv`, '
2183 . '`Grant_priv`, '
2184 . '`Index_priv`, '
2185 . '`Alter_priv`, '
2186 . '`References_priv`, '
2187 . '`Create_tmp_table_priv`, '
2188 . '`Lock_tables_priv`, '
2189 . '`Create_view_priv`, '
2190 . '`Show_view_priv`, '
2191 . '`Create_routine_priv`, '
2192 . '`Alter_routine_priv`, '
2193 . '`Execute_priv`';
2195 $list_of_compared_privileges =
2196 '`Select_priv` = \'N\''
2197 . ' AND `Insert_priv` = \'N\''
2198 . ' AND `Update_priv` = \'N\''
2199 . ' AND `Delete_priv` = \'N\''
2200 . ' AND `Create_priv` = \'N\''
2201 . ' AND `Drop_priv` = \'N\''
2202 . ' AND `Grant_priv` = \'N\''
2203 . ' AND `References_priv` = \'N\''
2204 . ' AND `Create_tmp_table_priv` = \'N\''
2205 . ' AND `Lock_tables_priv` = \'N\''
2206 . ' AND `Create_view_priv` = \'N\''
2207 . ' AND `Show_view_priv` = \'N\''
2208 . ' AND `Create_routine_priv` = \'N\''
2209 . ' AND `Alter_routine_priv` = \'N\''
2210 . ' AND `Execute_priv` = \'N\'';
2212 if (PMA_MYSQL_INT_VERSION >= 50106) {
2213 $list_of_privileges .=
2214 ', `Event_priv`, '
2215 . '`Trigger_priv`';
2216 $list_of_compared_privileges .=
2217 ' AND `Event_priv` = \'N\''
2218 . ' AND `Trigger_priv` = \'N\'';
2221 $sql_query =
2222 '(SELECT ' . $list_of_privileges . ', `Db`'
2223 .' FROM `mysql`.`db`'
2224 .' WHERE \'' . PMA_sqlAddslashes($checkprivs) . "'"
2225 .' LIKE `Db`'
2226 .' AND NOT (' . $list_of_compared_privileges. ')) '
2227 .'UNION '
2228 .'(SELECT ' . $list_of_privileges . ', \'*\' AS `Db`'
2229 .' FROM `mysql`.`user` '
2230 .' WHERE NOT (' . $list_of_compared_privileges . ')) '
2231 .' ORDER BY `User` ASC,'
2232 .' `Host` ASC,'
2233 .' `Db` ASC;';
2234 $res = PMA_DBI_query($sql_query);
2235 $row = PMA_DBI_fetch_assoc($res);
2236 if ($row) {
2237 $found = TRUE;
2240 if ($found) {
2241 while (TRUE) {
2242 // prepare the current user
2243 $current_privileges = array();
2244 $current_user = $row['User'];
2245 $current_host = $row['Host'];
2246 while ($row && $current_user == $row['User'] && $current_host == $row['Host']) {
2247 $current_privileges[] = $row;
2248 $row = PMA_DBI_fetch_assoc($res);
2250 echo ' <tr class="' . ($odd_row ? 'odd' : 'even') . '">' . "\n"
2251 . ' <td';
2252 if (count($current_privileges) > 1) {
2253 echo ' rowspan="' . count($current_privileges) . '"';
2255 echo '>' . (empty($current_user) ? '<span style="color: #FF0000">' . __('Any') . '</span>' : htmlspecialchars($current_user)) . "\n"
2256 . ' </td>' . "\n"
2257 . ' <td';
2258 if (count($current_privileges) > 1) {
2259 echo ' rowspan="' . count($current_privileges) . '"';
2261 echo '>' . htmlspecialchars($current_host) . '</td>' . "\n";
2262 foreach ($current_privileges as $current) {
2263 echo ' <td>' . "\n"
2264 . ' ';
2265 if (!isset($current['Db']) || $current['Db'] == '*') {
2266 echo __('global');
2267 } elseif ($current['Db'] == PMA_escape_mysql_wildcards($checkprivs)) {
2268 echo __('database-specific');
2269 } else {
2270 echo __('wildcard'), ': <tt>' . htmlspecialchars($current['Db']) . '</tt>';
2272 echo "\n"
2273 . ' </td>' . "\n"
2274 . ' <td>' . "\n"
2275 . ' <tt>' . "\n"
2276 . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($current, TRUE)) . "\n"
2277 . ' </tt>' . "\n"
2278 . ' </td>' . "\n"
2279 . ' <td>' . "\n"
2280 . ' ' . ($current['Grant_priv'] == 'Y' ? __('Yes') : __('No')) . "\n"
2281 . ' </td>' . "\n"
2282 . ' <td>' . "\n";
2283 printf($link_edit, urlencode($current_user),
2284 urlencode($current_host),
2285 urlencode(! isset($current['Db']) || $current['Db'] == '*' ? '' : $current['Db']),
2286 '');
2287 echo '</td>' . "\n"
2288 . ' </tr>' . "\n";
2290 if (empty($row) && empty($row1) && empty($row2)) {
2291 break;
2293 $odd_row = ! $odd_row;
2295 } else {
2296 echo ' <tr class="odd">' . "\n"
2297 . ' <td colspan="6">' . "\n"
2298 . ' ' . __('No user found.') . "\n"
2299 . ' </td>' . "\n"
2300 . ' </tr>' . "\n";
2302 echo '</tbody>' . "\n"
2303 . '</table>' . "\n";
2305 // Offer to create a new user for the current database
2306 echo '<fieldset id="fieldset_add_user">' . "\n"
2307 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;adduser=1&amp;dbname=' . htmlspecialchars($checkprivs) .'">' . "\n"
2308 . PMA_getIcon('b_usradd.png')
2309 . ' ' . __('Add a new User') . '</a>' . "\n"
2310 . '</fieldset>' . "\n";
2312 } // end if (empty($_REQUEST['adduser']) && empty($checkprivs)) ... elseif ... else ...
2316 * Displays the footer
2318 echo "\n\n";
2319 require './libraries/footer.inc.php';