Translated using Weblate (Thai)
[phpmyadmin.git] / server_privileges.php
blob7a94b94ec662011a0478b4f774392f03f3e13177
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
5 * @package PhpMyAdmin
6 */
8 /**
11 require_once 'libraries/common.inc.php';
13 /**
14 * functions implementation for this script
16 require_once 'libraries/display_change_password.lib.php';
17 require_once 'libraries/server_privileges.lib.php';
19 /**
20 * Does the common work
22 $response = PMA_Response::getInstance();
23 $header = $response->getHeader();
24 $scripts = $header->getScripts();
25 $scripts->addFile('server_privileges.js');
27 $_add_user_error = false;
29 if (isset ($_REQUEST['username'])) {
30 $username = $_REQUEST['username'];
32 if (isset ($_REQUEST['hostname'])) {
33 $hostname = $_REQUEST['hostname'];
36 /**
37 * Sets globals from $_POST patterns, for privileges and max_* vars
40 $post_patterns = array(
41 '/_priv$/i',
42 '/^max_/i'
44 foreach (array_keys($_POST) as $post_key) {
45 foreach ($post_patterns as $one_post_pattern) {
46 if (preg_match($one_post_pattern, $post_key)) {
47 $GLOBALS[$post_key] = $_POST[$post_key];
52 require 'libraries/server_common.inc.php';
54 $conditional_class = 'ajax';
56 /**
57 * Messages are built using the message name
59 $strPrivDescAllPrivileges = __('Includes all privileges except GRANT.');
60 $strPrivDescAlter = __('Allows altering the structure of existing tables.');
61 $strPrivDescAlterRoutine = __('Allows altering and dropping stored routines.');
62 $strPrivDescCreateDb = __('Allows creating new databases and tables.');
63 $strPrivDescCreateRoutine = __('Allows creating stored routines.');
64 $strPrivDescCreateTbl = __('Allows creating new tables.');
65 $strPrivDescCreateTmpTable = __('Allows creating temporary tables.');
66 $strPrivDescCreateUser = __('Allows creating, dropping and renaming user accounts.');
67 $strPrivDescCreateView = __('Allows creating new views.');
68 $strPrivDescDelete = __('Allows deleting data.');
69 $strPrivDescDropDb = __('Allows dropping databases and tables.');
70 $strPrivDescDropTbl = __('Allows dropping tables.');
71 $strPrivDescEvent = __('Allows to set up events for the event scheduler');
72 $strPrivDescExecute = __('Allows executing stored routines.');
73 $strPrivDescFile = __('Allows importing data from and exporting data into files.');
74 $strPrivDescGrant = __('Allows adding users and privileges without reloading the privilege tables.');
75 $strPrivDescIndex = __('Allows creating and dropping indexes.');
76 $strPrivDescInsert = __('Allows inserting and replacing data.');
77 $strPrivDescLockTables = __('Allows locking tables for the current thread.');
78 $strPrivDescMaxConnections = __('Limits the number of new connections the user may open per hour.');
79 $strPrivDescMaxQuestions = __('Limits the number of queries the user may send to the server per hour.');
80 $strPrivDescMaxUpdates = __('Limits the number of commands that change any table or database the user may execute per hour.');
81 $strPrivDescMaxUserConnections = __('Limits the number of simultaneous connections the user may have.');
82 $strPrivDescProcess = __('Allows viewing processes of all users');
83 $strPrivDescReferences = __('Has no effect in this MySQL version.');
84 $strPrivDescReload = __('Allows reloading server settings and flushing the server\'s caches.');
85 $strPrivDescReplClient = __('Allows the user to ask where the slaves / masters are.');
86 $strPrivDescReplSlave = __('Needed for the replication slaves.');
87 $strPrivDescSelect = __('Allows reading data.');
88 $strPrivDescShowDb = __('Gives access to the complete list of databases.');
89 $strPrivDescShowView = __('Allows performing SHOW CREATE VIEW queries.');
90 $strPrivDescShutdown = __('Allows shutting down the server.');
91 $strPrivDescSuper = __('Allows connecting, even if maximum number of connections is reached; required for most administrative operations like setting global variables or killing threads of other users.');
92 $strPrivDescTrigger = __('Allows creating and dropping triggers');
93 $strPrivDescUpdate = __('Allows changing data.');
94 $strPrivDescUsage = __('No privileges.');
96 /**
97 * Checks if a dropdown box has been used for selecting a database / table
99 if (PMA_isValid($_REQUEST['pred_tablename'])) {
100 $tablename = $_REQUEST['pred_tablename'];
101 } elseif (PMA_isValid($_REQUEST['tablename'])) {
102 $tablename = $_REQUEST['tablename'];
103 } else {
104 unset($tablename);
107 if (PMA_isValid($_REQUEST['pred_dbname'])) {
108 $dbname = $_REQUEST['pred_dbname'];
109 unset($pred_dbname);
110 } elseif (PMA_isValid($_REQUEST['dbname'])) {
111 $dbname = $_REQUEST['dbname'];
112 } else {
113 unset($dbname);
114 unset($tablename);
117 if (isset($dbname)) {
118 $unescaped_db = PMA_Util::unescapeMysqlWildcards($dbname);
119 $db_and_table = PMA_Util::backquote($unescaped_db) . '.';
120 if (isset($tablename)) {
121 $db_and_table .= PMA_Util::backquote($tablename);
122 } else {
123 $db_and_table .= '*';
125 } else {
126 $db_and_table = '*.*';
129 // check if given $dbname is a wildcard or not
130 if (isset($dbname)) {
131 //if (preg_match('/\\\\(?:_|%)/i', $dbname)) {
132 if (preg_match('/(?<!\\\\)(?:_|%)/i', $dbname)) {
133 $dbname_is_wildcard = true;
134 } else {
135 $dbname_is_wildcard = false;
140 * Checks if the user is allowed to do what he tries to...
142 if (! $is_superuser) {
143 $response->addHTML(
144 '<h2>' . "\n"
145 . PMA_Util::getIcon('b_usrlist.png')
146 . __('Privileges') . "\n"
147 . '</h2>' . "\n"
149 $response->addHTML(PMA_Message::error(__('No Privileges'))->getDisplay());
150 exit;
154 * Changes / copies a user, part I
156 if (isset($_REQUEST['change_copy'])) {
157 $user_host_condition = ' WHERE `User` = '
158 . "'". PMA_Util::sqlAddSlashes($_REQUEST['old_username']) . "'"
159 . ' AND `Host` = '
160 . "'" . PMA_Util::sqlAddSlashes($_REQUEST['old_hostname']) . "';";
161 $row = PMA_DBI_fetch_single_row(
162 'SELECT * FROM `mysql`.`user` ' . $user_host_condition
164 if (! $row) {
165 PMA_Message::notice(__('No user found.'))->display();
166 unset($_REQUEST['change_copy']);
167 } else {
168 extract($row, EXTR_OVERWRITE);
169 // Recent MySQL versions have the field "Password" in mysql.user,
170 // so the previous extract creates $Password but this script
171 // uses $password
172 if (! isset($password) && isset($Password)) {
173 $password = $Password;
175 $queries = array();
180 * Adds a user
181 * (Changes / copies a user, part II)
183 if (isset($_REQUEST['adduser_submit']) || isset($_REQUEST['change_copy'])) {
184 $sql_query = '';
185 if ($_POST['pred_username'] == 'any') {
186 $username = '';
188 switch ($_POST['pred_hostname']) {
189 case 'any':
190 $hostname = '%';
191 break;
192 case 'localhost':
193 $hostname = 'localhost';
194 break;
195 case 'hosttable':
196 $hostname = '';
197 break;
198 case 'thishost':
199 $_user_name = PMA_DBI_fetch_value('SELECT USER()');
200 $hostname = substr($_user_name, (strrpos($_user_name, '@') + 1));
201 unset($_user_name);
202 break;
204 $sql = "SELECT '1' FROM `mysql`.`user`"
205 . " WHERE `User` = '" . PMA_Util::sqlAddSlashes($username) . "'"
206 . " AND `Host` = '" . PMA_Util::sqlAddSlashes($hostname) . "';";
207 if (PMA_DBI_fetch_value($sql) == 1) {
208 $message = PMA_Message::error(__('The user %s already exists!'));
209 $message->addParam('[em]\'' . $username . '\'@\'' . $hostname . '\'[/em]');
210 $_REQUEST['adduser'] = true;
211 $_add_user_error = true;
212 } else {
213 list($create_user_real, $create_user_show, $real_sql_query, $sql_query)
214 = PMA_getSqlQueriesForDisplayAndAddUser(
215 $username, $hostname, (isset ($password) ? $password : '')
218 if (empty($_REQUEST['change_copy'])) {
219 $_error = false;
221 if (isset($create_user_real)) {
222 if (! PMA_DBI_try_query($create_user_real)) {
223 $_error = true;
225 $sql_query = $create_user_show . $sql_query;
227 list($sql_query, $message) = PMA_addUserAndCreateDatabase(
228 $_error, $real_sql_query, $sql_query, $username, $hostname,
229 isset($dbname) ? $dbname : null
232 } else {
233 if (isset($create_user_real)) {
234 $queries[] = $create_user_real;
236 $queries[] = $real_sql_query;
237 // we put the query containing the hidden password in
238 // $queries_for_display, at the same position occupied
239 // by the real query in $queries
240 $tmp_count = count($queries);
241 if (isset($create_user_real)) {
242 $queries_for_display[$tmp_count - 2] = $create_user_show;
244 $queries_for_display[$tmp_count - 1] = $sql_query;
246 unset($res, $real_sql_query);
251 * Changes / copies a user, part III
253 if (isset($_REQUEST['change_copy'])) {
254 $queries = PMA_getDbSpecificPrivsQueriesForChangeOrCopyUser(
255 $queries, $username, $hostname
260 * Updates privileges
262 if (! empty($_POST['update_privs'])) {
263 list($sql_query, $message) = PMA_updatePrivileges(
264 $username,
265 $hostname,
266 (isset($tablename) ? $tablename : ''),
267 (isset($dbname) ? $dbname : '')
272 * Revokes Privileges
274 if (isset($_REQUEST['revokeall'])) {
275 list ($message, $sql_query) = PMA_getMessageAndSqlQueryForPrivilegesRevoke(
276 $db_and_table,
277 (isset($dbname) ? $dbname : ''),
278 (isset($tablename) ? $tablename : ''),
279 $username, $hostname
284 * Updates the password
286 if (isset($_REQUEST['change_pw'])) {
287 $message = PMA_getMessageForUpdatePassword(
288 $err_url, $username, $hostname
293 * Deletes users
294 * (Changes / copies a user, part IV)
296 if (isset($_REQUEST['delete'])
297 || (isset($_REQUEST['change_copy']) && $_REQUEST['mode'] < 4)
299 if (isset($_REQUEST['change_copy'])) {
300 $selected_usr = array(
301 $_REQUEST['old_username'] . '&amp;#27;' . $_REQUEST['old_hostname']
303 } else {
304 $selected_usr = $_REQUEST['selected_usr'];
305 $queries = array();
307 foreach ($selected_usr as $each_user) {
308 list($this_user, $this_host) = explode('&amp;#27;', $each_user);
309 $queries[] = '# '
310 . sprintf(
311 __('Deleting %s'),
312 '\'' . $this_user . '\'@\'' . $this_host . '\''
314 . ' ...';
315 $queries[] = 'DROP USER \''
316 . PMA_Util::sqlAddSlashes($this_user)
317 . '\'@\'' . PMA_Util::sqlAddSlashes($this_host) . '\';';
319 if (isset($_REQUEST['drop_users_db'])) {
320 $queries[] = 'DROP DATABASE IF EXISTS '
321 . PMA_Util::backquote($this_user) . ';';
322 $GLOBALS['reload'] = true;
325 if (empty($_REQUEST['change_copy'])) {
326 list($sql_query, $message) = PMA_deleteUser($queries);
331 * Changes / copies a user, part V
333 if (isset($_REQUEST['change_copy'])) {
334 $tmp_count = 0;
335 foreach ($queries as $sql_query) {
336 if ($sql_query{0} != '#') {
337 PMA_DBI_query($sql_query);
339 // when there is a query containing a hidden password, take it
340 // instead of the real query sent
341 if (isset($queries_for_display[$tmp_count])) {
342 $queries[$tmp_count] = $queries_for_display[$tmp_count];
344 $tmp_count++;
346 $message = PMA_Message::success();
347 $sql_query = join("\n", $queries);
351 * Reloads the privilege tables into memory
353 if (isset($_REQUEST['flush_privileges'])) {
354 $sql_query = 'FLUSH PRIVILEGES;';
355 PMA_DBI_query($sql_query);
356 $message = PMA_Message::success(__('The privileges were reloaded successfully.'));
360 * some standard links
362 list($link_edit, $link_revoke, $link_export)
363 = PMA_getStandardLinks($conditional_class);
366 * If we are in an Ajax request for Create User/Edit User/Revoke User/
367 * Flush Privileges, show $message and exit.
369 if ($GLOBALS['is_ajax_request']
370 && empty($_REQUEST['ajax_page_request'])
371 && ! isset($_REQUEST['export'])
372 && (! isset($_REQUEST['submit_mult']) || $_REQUEST['submit_mult'] != 'export')
373 && (! isset($_REQUEST['adduser']) || $_add_user_error)
374 && (! isset($_REQUEST['initial']) || empty($_REQUEST['initial']))
375 && ! isset($_REQUEST['showall'])
376 && ! isset($_REQUEST['edit_user_dialog'])
377 && ! isset($_REQUEST['db_specific'])
379 $extra_data = PMA_getExtraDataForAjaxBehavior(
380 (isset($password) ? $password : ''),
381 $link_export,
382 (isset($sql_query) ? $sql_query : ''),
383 $link_edit,
384 (isset($hostname) ? $hostname : ''),
385 (isset($username) ? $username : '')
388 if (! empty($message) && $message instanceof PMA_Message) {
389 $response = PMA_Response::getInstance();
390 $response->isSuccess($message->isSuccess());
391 $response->addJSON('message', $message);
392 $response->addJSON($extra_data);
393 exit;
398 * Displays the links
400 if (isset($_REQUEST['viewing_mode']) && $_REQUEST['viewing_mode'] == 'db') {
401 $_REQUEST['db'] = $_REQUEST['checkprivs'];
403 $url_query .= '&amp;goto=db_operations.php';
405 // Gets the database structure
406 $sub_part = '_structure';
407 ob_start();
408 include 'libraries/db_info.inc.php';
409 $content = ob_get_contents();
410 ob_end_clean();
411 $response->addHTML($content . "\n");
412 } else {
413 if (! empty($GLOBALS['message'])) {
414 $response->addHTML(PMA_Util::getMessage($GLOBALS['message']));
415 unset($GLOBALS['message']);
420 * Displays the page
423 // export user definition
424 if (isset($_REQUEST['export'])
425 || (isset($_REQUEST['submit_mult']) && $_REQUEST['submit_mult'] == 'export')
427 list($title, $export) = PMA_getHtmlForExportUserDefinition(
428 isset($username) ? $username : null,
429 isset($hostname) ? $hostname : null
432 unset($username, $hostname, $grants, $one_grant);
434 $response = PMA_Response::getInstance();
435 if ($GLOBALS['is_ajax_request']) {
436 $response->addJSON('message', $export);
437 $response->addJSON('title', $title);
438 exit;
439 } else {
440 $response->addHTML("<h2>$title</h2>$export");
444 if (empty($_REQUEST['adduser'])
445 && (! isset($_REQUEST['checkprivs'])
446 || ! strlen($_REQUEST['checkprivs']))
448 if (! isset($username)) {
449 // No username is given --> display the overview
450 $response->addHTML(
451 PMA_getHtmlForDisplayUserOverviewPage(
452 $link_edit, $pmaThemeImage, $text_dir,
453 $conditional_class, $link_export
456 } else {
457 // A user was selected -> display the user's properties
459 // In an Ajax request, prevent cached values from showing
460 if ($GLOBALS['is_ajax_request'] == true) {
461 header('Cache-Control: no-cache');
463 $url_dbname = urlencode(
464 str_replace(
465 array('\_', '\%'),
466 array('_', '%'), $_REQUEST['dbname']
469 $response->addHTML(
470 PMA_getHtmlForDisplayUserProperties(
471 ((isset ($dbname_is_wildcard)) ? $dbname_is_wildcard : ''),
472 $url_dbname, $username, $hostname, $link_edit, $link_revoke,
473 (isset($unescaped_db) ? $unescaped_db : ''),
474 (isset($tablename) ? $tablename : '')
478 } elseif (isset($_REQUEST['adduser'])) {
479 // Add user
480 $response->addHTML(
481 PMA_getHtmlForAddUser((isset($dbname) ? $dbname : ''))
483 } else {
484 // check the privileges for a particular database.
485 $response->addHTML(
486 PMA_getHtmlForSpecificDbPrivileges($link_edit, $conditional_class)
488 } // end if (empty($_REQUEST['adduser']) && empty($checkprivs))... elseif... else...