Dia Schema Class: download fileName added + improved documentation
[phpmyadmin/crack.git] / server_privileges.php
blob576c0a16b2bc0fbd954f414dd5ae1fe07bbfe462
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
5 * @version $Id$
6 * @package phpMyAdmin
7 */
9 /**
12 require_once './libraries/common.inc.php';
14 /**
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';
21 /**
22 * Messages are built using the message name
24 $strPrivDescAllPrivileges = __('Includes all privileges except GRANT.');
25 $strPrivDescAlter = __('Allows altering the structure of existing tables.');
26 $strPrivDescAlterRoutine = __('Allows altering and dropping stored routines.');
27 $strPrivDescCreateDb = __('Allows creating new databases and tables.');
28 $strPrivDescCreateRoutine = __('Allows creating stored routines.');
29 $strPrivDescCreateTbl = __('Allows creating new tables.');
30 $strPrivDescCreateTmpTable = __('Allows creating temporary tables.');
31 $strPrivDescCreateUser = __('Allows creating, dropping and renaming user accounts.');
32 $strPrivDescCreateView = __('Allows creating new views.');
33 $strPrivDescDelete = __('Allows deleting data.');
34 $strPrivDescDropDb = __('Allows dropping databases and tables.');
35 $strPrivDescDropTbl = __('Allows dropping tables.');
36 $strPrivDescEvent = __('Allows to set up events for the event scheduler');
37 $strPrivDescExecute = __('Allows executing stored routines.');
38 $strPrivDescFile = __('Allows importing data from and exporting data into files.');
39 $strPrivDescGrant = __('Allows adding users and privileges without reloading the privilege tables.');
40 $strPrivDescIndex = __('Allows creating and dropping indexes.');
41 $strPrivDescInsert = __('Allows inserting and replacing data.');
42 $strPrivDescLockTables = __('Allows locking tables for the current thread.');
43 $strPrivDescMaxConnections = __('Limits the number of new connections the user may open per hour.');
44 $strPrivDescMaxQuestions = __('Limits the number of queries the user may send to the server per hour.');
45 $strPrivDescMaxUpdates = __('Limits the number of commands that change any table or database the user may execute per hour.');
46 $strPrivDescMaxUserConnections = __('Limits the number of simultaneous connections the user may have.');
47 $strPrivDescProcess = __('Allows viewing processes of all users');
48 $strPrivDescReferences = __('Has no effect in this MySQL version.');
49 $strPrivDescReload = __('Allows reloading server settings and flushing the server\'s caches.');
50 $strPrivDescReplClient = __('Allows the user to ask where the slaves / masters are.');
51 $strPrivDescReplSlave = __('Needed for the replication slaves.');
52 $strPrivDescSelect = __('Allows reading data.');
53 $strPrivDescShowDb = __('Gives access to the complete list of databases.');
54 $strPrivDescShowView = __('Allows performing SHOW CREATE VIEW queries.');
55 $strPrivDescShutdown = __('Allows shutting down the server.');
56 $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.');
57 $strPrivDescTrigger = __('Allows creating and dropping triggers');
58 $strPrivDescUpdate = __('Allows changing data.');
59 $strPrivDescUsage = __('No privileges.');
61 /**
62 * Checks if a dropdown box has been used for selecting a database / table
64 if (PMA_isValid($_REQUEST['pred_tablename'])) {
65 $tablename = $_REQUEST['pred_tablename'];
66 unset($pred_tablename);
67 } elseif (PMA_isValid($_REQUEST['tablename'])) {
68 $tablename = $_REQUEST['tablename'];
69 } else {
70 unset($tablename);
73 if (PMA_isValid($_REQUEST['pred_dbname'])) {
74 $dbname = $_REQUEST['pred_dbname'];
75 unset($pred_dbname);
76 } elseif (PMA_isValid($_REQUEST['dbname'])) {
77 $dbname = $_REQUEST['dbname'];
78 } else {
79 unset($dbname);
80 unset($tablename);
83 if (isset($dbname)) {
84 $db_and_table = PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . '.';
85 if (isset($tablename)) {
86 $db_and_table .= PMA_backquote($tablename);
87 } else {
88 $db_and_table .= '*';
90 } else {
91 $db_and_table = '*.*';
94 // check if given $dbname is a wildcard or not
95 if (isset($dbname)) {
96 //if (preg_match('/\\\\(?:_|%)/i', $dbname)) {
97 if (preg_match('/(?<!\\\\)(?:_|%)/i', $dbname)) {
98 $dbname_is_wildcard = true;
99 } else {
100 $dbname_is_wildcard = false;
105 * Checks if the user is allowed to do what he tries to...
107 if (!$is_superuser) {
108 require './libraries/server_links.inc.php';
109 echo '<h2>' . "\n"
110 . PMA_getIcon('b_usrlist.png')
111 . __('Privileges') . "\n"
112 . '</h2>' . "\n";
113 PMA_Message::error(__('No Privileges'))->display();
114 require_once './libraries/footer.inc.php';
118 * Escapes wildcard in a database+table specification
119 * before using it in a GRANT statement.
121 * Escaping a wildcard character in a GRANT is only accepted at the global
122 * or database level, not at table level; this is why I remove
123 * the escaping character. Internally, in mysql.tables_priv.Db there are
124 * no escaping (for example test_db) but in mysql.db you'll see test\_db
125 * for a db-specific privilege.
127 * @param string $db_and_table
128 * @param string $dbname
129 * @param string $tablename
130 * @return string the escaped (if necessary) $db_and_table
132 function PMA_WildcardEscapeForGrant($db_and_table, $dbname, $tablename) {
134 if (! strlen($dbname)) {
135 $db_and_table = '*.*';
136 } else {
137 if (strlen($tablename)) {
138 $db_and_table = PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . '.';
139 $db_and_table .= PMA_backquote($tablename);
140 } else {
141 $db_and_table = PMA_backquote($dbname) . '.';
142 $db_and_table .= '*';
145 return $db_and_table;
149 * Generates a condition on the user name
151 * @param string the user's initial
152 * @return string the generated condition
154 function PMA_RangeOfUsers($initial = '')
156 // strtolower() is used because the User field
157 // might be BINARY, so LIKE would be case sensitive
158 if (!empty($initial)) {
159 $ret = " WHERE `User` LIKE '" . $initial . "%'"
160 . " OR `User` LIKE '" . strtolower($initial) . "%'";
161 } else {
162 $ret = '';
164 return $ret;
165 } // end function
168 * Extracts the privilege information of a priv table row
170 * @param array $row the row
171 * @param boolean $enableHTML add <dfn> tag with tooltips
173 * @global ressource $user_link the database connection
175 * @return array
177 function PMA_extractPrivInfo($row = '', $enableHTML = FALSE)
179 $grants = array(
180 array('Select_priv', 'SELECT', __('Allows reading data.')),
181 array('Insert_priv', 'INSERT', __('Allows inserting and replacing data.')),
182 array('Update_priv', 'UPDATE', __('Allows changing data.')),
183 array('Delete_priv', 'DELETE', __('Allows deleting data.')),
184 array('Create_priv', 'CREATE', __('Allows creating new databases and tables.')),
185 array('Drop_priv', 'DROP', __('Allows dropping databases and tables.')),
186 array('Reload_priv', 'RELOAD', __('Allows reloading server settings and flushing the server\'s caches.')),
187 array('Shutdown_priv', 'SHUTDOWN', __('Allows shutting down the server.')),
188 array('Process_priv', 'PROCESS', __('Allows viewing processes of all users')),
189 array('File_priv', 'FILE', __('Allows importing data from and exporting data into files.')),
190 array('References_priv', 'REFERENCES', __('Has no effect in this MySQL version.')),
191 array('Index_priv', 'INDEX', __('Allows creating and dropping indexes.')),
192 array('Alter_priv', 'ALTER', __('Allows altering the structure of existing tables.')),
193 array('Show_db_priv', 'SHOW DATABASES', __('Gives access to the complete list of databases.')),
194 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.')),
195 array('Create_tmp_table_priv', 'CREATE TEMPORARY TABLES', __('Allows creating temporary tables.')),
196 array('Lock_tables_priv', 'LOCK TABLES', __('Allows locking tables for the current thread.')),
197 array('Repl_slave_priv', 'REPLICATION SLAVE', __('Needed for the replication slaves.')),
198 array('Repl_client_priv', 'REPLICATION CLIENT', __('Allows the user to ask where the slaves / masters are.')),
199 array('Create_view_priv', 'CREATE VIEW', __('Allows creating new views.')),
200 array('Event_priv', 'EVENT', __('Allows to set up events for the event scheduler')),
201 array('Trigger_priv', 'TRIGGER', __('Allows creating and dropping triggers')),
202 // for table privs:
203 array('Create View_priv', 'CREATE VIEW', __('Allows creating new views.')),
204 array('Show_view_priv', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')),
205 // for table privs:
206 array('Show view_priv', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')),
207 array('Create_routine_priv', 'CREATE ROUTINE', __('Allows creating stored routines.')),
208 array('Alter_routine_priv', 'ALTER ROUTINE', __('Allows altering and dropping stored routines.')),
209 array('Create_user_priv', 'CREATE USER', __('Allows creating, dropping and renaming user accounts.')),
210 array('Execute_priv', 'EXECUTE', __('Allows executing stored routines.')),
213 if (!empty($row) && isset($row['Table_priv'])) {
214 $row1 = PMA_DBI_fetch_single_row(
215 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
216 'ASSOC', $GLOBALS['userlink']);
217 $av_grants = explode('\',\'', substr($row1['Type'], 5, strlen($row1['Type']) - 7));
218 unset($row1);
219 $users_grants = explode(',', $row['Table_priv']);
220 foreach ($av_grants as $current_grant) {
221 $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ? 'Y' : 'N';
223 unset($current_grant);
224 unset($av_grants);
225 unset($users_grants);
227 $privs = array();
228 $allPrivileges = TRUE;
229 foreach ($grants as $current_grant) {
230 if ((!empty($row) && isset($row[$current_grant[0]]))
231 || (empty($row) && isset($GLOBALS[$current_grant[0]]))) {
232 if ((!empty($row) && $row[$current_grant[0]] == 'Y')
233 || (empty($row)
234 && ($GLOBALS[$current_grant[0]] == 'Y'
235 || (is_array($GLOBALS[$current_grant[0]])
236 && count($GLOBALS[$current_grant[0]]) == $GLOBALS['column_count']
237 && empty($GLOBALS[$current_grant[0] . '_none'])))))
239 if ($enableHTML) {
240 $privs[] = '<dfn title="' . $current_grant[2] . '">' . $current_grant[1] . '</dfn>';
241 } else {
242 $privs[] = $current_grant[1];
244 } elseif (!empty($GLOBALS[$current_grant[0]])
245 && is_array($GLOBALS[$current_grant[0]])
246 && empty($GLOBALS[$current_grant[0] . '_none'])) {
247 if ($enableHTML) {
248 $priv_string = '<dfn title="' . $current_grant[2] . '">' . $current_grant[1] . '</dfn>';
249 } else {
250 $priv_string = $current_grant[1];
252 $privs[] = $priv_string . ' (`' . join('`, `', $GLOBALS[$current_grant[0]]) . '`)';
253 } else {
254 $allPrivileges = FALSE;
258 if (empty($privs)) {
259 if ($enableHTML) {
260 $privs[] = '<dfn title="' . __('No privileges.') . '">USAGE</dfn>';
261 } else {
262 $privs[] = 'USAGE';
264 } elseif ($allPrivileges && (!isset($GLOBALS['grant_count']) || count($privs) == $GLOBALS['grant_count'])) {
265 if ($enableHTML) {
266 $privs = array('<dfn title="' . __('Includes all privileges except GRANT.') . '">ALL PRIVILEGES</dfn>');
267 } else {
268 $privs = array('ALL PRIVILEGES');
271 return $privs;
272 } // end of the 'PMA_extractPrivInfo()' function
275 * Displays on which column(s) a table-specific privilege is granted
277 function PMA_display_column_privs($columns, $row, $name_for_select,
278 $priv_for_header, $name, $name_for_dfn, $name_for_current)
280 echo ' <div class="item" id="div_item_' . $name . '">' . "\n"
281 . ' <label for="select_' . $name . '_priv">' . "\n"
282 . ' <tt><dfn title="' . $name_for_dfn . '">'
283 . $priv_for_header . '</dfn></tt>' . "\n"
284 . ' </label><br />' . "\n"
285 . ' <select id="select_' . $name . '_priv" name="'
286 . $name_for_select . '[]" multiple="multiple" size="8">' . "\n";
288 foreach ($columns as $current_column => $current_column_privileges) {
289 echo ' <option value="' . htmlspecialchars($current_column) . '"';
290 if ($row[$name_for_select] == 'Y' || $current_column_privileges[$name_for_current]) {
291 echo ' selected="selected"';
293 echo '>' . htmlspecialchars($current_column) . '</option>' . "\n";
296 echo ' </select>' . "\n"
297 . ' <i>' . __('Or') . '</i>' . "\n"
298 . ' <label for="checkbox_' . $name_for_select
299 . '_none"><input type="checkbox"'
300 . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"')
301 . ' name="' . $name_for_select . '_none" id="checkbox_'
302 . $name_for_select . '_none" title="' . _pgettext('None privileges', 'None') . '" />'
303 . _pgettext('None privileges', 'None') . '</label>' . "\n"
304 . ' </div>' . "\n";
305 } // end function
309 * Displays the privileges form table
311 * @param string $db the database
312 * @param string $table the table
313 * @param boolean $submit wheather to display the submit button or not
314 * @global array $cfg the phpMyAdmin configuration
315 * @global ressource $user_link the database connection
317 * @return void
319 function PMA_displayPrivTable($db = '*', $table = '*', $submit = TRUE)
321 if ($db == '*') {
322 $table = '*';
325 if (isset($GLOBALS['username'])) {
326 $username = $GLOBALS['username'];
327 $hostname = $GLOBALS['hostname'];
328 if ($db == '*') {
329 $sql_query =
330 "SELECT * FROM `mysql`.`user`"
331 ." WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
332 ." AND `Host` = '" . PMA_sqlAddslashes($hostname) . "';";
333 } elseif ($table == '*') {
334 $sql_query =
335 "SELECT * FROM `mysql`.`db`"
336 ." WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
337 ." AND `Host` = '" . PMA_sqlAddslashes($hostname) . "'"
338 ." AND '" . PMA_unescape_mysql_wildcards($db) . "'"
339 ." LIKE `Db`;";
340 } else {
341 $sql_query =
342 "SELECT `Table_priv`"
343 ." FROM `mysql`.`tables_priv`"
344 ." WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
345 ." AND `Host` = '" . PMA_sqlAddslashes($hostname) . "'"
346 ." AND `Db` = '" . PMA_unescape_mysql_wildcards($db) . "'"
347 ." AND `Table_name` = '" . PMA_sqlAddslashes($table) . "';";
349 $row = PMA_DBI_fetch_single_row($sql_query);
351 if (empty($row)) {
352 if ($table == '*') {
353 if ($db == '*') {
354 $sql_query = 'SHOW COLUMNS FROM `mysql`.`user`;';
355 } elseif ($table == '*') {
356 $sql_query = 'SHOW COLUMNS FROM `mysql`.`db`;';
358 $res = PMA_DBI_query($sql_query);
359 while ($row1 = PMA_DBI_fetch_row($res)) {
360 if (substr($row1[0], 0, 4) == 'max_') {
361 $row[$row1[0]] = 0;
362 } else {
363 $row[$row1[0]] = 'N';
366 PMA_DBI_free_result($res);
367 } else {
368 $row = array('Table_priv' => '');
371 if (isset($row['Table_priv'])) {
372 $row1 = PMA_DBI_fetch_single_row(
373 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
374 'ASSOC', $GLOBALS['userlink']);
375 // note: in MySQL 5.0.3 we get "Create View', 'Show view';
376 // the View for Create is spelled with uppercase V
377 // the view for Show is spelled with lowercase v
378 // and there is a space between the words
380 $av_grants = explode('\',\'', substr($row1['Type'], strpos($row1['Type'], '(') + 2, strpos($row1['Type'], ')') - strpos($row1['Type'], '(') - 3));
381 unset($row1);
382 $users_grants = explode(',', $row['Table_priv']);
384 foreach ($av_grants as $current_grant) {
385 $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ? 'Y' : 'N';
387 unset($row['Table_priv'], $current_grant, $av_grants, $users_grants);
389 // get collumns
390 $res = PMA_DBI_try_query('SHOW COLUMNS FROM ' . PMA_backquote(PMA_unescape_mysql_wildcards($db)) . '.' . PMA_backquote($table) . ';');
391 $columns = array();
392 if ($res) {
393 while ($row1 = PMA_DBI_fetch_row($res)) {
394 $columns[$row1[0]] = array(
395 'Select' => FALSE,
396 'Insert' => FALSE,
397 'Update' => FALSE,
398 'References' => FALSE
401 PMA_DBI_free_result($res);
403 unset($res, $row1);
405 // t a b l e - s p e c i f i c p r i v i l e g e s
406 if (! empty($columns)) {
407 $res = PMA_DBI_query(
408 'SELECT `Column_name`, `Column_priv`'
409 .' FROM `mysql`.`columns_priv`'
410 .' WHERE `User`'
411 .' = \'' . PMA_sqlAddslashes($username) . "'"
412 .' AND `Host`'
413 .' = \'' . PMA_sqlAddslashes($hostname) . "'"
414 .' AND `Db`'
415 .' = \'' . PMA_sqlAddslashes(PMA_unescape_mysql_wildcards($db)) . "'"
416 .' AND `Table_name`'
417 .' = \'' . PMA_sqlAddslashes($table) . '\';');
419 while ($row1 = PMA_DBI_fetch_row($res)) {
420 $row1[1] = explode(',', $row1[1]);
421 foreach ($row1[1] as $current) {
422 $columns[$row1[0]][$current] = TRUE;
425 PMA_DBI_free_result($res);
426 unset($res, $row1, $current);
428 echo '<input type="hidden" name="grant_count" value="' . count($row) . '" />' . "\n"
429 . '<input type="hidden" name="column_count" value="' . count($columns) . '" />' . "\n"
430 . '<fieldset id="fieldset_user_priv">' . "\n"
431 . ' <legend>' . __('Table-specific privileges')
432 . PMA_showHint(__(' Note: MySQL privilege names are expressed in English '))
433 . '</legend>' . "\n";
437 // privs that are attached to a specific column
438 PMA_display_column_privs($columns, $row, 'Select_priv',
439 'SELECT', 'select', __('Allows reading data.'), 'Select');
441 PMA_display_column_privs($columns, $row, 'Insert_priv',
442 'INSERT', 'insert', __('Allows inserting and replacing data.'), 'Insert');
444 PMA_display_column_privs($columns, $row, 'Update_priv',
445 'UPDATE', 'update', __('Allows changing data.'), 'Update');
447 PMA_display_column_privs($columns, $row, 'References_priv',
448 'REFERENCES', 'references', __('Has no effect in this MySQL version.'), 'References');
450 // privs that are not attached to a specific column
452 echo ' <div class="item">' . "\n";
453 foreach ($row as $current_grant => $current_grant_value) {
454 if (in_array(substr($current_grant, 0, (strlen($current_grant) - 5)),
455 array('Select', 'Insert', 'Update', 'References'))) {
456 continue;
458 // make a substitution to match the messages variables;
459 // also we must substitute the grant we get, because we can't generate
460 // a form variable containing blanks (those would get changed to
461 // an underscore when receiving the POST)
462 if ($current_grant == 'Create View_priv') {
463 $tmp_current_grant = 'CreateView_priv';
464 $current_grant = 'Create_view_priv';
465 } elseif ($current_grant == 'Show view_priv') {
466 $tmp_current_grant = 'ShowView_priv';
467 $current_grant = 'Show_view_priv';
468 } else {
469 $tmp_current_grant = $current_grant;
472 echo ' <div class="item">' . "\n"
473 . ' <input type="checkbox"'
474 . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"')
475 . ' name="' . $current_grant . '" id="checkbox_' . $current_grant
476 . '" value="Y" '
477 . ($current_grant_value == 'Y' ? 'checked="checked" ' : '')
478 . 'title="';
480 echo (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))])
481 ? $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))]
482 : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)) . 'Tbl']) . '"/>' . "\n";
484 echo ' <label for="checkbox_' . $current_grant
485 . '"><tt><dfn title="'
486 . (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))])
487 ? $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))]
488 : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)) . 'Tbl'])
489 . '">' . strtoupper(substr($current_grant, 0, strlen($current_grant) - 5)) . '</dfn></tt></label>' . "\n"
490 . ' </div>' . "\n";
491 } // end foreach ()
493 echo ' </div>' . "\n";
494 // for Safari 2.0.2
495 echo ' <div class="clearfloat"></div>' . "\n";
497 } else {
499 // g l o b a l o r d b - s p e c i f i c
501 // d a t a
502 $privTable[0] = array(
503 array('Select', 'SELECT', __('Allows reading data.')),
504 array('Insert', 'INSERT', __('Allows inserting and replacing data.')),
505 array('Update', 'UPDATE', __('Allows changing data.')),
506 array('Delete', 'DELETE', __('Allows deleting data.'))
508 if ($db == '*') {
509 $privTable[0][] = array('File', 'FILE', __('Allows importing data from and exporting data into files.'));
512 // s t r u c t u r e
513 $privTable[1] = array(
514 array('Create', 'CREATE', ($table == '*' ? __('Allows creating new databases and tables.') : __('Allows creating new tables.'))),
515 array('Alter', 'ALTER', __('Allows altering the structure of existing tables.')),
516 array('Index', 'INDEX', __('Allows creating and dropping indexes.')),
517 array('Drop', 'DROP', ($table == '*' ? __('Allows dropping databases and tables.') : __('Allows dropping tables.'))),
518 array('Create_tmp_table', 'CREATE TEMPORARY TABLES', __('Allows creating temporary tables.')),
519 array('Show_view', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')),
520 array('Create_routine', 'CREATE ROUTINE', __('Allows creating stored routines.')),
521 array('Alter_routine', 'ALTER ROUTINE', __('Allows altering and dropping stored routines.')),
522 array('Execute', 'EXECUTE', __('Allows executing stored routines.')),
524 // this one is for a db-specific priv: Create_view_priv
525 if (isset($row['Create_view_priv'])) {
526 $privTable[1][] = array('Create_view', 'CREATE VIEW', __('Allows creating new views.'));
528 // this one is for a table-specific priv: Create View_priv
529 if (isset($row['Create View_priv'])) {
530 $privTable[1][] = array('Create View', 'CREATE VIEW', __('Allows creating new views.'));
532 if (isset($row['Event_priv'])) {
533 // MySQL 5.1.6
534 $privTable[1][] = array('Event', 'EVENT', __('Allows to set up events for the event scheduler'));
535 $privTable[1][] = array('Trigger', 'TRIGGER', __('Allows creating and dropping triggers'));
538 // a d m i n i s t r a t i o n
539 $privTable[2] = array(
540 array('Grant', 'GRANT', __('Allows adding users and privileges without reloading the privilege tables.')),
542 if ($db == '*') {
543 $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.'));
544 $privTable[2][] = array('Process', 'PROCESS', __('Allows viewing processes of all users'));
545 $privTable[2][] = array('Reload', 'RELOAD', __('Allows reloading server settings and flushing the server\'s caches.'));
546 $privTable[2][] = array('Shutdown', 'SHUTDOWN', __('Allows shutting down the server.'));
547 $privTable[2][] = array('Show_db', 'SHOW DATABASES', __('Gives access to the complete list of databases.'));
549 $privTable[2][] = array('Lock_tables', 'LOCK TABLES', __('Allows locking tables for the current thread.'));
550 $privTable[2][] = array('References', 'REFERENCES', __('Has no effect in this MySQL version.'));
551 if ($db == '*') {
552 $privTable[2][] = array('Repl_client', 'REPLICATION CLIENT', __('Allows the user to ask where the slaves / masters are.'));
553 $privTable[2][] = array('Repl_slave', 'REPLICATION SLAVE', __('Needed for the replication slaves.'));
554 $privTable[2][] = array('Create_user', 'CREATE USER', __('Allows creating, dropping and renaming user accounts.'));
556 echo '<input type="hidden" name="grant_count" value="'
557 . (count($privTable[0]) + count($privTable[1]) + count($privTable[2]) - (isset($row['Grant_priv']) ? 1 : 0))
558 . '" />' . "\n"
559 . '<fieldset id="fieldset_user_global_rights">' . "\n"
560 . ' <legend>' . "\n"
561 . ' '
562 . ($db == '*'
563 ? __('Global privileges')
564 : ($table == '*'
565 ? __('Database-specific privileges')
566 : __('Table-specific privileges'))) . "\n"
567 . ' (<a href="server_privileges.php?'
568 . $GLOBALS['url_query'] . '&amp;checkall=1" onclick="setCheckboxes(\'usersForm\', true); return false;">'
569 . __('Check All') . '</a> /' . "\n"
570 . ' <a href="server_privileges.php?'
571 . $GLOBALS['url_query'] . '" onclick="setCheckboxes(\'usersForm\', false); return false;">'
572 . __('Uncheck All') . '</a>)' . "\n"
573 . ' </legend>' . "\n"
574 . ' <p><small><i>' . __(' Note: MySQL privilege names are expressed in English ') . '</i></small></p>' . "\n"
575 . ' <fieldset>' . "\n"
576 . ' <legend>' . __('Data') . '</legend>' . "\n";
577 foreach ($privTable[0] as $priv)
579 echo ' <div class="item">' . "\n"
580 . ' <input type="checkbox"'
581 . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"')
582 . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0]
583 . '_priv" value="Y" '
584 . ($row[$priv[0] . '_priv'] == 'Y' ? 'checked="checked" ' : '')
585 . 'title="' . $priv[2] . '"/>' . "\n"
586 . ' <label for="checkbox_' . $priv[0]
587 . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1]
588 . '</dfn></tt></label>' . "\n"
589 . ' </div>' . "\n";
591 echo ' </fieldset>' . "\n"
592 . ' <fieldset>' . "\n"
593 . ' <legend>' . __('Structure') . '</legend>' . "\n";
594 foreach ($privTable[1] as $priv)
596 echo ' <div class="item">' . "\n"
597 . ' <input type="checkbox"'
598 . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"')
599 . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0]
600 . '_priv" value="Y" '
601 . ($row[$priv[0] . '_priv'] == 'Y' ? 'checked="checked" ' : '')
602 . 'title="' . $priv[2] . '"/>' . "\n"
603 . ' <label for="checkbox_' . $priv[0]
604 . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1]
605 . '</dfn></tt></label>' . "\n"
606 . ' </div>' . "\n";
608 echo ' </fieldset>' . "\n"
609 . ' <fieldset>' . "\n"
610 . ' <legend>' . __('Administration') . '</legend>' . "\n";
611 foreach ($privTable[2] as $priv)
613 echo ' <div class="item">' . "\n"
614 . ' <input type="checkbox"'
615 . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"')
616 . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0]
617 . '_priv" value="Y" '
618 . ($row[$priv[0] . '_priv'] == 'Y' ? 'checked="checked" ' : '')
619 . 'title="' . $priv[2] . '"/>' . "\n"
620 . ' <label for="checkbox_' . $priv[0]
621 . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1]
622 . '</dfn></tt></label>' . "\n"
623 . ' </div>' . "\n";
626 echo ' </fieldset>' . "\n";
627 // The "Resource limits" box is not displayed for db-specific privs
628 if ($db == '*') {
629 echo ' <fieldset>' . "\n"
630 . ' <legend>' . __('Resource limits') . '</legend>' . "\n"
631 . ' <p><small><i>' . __('Note: Setting these options to 0 (zero) removes the limit.') . '</i></small></p>' . "\n"
632 . ' <div class="item">' . "\n"
633 . ' <label for="text_max_questions"><tt><dfn title="'
634 . __('Limits the number of queries the user may send to the server per hour.') . '">MAX QUERIES PER HOUR</dfn></tt></label>' . "\n"
635 . ' <input type="text" name="max_questions" id="text_max_questions" value="'
636 . $row['max_questions'] . '" size="11" maxlength="11" title="' . __('Limits the number of queries the user may send to the server per hour.') . '" />' . "\n"
637 . ' </div>' . "\n"
638 . ' <div class="item">' . "\n"
639 . ' <label for="text_max_updates"><tt><dfn title="'
640 . __('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"
641 . ' <input type="text" name="max_updates" id="text_max_updates" value="'
642 . $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"
643 . ' </div>' . "\n"
644 . ' <div class="item">' . "\n"
645 . ' <label for="text_max_connections"><tt><dfn title="'
646 . __('Limits the number of new connections the user may open per hour.') . '">MAX CONNECTIONS PER HOUR</dfn></tt></label>' . "\n"
647 . ' <input type="text" name="max_connections" id="text_max_connections" value="'
648 . $row['max_connections'] . '" size="11" maxlength="11" title="' . __('Limits the number of new connections the user may open per hour.') . '" />' . "\n"
649 . ' </div>' . "\n"
650 . ' <div class="item">' . "\n"
651 . ' <label for="text_max_user_connections"><tt><dfn title="'
652 . __('Limits the number of simultaneous connections the user may have.') . '">MAX USER_CONNECTIONS</dfn></tt></label>' . "\n"
653 . ' <input type="text" name="max_user_connections" id="text_max_user_connections" value="'
654 . $row['max_user_connections'] . '" size="11" maxlength="11" title="' . __('Limits the number of simultaneous connections the user may have.') . '" />' . "\n"
655 . ' </div>' . "\n"
656 . ' </fieldset>' . "\n";
658 // for Safari 2.0.2
659 echo ' <div class="clearfloat"></div>' . "\n";
661 echo '</fieldset>' . "\n";
662 if ($submit) {
663 echo '<fieldset id="fieldset_user_privtable_footer" class="tblFooters">' . "\n"
664 . ' <input type="submit" name="update_privs" value="' . __('Go') . '" />' . "\n"
665 . '</fieldset>' . "\n";
667 } // end of the 'PMA_displayPrivTable()' function
671 * Displays the fields used by the "new user" form as well as the
672 * "change login information / copy user" form.
674 * @param string $mode are we creating a new user or are we just
675 * changing one? (allowed values: 'new', 'change')
676 * @global array $cfg the phpMyAdmin configuration
677 * @global ressource $user_link the database connection
679 * @return void
681 function PMA_displayLoginInformationFields($mode = 'new')
683 // Get user/host name lengths
684 $fields_info = PMA_DBI_get_fields('mysql', 'user');
685 $username_length = 16;
686 $hostname_length = 41;
687 foreach ($fields_info as $key => $val) {
688 if ($val['Field'] == 'User') {
689 strtok($val['Type'], '()');
690 $v = strtok('()');
691 if (is_int($v)) {
692 $username_length = $v;
694 } elseif ($val['Field'] == 'Host') {
695 strtok($val['Type'], '()');
696 $v = strtok('()');
697 if (is_int($v)) {
698 $hostname_length = $v;
702 unset($fields_info);
704 if (isset($GLOBALS['username']) && strlen($GLOBALS['username']) === 0) {
705 $GLOBALS['pred_username'] = 'any';
707 echo '<fieldset id="fieldset_add_user_login">' . "\n"
708 . '<legend>' . __('Login Information') . '</legend>' . "\n"
709 . '<div class="item">' . "\n"
710 . '<label for="select_pred_username">' . "\n"
711 . ' ' . __('User name') . ':' . "\n"
712 . '</label>' . "\n"
713 . '<span class="options">' . "\n"
714 . ' <select name="pred_username" id="select_pred_username" title="' . __('User name') . '"' . "\n"
715 . ' onchange="if (this.value == \'any\') { username.value = \'\'; } else if (this.value == \'userdefined\') { username.focus(); username.select(); }">' . "\n"
716 . ' <option value="any"' . ((isset($GLOBALS['pred_username']) && $GLOBALS['pred_username'] == 'any') ? ' selected="selected"' : '') . '>' . __('Any user') . '</option>' . "\n"
717 . ' <option value="userdefined"' . ((!isset($GLOBALS['pred_username']) || $GLOBALS['pred_username'] == 'userdefined') ? ' selected="selected"' : '') . '>' . __('Use text field') . ':</option>' . "\n"
718 . ' </select>' . "\n"
719 . '</span>' . "\n"
720 . '<input type="text" name="username" maxlength="'
721 . $username_length . '" title="' . __('User name') . '"'
722 . (empty($GLOBALS['username'])
723 ? ''
724 : ' value="' . htmlspecialchars(isset($GLOBALS['new_username'])
725 ? $GLOBALS['new_username']
726 : $GLOBALS['username']) . '"')
727 . ' onchange="pred_username.value = \'userdefined\';" />' . "\n"
728 . '</div>' . "\n"
729 . '<div class="item">' . "\n"
730 . '<label for="select_pred_hostname">' . "\n"
731 . ' ' . __('Host') . ':' . "\n"
732 . '</label>' . "\n"
733 . '<span class="options">' . "\n"
734 . ' <select name="pred_hostname" id="select_pred_hostname" title="' . __('Host') . '"' . "\n";
735 $_current_user = PMA_DBI_fetch_value('SELECT USER();');
736 if (! empty($_current_user)) {
737 $thishost = str_replace("'", '', substr($_current_user, (strrpos($_current_user, '@') + 1)));
738 if ($thishost == 'localhost' || $thishost == '127.0.0.1') {
739 unset($thishost);
742 echo ' onchange="if (this.value == \'any\') { hostname.value = \'%\'; } else if (this.value == \'localhost\') { hostname.value = \'localhost\'; } '
743 . (empty($thishost) ? '' : 'else if (this.value == \'thishost\') { hostname.value = \'' . addslashes(htmlspecialchars($thishost)) . '\'; } ')
744 . 'else if (this.value == \'hosttable\') { hostname.value = \'\'; } else if (this.value == \'userdefined\') { hostname.focus(); hostname.select(); }">' . "\n";
745 unset($_current_user);
747 // when we start editing a user, $GLOBALS['pred_hostname'] is not defined
748 if (!isset($GLOBALS['pred_hostname']) && isset($GLOBALS['hostname'])) {
749 switch (strtolower($GLOBALS['hostname'])) {
750 case 'localhost':
751 case '127.0.0.1':
752 $GLOBALS['pred_hostname'] = 'localhost';
753 break;
754 case '%':
755 $GLOBALS['pred_hostname'] = 'any';
756 break;
757 default:
758 $GLOBALS['pred_hostname'] = 'userdefined';
759 break;
762 echo ' <option value="any"'
763 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'any')
764 ? ' selected="selected"' : '') . '>' . __('Any host')
765 . '</option>' . "\n"
766 . ' <option value="localhost"'
767 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'localhost')
768 ? ' selected="selected"' : '') . '>' . __('Local')
769 . '</option>' . "\n";
770 if (!empty($thishost)) {
771 echo ' <option value="thishost"'
772 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'thishost')
773 ? ' selected="selected"' : '') . '>' . __('This Host')
774 . '</option>' . "\n";
776 unset($thishost);
777 echo ' <option value="hosttable"'
778 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'hosttable')
779 ? ' selected="selected"' : '') . '>' . __('Use Host Table')
780 . '</option>' . "\n"
781 . ' <option value="userdefined"'
782 . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'userdefined')
783 ? ' selected="selected"' : '')
784 . '>' . __('Use text field') . ':</option>' . "\n"
785 . ' </select>' . "\n"
786 . '</span>' . "\n"
787 . '<input type="text" name="hostname" maxlength="'
788 . $hostname_length . '" value="'
789 . htmlspecialchars(isset($GLOBALS['hostname']) ? $GLOBALS['hostname'] : '')
790 . '" title="' . __('Host')
791 . '" onchange="pred_hostname.value = \'userdefined\';" />' . "\n"
792 . PMA_showHint(__('When Host table is used, this field is ignored and values stored in Host table are used instead.'))
793 . '</div>' . "\n"
794 . '<div class="item">' . "\n"
795 . '<label for="select_pred_password">' . "\n"
796 . ' ' . __('Password') . ':' . "\n"
797 . '</label>' . "\n"
798 . '<span class="options">' . "\n"
799 . ' <select name="pred_password" id="select_pred_password" title="'
800 . __('Password') . '"' . "\n"
801 . ' onchange="if (this.value == \'none\') { pma_pw.value = \'\'; pma_pw2.value = \'\'; } else if (this.value == \'userdefined\') { pma_pw.focus(); pma_pw.select(); }">' . "\n"
802 . ($mode == 'change' ? ' <option value="keep" selected="selected">' . __('Do not change the password') . '</option>' . "\n" : '')
803 . ' <option value="none"';
804 if (isset($GLOBALS['username']) && $mode != 'change') {
805 echo ' selected="selected"';
807 echo '>' . __('No Password') . '</option>' . "\n"
808 . ' <option value="userdefined"' . (isset($GLOBALS['username']) ? '' : ' selected="selected"') . '>' . __('Use text field') . ':</option>' . "\n"
809 . ' </select>' . "\n"
810 . '</span>' . "\n"
811 . '<input type="password" id="text_pma_pw" name="pma_pw" title="' . __('Password') . '" onchange="pred_password.value = \'userdefined\';" />' . "\n"
812 . '</div>' . "\n"
813 . '<div class="item">' . "\n"
814 . '<label for="text_pma_pw2">' . "\n"
815 . ' ' . __('Re-type') . ':' . "\n"
816 . '</label>' . "\n"
817 . '<span class="options">&nbsp;</span>' . "\n"
818 . '<input type="password" name="pma_pw2" id="text_pma_pw2" title="' . __('Re-type') . '" onchange="pred_password.value = \'userdefined\';" />' . "\n"
819 . '</div>' . "\n"
820 . '<div class="item">' . "\n"
821 . '<label for="button_generate_password">' . "\n"
822 . ' ' . __('Generate Password') . ':' . "\n"
823 . '</label>' . "\n"
824 . '<span class="options">' . "\n"
825 . ' <input type="button" id="button_generate_password" value="' . __('Generate') . '" onclick="suggestPassword(this.form)" />' . "\n"
826 . '</span>' . "\n"
827 . '<input type="text" name="generated_pw" id="generated_pw" />' . "\n"
828 . '</div>' . "\n"
829 . '</fieldset>' . "\n";
830 } // end of the 'PMA_displayUserAndHostFields()' function
833 * Changes / copies a user, part I
835 if (isset($_REQUEST['change_copy'])) {
836 $user_host_condition =
837 ' WHERE `User`'
838 .' = \'' . PMA_sqlAddslashes($old_username) . "'"
839 .' AND `Host`'
840 .' = \'' . PMA_sqlAddslashes($old_hostname) . '\';';
841 $row = PMA_DBI_fetch_single_row('SELECT * FROM `mysql`.`user` ' . $user_host_condition);
842 if (! $row) {
843 PMA_Message::notice(__('No user found.'))->display();
844 unset($_REQUEST['change_copy']);
845 } else {
846 extract($row, EXTR_OVERWRITE);
847 // Recent MySQL versions have the field "Password" in mysql.user,
848 // so the previous extract creates $Password but this script
849 // uses $password
850 if (!isset($password) && isset($Password)) {
851 $password = $Password;
853 $queries = array();
859 * Adds a user
860 * (Changes / copies a user, part II)
862 if (isset($_REQUEST['adduser_submit']) || isset($_REQUEST['change_copy'])) {
863 $sql_query = '';
864 if ($pred_username == 'any') {
865 $username = '';
867 switch ($pred_hostname) {
868 case 'any':
869 $hostname = '%';
870 break;
871 case 'localhost':
872 $hostname = 'localhost';
873 break;
874 case 'hosttable':
875 $hostname = '';
876 break;
877 case 'thishost':
878 $_user_name = PMA_DBI_fetch_value('SELECT USER()');
879 $hostname = substr($_user_name, (strrpos($_user_name, '@') + 1));
880 unset($_user_name);
881 break;
883 $sql = "SELECT '1' FROM `mysql`.`user`"
884 . " WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
885 . " AND `Host` = '" . PMA_sqlAddslashes($hostname) . "';";
886 if (PMA_DBI_fetch_value($sql) == 1) {
887 $message = PMA_Message::error(__('The user %s already exists!'));
888 $message->addParam('[i]\'' . $username . '\'@\'' . $hostname . '\'[/i]');
889 $_REQUEST['adduser'] = true;
890 } else {
892 $create_user_real = 'CREATE USER \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\'';
894 $real_sql_query =
895 'GRANT ' . join(', ', PMA_extractPrivInfo()) . ' ON *.* TO \''
896 . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\'';
897 if ($pred_password != 'none' && $pred_password != 'keep') {
898 $sql_query = $real_sql_query . ' IDENTIFIED BY \'***\'';
899 $real_sql_query .= ' IDENTIFIED BY \'' . PMA_sqlAddslashes($pma_pw) . '\'';
900 if (isset($create_user_real)) {
901 $create_user_show = $create_user_real . ' IDENTIFIED BY \'***\'';
902 $create_user_real .= ' IDENTIFIED BY \'' . PMA_sqlAddslashes($pma_pw) . '\'';
904 } else {
905 if ($pred_password == 'keep' && !empty($password)) {
906 $real_sql_query .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
907 if (isset($create_user_real)) {
908 $create_user_real .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
911 $sql_query = $real_sql_query;
912 if (isset($create_user_real)) {
913 $create_user_show = $create_user_real;
917 * @todo similar code appears twice in this script
919 if ((isset($Grant_priv) && $Grant_priv == 'Y')
920 || (isset($max_questions) || isset($max_connections)
921 || isset($max_updates) || isset($max_user_connections))) {
922 $real_sql_query .= ' WITH';
923 $sql_query .= ' WITH';
924 if (isset($Grant_priv) && $Grant_priv == 'Y') {
925 $real_sql_query .= ' GRANT OPTION';
926 $sql_query .= ' GRANT OPTION';
928 if (isset($max_questions)) {
929 // avoid negative values
930 $max_questions = max(0, (int)$max_questions);
931 $real_sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
932 $sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
934 if (isset($max_connections)) {
935 $max_connections = max(0, (int)$max_connections);
936 $real_sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
937 $sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
939 if (isset($max_updates)) {
940 $max_updates = max(0, (int)$max_updates);
941 $real_sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
942 $sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
944 if (isset($max_user_connections)) {
945 $max_user_connections = max(0, (int)$max_user_connections);
946 $real_sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
947 $sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
950 if (isset($create_user_real)) {
951 $create_user_real .= ';';
952 $create_user_show .= ';';
954 $real_sql_query .= ';';
955 $sql_query .= ';';
956 if (empty($_REQUEST['change_copy'])) {
957 $_error = false;
959 if (isset($create_user_real)) {
960 if (! PMA_DBI_try_query($create_user_real)) {
961 $_error = true;
963 $sql_query = $create_user_show . $sql_query;
966 if ($_error || ! PMA_DBI_try_query($real_sql_query)) {
967 $_REQUEST['createdb'] = false;
968 $message = PMA_Message::rawError(PMA_DBI_getError());
969 } else {
970 $message = PMA_Message::success(__('You have added a new user.'));
973 switch (PMA_ifSetOr($_REQUEST['createdb'], '0')) {
974 case '1' :
975 // Create database with same name and grant all privileges
976 $q = 'CREATE DATABASE IF NOT EXISTS '
977 . PMA_backquote(PMA_sqlAddslashes($username)) . ';';
978 $sql_query .= $q;
979 if (! PMA_DBI_try_query($q)) {
980 $message = PMA_Message::rawError(PMA_DBI_getError());
981 break;
983 $GLOBALS['reload'] = TRUE;
984 PMA_reloadNavigation();
986 $q = 'GRANT ALL PRIVILEGES ON '
987 . PMA_backquote(PMA_sqlAddslashes($username)) . '.* TO \''
988 . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
989 $sql_query .= $q;
990 if (! PMA_DBI_try_query($q)) {
991 $message = PMA_Message::rawError(PMA_DBI_getError());
993 break;
994 case '2' :
995 // Grant all privileges on wildcard name (username\_%)
996 $q = 'GRANT ALL PRIVILEGES ON '
997 . PMA_backquote(PMA_sqlAddslashes($username) . '\_%') . '.* TO \''
998 . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
999 $sql_query .= $q;
1000 if (! PMA_DBI_try_query($q)) {
1001 $message = PMA_Message::rawError(PMA_DBI_getError());
1003 break;
1004 case '3' :
1005 // Grant all privileges on the specified database to the new user
1006 $q = 'GRANT ALL PRIVILEGES ON '
1007 . PMA_backquote(PMA_sqlAddslashes($dbname)) . '.* TO \''
1008 . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1009 $sql_query .= $q;
1010 if (! PMA_DBI_try_query($q)) {
1011 $message = PMA_Message::rawError(PMA_DBI_getError());
1013 break;
1014 case '0' :
1015 default :
1016 break;
1018 } else {
1019 if (isset($create_user_real)) {
1020 $queries[] = $create_user_real;
1022 $queries[] = $real_sql_query;
1023 // we put the query containing the hidden password in
1024 // $queries_for_display, at the same position occupied
1025 // by the real query in $queries
1026 $tmp_count = count($queries);
1027 if (isset($create_user_real)) {
1028 $queries_for_display[$tmp_count - 2] = $create_user_show;
1030 $queries_for_display[$tmp_count - 1] = $sql_query;
1032 unset($res, $real_sql_query);
1038 * Changes / copies a user, part III
1040 if (isset($_REQUEST['change_copy'])) {
1041 $user_host_condition =
1042 ' WHERE `User`'
1043 .' = \'' . PMA_sqlAddslashes($old_username) . "'"
1044 .' AND `Host`'
1045 .' = \'' . PMA_sqlAddslashes($old_hostname) . '\';';
1046 $res = PMA_DBI_query('SELECT * FROM `mysql`.`db`' . $user_host_condition);
1047 while ($row = PMA_DBI_fetch_assoc($res)) {
1048 $queries[] =
1049 'GRANT ' . join(', ', PMA_extractPrivInfo($row))
1050 .' ON ' . PMA_backquote($row['Db']) . '.*'
1051 .' TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\''
1052 . ($row['Grant_priv'] == 'Y' ? ' WITH GRANT OPTION;' : ';');
1054 PMA_DBI_free_result($res);
1055 $res = PMA_DBI_query(
1056 'SELECT `Db`, `Table_name`, `Table_priv`'
1057 .' FROM `mysql`.`tables_priv`' . $user_host_condition,
1058 $GLOBALS['userlink'], PMA_DBI_QUERY_STORE);
1059 while ($row = PMA_DBI_fetch_assoc($res)) {
1061 $res2 = PMA_DBI_QUERY(
1062 'SELECT `Column_name`, `Column_priv`'
1063 .' FROM `mysql`.`columns_priv`'
1064 .' WHERE `User`'
1065 .' = \'' . PMA_sqlAddslashes($old_username) . "'"
1066 .' AND `Host`'
1067 .' = \'' . PMA_sqlAddslashes($old_hostname) . '\''
1068 .' AND `Db`'
1069 .' = \'' . PMA_sqlAddslashes($row['Db']) . "'"
1070 .' AND `Table_name`'
1071 .' = \'' . PMA_sqlAddslashes($row['Table_name']) . "'"
1072 .';',
1073 null, PMA_DBI_QUERY_STORE);
1075 $tmp_privs1 = PMA_extractPrivInfo($row);
1076 $tmp_privs2 = array(
1077 'Select' => array(),
1078 'Insert' => array(),
1079 'Update' => array(),
1080 'References' => array()
1083 while ($row2 = PMA_DBI_fetch_assoc($res2)) {
1084 $tmp_array = explode(',', $row2['Column_priv']);
1085 if (in_array('Select', $tmp_array)) {
1086 $tmp_privs2['Select'][] = $row2['Column_name'];
1088 if (in_array('Insert', $tmp_array)) {
1089 $tmp_privs2['Insert'][] = $row2['Column_name'];
1091 if (in_array('Update', $tmp_array)) {
1092 $tmp_privs2['Update'][] = $row2['Column_name'];
1094 if (in_array('References', $tmp_array)) {
1095 $tmp_privs2['References'][] = $row2['Column_name'];
1097 unset($tmp_array);
1099 if (count($tmp_privs2['Select']) > 0 && !in_array('SELECT', $tmp_privs1)) {
1100 $tmp_privs1[] = 'SELECT (`' . join('`, `', $tmp_privs2['Select']) . '`)';
1102 if (count($tmp_privs2['Insert']) > 0 && !in_array('INSERT', $tmp_privs1)) {
1103 $tmp_privs1[] = 'INSERT (`' . join('`, `', $tmp_privs2['Insert']) . '`)';
1105 if (count($tmp_privs2['Update']) > 0 && !in_array('UPDATE', $tmp_privs1)) {
1106 $tmp_privs1[] = 'UPDATE (`' . join('`, `', $tmp_privs2['Update']) . '`)';
1108 if (count($tmp_privs2['References']) > 0 && !in_array('REFERENCES', $tmp_privs1)) {
1109 $tmp_privs1[] = 'REFERENCES (`' . join('`, `', $tmp_privs2['References']) . '`)';
1111 unset($tmp_privs2);
1112 $queries[] =
1113 'GRANT ' . join(', ', $tmp_privs1)
1114 . ' ON ' . PMA_backquote($row['Db']) . '.' . PMA_backquote($row['Table_name'])
1115 . ' TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\''
1116 . (in_array('Grant', explode(',', $row['Table_priv'])) ? ' WITH GRANT OPTION;' : ';');
1122 * Updates privileges
1124 if (!empty($update_privs)) {
1125 $db_and_table = PMA_WildcardEscapeForGrant($db_and_table, $dbname, (isset($tablename) ? $tablename : ''));
1127 $sql_query0 =
1128 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
1129 . ' FROM \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1130 if (!isset($Grant_priv) || $Grant_priv != 'Y') {
1131 $sql_query1 =
1132 'REVOKE GRANT OPTION ON ' . $db_and_table
1133 . ' FROM \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1134 } else {
1135 $sql_query1 = '';
1138 // Should not do a GRANT USAGE for a table-specific privilege, it
1139 // causes problems later (cannot revoke it)
1140 if (! (isset($tablename) && 'USAGE' == implode('', PMA_extractPrivInfo()))) {
1141 $sql_query2 =
1142 'GRANT ' . join(', ', PMA_extractPrivInfo())
1143 . ' ON ' . $db_and_table
1144 . ' TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\'';
1147 * @todo similar code appears twice in this script
1149 if ((isset($Grant_priv) && $Grant_priv == 'Y')
1150 || (! isset($dbname)
1151 && (isset($max_questions) || isset($max_connections)
1152 || isset($max_updates) || isset($max_user_connections))))
1154 $sql_query2 .= 'WITH';
1155 if (isset($Grant_priv) && $Grant_priv == 'Y') {
1156 $sql_query2 .= ' GRANT OPTION';
1158 if (isset($max_questions)) {
1159 $max_questions = max(0, (int)$max_questions);
1160 $sql_query2 .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
1162 if (isset($max_connections)) {
1163 $max_connections = max(0, (int)$max_connections);
1164 $sql_query2 .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
1166 if (isset($max_updates)) {
1167 $max_updates = max(0, (int)$max_updates);
1168 $sql_query2 .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
1170 if (isset($max_user_connections)) {
1171 $max_user_connections = max(0, (int)$max_user_connections);
1172 $sql_query2 .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
1175 $sql_query2 .= ';';
1177 if (! PMA_DBI_try_query($sql_query0)) {
1178 // this query may fail, but this does not matter :o)
1179 $sql_query0 = '';
1181 if (isset($sql_query1) && !PMA_DBI_try_query($sql_query1)) {
1182 // this one may fail, too...
1183 $sql_query1 = '';
1185 if (isset($sql_query2)) {
1186 PMA_DBI_query($sql_query2);
1187 } else {
1188 $sql_query2 = '';
1190 $sql_query = $sql_query0 . ' ' . $sql_query1 . ' ' . $sql_query2;
1191 $message = PMA_Message::success(__('You have updated the privileges for %s.'));
1192 $message->addParam('\'' . $username . '\'@\'' . $hostname . '\'');
1197 * Revokes Privileges
1199 if (isset($_REQUEST['revokeall'])) {
1200 $db_and_table = PMA_WildcardEscapeForGrant($db_and_table, $dbname, isset($tablename) ? $tablename : '');
1202 $sql_query0 =
1203 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
1204 . ' FROM \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1205 $sql_query1 =
1206 'REVOKE GRANT OPTION ON ' . $db_and_table
1207 . ' FROM \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\';';
1209 PMA_DBI_query($sql_query0);
1210 if (! PMA_DBI_try_query($sql_query1)) {
1211 // this one may fail, too...
1212 $sql_query1 = '';
1214 $sql_query = $sql_query0 . ' ' . $sql_query1;
1215 $message = PMA_Message::success(__('You have revoked the privileges for %s'));
1216 $message->addParam('\'' . $username . '\'@\'' . $hostname . '\'');
1217 if (! isset($tablename)) {
1218 unset($dbname);
1219 } else {
1220 unset($tablename);
1226 * Updates the password
1228 if (isset($_REQUEST['change_pw'])) {
1229 // similar logic in user_password.php
1230 $message = '';
1232 if ($nopass == 0 && isset($pma_pw) && isset($pma_pw2)) {
1233 if ($pma_pw != $pma_pw2) {
1234 $message = PMA_Message::error(__('The passwords aren\'t the same!'));
1235 } elseif (empty($pma_pw) || empty($pma_pw2)) {
1236 $message = PMA_Message::error(__('The password is empty!'));
1238 } // end if
1240 // here $nopass could be == 1
1241 if (empty($message)) {
1243 $hashing_function = (!empty($pw_hash) && $pw_hash == 'old' ? 'OLD_' : '')
1244 . 'PASSWORD';
1246 // in $sql_query which will be displayed, hide the password
1247 $sql_query = 'SET PASSWORD FOR \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\' = ' . (($pma_pw == '') ? '\'\'' : $hashing_function . '(\'' . preg_replace('@.@s', '*', $pma_pw) . '\')');
1248 $local_query = 'SET PASSWORD FOR \'' . PMA_sqlAddslashes($username) . '\'@\'' . PMA_sqlAddslashes($hostname) . '\' = ' . (($pma_pw == '') ? '\'\'' : $hashing_function . '(\'' . PMA_sqlAddslashes($pma_pw) . '\')');
1249 PMA_DBI_try_query($local_query)
1250 or PMA_mysqlDie(PMA_DBI_getError(), $sql_query, FALSE, $err_url);
1251 $message = PMA_Message::success(__('The password for %s was changed successfully.'));
1252 $message->addParam('\'' . $username . '\'@\'' . $hostname . '\'');
1258 * Deletes users
1259 * (Changes / copies a user, part IV)
1262 if (isset($_REQUEST['delete']) || (isset($_REQUEST['change_copy']) && $_REQUEST['mode'] < 4)) {
1263 if (isset($_REQUEST['change_copy'])) {
1264 $selected_usr = array($old_username . '&amp;#27;' . $old_hostname);
1265 } else {
1266 $selected_usr = $_REQUEST['selected_usr'];
1267 $queries = array();
1269 foreach ($selected_usr as $each_user) {
1270 list($this_user, $this_host) = explode('&amp;#27;', $each_user);
1271 $queries[] = '# ' . sprintf(__('Deleting %s'), '\'' . $this_user . '\'@\'' . $this_host . '\'') . ' ...';
1272 $queries[] = 'DROP USER \'' . PMA_sqlAddslashes($this_user) . '\'@\'' . PMA_sqlAddslashes($this_host) . '\';';
1274 if (isset($_REQUEST['drop_users_db'])) {
1275 $queries[] = 'DROP DATABASE IF EXISTS ' . PMA_backquote($this_user) . ';';
1276 $GLOBALS['reload'] = TRUE;
1277 PMA_reloadNavigation();
1280 if (empty($_REQUEST['change_copy'])) {
1281 if (empty($queries)) {
1282 $message = PMA_Message::error(__('No users selected for deleting!'));
1283 } else {
1284 if ($_REQUEST['mode'] == 3) {
1285 $queries[] = '# ' . __('Reloading the privileges') . ' ...';
1286 $queries[] = 'FLUSH PRIVILEGES;';
1288 $drop_user_error = '';
1289 foreach ($queries as $sql_query) {
1290 if ($sql_query{0} != '#') {
1291 if (! PMA_DBI_try_query($sql_query, $GLOBALS['userlink'])) {
1292 $drop_user_error .= PMA_DBI_getError() . "\n";
1296 $sql_query = join("\n", $queries);
1297 if (! empty($drop_user_error)) {
1298 $message = PMA_Message::rawError($drop_user_error);
1299 } else {
1300 $message = PMA_Message::success(__('The selected users have been deleted successfully.'));
1303 unset($queries);
1309 * Changes / copies a user, part V
1311 if (isset($_REQUEST['change_copy'])) {
1312 $tmp_count = 0;
1313 foreach ($queries as $sql_query) {
1314 if ($sql_query{0} != '#') {
1315 PMA_DBI_query($sql_query);
1317 // when there is a query containing a hidden password, take it
1318 // instead of the real query sent
1319 if (isset($queries_for_display[$tmp_count])) {
1320 $queries[$tmp_count] = $queries_for_display[$tmp_count];
1322 $tmp_count++;
1324 $message = PMA_Message::success();
1325 $sql_query = join("\n", $queries);
1330 * Reloads the privilege tables into memory
1332 if (isset($_REQUEST['flush_privileges'])) {
1333 $sql_query = 'FLUSH PRIVILEGES;';
1334 PMA_DBI_query($sql_query);
1335 $message = PMA_Message::success(__('The privileges were reloaded successfully.'));
1340 * Displays the links
1342 if (isset($viewing_mode) && $viewing_mode == 'db') {
1343 $db = $checkprivs;
1344 $url_query .= '&amp;goto=db_operations.php';
1346 // Gets the database structure
1347 $sub_part = '_structure';
1348 require './libraries/db_info.inc.php';
1349 echo "\n";
1350 } else {
1351 require './libraries/server_links.inc.php';
1356 * defines some standard links
1358 $link_edit = '<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 . PMA_getIcon('b_usredit.png', __('Edit Privileges'))
1364 . '</a>';
1366 $link_revoke = '<a href="server_privileges.php?' . $GLOBALS['url_query']
1367 . '&amp;username=%s'
1368 . '&amp;hostname=%s'
1369 . '&amp;dbname=%s'
1370 . '&amp;tablename=%s'
1371 . '&amp;revokeall=1">'
1372 . PMA_getIcon('b_usrdrop.png', __('Revoke'))
1373 . '</a>';
1375 $link_export = '<a href="server_privileges.php?' . $GLOBALS['url_query']
1376 . '&amp;username=%s'
1377 . '&amp;hostname=%s'
1378 . '&amp;initial=%s'
1379 . '&amp;export=1">'
1380 . PMA_getIcon('b_tblexport.png', __('Export'))
1381 . '</a>';
1384 * Displays the page
1387 // export user definition
1388 if (isset($_REQUEST['export'])) {
1389 echo '<h2>' . __('User') . ' \'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'</h2>';
1390 echo '<textarea cols="' . $GLOBALS['cfg']['TextareaCols'] . '" rows="' . $GLOBALS['cfg']['TextareaRows'] . '">';
1391 $grants = PMA_DBI_fetch_result("SHOW GRANTS FOR '" . PMA_sqlAddslashes($username) . "'@'" . PMA_sqlAddslashes($hostname) . "'");
1392 foreach($grants as $one_grant) {
1393 echo $one_grant . ";\n\n";
1395 echo '</textarea>';
1396 unset($username, $hostname, $grants, $one_grant);
1399 if (empty($_REQUEST['adduser']) && (! isset($checkprivs) || ! strlen($checkprivs))) {
1400 if (! isset($username)) {
1401 // No username is given --> display the overview
1402 echo '<h2>' . "\n"
1403 . PMA_getIcon('b_usrlist.png')
1404 . __('User overview') . "\n"
1405 . '</h2>' . "\n";
1407 $sql_query =
1408 'SELECT *,' .
1409 " IF(`Password` = _latin1 '', 'N', 'Y') AS 'Password'" .
1410 ' FROM `mysql`.`user`';
1412 $sql_query .= (isset($initial) ? PMA_RangeOfUsers($initial) : '');
1414 $sql_query .= ' ORDER BY `User` ASC, `Host` ASC;';
1415 $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE);
1417 if (! $res) {
1418 // the query failed! This may have two reasons:
1419 // - the user does not have enough privileges
1420 // - the privilege tables use a structure of an earlier version.
1421 // so let's try a more simple query
1423 $sql_query = 'SELECT * FROM `mysql`.`user`';
1424 $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE);
1426 if (!$res) {
1427 PMA_Message::error(__('No Privileges'))->display();
1428 PMA_DBI_free_result($res);
1429 unset($res);
1430 } else {
1431 // This message is hardcoded because I will replace it by
1432 // a automatic repair feature soon.
1433 $raw = 'Your privilege table structure seems to be older than'
1434 . ' this MySQL version!<br />'
1435 . 'Please run the <tt>mysql_upgrade</tt> command'
1436 . '(<tt>mysql_fix_privilege_tables</tt> on older systems)'
1437 . ' that should be included in your MySQL server distribution'
1438 . ' to solve this problem!';
1439 PMA_Message::rawError($raw)->display();
1441 } else {
1443 // we also want users not in table `user` but in other table
1444 $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;');
1446 $tables_to_search_for_users = array(
1447 'user', 'db', 'tables_priv', 'columns_priv', 'procs_priv',
1450 $db_rights_sqls = array();
1451 foreach ($tables_to_search_for_users as $table_search_in) {
1452 if (in_array($table_search_in, $tables)) {
1453 $db_rights_sqls[] = 'SELECT DISTINCT `User`, `Host` FROM `mysql`.`' . $table_search_in . '` ' . (isset($initial) ? PMA_RangeOfUsers($initial) : '');
1457 $user_defaults = array(
1458 'User' => '',
1459 'Host' => '%',
1460 'Password' => '?',
1461 'Grant_priv' => 'N',
1462 'privs' => array('USAGE'),
1465 // for all initials, even non A-Z
1466 $array_initials = array();
1467 // for the rights
1468 $db_rights = array();
1470 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
1471 .' ORDER BY `User` ASC, `Host` ASC';
1473 $db_rights_result = PMA_DBI_query($db_rights_sql);
1475 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
1476 $db_rights_row = array_merge($user_defaults, $db_rights_row);
1477 $db_rights[$db_rights_row['User']][$db_rights_row['Host']] =
1478 $db_rights_row;
1480 PMA_DBI_free_result($db_rights_result);
1481 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
1482 ksort($db_rights);
1485 * Displays the initials
1488 // initialize to FALSE the letters A-Z
1489 for ($letter_counter = 1; $letter_counter < 27; $letter_counter++) {
1490 if (! isset($array_initials[chr($letter_counter + 64)])) {
1491 $array_initials[chr($letter_counter + 64)] = FALSE;
1495 $initials = PMA_DBI_try_query('SELECT DISTINCT UPPER(LEFT(`User`,1)) FROM `user` ORDER BY `User` ASC', null, PMA_DBI_QUERY_STORE);
1496 while (list($tmp_initial) = PMA_DBI_fetch_row($initials)) {
1497 $array_initials[$tmp_initial] = TRUE;
1500 // Display the initials, which can be any characters, not
1501 // just letters. For letters A-Z, we add the non-used letters
1502 // as greyed out.
1504 uksort($array_initials, "strnatcasecmp");
1506 echo '<table cellspacing="5"><tr>';
1507 foreach ($array_initials as $tmp_initial => $initial_was_found) {
1508 if ($initial_was_found) {
1509 echo '<td><a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;initial=' . urlencode($tmp_initial) . '">' . $tmp_initial . '</a></td>' . "\n";
1510 } else {
1511 echo '<td>' . $tmp_initial . '</td>';
1514 echo '<td><a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;showall=1">[' . __('Show all') . ']</a></td>' . "\n";
1515 echo '</tr></table>';
1518 * Display the user overview
1519 * (if less than 50 users, display them immediately)
1522 if (isset($initial) || isset($showall) || PMA_DBI_num_rows($res) < 50) {
1524 while ($row = PMA_DBI_fetch_assoc($res)) {
1525 $row['privs'] = PMA_extractPrivInfo($row, true);
1526 $db_rights[$row['User']][$row['Host']] = $row;
1528 @PMA_DBI_free_result($res);
1529 unset($res);
1531 echo '<form name="usersForm" id="usersForm" action="server_privileges.php" method="post">' . "\n"
1532 . PMA_generate_common_hidden_inputs('', '')
1533 . ' <table id="tableuserrights" class="data">' . "\n"
1534 . ' <thead>' . "\n"
1535 . ' <tr><th></th>' . "\n"
1536 . ' <th>' . __('User') . '</th>' . "\n"
1537 . ' <th>' . __('Host') . '</th>' . "\n"
1538 . ' <th>' . __('Password') . '</th>' . "\n"
1539 . ' <th>' . __('Global privileges') . ' '
1540 . PMA_showHint(__(' Note: MySQL privilege names are expressed in English ')) . '</th>' . "\n"
1541 . ' <th>' . __('Grant') . '</th>' . "\n"
1542 . ' <th colspan="2">' . __('Action') . '</th>' . "\n";
1543 echo ' </tr>' . "\n";
1544 echo ' </thead>' . "\n";
1545 echo ' <tbody>' . "\n";
1546 $odd_row = true;
1547 $index_checkbox = -1;
1548 foreach ($db_rights as $user) {
1549 $index_checkbox++;
1550 ksort($user);
1551 foreach ($user as $host) {
1552 $index_checkbox++;
1553 echo ' <tr class="' . ($odd_row ? 'odd' : 'even') . '">' . "\n"
1554 . ' <td><input type="checkbox" name="selected_usr[]" id="checkbox_sel_users_'
1555 . $index_checkbox . '" value="'
1556 . htmlspecialchars($host['User'] . '&amp;#27;' . $host['Host'])
1557 . '"'
1558 . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"')
1559 . ' /></td>' . "\n"
1560 . ' <td><label for="checkbox_sel_users_' . $index_checkbox . '">' . (empty($host['User']) ? '<span style="color: #FF0000">' . __('Any') . '</span>' : htmlspecialchars($host['User'])) . '</label></td>' . "\n"
1561 . ' <td>' . htmlspecialchars($host['Host']) . '</td>' . "\n";
1562 echo ' <td>';
1563 switch ($host['Password']) {
1564 case 'Y':
1565 echo __('Yes');
1566 break;
1567 case 'N':
1568 echo '<span style="color: #FF0000">' . __('No') . '</span>';
1569 break;
1570 // this happens if this is a definition not coming from mysql.user
1571 default:
1572 echo '--'; // in future version, replace by "not present"
1573 break;
1574 } // end switch
1575 echo '</td>' . "\n"
1576 . ' <td><tt>' . "\n"
1577 . ' ' . implode(',' . "\n" . ' ', $host['privs']) . "\n"
1578 . ' </tt></td>' . "\n"
1579 . ' <td>' . ($host['Grant_priv'] == 'Y' ? __('Yes') : __('No')) . '</td>' . "\n"
1580 . ' <td align="center">';
1581 printf($link_edit, urlencode($host['User']), urlencode($host['Host']), '', '');
1582 echo '</td>';
1583 echo '<td align="center">';
1584 printf($link_export, urlencode($host['User']), urlencode($host['Host']), (isset($initial) ? $initial : ''));
1585 echo '</td>';
1586 echo '</tr>';
1587 $odd_row = ! $odd_row;
1591 unset($user, $host, $odd_row);
1592 echo ' </tbody></table>' . "\n"
1593 .'<img class="selectallarrow"'
1594 .' src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png"'
1595 .' width="38" height="22"'
1596 .' alt="' . __('With selected:') . '" />' . "\n"
1597 .'<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;checkall=1"'
1598 .' onclick="if (markAllRows(\'usersForm\')) return false;">'
1599 . __('Check All') . '</a>' . "\n"
1600 .'/' . "\n"
1601 .'<a href="server_privileges.php?' . $GLOBALS['url_query'] . '"'
1602 .' onclick="if (unMarkAllRows(\'usersForm\')) return false;">'
1603 . __('Uncheck All') . '</a>' . "\n";
1605 // add/delete user fieldset
1606 echo ' <fieldset id="fieldset_add_user">' . "\n"
1607 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;adduser=1">' . "\n"
1608 . PMA_getIcon('b_usradd.png')
1609 . ' ' . __('Add a new User') . '</a>' . "\n"
1610 . ' </fieldset>' . "\n"
1611 . ' <fieldset id="fieldset_delete_user">'
1612 . ' <legend>' . "\n"
1613 . PMA_getIcon('b_usrdrop.png')
1614 . ' ' . __('Remove selected users') . '' . "\n"
1615 . ' </legend>' . "\n"
1616 . ' <input type="hidden" name="mode" value="2" />' . "\n"
1617 . '(' . __('Revoke all active privileges from the users and delete them afterwards.') . ')<br />' . "\n"
1618 . ' <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"
1619 . ' <label for="checkbox_drop_users_db" title="' . __('Drop the databases that have the same names as the users.') . '">' . "\n"
1620 . ' ' . __('Drop the databases that have the same names as the users.') . "\n"
1621 . ' </label>' . "\n"
1622 . ' </fieldset>' . "\n"
1623 . ' <fieldset id="fieldset_delete_user_footer" class="tblFooters">' . "\n"
1624 . ' <input type="submit" name="delete" value="' . __('Go') . '" id="buttonGo" />' . "\n"
1625 . ' </fieldset>' . "\n"
1626 . '</form>' . "\n";
1627 } else {
1629 unset ($row);
1630 echo ' <fieldset id="fieldset_add_user">' . "\n"
1631 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;adduser=1">' . "\n"
1632 . PMA_getIcon('b_usradd.png')
1633 . ' ' . __('Add a new User') . '</a>' . "\n"
1634 . ' </fieldset>' . "\n";
1635 } // end if (display overview)
1636 $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);
1637 $flushnote->addParam('<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;flush_privileges=1">', false);
1638 $flushnote->addParam('</a>', false);
1639 $flushnote->display();
1643 } else {
1645 // A user was selected -> display the user's properties
1647 echo '<h2>' . "\n"
1648 . PMA_getIcon('b_usredit.png')
1649 . __('Edit Privileges') . ': '
1650 . __('User') ;
1652 if (isset($dbname)) {
1653 echo ' <i><a href="server_privileges.php?'
1654 . $GLOBALS['url_query'] . '&amp;username=' . urlencode($username)
1655 . '&amp;hostname=' . urlencode($hostname) . '&amp;dbname=&amp;tablename=">\''
1656 . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname)
1657 . '\'</a></i>' . "\n";
1658 $url_dbname = urlencode(str_replace(array('\_', '\%'), array('_', '%'), $dbname));
1660 echo ' - ' . ($dbname_is_wildcard ? __('Databases') : __('Database') );
1661 if (isset($tablename)) {
1662 echo ' <i><a href="server_privileges.php?' . $GLOBALS['url_query']
1663 . '&amp;username=' . urlencode($username) . '&amp;hostname=' . urlencode($hostname)
1664 . '&amp;dbname=' . $url_dbname . '&amp;tablename=">' . htmlspecialchars($dbname) . '</a></i>';
1665 echo ' - ' . __('Table') . ' <i>' . htmlspecialchars($tablename) . '</i>';
1666 } else {
1667 echo ' <i>' . htmlspecialchars($dbname) . '</i>';
1670 } else {
1671 echo ' <i>\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname)
1672 . '\'</i>' . "\n";
1675 echo '</h2>' . "\n";
1678 $sql = "SELECT '1' FROM `mysql`.`user`"
1679 . " WHERE `User` = '" . PMA_sqlAddslashes($username) . "'"
1680 . " AND `Host` = '" . PMA_sqlAddslashes($hostname) . "';";
1681 $user_does_not_exists = (bool) ! PMA_DBI_fetch_value($sql);
1682 unset($sql);
1683 if ($user_does_not_exists) {
1684 PMA_Message::warning(__('The selected user was not found in the privilege table.'))->display();
1685 PMA_displayLoginInformationFields();
1686 //require_once './libraries/footer.inc.php';
1689 echo '<form name="usersForm" id="usersForm" action="server_privileges.php" method="post">' . "\n";
1690 $_params = array(
1691 'username' => $username,
1692 'hostname' => $hostname,
1694 if (isset($dbname)) {
1695 $_params['dbname'] = $dbname;
1696 if (isset($tablename)) {
1697 $_params['tablename'] = $tablename;
1700 echo PMA_generate_common_hidden_inputs($_params);
1702 PMA_displayPrivTable(PMA_ifSetOr($dbname, '*', 'length'),
1703 PMA_ifSetOr($tablename, '*', 'length'));
1705 echo '</form>' . "\n";
1707 if (! isset($tablename) && empty($dbname_is_wildcard)) {
1709 // no table name was given, display all table specific rights
1710 // but only if $dbname contains no wildcards
1712 // table header
1713 echo '<form action="server_privileges.php" method="post">' . "\n"
1714 . PMA_generate_common_hidden_inputs('', '')
1715 . '<input type="hidden" name="username" value="' . htmlspecialchars($username) . '" />' . "\n"
1716 . '<input type="hidden" name="hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n"
1717 . '<fieldset>' . "\n"
1718 . '<legend>' . (! isset($dbname) ? __('Database-specific privileges') : __('Table-specific privileges')) . '</legend>' . "\n"
1719 . '<table class="data">' . "\n"
1720 . '<thead>' . "\n"
1721 . '<tr><th>' . (! isset($dbname) ? __('Database') : __('Table')) . '</th>' . "\n"
1722 . ' <th>' . __('Privileges') . '</th>' . "\n"
1723 . ' <th>' . __('Grant') . '</th>' . "\n"
1724 . ' <th>' . (! isset($dbname) ? __('Table-specific privileges') : __('Column-specific privileges')) . '</th>' . "\n"
1725 . ' <th colspan="2">' . __('Action') . '</th>' . "\n"
1726 . '</tr>' . "\n"
1727 . '</thead>' . "\n"
1728 . '<tbody>' . "\n";
1730 $user_host_condition =
1731 ' WHERE `User`'
1732 . ' = \'' . PMA_sqlAddslashes($username) . "'"
1733 . ' AND `Host`'
1734 . ' = \'' . PMA_sqlAddslashes($hostname) . "'";
1736 // table body
1737 // get data
1739 // we also want privielgs for this user not in table `db` but in other table
1740 $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;');
1741 if (! isset($dbname)) {
1743 // no db name given, so we want all privs for the given user
1745 $tables_to_search_for_users = array(
1746 'tables_priv', 'columns_priv',
1749 $db_rights_sqls = array();
1750 foreach ($tables_to_search_for_users as $table_search_in) {
1751 if (in_array($table_search_in, $tables)) {
1752 $db_rights_sqls[] = '
1753 SELECT DISTINCT `Db`
1754 FROM `mysql`.' . PMA_backquote($table_search_in)
1755 . $user_host_condition;
1759 $user_defaults = array(
1760 'Db' => '',
1761 'Grant_priv' => 'N',
1762 'privs' => array('USAGE'),
1763 'Table_privs' => true,
1766 // for the rights
1767 $db_rights = array();
1769 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
1770 .' ORDER BY `Db` ASC';
1772 $db_rights_result = PMA_DBI_query($db_rights_sql);
1774 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
1775 $db_rights_row = array_merge($user_defaults, $db_rights_row);
1776 // only Db names in the table `mysql`.`db` uses wildcards
1777 // as we are in the db specific rights display we want
1778 // all db names escaped, also from other sources
1779 $db_rights_row['Db'] = PMA_escape_mysql_wildcards(
1780 $db_rights_row['Db']);
1781 $db_rights[$db_rights_row['Db']] = $db_rights_row;
1784 PMA_DBI_free_result($db_rights_result);
1785 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
1787 $sql_query = 'SELECT * FROM `mysql`.`db`' . $user_host_condition . ' ORDER BY `Db` ASC';
1788 $res = PMA_DBI_query($sql_query);
1789 $sql_query = '';
1791 while ($row = PMA_DBI_fetch_assoc($res)) {
1792 if (isset($db_rights[$row['Db']])) {
1793 $db_rights[$row['Db']] = array_merge($db_rights[$row['Db']], $row);
1794 } else {
1795 $db_rights[$row['Db']] = $row;
1797 // there are db specific rights for this user
1798 // so we can drop this db rights
1799 $db_rights[$row['Db']]['can_delete'] = true;
1801 PMA_DBI_free_result($res);
1802 unset($row, $res);
1804 } else {
1806 // db name was given,
1807 // so we want all user specific rights for this db
1809 $user_host_condition .=
1810 ' AND `Db`'
1811 .' LIKE \'' . PMA_sqlAddslashes($dbname) . "'";
1813 $tables_to_search_for_users = array(
1814 'columns_priv',
1817 $db_rights_sqls = array();
1818 foreach ($tables_to_search_for_users as $table_search_in) {
1819 if (in_array($table_search_in, $tables)) {
1820 $db_rights_sqls[] = '
1821 SELECT DISTINCT `Table_name`
1822 FROM `mysql`.' . PMA_backquote($table_search_in)
1823 . $user_host_condition;
1827 $user_defaults = array(
1828 'Table_name' => '',
1829 'Grant_priv' => 'N',
1830 'privs' => array('USAGE'),
1831 'Column_priv' => true,
1834 // for the rights
1835 $db_rights = array();
1837 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
1838 .' ORDER BY `Table_name` ASC';
1840 $db_rights_result = PMA_DBI_query($db_rights_sql);
1842 while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
1843 $db_rights_row = array_merge($user_defaults, $db_rights_row);
1844 $db_rights[$db_rights_row['Table_name']] = $db_rights_row;
1846 PMA_DBI_free_result($db_rights_result);
1847 unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row);
1849 $sql_query =
1850 'SELECT `Table_name`,'
1851 .' `Table_priv`,'
1852 .' IF(`Column_priv` = _latin1 \'\', 0, 1)'
1853 .' AS \'Column_priv\''
1854 .' FROM `mysql`.`tables_priv`'
1855 . $user_host_condition
1856 .' ORDER BY `Table_name` ASC;';
1857 $res = PMA_DBI_query($sql_query);
1858 $sql_query = '';
1860 while ($row = PMA_DBI_fetch_assoc($res)) {
1861 if (isset($db_rights[$row['Table_name']])) {
1862 $db_rights[$row['Table_name']] = array_merge($db_rights[$row['Table_name']], $row);
1863 } else {
1864 $db_rights[$row['Table_name']] = $row;
1867 PMA_DBI_free_result($res);
1868 unset($row, $res);
1870 ksort($db_rights);
1872 // display rows
1873 if (count($db_rights) < 1) {
1874 echo '<tr class="odd">' . "\n"
1875 . ' <td colspan="6"><center><i>' . __('None') . '</i></center></td>' . "\n"
1876 . '</tr>' . "\n";
1877 } else {
1878 $odd_row = true;
1879 $found_rows = array();
1880 //while ($row = PMA_DBI_fetch_assoc($res)) {
1881 foreach ($db_rights as $row) {
1882 $found_rows[] = (! isset($dbname)) ? $row['Db'] : $row['Table_name'];
1884 echo '<tr class="' . ($odd_row ? 'odd' : 'even') . '">' . "\n"
1885 . ' <td>' . htmlspecialchars((! isset($dbname)) ? $row['Db'] : $row['Table_name']) . '</td>' . "\n"
1886 . ' <td><tt>' . "\n"
1887 . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($row, TRUE)) . "\n"
1888 . ' </tt></td>' . "\n"
1889 . ' <td>' . ((((! isset($dbname)) && $row['Grant_priv'] == 'Y') || (isset($dbname) && in_array('Grant', explode(',', $row['Table_priv'])))) ? __('Yes') : __('No')) . '</td>' . "\n"
1890 . ' <td>';
1891 if (! empty($row['Table_privs']) || ! empty ($row['Column_priv'])) {
1892 echo __('Yes');
1893 } else {
1894 echo __('No');
1896 echo '</td>' . "\n"
1897 . ' <td>';
1898 printf($link_edit, urlencode($username),
1899 urlencode($hostname),
1900 urlencode((! isset($dbname)) ? $row['Db'] : $dbname),
1901 urlencode((! isset($dbname)) ? '' : $row['Table_name']));
1902 echo '</td>' . "\n"
1903 . ' <td>';
1904 if (! empty($row['can_delete']) || isset($row['Table_name']) && strlen($row['Table_name'])) {
1905 printf($link_revoke, urlencode($username),
1906 urlencode($hostname),
1907 urlencode((! isset($dbname)) ? $row['Db'] : $dbname),
1908 urlencode((! isset($dbname)) ? '' : $row['Table_name']));
1910 echo '</td>' . "\n"
1911 . '</tr>' . "\n";
1912 $odd_row = ! $odd_row;
1913 } // end while
1915 unset($row);
1916 echo '</tbody>' . "\n"
1917 . '</table>' . "\n";
1919 if (! isset($dbname)) {
1921 // no database name was given, display select db
1923 $pred_db_array =PMA_DBI_fetch_result('SHOW DATABASES;');
1925 echo ' <label for="text_dbname">' . __('Add privileges on the following database') . ':</label>' . "\n";
1926 if (!empty($pred_db_array)) {
1927 echo ' <select name="pred_dbname" onchange="this.form.submit();">' . "\n"
1928 . ' <option value="" selected="selected">' . __('Use text field') . ':</option>' . "\n";
1929 foreach ($pred_db_array as $current_db) {
1930 $current_db = PMA_escape_mysql_wildcards($current_db);
1931 // cannot use array_diff() once, outside of the loop,
1932 // because the list of databases has special characters
1933 // already escaped in $found_rows,
1934 // contrary to the output of SHOW DATABASES
1935 if (empty($found_rows) || ! in_array($current_db, $found_rows)) {
1936 echo ' <option value="' . htmlspecialchars($current_db) . '">'
1937 . htmlspecialchars($current_db) . '</option>' . "\n";
1940 echo ' </select>' . "\n";
1942 echo ' <input type="text" id="text_dbname" name="dbname" />' . "\n"
1943 . PMA_showHint(__('Wildcards % and _ should be escaped with a \ to use them literally'));
1944 } else {
1945 echo ' <input type="hidden" name="dbname" value="' . htmlspecialchars($dbname) . '"/>' . "\n"
1946 . ' <label for="text_tablename">' . __('Add privileges on the following table') . ':</label>' . "\n";
1947 if ($res = @PMA_DBI_try_query('SHOW TABLES FROM ' . PMA_backquote(PMA_unescape_mysql_wildcards($dbname)) . ';', null, PMA_DBI_QUERY_STORE)) {
1948 $pred_tbl_array = array();
1949 while ($row = PMA_DBI_fetch_row($res)) {
1950 if (!isset($found_rows) || !in_array($row[0], $found_rows)) {
1951 $pred_tbl_array[] = $row[0];
1954 PMA_DBI_free_result($res);
1955 unset($res, $row);
1956 if (!empty($pred_tbl_array)) {
1957 echo ' <select name="pred_tablename" onchange="this.form.submit();">' . "\n"
1958 . ' <option value="" selected="selected">' . __('Use text field') . ':</option>' . "\n";
1959 foreach ($pred_tbl_array as $current_table) {
1960 echo ' <option value="' . htmlspecialchars($current_table) . '">' . htmlspecialchars($current_table) . '</option>' . "\n";
1962 echo ' </select>' . "\n";
1964 } else {
1965 unset($res);
1967 echo ' <input type="text" id="text_tablename" name="tablename" />' . "\n";
1969 echo '</fieldset>' . "\n";
1970 echo '<fieldset class="tblFooters">' . "\n"
1971 . ' <input type="submit" value="' . __('Go') . '" />'
1972 . '</fieldset>' . "\n"
1973 . '</form>' . "\n";
1977 // Provide a line with links to the relevant database and table
1978 if (isset($dbname) && empty($dbname_is_wildcard)) {
1979 echo '[ ' . __('Database')
1980 . ' <a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?'
1981 . $GLOBALS['url_query'] . '&amp;db=' . $url_dbname . '&amp;reload=1">'
1982 . htmlspecialchars($dbname) . ': ' . PMA_getTitleForTarget($GLOBALS['cfg']['DefaultTabDatabase']) . "</a> ]\n";
1984 if (isset($tablename)) {
1985 echo ' [ ' . __('Table') . ' <a href="'
1986 . $GLOBALS['cfg']['DefaultTabTable'] . '?' . $GLOBALS['url_query']
1987 . '&amp;db=' . $url_dbname . '&amp;table=' . urlencode($tablename)
1988 . '&amp;reload=1">' . htmlspecialchars($tablename) . ': '
1989 . PMA_getTitleForTarget($GLOBALS['cfg']['DefaultTabTable'])
1990 . "</a> ]\n";
1992 unset($url_dbname);
1995 if (! isset($dbname) && ! $user_does_not_exists) {
1996 require_once './libraries/display_change_password.lib.php';
1998 echo '<form action="server_privileges.php" method="post" onsubmit="return checkPassword(this);">' . "\n"
1999 . PMA_generate_common_hidden_inputs('', '')
2000 . '<input type="hidden" name="old_username" value="' . htmlspecialchars($username) . '" />' . "\n"
2001 . '<input type="hidden" name="old_hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n"
2002 . '<fieldset id="fieldset_change_copy_user">' . "\n"
2003 . ' <legend>' . __('Change Login Information / Copy User') . '</legend>' . "\n";
2004 PMA_displayLoginInformationFields('change');
2005 echo ' <fieldset>' . "\n"
2006 . ' <legend>' . __('Create a new user with the same privileges and ...') . '</legend>' . "\n";
2007 $choices = array(
2008 '4' => __('... keep the old one.'),
2009 '1' => __(' ... delete the old one from the user tables.'),
2010 '2' => __(' ... revoke all active privileges from the old one and delete it afterwards.'),
2011 '3' => __(' ... delete the old one from the user tables and reload the privileges afterwards.'));
2012 PMA_display_html_radio('mode', $choices, '4', true);
2013 unset($choices);
2015 echo ' </fieldset>' . "\n"
2016 . '</fieldset>' . "\n"
2017 . '<fieldset id="fieldset_change_copy_user_footer" class="tblFooters">' . "\n"
2018 . ' <input type="submit" name="change_copy" value="' . __('Go') . '" />' . "\n"
2019 . '</fieldset>' . "\n"
2020 . '</form>' . "\n";
2023 } elseif (isset($_REQUEST['adduser'])) {
2024 // Add a new user
2025 $GLOBALS['url_query'] .= '&amp;adduser=1';
2026 echo '<h2>' . "\n"
2027 . PMA_getIcon('b_usradd.png') . __('Add a new User') . "\n"
2028 . '</h2>' . "\n"
2029 . '<form name="usersForm" id="usersForm" action="server_privileges.php" method="post" onsubmit="return checkAddUser(this);">' . "\n"
2030 . PMA_generate_common_hidden_inputs('', '');
2031 PMA_displayLoginInformationFields('new');
2032 echo '<fieldset id="fieldset_add_user_database">' . "\n"
2033 . '<legend>' . __('Database for user') . '</legend>' . "\n";
2035 $default_choice = 0;
2036 $choices = array(
2037 '0' => _pgettext('Create none database for user', 'None'),
2038 '1' => __('Create database with same name and grant all privileges'),
2039 '2' => __('Grant all privileges on wildcard name (username\\_%)'));
2041 if ( !empty($dbname) ) {
2042 $choices['3'] = sprintf( __('Grant all privileges on database &quot;%s&quot;'), htmlspecialchars($dbname));
2043 $default_choice = 3;
2044 echo '<input type="hidden" name="dbname" value="' . htmlspecialchars($dbname) . '" />' . "\n";
2047 // 4th parameter set to true to add line breaks
2048 // 5th parameter set to false to avoid htmlspecialchars() escaping in the label
2049 // since we have some HTML in some labels
2050 PMA_display_html_radio('createdb', $choices, $default_choice, true, false);
2051 unset($choices);
2052 unset($default_choice);
2054 echo '</fieldset>' . "\n";
2055 PMA_displayPrivTable('*', '*', FALSE);
2056 echo ' <fieldset id="fieldset_add_user_footer" class="tblFooters">' . "\n"
2057 . ' <input type="submit" name="adduser_submit" value="' . __('Go') . '" />' . "\n"
2058 . ' </fieldset>' . "\n"
2059 . '</form>' . "\n";
2060 } else {
2061 // check the privileges for a particular database.
2062 echo '<table id="tablespecificuserrights" class="data">' . "\n"
2063 . '<caption class="tblHeaders">' . "\n"
2064 . PMA_getIcon('b_usrcheck.png')
2065 . ' ' . sprintf(__('Users having access to &quot;%s&quot;'), '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?' . PMA_generate_common_url($checkprivs) . '">' . htmlspecialchars($checkprivs) . '</a>') . "\n"
2066 . '</caption>' . "\n"
2067 . '<thead>' . "\n"
2068 . ' <tr><th>' . __('User') . '</th>' . "\n"
2069 . ' <th>' . __('Host') . '</th>' . "\n"
2070 . ' <th>' . __('Type') . '</th>' . "\n"
2071 . ' <th>' . __('Privileges') . '</th>' . "\n"
2072 . ' <th>' . __('Grant') . '</th>' . "\n"
2073 . ' <th>' . __('Action') . '</th>' . "\n"
2074 . ' </tr>' . "\n"
2075 . '</thead>' . "\n"
2076 . '<tbody>' . "\n";
2077 $odd_row = TRUE;
2078 unset($row, $row1, $row2);
2080 // now, we build the table...
2081 $list_of_privileges =
2082 '`User`, '
2083 . '`Host`, '
2084 . '`Select_priv`, '
2085 . '`Insert_priv`, '
2086 . '`Update_priv`, '
2087 . '`Delete_priv`, '
2088 . '`Create_priv`, '
2089 . '`Drop_priv`, '
2090 . '`Grant_priv`, '
2091 . '`Index_priv`, '
2092 . '`Alter_priv`, '
2093 . '`References_priv`, '
2094 . '`Create_tmp_table_priv`, '
2095 . '`Lock_tables_priv`, '
2096 . '`Create_view_priv`, '
2097 . '`Show_view_priv`, '
2098 . '`Create_routine_priv`, '
2099 . '`Alter_routine_priv`, '
2100 . '`Execute_priv`';
2102 $list_of_compared_privileges =
2103 '`Select_priv` = \'N\''
2104 . ' AND `Insert_priv` = \'N\''
2105 . ' AND `Update_priv` = \'N\''
2106 . ' AND `Delete_priv` = \'N\''
2107 . ' AND `Create_priv` = \'N\''
2108 . ' AND `Drop_priv` = \'N\''
2109 . ' AND `Grant_priv` = \'N\''
2110 . ' AND `References_priv` = \'N\''
2111 . ' AND `Create_tmp_table_priv` = \'N\''
2112 . ' AND `Lock_tables_priv` = \'N\''
2113 . ' AND `Create_view_priv` = \'N\''
2114 . ' AND `Show_view_priv` = \'N\''
2115 . ' AND `Create_routine_priv` = \'N\''
2116 . ' AND `Alter_routine_priv` = \'N\''
2117 . ' AND `Execute_priv` = \'N\'';
2119 if (PMA_MYSQL_INT_VERSION >= 50106) {
2120 $list_of_privileges .=
2121 ', `Event_priv`, '
2122 . '`Trigger_priv`';
2123 $list_of_compared_privileges .=
2124 ' AND `Event_priv` = \'N\''
2125 . ' AND `Trigger_priv` = \'N\'';
2128 $sql_query =
2129 '(SELECT ' . $list_of_privileges . ', `Db`'
2130 .' FROM `mysql`.`db`'
2131 .' WHERE \'' . PMA_sqlAddslashes($checkprivs) . "'"
2132 .' LIKE `Db`'
2133 .' AND NOT (' . $list_of_compared_privileges. ')) '
2134 .'UNION '
2135 .'(SELECT ' . $list_of_privileges . ', \'*\' AS `Db`'
2136 .' FROM `mysql`.`user` '
2137 .' WHERE NOT (' . $list_of_compared_privileges . ')) '
2138 .' ORDER BY `User` ASC,'
2139 .' `Host` ASC,'
2140 .' `Db` ASC;';
2141 $res = PMA_DBI_query($sql_query);
2142 $row = PMA_DBI_fetch_assoc($res);
2143 if ($row) {
2144 $found = TRUE;
2147 if ($found) {
2148 while (TRUE) {
2149 // prepare the current user
2150 $current_privileges = array();
2151 $current_user = $row['User'];
2152 $current_host = $row['Host'];
2153 while ($row && $current_user == $row['User'] && $current_host == $row['Host']) {
2154 $current_privileges[] = $row;
2155 $row = PMA_DBI_fetch_assoc($res);
2157 echo ' <tr class="' . ($odd_row ? 'odd' : 'even') . '">' . "\n"
2158 . ' <td';
2159 if (count($current_privileges) > 1) {
2160 echo ' rowspan="' . count($current_privileges) . '"';
2162 echo '>' . (empty($current_user) ? '<span style="color: #FF0000">' . __('Any') . '</span>' : htmlspecialchars($current_user)) . "\n"
2163 . ' </td>' . "\n"
2164 . ' <td';
2165 if (count($current_privileges) > 1) {
2166 echo ' rowspan="' . count($current_privileges) . '"';
2168 echo '>' . htmlspecialchars($current_host) . '</td>' . "\n";
2169 foreach ($current_privileges as $current) {
2170 echo ' <td>' . "\n"
2171 . ' ';
2172 if (!isset($current['Db']) || $current['Db'] == '*') {
2173 echo __('global');
2174 } elseif ($current['Db'] == PMA_escape_mysql_wildcards($checkprivs)) {
2175 echo __('database-specific');
2176 } else {
2177 echo __('wildcard'), ': <tt>' . htmlspecialchars($current['Db']) . '</tt>';
2179 echo "\n"
2180 . ' </td>' . "\n"
2181 . ' <td>' . "\n"
2182 . ' <tt>' . "\n"
2183 . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($current, TRUE)) . "\n"
2184 . ' </tt>' . "\n"
2185 . ' </td>' . "\n"
2186 . ' <td>' . "\n"
2187 . ' ' . ($current['Grant_priv'] == 'Y' ? __('Yes') : __('No')) . "\n"
2188 . ' </td>' . "\n"
2189 . ' <td>' . "\n";
2190 printf($link_edit, urlencode($current_user),
2191 urlencode($current_host),
2192 urlencode(! isset($current['Db']) || $current['Db'] == '*' ? '' : $current['Db']),
2193 '');
2194 echo '</td>' . "\n"
2195 . ' </tr>' . "\n";
2197 if (empty($row) && empty($row1) && empty($row2)) {
2198 break;
2200 $odd_row = ! $odd_row;
2202 } else {
2203 echo ' <tr class="odd">' . "\n"
2204 . ' <td colspan="6">' . "\n"
2205 . ' ' . __('No user found.') . "\n"
2206 . ' </td>' . "\n"
2207 . ' </tr>' . "\n";
2209 echo '</tbody>' . "\n"
2210 . '</table>' . "\n";
2212 // Offer to create a new user for the current database
2213 echo '<fieldset id="fieldset_add_user">' . "\n"
2214 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;adduser=1&amp;dbname=' . $checkprivs .'">' . "\n"
2215 . PMA_getIcon('b_usradd.png')
2216 . ' ' . __('Add a new User') . '</a>' . "\n"
2217 . '</fieldset>' . "\n";
2219 } // end if (empty($_REQUEST['adduser']) && empty($checkprivs)) ... elseif ... else ...
2223 * Displays the footer
2225 echo "\n\n";
2226 require_once './libraries/footer.inc.php';