2007-08-09 15:03:39 +00:00
< ? php
2009-06-13 20:04:22 +00:00
$privileges = array ( " " => array ( " All privileges " => " " ));
2009-05-08 05:23:03 +00:00
$result = $dbh -> query ( " SHOW PRIVILEGES " );
2007-08-10 15:09:17 +00:00
while ( $row = $result -> fetch_assoc ()) {
2009-06-13 20:04:22 +00:00
if ( $row [ " Privilege " ] == " Grant option " ) {
$privileges [ " " ][ " Grant option " ] = $row [ " Comment " ];
} else {
foreach ( explode ( " , " , $row [ " Context " ]) as $context ) {
$privileges [ $context ][ $row [ " Privilege " ]] = $row [ " Comment " ];
}
2007-08-10 15:09:17 +00:00
}
}
$result -> free ();
$privileges [ " Server Admin " ] += $privileges [ " File access on server " ];
2009-06-21 23:20:32 +00:00
$privileges [ " Databases " ][ " Create routine " ] = $privileges [ " Procedures " ][ " Create routine " ]; // MySQL bug #30305
unset ( $privileges [ " Procedures " ][ " Create routine " ]);
2007-08-10 15:09:17 +00:00
$privileges [ " Columns " ] = array ();
foreach ( array ( " Select " , " Insert " , " Update " , " References " ) as $val ) {
$privileges [ " Columns " ][ $val ] = $privileges [ " Tables " ][ $val ];
}
unset ( $privileges [ " Server Admin " ][ " Usage " ]);
foreach ( $privileges [ " Tables " ] as $key => $val ) {
unset ( $privileges [ " Databases " ][ $key ]);
}
2009-06-13 20:04:22 +00:00
function grant ( $grant , $columns ) {
return preg_replace ( '~(GRANT OPTION)\\([^)]*\\)~' , '\\1' , implode ( " $columns , " , $grant ) . $columns );
2007-08-10 15:09:17 +00:00
}
2008-07-10 15:39:24 +00:00
$new_grants = array ();
2007-08-09 15:03:39 +00:00
if ( $_POST ) {
foreach ( $_POST [ " objects " ] as $key => $val ) {
$new_grants [ $val ] = (( array ) $new_grants [ $val ]) + (( array ) $_POST [ " grants " ][ $key ]);
}
}
$grants = array ();
$old_pass = " " ;
2009-06-22 09:58:58 +00:00
if ( isset ( $_GET [ " host " ]) && ( $result = $dbh -> query ( " SHOW GRANTS FOR " . $dbh -> quote ( $_GET [ " user " ]) . " @ " . $dbh -> quote ( $_GET [ " host " ])))) { //! use information_schema for MySQL 5 - column names in column privileges are not escaped
2007-08-09 15:03:39 +00:00
while ( $row = $result -> fetch_row ()) {
2009-06-13 20:04:22 +00:00
if ( preg_match ( '~GRANT (.*) ON (.*) TO ~' , $row [ 0 ], $match ) && preg_match_all ( '~ *([^(,]*[^ ,(])( *\\([^)]+\\))?~' , $match [ 1 ], $matches , PREG_SET_ORDER )) { //! escape the part between ON and TO
foreach ( $matches as $val ) {
$grants [ " $match[2] $val[2] " ][ $val [ 1 ]] = true ;
if ( preg_match ( '~ WITH GRANT OPTION~' , $row [ 0 ])) { //! don't check inside strings and identifiers
$grants [ " $match[2] $val[2] " ][ " GRANT OPTION " ] = true ;
2007-08-10 15:09:17 +00:00
}
2007-08-09 15:03:39 +00:00
}
}
if ( preg_match ( " ~ IDENTIFIED BY PASSWORD '([^']+)~ " , $row [ 0 ], $match )) {
$old_pass = $match [ 1 ];
}
}
$result -> free ();
}
if ( $_POST && ! $error ) {
2009-06-22 00:53:51 +00:00
$old_user = ( isset ( $_GET [ " host " ]) ? $dbh -> quote ( $_GET [ " user " ]) . " @ " . $dbh -> quote ( $_GET [ " host " ]) : " '' " );
2009-06-22 05:22:41 +00:00
$new_user = $dbh -> quote ( $_POST [ " user " ]) . " @ " . $dbh -> quote ( $_POST [ " host " ]); // if $_GET["host"] is not set then $new_user is always different
2009-06-22 00:53:51 +00:00
$pass = $dbh -> quote ( $_POST [ " pass " ]);
2007-08-09 15:03:39 +00:00
if ( $_POST [ " drop " ]) {
2009-06-22 00:53:51 +00:00
query_redirect ( " DROP USER $old_user " , $SELF . " privileges= " , lang ( 'User has been dropped.' ));
2009-06-13 20:04:22 +00:00
} else {
2007-08-11 06:25:58 +00:00
if ( $old_user == $new_user ) {
2009-06-22 00:53:51 +00:00
queries ( " SET PASSWORD FOR $new_user = " . ( $_POST [ " hashed " ] ? $pass : " PASSWORD( $pass ) " ));
2009-06-13 20:04:22 +00:00
} else {
2009-06-22 00:53:51 +00:00
$error = ! queries (( $dbh -> server_info < 5 ? " GRANT USAGE ON *.* TO " : " CREATE USER " ) . " $new_user IDENTIFIED BY " . ( $_POST [ " hashed " ] ? " PASSWORD " : " " ) . " $pass " );
2007-08-11 06:25:58 +00:00
}
2009-06-13 20:04:22 +00:00
if ( ! $error ) {
$revoke = array ();
foreach ( $new_grants as $object => $grant ) {
if ( isset ( $_GET [ " grant " ])) {
$grant = array_filter ( $grant );
}
$grant = array_keys ( $grant );
if ( isset ( $_GET [ " grant " ])) {
2009-06-21 23:20:32 +00:00
// no rights to mysql.user table
2009-06-13 20:04:22 +00:00
$revoke = array_diff ( array_keys ( array_filter ( $new_grants [ $object ], 'strlen' )), $grant );
} elseif ( $old_user == $new_user ) {
$old_grant = array_keys (( array ) $grants [ $object ]);
$revoke = array_diff ( $old_grant , $grant );
$grant = array_diff ( $grant , $old_grant );
unset ( $grants [ $object ]);
}
if ( preg_match ( '~^(.+)\\s*(\\(.*\\))?$~U' , $object , $match ) && (
2009-06-22 00:53:51 +00:00
( $grant && ! queries ( " GRANT " . grant ( $grant , $match [ 2 ]) . " ON $match[1] TO $new_user " )) //! SQL injection
|| ( $revoke && ! queries ( " REVOKE " . grant ( $revoke , $match [ 2 ]) . " ON $match[1] FROM $new_user " ))
2009-06-13 20:04:22 +00:00
)) {
$error = true ;
break ;
2007-08-09 15:03:39 +00:00
}
}
}
2009-06-13 20:04:22 +00:00
if ( ! $error && isset ( $_GET [ " host " ])) {
if ( $old_user != $new_user ) {
2009-06-22 00:53:51 +00:00
queries ( " DROP USER $old_user " );
2007-08-10 15:09:17 +00:00
} elseif ( ! isset ( $_GET [ " grant " ])) {
2007-08-09 15:03:39 +00:00
foreach ( $grants as $object => $revoke ) {
if ( preg_match ( '~^(.+)(\\(.*\\))?$~U' , $object , $match )) {
2009-06-22 00:53:51 +00:00
queries ( " REVOKE " . grant ( array_keys ( $revoke ), $match [ 2 ]) . " ON $match[1] FROM $new_user " );
2007-08-09 15:03:39 +00:00
}
}
}
}
2009-06-13 20:04:22 +00:00
query_redirect ( queries (), $SELF . " privileges= " , ( isset ( $_GET [ " host " ]) ? lang ( 'User has been altered.' ) : lang ( 'User has been created.' )), ! $error , false , $error );
if ( $old_user != $new_user ) {
2009-06-22 05:22:41 +00:00
// delete new user in case of an error
2009-06-22 00:53:51 +00:00
$dbh -> query ( " DROP USER $new_user " );
2009-06-13 20:04:22 +00:00
}
2007-08-09 15:03:39 +00:00
}
}
2009-07-11 19:45:57 +00:00
page_header (( isset ( $_GET [ " host " ]) ? lang ( 'Username' ) . " : " . htmlspecialchars ( " $_GET[user] @ $_GET[host] " ) : lang ( 'Create user' )), $error , array ( " privileges " => array ( '' , lang ( 'Privileges' ))));
2007-08-09 15:03:39 +00:00
if ( $_POST ) {
$row = $_POST ;
$grants = $new_grants ;
} else {
2009-06-22 06:11:15 +00:00
$row = $_GET + array ( " host " => $dbh -> result ( $dbh -> query ( " SELECT SUBSTRING_INDEX(CURRENT_USER, '@', -1) " ))); // create user on the same domain by default
2007-08-09 15:03:39 +00:00
$row [ " pass " ] = $old_pass ;
if ( strlen ( $old_pass )) {
$row [ " hashed " ] = true ;
}
$grants [ " " ] = true ;
}
?>
< form action = " " method = " post " >
2009-05-01 10:41:33 +00:00
< table cellspacing = " 0 " >
2007-08-09 15:03:39 +00:00
< tr >< th >< ? php echo lang ( 'Username' ); ?> </th><td><input name="user" maxlength="16" value="<?php echo htmlspecialchars($row["user"]); ?>" /></td></tr>
< tr >< th >< ? php echo lang ( 'Server' ); ?> </th><td><input name="host" maxlength="60" value="<?php echo htmlspecialchars($row["host"]); ?>" /></td></tr>
2008-10-01 11:39:13 +00:00
< tr >< th >< ? php echo lang ( 'Password' ); ?> </th><td><input id="pass" name="pass" value="<?php echo htmlspecialchars($row["pass"]); ?>" /><?php if (!$row["hashed"]) { ?><script type="text/javascript">document.getElementById('pass').type = 'password';</script><?php } ?> <label><input type="checkbox" name="hashed" value="1"<?php if ($row["hashed"]) { ?> checked="checked"<?php } ?> onclick="this.form['pass'].type = (this.checked ? 'text' : 'password');" /><?php echo lang('Hashed'); ?></label></td></tr>
2007-08-09 15:03:39 +00:00
</ table >
< ? php
//! MAX_* limits, REQUIRE
2009-05-01 10:41:33 +00:00
echo " <table cellspacing='0'> \n " ;
2008-01-08 15:46:32 +00:00
echo " <thead><tr><th colspan='2'> " . lang ( 'Privileges' ) . " </th> " ;
2007-08-09 15:03:39 +00:00
$i = 0 ;
2008-01-08 15:46:32 +00:00
foreach ( $grants as $object => $grant ) {
echo '<th>' . ( $object != " *.* " ? '<input name="objects[' . $i . ']" value="' . htmlspecialchars ( $object ) . '" size="10" />' : '<input type="hidden" name="objects[' . $i . ']" value="*.*" size="10" />*.*' ) . '</th>' ; //! separate db, table, columns, PROCEDURE|FUNCTION, routine
$i ++ ;
}
echo " </tr></thead> \n " ;
2007-08-09 15:03:39 +00:00
foreach ( array (
2009-06-13 20:04:22 +00:00
" " => " " ,
2007-08-09 15:03:39 +00:00
" Server Admin " => lang ( 'Server' ),
" Databases " => lang ( 'Database' ),
" Tables " => lang ( 'Table' ),
" Columns " => lang ( 'Column' ),
" Procedures " => lang ( 'Routine' ),
2008-01-08 15:46:32 +00:00
) as $context => $desc ) {
foreach (( array ) $privileges [ $context ] as $privilege => $comment ) {
2009-06-13 20:04:22 +00:00
echo " <tr " . odd () . " ><td " . ( $desc ? " > $desc </td><td " : " colspan='2' " ) . ' title="' . htmlspecialchars ( $comment ) . '"><i>' . htmlspecialchars ( $privilege ) . " </i></td> " ;
2008-01-08 15:46:32 +00:00
$i = 0 ;
2007-08-09 15:03:39 +00:00
foreach ( $grants as $object => $grant ) {
2008-01-08 15:46:32 +00:00
$name = '"grants[' . $i . '][' . htmlspecialchars ( strtoupper ( $privilege )) . ']"' ;
$value = $grant [ strtoupper ( $privilege )];
if ( $context == " Server Admin " && $object != ( isset ( $grants [ " *.* " ]) ? " *.* " : " " )) {
2009-06-11 11:17:53 +00:00
echo " <td> </td> " ;
2008-01-08 15:46:32 +00:00
} elseif ( isset ( $_GET [ " grant " ])) {
echo " <td><select name= $name ><option></option><option value='1' " . ( $value ? " selected='selected' " : " " ) . " > " . lang ( 'Grant' ) . " </option><option value='0' " . ( $value == " 0 " ? " selected='selected' " : " " ) . " > " . lang ( 'Revoke' ) . " </option></select></td> " ;
} else {
echo " <td align='center'><input type='checkbox' name= $name value='1' " . ( $value ? " checked='checked' " : " " ) . " /></td> " ;
2007-08-09 15:03:39 +00:00
}
2008-01-08 15:46:32 +00:00
$i ++ ;
2007-08-09 15:03:39 +00:00
}
2008-01-08 15:46:32 +00:00
echo " </tr> \n " ;
2007-08-09 15:03:39 +00:00
}
}
2008-01-08 15:46:32 +00:00
echo " </table> \n " ;
2007-08-09 15:03:39 +00:00
?>
< p >
< input type = " hidden " name = " token " value = " <?php echo $token ; ?> " />
< input type = " submit " value = " <?php echo lang('Save'); ?> " />
2008-10-09 14:13:17 +00:00
< ? php if ( isset ( $_GET [ " host " ])) { ?> <input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo $confirm; ?> /><?php } ?>
2007-08-09 15:03:39 +00:00
</ p >
</ form >