' . "\n" . PMA_getIcon('b_usrlist.png') . __('Privileges') . "\n" . '' . "\n"; PMA_Message::error(__('No Privileges'))->display(); include 'libraries/footer.inc.php'; } // a random number that will be appended to the id of the user forms $random_n = mt_rand(0, 1000000); /** * Escapes wildcard in a database+table specification * before using it in a GRANT statement. * * Escaping a wildcard character in a GRANT is only accepted at the global * or database level, not at table level; this is why I remove * the escaping character. Internally, in mysql.tables_priv.Db there are * no escaping (for example test_db) but in mysql.db you'll see test\_db * for a db-specific privilege. * * @param string $dbname Database name * @param string $tablename Table name * * @return string the escaped (if necessary) database.table */ function PMA_wildcardEscapeForGrant($dbname, $tablename) { if (! strlen($dbname)) { $db_and_table = '*.*'; } else { if (strlen($tablename)) { $db_and_table = PMA_backquote(PMA_unescapeMysqlWildcards($dbname)) . '.' . PMA_backquote($tablename); } else { $db_and_table = PMA_backquote($dbname) . '.*'; } } return $db_and_table; } /** * Generates a condition on the user name * * @param string $initial the user's initial * * @return string the generated condition */ function PMA_rangeOfUsers($initial = '') { // strtolower() is used because the User field // might be BINARY, so LIKE would be case sensitive if (! empty($initial)) { $ret = " WHERE `User` LIKE '" . PMA_sqlAddSlashes($initial, true) . "%'" . " OR `User` LIKE '" . PMA_sqlAddSlashes(strtolower($initial), true) . "%'"; } else { $ret = ''; } return $ret; } // end function /** * Extracts the privilege information of a priv table row * * @param array $row the row * @param boolean $enableHTML add tag with tooltips * * @global resource $user_link the database connection * * @return array */ function PMA_extractPrivInfo($row = '', $enableHTML = false) { $grants = array( array( 'Select_priv', 'SELECT', __('Allows reading data.')), array( 'Insert_priv', 'INSERT', __('Allows inserting and replacing data.')), array( 'Update_priv', 'UPDATE', __('Allows changing data.')), array( 'Delete_priv', 'DELETE', __('Allows deleting data.')), array( 'Create_priv', 'CREATE', __('Allows creating new databases and tables.')), array( 'Drop_priv', 'DROP', __('Allows dropping databases and tables.')), array( 'Reload_priv', 'RELOAD', __('Allows reloading server settings and flushing the server\'s caches.')), array( 'Shutdown_priv', 'SHUTDOWN', __('Allows shutting down the server.')), array( 'Process_priv', 'PROCESS', __('Allows viewing processes of all users')), array( 'File_priv', 'FILE', __('Allows importing data from and exporting data into files.')), array( 'References_priv', 'REFERENCES', __('Has no effect in this MySQL version.')), array( 'Index_priv', 'INDEX', __('Allows creating and dropping indexes.')), array( 'Alter_priv', 'ALTER', __('Allows altering the structure of existing tables.')), array( 'Show_db_priv', 'SHOW DATABASES', __('Gives access to the complete list of databases.')), array( 'Super_priv', 'SUPER', __('Allows connecting, even if maximum number of connections is reached; required for most administrative operations like setting global variables or killing threads of other users.')), array( 'Create_tmp_table_priv', 'CREATE TEMPORARY TABLES', __('Allows creating temporary tables.')), array( 'Lock_tables_priv', 'LOCK TABLES', __('Allows locking tables for the current thread.')), array( 'Repl_slave_priv', 'REPLICATION SLAVE', __('Needed for the replication slaves.')), array( 'Repl_client_priv', 'REPLICATION CLIENT', __('Allows the user to ask where the slaves / masters are.')), array( 'Create_view_priv', 'CREATE VIEW', __('Allows creating new views.')), array( 'Event_priv', 'EVENT', __('Allows to set up events for the event scheduler')), array( 'Trigger_priv', 'TRIGGER', __('Allows creating and dropping triggers')), // for table privs: array( 'Create View_priv', 'CREATE VIEW', __('Allows creating new views.')), array( 'Show_view_priv', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')), // for table privs: array( 'Show view_priv', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')), array( 'Create_routine_priv', 'CREATE ROUTINE', __('Allows creating stored routines.')), array( 'Alter_routine_priv', 'ALTER ROUTINE', __('Allows altering and dropping stored routines.')), array( 'Create_user_priv', 'CREATE USER', __('Allows creating, dropping and renaming user accounts.')), array( 'Execute_priv', 'EXECUTE', __('Allows executing stored routines.')), ); if (! empty($row) && isset($row['Table_priv'])) { $row1 = PMA_DBI_fetch_single_row( 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';', 'ASSOC', $GLOBALS['userlink'] ); $av_grants = explode( '\',\'', substr($row1['Type'], 5, strlen($row1['Type']) - 7) ); unset($row1); $users_grants = explode(',', $row['Table_priv']); foreach ($av_grants as $current_grant) { $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ? 'Y' : 'N'; } unset($current_grant); unset($av_grants); unset($users_grants); } $privs = array(); $allPrivileges = true; foreach ($grants as $current_grant) { if ((! empty($row) && isset($row[$current_grant[0]])) || (empty($row) && isset($GLOBALS[$current_grant[0]])) ) { if ((! empty($row) && $row[$current_grant[0]] == 'Y') || (empty($row) && ($GLOBALS[$current_grant[0]] == 'Y' || (is_array($GLOBALS[$current_grant[0]]) && count($GLOBALS[$current_grant[0]]) == $GLOBALS['column_count'] && empty($GLOBALS[$current_grant[0] . '_none'])))) ) { if ($enableHTML) { $privs[] = '' . $current_grant[1] . ''; } else { $privs[] = $current_grant[1]; } } elseif (! empty($GLOBALS[$current_grant[0]]) && is_array($GLOBALS[$current_grant[0]]) && empty($GLOBALS[$current_grant[0] . '_none'])) { if ($enableHTML) { $priv_string = '' . $current_grant[1] . ''; } else { $priv_string = $current_grant[1]; } $privs[] = $priv_string . ' (`' . join('`, `', $GLOBALS[$current_grant[0]]) . '`)'; } else { $allPrivileges = false; } } } if (empty($privs)) { if ($enableHTML) { $privs[] = 'USAGE'; } else { $privs[] = 'USAGE'; } } elseif ($allPrivileges && (! isset($GLOBALS['grant_count']) || count($privs) == $GLOBALS['grant_count']) ) { if ($enableHTML) { $privs = array('ALL PRIVILEGES' ); } else { $privs = array('ALL PRIVILEGES'); } } return $privs; } // end of the 'PMA_extractPrivInfo()' function /** * Displays on which column(s) a table-specific privilege is granted * * @param array $columns * @param array $row * @param string $name_for_select * @param string $priv_for_header * @param string $name * @param string $name_for_dfn * @param string $name_for_current * * @return void */ function PMA_displayColumnPrivs($columns, $row, $name_for_select, $priv_for_header, $name, $name_for_dfn, $name_for_current ) { echo '
' . "\n" . '
' . "\n" . ' ' . "\n" . ' ' . __('Or') . '' . "\n" . ' ' . "\n" . '
' . "\n"; } // end function /** * Displays the privileges form table * * @param string $db the database * @param string $table the table * @param boolean $submit wheather to display the submit button or not * * @global array $cfg the phpMyAdmin configuration * @global ressource $user_link the database connection * * @return void */ function PMA_displayPrivTable($db = '*', $table = '*', $submit = true) { global $random_n; if ($db == '*') { $table = '*'; } if (isset($GLOBALS['username'])) { $username = $GLOBALS['username']; $hostname = $GLOBALS['hostname']; if ($db == '*') { $sql_query = "SELECT * FROM `mysql`.`user`" ." WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'" ." AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "';"; } elseif ($table == '*') { $sql_query = "SELECT * FROM `mysql`.`db`" ." WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'" ." AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "'" ." AND '" . PMA_unescapeMysqlWildcards($db) . "'" ." LIKE `Db`;"; } else { $sql_query = "SELECT `Table_priv`" ." FROM `mysql`.`tables_priv`" ." WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'" ." AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "'" ." AND `Db` = '" . PMA_unescapeMysqlWildcards($db) . "'" ." AND `Table_name` = '" . PMA_sqlAddSlashes($table) . "';"; } $row = PMA_DBI_fetch_single_row($sql_query); } if (empty($row)) { if ($table == '*') { if ($db == '*') { $sql_query = 'SHOW COLUMNS FROM `mysql`.`user`;'; } elseif ($table == '*') { $sql_query = 'SHOW COLUMNS FROM `mysql`.`db`;'; } $res = PMA_DBI_query($sql_query); while ($row1 = PMA_DBI_fetch_row($res)) { if (substr($row1[0], 0, 4) == 'max_') { $row[$row1[0]] = 0; } else { $row[$row1[0]] = 'N'; } } PMA_DBI_free_result($res); } else { $row = array('Table_priv' => ''); } } if (isset($row['Table_priv'])) { $row1 = PMA_DBI_fetch_single_row( 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';', 'ASSOC', $GLOBALS['userlink'] ); // note: in MySQL 5.0.3 we get "Create View', 'Show view'; // the View for Create is spelled with uppercase V // the view for Show is spelled with lowercase v // and there is a space between the words $av_grants = explode( '\',\'', substr( $row1['Type'], strpos($row1['Type'], '(') + 2, strpos($row1['Type'], ')') - strpos($row1['Type'], '(') - 3 ) ); unset($row1); $users_grants = explode(',', $row['Table_priv']); foreach ($av_grants as $current_grant) { $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ? 'Y' : 'N'; } unset($row['Table_priv'], $current_grant, $av_grants, $users_grants); // get collumns $res = PMA_DBI_try_query( 'SHOW COLUMNS FROM ' . PMA_backquote(PMA_unescapeMysqlWildcards($db)) . '.' . PMA_backquote($table) . ';' ); $columns = array(); if ($res) { while ($row1 = PMA_DBI_fetch_row($res)) { $columns[$row1[0]] = array( 'Select' => false, 'Insert' => false, 'Update' => false, 'References' => false ); } PMA_DBI_free_result($res); } unset($res, $row1); } // t a b l e - s p e c i f i c p r i v i l e g e s if (! empty($columns)) { $res = PMA_DBI_query( 'SELECT `Column_name`, `Column_priv`' .' FROM `mysql`.`columns_priv`' .' WHERE `User`' .' = \'' . PMA_sqlAddSlashes($username) . "'" .' AND `Host`' .' = \'' . PMA_sqlAddSlashes($hostname) . "'" .' AND `Db`' .' = \'' . PMA_sqlAddSlashes(PMA_unescapeMysqlWildcards($db)) . "'" .' AND `Table_name`' .' = \'' . PMA_sqlAddSlashes($table) . '\';' ); while ($row1 = PMA_DBI_fetch_row($res)) { $row1[1] = explode(',', $row1[1]); foreach ($row1[1] as $current) { $columns[$row1[0]][$current] = true; } } PMA_DBI_free_result($res); unset($res, $row1, $current); echo '' . "\n" . '' . "\n" . '
' . "\n" . ' ' . __('Table-specific privileges') . PMA_showHint(__('Note: MySQL privilege names are expressed in English')) . '' . "\n"; // privs that are attached to a specific column PMA_displayColumnPrivs( $columns, $row, 'Select_priv', 'SELECT', 'select', __('Allows reading data.'), 'Select' ); PMA_displayColumnPrivs( $columns, $row, 'Insert_priv', 'INSERT', 'insert', __('Allows inserting and replacing data.'), 'Insert' ); PMA_displayColumnPrivs( $columns, $row, 'Update_priv', 'UPDATE', 'update', __('Allows changing data.'), 'Update' ); PMA_displayColumnPrivs( $columns, $row, 'References_priv', 'REFERENCES', 'references', __('Has no effect in this MySQL version.'), 'References' ); // privs that are not attached to a specific column echo '
' . "\n"; foreach ($row as $current_grant => $current_grant_value) { $grant_type = substr($current_grant, 0, (strlen($current_grant) - 5)); if (in_array($grant_type, array('Select', 'Insert', 'Update', 'References'))) { continue; } // make a substitution to match the messages variables; // also we must substitute the grant we get, because we can't generate // a form variable containing blanks (those would get changed to // an underscore when receiving the POST) if ($current_grant == 'Create View_priv') { $tmp_current_grant = 'CreateView_priv'; $current_grant = 'Create_view_priv'; } elseif ($current_grant == 'Show view_priv') { $tmp_current_grant = 'ShowView_priv'; $current_grant = 'Show_view_priv'; } else { $tmp_current_grant = $current_grant; } echo '
' . "\n" . ' ' . "\n"; echo ' ' . "\n" . '
' . "\n"; } // end foreach () echo '
' . "\n"; // for Safari 2.0.2 echo '
' . "\n"; } else { // g l o b a l o r d b - s p e c i f i c // $privTable_names = array(0 => __('Data'), 1 => __('Structure'), 2 => __('Administration')); // d a t a $privTable[0] = array( array('Select', 'SELECT', __('Allows reading data.')), array('Insert', 'INSERT', __('Allows inserting and replacing data.')), array('Update', 'UPDATE', __('Allows changing data.')), array('Delete', 'DELETE', __('Allows deleting data.')) ); if ($db == '*') { $privTable[0][] = array('File', 'FILE', __('Allows importing data from and exporting data into files.')); } // s t r u c t u r e $privTable[1] = array( array('Create', 'CREATE', ($table == '*' ? __('Allows creating new databases and tables.') : __('Allows creating new tables.'))), array('Alter', 'ALTER', __('Allows altering the structure of existing tables.')), array('Index', 'INDEX', __('Allows creating and dropping indexes.')), array('Drop', 'DROP', ($table == '*' ? __('Allows dropping databases and tables.') : __('Allows dropping tables.'))), array('Create_tmp_table', 'CREATE TEMPORARY TABLES', __('Allows creating temporary tables.')), array('Show_view', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')), array('Create_routine', 'CREATE ROUTINE', __('Allows creating stored routines.')), array('Alter_routine', 'ALTER ROUTINE', __('Allows altering and dropping stored routines.')), array('Execute', 'EXECUTE', __('Allows executing stored routines.')), ); // this one is for a db-specific priv: Create_view_priv if (isset($row['Create_view_priv'])) { $privTable[1][] = array('Create_view', 'CREATE VIEW', __('Allows creating new views.')); } // this one is for a table-specific priv: Create View_priv if (isset($row['Create View_priv'])) { $privTable[1][] = array('Create View', 'CREATE VIEW', __('Allows creating new views.')); } if (isset($row['Event_priv'])) { // MySQL 5.1.6 $privTable[1][] = array('Event', 'EVENT', __('Allows to set up events for the event scheduler')); $privTable[1][] = array('Trigger', 'TRIGGER', __('Allows creating and dropping triggers')); } // a d m i n i s t r a t i o n $privTable[2] = array( array('Grant', 'GRANT', __('Allows adding users and privileges without reloading the privilege tables.')), ); if ($db == '*') { $privTable[2][] = array('Super', 'SUPER', __('Allows connecting, even if maximum number of connections is reached; required for most administrative operations like setting global variables or killing threads of other users.')); $privTable[2][] = array('Process', 'PROCESS', __('Allows viewing processes of all users')); $privTable[2][] = array('Reload', 'RELOAD', __('Allows reloading server settings and flushing the server\'s caches.')); $privTable[2][] = array('Shutdown', 'SHUTDOWN', __('Allows shutting down the server.')); $privTable[2][] = array('Show_db', 'SHOW DATABASES', __('Gives access to the complete list of databases.')); } $privTable[2][] = array('Lock_tables', 'LOCK TABLES', __('Allows locking tables for the current thread.')); $privTable[2][] = array('References', 'REFERENCES', __('Has no effect in this MySQL version.')); if ($db == '*') { $privTable[2][] = array('Repl_client', 'REPLICATION CLIENT', __('Allows the user to ask where the slaves / masters are.')); $privTable[2][] = array('Repl_slave', 'REPLICATION SLAVE', __('Needed for the replication slaves.')); $privTable[2][] = array('Create_user', 'CREATE USER', __('Allows creating, dropping and renaming user accounts.')); } echo '' . "\n" . '
' . "\n" . ' ' . "\n" . ' ' . ($db == '*' ? __('Global privileges') : ($table == '*' ? __('Database-specific privileges') : __('Table-specific privileges'))) . "\n" . ' (' . __('Check All') . ' /' . "\n" . ' ' . __('Uncheck All') . ')' . "\n" . ' ' . "\n" . '

' . __('Note: MySQL privilege names are expressed in English') . '

' . "\n"; // Output the Global privilege tables with checkboxes foreach ($privTable as $i => $table) { echo '
' . "\n" . ' ' . __($privTable_names[$i]) . '' . "\n"; foreach ($table as $priv) { echo '
' . "\n" . ' ' . "\n" . ' ' . "\n" . '
' . "\n"; } echo '
' . "\n"; } // The "Resource limits" box is not displayed for db-specific privs if ($db == '*') { echo '
' . "\n" . ' ' . __('Resource limits') . '' . "\n" . '

' . __('Note: Setting these options to 0 (zero) removes the limit.') . '

' . "\n" . '
' . "\n" . ' ' . "\n" . ' ' . "\n" . '
' . "\n" . '
' . "\n" . ' ' . "\n" . ' ' . "\n" . '
' . "\n" . '
' . "\n" . ' ' . "\n" . ' ' . "\n" . '
' . "\n" . '
' . "\n" . ' ' . "\n" . ' ' . "\n" . '
' . "\n" . '
' . "\n"; } // for Safari 2.0.2 echo '
' . "\n"; } echo '
' . "\n"; if ($submit) { echo '' . "\n"; } } // end of the 'PMA_displayPrivTable()' function /** * Displays the fields used by the "new user" form as well as the * "change login information / copy user" form. * * @param string $mode are we creating a new user or are we just * changing one? (allowed values: 'new', 'change') * * @global array $cfg the phpMyAdmin configuration * @global ressource $user_link the database connection * * @return void */ function PMA_displayLoginInformationFields($mode = 'new') { // Get user/host name lengths $fields_info = PMA_DBI_get_columns('mysql', 'user', null, true); $username_length = 16; $hostname_length = 41; foreach ($fields_info as $val) { if ($val['Field'] == 'User') { strtok($val['Type'], '()'); $v = strtok('()'); if (is_int($v)) { $username_length = $v; } } elseif ($val['Field'] == 'Host') { strtok($val['Type'], '()'); $v = strtok('()'); if (is_int($v)) { $hostname_length = $v; } } } unset($fields_info); if (isset($GLOBALS['username']) && strlen($GLOBALS['username']) === 0) { $GLOBALS['pred_username'] = 'any'; } echo '
' . "\n" . '' . __('Login Information') . '' . "\n" . '
' . "\n" . '' . "\n" . '' . "\n" . ' ' . "\n" . '' . "\n" . '' . "\n" . '
' . "\n" . '
' . "\n" . '' . "\n" . '' . "\n" . ' ' . "\n" . '' . "\n" . '' . "\n" . PMA_showHint(__('When Host table is used, this field is ignored and values stored in Host table are used instead.')) . '
' . "\n" . '
' . "\n" . '' . "\n" . '' . "\n" . ' ' . "\n" . '' . "\n" . '' . "\n" . '
' . "\n" . '
' . "\n" . '' . "\n" . ' ' . "\n" . '' . "\n" . '
' . "\n" // Generate password added here via jQuery . '
' . "\n"; } // end of the 'PMA_displayUserAndHostFields()' function /** * Returns all the grants for a certain user on a certain host * Used in the export privileges for all users section * * @param string $user User name * @param string $host Host name * * @return string containing all the grants text */ function PMA_getGrants($user, $host) { $grants = PMA_DBI_fetch_result("SHOW GRANTS FOR '" . PMA_sqlAddSlashes($user) . "'@'" . PMA_sqlAddSlashes($host) . "'"); $response = ''; foreach ($grants as $one_grant) { $response .= $one_grant . ";\n\n"; } return $response; } // end of the 'PMA_getGrants()' function /** * Changes / copies a user, part I */ if (isset($_REQUEST['change_copy'])) { $user_host_condition = ' WHERE `User`' .' = \'' . PMA_sqlAddSlashes($old_username) . "'" .' AND `Host`' .' = \'' . PMA_sqlAddSlashes($old_hostname) . '\';'; $row = PMA_DBI_fetch_single_row('SELECT * FROM `mysql`.`user` ' . $user_host_condition); if (! $row) { PMA_Message::notice(__('No user found.'))->display(); unset($_REQUEST['change_copy']); } else { extract($row, EXTR_OVERWRITE); // Recent MySQL versions have the field "Password" in mysql.user, // so the previous extract creates $Password but this script // uses $password if (! isset($password) && isset($Password)) { $password = $Password; } $queries = array(); } } /** * Adds a user * (Changes / copies a user, part II) */ if (isset($_REQUEST['adduser_submit']) || isset($_REQUEST['change_copy'])) { $sql_query = ''; if ($pred_username == 'any') { $username = ''; } switch ($pred_hostname) { case 'any': $hostname = '%'; break; case 'localhost': $hostname = 'localhost'; break; case 'hosttable': $hostname = ''; break; case 'thishost': $_user_name = PMA_DBI_fetch_value('SELECT USER()'); $hostname = substr($_user_name, (strrpos($_user_name, '@') + 1)); unset($_user_name); break; } $sql = "SELECT '1' FROM `mysql`.`user`" . " WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'" . " AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "';"; if (PMA_DBI_fetch_value($sql) == 1) { $message = PMA_Message::error(__('The user %s already exists!')); $message->addParam('[i]\'' . $username . '\'@\'' . $hostname . '\'[/i]'); $_REQUEST['adduser'] = true; $_add_user_error = true; } else { $create_user_real = 'CREATE USER \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\''; $real_sql_query = 'GRANT ' . join(', ', PMA_extractPrivInfo()) . ' ON *.* TO \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\''; if ($pred_password != 'none' && $pred_password != 'keep') { $sql_query = $real_sql_query . ' IDENTIFIED BY \'***\''; $real_sql_query .= ' IDENTIFIED BY \'' . PMA_sqlAddSlashes($pma_pw) . '\''; if (isset($create_user_real)) { $create_user_show = $create_user_real . ' IDENTIFIED BY \'***\''; $create_user_real .= ' IDENTIFIED BY \'' . PMA_sqlAddSlashes($pma_pw) . '\''; } } else { if ($pred_password == 'keep' && ! empty($password)) { $real_sql_query .= ' IDENTIFIED BY PASSWORD \'' . $password . '\''; if (isset($create_user_real)) { $create_user_real .= ' IDENTIFIED BY PASSWORD \'' . $password . '\''; } } $sql_query = $real_sql_query; if (isset($create_user_real)) { $create_user_show = $create_user_real; } } /** * @todo similar code appears twice in this script */ if ((isset($Grant_priv) && $Grant_priv == 'Y') || (isset($max_questions) || isset($max_connections) || isset($max_updates) || isset($max_user_connections)) ) { $real_sql_query .= ' WITH'; $sql_query .= ' WITH'; if (isset($Grant_priv) && $Grant_priv == 'Y') { $real_sql_query .= ' GRANT OPTION'; $sql_query .= ' GRANT OPTION'; } if (isset($max_questions)) { // avoid negative values $max_questions = max(0, (int)$max_questions); $real_sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions; $sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions; } if (isset($max_connections)) { $max_connections = max(0, (int)$max_connections); $real_sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections; $sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections; } if (isset($max_updates)) { $max_updates = max(0, (int)$max_updates); $real_sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates; $sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates; } if (isset($max_user_connections)) { $max_user_connections = max(0, (int)$max_user_connections); $real_sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections; $sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections; } } if (isset($create_user_real)) { $create_user_real .= ';'; $create_user_show .= ';'; } $real_sql_query .= ';'; $sql_query .= ';'; if (empty($_REQUEST['change_copy'])) { $_error = false; if (isset($create_user_real)) { if (! PMA_DBI_try_query($create_user_real)) { $_error = true; } $sql_query = $create_user_show . $sql_query; } if ($_error || ! PMA_DBI_try_query($real_sql_query)) { $_REQUEST['createdb-1'] = $_REQUEST['createdb-2'] = $_REQUEST['createdb-3'] = false; $message = PMA_Message::rawError(PMA_DBI_getError()); } else { $message = PMA_Message::success(__('You have added a new user.')); } if (isset($_REQUEST['createdb-1'])) { // Create database with same name and grant all privileges $q = 'CREATE DATABASE IF NOT EXISTS ' . PMA_backquote(PMA_sqlAddSlashes($username)) . ';'; $sql_query .= $q; if (! PMA_DBI_try_query($q)) { $message = PMA_Message::rawError(PMA_DBI_getError()); } /** * If we are not in an Ajax request, we can't reload navigation now */ if ($GLOBALS['is_ajax_request'] != true) { // this is needed in case tracking is on: $GLOBALS['db'] = $username; $GLOBALS['reload'] = true; PMA_reloadNavigation(); } $q = 'GRANT ALL PRIVILEGES ON ' . PMA_backquote(PMA_escapeMysqlWildcards(PMA_sqlAddSlashes($username))) . '.* TO \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';'; $sql_query .= $q; if (! PMA_DBI_try_query($q)) { $message = PMA_Message::rawError(PMA_DBI_getError()); } } if (isset($_REQUEST['createdb-2'])) { // Grant all privileges on wildcard name (username\_%) $q = 'GRANT ALL PRIVILEGES ON ' . PMA_backquote(PMA_sqlAddSlashes($username) . '\_%') . '.* TO \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';'; $sql_query .= $q; if (! PMA_DBI_try_query($q)) { $message = PMA_Message::rawError(PMA_DBI_getError()); } } if (isset($_REQUEST['createdb-3'])) { // Grant all privileges on the specified database to the new user $q = 'GRANT ALL PRIVILEGES ON ' . PMA_backquote(PMA_sqlAddSlashes($dbname)) . '.* TO \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';'; $sql_query .= $q; if (! PMA_DBI_try_query($q)) { $message = PMA_Message::rawError(PMA_DBI_getError()); } } } else { if (isset($create_user_real)) { $queries[] = $create_user_real; } $queries[] = $real_sql_query; // we put the query containing the hidden password in // $queries_for_display, at the same position occupied // by the real query in $queries $tmp_count = count($queries); if (isset($create_user_real)) { $queries_for_display[$tmp_count - 2] = $create_user_show; } $queries_for_display[$tmp_count - 1] = $sql_query; } unset($res, $real_sql_query); } } /** * Changes / copies a user, part III */ if (isset($_REQUEST['change_copy'])) { $user_host_condition = ' WHERE `User`' .' = \'' . PMA_sqlAddSlashes($old_username) . "'" .' AND `Host`' .' = \'' . PMA_sqlAddSlashes($old_hostname) . '\';'; $res = PMA_DBI_query('SELECT * FROM `mysql`.`db`' . $user_host_condition); while ($row = PMA_DBI_fetch_assoc($res)) { $queries[] = 'GRANT ' . join(', ', PMA_extractPrivInfo($row)) .' ON ' . PMA_backquote($row['Db']) . '.*' .' TO \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\'' . ($row['Grant_priv'] == 'Y' ? ' WITH GRANT OPTION;' : ';'); } PMA_DBI_free_result($res); $res = PMA_DBI_query( 'SELECT `Db`, `Table_name`, `Table_priv` FROM `mysql`.`tables_priv`' . $user_host_condition, $GLOBALS['userlink'], PMA_DBI_QUERY_STORE ); while ($row = PMA_DBI_fetch_assoc($res)) { $res2 = PMA_DBI_QUERY( 'SELECT `Column_name`, `Column_priv`' .' FROM `mysql`.`columns_priv`' .' WHERE `User`' .' = \'' . PMA_sqlAddSlashes($old_username) . "'" .' AND `Host`' .' = \'' . PMA_sqlAddSlashes($old_hostname) . '\'' .' AND `Db`' .' = \'' . PMA_sqlAddSlashes($row['Db']) . "'" .' AND `Table_name`' .' = \'' . PMA_sqlAddSlashes($row['Table_name']) . "'" .';', null, PMA_DBI_QUERY_STORE ); $tmp_privs1 = PMA_extractPrivInfo($row); $tmp_privs2 = array( 'Select' => array(), 'Insert' => array(), 'Update' => array(), 'References' => array() ); while ($row2 = PMA_DBI_fetch_assoc($res2)) { $tmp_array = explode(',', $row2['Column_priv']); if (in_array('Select', $tmp_array)) { $tmp_privs2['Select'][] = $row2['Column_name']; } if (in_array('Insert', $tmp_array)) { $tmp_privs2['Insert'][] = $row2['Column_name']; } if (in_array('Update', $tmp_array)) { $tmp_privs2['Update'][] = $row2['Column_name']; } if (in_array('References', $tmp_array)) { $tmp_privs2['References'][] = $row2['Column_name']; } unset($tmp_array); } if (count($tmp_privs2['Select']) > 0 && ! in_array('SELECT', $tmp_privs1)) { $tmp_privs1[] = 'SELECT (`' . join('`, `', $tmp_privs2['Select']) . '`)'; } if (count($tmp_privs2['Insert']) > 0 && ! in_array('INSERT', $tmp_privs1)) { $tmp_privs1[] = 'INSERT (`' . join('`, `', $tmp_privs2['Insert']) . '`)'; } if (count($tmp_privs2['Update']) > 0 && ! in_array('UPDATE', $tmp_privs1)) { $tmp_privs1[] = 'UPDATE (`' . join('`, `', $tmp_privs2['Update']) . '`)'; } if (count($tmp_privs2['References']) > 0 && ! in_array('REFERENCES', $tmp_privs1)) { $tmp_privs1[] = 'REFERENCES (`' . join('`, `', $tmp_privs2['References']) . '`)'; } unset($tmp_privs2); $queries[] = 'GRANT ' . join(', ', $tmp_privs1) . ' ON ' . PMA_backquote($row['Db']) . '.' . PMA_backquote($row['Table_name']) . ' TO \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\'' . (in_array('Grant', explode(',', $row['Table_priv'])) ? ' WITH GRANT OPTION;' : ';'); } } /** * Updates privileges */ if (! empty($update_privs)) { $db_and_table = PMA_wildcardEscapeForGrant($dbname, (isset($tablename) ? $tablename : '')); $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $db_and_table . ' FROM \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';'; if (! isset($Grant_priv) || $Grant_priv != 'Y') { $sql_query1 = 'REVOKE GRANT OPTION ON ' . $db_and_table . ' FROM \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';'; } else { $sql_query1 = ''; } // Should not do a GRANT USAGE for a table-specific privilege, it // causes problems later (cannot revoke it) if (! (isset($tablename) && 'USAGE' == implode('', PMA_extractPrivInfo()))) { $sql_query2 = 'GRANT ' . join(', ', PMA_extractPrivInfo()) . ' ON ' . $db_and_table . ' TO \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\''; /** * @todo similar code appears twice in this script */ if ((isset($Grant_priv) && $Grant_priv == 'Y') || (! isset($dbname) && (isset($max_questions) || isset($max_connections) || isset($max_updates) || isset($max_user_connections))) ) { $sql_query2 .= 'WITH'; if (isset($Grant_priv) && $Grant_priv == 'Y') { $sql_query2 .= ' GRANT OPTION'; } if (isset($max_questions)) { $max_questions = max(0, (int)$max_questions); $sql_query2 .= ' MAX_QUERIES_PER_HOUR ' . $max_questions; } if (isset($max_connections)) { $max_connections = max(0, (int)$max_connections); $sql_query2 .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections; } if (isset($max_updates)) { $max_updates = max(0, (int)$max_updates); $sql_query2 .= ' MAX_UPDATES_PER_HOUR ' . $max_updates; } if (isset($max_user_connections)) { $max_user_connections = max(0, (int)$max_user_connections); $sql_query2 .= ' MAX_USER_CONNECTIONS ' . $max_user_connections; } } $sql_query2 .= ';'; } if (! PMA_DBI_try_query($sql_query0)) { // This might fail when the executing user does not have ALL PRIVILEGES himself. // See https://sourceforge.net/tracker/index.php?func=detail&aid=3285929&group_id=23067&atid=377408 $sql_query0 = ''; } if (isset($sql_query1) && ! PMA_DBI_try_query($sql_query1)) { // this one may fail, too... $sql_query1 = ''; } if (isset($sql_query2)) { PMA_DBI_query($sql_query2); } else { $sql_query2 = ''; } $sql_query = $sql_query0 . ' ' . $sql_query1 . ' ' . $sql_query2; $message = PMA_Message::success(__('You have updated the privileges for %s.')); $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\''); } /** * Revokes Privileges */ if (isset($_REQUEST['revokeall'])) { $db_and_table = PMA_wildcardEscapeForGrant($dbname, isset($tablename) ? $tablename : ''); $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $db_and_table . ' FROM \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';'; $sql_query1 = 'REVOKE GRANT OPTION ON ' . $db_and_table . ' FROM \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\';'; PMA_DBI_query($sql_query0); if (! PMA_DBI_try_query($sql_query1)) { // this one may fail, too... $sql_query1 = ''; } $sql_query = $sql_query0 . ' ' . $sql_query1; $message = PMA_Message::success(__('You have revoked the privileges for %s')); $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\''); if (! isset($tablename)) { unset($dbname); } else { unset($tablename); } } /** * Updates the password */ if (isset($_REQUEST['change_pw'])) { // similar logic in user_password.php $message = ''; if (empty($_REQUEST['nopass']) && isset($pma_pw) && isset($pma_pw2)) { if ($pma_pw != $pma_pw2) { $message = PMA_Message::error(__('The passwords aren\'t the same!')); } elseif (empty($pma_pw) || empty($pma_pw2)) { $message = PMA_Message::error(__('The password is empty!')); } } // end if // here $nopass could be == 1 if (empty($message)) { $hashing_function = (! empty($pw_hash) && $pw_hash == 'old' ? 'OLD_' : '') . 'PASSWORD'; // in $sql_query which will be displayed, hide the password $sql_query = 'SET PASSWORD FOR \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\' = ' . (($pma_pw == '') ? '\'\'' : $hashing_function . '(\'' . preg_replace('@.@s', '*', $pma_pw) . '\')'); $local_query = 'SET PASSWORD FOR \'' . PMA_sqlAddSlashes($username) . '\'@\'' . PMA_sqlAddSlashes($hostname) . '\' = ' . (($pma_pw == '') ? '\'\'' : $hashing_function . '(\'' . PMA_sqlAddSlashes($pma_pw) . '\')'); PMA_DBI_try_query($local_query) or PMA_mysqlDie(PMA_DBI_getError(), $sql_query, false, $err_url); $message = PMA_Message::success(__('The password for %s was changed successfully.')); $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\''); } } /** * Deletes users * (Changes / copies a user, part IV) */ if (isset($_REQUEST['delete']) || (isset($_REQUEST['change_copy']) && $_REQUEST['mode'] < 4)) { if (isset($_REQUEST['change_copy'])) { $selected_usr = array($old_username . '&#27;' . $old_hostname); } else { $selected_usr = $_REQUEST['selected_usr']; $queries = array(); } foreach ($selected_usr as $each_user) { list($this_user, $this_host) = explode('&#27;', $each_user); $queries[] = '# ' . sprintf(__('Deleting %s'), '\'' . $this_user . '\'@\'' . $this_host . '\'') . ' ...'; $queries[] = 'DROP USER \'' . PMA_sqlAddSlashes($this_user) . '\'@\'' . PMA_sqlAddSlashes($this_host) . '\';'; if (isset($_REQUEST['drop_users_db'])) { $queries[] = 'DROP DATABASE IF EXISTS ' . PMA_backquote($this_user) . ';'; $GLOBALS['reload'] = true; if ($GLOBALS['is_ajax_request'] != true) { PMA_reloadNavigation(); } } } if (empty($_REQUEST['change_copy'])) { if (empty($queries)) { $message = PMA_Message::error(__('No users selected for deleting!')); } else { if ($_REQUEST['mode'] == 3) { $queries[] = '# ' . __('Reloading the privileges') . ' ...'; $queries[] = 'FLUSH PRIVILEGES;'; } $drop_user_error = ''; foreach ($queries as $sql_query) { if ($sql_query{0} != '#') { if (! PMA_DBI_try_query($sql_query, $GLOBALS['userlink'])) { $drop_user_error .= PMA_DBI_getError() . "\n"; } } } // tracking sets this, causing the deleted db to be shown in navi unset($GLOBALS['db']); $sql_query = join("\n", $queries); if (! empty($drop_user_error)) { $message = PMA_Message::rawError($drop_user_error); } else { $message = PMA_Message::success(__('The selected users have been deleted successfully.')); } } unset($queries); } } /** * Changes / copies a user, part V */ if (isset($_REQUEST['change_copy'])) { $tmp_count = 0; foreach ($queries as $sql_query) { if ($sql_query{0} != '#') { PMA_DBI_query($sql_query); } // when there is a query containing a hidden password, take it // instead of the real query sent if (isset($queries_for_display[$tmp_count])) { $queries[$tmp_count] = $queries_for_display[$tmp_count]; } $tmp_count++; } $message = PMA_Message::success(); $sql_query = join("\n", $queries); } /** * Reloads the privilege tables into memory */ if (isset($_REQUEST['flush_privileges'])) { $sql_query = 'FLUSH PRIVILEGES;'; PMA_DBI_query($sql_query); $message = PMA_Message::success(__('The privileges were reloaded successfully.')); } /** * defines some standard links */ $link_edit = '' . PMA_getIcon('b_usredit.png', __('Edit Privileges')) . ''; $link_revoke = '' . PMA_getIcon('b_usrdrop.png', __('Revoke')) . ''; $link_export = '' . PMA_getIcon('b_tblexport.png', __('Export')) . ''; $link_export_all = '' . PMA_getIcon('b_tblexport.png', __('Export all')) . ''; /** * If we are in an Ajax request for Create User/Edit User/Revoke User/ * Flush Privileges, show $message and exit. */ if ($GLOBALS['is_ajax_request'] && ! isset($_REQUEST['export']) && (! isset($_REQUEST['submit_mult']) || $_REQUEST['submit_mult'] != 'export') && (! isset($_REQUEST['adduser']) || $_add_user_error) && (! isset($_REQUEST['initial']) || empty($_REQUEST['initial'])) && ! isset($_REQUEST['showall']) && ! isset($_REQUEST['edit_user_dialog']) && ! isset($_REQUEST['db_specific'])) { if (isset($sql_query)) { $extra_data['sql_query'] = PMA_getMessage(null, $sql_query); } if (isset($_REQUEST['adduser_submit']) || isset($_REQUEST['change_copy'])) { /** * generate html on the fly for the new user that was just created. */ $new_user_string = ''."\n" .' ' . "\n" .'' . "\n" .'' . htmlspecialchars($hostname) . '' . "\n"; $new_user_string .= ''; if (! empty($password) || isset($pma_pw)) { $new_user_string .= __('Yes'); } else { $new_user_string .= '' . __('No') . ''; }; $new_user_string .= ''."\n"; $new_user_string .= '' . join(', ', PMA_extractPrivInfo('', true)) . ''; //Fill in privileges here $new_user_string .= ''; if ((isset($Grant_priv) && $Grant_priv == 'Y')) { $new_user_string .= __('Yes'); } else { $new_user_string .= __('No'); } $new_user_string .=''; $new_user_string .= '' . sprintf($link_edit, urlencode($username), urlencode($hostname), '', '') . '' . "\n"; $new_user_string .= '' . sprintf($link_export, urlencode($username), urlencode($hostname), (isset($initial) ? $initial : '')) . '' . "\n"; $new_user_string .= ''; $extra_data['new_user_string'] = $new_user_string; /** * Generate the string for this alphabet's initial, to update the user * pagination */ $new_user_initial = strtoupper(substr($username, 0, 1)); $new_user_initial_string = '' . $new_user_initial . ''; $extra_data['new_user_initial'] = $new_user_initial; $extra_data['new_user_initial_string'] = $new_user_initial_string; } if (isset($update_privs)) { $extra_data['db_specific_privs'] = false; if (isset($dbname_is_wildcard)) { $extra_data['db_specific_privs'] = ! $dbname_is_wildcard; } $new_privileges = join(', ', PMA_extractPrivInfo('', true)); $extra_data['new_privileges'] = $new_privileges; } if ($message instanceof PMA_Message) { PMA_ajaxResponse($message, $message->isSuccess(), $extra_data); } } /** * Displays the links */ if (isset($viewing_mode) && $viewing_mode == 'db') { $db = $checkprivs; $url_query .= '&goto=db_operations.php'; // Gets the database structure $sub_part = '_structure'; include 'libraries/db_info.inc.php'; echo "\n"; } else { if (! empty($GLOBALS['message'])) { echo PMA_getMessage($GLOBALS['message']); unset($GLOBALS['message']); } } /** * Displays the page */ // export user definition if (isset($_REQUEST['export']) || (isset($_REQUEST['submit_mult']) && $_REQUEST['submit_mult'] == 'export')) { $response = ''; unset($username, $hostname, $grants, $one_grant); if ($GLOBALS['is_ajax_request']) { PMA_ajaxResponse($response, 1, array('title' => $title)); } else { echo "

$title

$response"; } } if (empty($_REQUEST['adduser']) && (! isset($checkprivs) || ! strlen($checkprivs))) { if (! isset($username)) { // No username is given --> display the overview echo '

' . "\n" . PMA_getIcon('b_usrlist.png') . __('Users overview') . "\n" . '

' . "\n"; $sql_query = 'SELECT *,' . " IF(`Password` = _latin1 '', 'N', 'Y') AS 'Password'" . ' FROM `mysql`.`user`'; $sql_query .= (isset($initial) ? PMA_rangeOfUsers($initial) : ''); $sql_query .= ' ORDER BY `User` ASC, `Host` ASC;'; $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE); if (! $res) { // the query failed! This may have two reasons: // - the user does not have enough privileges // - the privilege tables use a structure of an earlier version. // so let's try a more simple query $sql_query = 'SELECT * FROM `mysql`.`user`'; $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE); if (! $res) { PMA_Message::error(__('No Privileges'))->display(); PMA_DBI_free_result($res); unset($res); } else { // This message is hardcoded because I will replace it by // a automatic repair feature soon. $raw = 'Your privilege table structure seems to be older than' . ' this MySQL version!
' . 'Please run the mysql_upgrade command' . '(mysql_fix_privilege_tables on older systems)' . ' that should be included in your MySQL server distribution' . ' to solve this problem!'; PMA_Message::rawError($raw)->display(); } } else { // we also want users not in table `user` but in other table $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;'); $tables_to_search_for_users = array( 'user', 'db', 'tables_priv', 'columns_priv', 'procs_priv', ); $db_rights_sqls = array(); foreach ($tables_to_search_for_users as $table_search_in) { if (in_array($table_search_in, $tables)) { $db_rights_sqls[] = 'SELECT DISTINCT `User`, `Host` FROM `mysql`.`' . $table_search_in . '` ' . (isset($initial) ? PMA_rangeOfUsers($initial) : ''); } } $user_defaults = array( 'User' => '', 'Host' => '%', 'Password' => '?', 'Grant_priv' => 'N', 'privs' => array('USAGE'), ); // for all initials, even non A-Z $array_initials = array(); // for the rights $db_rights = array(); $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')' .' ORDER BY `User` ASC, `Host` ASC'; $db_rights_result = PMA_DBI_query($db_rights_sql); while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) { $db_rights_row = array_merge($user_defaults, $db_rights_row); $db_rights[$db_rights_row['User']][$db_rights_row['Host']] = $db_rights_row; } PMA_DBI_free_result($db_rights_result); unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row); ksort($db_rights); /** * Displays the initials * In an Ajax request, we don't need to show this. * Also not necassary if there is less than 20 privileges */ if ($GLOBALS['is_ajax_request'] != true && PMA_DBI_num_rows($res) > 20 ) { // initialize to false the letters A-Z for ($letter_counter = 1; $letter_counter < 27; $letter_counter++) { if (! isset($array_initials[chr($letter_counter + 64)])) { $array_initials[chr($letter_counter + 64)] = false; } } $initials = PMA_DBI_try_query('SELECT DISTINCT UPPER(LEFT(`User`,1)) FROM `user` ORDER BY `User` ASC', null, PMA_DBI_QUERY_STORE); while (list($tmp_initial) = PMA_DBI_fetch_row($initials)) { $array_initials[$tmp_initial] = true; } // Display the initials, which can be any characters, not // just letters. For letters A-Z, we add the non-used letters // as greyed out. uksort($array_initials, "strnatcasecmp"); echo ''; foreach ($array_initials as $tmp_initial => $initial_was_found) { if ($initial_was_found) { echo '' . "\n"; } else { echo ''; } } echo '' . "\n"; echo '
' . $tmp_initial . '' . $tmp_initial . '[' . __('Show all') . ']
'; } /** * Display the user overview * (if less than 50 users, display them immediately) */ if (isset($initial) || isset($showall) || PMA_DBI_num_rows($res) < 50) { while ($row = PMA_DBI_fetch_assoc($res)) { $row['privs'] = PMA_extractPrivInfo($row, true); $db_rights[$row['User']][$row['Host']] = $row; } @PMA_DBI_free_result($res); unset($res); echo '
' . "\n" . PMA_generate_common_hidden_inputs('', '') . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n"; echo ' ' . "\n"; echo ' ' . "\n"; echo ' ' . "\n"; $_SESSION['user_host_pairs'] = array(); $pair_count = 0; $odd_row = true; $index_checkbox = -1; foreach ($db_rights as $user) { $index_checkbox++; ksort($user); foreach ($user as $host) { $index_checkbox++; echo ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n"; echo ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' '; echo ''; echo ''; $odd_row = ! $odd_row; $_SESSION['user_host_pairs'][$pair_count]['user'] = $host['User']; $_SESSION['user_host_pairs'][$pair_count]['host'] = $host['Host']; $pair_count ++; } } unset($user, $host, $odd_row); echo '
' . __('User') . '' . __('Host') . '' . __('Password') . '' . __('Global privileges') . ' ' . PMA_showHint(__('Note: MySQL privilege names are expressed in English')) . '' . __('Grant') . '' . __('Action') . '
' . htmlspecialchars($host['Host']) . ''; switch ($host['Password']) { case 'Y': echo __('Yes'); break; case 'N': echo '' . __('No') . ''; break; // this happens if this is a definition not coming from mysql.user default: echo '--'; // in future version, replace by "not present" break; } // end switch echo '' . "\n" . ' ' . implode(',' . "\n" . ' ', $host['privs']) . "\n" . ' ' . ($host['Grant_priv'] == 'Y' ? __('Yes') : __('No')) . ''; printf($link_edit, urlencode($host['User']), urlencode($host['Host']), '', ''); echo ''; printf($link_export, urlencode($host['User']), urlencode($host['Host']), (isset($initial) ? $initial : '')); echo '
' . "\n" .'
' .'
' .'' . __('With selected:') . '' . "\n" .'' . __('Check All') . '' . "\n" .'/' . "\n" .'' . __('Uncheck All') . '' . "\n" .'' . __('With selected:') . '' . "\n"; echo PMA_getButtonOrImage( 'submit_mult', 'mult_submit', 'submit_mult_export', __('Export'), 'b_tblexport.png', 'export' ); echo ''; echo '
' . '
' . '
'; printf($link_export_all, urlencode('%'), urlencode('%'), (isset($initial) ? $initial : '')); echo '
' . '
' . '
'; // add/delete user fieldset echo '
' . "\n" . ' ' . "\n" . PMA_getIcon('b_usradd.png') . ' ' . __('Add user') . '' . "\n" . '
' . "\n" . '
' . ' ' . "\n" . PMA_getIcon('b_usrdrop.png') . ' ' . __('Remove selected users') . '' . "\n" . ' ' . "\n" . ' ' . "\n" . '(' . __('Revoke all active privileges from the users and delete them afterwards.') . ')
' . "\n" . ' ' . "\n" . ' ' . "\n" . '
' . "\n" . ' ' . "\n" . '
' . "\n"; } else { unset ($row); echo '
' . "\n" . ' ' . "\n" . PMA_getIcon('b_usradd.png') . ' ' . __('Add user') . '' . "\n" . '
' . "\n"; } // end if (display overview) if ($GLOBALS['is_ajax_request']) { exit; } $flushnote = new PMA_Message(__('Note: phpMyAdmin gets the users\' privileges directly from MySQL\'s privilege tables. The content of these tables may differ from the privileges the server uses, if they have been changed manually. In this case, you should %sreload the privileges%s before you continue.'), PMA_Message::NOTICE); $flushnote->addParam('', false); $flushnote->addParam('', false); $flushnote->display(); } } else { // A user was selected -> display the user's properties // In an Ajax request, prevent cached values from showing if ($GLOBALS['is_ajax_request'] == true) { header('Cache-Control: no-cache'); } echo '

' . "\n" . PMA_getIcon('b_usredit.png') . __('Edit Privileges') . ': ' . __('User'); if (isset($dbname)) { echo ' \'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'' . "\n"; $url_dbname = urlencode(str_replace(array('\_', '\%'), array('_', '%'), $dbname)); echo ' - ' . ($dbname_is_wildcard ? __('Databases') : __('Database') ); if (isset($tablename)) { echo ' ' . htmlspecialchars($dbname) . ''; echo ' - ' . __('Table') . ' ' . htmlspecialchars($tablename) . ''; } else { echo ' ' . htmlspecialchars($dbname) . ''; } } else { echo ' \'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'' . "\n"; } echo '

' . "\n"; $sql = "SELECT '1' FROM `mysql`.`user`" . " WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'" . " AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "';"; $user_does_not_exists = (bool) ! PMA_DBI_fetch_value($sql); unset($sql); if ($user_does_not_exists) { PMA_Message::error(__('The selected user was not found in the privilege table.'))->display(); PMA_displayLoginInformationFields(); //require 'libraries/footer.inc.php'; } echo '
' . "\n"; $_params = array( 'username' => $username, 'hostname' => $hostname, ); if (isset($dbname)) { $_params['dbname'] = $dbname; if (isset($tablename)) { $_params['tablename'] = $tablename; } } echo PMA_generate_common_hidden_inputs($_params); PMA_displayPrivTable( PMA_ifSetOr($dbname, '*', 'length'), PMA_ifSetOr($tablename, '*', 'length') ); echo '
' . "\n"; if (! isset($tablename) && empty($dbname_is_wildcard)) { // no table name was given, display all table specific rights // but only if $dbname contains no wildcards // table header echo '
' . "\n" . PMA_generate_common_hidden_inputs('', '') . '' . "\n" . '' . "\n" . '
' . "\n" . '' . (! isset($dbname) ? __('Database-specific privileges') : __('Table-specific privileges')) . '' . "\n" . '' . "\n" . '' . "\n" . '' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . '' . "\n" . '' . "\n" . '' . "\n"; $user_host_condition = ' WHERE `User`' . ' = \'' . PMA_sqlAddSlashes($username) . "'" . ' AND `Host`' . ' = \'' . PMA_sqlAddSlashes($hostname) . "'"; // table body // get data // we also want privielgs for this user not in table `db` but in other table $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;'); if (! isset($dbname)) { // no db name given, so we want all privs for the given user $tables_to_search_for_users = array( 'tables_priv', 'columns_priv', ); $db_rights_sqls = array(); foreach ($tables_to_search_for_users as $table_search_in) { if (in_array($table_search_in, $tables)) { $db_rights_sqls[] = ' SELECT DISTINCT `Db` FROM `mysql`.' . PMA_backquote($table_search_in) . $user_host_condition; } } $user_defaults = array( 'Db' => '', 'Grant_priv' => 'N', 'privs' => array('USAGE'), 'Table_privs' => true, ); // for the rights $db_rights = array(); $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')' .' ORDER BY `Db` ASC'; $db_rights_result = PMA_DBI_query($db_rights_sql); while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) { $db_rights_row = array_merge($user_defaults, $db_rights_row); // only Db names in the table `mysql`.`db` uses wildcards // as we are in the db specific rights display we want // all db names escaped, also from other sources $db_rights_row['Db'] = PMA_escapeMysqlWildcards( $db_rights_row['Db'] ); $db_rights[$db_rights_row['Db']] = $db_rights_row; } PMA_DBI_free_result($db_rights_result); unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row); $sql_query = 'SELECT * FROM `mysql`.`db`' . $user_host_condition . ' ORDER BY `Db` ASC'; $res = PMA_DBI_query($sql_query); $sql_query = ''; while ($row = PMA_DBI_fetch_assoc($res)) { if (isset($db_rights[$row['Db']])) { $db_rights[$row['Db']] = array_merge($db_rights[$row['Db']], $row); } else { $db_rights[$row['Db']] = $row; } // there are db specific rights for this user // so we can drop this db rights $db_rights[$row['Db']]['can_delete'] = true; } PMA_DBI_free_result($res); unset($row, $res); } else { // db name was given, // so we want all user specific rights for this db $user_host_condition .= ' AND `Db`' .' LIKE \'' . PMA_sqlAddSlashes($dbname, true) . "'"; $tables_to_search_for_users = array( 'columns_priv', ); $db_rights_sqls = array(); foreach ($tables_to_search_for_users as $table_search_in) { if (in_array($table_search_in, $tables)) { $db_rights_sqls[] = ' SELECT DISTINCT `Table_name` FROM `mysql`.' . PMA_backquote($table_search_in) . $user_host_condition; } } $user_defaults = array( 'Table_name' => '', 'Grant_priv' => 'N', 'privs' => array('USAGE'), 'Column_priv' => true, ); // for the rights $db_rights = array(); $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')' .' ORDER BY `Table_name` ASC'; $db_rights_result = PMA_DBI_query($db_rights_sql); while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) { $db_rights_row = array_merge($user_defaults, $db_rights_row); $db_rights[$db_rights_row['Table_name']] = $db_rights_row; } PMA_DBI_free_result($db_rights_result); unset($db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row); $sql_query = 'SELECT `Table_name`,' .' `Table_priv`,' .' IF(`Column_priv` = _latin1 \'\', 0, 1)' .' AS \'Column_priv\'' .' FROM `mysql`.`tables_priv`' . $user_host_condition .' ORDER BY `Table_name` ASC;'; $res = PMA_DBI_query($sql_query); $sql_query = ''; while ($row = PMA_DBI_fetch_assoc($res)) { if (isset($db_rights[$row['Table_name']])) { $db_rights[$row['Table_name']] = array_merge($db_rights[$row['Table_name']], $row); } else { $db_rights[$row['Table_name']] = $row; } } PMA_DBI_free_result($res); unset($row, $res); } ksort($db_rights); // display rows if (count($db_rights) < 1) { echo '' . "\n" . ' ' . "\n" . '' . "\n"; } else { $odd_row = true; $found_rows = array(); //while ($row = PMA_DBI_fetch_assoc($res)) { foreach ($db_rights as $row) { $found_rows[] = (! isset($dbname)) ? $row['Db'] : $row['Table_name']; echo '' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . '' . "\n"; $odd_row = ! $odd_row; } // end while } unset($row); echo '' . "\n" . '
' . (! isset($dbname) ? __('Database') : __('Table')) . '' . __('Privileges') . '' . __('Grant') . '' . (! isset($dbname) ? __('Table-specific privileges') : __('Column-specific privileges')) . '' . __('Action') . '
' . __('None') . '
' . htmlspecialchars((! isset($dbname)) ? $row['Db'] : $row['Table_name']) . '' . "\n" . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($row, true)) . "\n" . ' ' . ((((! isset($dbname)) && $row['Grant_priv'] == 'Y') || (isset($dbname) && in_array('Grant', explode(',', $row['Table_priv'])))) ? __('Yes') : __('No')) . ''; if (! empty($row['Table_privs']) || ! empty ($row['Column_priv'])) { echo __('Yes'); } else { echo __('No'); } echo ''; printf( $link_edit, htmlspecialchars(urlencode($username)), urlencode(htmlspecialchars($hostname)), urlencode((! isset($dbname)) ? $row['Db'] : htmlspecialchars($dbname)), urlencode((! isset($dbname)) ? '' : $row['Table_name']) ); echo ''; if (! empty($row['can_delete']) || isset($row['Table_name']) && strlen($row['Table_name'])) { printf( $link_revoke, htmlspecialchars(urlencode($username)), urlencode(htmlspecialchars($hostname)), urlencode((! isset($dbname)) ? $row['Db'] : htmlspecialchars($dbname)), urlencode((! isset($dbname)) ? '' : $row['Table_name']) ); } echo '
' . "\n"; if (! isset($dbname)) { // no database name was given, display select db $pred_db_array =PMA_DBI_fetch_result('SHOW DATABASES;'); echo ' ' . "\n"; if (! empty($pred_db_array)) { echo ' ' . "\n"; } echo ' ' . "\n" . PMA_showHint(__('Wildcards % and _ should be escaped with a \ to use them literally')); } else { echo ' ' . "\n" . ' ' . "\n"; if ($res = @PMA_DBI_try_query('SHOW TABLES FROM ' . PMA_backquote(PMA_unescapeMysqlWildcards($dbname)) . ';', null, PMA_DBI_QUERY_STORE)) { $pred_tbl_array = array(); while ($row = PMA_DBI_fetch_row($res)) { if (! isset($found_rows) || ! in_array($row[0], $found_rows)) { $pred_tbl_array[] = $row[0]; } } PMA_DBI_free_result($res); unset($res, $row); if (! empty($pred_tbl_array)) { echo ' ' . "\n"; } } else { unset($res); } echo ' ' . "\n"; } echo '
' . "\n"; echo '
' . "\n" . ' ' . '
' . "\n" . '
' . "\n"; } // Provide a line with links to the relevant database and table if (isset($dbname) && empty($dbname_is_wildcard)) { echo '[ ' . __('Database') . ' ' . htmlspecialchars($dbname) . ': ' . PMA_getTitleForTarget($GLOBALS['cfg']['DefaultTabDatabase']) . " ]\n"; if (isset($tablename)) { echo ' [ ' . __('Table') . ' ' . htmlspecialchars($tablename) . ': ' . PMA_getTitleForTarget($GLOBALS['cfg']['DefaultTabTable']) . " ]\n"; } unset($url_dbname); } if (! isset($dbname) && ! $user_does_not_exists) { include_once 'libraries/display_change_password.lib.php'; echo '
' . "\n" . PMA_generate_common_hidden_inputs('', '') . '' . "\n" . '' . "\n" . '
' . "\n" . ' ' . __('Change Login Information / Copy User') . '' . "\n"; PMA_displayLoginInformationFields('change'); echo '
' . "\n" . ' ' . __('Create a new user with the same privileges and ...') . '' . "\n"; $choices = array( '4' => __('... keep the old one.'), '1' => __('... delete the old one from the user tables.'), '2' => __('... revoke all active privileges from the old one and delete it afterwards.'), '3' => __('... delete the old one from the user tables and reload the privileges afterwards.')); echo PMA_getRadioFields('mode', $choices, '4', true); unset($choices); echo '
' . "\n" . '
' . "\n" . '' . "\n" . '
' . "\n"; } } } elseif (isset($_REQUEST['adduser'])) { // Add user $GLOBALS['url_query'] .= '&adduser=1'; echo '

' . "\n" . PMA_getIcon('b_usradd.png') . __('Add user') . "\n" . '

' . "\n" . '
' . "\n" . PMA_generate_common_hidden_inputs('', ''); PMA_displayLoginInformationFields('new'); echo '
' . "\n" . '' . __('Database for user') . '' . "\n"; echo PMA_getCheckbox('createdb-1', __('Create database with same name and grant all privileges'), false, false); echo '
' . "\n"; echo PMA_getCheckbox('createdb-2', __('Grant all privileges on wildcard name (username\\_%)'), false, false); echo '
' . "\n"; if (! empty($dbname) ) { echo PMA_getCheckbox('createdb-3', sprintf(__('Grant all privileges on database "%s"'), htmlspecialchars($dbname)), true, false); echo '' . "\n"; echo '
' . "\n"; } echo '
' . "\n"; PMA_displayPrivTable('*', '*', false); echo ' ' . "\n" . '
' . "\n"; } else { // check the privileges for a particular database. $user_form = '
' . "\n" . '' . "\n" . PMA_getIcon('b_usrcheck.png') . ' ' . sprintf(__('Users having access to "%s"'), '' . htmlspecialchars($checkprivs) . '') . "\n" . '' . "\n" . '' . "\n" . '' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . '' . "\n" . '' . "\n"; $odd_row = true; unset($row, $row1, $row2); // now, we build the table... $list_of_privileges = '`User`, ' . '`Host`, ' . '`Select_priv`, ' . '`Insert_priv`, ' . '`Update_priv`, ' . '`Delete_priv`, ' . '`Create_priv`, ' . '`Drop_priv`, ' . '`Grant_priv`, ' . '`Index_priv`, ' . '`Alter_priv`, ' . '`References_priv`, ' . '`Create_tmp_table_priv`, ' . '`Lock_tables_priv`, ' . '`Create_view_priv`, ' . '`Show_view_priv`, ' . '`Create_routine_priv`, ' . '`Alter_routine_priv`, ' . '`Execute_priv`'; $list_of_compared_privileges = '`Select_priv` = \'N\'' . ' AND `Insert_priv` = \'N\'' . ' AND `Update_priv` = \'N\'' . ' AND `Delete_priv` = \'N\'' . ' AND `Create_priv` = \'N\'' . ' AND `Drop_priv` = \'N\'' . ' AND `Grant_priv` = \'N\'' . ' AND `References_priv` = \'N\'' . ' AND `Create_tmp_table_priv` = \'N\'' . ' AND `Lock_tables_priv` = \'N\'' . ' AND `Create_view_priv` = \'N\'' . ' AND `Show_view_priv` = \'N\'' . ' AND `Create_routine_priv` = \'N\'' . ' AND `Alter_routine_priv` = \'N\'' . ' AND `Execute_priv` = \'N\''; if (PMA_MYSQL_INT_VERSION >= 50106) { $list_of_privileges .= ', `Event_priv`, ' . '`Trigger_priv`'; $list_of_compared_privileges .= ' AND `Event_priv` = \'N\'' . ' AND `Trigger_priv` = \'N\''; } $sql_query = '(SELECT ' . $list_of_privileges . ', `Db`' .' FROM `mysql`.`db`' .' WHERE \'' . PMA_sqlAddSlashes($checkprivs) . "'" .' LIKE `Db`' .' AND NOT (' . $list_of_compared_privileges. ')) ' .'UNION ' .'(SELECT ' . $list_of_privileges . ', \'*\' AS `Db`' .' FROM `mysql`.`user` ' .' WHERE NOT (' . $list_of_compared_privileges . ')) ' .' ORDER BY `User` ASC,' .' `Host` ASC,' .' `Db` ASC;'; $res = PMA_DBI_query($sql_query); $row = PMA_DBI_fetch_assoc($res); if ($row) { $found = true; } if ($found) { while (true) { // prepare the current user $current_privileges = array(); $current_user = $row['User']; $current_host = $row['Host']; while ($row && $current_user == $row['User'] && $current_host == $row['Host']) { $current_privileges[] = $row; $row = PMA_DBI_fetch_assoc($res); } $user_form .= ' ' . "\n" . ' 1) { $user_form .= ' rowspan="' . count($current_privileges) . '"'; } $user_form .= '>' . (empty($current_user) ? '' . __('Any') . '' : htmlspecialchars($current_user)) . "\n" . ' ' . "\n" . ' 1) { $user_form .= ' rowspan="' . count($current_privileges) . '"'; } $user_form .= '>' . htmlspecialchars($current_host) . '' . "\n"; for ($i = 0; $i < count($current_privileges); $i++) { $current = $current_privileges[$i]; $user_form .= ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . "\n"; if (($i + 1) < count($current_privileges)) { $user_form .= '' . "\n"; } } if (empty($row) && empty($row1) && empty($row2)) { break; } $odd_row = ! $odd_row; } } else { $user_form .= ' ' . "\n" . ' ' . "\n" . ' ' . "\n"; } $user_form .= '' . "\n" . '
' . __('User') . '' . __('Host') . '' . __('Type') . '' . __('Privileges') . '' . __('Grant') . '' . __('Action') . '
' . "\n" . ' '; if (! isset($current['Db']) || $current['Db'] == '*') { $user_form .= __('global'); } elseif ($current['Db'] == PMA_escapeMysqlWildcards($checkprivs)) { $user_form .= __('database-specific'); } else { $user_form .= __('wildcard'). ': ' . htmlspecialchars($current['Db']) . ''; } $user_form .= "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($current, true)) . "\n" . ' ' . "\n" . ' ' . "\n" . ' ' . ($current['Grant_priv'] == 'Y' ? __('Yes') : __('No')) . "\n" . ' ' . "\n"; $user_form .= sprintf( $link_edit, urlencode($current_user), urlencode($current_host), urlencode(! isset($current['Db']) || $current['Db'] == '*' ? '' : $current['Db']), '' ); $user_form .= '
' . "\n" . ' ' . __('No user found.') . "\n" . '
' . "\n"; if ($GLOBALS['is_ajax_request'] == true) { $extra_data['user_form'] = $user_form; $message = PMA_Message::success(__('User has been added.')); PMA_ajaxResponse($message, $message->isSuccess(), $extra_data); } else { // Offer to create a new user for the current database $user_form .= '
' . "\n" . '' . __('New') . '' . "\n" . ' ' . "\n" . PMA_getIcon('b_usradd.png') . ' ' . __('Add user') . '' . "\n" . '
' . "\n"; echo $user_form ; } } // end if (empty($_REQUEST['adduser']) && empty($checkprivs)) ... elseif ... else ... /** * Displays the footer */ echo "\n\n"; require 'libraries/footer.inc.php'; ?>