2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * set of functions with the Privileges section in pma
9 if (! defined('PHPMYADMIN')) {
14 * Get Html for User Group Dialog
16 * @param string $username username
17 * @param bool $is_menuswork Is menuswork set in configuration
21 function PMA_getHtmlForUserGroupDialog($username, $is_menuswork)
24 if (! empty($_REQUEST['edit_user_group_dialog']) && $is_menuswork) {
25 $dialog = PMA_getHtmlToChooseUserGroup($username);
26 $response = PMA_Response
::getInstance();
27 if ($GLOBALS['is_ajax_request']) {
28 $response->addJSON('message', $dialog);
39 * Escapes wildcard in a database+table specification
40 * before using it in a GRANT statement.
42 * Escaping a wildcard character in a GRANT is only accepted at the global
43 * or database level, not at table level; this is why I remove
44 * the escaping character. Internally, in mysql.tables_priv.Db there are
45 * no escaping (for example test_db) but in mysql.db you'll see test\_db
46 * for a db-specific privilege.
48 * @param string $dbname Database name
49 * @param string $tablename Table name
51 * @return string the escaped (if necessary) database.table
53 function PMA_wildcardEscapeForGrant($dbname, $tablename)
55 if (! strlen($dbname)) {
56 $db_and_table = '*.*';
58 if (strlen($tablename)) {
59 $db_and_table = PMA_Util
::backquote(
60 PMA_Util
::unescapeMysqlWildcards($dbname)
62 . '.' . PMA_Util
::backquote($tablename);
64 $db_and_table = PMA_Util
::backquote($dbname) . '.*';
71 * Generates a condition on the user name
73 * @param string $initial the user's initial
75 * @return string the generated condition
77 function PMA_rangeOfUsers($initial = '')
79 // strtolower() is used because the User field
80 // might be BINARY, so LIKE would be case sensitive
81 if (! empty($initial)) {
82 $ret = " WHERE `User` LIKE '"
83 . PMA_Util
::sqlAddSlashes($initial, true) . "%'"
85 . PMA_Util
::sqlAddSlashes(strtolower($initial), true) . "%'";
93 * Extracts the privilege information of a priv table row
95 * @param array $row the row
96 * @param boolean $enableHTML add <dfn> tag with tooltips
97 * @param boolean $tablePrivs whether row contains table privileges
99 * @global resource $user_link the database connection
103 function PMA_extractPrivInfo($row = '', $enableHTML = false, $tablePrivs = false)
106 $grants = PMA_getTableGrantsArray();
108 $grants = PMA_getGrantsArray();
111 if (! empty($row) && isset($row['Table_priv'])) {
112 $row1 = $GLOBALS['dbi']->fetchSingleRow(
113 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
114 'ASSOC', $GLOBALS['userlink']
116 $av_grants = explode(
118 substr($row1['Type'], 5, strlen($row1['Type']) - 7)
121 $users_grants = explode(',', $row['Table_priv']);
122 foreach ($av_grants as $current_grant) {
123 $row[$current_grant . '_priv']
124 = in_array($current_grant, $users_grants) ?
'Y' : 'N';
126 unset($current_grant);
130 $allPrivileges = true;
131 foreach ($grants as $current_grant) {
132 if ((! empty($row) && isset($row[$current_grant[0]]))
133 ||
(empty($row) && isset($GLOBALS[$current_grant[0]]))
135 if ((! empty($row) && $row[$current_grant[0]] == 'Y')
137 && ($GLOBALS[$current_grant[0]] == 'Y'
138 ||
(is_array($GLOBALS[$current_grant[0]])
139 && count($GLOBALS[$current_grant[0]]) == $_REQUEST['column_count']
140 && empty($GLOBALS[$current_grant[0] . '_none']))))
143 $privs[] = '<dfn title="' . $current_grant[2] . '">'
144 . $current_grant[1] . '</dfn>';
146 $privs[] = $current_grant[1];
148 } elseif (! empty($GLOBALS[$current_grant[0]])
149 && is_array($GLOBALS[$current_grant[0]])
150 && empty($GLOBALS[$current_grant[0] . '_none'])
153 $priv_string = '<dfn title="' . $current_grant[2] . '">'
154 . $current_grant[1] . '</dfn>';
156 $priv_string = $current_grant[1];
158 $privs[] = $priv_string . ' (`'
159 . join('`, `', $GLOBALS[$current_grant[0]]) . '`)';
161 $allPrivileges = false;
167 $privs[] = '<dfn title="' . __('No privileges.') . '">USAGE</dfn>';
171 } elseif ($allPrivileges
172 && (! isset($_POST['grant_count']) ||
count($privs) == $_POST['grant_count'])
175 $privs = array('<dfn title="'
176 . __('Includes all privileges except GRANT.')
177 . '">ALL PRIVILEGES</dfn>'
180 $privs = array('ALL PRIVILEGES');
184 } // end of the 'PMA_extractPrivInfo()' function
187 * Returns an array of table grants and their descriptions
189 * @return array array of table grants
191 function PMA_getTableGrantsArray()
197 $GLOBALS['strPrivDescDelete']
202 $GLOBALS['strPrivDescCreateTbl']
207 $GLOBALS['strPrivDescDropTbl']
212 $GLOBALS['strPrivDescIndex']
217 $GLOBALS['strPrivDescAlter']
222 $GLOBALS['strPrivDescCreateView']
227 $GLOBALS['strPrivDescShowView']
232 $GLOBALS['strPrivDescTrigger']
238 * Get the grants array which contains all the privilege types
239 * and relevent grant messages
243 function PMA_getGrantsArray()
249 __('Allows reading data.')
254 __('Allows inserting and replacing data.')
259 __('Allows changing data.')
264 __('Allows deleting data.')
269 __('Allows creating new databases and tables.')
274 __('Allows dropping databases and tables.')
279 __('Allows reloading server settings and flushing the server\'s caches.')
284 __('Allows shutting down the server.')
289 __('Allows viewing processes of all users')
294 __('Allows importing data from and exporting data into files.')
299 __('Has no effect in this MySQL version.')
304 __('Allows creating and dropping indexes.')
309 __('Allows altering the structure of existing tables.')
314 __('Gives access to the complete list of databases.')
320 'Allows connecting, even if maximum number of connections '
321 . 'is reached; required for most administrative operations '
322 . 'like setting global variables or killing threads of other users.'
326 'Create_tmp_table_priv',
327 'CREATE TEMPORARY TABLES',
328 __('Allows creating temporary tables.')
333 __('Allows locking tables for the current thread.')
338 __('Needed for the replication slaves.')
342 'REPLICATION CLIENT',
343 __('Allows the user to ask where the slaves / masters are.')
348 __('Allows creating new views.')
353 __('Allows to set up events for the event scheduler')
358 __('Allows creating and dropping triggers')
364 __('Allows creating new views.')
369 __('Allows performing SHOW CREATE VIEW queries.')
375 __('Allows performing SHOW CREATE VIEW queries.')
378 'Create_routine_priv',
380 __('Allows creating stored routines.')
383 'Alter_routine_priv',
385 __('Allows altering and dropping stored routines.')
390 __('Allows creating, dropping and renaming user accounts.')
395 __('Allows executing stored routines.')
401 * Displays on which column(s) a table-specific privilege is granted
403 * @param array $columns columns array
404 * @param array $row first row from result or boolean false
405 * @param string $name_for_select privilege types - Select_priv, Insert_priv
406 * Update_priv, References_priv
407 * @param string $priv_for_header privilege for header
408 * @param string $name privilege name: insert, select, update, references
409 * @param string $name_for_dfn name for dfn
410 * @param string $name_for_current name for current
412 * @return $html_output html snippet
414 function PMA_getHtmlForDisplayColumnPrivileges($columns, $row, $name_for_select,
415 $priv_for_header, $name, $name_for_dfn, $name_for_current
417 $html_output = '<div class="item" id="div_item_' . $name . '">' . "\n"
418 . '<label for="select_' . $name . '_priv">' . "\n"
419 . '<code><dfn title="' . $name_for_dfn . '">'
420 . $priv_for_header . '</dfn></code>' . "\n"
421 . '</label><br />' . "\n"
422 . '<select id="select_' . $name . '_priv" name="'
423 . $name_for_select . '[]" multiple="multiple" size="8">' . "\n";
425 foreach ($columns as $current_column => $current_column_privileges) {
426 $html_output .= '<option '
427 . 'value="' . htmlspecialchars($current_column) . '"';
428 if ($row[$name_for_select] == 'Y'
429 ||
$current_column_privileges[$name_for_current]
431 $html_output .= ' selected="selected"';
434 . htmlspecialchars($current_column) . '</option>' . "\n";
437 $html_output .= '</select>' . "\n"
438 . '<i>' . __('Or') . '</i>' . "\n"
439 . '<label for="checkbox_' . $name_for_select
440 . '_none"><input type="checkbox"'
441 . ' name="' . $name_for_select . '_none" id="checkbox_'
442 . $name_for_select . '_none" title="'
443 . _pgettext('None privileges', 'None') . '" />'
444 . _pgettext('None privileges', 'None') . '</label>' . "\n"
450 * Get sql query for display privileges table
452 * @param string $db the database
453 * @param string $table the table
454 * @param string $username username for database connection
455 * @param string $hostname hostname for database connection
457 * @return string sql query
459 function PMA_getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname)
462 return "SELECT * FROM `mysql`.`user`"
463 ." WHERE `User` = '" . PMA_Util
::sqlAddSlashes($username) . "'"
464 ." AND `Host` = '" . PMA_Util
::sqlAddSlashes($hostname) . "';";
465 } elseif ($table == '*') {
466 return "SELECT * FROM `mysql`.`db`"
467 ." WHERE `User` = '" . PMA_Util
::sqlAddSlashes($username) . "'"
468 ." AND `Host` = '" . PMA_Util
::sqlAddSlashes($hostname) . "'"
469 ." AND '" . PMA_Util
::unescapeMysqlWildcards($db) . "'"
472 return "SELECT `Table_priv`"
473 ." FROM `mysql`.`tables_priv`"
474 ." WHERE `User` = '" . PMA_Util
::sqlAddSlashes($username) . "'"
475 ." AND `Host` = '" . PMA_Util
::sqlAddSlashes($hostname) . "'"
476 ." AND `Db` = '" . PMA_Util
::unescapeMysqlWildcards($db) . "'"
477 ." AND `Table_name` = '" . PMA_Util
::sqlAddSlashes($table) . "';";
481 * Displays a dropdown to select the user group
482 * with menu items configured to each of them.
484 * @param string $username username
486 * @return string html to select the user group
488 function PMA_getHtmlToChooseUserGroup($username)
490 $html_output = '<form class="ajax" id="changeUserGroupForm"'
491 . ' action="server_privileges.php" method="post">';
492 $params = array('username' => $username);
493 $html_output .= PMA_URL_getHiddenInputs($params);
494 $html_output .= '<fieldset id="fieldset_user_group_selection">';
495 $html_output .= '<legend>' . __('User group') . '</legend>';
497 $groupTable = PMA_Util
::backquote($GLOBALS['cfg']['Server']['pmadb'])
498 . "." . PMA_Util
::backquote($GLOBALS['cfg']['Server']['usergroups']);
499 $userTable = PMA_Util
::backquote($GLOBALS['cfg']['Server']['pmadb'])
500 . "." . PMA_Util
::backquote($GLOBALS['cfg']['Server']['users']);
502 $userGroups = array();
503 $sql_query = "SELECT DISTINCT `usergroup` FROM " . $groupTable;
504 $result = PMA_queryAsControlUser($sql_query, false);
506 while ($row = $GLOBALS['dbi']->fetchRow($result)) {
507 $userGroups[] = $row[0];
510 $GLOBALS['dbi']->freeResult($result);
513 if (isset($GLOBALS['username'])) {
514 $sql_query = "SELECT `usergroup` FROM " . $userTable
515 . " WHERE `username` = '" . PMA_Util
::sqlAddSlashes($username) . "'";
516 $userGroup = $GLOBALS['dbi']->fetchValue(
517 $sql_query, 0, 0, $GLOBALS['controllink']
521 $html_output .= __('User group') . ': ';
522 $html_output .= '<select name="userGroup">';
523 $html_output .= '<option value=""></option>';
524 foreach ($userGroups as $oneUserGroup) {
525 $html_output .= '<option value="' . htmlspecialchars($oneUserGroup) . '"'
526 . ($oneUserGroup == $userGroup ?
' selected="selected"' : '')
528 . htmlspecialchars($oneUserGroup)
531 $html_output .= '</select>';
532 $html_output .= '<input type="hidden" name="changeUserGroup" value="1">';
533 $html_output .= '</fieldset>';
534 $html_output .= '</form>';
539 * Sets the user group from request values
541 * @param string $username username
542 * @param string $userGroup user group to set
546 function PMA_setUserGroup($username, $userGroup)
548 $userTable = PMA_Util
::backquote($GLOBALS['cfg']['Server']['pmadb'])
549 . "." . PMA_Util
::backquote($GLOBALS['cfg']['Server']['users']);
551 $sql_query = "SELECT `usergroup` FROM " . $userTable
552 . " WHERE `username` = '" . PMA_Util
::sqlAddSlashes($username) . "'";
553 $oldUserGroup = $GLOBALS['dbi']->fetchValue(
554 $sql_query, 0, 0, $GLOBALS['controllink']
557 if ($oldUserGroup === false) {
558 $upd_query = "INSERT INTO " . $userTable . "(`username`, `usergroup`)"
559 . " VALUES ('" . PMA_Util
::sqlAddSlashes($username) . "', "
560 . "'" . PMA_Util
::sqlAddSlashes($userGroup) . "')";
562 if (empty($userGroup)) {
563 $upd_query = "DELETE FROM " . $userTable
564 . " WHERE `username`='" . PMA_Util
::sqlAddSlashes($username) . "'";
565 } elseif ($oldUserGroup != $userGroup) {
566 $upd_query = "UPDATE " . $userTable
567 . " SET `usergroup`='" . PMA_Util
::sqlAddSlashes($userGroup) . "'"
568 . " WHERE `username`='" . PMA_Util
::sqlAddSlashes($username) . "'";
571 if (isset($upd_query)) {
572 PMA_queryAsControlUser($upd_query);
577 * Displays the privileges form table
579 * @param string $db the database
580 * @param string $table the table
581 * @param boolean $submit wheather to display the submit button or not
583 * @global array $cfg the phpMyAdmin configuration
584 * @global ressource $user_link the database connection
586 * @return string html snippet
588 function PMA_getHtmlToDisplayPrivilegesTable($db = '*',
589 $table = '*', $submit = true
597 if (isset($GLOBALS['username'])) {
598 $username = $GLOBALS['username'];
599 $hostname = $GLOBALS['hostname'];
600 $sql_query = PMA_getSqlQueryForDisplayPrivTable(
601 $db, $table, $username, $hostname
603 $row = $GLOBALS['dbi']->fetchSingleRow($sql_query);
608 $sql_query = 'SHOW COLUMNS FROM `mysql`.`user`;';
609 } elseif ($table == '*') {
610 $sql_query = 'SHOW COLUMNS FROM `mysql`.`db`;';
612 $res = $GLOBALS['dbi']->query($sql_query);
613 while ($row1 = $GLOBALS['dbi']->fetchRow($res)) {
614 if (substr($row1[0], 0, 4) == 'max_') {
617 $row[$row1[0]] = 'N';
620 $GLOBALS['dbi']->freeResult($res);
622 $row = array('Table_priv' => '');
625 if (isset($row['Table_priv'])) {
626 $row1 = $GLOBALS['dbi']->fetchSingleRow(
627 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
628 'ASSOC', $GLOBALS['userlink']
630 // note: in MySQL 5.0.3 we get "Create View', 'Show view';
631 // the View for Create is spelled with uppercase V
632 // the view for Show is spelled with lowercase v
633 // and there is a space between the words
635 $av_grants = explode(
639 strpos($row1['Type'], '(') +
2,
640 strpos($row1['Type'], ')') - strpos($row1['Type'], '(') - 3
644 $users_grants = explode(',', $row['Table_priv']);
646 foreach ($av_grants as $current_grant) {
647 $row[$current_grant . '_priv']
648 = in_array($current_grant, $users_grants) ?
'Y' : 'N';
650 unset($row['Table_priv'], $current_grant, $av_grants, $users_grants);
653 $res = $GLOBALS['dbi']->tryQuery(
655 . PMA_Util
::backquote(
656 PMA_Util
::unescapeMysqlWildcards($db)
658 . '.' . PMA_Util
::backquote($table) . ';'
662 while ($row1 = $GLOBALS['dbi']->fetchRow($res)) {
663 $columns[$row1[0]] = array(
667 'References' => false
670 $GLOBALS['dbi']->freeResult($res);
674 // table-specific privileges
675 if (! empty($columns)) {
676 $html_output .= PMA_getHtmlForTableSpecificPrivileges(
677 $username, $hostname, $db, $table, $columns, $row
680 // global or db-specific
681 $html_output .= PMA_getHtmlForGlobalOrDbSpecificPrivs($db, $table, $row);
683 $html_output .= '</fieldset>' . "\n";
685 $html_output .= '<fieldset id="fieldset_user_privtable_footer" '
686 . 'class="tblFooters">' . "\n"
687 . '<input type="submit" name="update_privs" '
688 . 'value="' . __('Go') . '" />' . "\n"
689 . '</fieldset>' . "\n";
692 } // end of the 'PMA_displayPrivTable()' function
695 * Get HTML for "Resource limits"
697 * @param array $row first row from result or boolean false
699 * @return string html snippet
701 function PMA_getHtmlForDisplayResourceLimits($row)
703 $html_output = '<fieldset>' . "\n"
704 . '<legend>' . __('Resource limits') . '</legend>' . "\n"
706 . '<i>' . __('Note: Setting these options to 0 (zero) removes the limit.')
707 . '</i></small></p>' . "\n";
709 $html_output .= '<div class="item">' . "\n"
710 . '<label for="text_max_questions">'
711 . '<code><dfn title="'
713 'Limits the number of queries the user may send to the server per hour.'
716 . 'MAX QUERIES PER HOUR'
717 . '</dfn></code></label>' . "\n"
718 . '<input type="number" name="max_questions" id="text_max_questions" '
719 . 'value="' . $row['max_questions'] . '" '
720 . 'size="6" maxlength="11" min="0" '
723 'Limits the number of queries the user may send to the server per hour.'
728 $html_output .= '<div class="item">' . "\n"
729 . '<label for="text_max_updates">'
730 . '<code><dfn title="'
732 'Limits the number of commands that change any table '
733 . 'or database the user may execute per hour.'
735 . 'MAX UPDATES PER HOUR'
736 . '</dfn></code></label>' . "\n"
737 . '<input type="number" name="max_updates" id="text_max_updates" '
738 . 'value="' . $row['max_updates'] . '" size="6" maxlength="11" min="0" '
741 'Limits the number of commands that change any table '
742 . 'or database the user may execute per hour.'
747 $html_output .= '<div class="item">' . "\n"
748 . '<label for="text_max_connections">'
749 . '<code><dfn title="'
751 'Limits the number of new connections the user may open per hour.'
753 . 'MAX CONNECTIONS PER HOUR'
754 . '</dfn></code></label>' . "\n"
755 . '<input type="number" name="max_connections" id="text_max_connections" '
756 . 'value="' . $row['max_connections'] . '" size="6" maxlength="11" min="0" '
758 'Limits the number of new connections the user may open per hour.'
763 $html_output .= '<div class="item">' . "\n"
764 . '<label for="text_max_user_connections">'
765 . '<code><dfn title="'
766 . __('Limits the number of simultaneous connections the user may have.')
768 . 'MAX USER_CONNECTIONS'
769 . '</dfn></code></label>' . "\n"
770 . '<input type="number" name="max_user_connections" '
771 . 'id="text_max_user_connections" '
772 . 'value="' . $row['max_user_connections'] . '" size="6" maxlength="11" '
774 . __('Limits the number of simultaneous connections the user may have.')
778 $html_output .= '</fieldset>' . "\n";
784 * Get the HTML snippet for table specific privileges
786 * @param string $username username for database connection
787 * @param string $hostname hostname for database connection
788 * @param string $db the database
789 * @param string $table the table
790 * @param boolean $columns columns array
791 * @param array $row current privileges row
793 * @return string $html_output
795 function PMA_getHtmlForTableSpecificPrivileges(
796 $username, $hostname, $db, $table, $columns, $row
798 $res = $GLOBALS['dbi']->query(
799 'SELECT `Column_name`, `Column_priv`'
800 .' FROM `mysql`.`columns_priv`'
802 .' = \'' . PMA_Util
::sqlAddSlashes($username) . "'"
804 .' = \'' . PMA_Util
::sqlAddSlashes($hostname) . "'"
806 .' = \'' . PMA_Util
::sqlAddSlashes(
807 PMA_Util
::unescapeMysqlWildcards($db)
810 .' = \'' . PMA_Util
::sqlAddSlashes($table) . '\';'
813 while ($row1 = $GLOBALS['dbi']->fetchRow($res)) {
814 $row1[1] = explode(',', $row1[1]);
815 foreach ($row1[1] as $current) {
816 $columns[$row1[0]][$current] = true;
819 $GLOBALS['dbi']->freeResult($res);
820 unset($res, $row1, $current);
822 $html_output = '<input type="hidden" name="grant_count" '
823 . 'value="' . count($row) . '" />' . "\n"
824 . '<input type="hidden" name="column_count" '
825 . 'value="' . count($columns) . '" />' . "\n"
826 . '<fieldset id="fieldset_user_priv">' . "\n"
827 . '<legend>' . __('Table-specific privileges')
828 . PMA_Util
::showHint(
829 __('Note: MySQL privilege names are expressed in English')
831 . '</legend>' . "\n";
833 // privs that are attached to a specific column
834 $html_output .= PMA_getHtmlForAttachedPrivilegesToTableSpecificColumn(
838 // privs that are not attached to a specific column
839 $html_output .= '<div class="item">' . "\n"
840 . PMA_getHtmlForNotAttachedPrivilegesToTableSpecificColumn($row)
844 $html_output .= '<div class="clearfloat"></div>' . "\n";
850 * Get HTML snippet for privileges that are attached to a specific column
852 * @param string $columns olumns array
853 * @param array $row first row from result or boolean false
855 * @return string $html_output
857 function PMA_getHtmlForAttachedPrivilegesToTableSpecificColumn($columns, $row)
859 $html_output = PMA_getHtmlForDisplayColumnPrivileges(
860 $columns, $row, 'Select_priv', 'SELECT',
861 'select', __('Allows reading data.'), 'Select'
864 $html_output .= PMA_getHtmlForDisplayColumnPrivileges(
865 $columns, $row, 'Insert_priv', 'INSERT',
866 'insert', __('Allows inserting and replacing data.'), 'Insert'
869 $html_output .= PMA_getHtmlForDisplayColumnPrivileges(
870 $columns, $row, 'Update_priv', 'UPDATE',
871 'update', __('Allows changing data.'), 'Update'
874 $html_output .= PMA_getHtmlForDisplayColumnPrivileges(
875 $columns, $row, 'References_priv', 'REFERENCES', 'references',
876 __('Has no effect in this MySQL version.'), 'References'
882 * Get HTML for privileges that are not attached to a specific column
884 * @param array $row first row from result or boolean false
886 * @return string $html_output
888 function PMA_getHtmlForNotAttachedPrivilegesToTableSpecificColumn($row)
891 foreach ($row as $current_grant => $current_grant_value) {
892 $grant_type = substr($current_grant, 0, (strlen($current_grant) - 5));
893 if (in_array($grant_type, array('Select', 'Insert', 'Update', 'References'))
897 // make a substitution to match the messages variables;
898 // also we must substitute the grant we get, because we can't generate
899 // a form variable containing blanks (those would get changed to
900 // an underscore when receiving the POST)
901 if ($current_grant == 'Create View_priv') {
902 $tmp_current_grant = 'CreateView_priv';
903 $current_grant = 'Create_view_priv';
904 } elseif ($current_grant == 'Show view_priv') {
905 $tmp_current_grant = 'ShowView_priv';
906 $current_grant = 'Show_view_priv';
908 $tmp_current_grant = $current_grant;
911 $html_output .= '<div class="item">' . "\n"
912 . '<input type="checkbox"'
913 . ' name="' . $current_grant . '" id="checkbox_' . $current_grant
915 . ($current_grant_value == 'Y' ?
'checked="checked" ' : '')
918 $html_output .= (isset($GLOBALS[
919 'strPrivDesc' . substr(
920 $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
924 'strPrivDesc' . substr(
925 $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
929 'strPrivDesc' . substr(
930 $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
936 $html_output .= '<label for="checkbox_' . $current_grant
937 . '"><code><dfn title="'
939 'strPrivDesc' . substr(
940 $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
944 'strPrivDesc' . substr(
945 $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
949 'strPrivDesc' . substr(
950 $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
956 substr($current_grant, 0, strlen($current_grant) - 5)
958 . '</dfn></code></label>' . "\n"
965 * Get HTML for global or database specific privileges
967 * @param string $db the database
968 * @param string $table the table
969 * @param string $row first row from result or boolean false
971 * @return string $html_output
973 function PMA_getHtmlForGlobalOrDbSpecificPrivs($db, $table, $row)
975 $privTable_names = array(0 => __('Data'),
976 1 => __('Structure'),
977 2 => __('Administration')
979 $privTable = array();
981 $privTable[0] = PMA_getDataPrivilegeTable($db);
984 $privTable[1] = PMA_getStructurePrivilegeTable($table, $row);
986 // a d m i n i s t r a t i o n
987 $privTable[2] = PMA_getAdministrationPrivilegeTable($db);
989 $html_output = '<input type="hidden" name="grant_count" value="'
990 . (count($privTable[0])
991 +
count($privTable[1])
992 +
count($privTable[2])
993 - (isset($row['Grant_priv']) ?
1 : 0)
996 $html_output .= '<fieldset id="fieldset_user_global_rights"><legend>';
998 $html_output .= __('Global privileges');
999 } else if ($table == '*') {
1000 $html_output .= __('Database-specific privileges');
1002 $html_output .= __('Table-specific privileges');
1004 $html_output .= '<input type="checkbox" id="addUsersForm_checkall" '
1005 . 'class="checkall_box" title="' . __('Check All') . '" /> '
1006 . '<label for="addUsersForm_checkall">' . __('Check All') . '</label> ';
1007 $html_output .= '</legend>';
1008 $html_output .= '<p><small><i>'
1009 . __('Note: MySQL privilege names are expressed in English')
1010 . '</i></small></p>';
1012 // Output the Global privilege tables with checkboxes
1013 $html_output .= PMA_getHtmlForGlobalPrivTableWithCheckboxes(
1014 $privTable, $privTable_names, $row
1017 // The "Resource limits" box is not displayed for db-specific privs
1019 $html_output .= PMA_getHtmlForDisplayResourceLimits($row);
1022 $html_output .= '<div class="clearfloat"></div>';
1024 return $html_output;
1028 * Get data privilege table as an array
1030 * @param string $db the database
1032 * @return string data privilege table
1034 function PMA_getDataPrivilegeTable($db)
1036 $data_privTable = array(
1037 array('Select', 'SELECT', __('Allows reading data.')),
1038 array('Insert', 'INSERT', __('Allows inserting and replacing data.')),
1039 array('Update', 'UPDATE', __('Allows changing data.')),
1040 array('Delete', 'DELETE', __('Allows deleting data.'))
1046 __('Allows importing data from and exporting data into files.')
1049 return $data_privTable;
1053 * Get structure privilege table as an array
1055 * @param string $table the table
1056 * @param array $row first row from result or boolean false
1058 * @return string structure privilege table
1060 function PMA_getStructurePrivilegeTable($table, $row)
1062 $structure_privTable = array(
1066 ?
__('Allows creating new databases and tables.')
1067 : __('Allows creating new tables.')
1072 __('Allows altering the structure of existing tables.')
1074 array('Index', 'INDEX', __('Allows creating and dropping indexes.')),
1078 ?
__('Allows dropping databases and tables.')
1079 : __('Allows dropping tables.')
1082 array('Create_tmp_table',
1083 'CREATE TEMPORARY TABLES',
1084 __('Allows creating temporary tables.')
1088 __('Allows performing SHOW CREATE VIEW queries.')
1090 array('Create_routine',
1092 __('Allows creating stored routines.')
1094 array('Alter_routine',
1096 __('Allows altering and dropping stored routines.')
1098 array('Execute', 'EXECUTE', __('Allows executing stored routines.')),
1100 // this one is for a db-specific priv: Create_view_priv
1101 if (isset($row['Create_view_priv'])) {
1102 $structure_privTable[] = array('Create_view',
1104 __('Allows creating new views.')
1107 // this one is for a table-specific priv: Create View_priv
1108 if (isset($row['Create View_priv'])) {
1109 $structure_privTable[] = array('Create View',
1111 __('Allows creating new views.')
1114 if (isset($row['Event_priv'])) {
1116 $structure_privTable[] = array('Event',
1118 __('Allows to set up events for the event scheduler')
1120 $structure_privTable[] = array('Trigger',
1122 __('Allows creating and dropping triggers')
1125 return $structure_privTable;
1129 * Get administration privilege table as an array
1131 * @param string $db the table
1133 * @return string administration privilege table
1135 function PMA_getAdministrationPrivilegeTable($db)
1137 $administration_privTable = array(
1141 'Allows adding users and privileges '
1142 . 'without reloading the privilege tables.'
1147 $administration_privTable[] = array('Super',
1150 'Allows connecting, even if maximum number '
1151 . 'of connections is reached; required for '
1152 . 'most administrative operations like '
1153 . 'setting global variables or killing threads of other users.'
1156 $administration_privTable[] = array('Process',
1158 __('Allows viewing processes of all users')
1160 $administration_privTable[] = array('Reload',
1162 __('Allows reloading server settings and flushing the server\'s caches.')
1164 $administration_privTable[] = array('Shutdown',
1166 __('Allows shutting down the server.')
1168 $administration_privTable[] = array('Show_db',
1170 __('Gives access to the complete list of databases.')
1173 $administration_privTable[] = array('Lock_tables',
1175 __('Allows locking tables for the current thread.')
1177 $administration_privTable[] = array('References',
1179 __('Has no effect in this MySQL version.')
1182 $administration_privTable[] = array('Repl_client',
1183 'REPLICATION CLIENT',
1184 __('Allows the user to ask where the slaves / masters are.')
1186 $administration_privTable[] = array('Repl_slave',
1187 'REPLICATION SLAVE',
1188 __('Needed for the replication slaves.')
1190 $administration_privTable[] = array('Create_user',
1192 __('Allows creating, dropping and renaming user accounts.')
1195 return $administration_privTable;
1199 * Get HTML snippet for global privileges table with check boxes
1201 * @param array $privTable privileges table array
1202 * @param array $privTable_names names of the privilege tables
1203 * (Data, Structure, Administration)
1204 * @param array $row first row from result or boolean false
1206 * @return string $html_output
1208 function PMA_getHtmlForGlobalPrivTableWithCheckboxes(
1209 $privTable, $privTable_names, $row
1212 foreach ($privTable as $i => $table) {
1213 $html_output .= '<fieldset>' . "\n"
1214 . '<legend>' . $privTable_names[$i] . '</legend>' . "\n";
1215 foreach ($table as $priv) {
1216 $html_output .= '<div class="item">' . "\n"
1217 . '<input type="checkbox" class="checkall"'
1218 . ' name="' . $priv[0] . '_priv" '
1219 . 'id="checkbox_' . $priv[0] . '_priv"'
1220 . ' value="Y" title="' . $priv[2] . '"'
1221 . (($row[$priv[0] . '_priv'] == 'Y')
1222 ?
' checked="checked"'
1226 . '<label for="checkbox_' . $priv[0] . '_priv">'
1227 . '<code><dfn title="' . $priv[2] . '">'
1228 . $priv[1] . '</dfn></code></label>' . "\n"
1231 $html_output .= '</fieldset>' . "\n";
1233 return $html_output;
1237 * Displays the fields used by the "new user" form as well as the
1238 * "change login information / copy user" form.
1240 * @param string $mode are we creating a new user or are we just
1241 * changing one? (allowed values: 'new', 'change')
1243 * @global array $cfg the phpMyAdmin configuration
1244 * @global ressource $user_link the database connection
1246 * @return string $html_output a HTML snippet
1248 function PMA_getHtmlForDisplayLoginInformationFields($mode = 'new')
1250 list($username_length, $hostname_length) = PMA_getUsernameAndHostnameLength();
1252 if (isset($GLOBALS['username']) && strlen($GLOBALS['username']) === 0) {
1253 $GLOBALS['pred_username'] = 'any';
1255 $html_output = '<fieldset id="fieldset_add_user_login">' . "\n"
1256 . '<legend>' . __('Login Information') . '</legend>' . "\n"
1257 . '<div class="item">' . "\n"
1258 . '<label for="select_pred_username">' . "\n"
1259 . ' ' . __('User name:') . "\n"
1261 . '<span class="options">' . "\n";
1263 $html_output .= '<select name="pred_username" id="select_pred_username" '
1264 . 'title="' . __('User name') . '"' . "\n";
1267 $html_output .= ' onchange="'
1268 . 'if (this.value == \'any\') {'
1269 . ' username.value = \'\'; '
1270 . ' user_exists_warning.style.display = \'none\'; '
1271 . '} else if (this.value == \'userdefined\') {'
1272 . ' username.focus(); username.select(); '
1275 $html_output .= '<option value="any"'
1276 . ((isset($GLOBALS['pred_username']) && $GLOBALS['pred_username'] == 'any')
1277 ?
' selected="selected"'
1280 . '</option>' . "\n";
1282 $html_output .= '<option value="userdefined"'
1283 . ((! isset($GLOBALS['pred_username'])
1284 ||
$GLOBALS['pred_username'] == 'userdefined'
1286 ?
' selected="selected"'
1288 . __('Use text field')
1289 . ':</option>' . "\n";
1291 $html_output .= '</select>' . "\n"
1294 $html_output .= '<input type="text" name="username" class="autofocus"'
1295 . ' maxlength="' . $username_length . '" title="' . __('User name') . '"'
1296 . (empty($GLOBALS['username'])
1298 : ' value="' . htmlspecialchars(
1299 isset($GLOBALS['new_username'])
1300 ?
$GLOBALS['new_username']
1301 : $GLOBALS['username']
1304 . ' onchange="pred_username.value = \'userdefined\';" />' . "\n";
1306 $html_output .= '<div id="user_exists_warning"'
1307 . ' name="user_exists_warning" style="display:none;">'
1308 . PMA_Message
::notice(
1310 'An account already exists with the same username '
1311 . 'but possibly a different hostname. '
1312 . 'Are you sure you wish to proceed?'
1316 $html_output .= '</div>';
1318 $html_output .= '<div class="item">' . "\n"
1319 . '<label for="select_pred_hostname">' . "\n"
1320 . ' ' . __('Host:') . "\n"
1321 . '</label>' . "\n";
1323 $html_output .= '<span class="options">' . "\n"
1324 . ' <select name="pred_hostname" id="select_pred_hostname" '
1325 . 'title="' . __('Host') . '"' . "\n";
1326 $_current_user = $GLOBALS['dbi']->fetchValue('SELECT USER();');
1327 if (! empty($_current_user)) {
1328 $thishost = str_replace(
1331 substr($_current_user, (strrpos($_current_user, '@') +
1))
1333 if ($thishost == 'localhost' ||
$thishost == '127.0.0.1') {
1337 $html_output .= ' onchange="'
1338 . 'if (this.value == \'any\') { '
1339 . ' hostname.value = \'%\'; '
1340 . '} else if (this.value == \'localhost\') { '
1341 . ' hostname.value = \'localhost\'; '
1345 : 'else if (this.value == \'thishost\') { '
1346 . ' hostname.value = \'' . addslashes(htmlspecialchars($thishost))
1350 . 'else if (this.value == \'hosttable\') { '
1351 . ' hostname.value = \'\'; '
1352 . '} else if (this.value == \'userdefined\') {'
1353 . ' hostname.focus(); hostname.select(); '
1355 unset($_current_user);
1357 // when we start editing a user, $GLOBALS['pred_hostname'] is not defined
1358 if (! isset($GLOBALS['pred_hostname']) && isset($GLOBALS['hostname'])) {
1359 switch (strtolower($GLOBALS['hostname'])) {
1362 $GLOBALS['pred_hostname'] = 'localhost';
1365 $GLOBALS['pred_hostname'] = 'any';
1368 $GLOBALS['pred_hostname'] = 'userdefined';
1372 $html_output .= '<option value="any"'
1373 . ((isset($GLOBALS['pred_hostname'])
1374 && $GLOBALS['pred_hostname'] == 'any'
1376 ?
' selected="selected"'
1379 . '</option>' . "\n"
1380 . '<option value="localhost"'
1381 . ((isset($GLOBALS['pred_hostname'])
1382 && $GLOBALS['pred_hostname'] == 'localhost'
1384 ?
' selected="selected"'
1387 . '</option>' . "\n";
1388 if (! empty($thishost)) {
1389 $html_output .= '<option value="thishost"'
1390 . ((isset($GLOBALS['pred_hostname'])
1391 && $GLOBALS['pred_hostname'] == 'thishost'
1393 ?
' selected="selected"'
1396 . '</option>' . "\n";
1399 $html_output .= '<option value="hosttable"'
1400 . ((isset($GLOBALS['pred_hostname'])
1401 && $GLOBALS['pred_hostname'] == 'hosttable'
1403 ?
' selected="selected"'
1405 . __('Use Host Table')
1406 . '</option>' . "\n";
1408 $html_output .= '<option value="userdefined"'
1409 . ((isset($GLOBALS['pred_hostname'])
1410 && $GLOBALS['pred_hostname'] == 'userdefined'
1412 ?
' selected="selected"'
1414 . __('Use text field:') . '</option>' . "\n"
1415 . '</select>' . "\n"
1418 $html_output .= '<input type="text" name="hostname" maxlength="'
1419 . $hostname_length . '" value="'
1420 . htmlspecialchars(isset($GLOBALS['hostname']) ?
$GLOBALS['hostname'] : '')
1421 . '" title="' . __('Host')
1422 . '" onchange="pred_hostname.value = \'userdefined\';" />' . "\n"
1423 . PMA_Util
::showHint(
1425 'When Host table is used, this field is ignored '
1426 . 'and values stored in Host table are used instead.'
1431 $html_output .= '<div class="item">' . "\n"
1432 . '<label for="select_pred_password">' . "\n"
1433 . ' ' . __('Password:') . "\n"
1435 . '<span class="options">' . "\n"
1436 . '<select name="pred_password" id="select_pred_password" title="'
1437 . __('Password') . '"' . "\n";
1439 $html_output .= ' onchange="'
1440 . 'if (this.value == \'none\') { '
1441 . ' pma_pw.value = \'\'; pma_pw2.value = \'\'; '
1442 . '} else if (this.value == \'userdefined\') { '
1443 . ' pma_pw.focus(); pma_pw.select(); '
1445 . ($mode == 'change' ?
'<option value="keep" selected="selected">'
1446 . __('Do not change the password')
1447 . '</option>' . "\n" : '')
1448 . '<option value="none"';
1450 if (isset($GLOBALS['username']) && $mode != 'change') {
1451 $html_output .= ' selected="selected"';
1453 $html_output .= '>' . __('No Password') . '</option>' . "\n"
1454 . '<option value="userdefined"'
1455 . (isset($GLOBALS['username']) ?
'' : ' selected="selected"') . '>'
1456 . __('Use text field')
1457 . ':</option>' . "\n"
1458 . '</select>' . "\n"
1460 . '<input type="password" id="text_pma_pw" name="pma_pw" '
1461 . 'title="' . __('Password') . '" '
1462 . 'onchange="pred_password.value = \'userdefined\';" />' . "\n"
1465 $html_output .= '<div class="item" '
1466 . 'id="div_element_before_generate_password">' . "\n"
1467 . '<label for="text_pma_pw2">' . "\n"
1468 . ' ' . __('Re-type:') . "\n"
1470 . '<span class="options"> </span>' . "\n"
1471 . '<input type="password" name="pma_pw2" id="text_pma_pw2" '
1472 . 'title="' . __('Re-type') . '" '
1473 . 'onchange="pred_password.value = \'userdefined\';" />' . "\n"
1475 // Generate password added here via jQuery
1476 . '</fieldset>' . "\n";
1478 return $html_output;
1479 } // end of the 'PMA_displayUserAndHostFields()' function
1482 * Get username and hostname length
1484 * @return array username length and hostname length
1486 function PMA_getUsernameAndHostnameLength()
1488 $fields_info = $GLOBALS['dbi']->getColumns('mysql', 'user', null, true);
1489 $username_length = 16;
1490 $hostname_length = 41;
1491 foreach ($fields_info as $val) {
1492 if ($val['Field'] == 'User') {
1493 strtok($val['Type'], '()');
1494 $value = strtok('()');
1495 if (is_int($value)) {
1496 $username_length = $value;
1498 } elseif ($val['Field'] == 'Host') {
1499 strtok($val['Type'], '()');
1500 $value = strtok('()');
1501 if (is_int($value)) {
1502 $hostname_length = $value;
1506 return array($username_length, $hostname_length);
1510 * Returns all the grants for a certain user on a certain host
1511 * Used in the export privileges for all users section
1513 * @param string $user User name
1514 * @param string $host Host name
1516 * @return string containing all the grants text
1518 function PMA_getGrants($user, $host)
1520 $grants = $GLOBALS['dbi']->fetchResult(
1522 . PMA_Util
::sqlAddSlashes($user) . "'@'"
1523 . PMA_Util
::sqlAddSlashes($host) . "'"
1526 foreach ($grants as $one_grant) {
1527 $response .= $one_grant . ";\n\n";
1530 } // end of the 'PMA_getGrants()' function
1533 * Update password and get message for password updating
1535 * @param string $err_url error url
1536 * @param string $username username
1537 * @param string $hostname hostname
1539 * @return string $message success or error message after updating password
1541 function PMA_updatePassword($err_url, $username, $hostname)
1543 // similar logic in user_password.php
1546 if (empty($_REQUEST['nopass'])
1547 && isset($_POST['pma_pw'])
1548 && isset($_POST['pma_pw2'])
1550 if ($_POST['pma_pw'] != $_POST['pma_pw2']) {
1551 $message = PMA_Message
::error(__('The passwords aren\'t the same!'));
1552 } elseif (empty($_POST['pma_pw']) ||
empty($_POST['pma_pw2'])) {
1553 $message = PMA_Message
::error(__('The password is empty!'));
1557 // here $nopass could be == 1
1558 if (empty($message)) {
1561 = (! empty($_REQUEST['pw_hash']) && $_REQUEST['pw_hash'] == 'old'
1567 // in $sql_query which will be displayed, hide the password
1568 $sql_query = 'SET PASSWORD FOR \''
1569 . PMA_Util
::sqlAddSlashes($username)
1570 . '\'@\'' . PMA_Util
::sqlAddSlashes($hostname) . '\' = '
1571 . (($_POST['pma_pw'] == '')
1573 : $hashing_function . '(\''
1574 . preg_replace('@.@s', '*', $_POST['pma_pw']) . '\')');
1576 $local_query = 'SET PASSWORD FOR \''
1577 . PMA_Util
::sqlAddSlashes($username)
1578 . '\'@\'' . PMA_Util
::sqlAddSlashes($hostname) . '\' = '
1579 . (($_POST['pma_pw'] == '') ?
'\'\'' : $hashing_function
1580 . '(\'' . PMA_Util
::sqlAddSlashes($_POST['pma_pw']) . '\')');
1582 $GLOBALS['dbi']->tryQuery($local_query)
1583 or PMA_Util
::mysqlDie(
1584 $GLOBALS['dbi']->getError(), $sql_query, false, $err_url
1586 $message = PMA_Message
::success(
1587 __('The password for %s was changed successfully.')
1590 '\'' . htmlspecialchars($username)
1591 . '\'@\'' . htmlspecialchars($hostname) . '\''
1598 * Revokes privileges and get message and SQL query for privileges revokes
1600 * @param string $db_and_table wildcard Escaped database+table specification
1601 * @param string $dbname database name
1602 * @param string $tablename table name
1603 * @param string $username username
1604 * @param string $hostname host name
1606 * @return array ($message, $sql_query)
1608 function PMA_getMessageAndSqlQueryForPrivilegesRevoke($db_and_table, $dbname,
1609 $tablename, $username, $hostname
1611 $db_and_table = PMA_wildcardEscapeForGrant($dbname, $tablename);
1613 $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
1615 . PMA_Util
::sqlAddSlashes($username) . '\'@\''
1616 . PMA_Util
::sqlAddSlashes($hostname) . '\';';
1618 $sql_query1 = 'REVOKE GRANT OPTION ON ' . $db_and_table
1619 . ' FROM \'' . PMA_Util
::sqlAddSlashes($username) . '\'@\''
1620 . PMA_Util
::sqlAddSlashes($hostname) . '\';';
1622 $GLOBALS['dbi']->query($sql_query0);
1623 if (! $GLOBALS['dbi']->tryQuery($sql_query1)) {
1624 // this one may fail, too...
1627 $sql_query = $sql_query0 . ' ' . $sql_query1;
1628 $message = PMA_Message
::success(
1629 __('You have revoked the privileges for %s.')
1632 '\'' . htmlspecialchars($username)
1633 . '\'@\'' . htmlspecialchars($hostname) . '\''
1636 return array($message, $sql_query);
1640 * Get a WITH clause for 'update privileges' and 'add user'
1642 * @return string $sql_query
1644 function PMA_getWithClauseForAddUserAndUpdatePrivs()
1647 if (isset($_POST['Grant_priv']) && $_POST['Grant_priv'] == 'Y') {
1648 $sql_query .= ' GRANT OPTION';
1650 if (isset($_POST['max_questions'])) {
1651 $max_questions = max(0, (int)$_POST['max_questions']);
1652 $sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
1654 if (isset($_POST['max_connections'])) {
1655 $max_connections = max(0, (int)$_POST['max_connections']);
1656 $sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
1658 if (isset($_POST['max_updates'])) {
1659 $max_updates = max(0, (int)$_POST['max_updates']);
1660 $sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
1662 if (isset($_POST['max_user_connections'])) {
1663 $max_user_connections = max(0, (int)$_POST['max_user_connections']);
1664 $sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
1666 return ((!empty($sql_query)) ?
'WITH' . $sql_query : '');
1670 * Get HTML for addUsersForm, This function call if isset($_REQUEST['adduser'])
1672 * @param string $dbname database name
1674 * @return string HTML for addUserForm
1676 function PMA_getHtmlForAddUser($dbname)
1678 $html_output = '<h2>' . "\n"
1679 . PMA_Util
::getIcon('b_usradd.png') . __('Add user') . "\n"
1681 . '<form name="usersForm" class="ajax" id="addUsersForm"'
1682 . ' action="server_privileges.php" method="post" autocomplete="off" >' . "\n"
1683 . PMA_URL_getHiddenInputs('', '')
1684 . PMA_getHtmlForDisplayLoginInformationFields('new');
1686 $html_output .= '<fieldset id="fieldset_add_user_database">' . "\n"
1687 . '<legend>' . __('Database for user') . '</legend>' . "\n";
1689 $html_output .= PMA_Util
::getCheckbox(
1691 __('Create database with same name and grant all privileges.'),
1694 $html_output .= '<br />' . "\n";
1695 $html_output .= PMA_Util
::getCheckbox(
1697 __('Grant all privileges on wildcard name (username\\_%).'),
1700 $html_output .= '<br />' . "\n";
1702 if (! empty($dbname) ) {
1703 $html_output .= PMA_Util
::getCheckbox(
1706 __('Grant all privileges on database "%s".'),
1707 htmlspecialchars($dbname)
1712 $html_output .= '<input type="hidden" name="dbname" value="'
1713 . htmlspecialchars($dbname) . '" />' . "\n";
1714 $html_output .= '<br />' . "\n";
1717 $html_output .= '</fieldset>' . "\n";
1718 $html_output .= PMA_getHtmlToDisplayPrivilegesTable('*', '*', false);
1719 $html_output .= '<fieldset id="fieldset_add_user_footer" class="tblFooters">'
1721 . '<input type="submit" name="adduser_submit" '
1722 . 'value="' . __('Go') . '" />' . "\n"
1723 . '</fieldset>' . "\n"
1726 return $html_output;
1730 * Get the list of privileges and list of compared privileges as strings
1731 * and return a array that contains both strings
1733 * @return array $list_of_privileges, $list_of_compared_privileges
1735 function PMA_getListOfPrivilegesAndComparedPrivileges()
1749 . '`References_priv`, '
1750 . '`Create_tmp_table_priv`, '
1751 . '`Lock_tables_priv`, '
1752 . '`Create_view_priv`, '
1753 . '`Show_view_priv`, '
1754 . '`Create_routine_priv`, '
1755 . '`Alter_routine_priv`, '
1758 $list_of_compared_privileges
1759 = '`Select_priv` = \'N\''
1760 . ' AND `Insert_priv` = \'N\''
1761 . ' AND `Update_priv` = \'N\''
1762 . ' AND `Delete_priv` = \'N\''
1763 . ' AND `Create_priv` = \'N\''
1764 . ' AND `Drop_priv` = \'N\''
1765 . ' AND `Grant_priv` = \'N\''
1766 . ' AND `References_priv` = \'N\''
1767 . ' AND `Create_tmp_table_priv` = \'N\''
1768 . ' AND `Lock_tables_priv` = \'N\''
1769 . ' AND `Create_view_priv` = \'N\''
1770 . ' AND `Show_view_priv` = \'N\''
1771 . ' AND `Create_routine_priv` = \'N\''
1772 . ' AND `Alter_routine_priv` = \'N\''
1773 . ' AND `Execute_priv` = \'N\'';
1775 if (PMA_MYSQL_INT_VERSION
>= 50106) {
1776 $list_of_privileges .=
1779 $list_of_compared_privileges .=
1780 ' AND `Event_priv` = \'N\''
1781 . ' AND `Trigger_priv` = \'N\'';
1783 return array($list_of_privileges, $list_of_compared_privileges);
1787 * Get the HTML for user form and check the privileges for a particular database.
1789 * @param string $db database name
1791 * @return string $html_output
1793 function PMA_getHtmlForSpecificDbPrivileges($db)
1795 // check the privileges for a particular database.
1796 $html_output = '<form id="usersForm" action="server_privileges.php">'
1797 . '<fieldset>' . "\n";
1798 $html_output .= '<legend>' . "\n"
1799 . PMA_Util
::getIcon('b_usrcheck.png')
1802 __('Users having access to "%s"'),
1803 '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?'
1804 . PMA_URL_getCommon($db) . '">'
1805 . htmlspecialchars($db)
1809 . '</legend>' . "\n";
1811 $html_output .= '<table id="dbspecificuserrights" class="data">' . "\n"
1813 . '<tr><th>' . __('User') . '</th>' . "\n"
1814 . '<th>' . __('Host') . '</th>' . "\n"
1815 . '<th>' . __('Type') . '</th>' . "\n"
1816 . '<th>' . __('Privileges') . '</th>' . "\n"
1817 . '<th>' . __('Grant') . '</th>' . "\n"
1818 . '<th>' . __('Action') . '</th>' . "\n"
1820 . '</thead>' . "\n";
1822 // now, we build the table...
1823 list($list_of_privileges, $list_of_compared_privileges)
1824 = PMA_getListOfPrivilegesAndComparedPrivileges();
1826 $sql_query = '(SELECT ' . $list_of_privileges . ', `Db`, \'d\' AS `Type`'
1827 .' FROM `mysql`.`db`'
1828 .' WHERE \'' . PMA_Util
::sqlAddSlashes($db)
1831 .' AND NOT (' . $list_of_compared_privileges. ')) '
1833 .'(SELECT ' . $list_of_privileges . ', \'*\' AS `Db`, \'g\' AS `Type`'
1834 .' FROM `mysql`.`user` '
1835 .' WHERE NOT (' . $list_of_compared_privileges . ')) '
1836 .' ORDER BY `User` ASC,'
1839 $res = $GLOBALS['dbi']->query($sql_query);
1842 while ($row = $GLOBALS['dbi']->fetchAssoc($res)) {
1843 $user = $row['User'];
1844 $host = $row['Host'];
1845 if (! isset($privMap[$user])) {
1846 $privMap[$user] = array();
1848 if (! isset($privMap[$user][$host])) {
1849 $privMap[$user][$host] = array();
1851 $privMap[$user][$host][] = $row;
1854 $html_output .= PMA_getHtmlTableBodyForSpecificDbOrTablePrivs($privMap, $db);
1855 $html_output .= '</table>'
1859 if ($GLOBALS['is_ajax_request'] == true
1860 && empty($_REQUEST['ajax_page_request'])
1862 $message = PMA_Message
::success(__('User has been added.'));
1863 $response = PMA_Response
::getInstance();
1864 $response->addJSON('message', $message);
1865 $response->addJSON('user_form', $html_output);
1868 // Offer to create a new user for the current database
1869 $html_output .= '<fieldset id="fieldset_add_user">' . "\n"
1870 . '<legend>' . _pgettext('Create new user', 'New') . '</legend>' . "\n";
1872 $html_output .= '<a href="server_privileges.php'
1873 . PMA_URL_getCommon(
1880 . PMA_URL_getCommon(array('checkprivsdb' => $db))
1881 . '" class="ajax" name="db_specific">' . "\n"
1882 . PMA_Util
::getIcon('b_usradd.png')
1883 . ' ' . __('Add user') . '</a>' . "\n";
1885 $html_output .= '</fieldset>' . "\n";
1887 return $html_output;
1891 * Get the HTML for user form and check the privileges for a particular table.
1893 * @param string $db database name
1894 * @param string $table table name
1896 * @return string $html_output
1898 function PMA_getHtmlForSpecificTablePrivileges($db, $table)
1900 // check the privileges for a particular table.
1901 $html_output = '<form id="usersForm" action="server_privileges.php">';
1902 $html_output .= '<fieldset>';
1903 $html_output .= '<legend>'
1904 . PMA_Util
::getIcon('b_usrcheck.png')
1906 __('Users having access to "%s"'),
1907 '<a href="' . $GLOBALS['cfg']['DefaultTabTable']
1908 . PMA_URL_getCommon(
1914 . htmlspecialchars($db) . '.' . htmlspecialchars($table)
1919 $html_output .= '<table id="tablespecificuserrights" class="data">';
1920 $html_output .= '<thead>'
1921 . '<tr><th>' . __('User') . '</th>'
1922 . '<th>' . __('Host') . '</th>'
1923 . '<th>' . __('Type') . '</th>'
1924 . '<th>' . __('Privileges') . '</th>'
1925 . '<th>' . __('Grant') . '</th>'
1926 . '<th>' . __('Action') . '</th>'
1930 list($list_of_privileges, $list_of_compared_privileges)
1931 = PMA_getListOfPrivilegesAndComparedPrivileges();
1934 . " SELECT " . $list_of_privileges . ", '*' AS `Db`, 'g' AS `Type`"
1935 . " FROM `mysql`.`user`"
1936 . " WHERE NOT (" . $list_of_compared_privileges . ")"
1940 . " SELECT " . $list_of_privileges . ", `Db`, 'd' AS `Type`"
1941 . " FROM `mysql`.`db`"
1942 . " WHERE '" . PMA_Util
::sqlAddSlashes($db) . "' LIKE `Db`"
1943 . " AND NOT (" . $list_of_compared_privileges. ")"
1945 . " ORDER BY `User` ASC, `Host` ASC, `Db` ASC;";
1946 $res = $GLOBALS['dbi']->query($sql_query);
1949 while ($row = $GLOBALS['dbi']->fetchAssoc($res)) {
1950 $user = $row['User'];
1951 $host = $row['Host'];
1952 if (! isset($privMap[$user])) {
1953 $privMap[$user] = array();
1955 if (! isset($privMap[$user][$host])) {
1956 $privMap[$user][$host] = array();
1958 $privMap[$user][$host][] = $row;
1961 $sql_query = "SELECT `User`, `Host`, `Db`,"
1962 . " 't' AS `Type`, `Table_name`, `Table_priv`"
1963 . " FROM `mysql`.`tables_priv`"
1964 . " WHERE '" . PMA_Util
::sqlAddSlashes($db) . "' LIKE `Db`"
1965 . " AND '" . PMA_Util
::sqlAddSlashes($table) . "' LIKE `Table_name`"
1966 . " AND NOT (`Table_priv` = '' AND Column_priv = '')"
1967 . " ORDER BY `User` ASC, `Host` ASC, `Db` ASC, `Table_priv` ASC;";
1968 $res = $GLOBALS['dbi']->query($sql_query);
1970 while ($row = $GLOBALS['dbi']->fetchAssoc($res)) {
1971 $user = $row['User'];
1972 $host = $row['Host'];
1973 if (! isset($privMap[$user])) {
1974 $privMap[$user] = array();
1976 if (! isset($privMap[$user][$host])) {
1977 $privMap[$user][$host] = array();
1979 $privMap[$user][$host][] = $row;
1982 $html_output .= PMA_getHtmlTableBodyForSpecificDbOrTablePrivs(
1983 $privMap, $db, $table
1985 $html_output .= '</table>';
1986 $html_output .= '</fieldset>';
1987 $html_output .= '</form>';
1989 // Offer to create a new user for the current database
1990 $html_output .= '<fieldset id="fieldset_add_user">'
1991 . '<legend>' . _pgettext('Create new user', 'New') . '</legend>';
1992 $html_output .= '<a href="server_privileges.php'
1993 . PMA_URL_getCommon(
1997 'tablename' => $table
2000 . '" rel="' . PMA_URL_getCommon(
2001 array('checkprivsdb' => $db, 'checkprivstable' => $table)
2003 . '" class="ajax" name="table_specific">'
2004 . PMA_Util
::getIcon('b_usradd.png') . __('Add user') . '</a>';
2006 $html_output .= '</fieldset>';
2007 return $html_output;
2011 * Get HTML snippet for table body of specific database or table privileges
2013 * @param boolean $privMap priviledge map
2014 * @param boolean $db database
2015 * @param boolean $table table
2017 * @return string $html_output
2019 function PMA_getHtmlTableBodyForSpecificDbOrTablePrivs($privMap, $db, $table = null)
2021 $html_output = '<tbody>';
2023 if (! empty($privMap)) {
2024 foreach ($privMap as $current_user => $val) {
2025 foreach ($val as $current_host => $current_privileges) {
2026 $html_output .= '<tr class="noclick '
2027 . ($odd_row ?
'odd' : 'even') . '">';
2030 $html_output .= '<td';
2031 if (count($current_privileges) > 1) {
2032 $html_output .= ' rowspan="' . count($current_privileges) . '"';
2034 $html_output .= '>';
2035 if (empty($current_user)) {
2036 $html_output .= '<span style="color: #FF0000">'
2037 . __('Any') . '</span>';
2039 $html_output .= htmlspecialchars($current_user);
2041 $html_output .= '</td>';
2044 $html_output .= '<td';
2045 if (count($current_privileges) > 1) {
2046 $html_output .= ' rowspan="' . count($current_privileges) . '"';
2048 $html_output .= '>';
2049 $html_output .= htmlspecialchars($current_host);
2050 $html_output .= '</td>';
2052 for ($i = 0; $i < count($current_privileges); $i++
) {
2053 $current = $current_privileges[$i];
2056 $html_output .= '<td>';
2057 if ($current['Type'] == 'g') {
2058 $html_output .= __('global');
2059 } elseif ($current['Type'] == 'd') {
2060 if ($current['Db'] == PMA_Util
::escapeMysqlWildcards($db)) {
2061 $html_output .= __('database-specific');
2063 $html_output .= __('wildcard'). ': '
2065 . htmlspecialchars($current['Db'])
2068 } elseif ($current['Type'] == 't') {
2069 $html_output .= __('table-specific');
2071 $html_output .= '</td>';
2074 $html_output .= '<td>';
2075 if (isset($current['Table_name'])) {
2076 $privList = explode(',', $current['Table_priv']);
2078 $grantsArr = PMA_getTableGrantsArray();
2079 foreach ($grantsArr as $grant) {
2080 $privs[$grant[0]] = 'N';
2081 foreach ($privList as $priv) {
2082 if ($grant[0] == $priv) {
2083 $privs[$grant[0]] = 'Y';
2087 $html_output .= '<code>'
2090 PMA_extractPrivInfo($privs, true, true)
2094 $html_output .= '<code>'
2097 PMA_extractPrivInfo($current, true, false)
2101 $html_output .= '</td>';
2104 $html_output .= '<td>';
2105 $containsGrant = false;
2106 if (isset($current['Table_name'])) {
2107 $privList = explode(',', $current['Table_priv']);
2108 foreach ($privList as $priv) {
2109 if ($priv == 'Grant') {
2110 $containsGrant = true;
2114 $containsGrant = $current['Grant_priv'] == 'Y';
2116 $html_output .= ($containsGrant ?
__('Yes') : __('No'));
2117 $html_output .= '</td>';
2120 $html_output .= '<td>';
2121 $specific_db = (isset($current['Db']) && $current['Db'] != '*')
2122 ?
$current['Db'] : '';
2123 $specific_table = (isset($current['Table_name'])
2124 && $current['Table_name'] != '*')
2125 ?
$current['Table_name'] : '';
2126 $html_output .= PMA_getUserEditLink(
2132 $html_output .= '</td>';
2134 $html_output .= '</tr>';
2135 if (($i +
1) < count($current_privileges)) {
2136 $html_output .= '<tr class="noclick '
2137 . ($odd_row ?
'odd' : 'even') . '">';
2140 $odd_row = ! $odd_row;
2144 $html_output .= '<tr class="odd">'
2145 . '<td colspan="6">'
2146 . __('No user found.')
2150 $html_output .= '</tbody>';
2152 return $html_output;
2156 * Returns edit link for a user.
2158 * @param string $username User name
2159 * @param string $hostname Host name
2160 * @param string $dbname Database name
2161 * @param string $tablename Table name
2163 * @return HTML code with link
2165 function PMA_getUserEditLink($username, $hostname, $dbname = '', $tablename = '')
2167 return '<a class="edit_user_anchor ajax"'
2168 . ' href="server_privileges.php'
2169 . PMA_URL_getCommon(
2171 'username' => $username,
2172 'hostname' => $hostname,
2173 'dbname' => $dbname,
2174 'tablename' => $tablename,
2178 . PMA_Util
::getIcon('b_usredit.png', __('Edit Privileges'))
2183 * Returns revoke link for a user.
2185 * @param string $username User name
2186 * @param string $hostname Host name
2187 * @param string $dbname Database name
2188 * @param string $tablename Table name
2190 * @return HTML code with link
2192 function PMA_getUserRevokeLink($username, $hostname, $dbname = '', $tablename = '')
2194 return '<a href="server_privileges.php'
2195 . PMA_URL_getCommon(
2197 'username' => $username,
2198 'hostname' => $hostname,
2199 'dbname' => $dbname,
2200 'tablename' => $tablename,
2205 . PMA_Util
::getIcon('b_usrdrop.png', __('Revoke'))
2210 * Returns export link for a user.
2212 * @param string $username User name
2213 * @param string $hostname Host name
2214 * @param string $initial Initial value
2216 * @return HTML code with link
2218 function PMA_getUserExportLink($username, $hostname, $initial = '')
2220 return '<a class="export_user_anchor ajax"'
2221 . ' href="server_privileges.php'
2222 . PMA_URL_getCommon(
2224 'username' => $username,
2225 'hostname' => $hostname,
2226 'initial' => $initial,
2231 . PMA_Util
::getIcon('b_tblexport.png', __('Export'))
2236 * This function return the extra data array for the ajax behavior
2238 * @param string $password password
2239 * @param string $sql_query sql query
2240 * @param string $hostname hostname
2241 * @param string $username username
2243 * @return array $extra_data
2245 function PMA_getExtraDataForAjaxBehavior(
2246 $password, $sql_query, $hostname, $username
2248 if (isset($GLOBALS['dbname'])) {
2249 //if (preg_match('/\\\\(?:_|%)/i', $dbname)) {
2250 if (preg_match('/(?<!\\\\)(?:_|%)/i', $GLOBALS['dbname'])) {
2251 $dbname_is_wildcard = true;
2253 $dbname_is_wildcard = false;
2257 $extra_data = array();
2258 if (strlen($sql_query)) {
2259 $extra_data['sql_query']
2260 = PMA_Util
::getMessage(null, $sql_query);
2263 if (isset($_REQUEST['adduser_submit']) ||
isset($_REQUEST['change_copy'])) {
2265 * generate html on the fly for the new user that was just created.
2267 $new_user_string = '<tr>'."\n"
2268 . '<td> <input type="checkbox" name="selected_usr[]" '
2269 . 'id="checkbox_sel_users_"'
2271 . htmlspecialchars($username)
2272 . '&#27;' . htmlspecialchars($hostname) . '" />'
2274 . '<td><label for="checkbox_sel_users_">'
2275 . (empty($_REQUEST['username'])
2276 ?
'<span style="color: #FF0000">' . __('Any') . '</span>'
2277 : htmlspecialchars($username) ) . '</label></td>' . "\n"
2278 . '<td>' . htmlspecialchars($hostname) . '</td>' . "\n";
2280 $new_user_string .= '<td>';
2282 if (! empty($password) ||
isset($_POST['pma_pw'])) {
2283 $new_user_string .= __('Yes');
2285 $new_user_string .= '<span style="color: #FF0000">'
2290 $new_user_string .= '</td>'."\n";
2291 $new_user_string .= '<td>'
2292 . '<code>' . join(', ', PMA_extractPrivInfo('', true)) . '</code>'
2293 . '</td>'; //Fill in privileges here
2294 $new_user_string .= '<td class="usrGroup"></td>';
2295 $new_user_string .= '<td>';
2297 if ((isset($_POST['Grant_priv']) && $_POST['Grant_priv'] == 'Y')) {
2298 $new_user_string .= __('Yes');
2300 $new_user_string .= __('No');
2303 $new_user_string .='</td>';
2305 $new_user_string .= '<td>'
2306 . PMA_getUserEditLink($username, $hostname)
2308 $new_user_string .= '<td>'
2309 . PMA_getUserExportLink(
2312 isset($_GET['initial']) ?
$_GET['initial'] : ''
2316 $new_user_string .= '</tr>';
2318 $extra_data['new_user_string'] = $new_user_string;
2321 * Generate the string for this alphabet's initial, to update the user
2324 $new_user_initial = strtoupper(substr($username, 0, 1));
2325 $new_user_initial_string = '<a href="server_privileges.php'
2326 . PMA_URL_getCommon(array('initial' => $new_user_initial)) .'">'
2327 . $new_user_initial . '</a>';
2328 $extra_data['new_user_initial'] = $new_user_initial;
2329 $extra_data['new_user_initial_string'] = $new_user_initial_string;
2332 if (isset($_POST['update_privs'])) {
2333 $extra_data['db_specific_privs'] = false;
2334 $extra_data['db_wildcard_privs'] = false;
2335 if (isset($dbname_is_wildcard)) {
2336 $extra_data['db_specific_privs'] = ! $dbname_is_wildcard;
2337 $extra_data['db_wildcard_privs'] = $dbname_is_wildcard;
2339 $new_privileges = join(', ', PMA_extractPrivInfo('', true));
2341 $extra_data['new_privileges'] = $new_privileges;
2344 if (isset($_REQUEST['validate_username'])) {
2345 $sql_query = "SELECT * FROM `mysql`.`user` WHERE `User` = '"
2346 . $_REQUEST['username'] . "';";
2347 $res = $GLOBALS['dbi']->query($sql_query);
2348 $row = $GLOBALS['dbi']->fetchRow($res);
2350 $extra_data['user_exists'] = false;
2352 $extra_data['user_exists'] = true;
2360 * Get the HTML snippet for change user login information
2362 * @param string $username username
2363 * @param string $hostname host name
2365 * @return string HTML snippet
2367 function PMA_getChangeLoginInformationHtmlForm($username, $hostname)
2370 '4' => __('… keep the old one.'),
2371 '1' => __('… delete the old one from the user tables.'),
2373 '… revoke all active privileges from '
2374 . 'the old one and delete it afterwards.'
2377 '… delete the old one from the user tables '
2378 . 'and reload the privileges afterwards.'
2383 $html_output = '<form action="server_privileges.php" '
2384 . 'method="post" class="copyUserForm' . $class .'">' . "\n"
2385 . PMA_URL_getHiddenInputs('', '')
2386 . '<input type="hidden" name="old_username" '
2387 . 'value="' . htmlspecialchars($username) . '" />' . "\n"
2388 . '<input type="hidden" name="old_hostname" '
2389 . 'value="' . htmlspecialchars($hostname) . '" />' . "\n"
2390 . '<fieldset id="fieldset_change_copy_user">' . "\n"
2391 . '<legend>' . __('Change Login Information / Copy User')
2392 . '</legend>' . "\n"
2393 . PMA_getHtmlForDisplayLoginInformationFields('change');
2395 $html_output .= '<fieldset id="fieldset_mode">' . "\n"
2397 . __('Create a new user with the same privileges and …')
2398 . '</legend>' . "\n";
2399 $html_output .= PMA_Util
::getRadioFields(
2400 'mode', $choices, '4', true
2402 $html_output .= '</fieldset>' . "\n"
2403 . '</fieldset>' . "\n";
2405 $html_output .= '<fieldset id="fieldset_change_copy_user_footer" '
2406 . 'class="tblFooters">' . "\n"
2407 . '<input type="submit" name="change_copy" '
2408 . 'value="' . __('Go') . '" />' . "\n"
2409 . '</fieldset>' . "\n"
2412 return $html_output;
2416 * Provide a line with links to the relevant database and table
2418 * @param string $url_dbname url database name that urlencode() string
2419 * @param string $dbname database name
2420 * @param string $tablename table name
2422 * @return string HTML snippet
2424 function PMA_getLinkToDbAndTable($url_dbname, $dbname, $tablename)
2426 $html_output = '[ ' . __('Database')
2427 . ' <a href="' . $GLOBALS['cfg']['DefaultTabDatabase']
2428 . PMA_URL_getCommon(
2430 'db' => $url_dbname,
2435 . htmlspecialchars($dbname) . ': '
2436 . PMA_Util
::getTitleForTarget(
2437 $GLOBALS['cfg']['DefaultTabDatabase']
2441 if (strlen($tablename)) {
2442 $html_output .= ' [ ' . __('Table') . ' <a href="'
2443 . $GLOBALS['cfg']['DefaultTabTable']
2444 . PMA_URL_getCommon(
2446 'db' => $url_dbname,
2447 'table' => $tablename,
2451 . '">' . htmlspecialchars($tablename) . ': '
2452 . PMA_Util
::getTitleForTarget(
2453 $GLOBALS['cfg']['DefaultTabTable']
2457 return $html_output;
2461 * no db name given, so we want all privs for the given user
2462 * db name was given, so we want all user specific rights for this db
2463 * So this function returns user rights as an array
2465 * @param array $tables tables
2466 * @param string $user_host_condition a where clause that containd user's host
2468 * @param string $dbname database name
2470 * @return array $db_rights database rights
2472 function PMA_getUserSpecificRights($tables, $user_host_condition, $dbname)
2474 if (! strlen($dbname)) {
2475 $tables_to_search_for_users = array(
2476 'tables_priv', 'columns_priv',
2478 $dbOrTableName = 'Db';
2480 $user_host_condition .=
2483 . PMA_Util
::sqlAddSlashes($dbname, true) . "'";
2484 $tables_to_search_for_users = array('columns_priv',);
2485 $dbOrTableName = 'Table_name';
2488 $db_rights_sqls = array();
2489 foreach ($tables_to_search_for_users as $table_search_in) {
2490 if (in_array($table_search_in, $tables)) {
2491 $db_rights_sqls[] = '
2492 SELECT DISTINCT `' . $dbOrTableName .'`
2493 FROM `mysql`.' . PMA_Util
::backquote($table_search_in)
2494 . $user_host_condition;
2498 $user_defaults = array(
2499 $dbOrTableName => '',
2500 'Grant_priv' => 'N',
2501 'privs' => array('USAGE'),
2502 'Column_priv' => true,
2506 $db_rights = array();
2508 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
2509 .' ORDER BY `' . $dbOrTableName .'` ASC';
2511 $db_rights_result = $GLOBALS['dbi']->query($db_rights_sql);
2513 while ($db_rights_row = $GLOBALS['dbi']->fetchAssoc($db_rights_result)) {
2514 $db_rights_row = array_merge($user_defaults, $db_rights_row);
2515 if (! strlen($dbname)) {
2516 // only Db names in the table `mysql`.`db` uses wildcards
2517 // as we are in the db specific rights display we want
2518 // all db names escaped, also from other sources
2519 $db_rights_row['Db'] = PMA_Util
::escapeMysqlWildcards(
2520 $db_rights_row['Db']
2523 $db_rights[$db_rights_row[$dbOrTableName]] = $db_rights_row;
2526 $GLOBALS['dbi']->freeResult($db_rights_result);
2528 if (! strlen($dbname)) {
2529 $sql_query = 'SELECT * FROM `mysql`.`db`'
2530 . $user_host_condition . ' ORDER BY `Db` ASC';
2532 $sql_query = 'SELECT `Table_name`,'
2534 .' IF(`Column_priv` = _latin1 \'\', 0, 1)'
2535 .' AS \'Column_priv\''
2536 .' FROM `mysql`.`tables_priv`'
2537 . $user_host_condition
2538 .' ORDER BY `Table_name` ASC;';
2541 $result = $GLOBALS['dbi']->query($sql_query);
2544 while ($row = $GLOBALS['dbi']->fetchAssoc($result)) {
2545 if (isset($db_rights[$row[$dbOrTableName]])) {
2546 $db_rights[$row[$dbOrTableName]]
2547 = array_merge($db_rights[$row[$dbOrTableName]], $row);
2549 $db_rights[$row[$dbOrTableName]] = $row;
2551 if (! strlen($dbname)) {
2552 // there are db specific rights for this user
2553 // so we can drop this db rights
2554 $db_rights[$row['Db']]['can_delete'] = true;
2557 $GLOBALS['dbi']->freeResult($result);
2562 * Display user rights in table rows(Table specific or database specific privs)
2564 * @param array $db_rights user's database rights array
2565 * @param string $dbname database name
2566 * @param string $hostname host name
2567 * @param string $username username
2569 * @return array $found_rows, $html_output
2571 function PMA_getHtmlForDisplayUserRightsInRows($db_rights, $dbname,
2572 $hostname, $username
2575 $found_rows = array();
2577 if (count($db_rights) < 1) {
2578 $html_output .= '<tr class="odd">' . "\n"
2579 . '<td colspan="6"><center><i>' . __('None') . '</i></center></td>' . "\n"
2583 //while ($row = $GLOBALS['dbi']->fetchAssoc($res)) {
2584 foreach ($db_rights as $row) {
2585 $found_rows[] = (! strlen($dbname)) ?
$row['Db'] : $row['Table_name'];
2587 $html_output .= '<tr class="' . ($odd_row ?
'odd' : 'even') . '">' . "\n"
2590 (! strlen($dbname)) ?
$row['Db'] : $row['Table_name']
2593 . '<td><code>' . "\n"
2597 PMA_extractPrivInfo($row, true)
2599 . '</code></td>' . "\n"
2601 . ((((! strlen($dbname)) && $row['Grant_priv'] == 'Y')
2603 && in_array('Grant', explode(',', $row['Table_priv']))))
2608 if (! empty($row['Table_privs']) ||
! empty ($row['Column_priv'])) {
2609 $html_output .= __('Yes');
2611 $html_output .= __('No');
2613 $html_output .= '</td>' . "\n"
2615 $html_output .= PMA_getUserEditLink(
2618 (! strlen($dbname)) ?
$row['Db'] : $dbname,
2619 (! strlen($dbname)) ?
'' : $row['Table_name']
2621 $html_output .= '</td>' . "\n"
2623 if (! empty($row['can_delete'])
2624 ||
isset($row['Table_name'])
2625 && strlen($row['Table_name'])
2627 $html_output .= PMA_getUserRevokeLink(
2630 (! strlen($dbname)) ?
$row['Db'] : $dbname,
2631 (! strlen($dbname)) ?
'' : $row['Table_name']
2634 $html_output .= '</td>' . "\n"
2636 $odd_row = ! $odd_row;
2639 return array($found_rows, $html_output);
2643 * Get a HTML table for display user's tabel specific or database specific rights
2645 * @param string $username username
2646 * @param string $hostname host name
2647 * @param string $dbname database name
2649 * @return array $html_output, $found_rows
2651 function PMA_getTableForDisplayAllTableSpecificRights(
2652 $username, $hostname, $dbname
2655 $html_output = PMA_URL_getHiddenInputs('', '')
2656 . '<input type="hidden" name="username" '
2657 . 'value="' . htmlspecialchars($username) . '" />' . "\n"
2658 . '<input type="hidden" name="hostname" '
2659 . 'value="' . htmlspecialchars($hostname) . '" />' . "\n"
2660 . '<fieldset>' . "\n"
2662 . (! strlen($dbname)
2663 ?
__('Database-specific privileges')
2664 : __('Table-specific privileges')
2666 . '</legend>' . "\n"
2667 . '<table class="data">' . "\n"
2670 . (! strlen($dbname) ?
__('Database') : __('Table'))
2672 . '<th>' . __('Privileges') . '</th>' . "\n"
2673 . '<th>' . __('Grant') . '</th>' . "\n"
2675 . (! strlen($dbname)
2676 ?
__('Table-specific privileges')
2677 : __('Column-specific privileges')
2680 . '<th colspan="2">' . __('Action') . '</th>' . "\n"
2682 . '</thead>' . "\n";
2684 $user_host_condition = ' WHERE `User`'
2685 . ' = \'' . PMA_Util
::sqlAddSlashes($username) . "'"
2687 . ' = \'' . PMA_Util
::sqlAddSlashes($hostname) . "'";
2692 // we also want privielgs for this user not in table `db` but in other table
2693 $tables = $GLOBALS['dbi']->fetchResult('SHOW TABLES FROM `mysql`;');
2696 * no db name given, so we want all privs for the given user
2697 * db name was given, so we want all user specific rights for this db
2699 $db_rights = PMA_getUserSpecificRights($tables, $user_host_condition, $dbname);
2703 $html_output .= '<tbody>' . "\n";
2705 list ($found_rows, $html_out) = PMA_getHtmlForDisplayUserRightsInRows(
2706 $db_rights, $dbname, $hostname, $username
2709 $html_output .= $html_out;
2710 $html_output .= '</tbody>' . "\n";
2711 $html_output .='</table>' . "\n";
2713 return array($html_output, $found_rows);
2717 * Get HTML for display select db
2719 * @param array $found_rows isset($dbname)) ? $row['Db'] : $row['Table_name']
2721 * @return string HTML snippet
2723 function PMA_getHtmlForDisplaySelectDbInEditPrivs($found_rows)
2725 $pred_db_array = $GLOBALS['dbi']->fetchResult('SHOW DATABASES;');
2727 $html_output = '<label for="text_dbname">'
2728 . __('Add privileges on the following database:') . '</label>' . "\n";
2729 if (! empty($pred_db_array)) {
2730 $html_output .= '<select name="pred_dbname" class="autosubmit">' . "\n"
2731 . '<option value="" selected="selected">'
2732 . __('Use text field:') . '</option>' . "\n";
2733 foreach ($pred_db_array as $current_db) {
2734 $current_db_show = $current_db;
2735 $current_db = PMA_Util
::escapeMysqlWildcards($current_db);
2736 // cannot use array_diff() once, outside of the loop,
2737 // because the list of databases has special characters
2738 // already escaped in $found_rows,
2739 // contrary to the output of SHOW DATABASES
2740 if (empty($found_rows) ||
! in_array($current_db, $found_rows)) {
2741 $html_output .= '<option value="'
2742 . htmlspecialchars($current_db) . '">'
2743 . htmlspecialchars($current_db_show) . '</option>' . "\n";
2746 $html_output .= '</select>' . "\n";
2748 $html_output .= '<input type="text" id="text_dbname" name="dbname" '
2749 . 'required="required" />'
2751 . PMA_Util
::showHint(
2752 __('Wildcards % and _ should be escaped with a \ to use them literally.')
2754 return $html_output;
2758 * Get HTML for display table in edit privilege
2760 * @param string $dbname database naame
2761 * @param array $found_rows isset($dbname)) ? $row['Db'] : $row['Table_name']
2763 * @return string HTML snippet
2765 function PMA_displayTablesInEditPrivs($dbname, $found_rows)
2767 $html_output = '<input type="hidden" name="dbname"
2768 '. 'value="' . htmlspecialchars($dbname) . '"/>' . "\n";
2769 $html_output .= '<label for="text_tablename">'
2770 . __('Add privileges on the following table:') . '</label>' . "\n";
2772 $result = @$GLOBALS['dbi']->tryQuery(
2773 'SHOW TABLES FROM ' . PMA_Util
::backquote(
2774 PMA_Util
::unescapeMysqlWildcards($dbname)
2777 PMA_DatabaseInterface
::QUERY_STORE
2781 $pred_tbl_array = array();
2782 while ($row = $GLOBALS['dbi']->fetchRow($result)) {
2783 if (! isset($found_rows) ||
! in_array($row[0], $found_rows)) {
2784 $pred_tbl_array[] = $row[0];
2787 $GLOBALS['dbi']->freeResult($result);
2789 if (! empty($pred_tbl_array)) {
2790 $html_output .= '<select name="pred_tablename" '
2791 . 'class="autosubmit">' . "\n"
2792 . '<option value="" selected="selected">' . __('Use text field')
2793 . ':</option>' . "\n";
2794 foreach ($pred_tbl_array as $current_table) {
2795 $html_output .= '<option '
2796 . 'value="' . htmlspecialchars($current_table) . '">'
2797 . htmlspecialchars($current_table)
2798 . '</option>' . "\n";
2800 $html_output .= '</select>' . "\n";
2803 $html_output .= '<input type="text" id="text_tablename" name="tablename" />'
2806 return $html_output;
2810 * Get HTML for display the users overview
2811 * (if less than 50 users, display them immediately)
2813 * @param array $result ran sql query
2814 * @param array $db_rights user's database rights array
2815 * @param string $pmaThemeImage a image source link
2816 * @param string $text_dir text directory
2818 * @return string HTML snippet
2820 function PMA_getUsersOverview($result, $db_rights, $pmaThemeImage, $text_dir)
2822 while ($row = $GLOBALS['dbi']->fetchAssoc($result)) {
2823 $row['privs'] = PMA_extractPrivInfo($row, true);
2824 $db_rights[$row['User']][$row['Host']] = $row;
2826 @$GLOBALS['dbi']->freeResult($result);
2829 = '<form name="usersForm" id="usersForm" action="server_privileges.php" '
2830 . 'method="post">' . "\n"
2831 . PMA_URL_getHiddenInputs('', '')
2832 . '<table id="tableuserrights" class="data">' . "\n"
2834 . '<tr><th></th>' . "\n"
2835 . '<th>' . __('User') . '</th>' . "\n"
2836 . '<th>' . __('Host') . '</th>' . "\n"
2837 . '<th>' . __('Password') . '</th>' . "\n"
2838 . '<th>' . __('Global privileges') . ' '
2839 . PMA_Util
::showHint(
2840 __('Note: MySQL privilege names are expressed in English')
2843 if ($GLOBALS['cfgRelation']['menuswork']) {
2844 $html_output .= '<th>' . __('User group') . '</th>' . "\n";
2846 $html_output .= '<th>' . __('Grant') . '</th>' . "\n"
2847 . '<th colspan="3">' . __('Action') . '</th>' . "\n"
2849 . '</thead>' . "\n";
2851 $html_output .= '<tbody>' . "\n";
2852 $html_output .= PMA_getTableBodyForUserRightsTable($db_rights);
2853 $html_output .= '</tbody>'
2854 . '</table>' . "\n";
2856 $html_output .= '<div style="float:left;">'
2857 . '<img class="selectallarrow"'
2858 . ' src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png"'
2859 . ' width="38" height="22"'
2860 . ' alt="' . __('With selected:') . '" />' . "\n"
2861 . '<input type="checkbox" id="usersForm_checkall" class="checkall_box" '
2862 . 'title="' . __('Check All') . '" /> '
2863 . '<label for="usersForm_checkall">' . __('Check All') . '</label> '
2864 . '<i style="margin-left: 2em">' . __('With selected:') . '</i>' . "\n";
2866 $html_output .= PMA_Util
::getButtonOrImage(
2867 'submit_mult', 'mult_submit', 'submit_mult_export',
2868 __('Export'), 'b_tblexport.png', 'export'
2870 $html_output .= '<input type="hidden" name="initial" '
2871 . 'value="' . (isset($_GET['initial']) ?
$_GET['initial'] : '') . '" />';
2872 $html_output .= '</div>'
2873 . '<div class="clear_both" style="clear:both"></div>';
2875 // add/delete user fieldset
2876 $html_output .= PMA_getFieldsetForAddDeleteUser();
2877 $html_output .= '</form>' . "\n";
2879 return $html_output;
2883 * Get table body for 'tableuserrights' table in userform
2885 * @param array $db_rights user's database rights array
2887 * @return string HTML snippet
2889 function PMA_getTableBodyForUserRightsTable($db_rights)
2891 if ($GLOBALS['cfgRelation']['menuswork']) {
2892 $usersTable = PMA_Util
::backquote($GLOBALS['cfg']['Server']['pmadb'])
2893 . "." . PMA_Util
::backquote($GLOBALS['cfg']['Server']['users']);
2894 $sqlQuery = "SELECT * FROM " . $usersTable;
2895 $result = PMA_queryAsControlUser($sqlQuery, false);
2896 $groupAssignment = array();
2898 while ($row = $GLOBALS['dbi']->fetchAssoc($result)) {
2899 $groupAssignment[$row['username']] = $row['usergroup'];
2902 $GLOBALS['dbi']->freeResult($result);
2904 $userGroupTable = PMA_Util
::backquote($GLOBALS['cfg']['Server']['pmadb'])
2905 . "." . PMA_Util
::backquote($GLOBALS['cfg']['Server']['usergroups']);
2906 $sqlQuery = "SELECT COUNT(*) FROM " . $userGroupTable;
2907 $userGroupCount = $GLOBALS['dbi']->fetchValue(
2908 $sqlQuery, 0, 0, $GLOBALS['controllink']
2913 $index_checkbox = 0;
2915 foreach ($db_rights as $user) {
2917 foreach ($user as $host) {
2919 $html_output .= '<tr class="' . ($odd_row ?
'odd' : 'even') . '">'
2921 $html_output .= '<td>'
2922 . '<input type="checkbox" class="checkall" name="selected_usr[]" '
2923 . 'id="checkbox_sel_users_'
2924 . $index_checkbox . '" value="'
2925 . htmlspecialchars($host['User'] . '&#27;' . $host['Host'])
2927 . ' /></td>' . "\n";
2929 $html_output .= '<td><label '
2930 . 'for="checkbox_sel_users_' . $index_checkbox . '">'
2931 . (empty($host['User'])
2932 ?
'<span style="color: #FF0000">' . __('Any') . '</span>'
2933 : htmlspecialchars($host['User'])) . '</label></td>' . "\n"
2934 . '<td>' . htmlspecialchars($host['Host']) . '</td>' . "\n";
2936 $html_output .= '<td>';
2937 switch ($host['Password']) {
2939 $html_output .= __('Yes');
2942 $html_output .= '<span style="color: #FF0000">' . __('No')
2945 // this happens if this is a definition not coming from mysql.user
2947 $html_output .= '--'; // in future version, replace by "not present"
2950 $html_output .= '</td>' . "\n";
2952 $html_output .= '<td><code>' . "\n"
2953 . '' . implode(',' . "\n" . ' ', $host['privs']) . "\n"
2954 . '</code></td>' . "\n";
2955 if ($GLOBALS['cfgRelation']['menuswork']) {
2956 $html_output .= '<td class="usrGroup">' . "\n"
2957 . (isset($groupAssignment[$host['User']])
2958 ?
$groupAssignment[$host['User']]
2963 $html_output .= '<td>'
2964 . ($host['Grant_priv'] == 'Y' ?
__('Yes') : __('No'))
2967 $html_output .= '<td class="center">'
2968 . PMA_getUserEditLink(
2973 if ($GLOBALS['cfgRelation']['menuswork'] && $userGroupCount > 0) {
2974 if (empty($host['User'])) {
2975 $html_output .= '<td class="center"></td>';
2977 $html_output .= '<td class="center">'
2978 . '<a class="edit_user_group_anchor ajax"'
2979 . ' href="server_privileges.php'
2980 . PMA_URL_getCommon(array('username' => $host['User']))
2982 . PMA_Util
::getIcon('b_usrlist.png', __('Edit user group'))
2987 $html_output .= '<td class="center">'
2988 . PMA_getUserExportLink(
2991 isset($_GET['initial']) ?
$_GET['initial'] : ''
2994 $html_output .= '</tr>';
2995 $odd_row = ! $odd_row;
2998 return $html_output;
3002 * Get HTML fieldset for Add/Delete user
3004 * @return string HTML snippet
3006 function PMA_getFieldsetForAddDeleteUser()
3008 $html_output = '<fieldset id="fieldset_add_user">' . "\n";
3009 $html_output .= '<a href="server_privileges.php'
3010 . PMA_URL_getCommon(array('adduser' => 1))
3011 . '" class="ajax">' . "\n"
3012 . PMA_Util
::getIcon('b_usradd.png')
3013 . ' ' . __('Add user') . '</a>' . "\n";
3014 $html_output .= '</fieldset>' . "\n";
3016 $html_output .= '<fieldset id="fieldset_delete_user">'
3018 . PMA_Util
::getIcon('b_usrdrop.png')
3019 . ' ' . __('Remove selected users') . '' . "\n"
3020 . '</legend>' . "\n";
3022 $html_output .= '<input type="hidden" name="mode" value="2" />' . "\n"
3025 'Revoke all active privileges from the users '
3026 . 'and delete them afterwards.'
3031 $html_output .= '<input type="checkbox" '
3033 . __('Drop the databases that have the same names as the users.')
3035 . 'name="drop_users_db" id="checkbox_drop_users_db" />' . "\n";
3037 $html_output .= '<label for="checkbox_drop_users_db" '
3039 . __('Drop the databases that have the same names as the users.')
3042 . __('Drop the databases that have the same names as the users.')
3045 . '</fieldset>' . "\n";
3047 $html_output .= '<fieldset id="fieldset_delete_user_footer" class="tblFooters">'
3049 $html_output .= '<input type="submit" name="delete" '
3050 . 'value="' . __('Go') . '" id="buttonGo" '
3051 . 'class="ajax"/>' . "\n";
3053 $html_output .= '</fieldset>' . "\n";
3055 return $html_output;
3059 * Get HTML for Displays the initials
3061 * @param array $array_initials array for all initials, even non A-Z
3063 * @return string HTML snippet
3065 function PMA_getHtmlForDisplayTheInitials($array_initials)
3067 // initialize to false the letters A-Z
3068 for ($letter_counter = 1; $letter_counter < 27; $letter_counter++
) {
3069 if (! isset($array_initials[chr($letter_counter +
64)])) {
3070 $array_initials[chr($letter_counter +
64)] = false;
3074 $initials = $GLOBALS['dbi']->tryQuery(
3075 'SELECT DISTINCT UPPER(LEFT(`User`,1)) FROM `user` ORDER BY `User` ASC',
3077 PMA_DatabaseInterface
::QUERY_STORE
3079 while (list($tmp_initial) = $GLOBALS['dbi']->fetchRow($initials)) {
3080 $array_initials[$tmp_initial] = true;
3083 // Display the initials, which can be any characters, not
3084 // just letters. For letters A-Z, we add the non-used letters
3087 uksort($array_initials, "strnatcasecmp");
3089 $html_output = '<table id="initials_table" <cellspacing="5">'
3091 foreach ($array_initials as $tmp_initial => $initial_was_found) {
3092 if (! empty($tmp_initial)) {
3093 if ($initial_was_found) {
3094 $html_output .= '<td>'
3096 . ' href="server_privileges.php'
3097 . PMA_URL_getCommon(array('initial' => $tmp_initial))
3098 . '">' . $tmp_initial
3102 $html_output .= '<td>' . $tmp_initial . '</td>';
3106 $html_output .= '<td>'
3107 . '<a href="server_privileges.php'
3108 . PMA_URL_getCommon(array('showall' => 1))
3109 . '" class="nowrap">[' . __('Show all') . ']</a></td>' . "\n";
3110 $html_output .= '</tr></table>';
3112 return $html_output;
3116 * Get the database rigths array for Display user overview
3118 * @return array $db_rights database rights array
3120 function PMA_getDbRightsForUserOverview()
3122 // we also want users not in table `user` but in other table
3123 $tables = $GLOBALS['dbi']->fetchResult('SHOW TABLES FROM `mysql`;');
3125 $tables_to_search_for_users = array(
3126 'user', 'db', 'tables_priv', 'columns_priv', 'procs_priv',
3129 $db_rights_sqls = array();
3130 foreach ($tables_to_search_for_users as $table_search_in) {
3131 if (in_array($table_search_in, $tables)) {
3132 $db_rights_sqls[] = 'SELECT DISTINCT `User`, `Host` FROM `mysql`.`'
3133 . $table_search_in . '` '
3134 . (isset($_GET['initial'])
3135 ?
PMA_rangeOfUsers($_GET['initial'])
3139 $user_defaults = array(
3143 'Grant_priv' => 'N',
3144 'privs' => array('USAGE'),
3148 $db_rights = array();
3150 $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
3151 .' ORDER BY `User` ASC, `Host` ASC';
3153 $db_rights_result = $GLOBALS['dbi']->query($db_rights_sql);
3155 while ($db_rights_row = $GLOBALS['dbi']->fetchAssoc($db_rights_result)) {
3156 $db_rights_row = array_merge($user_defaults, $db_rights_row);
3157 $db_rights[$db_rights_row['User']][$db_rights_row['Host']]
3160 $GLOBALS['dbi']->freeResult($db_rights_result);
3167 * Delete user and get message and sql query for delete user in privileges
3169 * @param string $queries queries
3171 * @return PMA_message
3173 function PMA_deleteUser($queries)
3175 if (empty($queries)) {
3176 $message = PMA_Message
::error(__('No users selected for deleting!'));
3178 if ($_REQUEST['mode'] == 3) {
3179 $queries[] = '# ' . __('Reloading the privileges') . ' …';
3180 $queries[] = 'FLUSH PRIVILEGES;';
3182 $drop_user_error = '';
3183 foreach ($queries as $sql_query) {
3184 if ($sql_query{0} != '#') {
3185 if (! $GLOBALS['dbi']->tryQuery($sql_query, $GLOBALS['userlink'])) {
3186 $drop_user_error .= $GLOBALS['dbi']->getError() . "\n";
3190 // tracking sets this, causing the deleted db to be shown in navi
3191 unset($GLOBALS['db']);
3193 $sql_query = join("\n", $queries);
3194 if (! empty($drop_user_error)) {
3195 $message = PMA_Message
::rawError($drop_user_error);
3197 $message = PMA_Message
::success(
3198 __('The selected users have been deleted successfully.')
3202 return array($sql_query, $message);
3206 * Update the privileges and return the success or error message
3208 * @param string $username username
3209 * @param string $hostname host name
3210 * @param string $tablename table name
3211 * @param string $dbname database name
3213 * @return PMA_message success message or error message for update
3215 function PMA_updatePrivileges($username, $hostname, $tablename, $dbname)
3217 $db_and_table = PMA_wildcardEscapeForGrant($dbname, $tablename);
3219 $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
3220 . ' FROM \'' . PMA_Util
::sqlAddSlashes($username)
3221 . '\'@\'' . PMA_Util
::sqlAddSlashes($hostname) . '\';';
3223 if (! isset($_POST['Grant_priv']) ||
$_POST['Grant_priv'] != 'Y') {
3224 $sql_query1 = 'REVOKE GRANT OPTION ON ' . $db_and_table
3225 . ' FROM \'' . PMA_Util
::sqlAddSlashes($username) . '\'@\''
3226 . PMA_Util
::sqlAddSlashes($hostname) . '\';';
3231 // Should not do a GRANT USAGE for a table-specific privilege, it
3232 // causes problems later (cannot revoke it)
3233 if (! (strlen($tablename) && 'USAGE' == implode('', PMA_extractPrivInfo()))) {
3234 $sql_query2 = 'GRANT ' . join(', ', PMA_extractPrivInfo())
3235 . ' ON ' . $db_and_table
3236 . ' TO \'' . PMA_Util
::sqlAddSlashes($username) . '\'@\''
3237 . PMA_Util
::sqlAddSlashes($hostname) . '\'';
3239 if ((isset($_POST['Grant_priv']) && $_POST['Grant_priv'] == 'Y')
3240 ||
(! strlen($dbname)
3241 && (isset($_POST['max_questions']) ||
isset($_POST['max_connections'])
3242 ||
isset($_POST['max_updates'])
3243 ||
isset($_POST['max_user_connections'])))
3245 $sql_query2 .= PMA_getWithClauseForAddUserAndUpdatePrivs();
3249 if (! $GLOBALS['dbi']->tryQuery($sql_query0)) {
3250 // This might fail when the executing user does not have
3251 // ALL PRIVILEGES himself.
3252 // See https://sourceforge.net/p/phpmyadmin/bugs/3270/
3255 if (! empty($sql_query1) && ! $GLOBALS['dbi']->tryQuery($sql_query1)) {
3256 // this one may fail, too...
3259 if (! empty($sql_query2)) {
3260 $GLOBALS['dbi']->query($sql_query2);
3264 $sql_query = $sql_query0 . ' ' . $sql_query1 . ' ' . $sql_query2;
3265 $message = PMA_Message
::success(__('You have updated the privileges for %s.'));
3267 '\'' . htmlspecialchars($username)
3268 . '\'@\'' . htmlspecialchars($hostname) . '\''
3271 return array($sql_query, $message);
3275 * Get List of information: Changes / copies a user
3279 function PMA_getDataForChangeOrCopyUser()
3285 if (isset($_REQUEST['change_copy'])) {
3286 $user_host_condition = ' WHERE `User` = '
3287 . "'". PMA_Util
::sqlAddSlashes($_REQUEST['old_username']) . "'"
3289 . "'" . PMA_Util
::sqlAddSlashes($_REQUEST['old_hostname']) . "';";
3290 $row = $GLOBALS['dbi']->fetchSingleRow(
3291 'SELECT * FROM `mysql`.`user` ' . $user_host_condition
3294 $response = PMA_Response
::getInstance();
3296 PMA_Message
::notice(__('No user found.'))->getDisplay()
3298 unset($_REQUEST['change_copy']);
3300 extract($row, EXTR_OVERWRITE
);
3301 // Recent MySQL versions have the field "Password" in mysql.user,
3302 // so the previous extract creates $Password but this script
3304 if (! isset($password) && isset($Password)) {
3305 $password = $Password;
3311 return array($queries, $password);
3315 * Update Data for information: Deletes users
3317 * @param array $queries queries array
3321 function PMA_getDataForDeleteUsers($queries)
3323 if (isset($_REQUEST['change_copy'])) {
3324 $selected_usr = array(
3325 $_REQUEST['old_username'] . '&#27;' . $_REQUEST['old_hostname']
3328 $selected_usr = $_REQUEST['selected_usr'];
3331 foreach ($selected_usr as $each_user) {
3332 list($this_user, $this_host) = explode('&#27;', $each_user);
3336 '\'' . $this_user . '\'@\'' . $this_host . '\''
3339 $queries[] = 'DROP USER \''
3340 . PMA_Util
::sqlAddSlashes($this_user)
3341 . '\'@\'' . PMA_Util
::sqlAddSlashes($this_host) . '\';';
3343 if (isset($_REQUEST['drop_users_db'])) {
3344 $queries[] = 'DROP DATABASE IF EXISTS '
3345 . PMA_Util
::backquote($this_user) . ';';
3346 $GLOBALS['reload'] = true;
3353 * update Message For Reload
3357 function PMA_updateMessageForReload()
3360 if (isset($_REQUEST['flush_privileges'])) {
3361 $sql_query = 'FLUSH PRIVILEGES;';
3362 $GLOBALS['dbi']->query($sql_query);
3363 $message = PMA_Message
::success(
3364 __('The privileges were reloaded successfully.')
3368 if (isset($_REQUEST['validate_username'])) {
3369 $message = PMA_Message
::success();
3376 * update Data For Queries from queries_for_display
3378 * @param array $queries queries array
3379 * @param array $queries_for_display queries arry for display
3383 function PMA_getDataForQueries($queries, $queries_for_display)
3386 foreach ($queries as $sql_query) {
3387 if ($sql_query{0} != '#') {
3388 $GLOBALS['dbi']->query($sql_query);
3390 // when there is a query containing a hidden password, take it
3391 // instead of the real query sent
3392 if (isset($queries_for_display[$tmp_count])) {
3393 $queries[$tmp_count] = $queries_for_display[$tmp_count];
3402 * update Data for information: Adds a user
3404 * @param string $dbname db name
3405 * @param string $username user name
3406 * @param string $hostname host name
3407 * @param string $password password
3408 * @param bool $is_menuwork is_menuwork set?
3412 function PMA_addUser(
3413 $dbname, $username, $hostname,
3414 $password, $is_menuwork
3416 $_add_user_error = false;
3419 $queries_for_display = null;
3421 if (isset($_REQUEST['adduser_submit']) ||
isset($_REQUEST['change_copy'])) {
3423 if ($_POST['pred_username'] == 'any') {
3426 switch ($_POST['pred_hostname']) {
3431 $hostname = 'localhost';
3437 $_user_name = $GLOBALS['dbi']->fetchValue('SELECT USER()');
3438 $hostname = substr($_user_name, (strrpos($_user_name, '@') +
1));
3442 $sql = "SELECT '1' FROM `mysql`.`user`"
3443 . " WHERE `User` = '" . PMA_Util
::sqlAddSlashes($username) . "'"
3444 . " AND `Host` = '" . PMA_Util
::sqlAddSlashes($hostname) . "';";
3445 if ($GLOBALS['dbi']->fetchValue($sql) == 1) {
3446 $message = PMA_Message
::error(__('The user %s already exists!'));
3448 '[em]\'' . $username . '\'@\'' . $hostname . '\'[/em]'
3450 $_REQUEST['adduser'] = true;
3451 $_add_user_error = true;
3453 list($create_user_real, $create_user_show, $real_sql_query, $sql_query)
3454 = PMA_getSqlQueriesForDisplayAndAddUser(
3455 $username, $hostname, (isset ($password) ?
$password : '')
3458 if (empty($_REQUEST['change_copy'])) {
3461 if (isset($create_user_real)) {
3462 if (! $GLOBALS['dbi']->tryQuery($create_user_real)) {
3465 $sql_query = $create_user_show . $sql_query;
3467 list($sql_query, $message) = PMA_addUserAndCreateDatabase(
3468 $_error, $real_sql_query, $sql_query, $username, $hostname,
3469 isset($dbname) ?
$dbname : null
3471 if (! empty($_REQUEST['userGroup']) && $is_menuwork) {
3472 PMA_setUserGroup($GLOBALS['username'], $_REQUEST['userGroup']);
3476 if (isset($create_user_real)) {
3477 $queries[] = $create_user_real;
3479 $queries[] = $real_sql_query;
3480 // we put the query containing the hidden password in
3481 // $queries_for_display, at the same position occupied
3482 // by the real query in $queries
3483 $tmp_count = count($queries);
3484 if (isset($create_user_real)) {
3485 $queries_for_display[$tmp_count - 2] = $create_user_show;
3487 $queries_for_display[$tmp_count - 1] = $sql_query;
3489 unset($res, $real_sql_query);
3494 $message, $queries, $queries_for_display, $sql_query, $_add_user_error
3499 * Update DB information: DB, Table, isWildcard
3503 function PMA_getDataForDBInfo()
3509 $db_and_table = null;
3510 $dbname_is_wildcard = null;
3512 if (isset ($_REQUEST['username'])) {
3513 $username = $_REQUEST['username'];
3515 if (isset ($_REQUEST['hostname'])) {
3516 $hostname = $_REQUEST['hostname'];
3519 * Checks if a dropdown box has been used for selecting a database / table
3521 if (PMA_isValid($_REQUEST['pred_tablename'])) {
3522 $tablename = $_REQUEST['pred_tablename'];
3523 } elseif (PMA_isValid($_REQUEST['tablename'])) {
3524 $tablename = $_REQUEST['tablename'];
3529 if (PMA_isValid($_REQUEST['pred_dbname'])) {
3530 $dbname = $_REQUEST['pred_dbname'];
3531 unset($pred_dbname);
3532 } elseif (PMA_isValid($_REQUEST['dbname'])) {
3533 $dbname = $_REQUEST['dbname'];
3539 if (isset($dbname)) {
3540 $unescaped_db = PMA_Util
::unescapeMysqlWildcards($dbname);
3541 $db_and_table = PMA_Util
::backquote($unescaped_db) . '.';
3542 if (isset($tablename)) {
3543 $db_and_table .= PMA_Util
::backquote($tablename);
3545 $db_and_table .= '*';
3548 $db_and_table = '*.*';
3551 // check if given $dbname is a wildcard or not
3552 if (isset($dbname)) {
3553 //if (preg_match('/\\\\(?:_|%)/i', $dbname)) {
3554 if (preg_match('/(?<!\\\\)(?:_|%)/i', $dbname)) {
3555 $dbname_is_wildcard = true;
3557 $dbname_is_wildcard = false;
3562 $username, $hostname,
3563 isset($dbname)?
$dbname : null,
3564 isset($tablename)?
$tablename : null,
3566 $dbname_is_wildcard,
3571 * Get title and textarea for export user definition in Privileges
3573 * @param string $username username
3574 * @param string $hostname host name
3576 * @return array ($title, $export)
3578 function PMA_getListForExportUserDefinition($username, $hostname)
3580 $export = '<textarea class="export" cols="' . $GLOBALS['cfg']['TextareaCols']
3581 . '" rows="' . $GLOBALS['cfg']['TextareaRows'] . '">';
3583 if (isset($_REQUEST['selected_usr'])) {
3584 // export privileges for selected users
3585 $title = __('Privileges');
3586 foreach ($_REQUEST['selected_usr'] as $export_user) {
3587 $export_username = substr($export_user, 0, strpos($export_user, '&'));
3588 $export_hostname = substr($export_user, strrpos($export_user, ';') +
1);
3591 __('Privileges for %s'),
3592 '`' . htmlspecialchars($export_username)
3593 . '`@`' . htmlspecialchars($export_hostname) . '`'
3596 $export .= PMA_getGrants($export_username, $export_hostname) . "\n";
3599 // export privileges for a single user
3600 $title = __('User') . ' `' . htmlspecialchars($username)
3601 . '`@`' . htmlspecialchars($hostname) . '`';
3602 $export .= PMA_getGrants($username, $hostname);
3604 // remove trailing whitespace
3605 $export = trim($export);
3607 $export .= '</textarea>';
3609 return array($title, $export);
3613 * Get HTML for display Add userfieldset
3615 * @return string html output
3617 function PMA_getAddUserHtmlFieldset()
3619 return '<fieldset id="fieldset_add_user">' . "\n"
3620 . '<a href="server_privileges.php'
3621 . PMA_URL_getCommon(array('adduser' => 1))
3622 . '" class="ajax">' . "\n"
3623 . PMA_Util
::getIcon('b_usradd.png')
3624 . ' ' . __('Add user') . '</a>' . "\n"
3625 . '</fieldset>' . "\n";
3629 * Get HTML header for display User's properties
3631 * @param boolean $dbname_is_wildcard whether database name is wildcard or not
3632 * @param string $url_dbname url database name that urlencode() string
3633 * @param string $dbname database name
3634 * @param string $username username
3635 * @param string $hostname host name
3636 * @param string $tablename table name
3638 * @return string $html_output
3640 function PMA_getHtmlHeaderForDisplayUserProperties(
3641 $dbname_is_wildcard, $url_dbname, $dbname, $username, $hostname, $tablename
3643 $html_output = '<h2>' . "\n"
3644 . PMA_Util
::getIcon('b_usredit.png')
3645 . __('Edit Privileges:') . ' '
3648 if (! empty($dbname)) {
3649 $html_output .= ' <i><a href="server_privileges.php'
3650 . PMA_URL_getCommon(
3652 'username' => $username,
3653 'hostname' => $hostname,
3658 . '">\'' . htmlspecialchars($username)
3659 . '\'@\'' . htmlspecialchars($hostname)
3660 . '\'</a></i>' . "\n";
3662 $html_output .= ' - ';
3663 $html_output .= $dbname_is_wildcard ?
__('Databases') : __('Database');
3664 if (! empty($_REQUEST['tablename'])) {
3665 $html_output .= ' <i><a href="server_privileges.php'
3666 . PMA_URL_getCommon(
3668 'username' => $username,
3669 'hostname' => $hostname,
3670 'dbname' => $url_dbname,
3674 . '">' . htmlspecialchars($dbname)
3677 $html_output .= ' - ' . __('Table')
3678 . ' <i>' . htmlspecialchars($tablename) . '</i>';
3680 $html_output .= ' <i>' . htmlspecialchars($dbname) . '</i>';
3684 $html_output .= ' <i>\'' . htmlspecialchars($username)
3685 . '\'@\'' . htmlspecialchars($hostname)
3689 $html_output .= '</h2>' . "\n";
3691 return $html_output;
3695 * Get HTML snippet for display user overview page
3697 * @param string $pmaThemeImage a image source link
3698 * @param string $text_dir text directory
3700 * @return string $html_output
3702 function PMA_getHtmlForDisplayUserOverviewPage($pmaThemeImage, $text_dir)
3704 $html_output = '<h2>' . "\n"
3705 . PMA_Util
::getIcon('b_usrlist.png')
3706 . __('Users overview') . "\n"
3709 $sql_query = 'SELECT *,' .
3710 " IF(`Password` = _latin1 '', 'N', 'Y') AS 'Password'" .
3711 ' FROM `mysql`.`user`';
3713 $sql_query .= (isset($_REQUEST['initial'])
3714 ?
PMA_rangeOfUsers($_REQUEST['initial'])
3717 $sql_query .= ' ORDER BY `User` ASC, `Host` ASC;';
3718 $res = $GLOBALS['dbi']->tryQuery(
3719 $sql_query, null, PMA_DatabaseInterface
::QUERY_STORE
3723 // the query failed! This may have two reasons:
3724 // - the user does not have enough privileges
3725 // - the privilege tables use a structure of an earlier version.
3726 // so let's try a more simple query
3728 $sql_query = 'SELECT * FROM `mysql`.`user`';
3729 $res = $GLOBALS['dbi']->tryQuery(
3730 $sql_query, null, PMA_DatabaseInterface
::QUERY_STORE
3734 $html_output .= PMA_Message
::error(__('No Privileges'))->getDisplay();
3735 $GLOBALS['dbi']->freeResult($res);
3738 // This message is hardcoded because I will replace it by
3739 // a automatic repair feature soon.
3740 $raw = 'Your privilege table structure seems to be older than'
3741 . ' this MySQL version!<br />'
3742 . 'Please run the <code>mysql_upgrade</code> command'
3743 . '(<code>mysql_fix_privilege_tables</code> on older systems)'
3744 . ' that should be included in your MySQL server distribution'
3745 . ' to solve this problem!';
3746 $html_output .= PMA_Message
::rawError($raw)->getDisplay();
3749 $db_rights = PMA_getDbRightsForUserOverview();
3750 // for all initials, even non A-Z
3751 $array_initials = array();
3754 * Displays the initials
3755 * Also not necassary if there is less than 20 privileges
3757 if ($GLOBALS['dbi']->numRows($res) > 20 ) {
3758 $html_output .= PMA_getHtmlForDisplayTheInitials($array_initials);
3762 * Display the user overview
3763 * (if less than 50 users, display them immediately)
3765 if (isset($_REQUEST['initial'])
3766 ||
isset($_REQUEST['showall'])
3767 ||
$GLOBALS['dbi']->numRows($res) < 50
3769 $html_output .= PMA_getUsersOverview(
3770 $res, $db_rights, $pmaThemeImage, $text_dir
3773 $html_output .= PMA_getAddUserHtmlFieldset();
3774 } // end if (display overview)
3776 if (! $GLOBALS['is_ajax_request']
3777 ||
! empty($_REQUEST['ajax_page_request'])
3779 $flushnote = new PMA_Message(
3781 'Note: phpMyAdmin gets the users\' privileges directly '
3782 . 'from MySQL\'s privilege tables. The content of these tables '
3783 . 'may differ from the privileges the server uses, '
3784 . 'if they have been changed manually. In this case, '
3785 . 'you should %sreload the privileges%s before you continue.'
3789 $flushLink = '<a href="server_privileges.php'
3790 . PMA_URL_getCommon(array('flush_privileges' => 1))
3791 . '" id="reload_privileges_anchor">';
3792 $flushnote->addParam(
3796 $flushnote->addParam('</a>', false);
3797 $html_output .= $flushnote->getDisplay();
3801 return $html_output;
3805 * Get HTML snippet for display user properties
3807 * @param boolean $dbname_is_wildcard whether database name is wildcard or not
3808 * @param type $url_dbname url database name that urlencode() string
3809 * @param string $username username
3810 * @param string $hostname host name
3811 * @param string $dbname database name
3812 * @param string $tablename table name
3814 * @return string $html_output
3816 function PMA_getHtmlForDisplayUserProperties($dbname_is_wildcard,$url_dbname,
3817 $username, $hostname, $dbname, $tablename
3819 $html_output = PMA_getHtmlHeaderForDisplayUserProperties(
3820 $dbname_is_wildcard, $url_dbname, $dbname, $username, $hostname, $tablename
3823 $sql = "SELECT '1' FROM `mysql`.`user`"
3824 . " WHERE `User` = '" . PMA_Util
::sqlAddSlashes($username) . "'"
3825 . " AND `Host` = '" . PMA_Util
::sqlAddSlashes($hostname) . "';";
3827 $user_does_not_exists = (bool) ! $GLOBALS['dbi']->fetchValue($sql);
3829 if ($user_does_not_exists) {
3830 $html_output .= PMA_Message
::error(
3831 __('The selected user was not found in the privilege table.')
3833 $html_output .= PMA_getHtmlForDisplayLoginInformationFields();
3837 $class = ' class="ajax"';
3839 'username' => $username,
3840 'hostname' => $hostname,
3842 if (strlen($dbname)) {
3843 $_params['dbname'] = $dbname;
3844 if (strlen($tablename)) {
3845 $_params['tablename'] = $tablename;
3849 $html_output .= '<form' . $class . ' name="usersForm" id="addUsersForm"'
3850 . ' action="server_privileges.php" method="post">' . "\n";
3851 $html_output .= PMA_URL_getHiddenInputs($_params);
3852 $html_output .= PMA_getHtmlToDisplayPrivilegesTable(
3853 PMA_ifSetOr($dbname, '*', 'length'),
3854 PMA_ifSetOr($tablename, '*', 'length')
3857 $html_output .= '</form>' . "\n";
3859 if (! strlen($tablename) && empty($dbname_is_wildcard)) {
3861 // no table name was given, display all table specific rights
3862 // but only if $dbname contains no wildcards
3864 $html_output .= '<form action="server_privileges.php" '
3865 . 'id="db_or_table_specific_priv" method="post">' . "\n";
3867 // unescape wildcards in dbname at table level
3868 $unescaped_db = PMA_Util
::unescapeMysqlWildcards($dbname);
3869 list($html_rightsTable, $found_rows)
3870 = PMA_getTableForDisplayAllTableSpecificRights(
3871 $username, $hostname, $unescaped_db
3873 $html_output .= $html_rightsTable;
3875 if (! strlen($dbname)) {
3876 // no database name was given, display select db
3877 $html_output .= PMA_getHtmlForDisplaySelectDbInEditPrivs($found_rows);
3880 $html_output .= PMA_displayTablesInEditPrivs($dbname, $found_rows);
3882 $html_output .= '</fieldset>' . "\n";
3884 $html_output .= '<fieldset class="tblFooters">' . "\n"
3885 . ' <input type="submit" value="' . __('Go') . '" />'
3886 . '</fieldset>' . "\n"
3890 // Provide a line with links to the relevant database and table
3891 if (strlen($dbname) && empty($dbname_is_wildcard)) {
3892 $html_output .= PMA_getLinkToDbAndTable($url_dbname, $dbname, $tablename);
3896 if (! strlen($dbname) && ! $user_does_not_exists) {
3897 //change login information
3898 $html_output .= PMA_getHtmlForChangePassword($username, $hostname);
3899 $html_output .= PMA_getChangeLoginInformationHtmlForm($username, $hostname);
3902 return $html_output;
3906 * Get queries for Table privileges to change or copy user
3908 * @param string $user_host_condition user host condition to
3909 select relevent table privileges
3910 * @param array $queries queries array
3911 * @param string $username username
3912 * @param string $hostname host name
3914 * @return array $queries
3916 function PMA_getTablePrivsQueriesForChangeOrCopyUser($user_host_condition,
3917 $queries, $username, $hostname
3919 $res = $GLOBALS['dbi']->query(
3920 'SELECT `Db`, `Table_name`, `Table_priv` FROM `mysql`.`tables_priv`'
3921 . $user_host_condition,
3922 $GLOBALS['userlink'],
3923 PMA_DatabaseInterface
::QUERY_STORE
3925 while ($row = $GLOBALS['dbi']->fetchAssoc($res)) {
3927 $res2 = $GLOBALS['dbi']->query(
3928 'SELECT `Column_name`, `Column_priv`'
3929 .' FROM `mysql`.`columns_priv`'
3931 .' = \'' . PMA_Util
::sqlAddSlashes($_REQUEST['old_username']) . "'"
3933 .' = \'' . PMA_Util
::sqlAddSlashes($_REQUEST['old_username']) . '\''
3935 .' = \'' . PMA_Util
::sqlAddSlashes($row['Db']) . "'"
3936 .' AND `Table_name`'
3937 .' = \'' . PMA_Util
::sqlAddSlashes($row['Table_name']) . "'"
3940 PMA_DatabaseInterface
::QUERY_STORE
3943 $tmp_privs1 = PMA_extractPrivInfo($row);
3944 $tmp_privs2 = array(
3945 'Select' => array(),
3946 'Insert' => array(),
3947 'Update' => array(),
3948 'References' => array()
3951 while ($row2 = $GLOBALS['dbi']->fetchAssoc($res2)) {
3952 $tmp_array = explode(',', $row2['Column_priv']);
3953 if (in_array('Select', $tmp_array)) {
3954 $tmp_privs2['Select'][] = $row2['Column_name'];
3956 if (in_array('Insert', $tmp_array)) {
3957 $tmp_privs2['Insert'][] = $row2['Column_name'];
3959 if (in_array('Update', $tmp_array)) {
3960 $tmp_privs2['Update'][] = $row2['Column_name'];
3962 if (in_array('References', $tmp_array)) {
3963 $tmp_privs2['References'][] = $row2['Column_name'];
3966 if (count($tmp_privs2['Select']) > 0 && ! in_array('SELECT', $tmp_privs1)) {
3967 $tmp_privs1[] = 'SELECT (`' . join('`, `', $tmp_privs2['Select']) . '`)';
3969 if (count($tmp_privs2['Insert']) > 0 && ! in_array('INSERT', $tmp_privs1)) {
3970 $tmp_privs1[] = 'INSERT (`' . join('`, `', $tmp_privs2['Insert']) . '`)';
3972 if (count($tmp_privs2['Update']) > 0 && ! in_array('UPDATE', $tmp_privs1)) {
3973 $tmp_privs1[] = 'UPDATE (`' . join('`, `', $tmp_privs2['Update']) . '`)';
3975 if (count($tmp_privs2['References']) > 0
3976 && ! in_array('REFERENCES', $tmp_privs1)
3979 = 'REFERENCES (`' . join('`, `', $tmp_privs2['References']) . '`)';
3982 $queries[] = 'GRANT ' . join(', ', $tmp_privs1)
3983 . ' ON ' . PMA_Util
::backquote($row['Db']) . '.'
3984 . PMA_Util
::backquote($row['Table_name'])
3985 . ' TO \'' . PMA_Util
::sqlAddSlashes($username)
3986 . '\'@\'' . PMA_Util
::sqlAddSlashes($hostname) . '\''
3987 . (in_array('Grant', explode(',', $row['Table_priv']))
3988 ?
' WITH GRANT OPTION;'
3995 * Get queries for database specific privileges for change or copy user
3997 * @param array $queries queries array with string
3998 * @param string $username username
3999 * @param string $hostname host name
4001 * @return array $queries
4003 function PMA_getDbSpecificPrivsQueriesForChangeOrCopyUser(
4004 $queries, $username, $hostname
4006 $user_host_condition = ' WHERE `User`'
4007 .' = \'' . PMA_Util
::sqlAddSlashes($_REQUEST['old_username']) . "'"
4009 .' = \'' . PMA_Util
::sqlAddSlashes($_REQUEST['old_hostname']) . '\';';
4011 $res = $GLOBALS['dbi']->query(
4012 'SELECT * FROM `mysql`.`db`' . $user_host_condition
4015 while ($row = $GLOBALS['dbi']->fetchAssoc($res)) {
4016 $queries[] = 'GRANT ' . join(', ', PMA_extractPrivInfo($row))
4017 .' ON ' . PMA_Util
::backquote($row['Db']) . '.*'
4018 .' TO \'' . PMA_Util
::sqlAddSlashes($username)
4019 . '\'@\'' . PMA_Util
::sqlAddSlashes($hostname) . '\''
4020 . ($row['Grant_priv'] == 'Y' ?
' WITH GRANT OPTION;' : ';');
4022 $GLOBALS['dbi']->freeResult($res);
4024 $queries = PMA_getTablePrivsQueriesForChangeOrCopyUser(
4025 $user_host_condition, $queries, $username, $hostname
4032 * Prepares queries for adding users and
4033 * also create database and return query and message
4035 * @param boolean $_error whether user create or not
4036 * @param string $real_sql_query SQL query for add a user
4037 * @param string $sql_query SQL query to be displayed
4038 * @param string $username username
4039 * @param string $hostname host name
4040 * @param string $dbname database name
4042 * @return array $sql_query, $message
4044 function PMA_addUserAndCreateDatabase($_error, $real_sql_query, $sql_query,
4045 $username, $hostname, $dbname
4047 if ($_error ||
! $GLOBALS['dbi']->tryQuery($real_sql_query)) {
4048 $_REQUEST['createdb-1'] = $_REQUEST['createdb-2']
4049 = $_REQUEST['createdb-3'] = false;
4050 $message = PMA_Message
::rawError($GLOBALS['dbi']->getError());
4052 $message = PMA_Message
::success(__('You have added a new user.'));
4055 if (isset($_REQUEST['createdb-1'])) {
4056 // Create database with same name and grant all privileges
4057 $q = 'CREATE DATABASE IF NOT EXISTS '
4058 . PMA_Util
::backquote(
4059 PMA_Util
::sqlAddSlashes($username)
4062 if (! $GLOBALS['dbi']->tryQuery($q)) {
4063 $message = PMA_Message
::rawError($GLOBALS['dbi']->getError());
4067 * Reload the navigation
4069 $GLOBALS['reload'] = true;
4070 $GLOBALS['db'] = $username;
4072 $q = 'GRANT ALL PRIVILEGES ON '
4073 . PMA_Util
::backquote(
4074 PMA_Util
::escapeMysqlWildcards(
4075 PMA_Util
::sqlAddSlashes($username)
4078 . PMA_Util
::sqlAddSlashes($username)
4079 . '\'@\'' . PMA_Util
::sqlAddSlashes($hostname) . '\';';
4081 if (! $GLOBALS['dbi']->tryQuery($q)) {
4082 $message = PMA_Message
::rawError($GLOBALS['dbi']->getError());
4086 if (isset($_REQUEST['createdb-2'])) {
4087 // Grant all privileges on wildcard name (username\_%)
4088 $q = 'GRANT ALL PRIVILEGES ON '
4089 . PMA_Util
::backquote(
4090 PMA_Util
::sqlAddSlashes($username) . '\_%'
4092 . PMA_Util
::sqlAddSlashes($username)
4093 . '\'@\'' . PMA_Util
::sqlAddSlashes($hostname) . '\';';
4095 if (! $GLOBALS['dbi']->tryQuery($q)) {
4096 $message = PMA_Message
::rawError($GLOBALS['dbi']->getError());
4100 if (isset($_REQUEST['createdb-3'])) {
4101 // Grant all privileges on the specified database to the new user
4102 $q = 'GRANT ALL PRIVILEGES ON '
4103 . PMA_Util
::backquote(
4104 PMA_Util
::sqlAddSlashes($dbname)
4106 . PMA_Util
::sqlAddSlashes($username)
4107 . '\'@\'' . PMA_Util
::sqlAddSlashes($hostname) . '\';';
4109 if (! $GLOBALS['dbi']->tryQuery($q)) {
4110 $message = PMA_Message
::rawError($GLOBALS['dbi']->getError());
4113 return array($sql_query, $message);
4117 * Get SQL queries for Display and Add user
4119 * @param string $username usernam
4120 * @param string $hostname host name
4121 * @param string $password password
4123 * @return array ($create_user_real, $create_user_show,$real_sql_query, $sql_query)
4125 function PMA_getSqlQueriesForDisplayAndAddUser($username, $hostname, $password)
4128 $create_user_real = 'CREATE USER \''
4129 . PMA_Util
::sqlAddSlashes($username) . '\'@\''
4130 . PMA_Util
::sqlAddSlashes($hostname) . '\'';
4132 $real_sql_query = 'GRANT ' . join(', ', PMA_extractPrivInfo()) . ' ON *.* TO \''
4133 . PMA_Util
::sqlAddSlashes($username) . '\'@\''
4134 . PMA_Util
::sqlAddSlashes($hostname) . '\'';
4136 if ($_POST['pred_password'] != 'none' && $_POST['pred_password'] != 'keep') {
4137 $sql_query = $real_sql_query . ' IDENTIFIED BY \'***\'';
4138 $real_sql_query .= ' IDENTIFIED BY \''
4139 . PMA_Util
::sqlAddSlashes($_POST['pma_pw']) . '\'';
4140 if (isset($create_user_real)) {
4141 $create_user_show = $create_user_real . ' IDENTIFIED BY \'***\'';
4142 $create_user_real .= ' IDENTIFIED BY \''
4143 . PMA_Util
::sqlAddSlashes($_POST['pma_pw']) . '\'';
4146 if ($_POST['pred_password'] == 'keep' && ! empty($password)) {
4147 $real_sql_query .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
4148 if (isset($create_user_real)) {
4149 $create_user_real .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
4152 $sql_query = $real_sql_query;
4153 if (isset($create_user_real)) {
4154 $create_user_show = $create_user_real;
4158 if ((isset($_POST['Grant_priv']) && $_POST['Grant_priv'] == 'Y')
4159 ||
(isset($_POST['max_questions']) ||
isset($_POST['max_connections'])
4160 ||
isset($_POST['max_updates']) ||
isset($_POST['max_user_connections']))
4162 $with_clause = PMA_getWithClauseForAddUserAndUpdatePrivs();
4163 $real_sql_query .= ' ' . $with_clause;
4164 $sql_query .= ' ' . $with_clause;
4167 if (isset($create_user_real)) {
4168 $create_user_real .= ';';
4169 $create_user_show .= ';';
4171 $real_sql_query .= ';';
4174 return array($create_user_real,