| [ Index ] |
|
Code source de phpMyAdmin 2.10.3 |
1 <?php 2 /* $Id: server_privileges.php 9855 2007-01-20 15:38:45Z lem9 $ */ 3 // vim: expandtab sw=4 ts=4 sts=4: 4 5 require_once ('./libraries/common.lib.php'); 6 7 /** 8 * Does the common work 9 */ 10 $js_to_run = 'server_privileges.js'; 11 require ('./libraries/server_common.inc.php'); 12 13 14 /** 15 * Checks if a dropdown box has been used for selecting a database / table 16 */ 17 if (isset($pred_dbname) && strlen($pred_dbname)) { 18 $dbname = $pred_dbname; 19 unset($pred_dbname); 20 } 21 if (isset($pred_tablename) && strlen($pred_tablename)) { 22 $tablename = $pred_tablename; 23 unset($pred_tablename); 24 } 25 26 // check if given $dbanem is a wildcard or not 27 if ( isset( $dbname ) ) { 28 //if ( preg_match( '/\\\\(?:_|%)/i', $dbname ) ) { 29 if ( preg_match( '/(?<!\\\\)(?:_|%)/i', $dbname ) ) { 30 $dbname_is_wildcard = true; 31 } else { 32 $dbname_is_wildcard = false; 33 } 34 } 35 36 /** 37 * Checks if the user is allowed to do what he tries to... 38 */ 39 if (!$is_superuser) { 40 require ('./libraries/server_links.inc.php'); 41 echo '<h2>' . "\n" 42 . ($GLOBALS['cfg']['MainPageIconic'] ? '<img class="icon" src="'. $GLOBALS['pmaThemeImage'] . 'b_usrlist.png" alt="" />' : '') 43 . $GLOBALS['strPrivileges'] . "\n" 44 . '</h2>' . "\n" 45 . $GLOBALS['strNoPrivileges'] . "\n"; 46 require_once ('./libraries/footer.inc.php'); 47 } 48 49 /** 50 * Generates a condition on the user name 51 * 52 * @param string the user's initial 53 * @return string the generated condition 54 */ 55 function PMA_RangeOfUsers($initial = '') { 56 // strtolower() is used because the User field 57 // might be BINARY, so LIKE would be case sensitive 58 if (!empty($initial)) { 59 $ret = " WHERE " . PMA_convert_using('User') 60 . " LIKE " . PMA_convert_using($initial . '%', 'quoted') 61 . " OR ". PMA_convert_using('User') 62 . " LIKE " . PMA_convert_using(strtolower($initial) . '%', 'quoted'); 63 } else { 64 $ret = ''; 65 } 66 return $ret; 67 } // end function 68 69 /** 70 * Extracts the privilege information of a priv table row 71 * 72 * @param array $row the row 73 * @param boolean $enableHTML add <dfn> tag with tooltips 74 * 75 * @global ressource $user_link the database connection 76 * 77 * @return array 78 */ 79 function PMA_extractPrivInfo($row = '', $enableHTML = FALSE) 80 { 81 $grants = array( 82 array('Select_priv', 'SELECT', $GLOBALS['strPrivDescSelect']), 83 array('Insert_priv', 'INSERT', $GLOBALS['strPrivDescInsert']), 84 array('Update_priv', 'UPDATE', $GLOBALS['strPrivDescUpdate']), 85 array('Delete_priv', 'DELETE', $GLOBALS['strPrivDescDelete']), 86 array('Create_priv', 'CREATE', $GLOBALS['strPrivDescCreateDb']), 87 array('Drop_priv', 'DROP', $GLOBALS['strPrivDescDropDb']), 88 array('Reload_priv', 'RELOAD', $GLOBALS['strPrivDescReload']), 89 array('Shutdown_priv', 'SHUTDOWN', $GLOBALS['strPrivDescShutdown']), 90 array('Process_priv', 'PROCESS', $GLOBALS['strPrivDescProcess' . ((!empty($row) && isset($row['Super_priv'])) || (empty($row) && isset($GLOBALS['Super_priv'])) ? '4' : '3')]), 91 array('File_priv', 'FILE', $GLOBALS['strPrivDescFile']), 92 array('References_priv', 'REFERENCES', $GLOBALS['strPrivDescReferences']), 93 array('Index_priv', 'INDEX', $GLOBALS['strPrivDescIndex']), 94 array('Alter_priv', 'ALTER', $GLOBALS['strPrivDescAlter']), 95 array('Show_db_priv', 'SHOW DATABASES', $GLOBALS['strPrivDescShowDb']), 96 array('Super_priv', 'SUPER', $GLOBALS['strPrivDescSuper']), 97 array('Create_tmp_table_priv', 'CREATE TEMPORARY TABLES', $GLOBALS['strPrivDescCreateTmpTable']), 98 array('Lock_tables_priv', 'LOCK TABLES', $GLOBALS['strPrivDescLockTables']), 99 array('Repl_slave_priv', 'REPLICATION SLAVE', $GLOBALS['strPrivDescReplSlave']), 100 array('Repl_client_priv', 'REPLICATION CLIENT', $GLOBALS['strPrivDescReplClient']), 101 array('Create_view_priv', 'CREATE VIEW', $GLOBALS['strPrivDescCreateView']), 102 // for table privs: 103 array('Create View_priv', 'CREATE VIEW', $GLOBALS['strPrivDescCreateView']), 104 array('Show_view_priv', 'SHOW VIEW', $GLOBALS['strPrivDescShowView']), 105 // for table privs: 106 array('Show view_priv', 'SHOW VIEW', $GLOBALS['strPrivDescShowView']), 107 array('Create_routine_priv', 'CREATE ROUTINE', $GLOBALS['strPrivDescCreateRoutine']), 108 array('Alter_routine_priv', 'ALTER ROUTINE', $GLOBALS['strPrivDescAlterRoutine']), 109 array('Create_user_priv', 'CREATE USER', $GLOBALS['strPrivDescCreateUser']) 110 ); 111 if (PMA_MYSQL_INT_VERSION >= 40002 && PMA_MYSQL_INT_VERSION <50003) { 112 $grants[] = array('Execute_priv', 'EXECUTE', $GLOBALS['strPrivDescExecute']); 113 } else { 114 $grants[] = array('Execute_priv', 'EXECUTE', $GLOBALS['strPrivDescExecute5']); 115 } 116 117 if (!empty($row) && isset($row['Table_priv'])) { 118 $res = PMA_DBI_query( 119 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';', 120 $GLOBALS['userlink'] ); 121 $row1 = PMA_DBI_fetch_assoc($res); 122 PMA_DBI_free_result($res); 123 $av_grants = explode ('\',\'', substr($row1['Type'], 5, strlen($row1['Type']) - 7)); 124 unset($row1); 125 $users_grants = explode(',', $row['Table_priv']); 126 foreach ($av_grants as $current_grant) { 127 $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ? 'Y' : 'N'; 128 } 129 unset($current_grant); 130 unset($av_grants); 131 unset($users_grants); 132 } 133 $privs = array(); 134 $allPrivileges = TRUE; 135 foreach ($grants as $current_grant) { 136 if ((!empty($row) && isset($row[$current_grant[0]])) || (empty($row) && isset($GLOBALS[$current_grant[0]]))) { 137 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']))))) { 138 if ($enableHTML) { 139 $privs[] = '<dfn title="' . $current_grant[2] . '">' . $current_grant[1] . '</dfn>'; 140 } else { 141 $privs[] = $current_grant[1]; 142 } 143 } elseif (!empty($GLOBALS[$current_grant[0]]) && is_array($GLOBALS[$current_grant[0]]) && empty($GLOBALS[$current_grant[0] . '_none'])) { 144 if ($enableHTML) { 145 $priv_string = '<dfn title="' . $current_grant[2] . '">' . $current_grant[1] . '</dfn>'; 146 } else { 147 $priv_string = $current_grant[1]; 148 } 149 $privs[] = $priv_string . ' (`' . join('`, `', $GLOBALS[$current_grant[0]]) . '`)'; 150 } else { 151 $allPrivileges = FALSE; 152 } 153 } 154 } 155 if (empty($privs)) { 156 if ($enableHTML) { 157 $privs[] = '<dfn title="' . $GLOBALS['strPrivDescUsage'] . '">USAGE</dfn>'; 158 } else { 159 $privs[] = 'USAGE'; 160 } 161 } elseif ($allPrivileges && (!isset($GLOBALS['grant_count']) || count($privs) == $GLOBALS['grant_count'])) { 162 if ($enableHTML) { 163 $privs = array('<dfn title="' . $GLOBALS['strPrivDescAllPrivileges'] . '">ALL PRIVILEGES</dfn>'); 164 } else { 165 $privs = array('ALL PRIVILEGES'); 166 } 167 } 168 return $privs; 169 } // end of the 'PMA_extractPrivInfo()' function 170 171 172 /** 173 * Displays on which column(s) a table-specific privilege is granted 174 */ 175 function PMA_display_column_privs($spaces, $columns, $row, $name_for_select, $priv_for_header, $name, $name_for_dfn, $name_for_current) { 176 177 echo $spaces . ' <div class="item" id="div_item_' . $name . '">' . "\n" 178 . $spaces . ' <label for="select_' . $name . '_priv">' . "\n" 179 . $spaces . ' <tt><dfn title="' . $name_for_dfn . '">' . $priv_for_header . '</dfn></tt>' . "\n" 180 . $spaces . ' </label>' . "\n" 181 . $spaces . ' <select id="select_' . $name . '_priv" name="' . $name_for_select . '[]" multiple="multiple">' . "\n"; 182 183 foreach ($columns as $current_column => $current_column_privileges) { 184 echo $spaces . ' <option value="' . htmlspecialchars($current_column) . '"'; 185 if ($row[$name_for_select] == 'Y' || $current_column_privileges[$name_for_current]) { 186 echo ' selected="selected"'; 187 } 188 echo '>' . htmlspecialchars($current_column) . '</option>' . "\n"; 189 } 190 191 echo $spaces . ' </select>' . "\n" 192 . $spaces . ' <i>' . $GLOBALS['strOr'] . '</i>' . "\n" 193 . $spaces . ' <label for="checkbox_' . $name_for_select . '_none"><input type="checkbox"' . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"') . ' name="' . $name_for_select . '_none" id="checkbox_' . $name_for_select . '_none" title="' . $GLOBALS['strNone'] . '" />' 194 . $GLOBALS['strNone'] . '</label>' . "\n" 195 . $spaces . ' </div>' . "\n"; 196 } // end function 197 198 /** 199 * Displays the privileges form table 200 * 201 * @param string $db the database 202 * @param string $table the table 203 * @param boolean $submit wheather to display the submit button or not 204 * @param int $indent the indenting level of the code 205 * 206 * @global array $cfg the phpMyAdmin configuration 207 * @global ressource $user_link the database connection 208 * 209 * @return void 210 */ 211 function PMA_displayPrivTable($db = '*', $table = '*', $submit = TRUE, $indent = 0) 212 { 213 if ($db == '*') { 214 $table = '*'; 215 } 216 $spaces = str_repeat( ' ', $indent ); 217 218 if (isset($GLOBALS['username'])) { 219 $username = $GLOBALS['username']; 220 $hostname = $GLOBALS['hostname']; 221 if ($db == '*') { 222 $sql_query = 223 'SELECT * FROM `mysql`.`user`' 224 .' WHERE ' . PMA_convert_using('User') 225 .' = ' . PMA_convert_using(PMA_sqlAddslashes($username), 'quoted') 226 .' AND ' . PMA_convert_using('Host') 227 .' = ' . PMA_convert_using($hostname, 'quoted') . ';'; 228 } elseif ($table == '*') { 229 $sql_query = 230 'SELECT * FROM `mysql`.`db`' 231 .' WHERE ' . PMA_convert_using('`User`') 232 .' = ' . PMA_convert_using(PMA_sqlAddslashes($username), 'quoted') 233 .' AND ' . PMA_convert_using('`Host`') 234 .' = ' . PMA_convert_using($hostname, 'quoted') 235 .' AND ' . PMA_convert_using( PMA_unescape_mysql_wildcards( $db ), 'quoted' ) 236 .' LIKE ' . PMA_convert_using( '`Db`' ) . ';'; 237 } else { 238 $sql_query = 239 'SELECT `Table_priv`' 240 .' FROM `mysql`.`tables_priv`' 241 .' WHERE ' . PMA_convert_using('`User`') 242 .' = ' . PMA_convert_using(PMA_sqlAddslashes($username), 'quoted') 243 .' AND ' .PMA_convert_using('`Host`') 244 .' = ' . PMA_convert_using( $hostname, 'quoted' ) 245 .' AND ' .PMA_convert_using('`Db`') 246 .' = ' . PMA_convert_using( PMA_unescape_mysql_wildcards( $db ), 'quoted' ) 247 .' AND ' . PMA_convert_using('`Table_name`') 248 .' = ' . PMA_convert_using($table, 'quoted') . ';'; 249 } 250 $res = PMA_DBI_query($sql_query); 251 $row = PMA_DBI_fetch_assoc($res); 252 PMA_DBI_free_result($res); 253 } 254 if (empty($row)) { 255 if ($table == '*') { 256 if ($db == '*') { 257 $sql_query = 'SHOW COLUMNS FROM `mysql`.`user`;'; 258 } elseif ($table == '*') { 259 $sql_query = 'SHOW COLUMNS FROM `mysql`.`db`;'; 260 } 261 $res = PMA_DBI_query($sql_query); 262 while ($row1 = PMA_DBI_fetch_row($res)) { 263 if (substr($row1[0], 0, 4) == 'max_') { 264 $row[$row1[0]] = 0; 265 } else { 266 $row[$row1[0]] = 'N'; 267 } 268 } 269 PMA_DBI_free_result($res); 270 } else { 271 $row = array('Table_priv' => ''); 272 } 273 } 274 if (isset($row['Table_priv'])) { 275 $res = PMA_DBI_query( 276 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';', 277 $GLOBALS['userlink'] ); 278 // note: in MySQL 5.0.3 we get "Create View', 'Show view'; 279 // the View for Create is spelled with uppercase V 280 // the view for Show is spelled with lowercase v 281 // and there is a space between the words 282 283 $row1 = PMA_DBI_fetch_assoc($res); 284 PMA_DBI_free_result($res); 285 $av_grants = explode ('\',\'', substr($row1['Type'], strpos($row1['Type'], '(') + 2, strpos($row1['Type'], ')') - strpos($row1['Type'], '(') - 3)); 286 unset($res, $row1); 287 $users_grants = explode(',', $row['Table_priv']); 288 289 foreach ($av_grants as $current_grant) { 290 $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ? 'Y' : 'N'; 291 } 292 unset($row['Table_priv'], $current_grant, $av_grants, $users_grants); 293 294 // get collumns 295 $res = PMA_DBI_try_query('SHOW COLUMNS FROM `' . PMA_unescape_mysql_wildcards( $db ) . '`.`' . $table . '`;'); 296 $columns = array(); 297 if ( $res ) { 298 while ($row1 = PMA_DBI_fetch_row($res)) { 299 $columns[$row1[0]] = array( 300 'Select' => FALSE, 301 'Insert' => FALSE, 302 'Update' => FALSE, 303 'References' => FALSE 304 ); 305 } 306 PMA_DBI_free_result($res); 307 } 308 unset($res, $row1); 309 } 310 // t a b l e - s p e c i f i c p r i v i l e g e s 311 if ( ! empty( $columns ) ) { 312 $res = PMA_DBI_query( 313 'SELECT `Column_name`, `Column_priv`' 314 .' FROM `mysql`.`columns_priv`' 315 .' WHERE ' . PMA_convert_using('`User`') 316 .' = ' . PMA_convert_using(PMA_sqlAddslashes($username), 'quoted') 317 .' AND ' . PMA_convert_using('`Host`') 318 .' = ' . PMA_convert_using($hostname, 'quoted') 319 .' AND ' . PMA_convert_using('`Db`') 320 .' = ' . PMA_convert_using( PMA_unescape_mysql_wildcards( $db ), 'quoted') 321 .' AND ' . PMA_convert_using('`Table_name`') 322 .' = ' . PMA_convert_using($table, 'quoted') . ';'); 323 324 while ($row1 = PMA_DBI_fetch_row($res)) { 325 $row1[1] = explode(',', $row1[1]); 326 foreach ($row1[1] as $current) { 327 $columns[$row1[0]][$current] = TRUE; 328 } 329 } 330 PMA_DBI_free_result($res); 331 unset( $res, $row1, $current ); 332 333 echo $spaces . '<input type="hidden" name="grant_count" value="' . count($row) . '" />' . "\n" 334 . $spaces . '<input type="hidden" name="column_count" value="' . count($columns) . '" />' . "\n" 335 . $spaces . '<fieldset id="fieldset_user_priv">' . "\n" 336 . $spaces . ' <legend>' . $GLOBALS['strTblPrivileges'] . '</legend>' . "\n" 337 . $spaces . ' <p><small><i>' . $GLOBALS['strEnglishPrivileges'] . '</i></small></p>' . "\n"; 338 339 340 // privs that are attached to a specific column 341 PMA_display_column_privs($spaces, $columns, $row, 'Select_priv', 'SELECT', 'select', $GLOBALS['strPrivDescSelect'], 'Select'); 342 343 PMA_display_column_privs($spaces, $columns, $row, 'Insert_priv', 'INSERT', 'insert', $GLOBALS['strPrivDescInsert'], 'Insert'); 344 345 PMA_display_column_privs($spaces, $columns, $row, 'Update_priv', 'UPDATE', 'update', $GLOBALS['strPrivDescUpdate'], 'Update'); 346 347 PMA_display_column_privs($spaces, $columns, $row, 'References_priv', 'REFERENCES', 'references', $GLOBALS['strPrivDescReferences'], 'References'); 348 349 // privs that are not attached to a specific column 350 351 echo $spaces . ' <div class="item">' . "\n"; 352 foreach ($row as $current_grant => $current_grant_value) { 353 if (in_array(substr($current_grant, 0, (strlen($current_grant) - 5)), array('Select', 'Insert', 'Update', 'References'))) { 354 continue; 355 } 356 // make a substitution to match the messages variables; 357 // also we must substitute the grant we get, because we can't generate 358 // a form variable containing blanks (those would get changed to 359 // an underscore when receiving the POST) 360 if ($current_grant == 'Create View_priv') { 361 $tmp_current_grant = 'CreateView_priv'; 362 $current_grant = 'Create_view_priv'; 363 } elseif ($current_grant == 'Show view_priv') { 364 $tmp_current_grant = 'ShowView_priv'; 365 $current_grant = 'Show_view_priv'; 366 } else { 367 $tmp_current_grant = $current_grant; 368 } 369 370 echo $spaces . ' <div class="item">' . "\n" 371 . $spaces . ' <input type="checkbox"' . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"') . ' name="' . $current_grant . '" id="checkbox_' . $current_grant . '" value="Y" ' . ($current_grant_value == 'Y' ? 'checked="checked" ' : '') . 'title="'; 372 373 echo (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))]) ? $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))] : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)) . 'Tbl']) . '"/>' . "\n"; 374 375 echo $spaces . ' <label for="checkbox_' . $current_grant . '"><tt><dfn title="' . (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))]) ? $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))] : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)) . 'Tbl']) . '">' . strtoupper(substr($current_grant, 0, strlen($current_grant) - 5)) . '</dfn></tt></label>' . "\n" 376 . $spaces . ' </div>' . "\n"; 377 } // end foreach () 378 379 echo $spaces . ' </div>' . "\n"; 380 // for Safari 2.0.2 381 echo $spaces . ' <div class="clearfloat"></div>' . "\n"; 382 383 } else { 384 385 // g l o b a l o r d b - s p e c i f i c 386 // 387 // d a t a 388 $privTable[0] = array( 389 array('Select', 'SELECT', $GLOBALS['strPrivDescSelect']), 390 array('Insert', 'INSERT', $GLOBALS['strPrivDescInsert']), 391 array('Update', 'UPDATE', $GLOBALS['strPrivDescUpdate']), 392 array('Delete', 'DELETE', $GLOBALS['strPrivDescDelete']) 393 ); 394 if ($db == '*') { 395 $privTable[0][] = array('File', 'FILE', $GLOBALS['strPrivDescFile']); 396 } 397 398 // s t r u c t u r e 399 $privTable[1] = array( 400 array('Create', 'CREATE', ($table == '*' ? $GLOBALS['strPrivDescCreateDb'] : $GLOBALS['strPrivDescCreateTbl'])), 401 array('Alter', 'ALTER', $GLOBALS['strPrivDescAlter']), 402 array('Index', 'INDEX', $GLOBALS['strPrivDescIndex']), 403 array('Drop', 'DROP', ($table == '*' ? $GLOBALS['strPrivDescDropDb'] : $GLOBALS['strPrivDescDropTbl'])) 404 ); 405 if (isset($row['Create_tmp_table_priv'])) { 406 $privTable[1][] = array('Create_tmp_table', 'CREATE TEMPORARY TABLES', $GLOBALS['strPrivDescCreateTmpTable']); 407 } 408 // this one is for a db-specific priv: Create_view_priv 409 if (isset($row['Create_view_priv'])) { 410 $privTable[1][] = array('Create_view', 'CREATE VIEW', $GLOBALS['strPrivDescCreateView']); 411 } 412 // this one is for a table-specific priv: Create View_priv 413 if (isset($row['Create View_priv'])) { 414 $privTable[1][] = array('Create View', 'CREATE VIEW', $GLOBALS['strPrivDescCreateView']); 415 } 416 if (isset($row['Show_view_priv'])) { 417 $privTable[1][] = array('Show_view', 'SHOW VIEW', $GLOBALS['strPrivDescShowView']); 418 } 419 if (isset($row['Create_routine_priv'])) { 420 $privTable[1][] = array('Create_routine', 'CREATE ROUTINE', $GLOBALS['strPrivDescCreateRoutine']); 421 } 422 if (isset($row['Alter_routine_priv'])) { 423 $privTable[1][] = array('Alter_routine', 'ALTER ROUTINE', $GLOBALS['strPrivDescAlterRoutine']); 424 } 425 if (isset($row['Execute_priv'])) { 426 if (PMA_MYSQL_INT_VERSION >= 40002 && PMA_MYSQL_INT_VERSION <50003) { 427 $privTable[1][] = array('Execute', 'EXECUTE', $GLOBALS['strPrivDescExecute']); 428 } else { 429 $privTable[1][] = array('Execute', 'EXECUTE', $GLOBALS['strPrivDescExecute5']); 430 } 431 } 432 433 // a d m i n i s t r a t i o n 434 $privTable[2] = array(); 435 if (isset($row['Grant_priv'])) { 436 $privTable[2][] = array('Grant', 'GRANT', $GLOBALS['strPrivDescGrant']); 437 } 438 if ($db == '*') { 439 if (isset($row['Super_priv'])) { 440 $privTable[2][] = array('Super', 'SUPER', $GLOBALS['strPrivDescSuper']); 441 $privTable[2][] = array('Process', 'PROCESS', $GLOBALS['strPrivDescProcess4']); 442 } else { 443 $privTable[2][] = array('Process', 'PROCESS', $GLOBALS['strPrivDescProcess3']); 444 } 445 $privTable[2][] = array('Reload', 'RELOAD', $GLOBALS['strPrivDescReload']); 446 $privTable[2][] = array('Shutdown', 'SHUTDOWN', $GLOBALS['strPrivDescShutdown']); 447 if (isset($row['Show_db_priv'])) { 448 $privTable[2][] = array('Show_db', 'SHOW DATABASES', $GLOBALS['strPrivDescShowDb']); 449 } 450 } 451 if (isset($row['Lock_tables_priv'])) { 452 $privTable[2][] = array('Lock_tables', 'LOCK TABLES', $GLOBALS['strPrivDescLockTables']); 453 } 454 $privTable[2][] = array('References', 'REFERENCES', $GLOBALS['strPrivDescReferences']); 455 if ($db == '*') { 456 //if (isset($row['Execute_priv'])) { 457 // $privTable[2][] = array('Execute', 'EXECUTE', $GLOBALS['strPrivDescExecute']); 458 //} 459 if (isset($row['Repl_client_priv'])) { 460 $privTable[2][] = array('Repl_client', 'REPLICATION CLIENT', $GLOBALS['strPrivDescReplClient']); 461 } 462 if (isset($row['Repl_slave_priv'])) { 463 $privTable[2][] = array('Repl_slave', 'REPLICATION SLAVE', $GLOBALS['strPrivDescReplSlave']); 464 } 465 if (isset($row['Create_user_priv'])) { 466 $privTable[2][] = array('Create_user', 'CREATE USER', $GLOBALS['strPrivDescCreateUser']); 467 } 468 } 469 echo $spaces . '<input type="hidden" name="grant_count" value="' . (count($privTable[0]) + count($privTable[1]) + count($privTable[2]) - (isset($row['Grant_priv']) ? 1 : 0)) . '" />' . "\n" 470 . $spaces . '<fieldset id="fieldset_user_global_rights">' . "\n" 471 . $spaces . ' <legend>' . "\n" 472 . $spaces . ' ' . ($db == '*' ? $GLOBALS['strGlobalPrivileges'] : ($table == '*' ? $GLOBALS['strDbPrivileges'] : $GLOBALS['strTblPrivileges'])) . "\n" 473 . $spaces . ' ( <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&checkall=1" onclick="setCheckboxes(\'usersForm\', true); return false;">' . $GLOBALS['strCheckAll'] . '</a> /' . "\n" 474 . $spaces . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '" onclick="setCheckboxes(\'usersForm\', false); return false;">' . $GLOBALS['strUncheckAll'] . '</a> )' . "\n" 475 . $spaces . ' </legend>' . "\n" 476 . $spaces . ' <p><small><i>' . $GLOBALS['strEnglishPrivileges'] . '</i></small></p>' . "\n" 477 . $spaces . ' <fieldset>' . "\n" 478 . $spaces . ' <legend>' . $GLOBALS['strData'] . '</legend>' . "\n"; 479 foreach ( $privTable[0] as $priv ) 480 { 481 echo $spaces . ' <div class="item">' . "\n" 482 . $spaces . ' <input type="checkbox"' . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"') . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0] . '_priv" value="Y" ' . ($row[$priv[0] . '_priv'] == 'Y' ? 'checked="checked" ' : '') . 'title="' . $priv[2] . '"/>' . "\n" 483 . $spaces . ' <label for="checkbox_' . $priv[0] . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1] . '</dfn></tt></label>' . "\n" 484 . $spaces . ' </div>' . "\n"; 485 } 486 echo $spaces . ' </fieldset>' . "\n" 487 . $spaces . ' <fieldset>' . "\n" 488 . $spaces . ' <legend>' . $GLOBALS['strStructure'] . '</legend>' . "\n"; 489 foreach ( $privTable[1] as $priv ) 490 { 491 echo $spaces . ' <div class="item">' . "\n" 492 . $spaces . ' <input type="checkbox"' . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"') . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0] . '_priv" value="Y" ' . ($row[$priv[0] . '_priv'] == 'Y' ? 'checked="checked" ' : '') . 'title="' . $priv[2] . '"/>' . "\n" 493 . $spaces . ' <label for="checkbox_' . $priv[0] . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1] . '</dfn></tt></label>' . "\n" 494 . $spaces . ' </div>' . "\n"; 495 } 496 echo $spaces . ' </fieldset>' . "\n" 497 . $spaces . ' <fieldset>' . "\n" 498 . $spaces . ' <legend>' . $GLOBALS['strAdministration'] . '</legend>' . "\n"; 499 foreach ( $privTable[2] as $priv ) 500 { 501 echo $spaces . ' <div class="item">' . "\n" 502 . $spaces . ' <input type="checkbox"' . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"') . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0] . '_priv" value="Y" ' . ($row[$priv[0] . '_priv'] == 'Y' ? 'checked="checked" ' : '') . 'title="' . $priv[2] . '"/>' . "\n" 503 . $spaces . ' <label for="checkbox_' . $priv[0] . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1] . '</dfn></tt></label>' . "\n" 504 . $spaces . ' </div>' . "\n"; 505 } 506 507 echo $spaces . ' </fieldset>' . "\n"; 508 // The "Resource limits" box is not displayed for db-specific privs 509 if ($db == '*' && PMA_MYSQL_INT_VERSION >= 40002) { 510 echo $spaces . ' <fieldset>' . "\n" 511 . $spaces . ' <legend>' . $GLOBALS['strResourceLimits'] . '</legend>' . "\n" 512 . $spaces . ' <p><small><i>' . $GLOBALS['strZeroRemovesTheLimit'] . '</i></small></p>' . "\n" 513 . $spaces . ' <div class="item">' . "\n" 514 . $spaces . ' <label for="text_max_questions"><tt><dfn title="' . $GLOBALS['strPrivDescMaxQuestions'] . '">MAX QUERIES PER HOUR</dfn></tt></label>' . "\n" 515 . $spaces . ' <input type="text" name="max_questions" id="text_max_questions" value="' . $row['max_questions'] . '" size="11" maxlength="11" title="' . $GLOBALS['strPrivDescMaxQuestions'] . '" />' . "\n" 516 . $spaces . ' </div>' . "\n" 517 . $spaces . ' <div class="item">' . "\n" 518 . $spaces . ' <label for="text_max_updates"><tt><dfn title="' . $GLOBALS['strPrivDescMaxUpdates'] . '">MAX UPDATES PER HOUR</dfn></tt></label>' . "\n" 519 . $spaces . ' <input type="text" name="max_updates" id="text_max_updates" value="' . $row['max_updates'] . '" size="11" maxlength="11" title="' . $GLOBALS['strPrivDescMaxUpdates'] . '" />' . "\n" 520 . $spaces . ' </div>' . "\n" 521 . $spaces . ' <div class="item">' . "\n" 522 . $spaces . ' <label for="text_max_connections"><tt><dfn title="' . $GLOBALS['strPrivDescMaxConnections'] . '">MAX CONNECTIONS PER HOUR</dfn></tt></label>' . "\n" 523 . $spaces . ' <input type="text" name="max_connections" id="text_max_connections" value="' . $row['max_connections'] . '" size="11" maxlength="11" title="' . $GLOBALS['strPrivDescMaxConnections'] . '" />' . "\n" 524 . $spaces . ' </div>' . "\n"; 525 526 if (PMA_MYSQL_INT_VERSION >= 50003) { 527 echo $spaces . ' <div class="item">' . "\n" 528 . $spaces . ' <label for="text_max_user_connections"><tt><dfn title="' . $GLOBALS['strPrivDescMaxUserConnections'] . '">MAX USER_CONNECTIONS</dfn></tt></label>' . "\n" 529 . $spaces . ' <input type="text" name="max_user_connections" id="text_max_user_connections" value="' . $row['max_user_connections'] . '" size="11" maxlength="11" title="' . $GLOBALS['strPrivDescMaxUserConnections'] . '" />' . "\n" 530 . $spaces . ' </div>' . "\n"; 531 } 532 echo $spaces . ' </fieldset>' . "\n"; 533 } 534 // for Safari 2.0.2 535 echo $spaces . ' <div class="clearfloat"></div>' . "\n"; 536 } 537 echo $spaces . '</fieldset>' . "\n"; 538 if ($submit) { 539 echo $spaces . '<fieldset id="fieldset_user_privtable_footer" class="tblFooters">' . "\n" 540 . $spaces . ' <input type="submit" name="update_privs" value="' . $GLOBALS['strGo'] . '" />' . "\n" 541 . $spaces . '</fieldset>' . "\n"; 542 } 543 } // end of the 'PMA_displayPrivTable()' function 544 545 546 /** 547 * Displays the fields used by the "new user" form as well as the 548 * "change login information / copy user" form. 549 * 550 * @param string $mode are we creating a new user or are we just 551 * changing one? (allowed values: 'new', 'change') 552 * @param int $indent the indenting level of the code 553 * 554 * @global array $cfg the phpMyAdmin configuration 555 * @global ressource $user_link the database connection 556 * 557 * @return void 558 */ 559 function PMA_displayLoginInformationFields($mode = 'new', $indent = 0 ) { 560 $spaces = str_repeat( ' ', $indent); 561 562 // Get user/host name lengths 563 $fields_info = PMA_DBI_get_fields('mysql', 'user'); 564 $username_length = 16; 565 $hostname_length = 41; 566 foreach ($fields_info as $key => $val) { 567 if ($val['Field'] == 'User') { 568 strtok($val['Type'], '()'); 569 $v = strtok('()'); 570 if (is_int($v)) { 571 $username_length = $v; 572 } 573 } elseif ($val['Field'] == 'Host') { 574 strtok($val['Type'], '()'); 575 $v = strtok('()'); 576 if (is_int($v)) { 577 $hostname_length = $v; 578 } 579 } 580 } 581 unset($fields_info); 582 583 if ( isset( $GLOBALS['username'] ) && strlen( $GLOBALS['username'] ) === 0 ) { 584 $GLOBALS['pred_username'] = 'any'; 585 } 586 echo $spaces . '<fieldset id="fieldset_add_user_login">' . "\n" 587 . $spaces . '<legend>' . $GLOBALS['strLoginInformation'] . '</legend>' . "\n" 588 . $spaces . '<div class="item">' . "\n" 589 . $spaces . '<label for="select_pred_username">' . "\n" 590 . $spaces . ' ' . $GLOBALS['strUserName'] . ':' . "\n" 591 . $spaces . '</label>' . "\n" 592 . $spaces . '<span class="options">' . "\n" 593 . $spaces . ' <select name="pred_username" id="select_pred_username" title="' . $GLOBALS['strUserName'] . '"' . "\n" 594 . $spaces . ' onchange="if (this.value == \'any\') { username.value = \'\'; } else if (this.value == \'userdefined\') { username.focus(); username.select(); }">' . "\n" 595 . $spaces . ' <option value="any"' . ((isset($GLOBALS['pred_username']) && $GLOBALS['pred_username'] == 'any') ? ' selected="selected"' : '') . '>' . $GLOBALS['strAnyUser'] . '</option>' . "\n" 596 . $spaces . ' <option value="userdefined"' . ((!isset($GLOBALS['pred_username']) || $GLOBALS['pred_username'] == 'userdefined') ? ' selected="selected"' : '') . '>' . $GLOBALS['strUseTextField'] . ':</option>' . "\n" 597 . $spaces . ' </select>' . "\n" 598 . $spaces . '</span>' . "\n" 599 . $spaces . '<input type="text" name="username" maxlength="' . $username_length . '" title="' . $GLOBALS['strUserName'] . '"' . (empty($GLOBALS['username']) ? '' : ' value="' . (isset($GLOBALS['new_username']) ? $GLOBALS['new_username'] : $GLOBALS['username']) . '"') . ' onchange="pred_username.value = \'userdefined\';" />' . "\n" 600 . $spaces . '</div>' . "\n" 601 . $spaces . '<div class="item">' . "\n" 602 . $spaces . '<label for="select_pred_hostname">' . "\n" 603 . $spaces . ' ' . $GLOBALS['strHost'] . ':' . "\n" 604 . $spaces . '</label>' . "\n" 605 . $spaces . '<span class="options">' . "\n" 606 . $spaces . ' <select name="pred_hostname" id="select_pred_hostname" title="' . $GLOBALS['strHost'] . '"' . "\n"; 607 $res = PMA_DBI_query('SELECT USER();'); 608 $row = PMA_DBI_fetch_row($res); 609 PMA_DBI_free_result($res); 610 unset($res); 611 if (!empty($row[0])) { 612 $thishost = str_replace("'", '', substr($row[0], (strrpos($row[0], '@') + 1))); 613 if ($thishost == 'localhost' || $thishost == '127.0.0.1') { 614 unset($thishost); 615 } 616 } 617 echo $spaces . ' onchange="if (this.value == \'any\') { hostname.value = \'%\'; } else if (this.value == \'localhost\') { hostname.value = \'localhost\'; } ' 618 . (empty($thishost) ? '' : 'else if (this.value == \'thishost\') { hostname.value = \'' . addslashes(htmlspecialchars($thishost)) . '\'; } ') 619 . 'else if (this.value == \'hosttable\') { hostname.value = \'\'; } else if (this.value == \'userdefined\') { hostname.focus(); hostname.select(); }">' . "\n"; 620 unset($row); 621 622 // when we start editing a user, $GLOBALS['pred_hostname'] is not defined 623 if (!isset($GLOBALS['pred_hostname']) && isset($GLOBALS['hostname'])) { 624 switch (strtolower($GLOBALS['hostname'])) { 625 case 'localhost': 626 case '127.0.0.1': 627 $GLOBALS['pred_hostname'] = 'localhost'; 628 break; 629 case '%': 630 $GLOBALS['pred_hostname'] = 'any'; 631 break; 632 default: 633 $GLOBALS['pred_hostname'] = 'userdefined'; 634 break; 635 } 636 } 637 echo $spaces . ' <option value="any"' . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'any') ? ' selected="selected"' : '') . '>' . $GLOBALS['strAnyHost'] . '</option>' . "\n" 638 . $spaces . ' <option value="localhost"' . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'localhost') ? ' selected="selected"' : '') . '>' . $GLOBALS['strLocalhost'] . '</option>' . "\n"; 639 if (!empty($thishost)) { 640 echo $spaces . ' <option value="thishost"' . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'thishost') ? ' selected="selected"' : '') . '>' . $GLOBALS['strThisHost'] . '</option>' . "\n"; 641 } 642 unset($thishost); 643 echo $spaces . ' <option value="hosttable"' . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'hosttable') ? ' selected="selected"' : '') . '>' . $GLOBALS['strUseHostTable'] . '</option>' . "\n" 644 . $spaces . ' <option value="userdefined"' . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'userdefined') ? ' selected="selected"' : '') . '>' . $GLOBALS['strUseTextField'] . ':</option>' . "\n" 645 . $spaces . ' </select>' . "\n" 646 . $spaces . '</span>' . "\n" 647 . $spaces . '<input type="text" name="hostname" maxlength="' . $hostname_length . '" value="' . ( isset($GLOBALS['hostname']) ? $GLOBALS['hostname'] : '' ) . '" title="' . $GLOBALS['strHost'] . '" onchange="pred_hostname.value = \'userdefined\';" />' . "\n" 648 . $spaces . '</div>' . "\n" 649 . $spaces . '<div class="item">' . "\n" 650 . $spaces . '<label for="select_pred_password">' . "\n" 651 . $spaces . ' ' . $GLOBALS['strPassword'] . ':' . "\n" 652 . $spaces . '</label>' . "\n" 653 . $spaces . '<span class="options">' . "\n" 654 . $spaces . ' <select name="pred_password" id="select_pred_password" title="' . $GLOBALS['strPassword'] . '"' . "\n" 655 . $spaces . ' onchange="if (this.value == \'none\') { pma_pw.value = \'\'; pma_pw2.value = \'\'; } else if (this.value == \'userdefined\') { pma_pw.focus(); pma_pw.select(); }">' . "\n" 656 . ($mode == 'change' ? $spaces . ' <option value="keep" selected="selected">' . $GLOBALS['strKeepPass'] . '</option>' . "\n" : '') 657 . $spaces . ' <option value="none"'; 658 if ( isset( $GLOBALS['username'] ) && $mode != 'change' ) { 659 echo ' selected="selected"'; 660 } 661 echo $spaces . '>' . $GLOBALS['strNoPassword'] . '</option>' . "\n" 662 . $spaces . ' <option value="userdefined"' . ( isset( $GLOBALS['username'] ) ? '' : ' selected="selected"') . '>' . $GLOBALS['strUseTextField'] . ':</option>' . "\n" 663 . $spaces . ' </select>' . "\n" 664 . $spaces . '</span>' . "\n" 665 . $spaces . '<input type="password" id="text_pma_pw" name="pma_pw" title="' . $GLOBALS['strPassword'] . '" onchange="pred_password.value = \'userdefined\';" />' . "\n" 666 . $spaces . '</div>' . "\n" 667 . $spaces . '<div class="item">' . "\n" 668 . $spaces . '<label for="text_pma_pw2">' . "\n" 669 . $spaces . ' ' . $GLOBALS['strReType'] . ':' . "\n" 670 . $spaces . '</label>' . "\n" 671 . $spaces . '<span class="options"> </span>' . "\n" 672 . $spaces . '<input type="password" name="pma_pw2" id="text_pma_pw2" title="' . $GLOBALS['strReType'] . '" onchange="pred_password.value = \'userdefined\';" />' . "\n" 673 . $spaces . '</div>' . "\n" 674 . $spaces . '<div class="item">' . "\n" 675 . $spaces . '<label for="button_generate_password">' . "\n" 676 . $spaces . ' ' . $GLOBALS['strGeneratePassword'] . ':' . "\n" 677 . $spaces . '</label>' . "\n" 678 . $spaces . '<span class="options">' . "\n" 679 . $spaces . ' <input type="button" id="button_generate_password" value="' . $GLOBALS['strGenerate'] . '" onclick="suggestPassword()" />' . "\n" 680 . $spaces . ' <input type="button" id="button_copy_password" value="' . $GLOBALS['strCopy'] . '" onclick="suggestPasswordCopy(this.form)" />' . "\n" 681 . $spaces . '</span>' . "\n" 682 . $spaces . '<input type="text" name="generated_pw" id="generated_pw" />' . "\n" 683 . $spaces . '</div>' . "\n" 684 . $spaces . '</fieldset>' . "\n"; 685 } // end of the 'PMA_displayUserAndHostFields()' function 686 687 688 /** 689 * Changes / copies a user, part I 690 */ 691 if (!empty($change_copy)) { 692 $user_host_condition = 693 ' WHERE ' . PMA_convert_using('User') 694 .' = ' . PMA_convert_using(PMA_sqlAddslashes($old_username), 'quoted') 695 .' AND ' . PMA_convert_using('Host') 696 .' = ' . PMA_convert_using($old_hostname, 'quoted') . ';'; 697 $res = PMA_DBI_query('SELECT * FROM `mysql`.`user` ' . $user_host_condition); 698 if (!$res) { 699 $message = $GLOBALS['strNoUsersFound']; 700 unset($change_copy); 701 } else { 702 $row = PMA_DBI_fetch_assoc($res); 703 extract($row, EXTR_OVERWRITE); 704 // Recent MySQL versions have the field "Password" in mysql.user, 705 // so the previous extract creates $Password but this script 706 // uses $password 707 if (!isset($password) && isset($Password)) { 708 $password=$Password; 709 } 710 PMA_DBI_free_result($res); 711 $queries = array(); 712 } 713 } 714 715 716 /** 717 * Adds a user 718 * (Changes / copies a user, part II) 719 */ 720 if (!empty($adduser_submit) || !empty($change_copy)) { 721 unset($sql_query); 722 if ($pred_username == 'any') { 723 $username = ''; 724 } 725 switch ($pred_hostname) { 726 case 'any': 727 $hostname = '%'; 728 break; 729 case 'localhost': 730 $hostname = 'localhost'; 731 break; 732 case 'hosttable': 733 $hostname = ''; 734 break; 735 case 'thishost': 736 $res = PMA_DBI_query('SELECT USER();'); 737 $row = PMA_DBI_fetch_row($res); 738 PMA_DBI_free_result($res); 739 unset($res); 740 $hostname = substr($row[0], (strrpos($row[0], '@') + 1)); 741 unset($row); 742 break; 743 } 744 $res = PMA_DBI_query( 745 'SELECT \'foo\' FROM `mysql`.`user`' 746 .' WHERE ' . PMA_convert_using('User') 747 .' = ' . PMA_convert_using(PMA_sqlAddslashes($username), 'quoted') 748 .' AND ' . PMA_convert_using('Host') 749 .' = ' . PMA_convert_using($hostname, 'quoted') . ';', 750 null, PMA_DBI_QUERY_STORE); 751 if (PMA_DBI_num_rows($res) == 1) { 752 PMA_DBI_free_result($res); 753 $message = sprintf($GLOBALS['strUserAlreadyExists'], '[i]\'' . $username . '\'@\'' . $hostname . '\'[/i]'); 754 $adduser = 1; 755 } else { 756 PMA_DBI_free_result($res); 757 758 if (50002 <= PMA_MYSQL_INT_VERSION) { 759 // MySQL 5 requires CREATE USER before any GRANT on this user can done 760 $create_user_real = 'CREATE USER \'' . PMA_sqlAddslashes($username) . '\'@\'' . $hostname . '\''; 761 } 762 763 $real_sql_query = 764 'GRANT ' . join(', ', PMA_extractPrivInfo()) . ' ON *.* TO \'' 765 . PMA_sqlAddslashes($username) . '\'@\'' . $hostname . '\''; 766 if ($pred_password != 'none' && $pred_password != 'keep') { 767 $pma_pw_hidden = str_repeat('*', strlen($pma_pw)); 768 $sql_query = $real_sql_query . ' IDENTIFIED BY \'' . $pma_pw_hidden . '\''; 769 $real_sql_query .= ' IDENTIFIED BY \'' . PMA_sqlAddslashes($pma_pw) . '\''; 770 if ( isset( $create_user_real ) ) { 771 $create_user_show = $create_user_real . ' IDENTIFIED BY \'' . $pma_pw_hidden . '\''; 772 $create_user_real .= ' IDENTIFIED BY \'' . PMA_sqlAddslashes($pma_pw) . '\''; 773 } 774 } else { 775 if ($pred_password == 'keep' && !empty($password)) { 776 $real_sql_query .= ' IDENTIFIED BY PASSWORD \'' . $password . '\''; 777 if ( isset( $create_user_real ) ) { 778 $create_user_real .= ' IDENTIFIED BY PASSWORD \'' . $password . '\''; 779 } 780 } 781 $sql_query = $real_sql_query; 782 if ( isset( $create_user_real ) ) { 783 $create_user_show = $create_user_real; 784 } 785 } 786 /** 787 * @todo similar code appears twice in this script 788 */ 789 if ((isset($Grant_priv) && $Grant_priv == 'Y') || (PMA_MYSQL_INT_VERSION >= 40002 && (isset($max_questions) || isset($max_connections) || isset($max_updates) || isset($max_user_connections)))) { 790 $real_sql_query .= 'WITH'; 791 $sql_query .= 'WITH'; 792 if (isset($Grant_priv) && $Grant_priv == 'Y') { 793 $real_sql_query .= ' GRANT OPTION'; 794 $sql_query .= ' GRANT OPTION'; 795 } 796 if (PMA_MYSQL_INT_VERSION >= 40002) { 797 if (isset($max_questions)) { 798 // avoid negative values 799 $max_questions = max(0, (int)$max_questions); 800 $real_sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions; 801 $sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions; 802 } 803 if (isset($max_connections)) { 804 $max_connections = max(0, (int)$max_connections); 805 $real_sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections; 806 $sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections; 807 } 808 if (isset($max_updates)) { 809 $max_updates = max(0, (int)$max_updates); 810 $real_sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates; 811 $sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates; 812 } 813 } 814 if (PMA_MYSQL_INT_VERSION >= 50003) { 815 if (isset($max_user_connections)) { 816 $max_user_connections = max(0, (int)$max_user_connections); 817 $real_sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections; 818 $sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections; 819 } 820 } 821 } 822 if ( isset( $create_user_real ) ) { 823 $create_user_real .= ';'; 824 $create_user_show .= ';'; 825 } 826 $real_sql_query .= ';'; 827 $sql_query .= ';'; 828 if (empty($change_copy)) { 829 if ( isset( $create_user_real ) ) { 830 PMA_DBI_try_query($create_user_real) or PMA_mysqlDie(PMA_DBI_getError(), $create_user_show); 831 $sql_query = $create_user_show . $sql_query; 832 } 833 PMA_DBI_try_query($real_sql_query) or PMA_mysqlDie(PMA_DBI_getError(), $sql_query); 834 $message = $GLOBALS['strAddUserMessage']; 835 836 /* Create database for new user */ 837 if (isset($createdb) && $createdb > 0) { 838 if ($createdb == 1) { 839 $q = 'CREATE DATABASE IF NOT EXISTS ' . PMA_backquote(PMA_sqlAddslashes($username)) . ';'; 840 $sql_query .= $q; 841 PMA_DBI_try_query($q) or PMA_mysqlDie(PMA_DBI_getError(), $sql_query); 842 $GLOBALS['reload'] = TRUE; 843 PMA_reloadNavigation(); 844 845 $q = 'GRANT ALL PRIVILEGES ON ' . PMA_backquote(PMA_sqlAddslashes($username)) . '.* TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . $hostname . '\';'; 846 $sql_query .= $q; 847 PMA_DBI_try_query($q) or PMA_mysqlDie(PMA_DBI_getError(), $sql_query); 848 } elseif ($createdb == 2) { 849 $q = 'GRANT ALL PRIVILEGES ON ' . PMA_backquote(PMA_sqlAddslashes($username) . '\_%') . '.* TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . $hostname . '\';'; 850 $sql_query .= $q; 851 PMA_DBI_try_query($q) or PMA_mysqlDie(PMA_DBI_getError(), $sql_query); 852 } 853 } 854 } else { 855 if ( isset( $create_user_real ) ) { 856 $queries[] = $create_user_real; 857 } 858 $queries[] = $real_sql_query; 859 // we put the query containing the hidden password in 860 // $queries_for_display, at the same position occupied 861 // by the real query in $queries 862 $tmp_count = count($queries); 863 if ( isset( $create_user_real ) ) { 864 $queries_for_display[$tmp_count - 2] = $create_user_show; 865 } 866 $queries_for_display[$tmp_count - 1] = $sql_query; 867 } 868 unset($res, $real_sql_query); 869 } 870 } 871 872 873 /** 874 * Changes / copies a user, part III 875 */ 876 if (!empty($change_copy)) { 877 $user_host_condition = 878 ' WHERE ' . PMA_convert_using('User') 879 .' = ' . PMA_convert_using(PMA_sqlAddslashes($old_username), 'quoted') 880 .' AND ' . PMA_convert_using('Host') 881 .' = ' . PMA_convert_using($old_hostname, 'quoted') . ';'; 882 $res = PMA_DBI_query('SELECT * FROM `mysql`.`db`' . $user_host_condition ); 883 while ($row = PMA_DBI_fetch_assoc($res)) { 884 $queries[] = 885 'GRANT ' . join(', ', PMA_extractPrivInfo($row)) 886 .' ON `' . $row['Db'] . '`.*' 887 .' TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . $hostname . '\'' 888 . ( $row['Grant_priv'] == 'Y' ? ' WITH GRANT OPTION;' : ';' ); 889 } 890 PMA_DBI_free_result($res); 891 $res = PMA_DBI_query( 892 'SELECT `Db`, `Table_name`, `Table_priv`' 893 .' FROM `mysql`.`tables_priv`' . $user_host_condition, 894 $GLOBALS['userlink'], PMA_DBI_QUERY_STORE ); 895 while ($row = PMA_DBI_fetch_assoc($res)) { 896 897 $res2 = PMA_DBI_QUERY( 898 'SELECT `Column_name`, `Column_priv`' 899 .' FROM `mysql`.`columns_priv`' 900 .' WHERE ' . PMA_convert_using('User') 901 .' = ' . PMA_convert_using(PMA_sqlAddslashes($old_username), 'quoted') 902 .' AND ' . PMA_convert_using('`Host`') 903 .' = ' . PMA_convert_using($old_hostname, 'quoted') 904 .' AND ' . PMA_convert_using('`Db`') 905 .' = ' . PMA_convert_using($row['Db'], 'quoted') 906 .' AND ' . PMA_convert_using('`Table_name`') 907 .' = ' . PMA_convert_using($row['Table_name'], 'quoted') 908 .';', 909 null, PMA_DBI_QUERY_STORE); 910 911 $tmp_privs1 = PMA_extractPrivInfo($row); 912 $tmp_privs2 = array( 913 'Select' => array(), 914 'Insert' => array(), 915 'Update' => array(), 916 'References' => array() 917 ); 918 919 while ($row2 = PMA_DBI_fetch_assoc($res2)) { 920 $tmp_array = explode(',', $row2['Column_priv']); 921 if (in_array('Select', $tmp_array)) { 922 $tmp_privs2['Select'][] = $row2['Column_name']; 923 } 924 if (in_array('Insert', $tmp_array)) { 925 $tmp_privs2['Insert'][] = $row2['Column_name']; 926 } 927 if (in_array('Update', $tmp_array)) { 928 $tmp_privs2['Update'][] = $row2['Column_name']; 929 } 930 if (in_array('References', $tmp_array)) { 931 $tmp_privs2['References'][] = $row2['Column_name']; 932 } 933 unset($tmp_array); 934 } 935 if (count($tmp_privs2['Select']) > 0 && !in_array('SELECT', $tmp_privs1)) { 936 $tmp_privs1[] = 'SELECT (`' . join('`, `', $tmp_privs2['Select']) . '`)'; 937 } 938 if (count($tmp_privs2['Insert']) > 0 && !in_array('INSERT', $tmp_privs1)) { 939 $tmp_privs1[] = 'INSERT (`' . join('`, `', $tmp_privs2['Insert']) . '`)'; 940 } 941 if (count($tmp_privs2['Update']) > 0 && !in_array('UPDATE', $tmp_privs1)) { 942 $tmp_privs1[] = 'UPDATE (`' . join('`, `', $tmp_privs2['Update']) . '`)'; 943 } 944 if (count($tmp_privs2['References']) > 0 && !in_array('REFERENCES', $tmp_privs1)) { 945 $tmp_privs1[] = 'REFERENCES (`' . join('`, `', $tmp_privs2['References']) . '`)'; 946 } 947 unset($tmp_privs2); 948 $queries[] = 949 'GRANT ' . join(', ', $tmp_privs1) 950 . ' ON `' . $row['Db'] . '`.`' . $row['Table_name'] 951 . '` TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . $hostname . '\'' 952 . (in_array('Grant', explode(',', $row['Table_priv'])) ? ' WITH GRANT OPTION;' : ';'); 953 } 954 } 955 956 957 /** 958 * Updates privileges 959 */ 960 if (!empty($update_privs)) { 961 // escaping a wildcard character in a GRANT is only accepted at the global 962 // or database level, not at table level; this is why I remove 963 // the escaping character 964 // Note: in the phpMyAdmin list of Database-specific privileges, 965 // we will have for example 966 // test\_db SELECT (this one is for privileges on a db level) 967 // test_db USAGE (this one is for table-specific privileges) 968 // 969 // It looks curious but reflects the way MySQL works 970 971 if (! isset($dbname) || ! strlen($dbname)) { 972 $db_and_table = '*.*'; 973 } else { 974 if ( isset( $tablename ) && strlen($tablename) ) { 975 $db_and_table = PMA_backquote( PMA_unescape_mysql_wildcards( $dbname ) ) . '.'; 976 $db_and_table .= PMA_backquote( $tablename ); 977 } else { 978 $db_and_table = PMA_backquote( $dbname ) . '.'; 979 $db_and_table .= '*'; 980 } 981 } 982 983 $sql_query0 = 984 'REVOKE ALL PRIVILEGES ON ' . $db_and_table 985 . ' FROM \'' . PMA_sqlAddslashes($username) . '\'@\'' . $hostname . '\';'; 986 if (!isset($Grant_priv) || $Grant_priv != 'Y') { 987 $sql_query1 = 988 'REVOKE GRANT OPTION ON ' . $db_and_table 989 . ' FROM \'' . PMA_sqlAddslashes($username) . '\'@\'' . $hostname . '\';'; 990 } 991 $sql_query2 = 992 'GRANT ' . join(', ', PMA_extractPrivInfo()) 993 . ' ON ' . $db_and_table 994 . ' TO \'' . PMA_sqlAddslashes($username) . '\'@\'' . $hostname . '\''; 995 996 /** 997 * @todo similar code appears twice in this script 998 */ 999 if ( ( isset($Grant_priv) && $Grant_priv == 'Y') 1000 || ( ( ! isset($dbname) || ! strlen($dbname) ) && PMA_MYSQL_INT_VERSION >= 40002 1001 && ( isset($max_questions) || isset($max_connections) 1002 || isset($max_updates) || isset($max_user_connections)))) 1003 { 1004 $sql_query2 .= 'WITH'; 1005 if (isset($Grant_priv) && $Grant_priv == 'Y') { 1006 $sql_query2 .= ' GRANT OPTION'; 1007 } 1008 if (PMA_MYSQL_INT_VERSION >= 40002) { 1009 if (isset($max_questions)) { 1010 $max_questions = max(0, (int)$max_questions); 1011 $sql_query2 .= ' MAX_QUERIES_PER_HOUR ' . $max_questions; 1012 } 1013 if (isset($max_connections)) { 1014 $max_connections = max(0, (int)$max_connections); 1015 $sql_query2 .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections; 1016 } 1017 if (isset($max_updates)) { 1018 $max_updates = max(0, (int)$max_updates); 1019 $sql_query2 .= ' MAX_UPDATES_PER_HOUR ' . $max_updates; 1020 } 1021 } 1022 if (PMA_MYSQL_INT_VERSION >= 50003) { 1023 if (isset($max_user_connections)) { 1024 $max_user_connections = max(0, (int)$max_user_connections); 1025 $sql_query2 .= ' MAX_USER_CONNECTIONS ' . $max_user_connections; 1026 } 1027 } 1028 } 1029 $sql_query2 .= ';'; 1030 if (!PMA_DBI_try_query($sql_query0)) { // this query may fail, but this does not matter :o) 1031 // a case when it can fail is when the admin does not have all 1032 // privileges: he can't do a REVOKE ALL PRIVILEGES ! 1033 // so at least we display the error 1034 echo PMA_DBI_getError(); 1035 unset($sql_query0); 1036 } 1037 if (isset($sql_query1) && !PMA_DBI_try_query($sql_query1)) { // this one may fail, too... 1038 unset($sql_query1); 1039 } 1040 PMA_DBI_query($sql_query2); 1041 $sql_query = (isset($sql_query0) ? $sql_query0 . ' ' : '') 1042 . (isset($sql_query1) ? $sql_query1 . ' ' : '') 1043 . $sql_query2; 1044 $message = sprintf($GLOBALS['strUpdatePrivMessage'], '\'' . $username . '\'@\'' . $hostname . '\''); 1045 } 1046 1047 1048 /** 1049 * Revokes Privileges 1050 */ 1051 if (!empty($revokeall)) { 1052 1053 if ( ! isset($dbname) || ! strlen($dbname) ) { 1054 $db_and_table = '*.*'; 1055 } else { 1056 if ( ! isset( $tablename ) || ! strlen($tablename) ) { 1057 $db_and_table = PMA_backquote( $dbname ) . '.'; 1058 $db_and_table .= '*'; 1059 } else { 1060 $db_and_table = PMA_backquote( PMA_unescape_mysql_wildcards( $dbname ) ) . '.'; 1061 $db_and_table .= PMA_backquote( $tablename ); 1062 } 1063 } 1064 1065 $sql_query0 = 1066 'REVOKE ALL PRIVILEGES ON ' . $db_and_table 1067 . ' FROM \'' . $username . '\'@\'' . $hostname . '\';'; 1068 $sql_query1 = 1069 'REVOKE GRANT OPTION ON ' . $db_and_table 1070 . ' FROM \'' . $username . '\'@\'' . $hostname . '\';'; 1071 PMA_DBI_query($sql_query0); 1072 if (!PMA_DBI_try_query($sql_query1)) { // this one may fail, too... 1073 unset($sql_query1); 1074 } 1075 $sql_query = $sql_query0 . (isset($sql_query1) ? ' ' . $sql_query1 : ''); 1076 $message = sprintf($GLOBALS['strRevokeMessage'], '\'' . $username . '\'@\'' . $hostname . '\''); 1077 if ( ! isset($tablename) || ! strlen($tablename) ) { 1078 unset($dbname); 1079 } else { 1080 unset($tablename); 1081 } 1082 } 1083 1084 1085 /** 1086 * Updates the password 1087 */ 1088 if (!empty($change_pw)) { 1089 if ($nopass == 1) { 1090 $sql_query = 'SET PASSWORD FOR \'' . $username . '\'@\'' . $hostname . '\' = \'\';'; 1091 PMA_DBI_query($sql_query); 1092 $message = sprintf($GLOBALS['strPasswordChanged'], '\'' . $username . '\'@\'' . $hostname . '\''); 1093 } elseif (empty($pma_pw) || empty($pma_pw2)) { 1094 $message = $GLOBALS['strPasswordEmpty']; 1095 } elseif ($pma_pw != $pma_pw2) { 1096 $message = $GLOBALS['strPasswordNotSame']; 1097 } else { 1098 $hidden_pw = ''; 1099 for ($i = 0; $i < strlen($pma_pw); $i++) { 1100 $hidden_pw .= '*'; 1101 } 1102 $local_query = 'SET PASSWORD FOR \'' . PMA_sqlAddslashes($username) . '\'@\'' . $hostname . '\' = PASSWORD(\'' . PMA_sqlAddslashes($pma_pw) . '\')'; 1103 $sql_query = 'SET PASSWORD FOR \'' . PMA_sqlAddslashes($username) . '\'@\'' . $hostname . '\' = PASSWORD(\'' . $hidden_pw . '\')'; 1104 PMA_DBI_try_query($local_query) or PMA_mysqlDie(PMA_DBI_getError(), $sql_query); 1105 $message = sprintf($GLOBALS['strPasswordChanged'], '\'' . $username . '\'@\'' . $hostname . '\''); 1106 } 1107 } 1108 1109 1110 /** 1111 * Deletes users 1112 * (Changes / copies a user, part IV) 1113 */ 1114 $user_host_separator = chr(27); 1115 1116 if (!empty($delete) || (!empty($change_copy) && $mode < 4)) { 1117 if (!empty($change_copy)) { 1118 $selected_usr = array($old_username . $user_host_separator . $old_hostname); 1119 } else { 1120 $queries = array(); 1121 } 1122 for ($i = 0; isset($selected_usr[$i]); $i++) { 1123 list($this_user, $this_host) = explode($user_host_separator, $selected_usr[$i]); 1124 $queries[] = '# ' . sprintf($GLOBALS['strDeleting'], '\'' . $this_user . '\'@\'' . $this_host . '\'') . ' ...'; 1125 if ( PMA_MYSQL_INT_VERSION >= 50002 ) { 1126 $queries[] = 'DROP USER \'' . PMA_sqlAddslashes($this_user) . '\'@\'' . $this_host . '\';'; 1127 } else { 1128 if ($mode == 2) { 1129 // The SHOW GRANTS query may fail if the user has not been loaded 1130 // into memory 1131 $res = PMA_DBI_try_query('SHOW GRANTS FOR \'' . PMA_sqlAddslashes($this_user) . '\'@\'' . $this_host . '\';'); 1132 if ($res) { 1133 $queries[] = 'REVOKE ALL PRIVILEGES ON *.* FROM \'' . PMA_sqlAddslashes($this_user) . '\'@\'' . $this_host . '\';'; 1134 while ($row = PMA_DBI_fetch_row($res)) { 1135 $this_table = substr($row[0], (strpos($row[0], 'ON') + 3), (strpos($row[0], ' TO ') - strpos($row[0], 'ON') - 3)); 1136 if ($this_table != '*.*') { 1137 $queries[] = 'REVOKE ALL PRIVILEGES ON ' . $this_table . ' FROM \'' . PMA_sqlAddslashes($this_user) . '\'@\'' . $this_host . '\';'; 1138 1139 if (strpos($row[0], 'WITH GRANT OPTION')) { 1140 $queries[] = 'REVOKE GRANT OPTION ON ' . $this_table . ' FROM \'' . PMA_sqlAddslashes($this_user) . '\'@\'' . $this_host . '\';'; 1141 } 1142 } 1143 unset($this_table); 1144 } 1145 PMA_DBI_free_result($res); 1146 } 1147 unset($res); 1148 } 1149 if ( PMA_MYSQL_INT_VERSION >= 40101 ) { 1150 if (PMA_MYSQL_INT_VERSION < 50002) { 1151 $queries[] = 'REVOKE GRANT OPTION ON *.* FROM \'' . PMA_sqlAddslashes($this_user) . '\'@\'' . $this_host . '\';'; 1152 } 1153 $queries[] = 'DROP USER \'' . PMA_sqlAddslashes($this_user) . '\'@\'' . $this_host . '\';'; 1154 } else { 1155 $queries[] = 'DELETE FROM `mysql`.`user` WHERE ' . PMA_convert_using('User') . ' = ' . PMA_convert_using(PMA_sqlAddslashes($this_user), 'quoted') . ' AND ' . PMA_convert_using('Host') . ' = ' . PMA_convert_using($this_host, 'quoted') . ';'; 1156 } 1157 if ($mode != 2) { 1158 // If we REVOKE the table grants, we should not need to modify the 1159 // `mysql`.`db`, `mysql`.`tables_priv` and `mysql`.`columns_priv` tables manually... 1160 $user_host_condition = 1161 ' WHERE ' . PMA_convert_using('User') 1162 . ' = ' . PMA_convert_using(PMA_sqlAddslashes($this_user), 'quoted') 1163 . ' AND ' . PMA_convert_using('Host') 1164 . ' = ' . PMA_convert_using($this_host, 'quoted') . ';'; 1165 $queries[] = 'DELETE FROM `mysql`.`db`' . $user_host_condition; 1166 $queries[] = 'DELETE FROM `mysql`.`tables_priv`' . $user_host_condition; 1167 $queries[] = 'DELETE FROM `mysql`.`columns_priv`' . $user_host_condition; 1168 } 1169 } 1170 if (!empty($drop_users_db)) { 1171 $queries[] = 'DROP DATABASE IF EXISTS ' . PMA_backquote($this_user) . ';'; 1172 $GLOBALS['reload'] = TRUE; 1173 PMA_reloadNavigation(); 1174 } 1175 } 1176 if (empty($change_copy)) { 1177 if (empty($queries)) { 1178 $show_error_header = TRUE; 1179 $message = $GLOBALS['strDeleteNoUsersSelected']; 1180 } else { 1181 if ($mode == 3) { 1182 $queries[] = '# ' . $GLOBALS['strReloadingThePrivileges'] . ' ...'; 1183 $queries[] = 'FLUSH PRIVILEGES;'; 1184 } 1185 foreach ($queries as $sql_query) { 1186 if ($sql_query{0} != '#') { 1187 PMA_DBI_query($sql_query, $GLOBALS['userlink']); 1188 } 1189 } 1190 $sql_query = join("\n", $queries); 1191 $message = $GLOBALS['strUsersDeleted']; 1192 } 1193 unset($queries); 1194 } 1195 } 1196 1197 1198 /** 1199 * Changes / copies a user, part V 1200 */ 1201 if (!empty($change_copy)) { 1202 $tmp_count = 0; 1203 foreach ($queries as $sql_query) { 1204 if ($sql_query{0} != '#') { 1205 PMA_DBI_query($sql_query); 1206 } 1207 // when there is a query containing a hidden password, take it 1208 // instead of the real query sent 1209 if (isset($queries_for_display[$tmp_count])) { 1210 $queries[$tmp_count] = $queries_for_display[$tmp_count]; 1211 } 1212 $tmp_count++; 1213 } 1214 $message = $GLOBALS['strSuccess']; 1215 $sql_query = join("\n", $queries); 1216 } 1217 1218 1219 /** 1220 * Reloads the privilege tables into memory 1221 */ 1222 if (!empty($flush_privileges)) { 1223 $sql_query = 'FLUSH PRIVILEGES;'; 1224 PMA_DBI_query($sql_query); 1225 $message = $GLOBALS['strPrivilegesReloaded']; 1226 } 1227 1228 1229 /** 1230 * Displays the links 1231 */ 1232 if (isset($viewing_mode) && $viewing_mode == 'db') { 1233 $db = $checkprivs; 1234 $url_query .= '&goto=db_operations.php'; 1235 1236 // Gets the database structure 1237 $sub_part = '_structure'; 1238 require ('./libraries/db_info.inc.php'); 1239 echo "\n"; 1240 } else { 1241 require ('./libraries/server_links.inc.php'); 1242 } 1243 1244 1245 /** 1246 * defines some standard links 1247 */ 1248 $link_edit = '<a href="server_privileges.php?' . $GLOBALS['url_query'] 1249 .'&username=%s' 1250 .'&hostname=%s' 1251 .'&dbname=%s' 1252 .'&tablename=%s">'; 1253 if ( $GLOBALS['cfg']['PropertiesIconic'] ) { 1254 $link_edit .= '<img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 'b_usredit.png" width="16" height="16" alt="' . $GLOBALS['strEditPrivileges'] . '" title="' . $GLOBALS['strEditPrivileges'] . '" />'; 1255 } else { 1256 $link_edit .= $GLOBALS['strEditPrivileges']; 1257 } 1258 $link_edit .= '</a>'; 1259 1260 $link_revoke = '<a href="server_privileges.php?' . $GLOBALS['url_query'] 1261 .'&username=%s' 1262 .'&hostname=%s' 1263 .'&dbname=%s' 1264 .'&tablename=%s' 1265 .'&revokeall=1">'; 1266 if ( $GLOBALS['cfg']['PropertiesIconic'] ) { 1267 $link_revoke .= '<img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 'b_usrdrop.png" width="16" height="16" alt="' . $GLOBALS['strRevoke'] . '" title="' . $GLOBALS['strRevoke'] . '" />'; 1268 } else { 1269 $link_revoke .= $GLOBALS['strRevoke']; 1270 } 1271 $link_revoke .= '</a>'; 1272 1273 /** 1274 * Displays the page 1275 */ 1276 if ( empty( $adduser ) && ( ! isset( $checkprivs ) || ! strlen($checkprivs) ) ) { 1277 if ( ! isset( $username ) ) { 1278 // No username is given --> display the overview 1279 echo '<h2>' . "\n" 1280 . ($GLOBALS['cfg']['MainPageIconic'] ? '<img class="icon" src="'. $GLOBALS['pmaThemeImage'] . 'b_usrlist.png" alt="" />' : '') 1281 . $GLOBALS['strUserOverview'] . "\n" 1282 . '</h2>' . "\n"; 1283 1284 $sql_query = 1285 'SELECT `User`,' . 1286 ' `Host`,' . 1287 ' IF(`Password` = ' . (PMA_MYSQL_INT_VERSION >= 40100 ? '_latin1 ' : '') . '\'\', \'N\', \'Y\') AS \'Password\',' . 1288 ' `Select_priv`,' . 1289 ' `Insert_priv`,' . 1290 ' `Update_priv`,' . 1291 ' `Delete_priv`,' . 1292 ' `Index_priv`,' . 1293 ' `Alter_priv`,' . 1294 ' `Create_priv`,' . 1295 ' `Drop_priv`,' . 1296 ' `Grant_priv`,' . 1297 ' `References_priv`,' . 1298 ' `Reload_priv`,' . 1299 ' `Shutdown_priv`,' . 1300 ' `Process_priv`,' . 1301 ' `File_priv`'; 1302 1303 if (PMA_MYSQL_INT_VERSION >= 40002) { 1304 $sql_query .= ', `Show_db_priv`, `Super_priv`, `Create_tmp_table_priv`, `Lock_tables_priv`, `Execute_priv`, `Repl_slave_priv`, `Repl_client_priv`'; 1305 } 1306 1307 if (PMA_MYSQL_INT_VERSION >= 50001) { 1308 $sql_query .= ', `Create_view_priv`, `Show_view_priv`'; 1309 } 1310 1311 if (PMA_MYSQL_INT_VERSION >= 50003) { 1312 $sql_query .= ', `Create_user_priv`, `Create_routine_priv`, `Alter_routine_priv`'; 1313 } 1314 1315 $sql_query .= ' FROM `mysql`.`user`'; 1316 1317 $sql_query .= (isset($initial) ? PMA_RangeOfUsers($initial) : ''); 1318 1319 $sql_query .= ' ORDER BY `User` ASC, `Host` ASC;'; 1320 $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE); 1321 1322 if (! $res) { 1323 // the query failed! This may have two reasons: 1324 // - the user does not have enough privileges 1325 // - the privilege tables use a structure of an earlier version. 1326 // so let's try a more simple query 1327 1328 $sql_query = 'SELECT * FROM `mysql`.`user`'; 1329 $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE); 1330 1331 if (!$res) { 1332 echo '<i>' . $GLOBALS['strNoPrivileges'] . '</i>' . "\n"; 1333 PMA_DBI_free_result($res); 1334 unset($res); 1335 } else { 1336 // rabus: This message is hardcoded because I will replace it by 1337 // a automatic repair feature soon. 1338 echo '<div class="warning">' . "\n" 1339 . ' Warning: Your privilege table structure seems to be older than this MySQL version!<br />' . "\n" 1340 . ' Please run the script <tt>mysql_fix_privilege_tables</tt> that should be included in your MySQL server distribution to solve this problem!' . "\n" 1341 . '</div><br />' . "\n"; 1342 } 1343 } else { 1344 1345 // we also want users not in table `user` but in other table 1346 $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;'); 1347 1348 $tables_to_search_for_users = array( 1349 'user', 'db', 'tables_priv', 'columns_priv', 'procs_priv', 1350 ); 1351 1352 $db_rights_sqls = array(); 1353 foreach ( $tables_to_search_for_users as $table_search_in ) { 1354 if ( in_array( $table_search_in, $tables ) ) { 1355 $db_rights_sqls[] = 'SELECT DISTINCT `User`, `Host` FROM `mysql`.`' . $table_search_in . '` ' . (isset($initial) ? PMA_RangeOfUsers($initial) : ''); 1356 } 1357 } 1358 1359 $user_defaults = array( 1360 'User' => '', 1361 'Host' => '%', 1362 'Password' => '?', 1363 'Grant_priv' => 'N', 1364 'privs' => array( 'USAGE' ), 1365 ); 1366 1367 // for all initials, even non A-Z 1368 $array_initials = array(); 1369 // for the rights 1370 $db_rights = array(); 1371 1372 // do not use UNION DISTINCT, as it's not allowed before 1373 // MySQL 4.0.17, and because "it does nothing" (cf manual) 1374 if ( PMA_MYSQL_INT_VERSION >= 40000 ) { 1375 $db_rights_sql = '(' . implode( ') UNION (', $db_rights_sqls ) . ')' 1376 .' ORDER BY `User` ASC, `Host` ASC'; 1377 1378 $db_rights_result = PMA_DBI_query( $db_rights_sql ); 1379 1380 while ( $db_rights_row = PMA_DBI_fetch_assoc( $db_rights_result ) ) { 1381 $db_rights_row = array_merge( $user_defaults, $db_rights_row ); 1382 $db_rights[$db_rights_row['User']][$db_rights_row['Host']] = 1383 $db_rights_row; 1384 } 1385 } else { 1386 foreach ( $db_rights_sqls as $db_rights_sql ) { 1387 $db_rights_result = PMA_DBI_query( $db_rights_sql ); 1388 1389 while ( $db_rights_row = PMA_DBI_fetch_assoc( $db_rights_result ) ) { 1390 $db_rights_row = array_merge( $user_defaults, $db_rights_row ); 1391 $db_rights[$db_rights_row['User']][$db_rights_row['Host']] = 1392 $db_rights_row; 1393 } 1394 } 1395 } 1396 PMA_DBI_free_result( $db_rights_result ); 1397 unset( $db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row ); 1398 ksort( $db_rights ); 1399 1400 /** 1401 * Displays the initials 1402 */ 1403 1404 // initialize to FALSE the letters A-Z 1405 for ($letter_counter = 1; $letter_counter < 27; $letter_counter++) { 1406 if ( ! isset( $array_initials[chr($letter_counter + 64)] ) ) { 1407 $array_initials[chr($letter_counter + 64)] = FALSE; 1408 } 1409 } 1410 1411 $initials = PMA_DBI_try_query('SELECT DISTINCT UPPER(LEFT(' . PMA_convert_using('User') . ',1)) FROM `user` ORDER BY `User` ASC', null, PMA_DBI_QUERY_STORE); 1412 while (list($tmp_initial) = PMA_DBI_fetch_row($initials)) { 1413 $array_initials[$tmp_initial] = TRUE; 1414 } 1415 1416 // Display the initials, which can be any characters, not 1417 // just letters. For letters A-Z, we add the non-used letters 1418 // as greyed out. 1419 1420 uksort( $array_initials, "strnatcasecmp" ); 1421 1422 echo '<table cellspacing="5"><tr>'; 1423 foreach ($array_initials as $tmp_initial => $initial_was_found) { 1424 if ($initial_was_found) { 1425 echo '<td><a href="server_privileges.php?' . $GLOBALS['url_query'] . '&initial=' . urlencode($tmp_initial) . '">' . $tmp_initial . '</a></td>' . "\n"; 1426 } else { 1427 echo '<td>' . $tmp_initial . '</td>'; 1428 } 1429 } 1430 echo '<td><a href="server_privileges.php?' . $GLOBALS['url_query'] . '&showall=1">[' . $GLOBALS['strShowAll'] . ']</a></td>' . "\n"; 1431 echo '</tr></table>'; 1432 1433 /** 1434 * Display the user overview 1435 * (if less than 50 users, display them immediately) 1436 */ 1437 1438 if (isset($initial) || isset($showall) || PMA_DBI_num_rows($res) < 50) { 1439 1440 while ( $row = PMA_DBI_fetch_assoc( $res ) ) { 1441 $row['privs'] = PMA_extractPrivInfo( $row, true ); 1442 $db_rights[$row['User']][$row['Host']] = $row; 1443 } 1444 @PMA_DBI_free_result( $res ); 1445 unset( $res ); 1446 1447 echo '<form name="usersForm" id="usersForm" action="server_privileges.php" method="post">' . "\n" 1448 . PMA_generate_common_hidden_inputs('', '', 1) 1449 . ' <table id="tableuserrights" class="data">' . "\n" 1450 . ' <thead>' . "\n" 1451 . ' <tr><td></td>' . "\n" 1452 . ' <th>' . $GLOBALS['strUser'] . '</th>' . "\n" 1453 . ' <th>' . $GLOBALS['strHost'] . '</th>' . "\n" 1454 . ' <th>' . $GLOBALS['strPassword'] . '</th>' . "\n" 1455 . ' <th>' . $GLOBALS['strGlobalPrivileges'] . ' ' 1456 . PMA_showHint( $GLOBALS['strEnglishPrivileges'] ) . '</th>' . "\n" 1457 . ' <th>' . $GLOBALS['strGrantOption'] . '</th>' . "\n" 1458 . ' ' . ($GLOBALS['cfg']['PropertiesIconic'] ? '<td></td>' : '<th>' . $GLOBALS['strAction'] . '</th>') . "\n"; 1459 echo ' </tr>' . "\n"; 1460 echo ' </thead>' . "\n"; 1461 echo ' <tbody>' . "\n"; 1462 $odd_row = true; 1463 $index_checkbox = -1; 1464 foreach ( $db_rights as $user ) { 1465 $index_checkbox++; 1466 ksort( $user ); 1467 foreach ( $user as $host ) { 1468 $index_checkbox++; 1469 echo ' <tr class="' . ( $odd_row ? 'odd' : 'even' ) . '">' . "\n" 1470 . ' <td><input type="checkbox" name="selected_usr[]" id="checkbox_sel_users_' . $index_checkbox . '" value="' . str_replace( chr(27), '', htmlentities($host['User'] . $user_host_separator . $host['Host'] ) ) . '"' . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"') . ' /></td>' . "\n" 1471 . ' <td><label for="checkbox_sel_users_' . $index_checkbox . '">' . (empty($host['User']) ? '<span style="color: #FF0000">' . $GLOBALS['strAny'] . '</span>' : htmlspecialchars($host['User'])) . '</label></td>' . "\n" 1472 . ' <td>' . htmlspecialchars($host['Host']) . '</td>' . "\n"; 1473 echo ' <td>'; 1474 switch ($host['Password']) { 1475 case 'Y': 1476 echo $GLOBALS['strYes']; 1477 break; 1478 case 'N': 1479 echo '<span style="color: #FF0000">' . $GLOBALS['strNo'] . '</span>'; 1480 break; 1481 // this happens if this is a definition not coming from mysql.user 1482 default: 1483 echo '--'; // in future version, replace by "not present" 1484 break; 1485 } // end switch 1486 echo '</td>' . "\n" 1487 . ' <td><tt>' . "\n" 1488 . ' ' . implode( ',' . "\n" . ' ', $host['privs'] ) . "\n" 1489 . ' </tt></td>' . "\n" 1490 . ' <td>' . ($host['Grant_priv'] == 'Y' ? $GLOBALS['strYes'] : $GLOBALS['strNo']) . '</td>' . "\n" 1491 . ' <td align="center">'; 1492 printf( $link_edit, urlencode( $host['User'] ), 1493 urlencode( $host['Host'] ), '', '' ); 1494 echo '</td>' . "\n" 1495 . ' </tr>' . "\n"; 1496 $odd_row = ! $odd_row; 1497 } 1498 } 1499 1500 unset( $user, $host, $odd_row ); 1501 echo ' </tbody></table>' . "\n" 1502 .'<img class="selectallarrow"' 1503 .' src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png"' 1504 .' width="38" height="22"' 1505 .' alt="' . $GLOBALS['strWithChecked'] . '" />' . "\n" 1506 .'<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&checkall=1"' 1507 .' onclick="if ( markAllRows(\'usersForm\') ) return false;">' 1508 . $GLOBALS['strCheckAll'] . '</a>' . "\n" 1509 .'/' . "\n" 1510 .'<a href="server_privileges.php?' . $GLOBALS['url_query'] . '"' 1511 .' onclick="if ( unMarkAllRows(\'usersForm\') ) return false;">' 1512 . $GLOBALS['strUncheckAll'] . '</a>' . "\n"; 1513 1514 // add/delete user fieldset 1515 echo ' <fieldset id="fieldset_add_user">' . "\n" 1516 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&adduser=1">' . "\n" 1517 . ($GLOBALS['cfg']['PropertiesIconic'] ? ' <img class="icon" src="' . $pmaThemeImage . 'b_usradd.png" width="16" height="16" alt="" />' . "\n" : '' ) 1518 . ' ' . $GLOBALS['strAddUser'] . '</a>' . "\n" 1519 . ' </fieldset>' . "\n" 1520 . ' <fieldset id="fieldset_delete_user">' 1521 . ' <legend>' . "\n" 1522 . ($GLOBALS['cfg']['PropertiesIconic'] ? ' <img class="icon" src="' . $pmaThemeImage . 'b_usrdrop.png" width="16" height="16" alt="" />' . "\n" : '' ) 1523 . ' ' . $GLOBALS['strRemoveSelectedUsers'] . '' . "\n" 1524 . ' </legend>' . "\n"; 1525 1526 // before MySQL 4.1.1, we offer some choices for the delete 1527 // mode, but for 4.1.1+, it will be done with REVOKEing the 1528 // privileges then a DROP USER (even no REVOKE at all 1529 // for MySQL 5), so no need to offer so many options 1530 if (PMA_MYSQL_INT_VERSION < 40101) { 1531 echo ' <input type="radio" title="' . $GLOBALS['strJustDelete'] . ' ' . $GLOBALS['strJustDeleteDescr'] . '" name="mode" id="radio_mode_1" value="1" checked="checked" />' . "\n" 1532 . ' <label for="radio_mode_1" title="' . $GLOBALS['strJustDelete'] . ' ' . $GLOBALS['strJustDeleteDescr'] . '">' . "\n" 1533 . ' ' . $GLOBALS['strJustDelete'] . "\n" 1534 . ' </label><br />' . "\n" 1535 . ' <input type="radio" title="' . $GLOBALS['strRevokeAndDelete'] . ' ' . $GLOBALS['strRevokeAndDeleteDescr'] . '" name="mode" id="radio_mode_2" value="2" />' . "\n" 1536 . ' <label for="radio_mode_2" title="' . $GLOBALS['strRevokeAndDelete'] . ' ' . $GLOBALS['strRevokeAndDeleteDescr'] . '">' . "\n" 1537 . ' ' . $GLOBALS['strRevokeAndDelete'] . "\n" 1538 . ' </label><br />' . "\n" 1539 . ' <input type="radio" title="' . $GLOBALS['strDeleteAndFlush'] . ' ' . $GLOBALS['strDeleteAndFlushDescr'] . '" name="mode" id="radio_mode_3" value="3" />' . "\n" 1540 . ' <label for="radio_mode_3" title="' . $GLOBALS['strDeleteAndFlush'] . ' ' . $GLOBALS['strDeleteAndFlushDescr'] . '">' . "\n" 1541 . ' ' . $GLOBALS['strDeleteAndFlush'] . "\n" 1542 . ' </label><br />' . "\n"; 1543 } else { 1544 echo ' <input type="hidden" name="mode" value="2" />' . "\n" 1545 . '( ' . $GLOBALS['strRevokeAndDelete'] . ' )<br />' . "\n"; 1546 } 1547 1548 echo ' <input type="checkbox" title="' . $GLOBALS['strDropUsersDb'] . '" name="drop_users_db" id="checkbox_drop_users_db" />' . "\n" 1549 . ' <label for="checkbox_drop_users_db" title="' . $GLOBALS['strDropUsersDb'] . '">' . "\n" 1550 . ' ' . $GLOBALS['strDropUsersDb'] . "\n" 1551 . ' </label>' . "\n" 1552 . ' </fieldset>' . "\n" 1553 . ' <fieldset id="fieldset_delete_user_footer" class="tblFooters">' . "\n" 1554 . ' <input type="submit" name="delete" value="' . $GLOBALS['strGo'] . '" id="buttonGo" />' . "\n" 1555 . ' </fieldset>' . "\n"; 1556 } else { 1557 1558 unset ($row); 1559 echo ' <fieldset id="fieldset_add_user">' . "\n" 1560 . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '&adduser=1">' . "\n" 1561 . ($GLOBALS['cfg']['PropertiesIconic'] ? ' <img class="icon" src="' . $pmaThemeImage . 'b_usradd.png" width="16" height="16" alt="" />' . "\n" : '' ) 1562 . ' ' . $GLOBALS['strAddUser'] . '</a>' . "\n" 1563 . ' </fieldset>' . "\n"; 1564 } // end if (display overview) 1565 echo '</form>' . "\n" 1566 . '<div class="warning">' . "\n" 1567 . ' ' . sprintf($GLOBALS['strFlushPrivilegesNote'], '<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&flush_privileges=1">', '</a>') . "\n" 1568 . '</div>' . "\n"; 1569 } 1570 1571 1572 } else { 1573 1574 // A user was selected -> display the user's properties 1575 1576 echo '<h2>' . "\n" 1577 . ($GLOBALS['cfg']['PropertiesIconic'] ? '<img class="icon" src="' . $pmaThemeImage . 'b_usredit.png" width="16" height="16" alt="" />' : '' ) 1578 . $GLOBALS['strUser'] . ' <i><a href="server_privileges.php?' . $GLOBALS['url_query'] . '&username=' . urlencode($username) . '&hostname=' . urlencode($hostname) . '">\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\'</a></i>' . "\n"; 1579 if ( isset( $dbname ) && strlen($dbname) ) { 1580 if ( $dbname_is_wildcard ) { 1581 echo ' - ' . $GLOBALS['strDatabases']; 1582 } else { 1583 echo ' - ' . $GLOBALS['strDatabase']; 1584 } 1585 $url_dbname = urlencode(str_replace('\_', '_', $dbname)); 1586 echo ' <i><a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?' . $GLOBALS['url_query'] . '&db=' . $url_dbname . '&reload=1">' . htmlspecialchars($dbname) . '</a></i>' . "\n"; 1587 if ( isset( $tablename ) && strlen($tablename) ) { 1588 echo ' - ' . $GLOBALS['strTable'] . ' <i><a href="' . $GLOBALS['cfg']['DefaultTabTable'] . '?' . $GLOBALS['url_query'] . '&db=' . $url_dbname . '&table=' . urlencode($tablename) . '&reload=1">' . htmlspecialchars($tablename) . '</a></i>' . "\n"; 1589 } 1590 unset($url_dbname); 1591 } 1592 echo ' : ' . $GLOBALS['strEditPrivileges'] . '</h2>' . "\n"; 1593 $res = PMA_DBI_query('SELECT \'foo\' FROM `mysql`.`user` WHERE ' . PMA_convert_using('User') . ' = ' . PMA_convert_using(PMA_sqlAddslashes($username), 'quoted') . ' AND ' . PMA_convert_using('Host') . ' = ' . PMA_convert_using($hostname, 'quoted') . ';', null, PMA_DBI_QUERY_STORE); 1594 $user_does_not_exists = (PMA_DBI_num_rows( $res ) < 1); 1595 PMA_DBI_free_result($res); 1596 unset($res); 1597 if ( $user_does_not_exists ) { 1598 echo $GLOBALS['strUserNotFound']; 1599 PMA_displayLoginInformationFields(); 1600 //require_once('./libraries/footer.inc.php'); 1601 } 1602 echo '<form name="usersForm" id="usersForm" action="server_privileges.php" method="post">' . "\n" 1603 . PMA_generate_common_hidden_inputs('', '', 3) 1604 . '<input type="hidden" name="username" value="' . htmlspecialchars($username) . '" />' . "\n" 1605 . '<input type="hidden" name="hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n"; 1606 if ( isset( $dbname ) && strlen($dbname) ) { 1607 echo '<input type="hidden" name="dbname" value="' . htmlspecialchars($dbname) . '" />' . "\n"; 1608 if ( isset( $tablename ) && strlen($tablename) ) { 1609 echo ' <input type="hidden" name="tablename" value="' . htmlspecialchars($tablename) . '" />' . "\n"; 1610 } 1611 } 1612 PMA_displayPrivTable((( ! isset( $dbname ) || ! strlen($dbname) ) ? '*' : $dbname), 1613 ((( ! isset( $dbname ) || ! strlen($dbname) ) || ( ! isset( $tablename ) || ! strlen($tablename) )) ? '*' : $tablename), 1614 TRUE, 3); 1615 echo '</form>' . "\n"; 1616 1617 if ( ( ! isset( $tablename ) || ! strlen($tablename) ) && empty( $dbname_is_wildcard ) ) { 1618 1619 // no table name was given, display all table specific rights 1620 // but only if $dbname contains no wildcards 1621 1622 // table header 1623 echo '<form action="server_privileges.php" method="post">' . "\n" 1624 . PMA_generate_common_hidden_inputs('', '', 6) 1625 . '<input type="hidden" name="username" value="' . htmlspecialchars($username) . '" />' . "\n" 1626 . '<input type="hidden" name="hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n" 1627 . '<fieldset>' . "\n" 1628 . '<legend>' . (( ! isset( $dbname ) || ! strlen($dbname) ) ? $GLOBALS['strDbPrivileges'] : $GLOBALS['strTblPrivileges']) . '</legend>' . "\n" 1629 . '<table class="data">' . "\n" 1630 . '<thead>' . "\n" 1631 . '<tr><th>' . (( ! isset( $dbname ) || ! strlen($dbname) ) ? $GLOBALS['strDatabase'] : $GLOBALS['strTable']) . '</th>' . "\n" 1632 . ' <th>' . $GLOBALS['strPrivileges'] . '</th>' . "\n" 1633 . ' <th>' . $GLOBALS['strGrantOption'] . '</th>' . "\n" 1634 . ' <th>' . (( ! isset( $dbname ) || ! strlen($dbname) ) ? $GLOBALS['strTblPrivileges'] : $GLOBALS['strColumnPrivileges']) . '</th>' . "\n" 1635 . ' <th colspan="2">' . $GLOBALS['strAction'] . '</th>' . "\n" 1636 . '</tr>' . "\n" 1637 . '</thead>' . "\n" 1638 . '<tbody>' . "\n"; 1639 1640 $user_host_condition = 1641 ' WHERE ' . PMA_convert_using('`User`') 1642 . ' = ' . PMA_convert_using(PMA_sqlAddslashes($username), 'quoted') 1643 . ' AND ' . PMA_convert_using('`Host`') 1644 . ' = ' . PMA_convert_using($hostname, 'quoted'); 1645 1646 // table body 1647 // get data 1648 1649 // we also want privielgs for this user not in table `db` but in other table 1650 $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;'); 1651 if ( ( ! isset( $dbname ) || ! strlen($dbname) ) ) { 1652 1653 // no db name given, so we want all privs for the given user 1654 1655 $tables_to_search_for_users = array( 1656 'tables_priv', 'columns_priv', 1657 ); 1658 1659 $db_rights_sqls = array(); 1660 foreach ( $tables_to_search_for_users as $table_search_in ) { 1661 if ( in_array( $table_search_in, $tables ) ) { 1662 $db_rights_sqls[] = ' 1663 SELECT DISTINCT `Db` 1664 FROM `mysql`.`' . $table_search_in . '` 1665 ' . $user_host_condition; 1666 } 1667 } 1668 1669 $user_defaults = array( 1670 'Db' => '', 1671 'Grant_priv' => 'N', 1672 'privs' => array( 'USAGE' ), 1673 'Table_privs' => true, 1674 ); 1675 1676 // for the rights 1677 $db_rights = array(); 1678 1679 if ( PMA_MYSQL_INT_VERSION >= 40000 ) { 1680 $db_rights_sql = '(' . implode( ') UNION (', $db_rights_sqls ) . ')' 1681 .' ORDER BY `Db` ASC'; 1682 1683 $db_rights_result = PMA_DBI_query( $db_rights_sql ); 1684 1685 while ( $db_rights_row = PMA_DBI_fetch_assoc( $db_rights_result ) ) { 1686 $db_rights_row = array_merge( $user_defaults, $db_rights_row ); 1687 // only Db names in the table `mysql`.`db` uses wildcards 1688 // as we are in the db specific rights display we want 1689 // all db names escaped, also from other sources 1690 $db_rights_row['Db'] = PMA_escape_mysql_wildcards( 1691 $db_rights_row['Db'] ); 1692 $db_rights[$db_rights_row['Db']] = $db_rights_row; 1693 } 1694 } else { 1695 foreach ( $db_rights_sqls as $db_rights_sql ) { 1696 $db_rights_result = PMA_DBI_query( $db_rights_sql ); 1697 1698 while ( $db_rights_row = PMA_DBI_fetch_assoc( $db_rights_result ) ) { 1699 $db_rights_row = array_merge( $user_defaults, $db_rights_row ); 1700 $db_rights[$db_rights_row['Db']] = $db_rights_row; 1701 } 1702 } 1703 } 1704 PMA_DBI_free_result( $db_rights_result ); 1705 unset( $db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row ); 1706 1707 $sql_query = 'SELECT * FROM `mysql`.`db`' . $user_host_condition . ' ORDER BY `Db` ASC'; 1708 $res = PMA_DBI_query( $sql_query ); 1709 unset( $sql_query ); 1710 1711 while ( $row = PMA_DBI_fetch_assoc( $res ) ) { 1712 if ( isset( $db_rights[$row['Db']] ) ) { 1713 $db_rights[$row['Db']] = array_merge( $db_rights[$row['Db']], $row ); 1714 } else { 1715 $db_rights[$row['Db']] = $row; 1716 } 1717 // there are db specific rights for this user 1718 // so we can drop this db rights 1719 $db_rights[$row['Db']]['can_delete'] = true; 1720 } 1721 PMA_DBI_free_result( $res ); 1722 unset( $row, $res ); 1723 1724 } else { 1725 1726 // db name was given, 1727 // so we want all user specific rights for this db 1728 1729 $user_host_condition .= 1730 ' AND ' . PMA_convert_using('`Db`') 1731 .' LIKE ' . PMA_convert_using( $dbname, 'quoted' ); 1732 1733 $tables_to_search_for_users = array( 1734 'columns_priv', 1735 ); 1736 1737 $db_rights_sqls = array(); 1738 foreach ( $tables_to_search_for_users as $table_search_in ) { 1739 if ( in_array( $table_search_in, $tables ) ) { 1740 $db_rights_sqls[] = ' 1741 SELECT DISTINCT `Table_name` 1742 FROM `mysql`.`' . $table_search_in . '` 1743 ' . $user_host_condition; 1744 } 1745 } 1746 1747 $user_defaults = array( 1748 'Table_name' => '', 1749 'Grant_priv' => 'N', 1750 'privs' => array( 'USAGE' ), 1751 'Column_priv' => true, 1752 ); 1753 1754 // for the rights 1755 $db_rights = array(); 1756 1757 if ( PMA_MYSQL_INT_VERSION >= 40000 ) { 1758 $db_rights_sql = '(' . implode( ') UNION (', $db_rights_sqls ) . ')' 1759 .' ORDER BY `Table_name` ASC'; 1760 1761 $db_rights_result = PMA_DBI_query( $db_rights_sql ); 1762 1763 while ( $db_rights_row = PMA_DBI_fetch_assoc( $db_rights_result ) ) { 1764 $db_rights_row = array_merge( $user_defaults, $db_rights_row ); 1765 $db_rights[$db_rights_row['Table_name']] = $db_rights_row; 1766 } 1767 } else { 1768 foreach ( $db_rights_sqls as $db_rights_sql ) { 1769 $db_rights_result = PMA_DBI_query( $db_rights_sql ); 1770 1771 while ( $db_rights_row = PMA_DBI_fetch_assoc( $db_rights_result ) ) { 1772 $db_rights_row = array_merge( $user_defaults, $db_rights_row ); 1773 $db_rights[$db_rights_row['Table_name']] = $db_rights_row; 1774 } 1775 } 1776 } 1777 PMA_DBI_free_result( $db_rights_result ); 1778 unset( $db_rights_sql, $db_rights_sqls, $db_rights_result, $db_rights_row ); 1779 1780 $sql_query = 1781 'SELECT `Table_name`,' 1782 .' `Table_priv`,' 1783 .' IF(`Column_priv` = ' . (PMA_MYSQL_INT_VERSION >= 40100 ? '_latin1 ' : '') . ' \'\', 0, 1)' 1784 .' AS \'Column_priv\'' 1785 .' FROM `mysql`.`tables_priv`' 1786 . $user_host_condition 1787 .' ORDER BY `Table_name` ASC;'; 1788 $res = PMA_DBI_query( $sql_query ); 1789 unset( $sql_query ); 1790 1791 while ( $row = PMA_DBI_fetch_assoc( $res ) ) { 1792 if ( isset( $db_rights[$row['Table_name']] ) ) { 1793 $db_rights[$row['Table_name']] = array_merge( $db_rights[$row['Table_name']], $row ); 1794 } else { 1795 $db_rights[$row['Table_name']] = $row; 1796 } 1797 } 1798 PMA_DBI_free_result( $res ); 1799 unset( $row, $res ); 1800 } 1801 ksort( $db_rights ); 1802 1803 // display rows 1804 if ( count( $db_rights ) < 1 ) { 1805 echo '<tr class="odd">' . "\n" 1806 . ' <td colspan="6"><center><i>' . $GLOBALS['strNone'] . '</i></center></td>' . "\n" 1807 . '</tr>' . "\n"; 1808 } else { 1809 $odd_row = true; 1810 $found_rows = array(); 1811 //while ( $row = PMA_DBI_fetch_assoc( $res ) ) { 1812 foreach ( $db_rights as $row ) { 1813 $found_rows[] = ( ! isset( $dbname ) || ! strlen($dbname) ) ? $row['Db'] : $row['Table_name']; 1814 1815 echo '<tr class="' . ( $odd_row ? 'odd' : 'even' ) . '">' . "\n" 1816 . ' <td>' . htmlspecialchars(( ! isset( $dbname ) || ! strlen($dbname) ) ? $row['Db'] : $row['Table_name']) . '</td>' . "\n" 1817 . ' <td><tt>' . "\n" 1818 . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($row, TRUE)) . "\n" 1819 . ' </tt></td>' . "\n" 1820 . ' <td>' . (((( ! isset( $dbname ) || ! strlen($dbname) ) && $row['Grant_priv'] == 'Y') || (isset($dbname) && strlen($dbname) && in_array('Grant', explode(',', $row['Table_priv'])))) ? $GLOBALS['strYes'] : $GLOBALS['strNo']) . '</td>' . "\n" 1821 . ' <td>'; 1822 if ( ! empty( $row['Table_privs'] ) || ! empty ( $row['Column_priv'] ) ) { 1823 echo $GLOBALS['strYes']; 1824 } else { 1825 echo $GLOBALS['strNo']; 1826 } 1827 echo '</td>' . "\n" 1828 . ' <td>'; 1829 printf( $link_edit, urlencode( $username ), 1830 urlencode( $hostname ), 1831 urlencode( ( ! isset( $dbname ) || ! strlen($dbname) ) ? $row['Db'] : $dbname ), 1832 urlencode( ( ! isset( $dbname ) || ! strlen($dbname) ) ? '' : $row['Table_name'] ) ); 1833 echo '</td>' . "\n" 1834 . ' <td>'; 1835 if ( ! empty( $row['can_delete'] ) || isset( $row['Table_name'] ) && strlen($row['Table_name']) ) { 1836 printf( $link_revoke, urlencode( $username ), 1837 urlencode( $hostname ), 1838 urlencode( ( ! isset( $dbname ) || ! strlen($dbname) ) ? $row['Db'] : $dbname ), 1839 urlencode( ( ! isset( $dbname ) || ! strlen($dbname) ) ? '' : $row['Table_name'] ) ); 1840 } 1841 echo '</td>' . "\n" 1842 . '</tr>' . "\n"; 1843 $odd_row = ! $odd_row; 1844 } // end while 1845 } 1846 unset($row); 1847 echo '</tbody>' . "\n" 1848 . '</table>' . "\n"; 1849 1850 if ( ! isset( $dbname ) || ! strlen($dbname) ) { 1851 1852 // no database name was give, display select db 1853 1854 if ( ! empty( $found_rows ) ) { 1855 $pred_db_array = array_diff( 1856 PMA_DBI_fetch_result( 'SHOW DATABASES;' ), 1857 $found_rows ); 1858 } else { 1859 $pred_db_array =PMA_DBI_fetch_result( 'SHOW DATABASES;' ); 1860 } 1861 1862 echo ' <label for="text_dbname">' . $GLOBALS['strAddPrivilegesOnDb'] . ':</label>' . "\n"; 1863 if (!empty($pred_db_array)) { 1864 echo ' <select name="pred_dbname" onchange="this.form.submit();">' . "\n" 1865 . ' <option value="" selected="selected">' . $GLOBALS['strUseTextField'] . ':</option>' . "\n"; 1866 foreach ($pred_db_array as $current_db) { 1867 $current_db = PMA_escape_mysql_wildcards( $current_db ); 1868 echo ' <option value="' . htmlspecialchars( $current_db ) . '">' 1869 . htmlspecialchars( $current_db ) . '</option>' . "\n"; 1870 } 1871 echo ' </select>' . "\n"; 1872 } 1873 echo ' <input type="text" id="text_dbname" name="dbname" />' . "\n" 1874 .PMA_showHint( $GLOBALS['strEscapeWildcards'] ); 1875 } else { 1876 echo ' <input type="hidden" name="dbname" value="' . htmlspecialchars($dbname) . '"/>' . "\n" 1877 . ' <label for="text_tablename">' . $GLOBALS['strAddPrivilegesOnTbl'] . ':</label>' . "\n"; 1878 if ($res = @PMA_DBI_try_query('SHOW TABLES FROM ' . PMA_backquote($dbname) . ';', null, PMA_DBI_QUERY_STORE)) { 1879 $pred_tbl_array = array(); 1880 while ($row = PMA_DBI_fetch_row($res)) { 1881 if (!isset($found_rows) || !in_array($row[0], $found_rows)) { 1882 $pred_tbl_array[] = $row[0]; 1883 } 1884 } 1885 PMA_DBI_free_result($res); 1886 unset( $res, $row ); 1887 if (!empty($pred_tbl_array)) { 1888 echo ' <select name="pred_tablename" onchange="this.form.submit();">' . "\n" 1889 . ' <option value="" selected="selected">' . $GLOBALS['strUseTextField'] . ':</option>' . "\n"; 1890 foreach ($pred_tbl_array as $current_table) { 1891 echo ' <option value="' . htmlspecialchars($current_table) . '">' . htmlspecialchars($current_table) . '</option>' . "\n"; 1892 } 1893 echo ' </select>' . "\n"; 1894 } 1895 } else { 1896 unset($res); 1897 } 1898 echo ' <input type="text" id="text_tablename" name="tablename" />' . "\n"; 1899 } 1900 echo '</fieldset>' . "\n"; 1901 echo '<fieldset class="tblFooters">' . "\n" 1902 . ' <input type="submit" value="' . $GLOBALS['strGo'] . '" />' 1903 . '</fieldset>' . "\n" 1904 . '</form>' . "\n"; 1905 } 1906 1907 if ( ( ! isset( $dbname ) || ! strlen($dbname) ) && ! $user_does_not_exists ) { 1908 echo '<form action="server_privileges.php" method="post" onsubmit="return checkPassword(this);">' . "\n" 1909 . PMA_generate_common_hidden_inputs('', '', 3) 1910 . '<input type="hidden" name="username" value="' . htmlspecialchars($username) . '" />' . "\n" 1911 . '<input type="hidden" name="hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n" 1912 . '<fieldset id="fieldset_change_password">' . "\n" 1913 . ' <legend>' . $GLOBALS['strChangePassword'] . '</legend>' . "\n" 1914 . ' <table class="data">' . "\n" 1915 . ' <tr class="odd noclick">' . "\n" 1916 . ' <td><input type="radio" name="nopass" value="1" id="radio_nopass_1" onclick="pw_pma_pw.value=\'\'; pw_pma_pw2.value=\'\';" /></td>' . "\n" 1917 . ' <td colspan="2"><label for="radio_nopass_1">' . $GLOBALS['strNoPassword'] . '</label></td>' . "\n" 1918 . ' </tr>' . "\n" 1919 . ' <tr class="even noclick">' . "\n" 1920 . ' <td><input type="radio" name="nopass" value="0" id="radio_nopass_0" onclick="document.getElementById(\'pw_pma_pw\').focus();" /></td>' . "\n" 1921 . ' <td><label for="radio_nopass_0">' . $GLOBALS['strPassword'] . ':</label></td>' . "\n" 1922 . ' <td><input type="password" name="pma_pw" id="pw_pma_pw" onchange="nopass[1].checked = true;" /></td>' . "\n" 1923 . ' </tr>' . "\n" 1924 . ' <tr class="odd noclick">' . "\n" 1925 . ' <td></td>' . "\n" 1926 . ' <td><label for="pw_pma_pw2">' . $GLOBALS['strReType'] . ':</label></td>' . "\n" 1927 . ' <td><input type="password" name="pma_pw2" id="pw_pma_pw2" onchange="nopass[1].checked = true;" /></td>' . "\n" 1928 . ' </tr>' . "\n" 1929 . ' </table>' . "\n" 1930 . '</fieldset>' . "\n" 1931 . '<fieldset id="fieldset_change_password_footer" class="tblFooters">' . "\n" 1932 . ' <input type="submit" name="change_pw" value="' . $GLOBALS['strGo'] . '" />' . "\n" 1933 . '</fieldset>' . "\n" 1934 . '</form>' . "\n" 1935 . '<form action="server_privileges.php" method="post" onsubmit="return checkPassword(this);">' . "\n" 1936 . PMA_generate_common_hidden_inputs('', '', 3) 1937 . '<input type="hidden" name="old_username" value="' . htmlspecialchars($username) . '" />' . "\n" 1938 . '<input type="hidden" name="old_hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n" 1939 . '<fieldset id="fieldset_change_copy_user">' . "\n" 1940 . ' <legend>' . $GLOBALS['strChangeCopyUser'] . '</legend>' . "\n"; 1941 PMA_displayLoginInformationFields('change', 3 ); 1942 echo ' <fieldset>' . "\n" 1943 . ' <legend>' . $GLOBALS['strChangeCopyMode'] . '</legend>' . "\n" 1944 . ' <input type="radio" name="mode" value="4" id="radio_mode_4" checked="checked" /><label for="radio_mode_4">' . "\n" 1945 . ' ' . $GLOBALS['strChangeCopyModeCopy'] . "\n" 1946 . ' </label><br />' . "\n" 1947 . ' <input type="radio" name="mode" value="1" id="radio_mode_1" /><label for="radio_mode_1">' . "\n" 1948 . ' ' . $GLOBALS['strChangeCopyModeJustDelete'] . "\n" 1949 . ' </label><br />' . "\n" 1950 . ' <input type="radio" name="mode" value="2" id="radio_mode_2" /><label for="radio_mode_2">' . "\n" 1951 . ' ' . $GLOBALS['strChangeCopyModeRevoke'] . "\n" 1952 . ' </label><br />' . "\n" 1953 . ' <input type="radio" name="mode" value="3" id="radio_mode_3" /><label for="radio_mode_3">' . "\n" 1954 . ' ' . $GLOBALS['strChangeCopyModeDeleteAndReload'] . "\n" 1955 . ' </label>' . "\n" 1956 . ' </fieldset>' . "\n" 1957 . '</fieldset>' . "\n" 1958 . '<fieldset id="fieldset_change_copy_user_footer" class="tblFooters">' . "\n" 1959 . ' <input type="submit" name="change_copy" value="' . $GLOBALS['strGo'] . '" />' . "\n" 1960 . '</fieldset>' . "\n" 1961 . '</form>' . "\n"; 1962 } 1963 } 1964 } elseif (!empty($adduser)) { 1965 // Add a new user 1966 $GLOBALS['url_query'] .= '&adduser=1'; 1967 echo '<h2>' . "\n" 1968 . ($GLOBALS['cfg']['PropertiesIconic'] ? '<img class="icon" src="' . $pmaThemeImage . 'b_usradd.png" width="16" height="16" alt="" />' : '' ) 1969 . ' ' . $GLOBALS['strAddUser'] . "\n" 1970 . '</h2>' . "\n" 1971 . '<form name="usersForm" id="usersForm" action="server_privileges.php" method="post" onsubmit="return checkAddUser(this);">' . "\n" 1972 . PMA_generate_common_hidden_inputs('', '', 1); 1973 PMA_displayLoginInformationFields('new', 2); 1974 echo '<fieldset id="fieldset_add_user_database">' . "\n" 1975 . '<legend>' . $GLOBALS['strCreateUserDatabase'] . '</legend>' . "\n" 1976 . ' <div class="item">' . "\n" 1977 . ' <input type="radio" name="createdb" value="0" id="radio_createdb_0" checked="checked" />' . "\n" 1978 . ' <label for="radio_createdb_0">' . $GLOBALS['strCreateUserDatabaseNone'] . '</label>' . "\n" 1979 . ' </div>' . "\n" 1980 . ' <div class="item">' . "\n" 1981 . ' <input type="radio" name="createdb" value="1" id="radio_createdb_1" />' . "\n" 1982 . ' <label for="radio_createdb_1">' . $GLOBALS['strCreateUserDatabaseName'] . '</label>' . "\n" 1983 . ' </div>' . "\n" 1984 . ' <div class="item">' . "\n" 1985 . ' <input type="radio" name="createdb" value="2" id="radio_createdb_2" />' . "\n" 1986 . ' <label for="radio_createdb_2">' . $GLOBALS['strCreateUserDatabaseWildcard'] . '</label>' . "\n" 1987 . ' </div>' . "\n" 1988 . '</fieldset>' . "\n"; 1989 PMA_displayPrivTable('*', '*', FALSE, 1); 1990 echo ' <fieldset id="fieldset_add_user_footer" class="tblFooters">' . "\n" 1991 . ' <input type="submit" name="adduser_submit" value="' . $GLOBALS['strGo'] . '" />' . "\n" 1992 . ' </fieldset>' . "\n" 1993 . '</form>' . "\n"; 1994 } else { 1995 // check the privileges for a particular database. 1996 echo '<table id="tablespecificuserrights" class="data">' . "\n" 1997 . '<caption class="tblHeaders">' . "\n" 1998 . ($GLOBALS['cfg']['PropertiesIconic'] ? ' <img class="icon" src="' . $pmaThemeImage . 'b_usrcheck.png" width="16" height="16" alt="" />' . "\n" : '' ) 1999 . ' ' . sprintf($GLOBALS['strUsersHavingAccessToDb'], '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?' . PMA_generate_common_url($checkprivs) . '">' . htmlspecialchars($checkprivs) . '</a>') . "\n" 2000 . '</caption>' . "\n" 2001 . '<thead>' . "\n" 2002 . ' <tr><th>' . $GLOBALS['strUser'] . '</th>' . "\n" 2003 . ' <th>' . $GLOBALS['strHost'] . '</th>' . "\n" 2004 . ' <th>' . $GLOBALS['strType'] . '</th>' . "\n" 2005 . ' <th>' . $GLOBALS['strPrivileges'] . '</th>' . "\n" 2006 . ' <th>' . $GLOBALS['strGrantOption'] . '</th>' . "\n" 2007 . ' <th>' . $GLOBALS['strAction'] . '</th>' . "\n" 2008 . ' </tr>' . "\n" 2009 . '</thead>' . "\n" 2010 . '<tbody>' . "\n"; 2011 $odd_row = TRUE; 2012 unset($row); 2013 unset($row1); 2014 unset($row2); 2015 // now, we build the table... 2016 if (PMA_MYSQL_INT_VERSION >= 40000) { 2017 // Starting with MySQL 4.0.0, we may use UNION SELECTs and this makes 2018 // the job much easier here! 2019 2020 $no = PMA_convert_using('N', 'quoted'); 2021 2022 $list_of_privileges = 2023 PMA_convert_using('Select_priv') . ' AS Select_priv, ' 2024 . PMA_convert_using('Insert_priv') . ' AS Insert_priv, ' 2025 . PMA_convert_using('Update_priv') . ' AS Update_priv, ' 2026 . PMA_convert_using('Delete_priv') . ' AS Delete_priv, ' 2027 . PMA_convert_using('Create_priv') . ' AS Create_priv, ' 2028 . PMA_convert_using('Drop_priv') . ' AS Drop_priv, ' 2029 . PMA_convert_using('Grant_priv') . ' AS Grant_priv, ' 2030 . PMA_convert_using('References_priv') . ' AS References_priv'; 2031 2032 $list_of_compared_privileges = 2033 PMA_convert_using('Select_priv') . ' = ' . $no 2034 . ' AND ' . PMA_convert_using('Insert_priv') . ' = ' . $no 2035 . ' AND ' . PMA_convert_using('Update_priv') . ' = ' . $no 2036 . ' AND ' . PMA_convert_using('Delete_priv') . ' = ' . $no 2037 . ' AND ' . PMA_convert_using('Create_priv') . ' = ' . $no 2038 . ' AND ' . PMA_convert_using('Drop_priv') . ' = ' . $no 2039 . ' AND ' . PMA_convert_using('Grant_priv') . ' = ' . $no 2040 . ' AND ' . PMA_convert_using('References_priv') . ' = ' . $no; 2041 2042 $sql_query = 2043 '(SELECT ' . PMA_convert_using('`User`') . ' AS `User`, ' 2044 . PMA_convert_using('`Host`') . ' AS `Host`, ' 2045 . PMA_convert_using('`Db`') . ' AS `Db`, ' 2046 . $list_of_privileges 2047 .' FROM `mysql`.`db`' 2048 .' WHERE ' . PMA_convert_using( $checkprivs, 'quoted' ) 2049 .' LIKE ' . PMA_convert_using('`Db`') 2050 .' AND NOT (' . $list_of_compared_privileges. ')) ' 2051 .'UNION ' 2052 .'(SELECT ' . PMA_convert_using('`User`') . ' AS `User`, ' 2053 . PMA_convert_using('`Host`') . ' AS `Host`, ' 2054 . PMA_convert_using('*', 'quoted') .' AS `Db`, ' 2055 . $list_of_privileges 2056 .' FROM `mysql`.`user` ' 2057 .' WHERE NOT (' . $list_of_compared_privileges . ')) ' 2058 .' ORDER BY `User` ASC,' 2059 .' `Host` ASC,' 2060 .' `Db` ASC;'; 2061 $res = PMA_DBI_query($sql_query); 2062 $row = PMA_DBI_fetch_assoc($res); 2063 if ($row) { 2064 $found = TRUE; 2065 } 2066 } else { 2067 // With MySQL 3, we need 2 seperate queries here. 2068 $sql_query = 'SELECT * FROM `mysql`.`user` WHERE NOT (`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\') ORDER BY `User` ASC, `Host` ASC;'; 2069 $res1 = PMA_DBI_query($sql_query); 2070 $row1 = PMA_DBI_fetch_assoc($res1); 2071 $sql_query = 2072 'SELECT * FROM `mysql`.`db`' 2073 .' WHERE \'' . $checkprivs . '\'' 2074 .' LIKE `Db`' 2075 .' AND NOT (`Select_priv` = \'N\'' 2076 .' AND `Insert_priv` = \'N\'' 2077 .' AND `Update_priv` = \'N\'' 2078 .' AND `Delete_priv` = \'N\'' 2079 .' AND `Create_priv` = \'N\'' 2080 .' AND `Drop_priv` = \'N\'' 2081 .' AND `Grant_priv` = \'N\'' 2082 .' AND `References_priv` = \'N\')' 2083 .' ORDER BY `User` ASC, `Host` ASC;'; 2084 $res2 = PMA_DBI_query($sql_query); 2085 $row2 = PMA_DBI_fetch_assoc($res2); 2086 if ($row1 || $row2) { 2087 $found = TRUE; 2088 } 2089 } // end if (PMA_MYSQL_INT_VERSION >= 40000) ... else ... 2090 if ($found) { 2091 while (TRUE) { 2092 // prepare the current user 2093 if (PMA_MYSQL_INT_VERSION >= 40000) { 2094 $current_privileges = array(); 2095 $current_user = $row['User']; 2096 $current_host = $row['Host']; 2097 while ($row && $current_user == $row['User'] && $current_host == $row['Host']) { 2098 $current_privileges[] = $row; 2099 $row = PMA_DBI_fetch_assoc($res); 2100 } 2101 } else { 2102 $current_privileges = array(); 2103 if ($row1 && (!$row2 || ($row1['User'] < $row2['User'] || ($row1['User'] == $row2['User'] && $row1['Host'] <= $row2['Host'])))) { 2104 $current_user = $row1['User']; 2105 $current_host = $row1['Host']; 2106 $current_privileges = array($row1); 2107 $row1 = PMA_DBI_fetch_assoc($res1); 2108 } else { 2109 $current_user = $row2['User']; 2110 $current_host = $row2['Host']; 2111 $current_privileges = array(); 2112 } 2113 while ($row2 && $current_user == $row2['User'] && $current_host == $row2['Host']) { 2114 $current_privileges[] = $row2; 2115 $row2 = PMA_DBI_fetch_assoc($res2); 2116 } 2117 } 2118 echo ' <tr class="' . ( $odd_row ? 'odd' : 'even' ) . '">' . "\n" 2119 . ' <td'; 2120 if (count($current_privileges) > 1) { 2121 echo ' rowspan="' . count($current_privileges) . '"'; 2122 } 2123 echo '>' . (empty($current_user) ? '<span style="color: #FF0000">' . $GLOBALS['strAny'] . '</span>' : htmlspecialchars($current_user)) . "\n" 2124 . ' </td>' . "\n" 2125 . ' <td'; 2126 if (count($current_privileges) > 1) { 2127 echo ' rowspan="' . count($current_privileges) . '"'; 2128 } 2129 echo '>' . htmlspecialchars($current_host) . '</td>' . "\n"; 2130 foreach ($current_privileges as $current) { 2131 echo ' <td>' . "\n" 2132 . ' '; 2133 if (!isset($current['Db']) || $current['Db'] == '*') { 2134 echo $GLOBALS['strGlobal']; 2135 } elseif ( $current['Db'] == PMA_escape_mysql_wildcards( $checkprivs ) ) { 2136 echo $GLOBALS['strDbSpecific']; 2137 } else { 2138 echo $GLOBALS['strWildcard'], ': <tt>' . htmlspecialchars($current['Db']) . '</tt>'; 2139 } 2140 echo "\n" 2141 . ' </td>' . "\n" 2142 . ' <td>' . "\n" 2143 . ' <tt>' . "\n" 2144 . ' ' . join(',' . "\n" . ' ', PMA_extractPrivInfo($current, TRUE)) . "\n" 2145 . ' </tt>' . "\n" 2146 . ' </td>' . "\n" 2147 . ' <td>' . "\n" 2148 . ' ' . ($current['Grant_priv'] == 'Y' ? $GLOBALS['strYes'] : $GLOBALS['strNo']) . "\n" 2149 . ' </td>' . "\n" 2150 . ' <td>' . "\n"; 2151 printf( $link_edit, urlencode( $current_user ), 2152 urlencode( $current_host ), 2153 urlencode( ! isset( $current['Db'] ) || $current['Db'] == '*' ? '' : $current['Db'] ), 2154 '' ); 2155 echo '</td>' . "\n" 2156 . ' </tr>' . "\n"; 2157 } 2158 if (empty($row) && empty($row1) && empty($row2)) { 2159 break; 2160 } 2161 $odd_row = ! $odd_row; 2162 } 2163 } else { 2164 echo ' <tr class="odd">' . "\n" 2165 . ' <td colspan="6">' . "\n" 2166 . ' ' . $GLOBALS['strNoUsersFound'] . "\n" 2167 . ' </td>' . "\n" 2168 . ' </tr>' . "\n"; 2169 } 2170 echo '</tbody>' . "\n" 2171 . '</table>' . "\n"; 2172 } // end if (empty($adduser) && empty($checkprivs)) ... elseif ... else ... 2173 2174 2175 /** 2176 * Displays the footer 2177 */ 2178 echo "\n\n"; 2179 require_once ('./libraries/footer.inc.php'); 2180 2181 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Mon Nov 26 15:18:20 2007 | par Balluche grâce à PHPXref 0.7 |
|