update
[phpmyadmin/crack.git] / server_privileges.php3
blob27cbb33c3d1452fc43c885a220f0b7731e8e7987
1 <?php
2 /* $Id$ */
3 // vim: expandtab sw=4 ts=4 sts=4:
6 /**
7 * Gets some core libraries
8 */
9 if (!defined('PMA_GRAB_GLOBALS_INCLUDED')) {
10 include('./libraries/grab_globals.lib.php3');
12 if (!defined('PMA_COMMON_LIB_INCLUDED')) {
13 include('./libraries/common.lib.php3');
16 /**
17 * Extracts the privilege information of a priv table row
19 * @param array the row
20 * @param boolean add <dfn> tag with tooltips
22 * @return array
24 function PMA_extractPrivInfo($row = '', $enableHTML = FALSE)
26 $grants = array(
27 array('Select_priv', 'SELECT', $GLOBALS['strPrivDescSelect']),
28 array('Insert_priv', 'INSERT', $GLOBALS['strPrivDescInsert']),
29 array('Update_priv', 'UPDATE', $GLOBALS['strPrivDescUpdate']),
30 array('Delete_priv', 'DELETE', $GLOBALS['strPrivDescDelete']),
31 array('Create_priv', 'CREATE', $GLOBALS['strPrivDescCreate' . (isset($GOLBALS['tablename']) ? 'Tbl' : 'Db')]),
32 array('Drop_priv', 'DROP', $GLOBALS['strPrivDescDrop' . (isset($GOLBALS['tablename']) ? 'Tbl' : 'Db')]),
33 array('Reload_priv', 'RELOAD', $GLOBALS['strPrivDescReload']),
34 array('Shutdown_priv', 'SHUTDOWN', $GLOBALS['strPrivDescShutdown']),
35 array('Process_priv', 'PROCESS', $GLOBALS['strPrivDescProcess' . ((!empty($row) && isset($row['Super_priv'])) || (empty($row) && isset($GLOBALS['Super_priv'])) ? '4' : '3')]),
36 array('File_priv', 'FILE', $GLOBALS['strPrivDescFile']),
37 array('References_priv', 'REFERENCES', $GLOBALS['strPrivDescReferences']),
38 array('Index_priv', 'INDEX', $GLOBALS['strPrivDescIndex']),
39 array('Alter_priv', 'ALTER', $GLOBALS['strPrivDescAlter']),
40 array('Show_db_priv', 'SHOW DATABASES', $GLOBALS['strPrivDescShowDb']),
41 array('Super_priv', 'SUPER', $GLOBALS['strPrivDescSuper']),
42 array('Create_tmp_table_priv', 'CREATE TEMPORARY TABLES', $GLOBALS['strPrivDescCreateTmpTable']),
43 array('Lock_tables_priv', 'LOCK TABLES', $GLOBALS['strPrivDescLockTables']),
44 array('Execute_priv', 'EXECUTE', $GLOBALS['strPrivDescExecute']),
45 array('Repl_slave_priv', 'REPLICATION SLAVE', $GLOBALS['strPrivDescReplSlave']),
46 array('Repl_client_priv', 'REPLICATION CLIENT', $GLOBALS['strPrivDescReplClient'])
48 $privs = array();
49 $allPrivileges = TRUE;
50 while (list(, $current_grant) = each($grants)) {
51 if ((!empty($row) && isset($row[$current_grant[0]])) || (empty($row) && isset($GLOBALS[$current_grant[0]]))) {
52 if ((!empty($row) && $row[$current_grant[0]] == 'Y') || (empty($row) && $GLOBALS[$current_grant[0]] == 'Y')) {
53 if ($enableHTML) {
54 $privs[] = '<dfn title="' . $current_grant[2] . '">' . str_replace(' ', '&nbsp;', $current_grant[1]) . '</dfn>';
55 } else {
56 $privs[] = $current_grant[1];
58 } else {
59 $allPrivileges = FALSE;
63 if (empty($privs)) {
64 if ($enableHTML) {
65 $privs[] = '<dfn title="' . $GLOBALS['strPrivDescUsage'] . '">USAGE</dfn>';
66 } else {
67 $privs[] = 'USAGE';
69 } else if ($allPrivileges && (!isset($GLOBALS['grant_count']) || count($privs) == $GLOBALS['grant_count'])) {
70 if ($enableHTML) {
71 $privs = array('<dfn title="' . $GLOBALS['strPrivDescAllPrivileges'] . '">ALL&nbsp;PRIVILEGES</dfn>');
72 } else {
73 $privs = array('ALL PRIVILEGES');
76 return $privs;
79 /**
80 * Updates privileges
82 if (!empty($update_privs)) {
83 if (empty($hostname)) {
84 $hostname = '%';
86 if (PMA_MYSQL_INT_VERSION >= 32211) {
87 $sql_query0 = 'REVOKE ALL PRIVILEGES ON *.* FROM "' . $username . '"@"' . $hostname . '";';
88 $sql_query1 = 'REVOKE GRANT OPTION ON *.* FROM "' . $username . '"@"' . $hostname . '";';
89 $sql_query2 = 'GRANT ' . join(', ', PMA_extractPrivInfo()) . ' ON *.* TO "' . $username . '"@"' . $hostname . '"';
90 if (isset($Grant_priv) || isset($max_questions) || isset($max_connections) || isset($max_updates)) {
91 $sql_query2 .= 'WITH';
92 if (isset($Grant_priv) && $Grant_priv == 'Y') {
93 $sql_query2 .= ' GRANT OPTION';
95 if (isset($max_questions)) {
96 $sql_query2 .= ' MAX_QUERIES_PER_HOUR ' . (int)$max_questions;
98 if (isset($max_connections)) {
99 $sql_query2 .= ' MAX_CONNECTIONS_PER_HOUR ' . (int)$max_connections;
101 if (isset($max_updates)) {
102 $sql_query2 .= ' MAX_UPDATES_PER_HOUR ' . (int)$max_updates;
105 $sql_query2 .= ';';
106 if (!@PMA_mysql_query($sql_query0, $userlink)) {
107 PMA_mysqlDie(PMA_mysql_error($userlink), $sql_query0);
109 if (!@PMA_mysql_query($sql_query1, $userlink)) {
110 PMA_mysqlDie(PMA_mysql_error($userlink), $sql_query1);
112 if (!@PMA_mysql_query($sql_query2, $userlink)) {
113 PMA_mysqlDie(PMA_mysql_error($userlink), $sql_query2);
115 $sql_query = $sql_query0 . ' ' . $sql_query1 . ' ' . $sql_query2;
116 $message = sprintf($strUpdatePrivMessage, '\'' . $username . '\'@\'' . $hostname . '\'');
117 } else {
118 $sql_query = 'SHOW COLUMNS FROM `user`;';
119 $res = PMA_mysql_query($sql_query, $userlink) or PMA_mysqlDie(PMA_mysql_error($userlink));
120 $grants = array();
121 while ($row = PMA_mysql_fetch_row($res)) {
122 if (substr($row[0], -5) == '_priv') {
123 $grants[] = PMA_backquote($row[0]) . ' = "' . (empty($$row[0]) ? 'N' : 'Y') . '"';
126 mysql_free_result($res);
127 unset($res);
128 unset($row);
129 $sql_query = 'UPDATE `user` SET ' . join(', ', $grants) . ' WHERE `User` = "' . $username . '" AND `Host` = "' . $hostname . '";';
130 PMA_mysql_query($sql_query, $userlink) or PMA_mysqlDie(PMA_mysql_error($userlink));
131 $message = sprintf($strUpdatePrivMessage, '\'' . $username . '\'@\'' . $hostname . '\'') . '<br />' . "\n" . $strRememberReload;
136 * Updates the password
138 if (!empty($change_pw)) {
139 if (empty($hostname)) {
140 $hostname = '%';
142 if ($nopass == 1) {
143 $sql_query = 'SET PASSWORD FOR "' . $username . '"@"' . $hostname . '" = ""';
144 PMA_mysql_query($sql_query, $userlink) or PMA_mysqlDie(PMA_mysql_error($userlink));
145 $message = sprintf($strPasswordChanged, '\'' . $username . '\'@\'' . $hostname . '\'');
146 } else if (empty($pma_pw) || empty($pma_pw2)) {
147 $message = $strPasswordEmpty;
148 } else if ($pma_pw != $pma_pw2) {
149 $message = $strPasswordNotSame;
150 } else {
151 $hidden_pw = '';
152 for ($i = 0; $i < strlen($pma_pw); $i++) {
153 $hidden_pw .= '*';
155 $local_query = 'SET PASSWORD FOR "' . $username . '"@"' . $hostname . '" = PASSWORD("' . $pma_pw . '")';
156 $sql_query = 'SET PASSWORD FOR "' . $username . '"@"' . $hostname . '" = PASSWORD("' . $hidden_pw . '")';
157 PMA_mysql_query($local_query, $userlink) or PMA_mysqlDie(PMA_mysql_error($userlink));
158 $message = sprintf($strPasswordChanged, '\'' . $username . '\'@\'' . $hostname . '\'');
163 * Deletes users
165 if (!empty($delete)) {
166 PMA_mysql_query('USE `mysql`;', $userlink) or PMA_mysqlDie(PMA_mysql_error($userlink), 'USE `mysql`;');
167 $is_superuser = TRUE;
168 $queries = array();
169 for ($i = 0; isset($selected_usr[$i]); $i++) {
170 list($this_user, $this_host) = explode('@', $selected_usr[$i]);
171 $queries[] = '# ' . sprintf($strDeleting, '\'' . $this_user . '\'@\'' . $this_host . '\'') . ' ...';
172 if ($mode == 2) {
173 // The SHOW GRANTS query may fail if the user has not been loaded
174 // into memory
175 $res = PMA_mysql_query('SHOW GRANTS FOR "' . $this_user . '"@"' . $this_host . '";', $userlink);
176 if ($res) {
177 $queries[] = 'REVOKE ALL PRIVILEGES ON *.* FROM "' . $this_user . '"@"' . $this_host . '";';
178 while ($row = PMA_mysql_fetch_row($res)) {
179 $this_table = substr($row[0], (strpos($row[0], 'ON') + 3), -(9 + strlen($this_user . $this_host)));
180 if ($this_table != '*.*') {
181 $queries[] = 'REVOKE ALL PRIVILEGES ON ' . $this_table . ' FROM "' . $this_user . '"@"' . $this_host . '";';
183 unset($this_table);
185 mysql_free_result($res);
187 unset($res);
189 $queries[] = 'DELETE FROM `user` WHERE `User` = "' . $this_user . '" AND `Host` = "' . $this_host . '";';
190 if ($mode != 2) {
191 // If we REVOKE the table grants, we should not need to modify the
192 // `db`, `tables_priv` and `columns_priv` tables manually...
193 $queries[] = 'DELETE FROM `db` WHERE `User` = "' . $this_user . '" AND `Host` = "' . $this_host . '";';
194 $queries[] = 'DELETE FROM `tables_priv` WHERE `User` = "' . $this_user . '" AND `Host` = "' . $this_host . '";';
195 $queries[] = 'DELETE FROM `columns_priv` WHERE `User` = "' . $this_user . '" AND `Host` = "' . $this_host . '";';
198 if ($mode == 3) {
199 $queries[] = '# ' . $strReloadingThePrivileges . ' ...' . "\n" . 'FLUSH PRIVILEGES;';
201 while (list(, $sql_query) = each($queries)) {
202 PMA_mysql_query($sql_query, $userlink) or PMA_mysqlDie(PMA_mysql_error($userlink));
204 $sql_query = join("\n", $queries);
205 unset($queries);
206 $message = $strUsersDeleted;
210 * Reloads the privilege tables into memory
212 if (!empty($flush_privileges)) {
213 $sql_query = 'FLUSH PRIVILEGES';
214 if (@PMA_mysql_query($sql_query, $userlink)) {
215 $message = $strPrivilegesReloaded;
216 } else {
217 PMA_mysqlDie(PMA_mysql_error($userlink));
222 * Does the common work
224 $js_to_run = 'user_details.js';
225 require('./server_common.inc.php3');
228 * Displays the links
230 require('./server_links.inc.php3');
233 * Checks if the user is allowed to do what he tries to...
235 if (!$is_superuser) {
236 echo '<h2>' . "\n"
237 . ' ' . $strPrivileges . "\n"
238 . '</h2>' . "\n"
239 . $strNoPrivileges . "\n";
240 include('./footer.inc.php3');
241 exit;
244 if (!isset($username) && !isset($hostname)) {
245 // No username is given --> display the overview
246 echo '<h2>' . "\n"
247 . ' ' . $strUserOverview . "\n"
248 . '</h2>' . "\n";
249 $oldPrivTables = FALSE;
250 if (PMA_MYSQL_INT_VERSION >= 40002) {
251 $res = PMA_mysql_query('SELECT `User`, `Host`, IF(`Password` = "", "N", "Y") AS "Password", `Select_priv`, `Insert_priv`, `Update_priv`, `Delete_priv`, `Create_priv`, `Drop_priv`, `Reload_priv`, `Shutdown_priv`, `Process_priv`, `File_priv`, `Grant_priv`, `References_priv`, `Index_priv`, `Alter_priv`, `Show_db_priv`, `Super_priv`, `Create_tmp_table_priv`, `Lock_tables_priv`, `Execute_priv`, `Repl_slave_priv`, `Repl_client_priv` FROM `user`;', $userlink);
252 if (!$res) {
253 // the query failed! This may have two reasons:
254 // - the user has not enough privileges
255 // - the privilege tables use a structure of an earlier version.
256 $oldPrivTables = TRUE;
259 if (empty($res) || (PMA_MYSQL_INT_VERSION >= 32211 && PMA_MYSQL_INT_VERSION < 40002)) {
260 $res = PMA_mysql_query('SELECT `User`, `Host`, IF(`Password` = "", "N", "Y") AS "Password", `Select_priv`, `Insert_priv`, `Update_priv`, `Delete_priv`, `Index_priv`, `Alter_priv`, `Create_priv`, `Drop_priv`, `Grant_priv`, `References_priv`, `Reload_priv`, `Shutdown_priv`, `Process_priv`, `File_priv` FROM `user`;', $userlink);
261 if (!$res) {
262 // the query failed! This may have two reasons:
263 // - the user has not enough privileges
264 // - the privilege tables use a structure of an earlier version.
265 $oldPrivTables = TRUE;
268 if (empty($res) || PMA_MYSQL_INT_VERSION < 32211) {
269 $res = PMA_mysql_query('SELECT * FROM `user`;', $userlink);
271 if (!$res) {
272 echo '<i>' . $strNoPrivileges . '</i>' . "\n";
273 @mysql_free_result($res);
274 unset($res);
275 } else {
276 if ($oldPrivTables) {
277 // rabus: This message is hardcoded because I will replace it by
278 // a automatic repair feature soon.
279 echo '<div class="warning">' . "\n"
280 . ' Warning: Your privilege table structure seem to be older than this MySQL version!<br />' . "\n"
281 . ' Please run the script <tt>mysql_fix_privilege_tables</tt> that should be included in your MySQL server distribution to solve this problem!' . "\n"
282 . '</div><br />' . "\n";
284 echo '<form name="usersForm" action="server_privileges.php3" method="post" />' . "\n"
285 . ' <input type="hidden" name="lang" value="' . $lang . '" />' . "\n"
286 . ' <input type="hidden" name="convcharset" value="' . $convcharset . '" />' . "\n"
287 . ' <input type="hidden" name="server" value="' . $server . '" />' . "\n"
288 . ' <table border="0">' . "\n"
289 . ' <tr>' . "\n"
290 . ' <th></th>' . "\n"
291 . ' <th>&nbsp;' . $strUser . '&nbsp;</th>' . "\n"
292 . ' <th>&nbsp;' . $strHost . '&nbsp;</th>' . "\n"
293 . ' <th>&nbsp;' . $strPassword . '&nbsp;</th>' . "\n"
294 . ' <th>&nbsp;' . $strGlobalPrivileges . '&nbsp;</th>' . "\n"
295 . ' <th>&nbsp;' . $strGrantOption . '&nbsp;</th>' . "\n"
296 . ' <th>&nbsp;' . $strAction . '&nbsp;</th>' . "\n";
297 echo ' </tr>' . "\n";
298 $useBgcolorOne = TRUE;
299 for ($i = 0; $row = PMA_mysql_fetch_array($res, MYSQL_ASSOC); $i++) {
300 echo ' <tr>' . "\n"
301 . ' <td bgcolor="' . ($useBgcolorOne ? $cfg['BgcolorOne'] : $cfg['BgcolorTwo']) . '"><input type="checkbox" name="selected_usr[]" id="checkbox_sel_users_' . $i . '" value="' . htmlspecialchars($row['User'] . '@' . $row['Host']) . '"' . (empty($checkall) ? '' : ' checked="checked"') . ' /></td>' . "\n"
302 . ' <td bgcolor="' . ($useBgcolorOne ? $cfg['BgcolorOne'] : $cfg['BgcolorTwo']) . '"><label for="checkbox_sel_users_' . $i . '">' . (empty($row['User']) ? '<span style="color: #FF0000">' . $strAny . '</span>' : htmlspecialchars($row['User'])) . '</label></td>' . "\n"
303 . ' <td bgcolor="' . ($useBgcolorOne ? $cfg['BgcolorOne'] : $cfg['BgcolorTwo']) . '">' . htmlspecialchars($row['Host']) . '</td>' . "\n";
304 $privs = PMA_extractPrivInfo($row, TRUE);
305 echo ' <td bgcolor="' . ($useBgcolorOne ? $cfg['BgcolorOne'] : $cfg['BgcolorTwo']) . '">' . ($row['Password'] == 'Y' ? $strYes : '<span style="color: #FF0000">' . $strNo . '</span>') . '</td>' . "\n"
306 . ' <td bgcolor="' . ($useBgcolorOne ? $cfg['BgcolorOne'] : $cfg['BgcolorTwo']) . '"><tt>' . "\n"
307 . ' ' . join(',' . "\n" . ' ', $privs) . "\n"
308 . ' </tt></td>' . "\n"
309 . ' <td bgcolor="' . ($useBgcolorOne ? $cfg['BgcolorOne'] : $cfg['BgcolorTwo']) . '">' . ($row['Grant_priv'] == 'Y' ? $strYes : $strNo) . '</td>' . "\n"
310 . ' <td bgcolor="' . ($useBgcolorOne ? $cfg['BgcolorOne'] : $cfg['BgcolorTwo']) . '"><a href="server_privileges.php3?' . $url_query . '&amp;username=' . urlencode($row['User']) . ($row['Host'] == '%' ? '' : '&amp;hostname=' . urlencode($row['Host'])) . '">' . $strEdit . '</a></td>' . "\n"
311 . ' </tr>' . "\n";
312 $useBgcolorOne = !$useBgcolorOne;
314 @mysql_free_result($res);
315 unset($res);
316 unset ($row);
317 echo ' <tr>' . "\n"
318 . ' <td></td>' . "\n"
319 . ' <td colspan="5">' . "\n"
320 . ' &nbsp;<i>' . $strEnglishPrivileges . '</i>&nbsp;' . "\n"
321 . ' </td>' . "\n"
322 . ' </tr>' . "\n"
323 . ' <tr>' . "\n"
324 . ' <td colspan="6" valign="bottom">' . "\n"
325 . ' <img src="./images/arrow_' . $text_dir . '.gif" border="0" width="38" height="22" alt="' . $strWithChecked . '" />' . "\n"
326 . ' <a href="./*server_privileges.php3?' . $url_query . '&amp;checkall=1" onclick="setCheckboxes(\'usersForm\', true); return false;">' . $strCheckAll . '</a>' . "\n"
327 . ' &nbsp;/&nbsp;' . "\n"
328 . ' <a href="server_privileges.php3' . $url_query . '" onclick="setCheckboxes(\'usersForm\', false); return false;">' . $strUncheckAll . '</a>' . "\n"
329 . ' </td>' . "\n"
330 . ' </tr>' . "\n"
331 . ' </table>' . "\n"
332 . ' <ul>' . "\n"
333 . ' <li>' . "\n"
334 . ' <b>' . $strRemoveSelectedUsers . '</b><br>' . "\n"
335 . ' <input type="radio" title="' . $strJustDelete . ' ' . $strJustDeleteDescr . '" name="mode" id="radio_mode_1" value="1" checked="checked" />' . "\n"
336 . ' <label for="radio_mode_1" title="' . $strJustDelete . ' ' . $strJustDeleteDescr . '">' . "\n"
337 . ' ' . $strJustDelete . "\n"
338 . ' </label><br />' . "\n";
339 if (PMA_MYSQL_INT_VERSION >= 32304) {
340 echo ' <input type="radio" title="' . $strRevokeAndDelete . ' ' . $strRevokeAndDeleteDescr . '" name="mode" id="radio_mode_2" value="2" />' . "\n"
341 . ' <label for="radio_mode_2" title="' . $strRevokeAndDelete . ' ' . $strRevokeAndDeleteDescr . '">' . "\n"
342 . ' ' . $strRevokeAndDelete . "\n"
343 . ' </label><br />' . "\n";
345 echo ' <input type="radio" title="' . $strDeleteAndFlush . ' ' . $strDeleteAndFlushDescr . '" name="mode" id="radio_mode_3" value="3" />' . "\n"
346 . ' <label for="radio_mode_3" title="' . $strDeleteAndFlush . ' ' . $strDeleteAndFlushDescr . '">' . "\n"
347 . ' ' . $strDeleteAndFlush . "\n"
348 . ' </label><br />' . "\n"
349 . ' <input type="submit" name="delete" value="' . $strGo . '" />' . "\n"
350 . ' </li>' . "\n"
351 . ' </ul>' . "\n"
352 . '</form>' . "\n"
353 . '<div>' . "\n"
354 . ' ' . sprintf($strFlushPrivilegesNote, '<a href="server_privileges.php3?' . $url_query . '&amp;flush_privileges=1">', '</a>');
356 } else if (isset($username)) {
357 if (!isset($hostname)) {
358 $hostname = '%';
360 echo '<h2>' . "\n"
361 . ' ' . $strUser . ' <i>\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'</i>' . "\n"
362 . '</h2>' . "\n"
363 . '<ul>' . "\n"
364 . ' <li>' . "\n";
365 $res = PMA_mysql_query('SELECT * FROM `user` WHERE `User` = "' . $username . '" AND `Host` = "' . $hostname . '"', $userlink);
366 $row = PMA_mysql_fetch_array($res, MYSQL_ASSOC);
367 @mysql_free_result($res);
368 unset($res);
369 $privTable[0] = array(
370 array('Select', 'SELECT', $strPrivDescSelect),
371 array('Insert', 'INSERT', $strPrivDescInsert),
372 array('Update', 'UPDATE', $strPrivDescUpdate),
373 array('Delete', 'DELETE', $strPrivDescDelete),
374 array('File', 'FILE', $strPrivDescFile)
376 $privTable[1] = array(
377 array('Create', 'CREATE', $strPrivDescCreateDb),
378 array('Alter', 'ALTER', $strPrivDescAlter),
379 array('Index', 'INDEX', $strPrivDescIndex),
380 array('Drop', 'DROP', $strPrivDescDropDb)
382 if (isset($row['Create_tmp_table_priv'])) {
383 $privTable[1][] = array('Create_tmp_table', 'CREATE&nbsp;TEMPORARAY&nbsp;TABLES', $strPrivDescCreateTmpTable);
385 $privTable[2] = array();
386 if (isset($row['Grant_priv'])) {
387 $privTable[2][] = array('Grant', 'GRANT', $strPrivDescGrant);
389 if (isset($row['Super_priv'])) {
390 $privTable[2][] = array('Super', 'SUPER', $strPrivDescSuper);
391 $privTable[2][] = array('Process', 'PROCESS', $strPrivDescProcess4);
392 } else {
393 $privTable[2][] = array('Process', 'PROCESS', $strPrivDescProcess3);
395 $privTable[2][] = array('Reload', 'RELOAD', $strPrivDescReload);
396 $privTable[2][] = array('Shutdown', 'SHUTDOWN', $strPrivDescShutdown);
397 if (isset($row['Show_db_priv'])) {
398 $privTable[2][] = array('Show_db', 'SHOW&nbsp;DATABASES', $strPrivDescShowDb);
400 if (isset($row['Lock_tables_priv'])) {
401 $privTable[2][] = array('Lock_tables', 'LOCK&nbsp;TABLES', $strPrivDescLockTables);
403 $privTable[2][] = array('References', 'REFERENCES', $strPrivDescReferences);
404 if (isset($row['Execute_priv'])) {
405 $privTable[2][] = array('Execute', 'EXECUTE', $strPrivDescExecute);
407 if (isset($row['Repl_client_priv'])) {
408 $privTable[2][] = array('Repl_client', 'REPLICATION&nbsp;CLIENT', $strPrivDescReplClient);
410 if (isset($row['Repl_slave_priv'])) {
411 $privTable[2][] = array('Repl_slave', 'REPLICATION&nbsp;SLAVE', $strPrivDescReplSlave);
413 echo ' <form action="server_privileges.php3" method="post">' . "\n"
414 . ' <input type="hidden" name="lang" value="' . $lang . '" />' . "\n"
415 . ' <input type="hidden" name="convcharset" value="' . $convcharset . '" />' . "\n"
416 . ' <input type="hidden" name="server" value="' . $server . '" />' . "\n"
417 . ' <input type="hidden" name="username" value="' . htmlspecialchars($username) . '" />' . "\n";
418 if ($hostname != '%') {
419 echo ' <input type="hidden" name="hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n";
421 echo ' <input type="hidden" name="grant_count" value="' . (count($privTable[0]) + count($privTable[1]) + count($privTable[2]) - (isset($row['Grant_priv']) ? 1 : 0)) . '" />' . "\n"
422 . ' <b>' . $strEditPrivileges . '</b><br />' . "\n"
423 . ' <table border="0">' . "\n"
424 . ' <tr>' . "\n"
425 . ' <th colspan="6">&nbsp;' . $strGlobalPrivileges . '&nbsp;</th>' . "\n"
426 . ' </tr>' . "\n"
427 . ' <tr>' . "\n"
428 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '" colspan="6"><small><i>' . $strEnglishPrivileges . '</i></small></th>' . "\n"
429 . ' </tr>' . "\n"
430 . ' <tr>'
431 . ' <td bgcolor="' . $cfg['BgcolorOne'] . '" colspan="2">&nbsp;<b><i>' . $strData . '</i></b>&nbsp;</td>' . "\n"
432 . ' <td bgcolor="' . $cfg['BgcolorOne'] . '" colspan="2">&nbsp;<b><i>' . $strStructure . '</i></b>&nbsp;</td>' . "\n"
433 . ' <td bgcolor="' . $cfg['BgcolorOne'] . '" colspan="2">&nbsp;<b><i>' . $strAdministration . '</i></b>&nbsp;</td>' . "\n"
434 . ' </tr>' . "\n";
435 $limitTable = FALSE;
436 for ($i = 0; isset($privTable[0][$i]) || isset($privTable[1][$i]) || isset($privTable[2][$i]); $i++) {
437 echo ' <tr>' . "\n";
438 for ($j = 0; $j < 3; $j++) {
439 if (isset($privTable[$j][$i])) {
440 echo ' <td bgcolor="' . $cfg['BgcolorTwo'] . '"><input type="checkbox" name="' . $privTable[$j][$i][0] . '_priv" id="checkbox_' . $privTable[$j][$i][0] . '_priv" value="Y" ' . ($row[$privTable[$j][$i][0] . '_priv'] == 'Y' ? 'checked="checked" ' : '') . 'title="' . $privTable[$j][$i][2] . '"/></td>' . "\n"
441 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '"><label for="checkbox_' . $privTable[$j][$i][0] . '_priv"><tt><dfn title="' . $privTable[$j][$i][2] . '">' . $privTable[$j][$i][1] . '</dfn></tt></label></td>' . "\n";
442 } else if (!isset($privTable[0][$i]) && !isset($privTable[1][$i])
443 && isset($row['max_questions']) && isset($row['max_updates']) && isset($row['max_connections'])
444 && !$limitTable) {
445 echo ' <td colspan="4" rowspan="' . (count($privTable[2]) - $i) . '">' . "\n"
446 . ' <table border="0">' . "\n"
447 . ' <tr>' . "\n"
448 . ' <th colspan="2">&nbsp;' . $strResourceLimits . '&nbsp;</th>' . "\n"
449 . ' </tr>' . "\n"
450 . ' <tr>' . "\n"
451 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '" colspan="2"><small><i>' . $strZeroRemovesTheLimit . '</i></small></td>' . "\n"
452 . ' </tr>' . "\n"
453 . ' <tr>' . "\n"
454 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '"><label for="text_max_questions"><tt><dfn title="' . $strPrivDescMaxQuestions . '">MAX&nbsp;QUERIES&nbsp;PER&nbsp;HOUR</dfn></tt></label></td>' . "\n"
455 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '"><input type="text" name="max_questions" id="text_max_questions" value="' . $row['max_questions'] . '" size="11" maxlength="11" title="' . $strPrivDescMaxQuestions . '" /></td>' . "\n"
456 . ' </tr>' . "\n"
457 . ' <tr>' . "\n"
458 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '"><label for="text_max_updates"><tt><dfn title="' . $strPrivDescMaxUpdates . '">MAX&nbsp;UPDATES&nbsp;PER&nbsp;HOUR</dfn></tt></label></td>' . "\n"
459 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '"><input type="text" name="max_updates" id="text_max_updates" value="' . $row['max_updates'] . '" size="11" maxlength="11" title="' . $strPrivDescMaxUpdates . '" /></td>' . "\n"
460 . ' </tr>' . "\n"
461 . ' <tr>' . "\n"
462 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '"><label for="text_max_connections"><tt><dfn title="' . $strPrivDescMaxConnections . '">MAX&nbsp;CONNECTIONS&nbsp;PER&nbsp;HOUR</dfn></tt></label></td>' . "\n"
463 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '"><input type="text" name="max_connections" id="text_max_connections" value="' . $row['max_connections'] . '" size="11" maxlength="11" title="' . $strPrivDescMaxConnections . '" /></td>' . "\n"
464 . ' </tr>' . "\n"
465 . ' </table>' . "\n"
466 . ' </td>' . "\n";
467 $limitTable = TRUE;
468 } else if (!$limitTable) {
469 echo ' <td colspan="2"></td>' . "\n";
472 echo ' </tr>' . "\n";
474 echo ' <tr>' . "\n"
475 . ' <td colspan="6" align="center">' . "\n"
476 . ' <input type="submit" name="update_privs" value="' . $strGo . '" />' . "\n"
477 . ' </td>' . "\n"
478 . ' </tr>' . "\n"
479 . ' </table>' . "\n"
480 . ' </form>' . "\n"
481 . ' </li>' . "\n"
482 . ' <li>' . "\n"
483 . ' <form name="chgPassword" action="server_privileges.php3" method="post" onsubmit="return checkPassword(this);">' . "\n"
484 . ' <input type="hidden" name="lang" value="' . $lang . '" />' . "\n"
485 . ' <input type="hidden" name="convcharset" value="' . $convcharset . '" />' . "\n"
486 . ' <input type="hidden" name="server" value="' . $server . '" />' . "\n"
487 . ' <input type="hidden" name="username" value="' . urlencode($username) . '" />' . "\n";
488 if ($hostname != '%') {
489 echo ' <input type="hidden" name="hostname" value="' . urlencode($hostname) . '" />' . "\n";
491 echo ' <b>' . $strChangePassword . '</b><br />' . "\n"
492 . ' <table border="0">' . "\n"
493 . ' <tr>' . "\n"
494 . ' <td bgcolor="' . $cfg['BgcolorOne'] . '"><input type="radio" name="nopass" value="1" id="radio_nopass_1" onclick="pma_pw.value=\'\'; pma_pw2.value=\'\';" /></td>' . "\n"
495 . ' <td bgcolor="' . $cfg['BgcolorOne'] . '" colspan="2"><label for="radio_nopass_1">' . $strNoPassword . '</label></td>' . "\n"
496 . ' </tr>' . "\n"
497 . ' <tr>' . "\n"
498 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '"><input type="radio" name="nopass" value="0" id="radio_nopass_0" onclick="document.getElementById(\'pw_pma_pw\').focus();" /></td>' . "\n"
499 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '"><label for="radio_nopass_0">' . $strPassword . ':</label></td>' . "\n"
500 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '"><input type="password" name="pma_pw" id="pw_pma_pw" class="textfield" onchange="nopass[1].checked = true;" /></td>' . "\n"
501 . ' </tr>' . "\n"
502 . ' <tr>' . "\n"
503 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '">&nbsp;</td>' . "\n"
504 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '"><label for="pw_pma_pw2">' . $strReType . ':</label></td>' . "\n"
505 . ' <td bgcolor="' . $cfg['BgcolorTwo'] . '"><input type="password" name="pma_pw2" id="pw_pma_pw2" class="textfield" onchange="nopass[1].checked = true;" /></td>' . "\n"
506 . ' </tr>' . "\n"
507 . ' <td colspan="3" align="center">' . "\n"
508 . ' <input type="submit" name="change_pw" value="' . $strGo . '" />' . "\n"
509 . ' </td>' . "\n"
510 . ' </table>' . "\n"
511 . ' </form>' . "\n"
512 . ' </li>' . "\n"
513 . '</ul>' . "\n";
514 } else if (isset($hostname)) {
515 // TODO: Host privilege editor
519 * Displays the footer
521 require('./footer.inc.php3');