2007-08-09 15:03:39 +00:00
< ? php
2009-08-29 13:57:50 +00:00
$USER = $_GET [ " user " ];
2009-06-13 20:04:22 +00:00
$privileges = array ( " " => array ( " All privileges " => " " ));
2010-10-13 15:53:59 +00:00
foreach ( get_rows ( " SHOW PRIVILEGES " ) as $row ) {
2009-07-13 21:46:16 +00:00
foreach ( explode ( " , " , ( $row [ " Privilege " ] == " Grant option " ? " " : $row [ " Context " ])) as $context ) {
$privileges [ $context ][ $row [ " Privilege " ]] = $row [ " Comment " ];
2007-08-10 15:09:17 +00:00
}
}
$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 ]);
}
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 ) {
2010-03-19 13:57:20 +00:00
$new_grants [ $val ] = ( array ) $new_grants [ $val ] + ( array ) $_POST [ " grants " ][ $key ];
2007-08-09 15:03:39 +00:00
}
}
$grants = array ();
$old_pass = " " ;
2013-05-02 01:28:04 +00:00
2010-10-13 16:04:40 +00:00
if ( isset ( $_GET [ " host " ]) && ( $result = $connection -> query ( " SHOW GRANTS FOR " . q ( $USER ) . " @ " . q ( $_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 ) {
2010-03-19 13:57:20 +00:00
if ( $val [ 1 ] != " USAGE " ) {
$grants [ " $match[2] $val[2] " ][ $val [ 1 ]] = true ;
}
2013-07-24 23:26:41 +00:00
if ( preg_match ( '~ WITH GRANT OPTION~' , $row [ 0 ])) { //! don't check inside strings and identifiers
2009-06-13 20:04:22 +00:00
$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 ];
}
}
}
if ( $_POST && ! $error ) {
2010-10-13 16:04:40 +00:00
$old_user = ( isset ( $_GET [ " host " ]) ? q ( $USER ) . " @ " . q ( $_GET [ " host " ]) : " '' " );
2007-08-09 15:03:39 +00:00
if ( $_POST [ " drop " ]) {
2009-07-30 08:12:54 +00:00
query_redirect ( " DROP USER $old_user " , ME . " privileges= " , lang ( 'User has been dropped.' ));
2009-06-13 20:04:22 +00:00
} else {
2013-04-25 01:42:26 +00:00
$new_user = q ( $_POST [ " user " ]) . " @ " . q ( $_POST [ " host " ]); // if $_GET["host"] is not set then $new_user is always different
$pass = $_POST [ " pass " ];
2013-04-25 16:46:37 +00:00
if ( $pass != '' && ! $_POST [ " hashed " ]) {
2013-04-25 01:42:26 +00:00
// compute hash in a separate query so that plain text password is not saved to history
$pass = $connection -> result ( " SELECT PASSWORD( " . q ( $pass ) . " ) " );
$error = ! $pass ;
}
2013-07-24 23:26:41 +00:00
2011-08-12 15:45:14 +00:00
$created = false ;
2013-04-25 01:42:26 +00:00
if ( ! $error ) {
if ( $old_user != $new_user ) {
$created = queries (( $connection -> server_info < 5 ? " GRANT USAGE ON *.* TO " : " CREATE USER " ) . " $new_user IDENTIFIED BY PASSWORD " . q ( $pass ));
$error = ! $created ;
} elseif ( $pass != $old_pass ) {
queries ( " SET PASSWORD FOR $new_user = " . q ( $pass ));
}
2007-08-11 06:25:58 +00:00
}
2013-07-24 23:26:41 +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-12-03 21:02:04 +00:00
! grant ( " REVOKE " , $revoke , $match [ 2 ], " ON $match[1] FROM $new_user " ) //! SQL injection
|| ! grant ( " GRANT " , $grant , $match [ 2 ], " ON $match[1] TO $new_user " )
2009-06-13 20:04:22 +00:00
)) {
$error = true ;
break ;
2007-08-09 15:03:39 +00:00
}
}
}
2013-07-24 23:26:41 +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 )) {
2010-03-19 13:57:20 +00:00
grant ( " REVOKE " , array_keys ( $revoke ), $match [ 2 ], " ON $match[1] FROM $new_user " );
2007-08-09 15:03:39 +00:00
}
}
}
}
2013-07-24 23:26:41 +00:00
2009-10-13 20:01:52 +00:00
queries_redirect ( ME . " privileges= " , ( isset ( $_GET [ " host " ]) ? lang ( 'User has been altered.' ) : lang ( 'User has been created.' )), ! $error );
2013-07-24 23:26:41 +00:00
2011-08-12 15:45:14 +00:00
if ( $created ) {
2009-06-22 05:22:41 +00:00
// delete new user in case of an error
2009-09-22 10:51:40 +00:00
$connection -> query ( " DROP USER $new_user " );
2009-06-13 20:04:22 +00:00
}
2007-08-09 15:03:39 +00:00
}
}
2009-07-20 12:12:55 +00:00
2009-08-29 13:57:50 +00:00
page_header (( isset ( $_GET [ " host " ]) ? lang ( 'Username' ) . " : " . h ( " $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 {
2010-04-21 12:01:32 +00:00
$row = $_GET + array ( " host " => $connection -> result ( " 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 ;
2010-04-26 16:24:00 +00:00
if ( $old_pass != " " ) {
$row [ " hashed " ] = true ;
}
2013-04-27 02:24:07 +00:00
$grants [( DB == " " || $grants ? " " : idf_escape ( addcslashes ( DB , " %_ \\ " ))) . " .* " ] = array ();
2007-08-09 15:03:39 +00:00
}
?>
< form action = " " method = " post " >
2009-05-01 10:41:33 +00:00
< table cellspacing = " 0 " >
2013-01-31 05:35:51 +00:00
< tr >< th >< ? php echo lang ( 'Server' ); ?> <td><input name="host" maxlength="60" value="<?php echo h($row["host"]); ?>" autocapitalize="off">
< tr >< th >< ? php echo lang ( 'Username' ); ?> <td><input name="user" maxlength="16" value="<?php echo h($row["user"]); ?>" autocapitalize="off">
< tr >< th >< ? php echo lang ( 'Password' ); ?> <td><input name="pass" id="pass" value="<?php echo h($row["pass"]); ?>">
2018-01-11 10:55:17 +00:00
< ? php if ( ! $row [ " hashed " ]) { ?> <script type="text/javascript">typePassword(qs('#pass'));</script><?php } ?>
2009-12-17 13:22:28 +00:00
< ? php echo checkbox ( " hashed " , 1 , $row [ " hashed " ], lang ( 'Hashed' ), " typePassword(this.form['pass'], this.checked); " ); ?>
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 " ;
2013-08-06 01:55:27 +00:00
echo " <thead><tr><th colspan='2'> " . lang ( 'Privileges' ) . doc_link ( array ( 'sql' => " grant.html#priv_level " ));
2007-08-09 15:03:39 +00:00
$i = 0 ;
2008-01-08 15:46:32 +00:00
foreach ( $grants as $object => $grant ) {
2013-01-31 05:35:51 +00:00
echo '<th>' . ( $object != " *.* " ? " <input name='objects[ $i ]' value=' " . h ( $object ) . " ' size='10' autocapitalize='off'> " : " <input type='hidden' name='objects[ $i ]' value='*.*' size='10'>*.* " ); //! separate db, table, columns, PROCEDURE|FUNCTION, routine
2008-01-08 15:46:32 +00:00
$i ++ ;
}
2009-07-11 20:30:40 +00:00
echo " </thead> \n " ;
2013-05-02 01:28:04 +00:00
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-07-28 16:20:50 +00:00
echo " <tr " . odd () . " ><td " . ( $desc ? " > $desc <td " : " colspan='2' " ) . ' lang="en" title="' . h ( $comment ) . '">' . h ( $privilege );
2008-01-08 15:46:32 +00:00
$i = 0 ;
2007-08-09 15:03:39 +00:00
foreach ( $grants as $object => $grant ) {
2009-07-28 16:20:50 +00:00
$name = " 'grants[ $i ][ " . h ( strtoupper ( $privilege )) . " ]' " ;
2008-01-08 15:46:32 +00:00
$value = $grant [ strtoupper ( $privilege )];
2011-12-21 16:52:45 +00:00
if ( $context == " Server Admin " && $object != ( isset ( $grants [ " *.* " ]) ? " *.* " : " .* " )) {
2009-07-11 20:30:40 +00:00
echo " <td> " ;
2008-01-08 15:46:32 +00:00
} elseif ( isset ( $_GET [ " grant " ])) {
2009-07-28 16:28:47 +00:00
echo " <td><select name= $name ><option><option value='1' " . ( $value ? " selected " : " " ) . " > " . lang ( 'Grant' ) . " <option value='0' " . ( $value == " 0 " ? " selected " : " " ) . " > " . lang ( 'Revoke' ) . " </select> " ;
2008-01-08 15:46:32 +00:00
} else {
2013-05-20 17:06:23 +00:00
echo " <td align='center'><label class='block'><input type='checkbox' name= $name value='1' " . ( $value ? " checked " : " " ) . ( $privilege == " All privileges " ? " id='grants- $i -all' " : ( $privilege == " Grant option " ? " " : " onclick= \" if (this.checked) formUncheck('grants- $i -all'); \" " )) . " ></label> " ; //! uncheck all except grant if all is checked
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
}
}
}
2013-05-02 01:28:04 +00:00
2008-01-08 15:46:32 +00:00
echo " </table> \n " ;
2007-08-09 15:03:39 +00:00
?>
< p >
2009-07-11 20:30:40 +00:00
< input type = " submit " value = " <?php echo lang('Save'); ?> " >
2010-10-18 21:57:39 +00:00
< ? php if ( isset ( $_GET [ " host " ])) { ?> <input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?>
2011-03-08 12:43:05 +00:00
< input type = " hidden " name = " token " value = " <?php echo $token ; ?> " >
2007-08-09 15:03:39 +00:00
</ form >