Merge pull request #431 from xmujay/0609_monitor
[phpmyadmin/aamir.git] / libraries / server_privileges.lib.php
blob48e98c19b6d3a28f8278eb36bb75492a16e91d06
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * set of functions with the Privileges section in pma
6 * @package PhpMyAdmin
7 */
9 if (! defined('PHPMYADMIN')) {
10 exit;
12 /**
13 * Escapes wildcard in a database+table specification
14 * before using it in a GRANT statement.
16 * Escaping a wildcard character in a GRANT is only accepted at the global
17 * or database level, not at table level; this is why I remove
18 * the escaping character. Internally, in mysql.tables_priv.Db there are
19 * no escaping (for example test_db) but in mysql.db you'll see test\_db
20 * for a db-specific privilege.
22 * @param string $dbname Database name
23 * @param string $tablename Table name
25 * @return string the escaped (if necessary) database.table
27 function PMA_wildcardEscapeForGrant($dbname, $tablename)
29 if (! strlen($dbname)) {
30 $db_and_table = '*.*';
31 } else {
32 if (strlen($tablename)) {
33 $db_and_table = PMA_Util::backquote(
34 PMA_Util::unescapeMysqlWildcards($dbname)
36 . '.' . PMA_Util::backquote($tablename);
37 } else {
38 $db_and_table = PMA_Util::backquote($dbname) . '.*';
41 return $db_and_table;
44 /**
45 * Generates a condition on the user name
47 * @param string $initial the user's initial
49 * @return string the generated condition
51 function PMA_rangeOfUsers($initial = '')
53 // strtolower() is used because the User field
54 // might be BINARY, so LIKE would be case sensitive
55 if (! empty($initial)) {
56 $ret = " WHERE `User` LIKE '"
57 . PMA_Util::sqlAddSlashes($initial, true) . "%'"
58 . " OR `User` LIKE '"
59 . PMA_Util::sqlAddSlashes(strtolower($initial), true) . "%'";
60 } else {
61 $ret = '';
63 return $ret;
64 } // end function
66 /**
67 * Extracts the privilege information of a priv table row
69 * @param array $row the row
70 * @param boolean $enableHTML add <dfn> tag with tooltips
72 * @global resource $user_link the database connection
74 * @return array
76 function PMA_extractPrivInfo($row = '', $enableHTML = false)
78 $grants = PMA_getGrantsArray();
80 if (! empty($row) && isset($row['Table_priv'])) {
81 $row1 = $GLOBALS['dbi']->fetchSingleRow(
82 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
83 'ASSOC', $GLOBALS['userlink']
85 $av_grants = explode(
86 '\',\'',
87 substr($row1['Type'], 5, strlen($row1['Type']) - 7)
89 unset($row1);
90 $users_grants = explode(',', $row['Table_priv']);
91 foreach ($av_grants as $current_grant) {
92 $row[$current_grant . '_priv']
93 = in_array($current_grant, $users_grants) ? 'Y' : 'N';
95 unset($current_grant);
98 $privs = array();
99 $allPrivileges = true;
100 foreach ($grants as $current_grant) {
101 if ((! empty($row) && isset($row[$current_grant[0]]))
102 || (empty($row) && isset($GLOBALS[$current_grant[0]]))
104 if ((! empty($row) && $row[$current_grant[0]] == 'Y')
105 || (empty($row)
106 && ($GLOBALS[$current_grant[0]] == 'Y'
107 || (is_array($GLOBALS[$current_grant[0]])
108 && count($GLOBALS[$current_grant[0]]) == $_REQUEST['column_count']
109 && empty($GLOBALS[$current_grant[0] . '_none']))))
111 if ($enableHTML) {
112 $privs[] = '<dfn title="' . $current_grant[2] . '">'
113 . $current_grant[1] . '</dfn>';
114 } else {
115 $privs[] = $current_grant[1];
117 } elseif (! empty($GLOBALS[$current_grant[0]])
118 && is_array($GLOBALS[$current_grant[0]])
119 && empty($GLOBALS[$current_grant[0] . '_none'])) {
120 if ($enableHTML) {
121 $priv_string = '<dfn title="' . $current_grant[2] . '">'
122 . $current_grant[1] . '</dfn>';
123 } else {
124 $priv_string = $current_grant[1];
126 $privs[] = $priv_string . ' (`'
127 . join('`, `', $GLOBALS[$current_grant[0]]) . '`)';
128 } else {
129 $allPrivileges = false;
133 if (empty($privs)) {
134 if ($enableHTML) {
135 $privs[] = '<dfn title="' . __('No privileges.') . '">USAGE</dfn>';
136 } else {
137 $privs[] = 'USAGE';
139 } elseif ($allPrivileges
140 && (! isset($_POST['grant_count'])
141 || count($privs) == $_POST['grant_count'])
143 if ($enableHTML) {
144 $privs = array('<dfn title="'
145 . __('Includes all privileges except GRANT.')
146 . '">ALL PRIVILEGES</dfn>'
148 } else {
149 $privs = array('ALL PRIVILEGES');
152 return $privs;
153 } // end of the 'PMA_extractPrivInfo()' function
156 * Get the grants array which contains all the privilege types
157 * and relevent grant messages
159 * @return array
161 function PMA_getGrantsArray()
163 return array(
164 array(
165 'Select_priv',
166 'SELECT',
167 __('Allows reading data.')),
168 array(
169 'Insert_priv',
170 'INSERT',
171 __('Allows inserting and replacing data.')),
172 array(
173 'Update_priv',
174 'UPDATE',
175 __('Allows changing data.')),
176 array(
177 'Delete_priv',
178 'DELETE',
179 __('Allows deleting data.')),
180 array(
181 'Create_priv',
182 'CREATE',
183 __('Allows creating new databases and tables.')),
184 array(
185 'Drop_priv',
186 'DROP',
187 __('Allows dropping databases and tables.')),
188 array(
189 'Reload_priv',
190 'RELOAD',
191 __('Allows reloading server settings and flushing the server\'s caches.')),
192 array(
193 'Shutdown_priv',
194 'SHUTDOWN',
195 __('Allows shutting down the server.')),
196 array(
197 'Process_priv',
198 'PROCESS',
199 __('Allows viewing processes of all users')),
200 array(
201 'File_priv',
202 'FILE',
203 __('Allows importing data from and exporting data into files.')),
204 array(
205 'References_priv',
206 'REFERENCES',
207 __('Has no effect in this MySQL version.')),
208 array(
209 'Index_priv',
210 'INDEX',
211 __('Allows creating and dropping indexes.')),
212 array(
213 'Alter_priv',
214 'ALTER',
215 __('Allows altering the structure of existing tables.')),
216 array(
217 'Show_db_priv',
218 'SHOW DATABASES',
219 __('Gives access to the complete list of databases.')),
220 array(
221 'Super_priv',
222 'SUPER',
223 __('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.')),
224 array(
225 'Create_tmp_table_priv',
226 'CREATE TEMPORARY TABLES',
227 __('Allows creating temporary tables.')),
228 array(
229 'Lock_tables_priv',
230 'LOCK TABLES',
231 __('Allows locking tables for the current thread.')),
232 array(
233 'Repl_slave_priv',
234 'REPLICATION SLAVE',
235 __('Needed for the replication slaves.')),
236 array(
237 'Repl_client_priv',
238 'REPLICATION CLIENT',
239 __('Allows the user to ask where the slaves / masters are.')),
240 array(
241 'Create_view_priv',
242 'CREATE VIEW',
243 __('Allows creating new views.')),
244 array(
245 'Event_priv',
246 'EVENT',
247 __('Allows to set up events for the event scheduler')),
248 array(
249 'Trigger_priv',
250 'TRIGGER',
251 __('Allows creating and dropping triggers')),
252 // for table privs:
253 array(
254 'Create View_priv',
255 'CREATE VIEW',
256 __('Allows creating new views.')),
257 array(
258 'Show_view_priv',
259 'SHOW VIEW',
260 __('Allows performing SHOW CREATE VIEW queries.')),
261 // for table privs:
262 array(
263 'Show view_priv',
264 'SHOW VIEW',
265 __('Allows performing SHOW CREATE VIEW queries.')),
266 array(
267 'Create_routine_priv',
268 'CREATE ROUTINE',
269 __('Allows creating stored routines.')),
270 array(
271 'Alter_routine_priv',
272 'ALTER ROUTINE',
273 __('Allows altering and dropping stored routines.')),
274 array(
275 'Create_user_priv',
276 'CREATE USER',
277 __('Allows creating, dropping and renaming user accounts.')),
278 array(
279 'Execute_priv',
280 'EXECUTE',
281 __('Allows executing stored routines.')),
286 * Displays on which column(s) a table-specific privilege is granted
288 * @param array $columns columns array
289 * @param array $row first row from result or boolean false
290 * @param string $name_for_select privilege types - Select_priv, Insert_priv
291 * Update_priv, References_priv
292 * @param string $priv_for_header privilege for header
293 * @param string $name privilege name: insert, select, update, references
294 * @param string $name_for_dfn name for dfn
295 * @param string $name_for_current name for current
297 * @return $html_output html snippet
299 function PMA_getHtmlForDisplayColumnPrivileges($columns, $row, $name_for_select,
300 $priv_for_header, $name, $name_for_dfn, $name_for_current
302 $html_output = '<div class="item" id="div_item_' . $name . '">' . "\n"
303 . '<label for="select_' . $name . '_priv">' . "\n"
304 . '<code><dfn title="' . $name_for_dfn . '">'
305 . $priv_for_header . '</dfn></code>' . "\n"
306 . '</label><br />' . "\n"
307 . '<select id="select_' . $name . '_priv" name="'
308 . $name_for_select . '[]" multiple="multiple" size="8">' . "\n";
310 foreach ($columns as $current_column => $current_column_privileges) {
311 $html_output .= '<option '
312 . 'value="' . htmlspecialchars($current_column) . '"';
313 if ($row[$name_for_select] == 'Y'
314 || $current_column_privileges[$name_for_current]
316 $html_output .= ' selected="selected"';
318 $html_output .= '>'
319 . htmlspecialchars($current_column) . '</option>' . "\n";
322 $html_output .= '</select>' . "\n"
323 . '<i>' . __('Or') . '</i>' . "\n"
324 . '<label for="checkbox_' . $name_for_select
325 . '_none"><input type="checkbox"'
326 . ' name="' . $name_for_select . '_none" id="checkbox_'
327 . $name_for_select . '_none" title="'
328 . _pgettext('None privileges', 'None') . '" />'
329 . _pgettext('None privileges', 'None') . '</label>' . "\n"
330 . '</div>' . "\n";
331 return $html_output;
332 } // end function
335 * Get sql query for display privileges table
337 * @param string $db the database
338 * @param string $table the table
339 * @param string $username username for database connection
340 * @param string $hostname hostname for database connection
342 * @return string sql query
344 function PMA_getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname)
346 if ($db == '*') {
347 return "SELECT * FROM `mysql`.`user`"
348 ." WHERE `User` = '" . PMA_Util::sqlAddSlashes($username) . "'"
349 ." AND `Host` = '" . PMA_Util::sqlAddSlashes($hostname) . "';";
350 } elseif ($table == '*') {
351 return "SELECT * FROM `mysql`.`db`"
352 ." WHERE `User` = '" . PMA_Util::sqlAddSlashes($username) . "'"
353 ." AND `Host` = '" . PMA_Util::sqlAddSlashes($hostname) . "'"
354 ." AND '" . PMA_Util::unescapeMysqlWildcards($db) . "'"
355 ." LIKE `Db`;";
357 return "SELECT `Table_priv`"
358 ." FROM `mysql`.`tables_priv`"
359 ." WHERE `User` = '" . PMA_Util::sqlAddSlashes($username) . "'"
360 ." AND `Host` = '" . PMA_Util::sqlAddSlashes($hostname) . "'"
361 ." AND `Db` = '" . PMA_Util::unescapeMysqlWildcards($db) . "'"
362 ." AND `Table_name` = '" . PMA_Util::sqlAddSlashes($table) . "';";
365 * Displays the privileges form table
367 * @param string $db the database
368 * @param string $table the table
369 * @param boolean $submit wheather to display the submit button or not
371 * @global array $cfg the phpMyAdmin configuration
372 * @global ressource $user_link the database connection
374 * @return string html snippet
376 function PMA_getHtmlToDisplayPrivilegesTable($db = '*',
377 $table = '*', $submit = true
379 $html_output = '';
381 if ($db == '*') {
382 $table = '*';
385 if (isset($GLOBALS['username'])) {
386 $username = $GLOBALS['username'];
387 $hostname = $GLOBALS['hostname'];
388 $sql_query = PMA_getSqlQueryForDisplayPrivTable(
389 $db, $table, $username, $hostname
391 $row = $GLOBALS['dbi']->fetchSingleRow($sql_query);
393 if (empty($row)) {
394 if ($table == '*') {
395 if ($db == '*') {
396 $sql_query = 'SHOW COLUMNS FROM `mysql`.`user`;';
397 } elseif ($table == '*') {
398 $sql_query = 'SHOW COLUMNS FROM `mysql`.`db`;';
400 $res = $GLOBALS['dbi']->query($sql_query);
401 while ($row1 = $GLOBALS['dbi']->fetchRow($res)) {
402 if (substr($row1[0], 0, 4) == 'max_') {
403 $row[$row1[0]] = 0;
404 } else {
405 $row[$row1[0]] = 'N';
408 $GLOBALS['dbi']->freeResult($res);
409 } else {
410 $row = array('Table_priv' => '');
413 if (isset($row['Table_priv'])) {
414 $row1 = $GLOBALS['dbi']->fetchSingleRow(
415 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
416 'ASSOC', $GLOBALS['userlink']
418 // note: in MySQL 5.0.3 we get "Create View', 'Show view';
419 // the View for Create is spelled with uppercase V
420 // the view for Show is spelled with lowercase v
421 // and there is a space between the words
423 $av_grants = explode(
424 '\',\'',
425 substr(
426 $row1['Type'],
427 strpos($row1['Type'], '(') + 2,
428 strpos($row1['Type'], ')') - strpos($row1['Type'], '(') - 3
431 unset($row1);
432 $users_grants = explode(',', $row['Table_priv']);
434 foreach ($av_grants as $current_grant) {
435 $row[$current_grant . '_priv']
436 = in_array($current_grant, $users_grants) ? 'Y' : 'N';
438 unset($row['Table_priv'], $current_grant, $av_grants, $users_grants);
440 // get columns
441 $res = $GLOBALS['dbi']->tryQuery(
442 'SHOW COLUMNS FROM '
443 . PMA_Util::backquote(
444 PMA_Util::unescapeMysqlWildcards($db)
446 . '.' . PMA_Util::backquote($table) . ';'
448 $columns = array();
449 if ($res) {
450 while ($row1 = $GLOBALS['dbi']->fetchRow($res)) {
451 $columns[$row1[0]] = array(
452 'Select' => false,
453 'Insert' => false,
454 'Update' => false,
455 'References' => false
458 $GLOBALS['dbi']->freeResult($res);
460 unset($res, $row1);
462 // t a b l e - s p e c i f i c p r i v i l e g e s
463 if (! empty($columns)) {
464 $html_output .= PMA_getHtmlForTableSpecificPrivileges(
465 $username, $hostname, $db, $table, $columns, $row
467 } else {
468 // g l o b a l o r d b - s p e c i f i c
469 $html_output .= PMA_getHtmlForGlobalOrDbSpecificPrivs($db, $table, $row);
471 $html_output .= '</fieldset>' . "\n";
472 if ($submit) {
473 $html_output .= '<fieldset id="fieldset_user_privtable_footer" '
474 . 'class="tblFooters">' . "\n"
475 . '<input type="submit" name="update_privs" '
476 . 'value="' . __('Go') . '" />' . "\n"
477 . '</fieldset>' . "\n";
479 return $html_output;
480 } // end of the 'PMA_displayPrivTable()' function
483 * Get HTML for "Resource limits"
485 * @param array $row first row from result or boolean false
487 * @return string html snippet
489 function PMA_getHtmlForDisplayResourceLimits($row)
491 $html_output = '<fieldset>' . "\n"
492 . '<legend>' . __('Resource limits') . '</legend>' . "\n"
493 . '<p><small>'
494 . '<i>' . __('Note: Setting these options to 0 (zero) removes the limit.')
495 . '</i></small></p>' . "\n";
497 $html_output .= '<div class="item">' . "\n"
498 . '<label for="text_max_questions">'
499 . '<code><dfn title="'
500 . __('Limits the number of queries the user may send to the server per hour.')
501 . '">'
502 . 'MAX QUERIES PER HOUR'
503 . '</dfn></code></label>' . "\n"
504 . '<input type="text" name="max_questions" id="text_max_questions" '
505 . 'value="' . $row['max_questions'] . '" '
506 . 'size="11" maxlength="11" '
507 . 'title="'
508 . __('Limits the number of queries the user may send to the server per hour.')
509 . '" />' . "\n"
510 . '</div>' . "\n";
512 $html_output .= '<div class="item">' . "\n"
513 . '<label for="text_max_updates">'
514 . '<code><dfn title="'
515 . __('Limits the number of commands that change any table or database the user may execute per hour.') . '">'
516 . 'MAX UPDATES PER HOUR'
517 . '</dfn></code></label>' . "\n"
518 . '<input type="text" name="max_updates" id="text_max_updates" '
519 . 'value="' . $row['max_updates'] . '" size="11" maxlength="11" '
520 . 'title="'
521 . __('Limits the number of commands that change any table or database the user may execute per hour.')
522 . '" />' . "\n"
523 . '</div>' . "\n";
525 $html_output .= '<div class="item">' . "\n"
526 . '<label for="text_max_connections">'
527 . '<code><dfn title="'
528 . __('Limits the number of new connections the user may open per hour.') . '">'
529 . 'MAX CONNECTIONS PER HOUR'
530 . '</dfn></code></label>' . "\n"
531 . '<input type="text" name="max_connections" id="text_max_connections" '
532 . 'value="' . $row['max_connections'] . '" size="11" maxlength="11" '
533 . 'title="' . __('Limits the number of new connections the user may open per hour.')
534 . '" />' . "\n"
535 . '</div>' . "\n";
537 $html_output .= '<div class="item">' . "\n"
538 . '<label for="text_max_user_connections">'
539 . '<code><dfn title="'
540 . __('Limits the number of simultaneous connections the user may have.')
541 . '">'
542 . 'MAX USER_CONNECTIONS'
543 . '</dfn></code></label>' . "\n"
544 . '<input type="text" name="max_user_connections" '
545 . 'id="text_max_user_connections" '
546 . 'value="' . $row['max_user_connections'] . '" size="11" maxlength="11" '
547 . 'title="'
548 . __('Limits the number of simultaneous connections the user may have.')
549 . '" />' . "\n"
550 . '</div>' . "\n";
552 $html_output .= '</fieldset>' . "\n";
554 return $html_output;
558 * Get the HTML snippet for table specific privileges
560 * @param string $username username for database connection
561 * @param string $hostname hostname for database connection
562 * @param string $db the database
563 * @param string $table the table
564 * @param boolean $columns columns array
565 * @param $row
567 * @return string $html_output
569 function PMA_getHtmlForTableSpecificPrivileges($username, $hostname, $db,
570 $table, $columns, $row
572 $res = $GLOBALS['dbi']->query(
573 'SELECT `Column_name`, `Column_priv`'
574 .' FROM `mysql`.`columns_priv`'
575 .' WHERE `User`'
576 .' = \'' . PMA_Util::sqlAddSlashes($username) . "'"
577 .' AND `Host`'
578 .' = \'' . PMA_Util::sqlAddSlashes($hostname) . "'"
579 .' AND `Db`'
580 .' = \'' . PMA_Util::sqlAddSlashes(
581 PMA_Util::unescapeMysqlWildcards($db)
582 ) . "'"
583 .' AND `Table_name`'
584 .' = \'' . PMA_Util::sqlAddSlashes($table) . '\';'
587 while ($row1 = $GLOBALS['dbi']->fetchRow($res)) {
588 $row1[1] = explode(',', $row1[1]);
589 foreach ($row1[1] as $current) {
590 $columns[$row1[0]][$current] = true;
593 $GLOBALS['dbi']->freeResult($res);
594 unset($res, $row1, $current);
596 $html_output = '<input type="hidden" name="grant_count" '
597 . 'value="' . count($row) . '" />' . "\n"
598 . '<input type="hidden" name="column_count" '
599 . 'value="' . count($columns) . '" />' . "\n"
600 . '<fieldset id="fieldset_user_priv">' . "\n"
601 . '<legend>' . __('Table-specific privileges')
602 . PMA_Util::showHint(
603 __('Note: MySQL privilege names are expressed in English')
605 . '</legend>' . "\n";
607 // privs that are attached to a specific column
608 $html_output .= PMA_getHtmlForAttachedPrivilegesToTableSpecificColumn(
609 $columns, $row
612 // privs that are not attached to a specific column
613 $html_output .= '<div class="item">' . "\n"
614 . PMA_getHtmlForNotAttachedPrivilegesToTableSpecificColumn($row)
615 . '</div>' . "\n";
617 // for Safari 2.0.2
618 $html_output .= '<div class="clearfloat"></div>' . "\n";
620 return $html_output;
624 * Get HTML snippet for privileges that are attached to a specific column
626 * @param string $columns olumns array
627 * @param array $row first row from result or boolean false
629 * @return string $html_output
631 function PMA_getHtmlForAttachedPrivilegesToTableSpecificColumn($columns, $row)
633 $html_output = PMA_getHtmlForDisplayColumnPrivileges(
634 $columns, $row, 'Select_priv', 'SELECT',
635 'select', __('Allows reading data.'), 'Select'
638 $html_output .= PMA_getHtmlForDisplayColumnPrivileges(
639 $columns, $row, 'Insert_priv', 'INSERT',
640 'insert', __('Allows inserting and replacing data.'), 'Insert'
643 $html_output .= PMA_getHtmlForDisplayColumnPrivileges(
644 $columns, $row, 'Update_priv', 'UPDATE',
645 'update', __('Allows changing data.'), 'Update'
648 $html_output .= PMA_getHtmlForDisplayColumnPrivileges(
649 $columns, $row, 'References_priv', 'REFERENCES', 'references',
650 __('Has no effect in this MySQL version.'), 'References'
652 return $html_output;
656 * Get HTML for privileges that are not attached to a specific column
658 * @param array $row first row from result or boolean false
660 * @return string $html_output
662 function PMA_getHtmlForNotAttachedPrivilegesToTableSpecificColumn($row)
664 $html_output = '';
665 foreach ($row as $current_grant => $current_grant_value) {
666 $grant_type = substr($current_grant, 0, (strlen($current_grant) - 5));
667 if (in_array($grant_type, array('Select', 'Insert', 'Update', 'References'))) {
668 continue;
670 // make a substitution to match the messages variables;
671 // also we must substitute the grant we get, because we can't generate
672 // a form variable containing blanks (those would get changed to
673 // an underscore when receiving the POST)
674 if ($current_grant == 'Create View_priv') {
675 $tmp_current_grant = 'CreateView_priv';
676 $current_grant = 'Create_view_priv';
677 } elseif ($current_grant == 'Show view_priv') {
678 $tmp_current_grant = 'ShowView_priv';
679 $current_grant = 'Show_view_priv';
680 } else {
681 $tmp_current_grant = $current_grant;
684 $html_output .= '<div class="item">' . "\n"
685 . '<input type="checkbox"'
686 . ' name="' . $current_grant . '" id="checkbox_' . $current_grant
687 . '" value="Y" '
688 . ($current_grant_value == 'Y' ? 'checked="checked" ' : '')
689 . 'title="';
691 $html_output .= (isset($GLOBALS[
692 'strPrivDesc' . substr(
693 $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
696 ? $GLOBALS[
697 'strPrivDesc' . substr(
698 $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
701 : $GLOBALS[
702 'strPrivDesc' . substr(
703 $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
704 ) . 'Tbl'
707 . '"/>' . "\n";
709 $html_output .= '<label for="checkbox_' . $current_grant
710 . '"><code><dfn title="'
711 . (isset($GLOBALS[
712 'strPrivDesc' . substr(
713 $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
716 ? $GLOBALS[
717 'strPrivDesc' . substr(
718 $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
721 : $GLOBALS[
722 'strPrivDesc' . substr(
723 $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
724 ) . 'Tbl'
727 . '">'
728 . strtoupper(
729 substr($current_grant, 0, strlen($current_grant) - 5)
731 . '</dfn></code></label>' . "\n"
732 . '</div>' . "\n";
733 } // end foreach ()
734 return $html_output;
738 * Get HTML for global or database specific privileges
740 * @param string $db the database
741 * @param string $table the table
742 * @param string $row first row from result or boolean false
744 * @return string $html_output
746 function PMA_getHtmlForGlobalOrDbSpecificPrivs($db, $table, $row)
748 $privTable_names = array(0 => __('Data'),
749 1 => __('Structure'),
750 2 => __('Administration')
752 $privTable = array();
753 // d a t a
754 $privTable[0] = PMA_getDataPrivilegeTable($db);
756 // s t r u c t u r e
757 $privTable[1] = PMA_getStructurePrivilegeTable($table, $row);
759 // a d m i n i s t r a t i o n
760 $privTable[2] = PMA_getAdministrationPrivilegeTable($db);
762 $html_output = '<input type="hidden" name="grant_count" value="'
763 . (count($privTable[0])
764 + count($privTable[1])
765 + count($privTable[2])
766 - (isset($row['Grant_priv']) ? 1 : 0)
768 . '" />';
769 $html_output .= '<fieldset id="fieldset_user_global_rights"><legend>';
770 if ($db == '*') {
771 $html_output .= __('Global privileges');
772 } else if ($table == '*') {
773 $html_output .= __('Database-specific privileges');
774 } else {
775 $html_output .= __('Table-specific privileges');
777 $html_output .= '<input type="checkbox" id="addUsersForm_checkall" '
778 . 'class="checkall_box" title="' . __('Check All') . '" /> '
779 . '<label for="addUsersForm_checkall">' . __('Check All') . '</label> ';
780 $html_output .= '</legend>';
781 $html_output .= '<p><small><i>'
782 . __('Note: MySQL privilege names are expressed in English')
783 . '</i></small></p>';
785 // Output the Global privilege tables with checkboxes
786 $html_output .= PMA_getHtmlForGlobalPrivTableWithCheckboxes(
787 $privTable, $privTable_names, $row
790 // The "Resource limits" box is not displayed for db-specific privs
791 if ($db == '*') {
792 $html_output .= PMA_getHtmlForDisplayResourceLimits($row);
794 // for Safari 2.0.2
795 $html_output .= '<div class="clearfloat"></div>';
797 return $html_output;
801 * Get data privilege table as an array
803 * @param string $db the database
805 * @return string data privilege table
807 function PMA_getDataPrivilegeTable($db)
809 $data_privTable = array(
810 array('Select', 'SELECT', __('Allows reading data.')),
811 array('Insert', 'INSERT', __('Allows inserting and replacing data.')),
812 array('Update', 'UPDATE', __('Allows changing data.')),
813 array('Delete', 'DELETE', __('Allows deleting data.'))
815 if ($db == '*') {
816 $data_privTable[]
817 = array('File',
818 'FILE',
819 __('Allows importing data from and exporting data into files.')
822 return $data_privTable;
826 * Get structure privilege table as an array
828 * @param string $table the table
829 * @param array $row first row from result or boolean false
831 * @return string structure privilege table
833 function PMA_getStructurePrivilegeTable($table, $row)
835 $structure_privTable = array(
836 array('Create',
837 'CREATE',
838 ($table == '*'
839 ? __('Allows creating new databases and tables.')
840 : __('Allows creating new tables.')
843 array('Alter',
844 'ALTER',
845 __('Allows altering the structure of existing tables.')
847 array('Index', 'INDEX', __('Allows creating and dropping indexes.')),
848 array('Drop',
849 'DROP',
850 ($table == '*'
851 ? __('Allows dropping databases and tables.')
852 : __('Allows dropping tables.')
855 array('Create_tmp_table',
856 'CREATE TEMPORARY TABLES',
857 __('Allows creating temporary tables.')
859 array('Show_view',
860 'SHOW VIEW',
861 __('Allows performing SHOW CREATE VIEW queries.')
863 array('Create_routine',
864 'CREATE ROUTINE',
865 __('Allows creating stored routines.')
867 array('Alter_routine',
868 'ALTER ROUTINE',
869 __('Allows altering and dropping stored routines.')
871 array('Execute', 'EXECUTE', __('Allows executing stored routines.')),
873 // this one is for a db-specific priv: Create_view_priv
874 if (isset($row['Create_view_priv'])) {
875 $structure_privTable[] = array('Create_view',
876 'CREATE VIEW',
877 __('Allows creating new views.')
880 // this one is for a table-specific priv: Create View_priv
881 if (isset($row['Create View_priv'])) {
882 $structure_privTable[] = array('Create View',
883 'CREATE VIEW',
884 __('Allows creating new views.')
887 if (isset($row['Event_priv'])) {
888 // MySQL 5.1.6
889 $structure_privTable[] = array('Event',
890 'EVENT',
891 __('Allows to set up events for the event scheduler')
893 $structure_privTable[] = array('Trigger',
894 'TRIGGER',
895 __('Allows creating and dropping triggers')
898 return $structure_privTable;
902 * Get administration privilege table as an array
904 * @param string $db the table
906 * @return string administration privilege table
908 function PMA_getAdministrationPrivilegeTable($db)
910 $administration_privTable = array(
911 array('Grant',
912 'GRANT',
913 __('Allows adding users and privileges without reloading the privilege tables.')
916 if ($db == '*') {
917 $administration_privTable[] = array('Super',
918 'SUPER',
919 __('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.')
921 $administration_privTable[] = array('Process',
922 'PROCESS',
923 __('Allows viewing processes of all users')
925 $administration_privTable[] = array('Reload',
926 'RELOAD',
927 __('Allows reloading server settings and flushing the server\'s caches.')
929 $administration_privTable[] = array('Shutdown',
930 'SHUTDOWN',
931 __('Allows shutting down the server.')
933 $administration_privTable[] = array('Show_db',
934 'SHOW DATABASES',
935 __('Gives access to the complete list of databases.')
938 $administration_privTable[] = array('Lock_tables',
939 'LOCK TABLES',
940 __('Allows locking tables for the current thread.')
942 $administration_privTable[] = array('References',
943 'REFERENCES',
944 __('Has no effect in this MySQL version.')
946 if ($db == '*') {
947 $administration_privTable[] = array('Repl_client',
948 'REPLICATION CLIENT',
949 __('Allows the user to ask where the slaves / masters are.')
951 $administration_privTable[] = array('Repl_slave',
952 'REPLICATION SLAVE',
953 __('Needed for the replication slaves.')
955 $administration_privTable[] = array('Create_user',
956 'CREATE USER',
957 __('Allows creating, dropping and renaming user accounts.')
960 return $administration_privTable;
964 * Get HTML snippet for global privileges table with check boxes
966 * @param array $privTable privileges table array
967 * @param array $privTable_names names of the privilege tables
968 * (Data, Structure, Administration)
969 * @param array $row first row from result or boolean false
971 * @return string $html_output
973 function PMA_getHtmlForGlobalPrivTableWithCheckboxes(
974 $privTable, $privTable_names, $row
976 $html_output = '';
977 foreach ($privTable as $i => $table) {
978 $html_output .= '<fieldset>' . "\n"
979 . '<legend>' . $privTable_names[$i] . '</legend>' . "\n";
980 foreach ($table as $priv) {
981 $html_output .= '<div class="item">' . "\n"
982 . '<input type="checkbox" class="checkall"'
983 . ' name="' . $priv[0] . '_priv" '
984 . 'id="checkbox_' . $priv[0] . '_priv"'
985 . ' value="Y" title="' . $priv[2] . '"'
986 . (($row[$priv[0] . '_priv'] == 'Y')
987 ? ' checked="checked"'
988 : ''
990 . '/>' . "\n"
991 . '<label for="checkbox_' . $priv[0] . '_priv">'
992 . '<code><dfn title="' . $priv[2] . '">'
993 . $priv[1] . '</dfn></code></label>' . "\n"
994 . '</div>' . "\n";
996 $html_output .= '</fieldset>' . "\n";
998 return $html_output;
1002 * Displays the fields used by the "new user" form as well as the
1003 * "change login information / copy user" form.
1005 * @param string $mode are we creating a new user or are we just
1006 * changing one? (allowed values: 'new', 'change')
1008 * @global array $cfg the phpMyAdmin configuration
1009 * @global ressource $user_link the database connection
1011 * @return string $html_output a HTML snippet
1013 function PMA_getHtmlForDisplayLoginInformationFields($mode = 'new')
1015 list($username_length, $hostname_length) = PMA_getUsernameAndHostnameLength();
1017 if (isset($GLOBALS['username']) && strlen($GLOBALS['username']) === 0) {
1018 $GLOBALS['pred_username'] = 'any';
1020 $html_output = '<fieldset id="fieldset_add_user_login">' . "\n"
1021 . '<legend>' . __('Login Information') . '</legend>' . "\n"
1022 . '<div class="item">' . "\n"
1023 . '<label for="select_pred_username">' . "\n"
1024 . ' ' . __('User name:') . "\n"
1025 . '</label>' . "\n"
1026 . '<span class="options">' . "\n";
1028 $html_output .= '<select name="pred_username" id="select_pred_username" '
1029 . 'title="' . __('User name') . '"' . "\n";
1032 $html_output .= ' onchange="'
1033 . 'if (this.value == \'any\') {'
1034 . ' username.value = \'\'; '
1035 . ' user_exists_warning.style.display = \'none\'; '
1036 . '} else if (this.value == \'userdefined\') {'
1037 . ' username.focus(); username.select(); '
1038 . '}">' . "\n";
1040 $html_output .= '<option value="any"'
1041 . ((isset($GLOBALS['pred_username']) && $GLOBALS['pred_username'] == 'any')
1042 ? ' selected="selected"'
1043 : '') . '>'
1044 . __('Any user')
1045 . '</option>' . "\n";
1047 $html_output .= '<option value="userdefined"'
1048 . ((! isset($GLOBALS['pred_username'])
1049 || $GLOBALS['pred_username'] == 'userdefined'
1051 ? ' selected="selected"'
1052 : '') . '>'
1053 . __('Use text field')
1054 . ':</option>' . "\n";
1056 $html_output .= '</select>' . "\n"
1057 . '</span>' . "\n";
1059 $html_output .= '<input type="text" name="username" class="autofocus"'
1060 . ' maxlength="' . $username_length . '" title="' . __('User name') . '"'
1061 . (empty($GLOBALS['username'])
1062 ? ''
1063 : ' value="' . htmlspecialchars(
1064 isset($GLOBALS['new_username'])
1065 ? $GLOBALS['new_username']
1066 : $GLOBALS['username']
1067 ) . '"'
1069 . ' onchange="pred_username.value = \'userdefined\';" />' . "\n";
1071 $html_output .= '<div id="user_exists_warning"'
1072 . ' name="user_exists_warning" style="display:none;">'
1073 . PMA_Message::notice(
1074 __('An account already exists with the same username but possibly a different hostname. Are you sure you wish to proceed?')
1075 )->getDisplay()
1076 . '</div>';
1077 $html_output .= '</div>';
1079 $html_output .= '<div class="item">' . "\n"
1080 . '<label for="select_pred_hostname">' . "\n"
1081 . ' ' . __('Host:') . "\n"
1082 . '</label>' . "\n";
1084 $html_output .= '<span class="options">' . "\n"
1085 . ' <select name="pred_hostname" id="select_pred_hostname" '
1086 . 'title="' . __('Host') . '"' . "\n";
1087 $_current_user = $GLOBALS['dbi']->fetchValue('SELECT USER();');
1088 if (! empty($_current_user)) {
1089 $thishost = str_replace(
1090 "'",
1092 substr($_current_user, (strrpos($_current_user, '@') + 1))
1094 if ($thishost == 'localhost' || $thishost == '127.0.0.1') {
1095 unset($thishost);
1098 $html_output .= ' onchange="'
1099 . 'if (this.value == \'any\') { '
1100 . ' hostname.value = \'%\'; '
1101 . '} else if (this.value == \'localhost\') { '
1102 . ' hostname.value = \'localhost\'; '
1103 . '} '
1104 . (empty($thishost)
1105 ? ''
1106 : 'else if (this.value == \'thishost\') { '
1107 . ' hostname.value = \'' . addslashes(htmlspecialchars($thishost))
1108 . '\'; '
1109 . '} '
1111 . 'else if (this.value == \'hosttable\') { '
1112 . ' hostname.value = \'\'; '
1113 . '} else if (this.value == \'userdefined\') {'
1114 . ' hostname.focus(); hostname.select(); '
1115 . '}">' . "\n";
1116 unset($_current_user);
1118 // when we start editing a user, $GLOBALS['pred_hostname'] is not defined
1119 if (! isset($GLOBALS['pred_hostname']) && isset($GLOBALS['hostname'])) {
1120 switch (strtolower($GLOBALS['hostname'])) {
1121 case 'localhost':
1122 case '127.0.0.1':
1123 $GLOBALS['pred_hostname'] = 'localhost';
1124 break;
1125 case '%':
1126 $GLOBALS['pred_hostname'] = 'any';
1127 break;
1128 default:
1129 $GLOBALS['pred_hostname'] = 'userdefined';
1130 break;
1133 $html_output .= '<option value="any"'
1134 . ((isset($GLOBALS['pred_hostname'])
1135 && $GLOBALS['pred_hostname'] == 'any'
1137 ? ' selected="selected"'
1138 : '') . '>'
1139 . __('Any host')
1140 . '</option>' . "\n"
1141 . '<option value="localhost"'
1142 . ((isset($GLOBALS['pred_hostname'])
1143 && $GLOBALS['pred_hostname'] == 'localhost'
1145 ? ' selected="selected"'
1146 : '') . '>'
1147 . __('Local')
1148 . '</option>' . "\n";
1149 if (! empty($thishost)) {
1150 $html_output .= '<option value="thishost"'
1151 . ((isset($GLOBALS['pred_hostname'])
1152 && $GLOBALS['pred_hostname'] == 'thishost'
1154 ? ' selected="selected"'
1155 : '') . '>'
1156 . __('This Host')
1157 . '</option>' . "\n";
1159 unset($thishost);
1160 $html_output .= '<option value="hosttable"'
1161 . ((isset($GLOBALS['pred_hostname'])
1162 && $GLOBALS['pred_hostname'] == 'hosttable'
1164 ? ' selected="selected"'
1165 : '') . '>'
1166 . __('Use Host Table')
1167 . '</option>' . "\n";
1169 $html_output .= '<option value="userdefined"'
1170 . ((isset($GLOBALS['pred_hostname'])
1171 && $GLOBALS['pred_hostname'] == 'userdefined'
1173 ? ' selected="selected"'
1174 : '') . '>'
1175 . __('Use text field:') . '</option>' . "\n"
1176 . '</select>' . "\n"
1177 . '</span>' . "\n";
1179 $html_output .= '<input type="text" name="hostname" maxlength="'
1180 . $hostname_length . '" value="'
1181 . htmlspecialchars(isset($GLOBALS['hostname']) ? $GLOBALS['hostname'] : '')
1182 . '" title="' . __('Host')
1183 . '" onchange="pred_hostname.value = \'userdefined\';" />' . "\n"
1184 . PMA_Util::showHint(
1185 __('When Host table is used, this field is ignored and values stored in Host table are used instead.')
1187 . '</div>' . "\n";
1189 $html_output .= '<div class="item">' . "\n"
1190 . '<label for="select_pred_password">' . "\n"
1191 . ' ' . __('Password:') . "\n"
1192 . '</label>' . "\n"
1193 . '<span class="options">' . "\n"
1194 . '<select name="pred_password" id="select_pred_password" title="'
1195 . __('Password') . '"' . "\n";
1197 $html_output .= ' onchange="'
1198 . 'if (this.value == \'none\') { '
1199 . ' pma_pw.value = \'\'; pma_pw2.value = \'\'; '
1200 . '} else if (this.value == \'userdefined\') { '
1201 . ' pma_pw.focus(); pma_pw.select(); '
1202 . '}">' . "\n"
1203 . ($mode == 'change' ? '<option value="keep" selected="selected">'
1204 . __('Do not change the password')
1205 . '</option>' . "\n" : '')
1206 . '<option value="none"';
1208 if (isset($GLOBALS['username']) && $mode != 'change') {
1209 $html_output .= ' selected="selected"';
1211 $html_output .= '>' . __('No Password') . '</option>' . "\n"
1212 . '<option value="userdefined"'
1213 . (isset($GLOBALS['username']) ? '' : ' selected="selected"') . '>'
1214 . __('Use text field')
1215 . ':</option>' . "\n"
1216 . '</select>' . "\n"
1217 . '</span>' . "\n"
1218 . '<input type="password" id="text_pma_pw" name="pma_pw" '
1219 . 'title="' . __('Password') . '" '
1220 . 'onchange="pred_password.value = \'userdefined\';" />' . "\n"
1221 . '</div>' . "\n";
1223 $html_output .= '<div class="item" '
1224 . 'id="div_element_before_generate_password">' . "\n"
1225 . '<label for="text_pma_pw2">' . "\n"
1226 . ' ' . __('Re-type:') . "\n"
1227 . '</label>' . "\n"
1228 . '<span class="options">&nbsp;</span>' . "\n"
1229 . '<input type="password" name="pma_pw2" id="text_pma_pw2" '
1230 . 'title="' . __('Re-type') . '" '
1231 . 'onchange="pred_password.value = \'userdefined\';" />' . "\n"
1232 . '</div>' . "\n"
1233 // Generate password added here via jQuery
1234 . '</fieldset>' . "\n";
1236 return $html_output;
1237 } // end of the 'PMA_displayUserAndHostFields()' function
1240 * Get username and hostname length
1242 * @return array username length and hostname length
1244 function PMA_getUsernameAndHostnameLength()
1246 $fields_info = $GLOBALS['dbi']->getColumns('mysql', 'user', null, true);
1247 $username_length = 16;
1248 $hostname_length = 41;
1249 foreach ($fields_info as $val) {
1250 if ($val['Field'] == 'User') {
1251 strtok($val['Type'], '()');
1252 $value = strtok('()');
1253 if (is_int($value)) {
1254 $username_length = $value;
1256 } elseif ($val['Field'] == 'Host') {
1257 strtok($val['Type'], '()');
1258 $value = strtok('()');
1259 if (is_int($value)) {
1260 $hostname_length = $value;
1264 return array($username_length, $hostname_length);
1268 * Returns all the grants for a certain user on a certain host
1269 * Used in the export privileges for all users section
1271 * @param string $user User name
1272 * @param string $host Host name
1274 * @return string containing all the grants text
1276 function PMA_getGrants($user, $host)
1278 $grants = $GLOBALS['dbi']->fetchResult(
1279 "SHOW GRANTS FOR '"
1280 . PMA_Util::sqlAddSlashes($user) . "'@'"
1281 . PMA_Util::sqlAddSlashes($host) . "'"
1283 $response = '';
1284 foreach ($grants as $one_grant) {
1285 $response .= $one_grant . ";\n\n";
1287 return $response;
1288 } // end of the 'PMA_getGrants()' function
1291 * Update password and get message for password updating
1293 * @param string $err_url error url
1294 * @param string $username username
1295 * @param string $hostname hostname
1297 * @return string $message success or error message after updating password
1299 function PMA_getMessageForUpdatePassword($err_url, $username, $hostname)
1301 // similar logic in user_password.php
1302 $message = '';
1304 if (empty($_REQUEST['nopass'])
1305 && isset($_POST['pma_pw'])
1306 && isset($_POST['pma_pw2'])
1308 if ($_POST['pma_pw'] != $_POST['pma_pw2']) {
1309 $message = PMA_Message::error(__('The passwords aren\'t the same!'));
1310 } elseif (empty($_POST['pma_pw']) || empty($_POST['pma_pw2'])) {
1311 $message = PMA_Message::error(__('The password is empty!'));
1315 // here $nopass could be == 1
1316 if (empty($message)) {
1318 $hashing_function
1319 = (! empty($_REQUEST['pw_hash']) && $_REQUEST['pw_hash'] == 'old'
1320 ? 'OLD_'
1321 : ''
1323 . 'PASSWORD';
1325 // in $sql_query which will be displayed, hide the password
1326 $sql_query = 'SET PASSWORD FOR \''
1327 . PMA_Util::sqlAddSlashes($username)
1328 . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\' = '
1329 . (($_POST['pma_pw'] == '')
1330 ? '\'\''
1331 : $hashing_function . '(\''
1332 . preg_replace('@.@s', '*', $_POST['pma_pw']) . '\')');
1334 $local_query = 'SET PASSWORD FOR \''
1335 . PMA_Util::sqlAddSlashes($username)
1336 . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\' = '
1337 . (($_POST['pma_pw'] == '') ? '\'\'' : $hashing_function
1338 . '(\'' . PMA_Util::sqlAddSlashes($_POST['pma_pw']) . '\')');
1340 $GLOBALS['dbi']->tryQuery($local_query)
1341 or PMA_Util::mysqlDie(
1342 $GLOBALS['dbi']->getError(), $sql_query, false, $err_url
1344 $message = PMA_Message::success(
1345 __('The password for %s was changed successfully.')
1347 $message->addParam(
1348 '\'' . htmlspecialchars($username)
1349 . '\'@\'' . htmlspecialchars($hostname) . '\''
1352 return $message;
1356 * Revokes privileges and get message and SQL query for privileges revokes
1358 * @param string $db_and_table wildcard Escaped database+table specification
1359 * @param string $dbname database name
1360 * @param string $tablename table name
1361 * @param string $username username
1362 * @param string $hostname host name
1364 * @return array ($message, $sql_query)
1366 function PMA_getMessageAndSqlQueryForPrivilegesRevoke($db_and_table, $dbname,
1367 $tablename, $username, $hostname
1369 $db_and_table = PMA_wildcardEscapeForGrant($dbname, $tablename);
1371 $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
1372 . ' FROM \''
1373 . PMA_Util::sqlAddSlashes($username) . '\'@\''
1374 . PMA_Util::sqlAddSlashes($hostname) . '\';';
1376 $sql_query1 = 'REVOKE GRANT OPTION ON ' . $db_and_table
1377 . ' FROM \'' . PMA_Util::sqlAddSlashes($username) . '\'@\''
1378 . PMA_Util::sqlAddSlashes($hostname) . '\';';
1380 $GLOBALS['dbi']->query($sql_query0);
1381 if (! $GLOBALS['dbi']->tryQuery($sql_query1)) {
1382 // this one may fail, too...
1383 $sql_query1 = '';
1385 $sql_query = $sql_query0 . ' ' . $sql_query1;
1386 $message = PMA_Message::success(
1387 __('You have revoked the privileges for %s')
1389 $message->addParam(
1390 '\'' . htmlspecialchars($username)
1391 . '\'@\'' . htmlspecialchars($hostname) . '\''
1394 return array($message, $sql_query);
1398 * Get a WITH clause for 'update privileges' and 'add user'
1400 * @return string $sql_query
1402 function PMA_getWithClauseForAddUserAndUpdatePrivs()
1404 $sql_query = '';
1405 if (isset($_POST['Grant_priv']) && $_POST['Grant_priv'] == 'Y') {
1406 $sql_query .= ' GRANT OPTION';
1408 if (isset($_POST['max_questions'])) {
1409 $max_questions = max(0, (int)$_POST['max_questions']);
1410 $sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
1412 if (isset($_POST['max_connections'])) {
1413 $max_connections = max(0, (int)$_POST['max_connections']);
1414 $sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
1416 if (isset($_POST['max_updates'])) {
1417 $max_updates = max(0, (int)$_POST['max_updates']);
1418 $sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
1420 if (isset($_POST['max_user_connections'])) {
1421 $max_user_connections = max(0, (int)$_POST['max_user_connections']);
1422 $sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
1424 return ((!empty($sql_query)) ? 'WITH' . $sql_query : '');
1428 * Get HTML for addUsersForm, This function call if isset($_REQUEST['adduser'])
1430 * @param string $dbname database name
1432 * @return string HTML for addUserForm
1434 function PMA_getHtmlForAddUser($dbname)
1436 $GLOBALS['url_query'] .= '&amp;adduser=1';
1438 $html_output = '<h2>' . "\n"
1439 . PMA_Util::getIcon('b_usradd.png') . __('Add user') . "\n"
1440 . '</h2>' . "\n"
1441 . '<form name="usersForm" class="ajax" id="addUsersForm"'
1442 . ' action="server_privileges.php" method="post">' . "\n"
1443 . PMA_generate_common_hidden_inputs('', '')
1444 . PMA_getHtmlForDisplayLoginInformationFields('new');
1446 $html_output .= '<fieldset id="fieldset_add_user_database">' . "\n"
1447 . '<legend>' . __('Database for user') . '</legend>' . "\n";
1449 $html_output .= PMA_Util::getCheckbox(
1450 'createdb-1',
1451 __('Create database with same name and grant all privileges'),
1452 false, false
1454 $html_output .= '<br />' . "\n";
1455 $html_output .= PMA_Util::getCheckbox(
1456 'createdb-2',
1457 __('Grant all privileges on wildcard name (username\\_%)'),
1458 false, false
1460 $html_output .= '<br />' . "\n";
1462 if (! empty($dbname) ) {
1463 $html_output .= PMA_Util::getCheckbox(
1464 'createdb-3',
1465 sprintf(__('Grant all privileges on database &quot;%s&quot;'), htmlspecialchars($dbname)),
1466 true,
1467 false
1469 $html_output .= '<input type="hidden" name="dbname" value="'
1470 . htmlspecialchars($dbname) . '" />' . "\n";
1471 $html_output .= '<br />' . "\n";
1474 $html_output .= '</fieldset>' . "\n";
1475 $html_output .= PMA_getHtmlToDisplayPrivilegesTable('*', '*', false);
1476 $html_output .= '<fieldset id="fieldset_add_user_footer" class="tblFooters">'
1477 . "\n"
1478 . '<input type="submit" name="adduser_submit" '
1479 . 'value="' . __('Go') . '" />' . "\n"
1480 . '</fieldset>' . "\n"
1481 . '</form>' . "\n";
1483 return $html_output;
1487 * Get the list of privileges and list of compared privileges as strings
1488 * and return a array that contains both strings
1490 * @return array $list_of_privileges, $list_of_compared_privileges
1492 function PMA_getListOfPrivilegesAndComparedPrivileges()
1494 $list_of_privileges
1495 = '`User`, '
1496 . '`Host`, '
1497 . '`Select_priv`, '
1498 . '`Insert_priv`, '
1499 . '`Update_priv`, '
1500 . '`Delete_priv`, '
1501 . '`Create_priv`, '
1502 . '`Drop_priv`, '
1503 . '`Grant_priv`, '
1504 . '`Index_priv`, '
1505 . '`Alter_priv`, '
1506 . '`References_priv`, '
1507 . '`Create_tmp_table_priv`, '
1508 . '`Lock_tables_priv`, '
1509 . '`Create_view_priv`, '
1510 . '`Show_view_priv`, '
1511 . '`Create_routine_priv`, '
1512 . '`Alter_routine_priv`, '
1513 . '`Execute_priv`';
1515 $list_of_compared_privileges
1516 = '`Select_priv` = \'N\''
1517 . ' AND `Insert_priv` = \'N\''
1518 . ' AND `Update_priv` = \'N\''
1519 . ' AND `Delete_priv` = \'N\''
1520 . ' AND `Create_priv` = \'N\''
1521 . ' AND `Drop_priv` = \'N\''
1522 . ' AND `Grant_priv` = \'N\''
1523 . ' AND `References_priv` = \'N\''
1524 . ' AND `Create_tmp_table_priv` = \'N\''
1525 . ' AND `Lock_tables_priv` = \'N\''
1526 . ' AND `Create_view_priv` = \'N\''
1527 . ' AND `Show_view_priv` = \'N\''
1528 . ' AND `Create_routine_priv` = \'N\''
1529 . ' AND `Alter_routine_priv` = \'N\''
1530 . ' AND `Execute_priv` = \'N\'';
1532 if (PMA_MYSQL_INT_VERSION >= 50106) {
1533 $list_of_privileges .=
1534 ', `Event_priv`, '
1535 . '`Trigger_priv`';
1536 $list_of_compared_privileges .=
1537 ' AND `Event_priv` = \'N\''
1538 . ' AND `Trigger_priv` = \'N\'';
1540 return array($list_of_privileges, $list_of_compared_privileges);
1544 * Get the HTML for user form and check the privileges for a particular database.
1546 * @param string $link_edit standard link for edit
1547 * @param string $conditional_class if ajaxable 'Ajax' otherwise ''
1549 * @return string $html_output
1551 function PMA_getHtmlForSpecificDbPrivileges($link_edit, $conditional_class)
1553 // check the privileges for a particular database.
1554 $html_output = '<form id="usersForm" action="server_privileges.php">'
1555 . '<fieldset>' . "\n";
1556 $html_output .= '<legend>' . "\n"
1557 . PMA_Util::getIcon('b_usrcheck.png')
1558 . ' '
1559 . sprintf(
1560 __('Users having access to &quot;%s&quot;'),
1561 '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?'
1562 . PMA_generate_common_url($_REQUEST['checkprivs']) . '">'
1563 . htmlspecialchars($_REQUEST['checkprivs'])
1564 . '</a>'
1566 . "\n"
1567 . '</legend>' . "\n";
1569 $html_output .= '<table id="dbspecificuserrights" class="data">' . "\n"
1570 . '<thead>' . "\n"
1571 . '<tr><th>' . __('User') . '</th>' . "\n"
1572 . '<th>' . __('Host') . '</th>' . "\n"
1573 . '<th>' . __('Type') . '</th>' . "\n"
1574 . '<th>' . __('Privileges') . '</th>' . "\n"
1575 . '<th>' . __('Grant') . '</th>' . "\n"
1576 . '<th>' . __('Action') . '</th>' . "\n"
1577 . '</tr>' . "\n"
1578 . '</thead>' . "\n";
1579 $odd_row = true;
1580 // now, we build the table...
1581 list($list_of_privileges, $list_of_compared_privileges)
1582 = PMA_getListOfPrivilegesAndComparedPrivileges();
1584 $sql_query = '(SELECT ' . $list_of_privileges . ', `Db`'
1585 .' FROM `mysql`.`db`'
1586 .' WHERE \'' . PMA_Util::sqlAddSlashes($_REQUEST['checkprivs'])
1587 . "'"
1588 .' LIKE `Db`'
1589 .' AND NOT (' . $list_of_compared_privileges. ')) '
1590 .'UNION '
1591 .'(SELECT ' . $list_of_privileges . ', \'*\' AS `Db`'
1592 .' FROM `mysql`.`user` '
1593 .' WHERE NOT (' . $list_of_compared_privileges . ')) '
1594 .' ORDER BY `User` ASC,'
1595 .' `Host` ASC,'
1596 .' `Db` ASC;';
1597 $res = $GLOBALS['dbi']->query($sql_query);
1598 $row = $GLOBALS['dbi']->fetchAssoc($res);
1599 if ($row) {
1600 $found = true;
1602 $html_output .= PMA_getHtmlTableBodyForSpecificDbPrivs(
1603 $found, $row, $odd_row, $link_edit, $res
1605 $html_output .= '</table>'
1606 . '</fieldset>'
1607 . '</form>' . "\n";
1609 if ($GLOBALS['is_ajax_request'] == true && empty($_REQUEST['ajax_page_request'])) {
1610 $message = PMA_Message::success(__('User has been added.'));
1611 $response = PMA_Response::getInstance();
1612 $response->addJSON('message', $message);
1613 $response->addJSON('user_form', $html_output);
1614 exit;
1615 } else {
1616 // Offer to create a new user for the current database
1617 $html_output .= '<fieldset id="fieldset_add_user">' . "\n"
1618 . '<legend>' . _pgettext('Create new user', 'New') . '</legend>' . "\n";
1620 $html_output .= '<a href="server_privileges.php?'
1621 . $GLOBALS['url_query'] . '&amp;adduser=1&amp;'
1622 . 'dbname=' . htmlspecialchars($_REQUEST['checkprivs'])
1623 .'" rel="'
1624 .'checkprivs='.htmlspecialchars($_REQUEST['checkprivs'])
1625 . '&amp;'.$GLOBALS['url_query']
1626 . '" class="'.$conditional_class
1627 .'" name="db_specific">' . "\n"
1628 . PMA_Util::getIcon('b_usradd.png')
1629 . ' ' . __('Add user') . '</a>' . "\n";
1631 $html_output .= '</fieldset>' . "\n";
1633 return $html_output;
1637 * Get HTML snippet for table body of specific database privileges
1639 * @param boolean $found whether user found or not
1640 * @param array $row array of rows from mysql,
1641 * db table with list of privileges
1642 * @param boolean $odd_row whether odd or not
1643 * @param string $link_edit standard link for edit
1644 * @param string $res ran sql query
1646 * @return string $html_output
1648 function PMA_getHtmlTableBodyForSpecificDbPrivs($found, $row, $odd_row,
1649 $link_edit, $res
1651 $html_output = '<tbody>' . "\n";
1652 if ($found) {
1653 while (true) {
1654 // prepare the current user
1655 $current_privileges = array();
1656 $current_user = $row['User'];
1657 $current_host = $row['Host'];
1658 while ($row
1659 && $current_user == $row['User']
1660 && $current_host == $row['Host']
1662 $current_privileges[] = $row;
1663 $row = $GLOBALS['dbi']->fetchAssoc($res);
1665 $html_output .= '<tr '
1666 . 'class="noclick ' . ($odd_row ? 'odd' : 'even')
1667 . '">' . "\n"
1668 . '<td';
1669 if (count($current_privileges) > 1) {
1670 $html_output .= ' rowspan="' . count($current_privileges) . '"';
1672 $html_output .= '>'
1673 . (empty($current_user)
1674 ? '<span style="color: #FF0000">' . __('Any') . '</span>'
1675 : htmlspecialchars($current_user)) . "\n"
1676 . '</td>' . "\n";
1678 $html_output .= '<td';
1679 if (count($current_privileges) > 1) {
1680 $html_output .= ' rowspan="' . count($current_privileges) . '"';
1682 $html_output .= '>'
1683 . htmlspecialchars($current_host) . '</td>' . "\n";
1684 for ($i = 0; $i < count($current_privileges); $i++) {
1685 $current = $current_privileges[$i];
1686 $html_output .= '<td>' . "\n"
1687 . ' ';
1688 if (! isset($current['Db']) || $current['Db'] == '*') {
1689 $html_output .= __('global');
1690 } elseif (
1691 $current['Db'] == PMA_Util::escapeMysqlWildcards(
1692 $_REQUEST['checkprivs']
1695 $html_output .= __('database-specific');
1696 } else {
1697 $html_output .= __('wildcard'). ': '
1698 . '<code>' . htmlspecialchars($current['Db']) . '</code>';
1700 $html_output .= "\n"
1701 . '</td>' . "\n";
1703 $html_output .='<td>' . "\n"
1704 . '<code>' . "\n"
1705 . ''
1706 . join(
1707 ',' . "\n" . ' ',
1708 PMA_extractPrivInfo($current, true)
1710 . "\n"
1711 . '</code>' . "\n"
1712 . '</td>' . "\n";
1714 $html_output .= '<td>' . "\n"
1715 . '' . ($current['Grant_priv'] == 'Y' ? __('Yes') : __('No'))
1716 . "\n"
1717 . '</td>' . "\n"
1718 . '<td>' . "\n";
1719 $html_output .= sprintf(
1720 $link_edit,
1721 urlencode($current_user),
1722 urlencode($current_host),
1723 urlencode(
1724 ! (isset($current['Db']) || $current['Db'] == '*') ? '' : $current['Db']
1728 $html_output .= '</td>' . "\n"
1729 . ' </tr>' . "\n";
1730 if (($i + 1) < count($current_privileges)) {
1731 $html_output .= '<tr '
1732 . 'class="noclick ' . ($odd_row ? 'odd' : 'even') . '">'
1733 . "\n";
1736 if (empty($row)) {
1737 break;
1739 $odd_row = ! $odd_row;
1741 } else {
1742 $html_output .= '<tr class="odd">' . "\n"
1743 . '<td colspan="6">' . "\n"
1744 . ' ' . __('No user found.') . "\n"
1745 . '</td>' . "\n"
1746 . '</tr>' . "\n";
1748 $html_output .= '</tbody>' . "\n";
1750 return $html_output;
1754 * Define some standard links
1755 * $link_edit, $link_revoke, $link_export
1757 * @param string $conditional_class if ajaxable 'Ajax' otherwise ''
1759 * @return array with some standard links
1761 function PMA_getStandardLinks($conditional_class)
1763 $link_edit = '<a class="edit_user_anchor ' . $conditional_class . '"'
1764 . ' href="server_privileges.php?'
1765 . str_replace('%', '%%', $GLOBALS['url_query'])
1766 . '&amp;username=%s'
1767 . '&amp;hostname=%s'
1768 . '&amp;dbname=%s'
1769 . '&amp;tablename=%s">'
1770 . PMA_Util::getIcon('b_usredit.png', __('Edit Privileges'))
1771 . '</a>';
1773 $link_revoke = '<a href='
1774 .'"server_privileges.php?'
1775 . str_replace('%', '%%', $GLOBALS['url_query'])
1776 . '&amp;username=%s'
1777 . '&amp;hostname=%s'
1778 . '&amp;dbname=%s'
1779 . '&amp;tablename=%s'
1780 . '&amp;revokeall=1">'
1781 . PMA_Util::getIcon('b_usrdrop.png', __('Revoke'))
1782 . '</a>';
1784 $link_export = '<a class="export_user_anchor ' . $conditional_class . '"'
1785 . ' href="server_privileges.php?'
1786 . str_replace('%', '%%', $GLOBALS['url_query'])
1787 . '&amp;username=%s'
1788 . '&amp;hostname=%s'
1789 . '&amp;initial=%s'
1790 . '&amp;export=1">'
1791 . PMA_Util::getIcon('b_tblexport.png', __('Export'))
1792 . '</a>';
1794 return array($link_edit, $link_revoke, $link_export);
1798 * This function return the extra data array for the ajax behavior
1800 * @param string $password password
1801 * @param string $link_export export link
1802 * @param string $sql_query sql query
1803 * @param string $link_edit standard link for edit
1804 * @param string $hostname hostname
1805 * @param string $username username
1807 * @return array $extra_data
1809 function PMA_getExtraDataForAjaxBehavior($password, $link_export, $sql_query,
1810 $link_edit, $hostname, $username
1812 if (isset($GLOBALS['dbname'])) {
1813 //if (preg_match('/\\\\(?:_|%)/i', $dbname)) {
1814 if (preg_match('/(?<!\\\\)(?:_|%)/i', $GLOBALS['dbname'])) {
1815 $dbname_is_wildcard = true;
1816 } else {
1817 $dbname_is_wildcard = false;
1821 $extra_data = array();
1822 if (strlen($sql_query)) {
1823 $extra_data['sql_query']
1824 = PMA_Util::getMessage(null, $sql_query);
1827 if (isset($_REQUEST['adduser_submit']) || isset($_REQUEST['change_copy'])) {
1829 * generate html on the fly for the new user that was just created.
1831 $new_user_string = '<tr>'."\n"
1832 . '<td> <input type="checkbox" name="selected_usr[]" '
1833 . 'id="checkbox_sel_users_"'
1834 . 'value="'
1835 . htmlspecialchars($username)
1836 . '&amp;#27;' . htmlspecialchars($hostname) . '" />'
1837 . '</td>' . "\n"
1838 . '<td><label for="checkbox_sel_users_">'
1839 . (empty($_REQUEST['username'])
1840 ? '<span style="color: #FF0000">' . __('Any') . '</span>'
1841 : htmlspecialchars($username) ) . '</label></td>' . "\n"
1842 . '<td>' . htmlspecialchars($hostname) . '</td>' . "\n";
1844 $new_user_string .= '<td>';
1846 if (! empty($password) || isset($_POST['pma_pw'])) {
1847 $new_user_string .= __('Yes');
1848 } else {
1849 $new_user_string .= '<span style="color: #FF0000">'
1850 . __('No')
1851 . '</span>';
1854 $new_user_string .= '</td>'."\n";
1855 $new_user_string .= '<td>'
1856 . '<code>' . join(', ', PMA_extractPrivInfo('', true)) . '</code>'
1857 . '</td>'; //Fill in privileges here
1858 $new_user_string .= '<td>';
1860 if ((isset($_POST['Grant_priv']) && $_POST['Grant_priv'] == 'Y')) {
1861 $new_user_string .= __('Yes');
1862 } else {
1863 $new_user_string .= __('No');
1866 $new_user_string .='</td>';
1868 $new_user_string .= '<td>'
1869 . sprintf(
1870 $link_edit,
1871 urlencode($username),
1872 urlencode($hostname),
1876 . '</td>' . "\n";
1877 $new_user_string .= '<td>'
1878 . sprintf(
1879 $link_export,
1880 urlencode($username),
1881 urlencode($hostname),
1882 (isset($_GET['initial']) ? $_GET['initial'] : '')
1884 . '</td>' . "\n";
1886 $new_user_string .= '</tr>';
1888 $extra_data['new_user_string'] = $new_user_string;
1891 * Generate the string for this alphabet's initial, to update the user
1892 * pagination
1894 $new_user_initial = strtoupper(substr($username, 0, 1));
1895 $new_user_initial_string = '<a href="server_privileges.php?'
1896 . $GLOBALS['url_query'] . '&initial=' . $new_user_initial .'">'
1897 . $new_user_initial . '</a>';
1898 $extra_data['new_user_initial'] = $new_user_initial;
1899 $extra_data['new_user_initial_string'] = $new_user_initial_string;
1902 if (isset($_POST['update_privs'])) {
1903 $extra_data['db_specific_privs'] = false;
1904 $extra_data['db_wildcard_privs'] = false;
1905 if (isset($dbname_is_wildcard)) {
1906 $extra_data['db_specific_privs'] = ! $dbname_is_wildcard;
1907 $extra_data['db_wildcard_privs'] = $dbname_is_wildcard;
1909 $new_privileges = join(', ', PMA_extractPrivInfo('', true));
1911 $extra_data['new_privileges'] = $new_privileges;
1914 if (isset($_REQUEST['validate_username'])) {
1915 $sql_query = "SELECT * FROM `mysql`.`user` WHERE `User` = '"
1916 . $_REQUEST['username'] . "';";
1917 $res = $GLOBALS['dbi']->query($sql_query);
1918 $row = $GLOBALS['dbi']->fetchRow($res);
1919 if (empty($row)) {
1920 $extra_data['user_exists'] = false;
1921 } else {
1922 $extra_data['user_exists'] = true;
1926 return $extra_data;
1930 * Get the HTML snippet for change user login information
1932 * @param string $username username
1933 * @param string $hostname host name
1935 * @return string HTML snippet
1937 function PMA_getChangeLoginInformationHtmlForm($username, $hostname)
1939 $choices = array(
1940 '4' => __('… keep the old one.'),
1941 '1' => __('… delete the old one from the user tables.'),
1942 '2' => __('… revoke all active privileges from the old one and delete it afterwards.'),
1943 '3' => __('… delete the old one from the user tables and reload the privileges afterwards.'));
1945 $class = ' ajax';
1946 $html_output = '<form action="server_privileges.php" '
1947 . 'method="post" class="copyUserForm' . $class .'">' . "\n"
1948 . PMA_generate_common_hidden_inputs('', '')
1949 . '<input type="hidden" name="old_username" '
1950 . 'value="' . htmlspecialchars($username) . '" />' . "\n"
1951 . '<input type="hidden" name="old_hostname" '
1952 . 'value="' . htmlspecialchars($hostname) . '" />' . "\n"
1953 . '<fieldset id="fieldset_change_copy_user">' . "\n"
1954 . '<legend>' . __('Change Login Information / Copy User')
1955 . '</legend>' . "\n"
1956 . PMA_getHtmlForDisplayLoginInformationFields('change');
1958 $html_output .= '<fieldset id="fieldset_mode">' . "\n"
1959 . ' <legend>'
1960 . __('Create a new user with the same privileges and …')
1961 . '</legend>' . "\n";
1962 $html_output .= PMA_Util::getRadioFields(
1963 'mode', $choices, '4', true
1965 $html_output .= '</fieldset>' . "\n"
1966 . '</fieldset>' . "\n";
1968 $html_output .= '<fieldset id="fieldset_change_copy_user_footer" '
1969 . 'class="tblFooters">' . "\n"
1970 . '<input type="submit" name="change_copy" '
1971 . 'value="' . __('Go') . '" />' . "\n"
1972 . '</fieldset>' . "\n"
1973 . '</form>' . "\n";
1975 return $html_output;
1979 * Provide a line with links to the relevant database and table
1981 * @param string $url_dbname url database name that urlencode() string
1982 * @param string $dbname database name
1983 * @param string $tablename table name
1985 * @return string HTML snippet
1987 function PMA_getLinkToDbAndTable($url_dbname, $dbname, $tablename)
1989 $html_output = '[ ' . __('Database')
1990 . ' <a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?'
1991 . $GLOBALS['url_query'] . '&amp;db=' . $url_dbname . '&amp;reload=1">'
1992 . htmlspecialchars($dbname) . ': '
1993 . PMA_Util::getTitleForTarget(
1994 $GLOBALS['cfg']['DefaultTabDatabase']
1996 . "</a> ]\n";
1998 if (strlen($tablename)) {
1999 $html_output .= ' [ ' . __('Table') . ' <a href="'
2000 . $GLOBALS['cfg']['DefaultTabTable'] . '?' . $GLOBALS['url_query']
2001 . '&amp;db=' . $url_dbname
2002 . '&amp;table=' . htmlspecialchars(urlencode($tablename))
2003 . '&amp;reload=1">' . htmlspecialchars($tablename) . ': '
2004 . PMA_Util::getTitleForTarget(
2005 $GLOBALS['cfg']['DefaultTabTable']
2007 . "</a> ]\n";
2009 return $html_output;
2013 * no db name given, so we want all privs for the given user
2014 * db name was given, so we want all user specific rights for this db
2015 * So this function returns user rights as an array
2017 * @param array $tables tables
2018 * @param string $user_host_condition a where clause that containd user's host condition
2019 * @param string $dbname database name
2021 * @return array $db_rights database rights
2023 function PMA_getUserSpecificRights($tables, $user_host_condition, $dbname)
2025 if (! strlen($dbname)) {
2026 $tables_to_search_for_users = array(
2027 'tables_priv', 'columns_priv',
2029 $dbOrTableName = 'Db';
2030 } else {
2031 $user_host_condition .=
2032 ' AND `Db`'
2033 .' LIKE \''
2034 . PMA_Util::sqlAddSlashes($dbname, true) . "'";
2035 $tables_to_search_for_users = array('columns_priv',);
2036 $dbOrTableName = 'Table_name';
2039 $db_rights_sqls = array();
2040 foreach ($tables_to_search_for_users as $table_search_in) {
2041 if (in_array($table_search_in, $tables)) {
2042 $db_rights_sqls[] = '
2043 SELECT DISTINCT `' . $dbOrTableName .'`
2044 FROM `mysql`.' . PMA_Util::backquote($table_search_in)
2045 . $user_host_condition;
2049 $user_defaults = array(
2050 $dbOrTableName => '',
2051 'Grant_priv' => 'N',
2052 'privs' => array('USAGE'),
2053 'Column_priv' => true,
2056 // for the rights
2057 $db_rights = array();
2059 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
2060 .' ORDER BY `' . $dbOrTableName .'` ASC';
2062 $db_rights_result = $GLOBALS['dbi']->query($db_rights_sql);
2064 while ($db_rights_row = $GLOBALS['dbi']->fetchAssoc($db_rights_result)) {
2065 $db_rights_row = array_merge($user_defaults, $db_rights_row);
2066 if (! strlen($dbname)) {
2067 // only Db names in the table `mysql`.`db` uses wildcards
2068 // as we are in the db specific rights display we want
2069 // all db names escaped, also from other sources
2070 $db_rights_row['Db'] = PMA_Util::escapeMysqlWildcards(
2071 $db_rights_row['Db']
2074 $db_rights[$db_rights_row[$dbOrTableName]] = $db_rights_row;
2077 $GLOBALS['dbi']->freeResult($db_rights_result);
2079 if (! strlen($dbname)) {
2080 $sql_query = 'SELECT * FROM `mysql`.`db`'
2081 . $user_host_condition . ' ORDER BY `Db` ASC';
2082 } else {
2083 $sql_query = 'SELECT `Table_name`,'
2084 .' `Table_priv`,'
2085 .' IF(`Column_priv` = _latin1 \'\', 0, 1)'
2086 .' AS \'Column_priv\''
2087 .' FROM `mysql`.`tables_priv`'
2088 . $user_host_condition
2089 .' ORDER BY `Table_name` ASC;';
2092 $result = $GLOBALS['dbi']->query($sql_query);
2093 $sql_query = '';
2095 while ($row = $GLOBALS['dbi']->fetchAssoc($result)) {
2096 if (isset($db_rights[$row[$dbOrTableName]])) {
2097 $db_rights[$row[$dbOrTableName]]
2098 = array_merge($db_rights[$row[$dbOrTableName]], $row);
2099 } else {
2100 $db_rights[$row[$dbOrTableName]] = $row;
2102 if (! strlen($dbname)) {
2103 // there are db specific rights for this user
2104 // so we can drop this db rights
2105 $db_rights[$row['Db']]['can_delete'] = true;
2108 $GLOBALS['dbi']->freeResult($result);
2109 return $db_rights;
2113 * Display user rights in table rows(Table specific or database specific privs)
2115 * @param array $db_rights user's database rights array
2116 * @param string $link_edit standard link to edit privileges
2117 * @param string $dbname database name
2118 * @param string $link_revoke standard link to revoke
2119 * @param string $hostname host name
2120 * @param string $username username
2122 * @return array $found_rows, $html_output
2124 function PMA_getHtmlForDisplayUserRightsInRows($db_rights, $link_edit, $dbname,
2125 $link_revoke, $hostname, $username
2127 $html_output = '';
2128 $found_rows = array();
2129 // display rows
2130 if (count($db_rights) < 1) {
2131 $html_output .= '<tr class="odd">' . "\n"
2132 . '<td colspan="6"><center><i>' . __('None') . '</i></center></td>' . "\n"
2133 . '</tr>' . "\n";
2134 } else {
2135 $odd_row = true;
2136 //while ($row = $GLOBALS['dbi']->fetchAssoc($res)) {
2137 foreach ($db_rights as $row) {
2138 $found_rows[] = (! strlen($dbname)) ? $row['Db'] : $row['Table_name'];
2140 $html_output .= '<tr class="' . ($odd_row ? 'odd' : 'even') . '">' . "\n"
2141 . '<td>'
2142 . htmlspecialchars(
2143 (! strlen($dbname)) ? $row['Db'] : $row['Table_name']
2145 . '</td>' . "\n"
2146 . '<td><code>' . "\n"
2147 . ' '
2148 . join(
2149 ',' . "\n" . ' ',
2150 PMA_extractPrivInfo($row, true)
2151 ) . "\n"
2152 . '</code></td>' . "\n"
2153 . '<td>'
2154 . ((((! strlen($dbname)) && $row['Grant_priv'] == 'Y')
2155 || (strlen($dbname) && in_array('Grant', explode(',', $row['Table_priv']))))
2156 ? __('Yes')
2157 : __('No'))
2158 . '</td>' . "\n"
2159 . '<td>';
2160 if (! empty($row['Table_privs']) || ! empty ($row['Column_priv'])) {
2161 $html_output .= __('Yes');
2162 } else {
2163 $html_output .= __('No');
2165 $html_output .= '</td>' . "\n"
2166 . '<td>';
2167 $html_output .= sprintf(
2168 $link_edit,
2169 htmlspecialchars(urlencode($username)),
2170 urlencode(htmlspecialchars($hostname)),
2171 urlencode(
2172 (! strlen($dbname)) ? $row['Db'] : htmlspecialchars($dbname)
2174 urlencode((! strlen($dbname)) ? '' : $row['Table_name'])
2176 $html_output .= '</td>' . "\n"
2177 . ' <td>';
2178 if (! empty($row['can_delete'])
2179 || isset($row['Table_name'])
2180 && strlen($row['Table_name'])
2182 $html_output .= sprintf(
2183 $link_revoke,
2184 htmlspecialchars(urlencode($username)),
2185 urlencode(htmlspecialchars($hostname)),
2186 urlencode(
2187 (! strlen($dbname)) ? $row['Db'] : htmlspecialchars($dbname)
2189 urlencode((! strlen($dbname)) ? '' : $row['Table_name'])
2192 $html_output .= '</td>' . "\n"
2193 . '</tr>' . "\n";
2194 $odd_row = ! $odd_row;
2195 } // end while
2196 } //end if
2197 return array($found_rows, $html_output);
2201 * Get a HTML table for display user's tabel specific or database specific rights
2203 * @param string $username username
2204 * @param string $hostname host name
2205 * @param string $link_edit standard link to edit privileges
2206 * @param string $link_revoke standard link to revoke
2207 * @param string $dbname database name
2209 * @return array $html_output, $found_rows
2211 function PMA_getTableForDisplayAllTableSpecificRights($username, $hostname
2212 , $link_edit, $link_revoke, $dbname
2214 // table header
2215 $html_output = PMA_generate_common_hidden_inputs('', '')
2216 . '<input type="hidden" name="username" '
2217 . 'value="' . htmlspecialchars($username) . '" />' . "\n"
2218 . '<input type="hidden" name="hostname" '
2219 . 'value="' . htmlspecialchars($hostname) . '" />' . "\n"
2220 . '<fieldset>' . "\n"
2221 . '<legend>'
2222 . (! strlen($dbname)
2223 ? __('Database-specific privileges')
2224 : __('Table-specific privileges')
2226 . '</legend>' . "\n"
2227 . '<table class="data">' . "\n"
2228 . '<thead>' . "\n"
2229 . '<tr><th>'
2230 . (! strlen($dbname) ? __('Database') : __('Table'))
2231 . '</th>' . "\n"
2232 . '<th>' . __('Privileges') . '</th>' . "\n"
2233 . '<th>' . __('Grant') . '</th>' . "\n"
2234 . '<th>'
2235 . (! strlen($dbname)
2236 ? __('Table-specific privileges')
2237 : __('Column-specific privileges')
2239 . '</th>' . "\n"
2240 . '<th colspan="2">' . __('Action') . '</th>' . "\n"
2241 . '</tr>' . "\n"
2242 . '</thead>' . "\n";
2244 $user_host_condition = ' WHERE `User`'
2245 . ' = \'' . PMA_Util::sqlAddSlashes($username) . "'"
2246 . ' AND `Host`'
2247 . ' = \'' . PMA_Util::sqlAddSlashes($hostname) . "'";
2249 // table body
2250 // get data
2252 // we also want privielgs for this user not in table `db` but in other table
2253 $tables = $GLOBALS['dbi']->fetchResult('SHOW TABLES FROM `mysql`;');
2256 * no db name given, so we want all privs for the given user
2257 * db name was given, so we want all user specific rights for this db
2259 $db_rights = PMA_getUserSpecificRights($tables, $user_host_condition, $dbname);
2261 ksort($db_rights);
2263 $html_output .= '<tbody>' . "\n";
2264 // display rows
2265 list ($found_rows, $html_out) = PMA_getHtmlForDisplayUserRightsInRows(
2266 $db_rights, $link_edit, $dbname, $link_revoke, $hostname, $username
2269 $html_output .= $html_out;
2270 $html_output .= '</tbody>' . "\n";
2271 $html_output .='</table>' . "\n";
2273 return array($html_output, $found_rows);
2277 * Get HTML for display select db
2279 * @param array $found_rows isset($dbname)) ? $row['Db'] : $row['Table_name']
2281 * @return string HTML snippet
2283 function PMA_getHtmlForDisplaySelectDbInEditPrivs($found_rows)
2285 $pred_db_array = $GLOBALS['dbi']->fetchResult('SHOW DATABASES;');
2287 $html_output = '<label for="text_dbname">'
2288 . __('Add privileges on the following database:') . '</label>' . "\n";
2289 if (! empty($pred_db_array)) {
2290 $html_output .= '<select name="pred_dbname" class="autosubmit">' . "\n"
2291 . '<option value="" selected="selected">'
2292 . __('Use text field:') . '</option>' . "\n";
2293 foreach ($pred_db_array as $current_db) {
2294 $current_db_show = $current_db;
2295 $current_db = PMA_Util::escapeMysqlWildcards($current_db);
2296 // cannot use array_diff() once, outside of the loop,
2297 // because the list of databases has special characters
2298 // already escaped in $found_rows,
2299 // contrary to the output of SHOW DATABASES
2300 if (empty($found_rows) || ! in_array($current_db, $found_rows)) {
2301 $html_output .= '<option value="' . htmlspecialchars($current_db) . '">'
2302 . htmlspecialchars($current_db_show) . '</option>' . "\n";
2305 $html_output .= '</select>' . "\n";
2307 $html_output .= '<input type="text" id="text_dbname" name="dbname" />' . "\n"
2308 . PMA_Util::showHint(
2309 __('Wildcards % and _ should be escaped with a \ to use them literally')
2311 return $html_output;
2315 * Get HTML for display table in edit privilege
2317 * @param string $dbname database naame
2318 * @param array $found_rows isset($dbname)) ? $row['Db'] : $row['Table_name']
2320 * @return string HTML snippet
2322 function PMA_displayTablesInEditPrivs($dbname, $found_rows)
2324 $html_output = '<input type="hidden" name="dbname"
2325 '. 'value="' . htmlspecialchars($dbname) . '"/>' . "\n";
2326 $html_output .= '<label for="text_tablename">'
2327 . __('Add privileges on the following table:') . '</label>' . "\n";
2329 $result = @$GLOBALS['dbi']->tryQuery(
2330 'SHOW TABLES FROM ' . PMA_Util::backquote(
2331 PMA_Util::unescapeMysqlWildcards($dbname)
2332 ) . ';',
2333 null,
2334 PMA_DatabaseInterface::QUERY_STORE
2337 if ($result) {
2338 $pred_tbl_array = array();
2339 while ($row = $GLOBALS['dbi']->fetchRow($result)) {
2340 if (! isset($found_rows) || ! in_array($row[0], $found_rows)) {
2341 $pred_tbl_array[] = $row[0];
2344 $GLOBALS['dbi']->freeResult($result);
2346 if (! empty($pred_tbl_array)) {
2347 $html_output .= '<select name="pred_tablename" '
2348 . 'class="autosubmit">' . "\n"
2349 . '<option value="" selected="selected">' . __('Use text field')
2350 . ':</option>' . "\n";
2351 foreach ($pred_tbl_array as $current_table) {
2352 $html_output .= '<option '
2353 . 'value="' . htmlspecialchars($current_table) . '">'
2354 . htmlspecialchars($current_table)
2355 . '</option>' . "\n";
2357 $html_output .= '</select>' . "\n";
2360 $html_output .= '<input type="text" id="text_tablename" name="tablename" />'
2361 . "\n";
2363 return $html_output;
2367 * Get HTML for display the users overview
2368 * (if less than 50 users, display them immediately)
2370 * @param array $result ran sql query
2371 * @param array $db_rights user's database rights array
2372 * @param string $link_edit standard link to edit privileges
2373 * @param string $pmaThemeImage a image source link
2374 * @param string $text_dir text directory
2375 * @param string $conditional_class if ajaxable 'Ajax' otherwise ''
2376 * @param string $link_export standard link to export privileges
2378 * @return string HTML snippet
2380 function PMA_getUsersOverview($result, $db_rights, $link_edit, $pmaThemeImage,
2381 $text_dir, $conditional_class, $link_export
2383 while ($row = $GLOBALS['dbi']->fetchAssoc($result)) {
2384 $row['privs'] = PMA_extractPrivInfo($row, true);
2385 $db_rights[$row['User']][$row['Host']] = $row;
2387 @$GLOBALS['dbi']->freeResult($result);
2389 $html_output
2390 = '<form name="usersForm" id="usersForm" action="server_privileges.php" '
2391 . 'method="post">' . "\n"
2392 . PMA_generate_common_hidden_inputs('', '')
2393 . '<table id="tableuserrights" class="data">' . "\n"
2394 . '<thead>' . "\n"
2395 . '<tr><th></th>' . "\n"
2396 . '<th>' . __('User') . '</th>' . "\n"
2397 . '<th>' . __('Host') . '</th>' . "\n"
2398 . '<th>' . __('Password') . '</th>' . "\n"
2399 . '<th>' . __('Global privileges') . ' '
2400 . PMA_Util::showHint(
2401 __('Note: MySQL privilege names are expressed in English')
2403 . '</th>' . "\n"
2404 . '<th>' . __('Grant') . '</th>' . "\n"
2405 . '<th colspan="2">' . __('Action') . '</th>' . "\n"
2406 . '</tr>' . "\n"
2407 . '</thead>' . "\n";
2409 $html_output .= '<tbody>' . "\n";
2410 $html_output .= PMA_getTableBodyForUserRightsTable(
2411 $db_rights, $link_edit, $link_export
2413 $html_output .= '</tbody>'
2414 . '</table>' . "\n";
2416 $html_output .= '<div style="float:left;">'
2417 . '<img class="selectallarrow"'
2418 . ' src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png"'
2419 . ' width="38" height="22"'
2420 . ' alt="' . __('With selected:') . '" />' . "\n"
2421 . '<input type="checkbox" id="usersForm_checkall" class="checkall_box" '
2422 . 'title="' . __('Check All') . '" /> '
2423 . '<label for="usersForm_checkall">' . __('Check All') . '</label> '
2424 . '<i style="margin-left: 2em">' . __('With selected:') . '</i>' . "\n";
2426 $html_output .= PMA_Util::getButtonOrImage(
2427 'submit_mult', 'mult_submit', 'submit_mult_export',
2428 __('Export'), 'b_tblexport.png', 'export'
2430 $html_output .= '<input type="hidden" name="initial" '
2431 . 'value="' . (isset($_GET['initial']) ? $_GET['initial'] : '') . '" />';
2432 $html_output .= '</div>'
2433 . '<div class="clear_both" style="clear:both"></div>';
2435 // add/delete user fieldset
2436 $html_output .= PMA_getFieldsetForAddDeleteUser($conditional_class);
2437 $html_output .= '</form>' . "\n";
2439 return $html_output;
2443 * Get table body for 'tableuserrights' table in userform
2445 * @param array $db_rights user's database rights array
2446 * @param string $link_edit standard link to edit privileges
2447 * @param string $link_export Link for export all users
2449 * @return string HTML snippet
2451 function PMA_getTableBodyForUserRightsTable($db_rights, $link_edit, $link_export)
2453 $odd_row = true;
2454 $index_checkbox = 0;
2455 $html_output = '';
2456 foreach ($db_rights as $user) {
2457 ksort($user);
2458 foreach ($user as $host) {
2459 $index_checkbox++;
2460 $html_output .= '<tr class="' . ($odd_row ? 'odd' : 'even') . '">'
2461 . "\n";
2462 $html_output .= '<td>'
2463 . '<input type="checkbox" class="checkall" name="selected_usr[]" '
2464 . 'id="checkbox_sel_users_'
2465 . $index_checkbox . '" value="'
2466 . htmlspecialchars($host['User'] . '&amp;#27;' . $host['Host'])
2467 . '"'
2468 . ' /></td>' . "\n";
2470 $html_output .= '<td><label '
2471 . 'for="checkbox_sel_users_' . $index_checkbox . '">'
2472 . (empty($host['User'])
2473 ? '<span style="color: #FF0000">' . __('Any') . '</span>'
2474 : htmlspecialchars($host['User'])) . '</label></td>' . "\n"
2475 . '<td>' . htmlspecialchars($host['Host']) . '</td>' . "\n";
2477 $html_output .= '<td>';
2478 switch ($host['Password']) {
2479 case 'Y':
2480 $html_output .= __('Yes');
2481 break;
2482 case 'N':
2483 $html_output .= '<span style="color: #FF0000">' . __('No')
2484 . '</span>';
2485 break;
2486 // this happens if this is a definition not coming from mysql.user
2487 default:
2488 $html_output .= '--'; // in future version, replace by "not present"
2489 break;
2490 } // end switch
2491 $html_output .= '</td>' . "\n";
2493 $html_output .= '<td><code>' . "\n"
2494 . '' . implode(',' . "\n" . ' ', $host['privs']) . "\n"
2495 . '</code></td>' . "\n"
2496 . '<td>'
2497 . ($host['Grant_priv'] == 'Y' ? __('Yes') : __('No'))
2498 . '</td>' . "\n"
2499 . '<td class="center">'
2500 . sprintf(
2501 $link_edit,
2502 urlencode($host['User']),
2503 urlencode($host['Host']),
2507 $html_output .= '</td>';
2509 $html_output .= '<td class="center">';
2510 $html_output .= sprintf(
2511 $link_export,
2512 urlencode($host['User']),
2513 urlencode($host['Host']),
2514 (isset($_GET['initial']) ? $_GET['initial'] : '')
2516 $html_output .= '</td>';
2517 $html_output .= '</tr>';
2518 $odd_row = ! $odd_row;
2521 return $html_output;
2525 * Get HTML fieldset for Add/Delete user
2527 * @param string $conditional_class if ajaxable 'Ajax' otherwise ''
2529 * @return string HTML snippet
2531 function PMA_getFieldsetForAddDeleteUser($conditional_class)
2533 $html_output = '<fieldset id="fieldset_add_user">' . "\n";
2534 $html_output .= '<a href="server_privileges.php?'
2535 . $GLOBALS['url_query'] . '&amp;adduser=1"'
2536 . 'class="' . $conditional_class . '">' . "\n"
2537 . PMA_Util::getIcon('b_usradd.png')
2538 . ' ' . __('Add user') . '</a>' . "\n";
2539 $html_output .= '</fieldset>' . "\n";
2541 $html_output .= '<fieldset id="fieldset_delete_user">'
2542 . '<legend>' . "\n"
2543 . PMA_Util::getIcon('b_usrdrop.png')
2544 . ' ' . __('Remove selected users') . '' . "\n"
2545 . '</legend>' . "\n";
2547 $html_output .= '<input type="hidden" name="mode" value="2" />' . "\n"
2548 . '(' . __('Revoke all active privileges from the users and delete them afterwards.') . ')'
2549 . '<br />' . "\n";
2551 $html_output .= '<input type="checkbox" '
2552 . 'title="' . __('Drop the databases that have the same names as the users.') . '" '
2553 . 'name="drop_users_db" id="checkbox_drop_users_db" />' . "\n";
2555 $html_output .= '<label for="checkbox_drop_users_db" '
2556 . 'title="' . __('Drop the databases that have the same names as the users.') . '">' . "\n"
2557 . ' ' . __('Drop the databases that have the same names as the users.') . "\n"
2558 . '</label>' . "\n"
2559 . '</fieldset>' . "\n";
2561 $html_output .= '<fieldset id="fieldset_delete_user_footer" class="tblFooters">' . "\n";
2562 $html_output .= '<input type="submit" name="delete" '
2563 . 'value="' . __('Go') . '" id="buttonGo" '
2564 . 'class="' . $conditional_class . '"/>' . "\n";
2566 $html_output .= '</fieldset>' . "\n";
2568 return $html_output;
2572 * Get HTML for Displays the initials
2574 * @param array $array_initials array for all initials, even non A-Z
2575 * @param string $conditional_class if ajaxable 'Ajax' otherwise ''
2577 * @return string HTML snippet
2579 function PMA_getHtmlForDisplayTheInitials($array_initials, $conditional_class)
2581 // initialize to false the letters A-Z
2582 for ($letter_counter = 1; $letter_counter < 27; $letter_counter++) {
2583 if (! isset($array_initials[chr($letter_counter + 64)])) {
2584 $array_initials[chr($letter_counter + 64)] = false;
2588 $initials = $GLOBALS['dbi']->tryQuery(
2589 'SELECT DISTINCT UPPER(LEFT(`User`,1)) FROM `user` ORDER BY `User` ASC',
2590 null,
2591 PMA_DatabaseInterface::QUERY_STORE
2593 while (list($tmp_initial) = $GLOBALS['dbi']->fetchRow($initials)) {
2594 $array_initials[$tmp_initial] = true;
2597 // Display the initials, which can be any characters, not
2598 // just letters. For letters A-Z, we add the non-used letters
2599 // as greyed out.
2601 uksort($array_initials, "strnatcasecmp");
2603 $html_output = '<table id="initials_table" <cellspacing="5">'
2604 . '<tr>';
2605 foreach ($array_initials as $tmp_initial => $initial_was_found) {
2606 if (! empty($tmp_initial)) {
2607 if ($initial_was_found) {
2608 $html_output .= '<td>'
2609 . '<a class="' . $conditional_class . '"'
2610 . ' href="server_privileges.php?'
2611 . $GLOBALS['url_query'] . '&amp;'
2612 . 'initial=' . urlencode($tmp_initial) . '">' . $tmp_initial
2613 . '</a>'
2614 . '</td>' . "\n";
2615 } else {
2616 $html_output .= '<td>' . $tmp_initial . '</td>';
2620 $html_output .= '<td>'
2621 . '<a href="server_privileges.php?' . $GLOBALS['url_query']
2622 . '&amp;showall=1" '
2623 . 'class="nowrap">[' . __('Show all') . ']</a></td>' . "\n";
2624 $html_output .= '</tr></table>';
2626 return $html_output;
2630 * Get the database rigths array for Display user overview
2632 * @return array $db_rights database rights array
2634 function PMA_getDbRightsForUserOverview()
2636 // we also want users not in table `user` but in other table
2637 $tables = $GLOBALS['dbi']->fetchResult('SHOW TABLES FROM `mysql`;');
2639 $tables_to_search_for_users = array(
2640 'user', 'db', 'tables_priv', 'columns_priv', 'procs_priv',
2643 $db_rights_sqls = array();
2644 foreach ($tables_to_search_for_users as $table_search_in) {
2645 if (in_array($table_search_in, $tables)) {
2646 $db_rights_sqls[] = 'SELECT DISTINCT `User`, `Host` FROM `mysql`.`'
2647 . $table_search_in . '` '
2648 . (isset($_GET['initial']) ? PMA_rangeOfUsers($_GET['initial']) : '');
2651 $user_defaults = array(
2652 'User' => '',
2653 'Host' => '%',
2654 'Password' => '?',
2655 'Grant_priv' => 'N',
2656 'privs' => array('USAGE'),
2659 // for the rights
2660 $db_rights = array();
2662 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
2663 .' ORDER BY `User` ASC, `Host` ASC';
2665 $db_rights_result = $GLOBALS['dbi']->query($db_rights_sql);
2667 while ($db_rights_row = $GLOBALS['dbi']->fetchAssoc($db_rights_result)) {
2668 $db_rights_row = array_merge($user_defaults, $db_rights_row);
2669 $db_rights[$db_rights_row['User']][$db_rights_row['Host']]
2670 = $db_rights_row;
2672 $GLOBALS['dbi']->freeResult($db_rights_result);
2673 ksort($db_rights);
2675 return $db_rights;
2679 * Delete user and get message and sql query for delete user in privileges
2681 * @param string $queries queries
2683 * @return PMA_message
2685 function PMA_deleteUser($queries)
2687 if (empty($queries)) {
2688 $message = PMA_Message::error(__('No users selected for deleting!'));
2689 } else {
2690 if ($_REQUEST['mode'] == 3) {
2691 $queries[] = '# ' . __('Reloading the privileges') . ' …';
2692 $queries[] = 'FLUSH PRIVILEGES;';
2694 $drop_user_error = '';
2695 foreach ($queries as $sql_query) {
2696 if ($sql_query{0} != '#') {
2697 if (! $GLOBALS['dbi']->tryQuery($sql_query, $GLOBALS['userlink'])) {
2698 $drop_user_error .= $GLOBALS['dbi']->getError() . "\n";
2702 // tracking sets this, causing the deleted db to be shown in navi
2703 unset($GLOBALS['db']);
2705 $sql_query = join("\n", $queries);
2706 if (! empty($drop_user_error)) {
2707 $message = PMA_Message::rawError($drop_user_error);
2708 } else {
2709 $message = PMA_Message::success(
2710 __('The selected users have been deleted successfully.')
2714 return array($sql_query, $message);
2718 * Update the privileges and return the success or error message
2720 * @param string $username username
2721 * @param string $hostname host name
2722 * @param string $tablename table name
2723 * @param string $dbname database name
2725 * @return PMA_message success message or error message for update
2727 function PMA_updatePrivileges($username, $hostname, $tablename, $dbname)
2729 $db_and_table = PMA_wildcardEscapeForGrant($dbname, $tablename);
2731 $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
2732 . ' FROM \'' . PMA_Util::sqlAddSlashes($username)
2733 . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\';';
2735 if (! isset($_POST['Grant_priv']) || $_POST['Grant_priv'] != 'Y') {
2736 $sql_query1 = 'REVOKE GRANT OPTION ON ' . $db_and_table
2737 . ' FROM \'' . PMA_Util::sqlAddSlashes($username) . '\'@\''
2738 . PMA_Util::sqlAddSlashes($hostname) . '\';';
2739 } else {
2740 $sql_query1 = '';
2743 // Should not do a GRANT USAGE for a table-specific privilege, it
2744 // causes problems later (cannot revoke it)
2745 if (! (strlen($tablename) && 'USAGE' == implode('', PMA_extractPrivInfo()))) {
2746 $sql_query2 = 'GRANT ' . join(', ', PMA_extractPrivInfo())
2747 . ' ON ' . $db_and_table
2748 . ' TO \'' . PMA_Util::sqlAddSlashes($username) . '\'@\''
2749 . PMA_Util::sqlAddSlashes($hostname) . '\'';
2751 if ((isset($_POST['Grant_priv']) && $_POST['Grant_priv'] == 'Y')
2752 || (! strlen($dbname)
2753 && (isset($_POST['max_questions']) || isset($_POST['max_connections'])
2754 || isset($_POST['max_updates']) || isset($_POST['max_user_connections'])))
2756 $sql_query2 .= PMA_getWithClauseForAddUserAndUpdatePrivs();
2758 $sql_query2 .= ';';
2760 if (! $GLOBALS['dbi']->tryQuery($sql_query0)) {
2761 // This might fail when the executing user does not have
2762 // ALL PRIVILEGES himself.
2763 // See https://sourceforge.net/p/phpmyadmin/bugs/3270/
2764 $sql_query0 = '';
2766 if (isset($sql_query1) && ! $GLOBALS['dbi']->tryQuery($sql_query1)) {
2767 // this one may fail, too...
2768 $sql_query1 = '';
2770 if (isset($sql_query2)) {
2771 $GLOBALS['dbi']->query($sql_query2);
2772 } else {
2773 $sql_query2 = '';
2775 $sql_query = $sql_query0 . ' ' . $sql_query1 . ' ' . $sql_query2;
2776 $message = PMA_Message::success(__('You have updated the privileges for %s.'));
2777 $message->addParam(
2778 '\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\''
2781 return array($sql_query, $message);
2785 * Get title and textarea for export user definition in Privileges
2787 * @param string $username username
2788 * @param string $hostname host name
2790 * @return array ($title, $export)
2792 function PMA_getHtmlForExportUserDefinition($username, $hostname)
2794 $export = '<textarea class="export" cols="' . $GLOBALS['cfg']['TextareaCols']
2795 . '" rows="' . $GLOBALS['cfg']['TextareaRows'] . '">';
2797 if (isset($_REQUEST['selected_usr'])) {
2798 // export privileges for selected users
2799 $title = __('Privileges');
2800 foreach ($_REQUEST['selected_usr'] as $export_user) {
2801 $export_username = substr($export_user, 0, strpos($export_user, '&'));
2802 $export_hostname = substr($export_user, strrpos($export_user, ';') + 1);
2803 $export .= '# '
2804 . sprintf(
2805 __('Privileges for %s'),
2806 '`' . htmlspecialchars($export_username)
2807 . '`@`' . htmlspecialchars($export_hostname) . '`'
2809 . "\n\n";
2810 $export .= PMA_getGrants($export_username, $export_hostname) . "\n";
2812 } else {
2813 // export privileges for a single user
2814 $title = __('User') . ' `' . htmlspecialchars($username)
2815 . '`@`' . htmlspecialchars($hostname) . '`';
2816 $export .= PMA_getGrants($username, $hostname);
2818 // remove trailing whitespace
2819 $export = trim($export);
2821 $export .= '</textarea>';
2823 return array($title, $export);
2827 * Get HTML for display Add userfieldset
2829 * @param string $conditional_class if ajaxable 'Ajax' otherwise ''
2831 * @return string html output
2833 function PMA_getAddUserHtmlFieldset($conditional_class)
2835 return '<fieldset id="fieldset_add_user">' . "\n"
2836 . '<a href="server_privileges.php?' . $GLOBALS['url_query']
2837 . '&amp;adduser=1" '
2838 . 'class="' . $conditional_class . '">' . "\n"
2839 . PMA_Util::getIcon('b_usradd.png')
2840 . ' ' . __('Add user') . '</a>' . "\n"
2841 . '</fieldset>' . "\n";
2845 * Get HTML header for display User's properties
2847 * @param boolean $dbname_is_wildcard whether database name is wildcard or not
2848 * @param string $url_dbname url database name that urlencode() string
2849 * @param string $dbname database name
2850 * @param string $username username
2851 * @param string $hostname host name
2852 * @param string $tablename table name
2854 * @return string $html_output
2856 function PMA_getHtmlHeaderForDisplayUserProperties(
2857 $dbname_is_wildcard, $url_dbname, $dbname, $username, $hostname, $tablename
2859 $html_output = '<h2>' . "\n"
2860 . PMA_Util::getIcon('b_usredit.png')
2861 . __('Edit Privileges:') . ' '
2862 . __('User');
2864 if (isset($dbname)) {
2865 $html_output .= ' <i><a href="server_privileges.php?'
2866 . $GLOBALS['url_query']
2867 . '&amp;username=' . htmlspecialchars(urlencode($username))
2868 . '&amp;hostname=' . htmlspecialchars(urlencode($hostname))
2869 . '&amp;dbname=&amp;tablename=">\'' . htmlspecialchars($username)
2870 . '\'@\'' . htmlspecialchars($hostname)
2871 . '\'</a></i>' . "\n";
2873 $html_output .= ' - ' . ($dbname_is_wildcard ? __('Databases') : __('Database') );
2874 if (isset($_REQUEST['tablename'])) {
2875 $html_output .= ' <i><a href="server_privileges.php?' . $GLOBALS['url_query']
2876 . '&amp;username=' . htmlspecialchars(urlencode($username))
2877 . '&amp;hostname=' . htmlspecialchars(urlencode($hostname))
2878 . '&amp;dbname=' . htmlspecialchars($url_dbname)
2879 . '&amp;tablename=">' . htmlspecialchars($dbname)
2880 . '</a></i>';
2882 $html_output .= ' - ' . __('Table')
2883 . ' <i>' . htmlspecialchars($tablename) . '</i>';
2884 } else {
2885 $html_output .= ' <i>' . htmlspecialchars($dbname) . '</i>';
2888 } else {
2889 $html_output .= ' <i>\'' . htmlspecialchars($username)
2890 . '\'@\'' . htmlspecialchars($hostname)
2891 . '\'</i>' . "\n";
2894 $html_output .= '</h2>' . "\n";
2896 return $html_output;
2900 * Get HTML snippet for display user overview page
2902 * @param string $link_edit standard link to edit privileges
2903 * @param string $pmaThemeImage a image source link
2904 * @param string $text_dir text directory
2905 * @param string $conditional_class if ajaxable 'Ajax' otherwise ''
2906 * @param string $link_export standard link to export privileges
2908 * @return string $html_output
2910 function PMA_getHtmlForDisplayUserOverviewPage($link_edit, $pmaThemeImage,
2911 $text_dir, $conditional_class, $link_export
2913 $html_output = '<h2>' . "\n"
2914 . PMA_Util::getIcon('b_usrlist.png')
2915 . __('Users overview') . "\n"
2916 . '</h2>' . "\n";
2918 $sql_query = 'SELECT *,' .
2919 " IF(`Password` = _latin1 '', 'N', 'Y') AS 'Password'" .
2920 ' FROM `mysql`.`user`';
2922 $sql_query .= (isset($_REQUEST['initial'])
2923 ? PMA_rangeOfUsers($_REQUEST['initial'])
2924 : '');
2926 $sql_query .= ' ORDER BY `User` ASC, `Host` ASC;';
2927 $res = $GLOBALS['dbi']->tryQuery(
2928 $sql_query, null, PMA_DatabaseInterface::QUERY_STORE
2931 if (! $res) {
2932 // the query failed! This may have two reasons:
2933 // - the user does not have enough privileges
2934 // - the privilege tables use a structure of an earlier version.
2935 // so let's try a more simple query
2937 $sql_query = 'SELECT * FROM `mysql`.`user`';
2938 $res = $GLOBALS['dbi']->tryQuery(
2939 $sql_query, null, PMA_DatabaseInterface::QUERY_STORE
2942 if (! $res) {
2943 $html_output .= PMA_Message::error(__('No Privileges'))->getDisplay();
2944 $GLOBALS['dbi']->freeResult($res);
2945 unset($res);
2946 } else {
2947 // This message is hardcoded because I will replace it by
2948 // a automatic repair feature soon.
2949 $raw = 'Your privilege table structure seems to be older than'
2950 . ' this MySQL version!<br />'
2951 . 'Please run the <code>mysql_upgrade</code> command'
2952 . '(<code>mysql_fix_privilege_tables</code> on older systems)'
2953 . ' that should be included in your MySQL server distribution'
2954 . ' to solve this problem!';
2955 $html_output .= PMA_Message::rawError($raw)->getDisplay();
2957 } else {
2958 $db_rights = PMA_getDbRightsForUserOverview();
2959 // for all initials, even non A-Z
2960 $array_initials = array();
2963 * Displays the initials
2964 * Also not necassary if there is less than 20 privileges
2966 if ($GLOBALS['dbi']->numRows($res) > 20 ) {
2967 $html_output .= PMA_getHtmlForDisplayTheInitials(
2968 $array_initials, $conditional_class
2973 * Display the user overview
2974 * (if less than 50 users, display them immediately)
2976 if (isset($_REQUEST['initial'])
2977 || isset($_REQUEST['showall'])
2978 || $GLOBALS['dbi']->numRows($res) < 50
2980 $html_output .= PMA_getUsersOverview(
2981 $res, $db_rights, $link_edit, $pmaThemeImage,
2982 $text_dir, $conditional_class, $link_export
2984 } else {
2985 $html_output .= PMA_getAddUserHtmlFieldset($conditional_class);
2986 } // end if (display overview)
2988 if (! $GLOBALS['is_ajax_request'] || ! empty($_REQUEST['ajax_page_request'])) {
2989 $flushnote = new PMA_Message(
2990 __('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.'),
2991 PMA_Message::NOTICE
2993 $flushLink = '<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&amp;'
2994 . 'flush_privileges=1" id="reload_privileges_anchor" '
2995 . 'class="' . $conditional_class . '">';
2996 $flushnote->addParam(
2997 $flushLink,
2998 false
3000 $flushnote->addParam('</a>', false);
3001 $html_output .= $flushnote->getDisplay();
3003 return $html_output;
3008 * Get HTML snippet for display user properties
3010 * @param boolean $dbname_is_wildcard whether database name is wildcard or not
3011 * @param type $url_dbname url database name that urlencode() string
3012 * @param string $username username
3013 * @param string $hostname host name
3014 * @param string $link_edit standard link to edit privileges
3015 * @param string $link_revoke standard link to revoke
3016 * @param string $dbname database name
3017 * @param string $tablename table name
3019 * @return string $html_output
3021 function PMA_getHtmlForDisplayUserProperties($dbname_is_wildcard,$url_dbname,
3022 $username, $hostname, $link_edit, $link_revoke, $dbname, $tablename
3024 $html_output = PMA_getHtmlHeaderForDisplayUserProperties(
3025 $dbname_is_wildcard, $url_dbname, $dbname, $username, $hostname, $tablename
3028 $sql = "SELECT '1' FROM `mysql`.`user`"
3029 . " WHERE `User` = '" . PMA_Util::sqlAddSlashes($username) . "'"
3030 . " AND `Host` = '" . PMA_Util::sqlAddSlashes($hostname) . "';";
3032 $user_does_not_exists = (bool) ! $GLOBALS['dbi']->fetchValue($sql);
3034 if ($user_does_not_exists) {
3035 $html_output .= PMA_Message::error(
3036 __('The selected user was not found in the privilege table.')
3037 )->getDisplay();
3038 $html_output .= PMA_getHtmlForDisplayLoginInformationFields();
3039 //exit;
3042 $class = ' class="ajax"';
3043 $html_output .= '<form' . $class . ' name="usersForm" id="addUsersForm"'
3044 . ' action="server_privileges.php" method="post">' . "\n";
3046 $_params = array(
3047 'username' => $username,
3048 'hostname' => $hostname,
3050 if (strlen($dbname)) {
3051 $_params['dbname'] = $dbname;
3052 if (strlen($tablename)) {
3053 $_params['tablename'] = $tablename;
3056 $html_output .= PMA_generate_common_hidden_inputs($_params);
3058 $html_output .= PMA_getHtmlToDisplayPrivilegesTable(
3059 PMA_ifSetOr($dbname, '*', 'length'),
3060 PMA_ifSetOr($tablename, '*', 'length')
3063 $html_output .= '</form>' . "\n";
3065 if (! strlen($tablename) && empty($dbname_is_wildcard)) {
3067 // no table name was given, display all table specific rights
3068 // but only if $dbname contains no wildcards
3070 $html_output .= '<form action="server_privileges.php" '
3071 . 'id="db_or_table_specific_priv" method="post">' . "\n";
3073 // unescape wildcards in dbname at table level
3074 $unescaped_db = PMA_Util::unescapeMysqlWildcards($dbname);
3075 list($html_rightsTable, $found_rows)
3076 = PMA_getTableForDisplayAllTableSpecificRights(
3077 $username, $hostname, $link_edit, $link_revoke, $unescaped_db
3079 $html_output .= $html_rightsTable;
3081 if (! strlen($dbname)) {
3082 // no database name was given, display select db
3083 $html_output .= PMA_getHtmlForDisplaySelectDbInEditPrivs($found_rows);
3085 } else {
3086 $html_output .= PMA_displayTablesInEditPrivs($dbname, $found_rows);
3088 $html_output .= '</fieldset>' . "\n";
3090 $html_output .= '<fieldset class="tblFooters">' . "\n"
3091 . ' <input type="submit" value="' . __('Go') . '" />'
3092 . '</fieldset>' . "\n"
3093 . '</form>' . "\n";
3096 // Provide a line with links to the relevant database and table
3097 if (strlen($dbname) && empty($dbname_is_wildcard)) {
3098 $html_output .= PMA_getLinkToDbAndTable($url_dbname, $dbname, $tablename);
3102 if (! strlen($dbname) && ! $user_does_not_exists) {
3103 //change login information
3104 $html_output .= PMA_getHtmlForChangePassword($username, $hostname);
3105 $html_output .= PMA_getChangeLoginInformationHtmlForm($username, $hostname);
3108 return $html_output;
3112 * Get queries for Table privileges to change or copy user
3114 * @param string $user_host_condition user host condition to select relevent table privileges
3115 * @param array $queries queries array
3116 * @param string $username username
3117 * @param string $hostname host name
3119 * @return array $queries
3121 function PMA_getTablePrivsQueriesForChangeOrCopyUser($user_host_condition,
3122 $queries, $username, $hostname
3124 $res = $GLOBALS['dbi']->query(
3125 'SELECT `Db`, `Table_name`, `Table_priv` FROM `mysql`.`tables_priv`' . $user_host_condition,
3126 $GLOBALS['userlink'],
3127 PMA_DatabaseInterface::QUERY_STORE
3129 while ($row = $GLOBALS['dbi']->fetchAssoc($res)) {
3131 $res2 = $GLOBALS['dbi']->query(
3132 'SELECT `Column_name`, `Column_priv`'
3133 .' FROM `mysql`.`columns_priv`'
3134 .' WHERE `User`'
3135 .' = \'' . PMA_Util::sqlAddSlashes($_REQUEST['old_username']) . "'"
3136 .' AND `Host`'
3137 .' = \'' . PMA_Util::sqlAddSlashes($_REQUEST['old_username']) . '\''
3138 .' AND `Db`'
3139 .' = \'' . PMA_Util::sqlAddSlashes($row['Db']) . "'"
3140 .' AND `Table_name`'
3141 .' = \'' . PMA_Util::sqlAddSlashes($row['Table_name']) . "'"
3142 .';',
3143 null,
3144 PMA_DatabaseInterface::QUERY_STORE
3147 $tmp_privs1 = PMA_extractPrivInfo($row);
3148 $tmp_privs2 = array(
3149 'Select' => array(),
3150 'Insert' => array(),
3151 'Update' => array(),
3152 'References' => array()
3155 while ($row2 = $GLOBALS['dbi']->fetchAssoc($res2)) {
3156 $tmp_array = explode(',', $row2['Column_priv']);
3157 if (in_array('Select', $tmp_array)) {
3158 $tmp_privs2['Select'][] = $row2['Column_name'];
3160 if (in_array('Insert', $tmp_array)) {
3161 $tmp_privs2['Insert'][] = $row2['Column_name'];
3163 if (in_array('Update', $tmp_array)) {
3164 $tmp_privs2['Update'][] = $row2['Column_name'];
3166 if (in_array('References', $tmp_array)) {
3167 $tmp_privs2['References'][] = $row2['Column_name'];
3170 if (count($tmp_privs2['Select']) > 0 && ! in_array('SELECT', $tmp_privs1)) {
3171 $tmp_privs1[] = 'SELECT (`' . join('`, `', $tmp_privs2['Select']) . '`)';
3173 if (count($tmp_privs2['Insert']) > 0 && ! in_array('INSERT', $tmp_privs1)) {
3174 $tmp_privs1[] = 'INSERT (`' . join('`, `', $tmp_privs2['Insert']) . '`)';
3176 if (count($tmp_privs2['Update']) > 0 && ! in_array('UPDATE', $tmp_privs1)) {
3177 $tmp_privs1[] = 'UPDATE (`' . join('`, `', $tmp_privs2['Update']) . '`)';
3179 if (count($tmp_privs2['References']) > 0 && ! in_array('REFERENCES', $tmp_privs1)) {
3180 $tmp_privs1[] = 'REFERENCES (`' . join('`, `', $tmp_privs2['References']) . '`)';
3183 $queries[] = 'GRANT ' . join(', ', $tmp_privs1)
3184 . ' ON ' . PMA_Util::backquote($row['Db']) . '.'
3185 . PMA_Util::backquote($row['Table_name'])
3186 . ' TO \'' . PMA_Util::sqlAddSlashes($username)
3187 . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\''
3188 . (in_array('Grant', explode(',', $row['Table_priv'])) ? ' WITH GRANT OPTION;' : ';');
3190 return $queries;
3194 * Get queries for database specific privileges for change or copy user
3196 * @param array $queries queries array with string
3197 * @param string $username username
3198 * @param string $hostname host name
3200 * @return array $queries
3202 function PMA_getDbSpecificPrivsQueriesForChangeOrCopyUser(
3203 $queries, $username, $hostname
3205 $user_host_condition = ' WHERE `User`'
3206 .' = \'' . PMA_Util::sqlAddSlashes($_REQUEST['old_username']) . "'"
3207 .' AND `Host`'
3208 .' = \'' . PMA_Util::sqlAddSlashes($_REQUEST['old_username']) . '\';';
3210 $res = $GLOBALS['dbi']->query('SELECT * FROM `mysql`.`db`' . $user_host_condition);
3212 while ($row = $GLOBALS['dbi']->fetchAssoc($res)) {
3213 $queries[] = 'GRANT ' . join(', ', PMA_extractPrivInfo($row))
3214 .' ON ' . PMA_Util::backquote($row['Db']) . '.*'
3215 .' TO \'' . PMA_Util::sqlAddSlashes($username)
3216 . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\''
3217 . ($row['Grant_priv'] == 'Y' ? ' WITH GRANT OPTION;' : ';');
3219 $GLOBALS['dbi']->freeResult($res);
3221 $queries = PMA_getTablePrivsQueriesForChangeOrCopyUser(
3222 $user_host_condition, $queries, $username, $hostname
3225 return $queries;
3229 * Prepares queries for adding users and
3230 * also create database and return query and message
3232 * @param boolean $_error whether user create or not
3233 * @param string $real_sql_query SQL query for add a user
3234 * @param string $sql_query SQL query to be displayed
3235 * @param string $username username
3236 * @param string $hostname host name
3237 * @param string $dbname database name
3239 * @return array $sql_query, $message
3241 function PMA_addUserAndCreateDatabase($_error, $real_sql_query, $sql_query,
3242 $username, $hostname, $dbname
3244 if ($_error || ! $GLOBALS['dbi']->tryQuery($real_sql_query)) {
3245 $_REQUEST['createdb-1'] = $_REQUEST['createdb-2']
3246 = $_REQUEST['createdb-3'] = false;
3247 $message = PMA_Message::rawError($GLOBALS['dbi']->getError());
3248 } else {
3249 $message = PMA_Message::success(__('You have added a new user.'));
3252 if (isset($_REQUEST['createdb-1'])) {
3253 // Create database with same name and grant all privileges
3254 $q = 'CREATE DATABASE IF NOT EXISTS '
3255 . PMA_Util::backquote(
3256 PMA_Util::sqlAddSlashes($username)
3257 ) . ';';
3258 $sql_query .= $q;
3259 if (! $GLOBALS['dbi']->tryQuery($q)) {
3260 $message = PMA_Message::rawError($GLOBALS['dbi']->getError());
3264 * Reload the navigation
3266 $GLOBALS['reload'] = true;
3267 $GLOBALS['db'] = $username;
3269 $q = 'GRANT ALL PRIVILEGES ON '
3270 . PMA_Util::backquote(
3271 PMA_Util::escapeMysqlWildcards(
3272 PMA_Util::sqlAddSlashes($username)
3274 ) . '.* TO \''
3275 . PMA_Util::sqlAddSlashes($username)
3276 . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\';';
3277 $sql_query .= $q;
3278 if (! $GLOBALS['dbi']->tryQuery($q)) {
3279 $message = PMA_Message::rawError($GLOBALS['dbi']->getError());
3283 if (isset($_REQUEST['createdb-2'])) {
3284 // Grant all privileges on wildcard name (username\_%)
3285 $q = 'GRANT ALL PRIVILEGES ON '
3286 . PMA_Util::backquote(
3287 PMA_Util::sqlAddSlashes($username) . '\_%'
3288 ) . '.* TO \''
3289 . PMA_Util::sqlAddSlashes($username)
3290 . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\';';
3291 $sql_query .= $q;
3292 if (! $GLOBALS['dbi']->tryQuery($q)) {
3293 $message = PMA_Message::rawError($GLOBALS['dbi']->getError());
3297 if (isset($_REQUEST['createdb-3'])) {
3298 // Grant all privileges on the specified database to the new user
3299 $q = 'GRANT ALL PRIVILEGES ON '
3300 . PMA_Util::backquote(
3301 PMA_Util::sqlAddSlashes($dbname)
3302 ) . '.* TO \''
3303 . PMA_Util::sqlAddSlashes($username)
3304 . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\';';
3305 $sql_query .= $q;
3306 if (! $GLOBALS['dbi']->tryQuery($q)) {
3307 $message = PMA_Message::rawError($GLOBALS['dbi']->getError());
3310 return array($sql_query, $message);
3314 * Get SQL queries for Display and Add user
3316 * @param string $username usernam
3317 * @param string $hostname host name
3318 * @param string $password password
3320 * @return array ($create_user_real, $create_user_show,$real_sql_query, $sql_query)
3322 function PMA_getSqlQueriesForDisplayAndAddUser($username, $hostname, $password)
3324 $sql_query = '';
3325 $create_user_real = 'CREATE USER \''
3326 . PMA_Util::sqlAddSlashes($username) . '\'@\''
3327 . PMA_Util::sqlAddSlashes($hostname) . '\'';
3329 $real_sql_query = 'GRANT ' . join(', ', PMA_extractPrivInfo()) . ' ON *.* TO \''
3330 . PMA_Util::sqlAddSlashes($username) . '\'@\''
3331 . PMA_Util::sqlAddSlashes($hostname) . '\'';
3333 if ($_POST['pred_password'] != 'none' && $_POST['pred_password'] != 'keep') {
3334 $sql_query = $real_sql_query . ' IDENTIFIED BY \'***\'';
3335 $real_sql_query .= ' IDENTIFIED BY \''
3336 . PMA_Util::sqlAddSlashes($_POST['pma_pw']) . '\'';
3337 if (isset($create_user_real)) {
3338 $create_user_show = $create_user_real . ' IDENTIFIED BY \'***\'';
3339 $create_user_real .= ' IDENTIFIED BY \''
3340 . PMA_Util::sqlAddSlashes($_POST['pma_pw']) . '\'';
3342 } else {
3343 if ($_POST['pred_password'] == 'keep' && ! empty($password)) {
3344 $real_sql_query .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
3345 if (isset($create_user_real)) {
3346 $create_user_real .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
3349 $sql_query = $real_sql_query;
3350 if (isset($create_user_real)) {
3351 $create_user_show = $create_user_real;
3355 if ((isset($_POST['Grant_priv']) && $_POST['Grant_priv'] == 'Y')
3356 || (isset($_POST['max_questions']) || isset($_POST['max_connections'])
3357 || isset($_POST['max_updates']) || isset($_POST['max_user_connections']))
3359 $with_clause = PMA_getWithClauseForAddUserAndUpdatePrivs();
3360 $real_sql_query .= ' ' . $with_clause;
3361 $sql_query .= ' ' . $with_clause;
3364 if (isset($create_user_real)) {
3365 $create_user_real .= ';';
3366 $create_user_show .= ';';
3368 $real_sql_query .= ';';
3369 $sql_query .= ';';
3371 return array($create_user_real,
3372 $create_user_show,
3373 $real_sql_query,
3374 $sql_query