mirror of
https://github.com/percona/percona-toolkit.git
synced 2026-05-17 01:01:27 +08:00
PT-2247 - pt-show-grants does not CREATE USER
- Removed option print_identified_with_as_hex, because it was already implemented in the PT-2190 fix - Simplified patch - Kept CREATE USER/ALTER USER sequence and extra DELETE from mysql.user table - Added test case
This commit is contained in:
Regular → Executable
+29
-50
@@ -2062,51 +2062,34 @@ sub main {
|
||||
|
||||
# If MySQL 5.7.6+ then we need to use SHOW CREATE USER
|
||||
my @create_user;
|
||||
if (( VersionCompare::cmp($version, '5.7.6') >= 0 ) ||
|
||||
( VersionCompare::cmp($version, '10.0.0') <= 0 )) {
|
||||
if ( ( VersionCompare::cmp($version, '5.7.6') >= 0 ) ) {
|
||||
eval {
|
||||
if (!($version =~ m/MariaDB/) && ( VersionCompare::cmp($version, '8.0.17') >= 0 ) && ($o->get('print_identified_with_as_hex'))){
|
||||
$dbh->do("SET print_identified_with_as_hex=1") or die();
|
||||
print "-- Setting print_identified_with_as_hex as ACTIVE at session level for correct export/import\n";
|
||||
}
|
||||
@create_user = @{ $dbh->selectcol_arrayref("SHOW CREATE USER $user_host") };
|
||||
};
|
||||
if ( $EVAL_ERROR ) {
|
||||
PTDEBUG && _d($EVAL_ERROR);
|
||||
$exit_status = 1;
|
||||
}
|
||||
if ($#create_user >= 0){
|
||||
PTDEBUG && _d('CreateUser:', Dumper(\@create_user));
|
||||
#given caching_sha2_password issue we need to select the password in binary format and replace the one coming from the create
|
||||
#my $query = "SELECT authentication_string as sha2, convert(authentication_string using Binary) as bin from mysql.user where user='$u->{User}' and host='$u->{Host}'";
|
||||
my $query = "SELECT authentication_string sha2 from mysql.user where user='$u->{User}' and host='$u->{Host}'";
|
||||
PTDEBUG && _d('get password:', Dumper($query));
|
||||
my ( $pw_sha2) = $dbh->selectrow_array($query);
|
||||
my $pw_bin = $pw_sha2;
|
||||
$pw_bin =~ s/(.)/sprintf '%02X', ord $1/seg;
|
||||
$pw_bin = "0x".$pw_bin;
|
||||
|
||||
# make this replication safe converting the CREATE USER into
|
||||
if ( $#create_user >= 0 ) {
|
||||
PTDEBUG && _d('CREATE USER:', Dumper(\@create_user));
|
||||
|
||||
# Make this replication safe converting the CREATE USER into
|
||||
# CREATE USER IF NOT EXISTS and then doing an ALTER USER
|
||||
my $create = $create_user[0];
|
||||
my $alter = $create_user[0];
|
||||
$create =~ s{CREATE USER}{CREATE USER IF NOT EXISTS};
|
||||
$create =~ s{ IDENTIFIED VIA }{ IDENTIFIED AS };
|
||||
$create =~ s{ BY }{ AS };
|
||||
if (( $create =~ m/caching_sha2_password/ ) && !($o->get('print_identified_with_as_hex'))) {
|
||||
print "-- Converting $user_host caching_sha2_password to binary for correct export/import\n";
|
||||
$create =~ s/\sAS\s.*'\s/ AS $pw_bin /g;
|
||||
}
|
||||
$alter =~ s{CREATE USER}{ALTER USER};
|
||||
# Alter user should not be pass in the latest MySQL version
|
||||
#we need to cleanup other MariaDB diversions
|
||||
if ( ($version =~ m/MariaDB/) && $o->get('convert-MariaDB')){
|
||||
$create =~ s{ AS.*PASSWORD }{ AS };
|
||||
$create =~ s/IDENTIFIED.*USING.*unix_socket.*/IDENTIFIED WITH auth_socket/;
|
||||
$create =~ s/IDENTIFIED AS/IDENTIFIED WITH mysql_native_password AS/;
|
||||
}
|
||||
@create_user = ( $create);
|
||||
PTDEBUG && _d('AdjustedCreateUser:', Dumper(\@create_user));
|
||||
my $create = $create_user[0];
|
||||
my $alter = $create;
|
||||
$create =~ s{CREATE USER}{CREATE USER IF NOT EXISTS};
|
||||
$create =~ s{ IDENTIFIED .*}{};
|
||||
$alter =~ s{CREATE USER}{ALTER USER};
|
||||
|
||||
# We need to cleanup MariaDB diversions
|
||||
if ( ($version =~ m/MariaDB/) && $o->get('convert-MariaDB')){
|
||||
$create =~ s{ AS.*PASSWORD }{ AS };
|
||||
$create =~ s/IDENTIFIED.*USING.*unix_socket.*/IDENTIFIED WITH auth_socket/;
|
||||
$create =~ s/IDENTIFIED AS/IDENTIFIED WITH mysql_native_password AS/;
|
||||
}
|
||||
|
||||
@create_user = ( $create, $alter );
|
||||
PTDEBUG && _d('Adjusted CREATE USER:', Dumper(\@create_user));
|
||||
}
|
||||
}
|
||||
my @grants;
|
||||
@@ -2117,13 +2100,15 @@ sub main {
|
||||
PTDEBUG && _d($EVAL_ERROR);
|
||||
$exit_status = 1;
|
||||
}
|
||||
#IF is MariaDB we need to remove the password from the user
|
||||
if (($version =~ m/MariaDB/)){
|
||||
for my $i (0 .. $#grants){
|
||||
|
||||
# We need to remove password form the user grants when dump MariaDB
|
||||
if ( $version =~ m/MariaDB/ ){
|
||||
PTDEBUG && _d('Original Grants - MariaDB:', Dumper(\@grants));
|
||||
for my $i (0 .. $#grants){
|
||||
$grants[$i] =~ s{IDENTIFIED.*}{};
|
||||
}
|
||||
PTDEBUG && _d('Grants:', Dumper(\@grants));
|
||||
}
|
||||
}
|
||||
|
||||
PTDEBUG && _d('Grants:', Dumper(\@grants));
|
||||
next unless @grants;
|
||||
|
||||
@@ -2204,7 +2189,7 @@ sub main {
|
||||
if ( $o->get('drop') && !defined($u->{IsRole}) ) {
|
||||
print join("\n",
|
||||
"DROP USER IF EXISTS $user_host;",
|
||||
#"DELETE FROM `mysql`.`user` WHERE `User`='$u->{User}' AND `Host`='$u->{Host}';",
|
||||
"DELETE FROM `mysql`.`user` WHERE `User`='$u->{User}' AND `Host`='$u->{Host}';",
|
||||
), "\n";
|
||||
}
|
||||
|
||||
@@ -2492,13 +2477,7 @@ Only show grants for this comma-separated list of users.
|
||||
|
||||
=item --convert-MariaDB
|
||||
|
||||
When set it convert some of the proprietary MariaDB syntax into valid MySQL form
|
||||
|
||||
=item --print_identified_with_as_hex
|
||||
|
||||
Enabling print_identified_with_as_hex causes SHOW CREATE USER to display such hash values as hexadecimal strings rather than as regular string literals.
|
||||
Hash values that do not contain unprintable characters still display as regular string literals, even with this variable enabled.
|
||||
|
||||
Convert proprietary MariaDB syntax into valid MySQL form
|
||||
|
||||
=item --password
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
BEGIN {
|
||||
die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
|
||||
unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
|
||||
unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
|
||||
};
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use English qw(-no_match_vars);
|
||||
use Test::More;
|
||||
|
||||
use PerconaTest;
|
||||
use Sandbox;
|
||||
use SqlModes;
|
||||
use VersionParser;
|
||||
require "$trunk/bin/pt-show-grants";
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $dbh = $sb->get_dbh_for('master');
|
||||
|
||||
if ( !$dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox master';
|
||||
}
|
||||
|
||||
if ( VersionParser->new($dbh)->flavor !~ m/maria/i ) {
|
||||
plan skip_all => "This test requires MariaDB";
|
||||
}
|
||||
|
||||
$sb->wipe_clean($dbh);
|
||||
|
||||
my $output;
|
||||
my $cnf = '/tmp/12345/my.sandbox.cnf';
|
||||
|
||||
diag(`/tmp/12345/use -u root -e "CREATE USER 'sally'\@'%' IDENTIFIED BY 'A005?>6LZe1'"`);
|
||||
|
||||
ok(
|
||||
`/tmp/12345/use -s -u sally -p'A005?>6LZe1' -e "SELECT 1" 2>/dev/null`,
|
||||
'User sally can log in before tests'
|
||||
);
|
||||
|
||||
$output = output(
|
||||
sub { pt_show_grants::main('-F', $cnf, qw(--only sally)); }
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/CREATE USER IF NOT EXISTS `sally`@`%`;/,
|
||||
'CREATE USER printed'
|
||||
) or diag($output);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/ALTER USER `sally`@`%` IDENTIFIED BY PASSWORD '\*A5C09B5E9542E3C716E3E0A711336D9ABB48D89F';/,
|
||||
'ALTER USER printed'
|
||||
) or diag($output);
|
||||
|
||||
diag(`/tmp/12345/use -u root -e "DROP USER 'sally'\@'%'"`);
|
||||
open(my $pipe, '|-', '/tmp/12345/use -u root');
|
||||
print $pipe $output;
|
||||
close($pipe);
|
||||
|
||||
ok(
|
||||
`/tmp/12345/use -s -u sally -p'A005?>6LZe1' -e "SELECT 1" 2>/dev/null`,
|
||||
'User sally can log in'
|
||||
) or diag($output);
|
||||
|
||||
diag(`/tmp/12345/use -u root -e "DROP USER 'sally'\@'%'"`);
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
$sb->wipe_clean($dbh);
|
||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||
done_testing;
|
||||
Reference in New Issue
Block a user