Fix 1036747: Remove priv checks from pt-table-sync

This commit is contained in:
Brian Fraser
2012-08-16 18:06:49 -03:00
parent 1481494ef1
commit 0ac09e77b4
3 changed files with 9 additions and 97 deletions

View File

@@ -6140,30 +6140,6 @@ sub lock_and_wait {
return $result; return $result;
} }
sub have_all_privs {
my ( $self, $dbh, $db, $tbl ) = @_;
my $db_tbl = $self->{Quoter}->quote($db, $tbl);
my $sql = "SHOW FULL COLUMNS FROM $db_tbl";
PTDEBUG && _d('Permissions check:', $sql);
my $cols = $dbh->selectall_arrayref($sql, {Slice => {}});
my ($hdr_name) = grep { m/privileges/i } keys %{$cols->[0]};
my $privs = $cols->[0]->{$hdr_name};
$sql = "DELETE FROM $db_tbl LIMIT 0"; # FULL COLUMNS doesn't show all privs
PTDEBUG && _d('Permissions check:', $sql);
eval { $dbh->do($sql); };
my $can_delete = $EVAL_ERROR ? 0 : 1;
PTDEBUG && _d('User privs on', $db_tbl, ':', $privs,
($can_delete ? 'delete' : ''));
if ( $privs =~ m/select/ && $privs =~ m/insert/ && $privs =~ m/update/
&& $can_delete ) {
PTDEBUG && _d('User has all privs');
return 1;
}
PTDEBUG && _d('User does not have all privs');
return 0;
}
sub _d { sub _d {
my ($package, undef, $line) = caller 0; my ($package, undef, $line) = caller 0;
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; } @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
@@ -9296,7 +9272,7 @@ sub make_action_subs {
my ( $sql, $dbh ) = @_; my ( $sql, $dbh ) = @_;
# Use $dbh if given. It's from a bidirectional callback. # Use $dbh if given. It's from a bidirectional callback.
$dbh ||= $change_dbh; $dbh ||= $change_dbh;
PTDEBUG && _d('Execute on dbh', $dbh, $sql); PTDEBUG && _d('Execute on dbh', $dbh, $sql);;
$dbh->do($sql); $dbh->do($sql);
}; };
} }
@@ -9503,21 +9479,6 @@ sub ok_to_sync {
. $dp->as_string($dst->{dsn}) . "\n"; . $dp->as_string($dst->{dsn}) . "\n";
} }
# Check that the user has all the necessary privs on the tbls.
if ( $o->get('check-privileges') ) {
PTDEBUG && _d('Checking privileges');
if ( !$syncer->have_all_privs($src->{dbh}, $src->{db}, $src->{tbl}) ) {
my $user = get_current_user($src->{dbh}) || "";
die "User $user does not have all necessary privileges on ",
$q->quote($src->{db}, $src->{tbl});
}
if ( !$syncer->have_all_privs($dst->{dbh}, $dst->{db}, $dst->{tbl}) ) {
my $user = get_current_user($dst->{dbh}) || "";
die "User $user does not have all necessary privileges on ",
$q->quote($dst->{db}, $dst->{tbl});
}
}
# Check that no triggers are defined on the dst tbl. # Check that no triggers are defined on the dst tbl.
if ( $o->get('check-triggers') ) { if ( $o->get('check-triggers') ) {
PTDEBUG && _d('Checking for triggers'); PTDEBUG && _d('Checking for triggers');
@@ -10423,12 +10384,6 @@ default: yes
With L<"--sync-to-master">, try to verify that the detected With L<"--sync-to-master">, try to verify that the detected
master is the real master. master is the real master.
=item --[no]check-privileges
default: yes
Check that user has all necessary privileges on source and destination table.
=item --[no]check-slave =item --[no]check-slave
default: yes default: yes

View File

@@ -618,34 +618,6 @@ sub lock_and_wait {
return $result; return $result;
} }
# This query will check all needed privileges on the table without actually
# changing anything in it. We can't use REPLACE..SELECT because that doesn't
# work inside of LOCK TABLES. Returns 1 if user has all needed privs to
# sync table, else returns 0.
sub have_all_privs {
my ( $self, $dbh, $db, $tbl ) = @_;
my $db_tbl = $self->{Quoter}->quote($db, $tbl);
my $sql = "SHOW FULL COLUMNS FROM $db_tbl";
PTDEBUG && _d('Permissions check:', $sql);
my $cols = $dbh->selectall_arrayref($sql, {Slice => {}});
my ($hdr_name) = grep { m/privileges/i } keys %{$cols->[0]};
my $privs = $cols->[0]->{$hdr_name};
$sql = "DELETE FROM $db_tbl LIMIT 0"; # FULL COLUMNS doesn't show all privs
PTDEBUG && _d('Permissions check:', $sql);
eval { $dbh->do($sql); };
my $can_delete = $EVAL_ERROR ? 0 : 1;
PTDEBUG && _d('User privs on', $db_tbl, ':', $privs,
($can_delete ? 'delete' : ''));
if ( $privs =~ m/select/ && $privs =~ m/insert/ && $privs =~ m/update/
&& $can_delete ) {
PTDEBUG && _d('User has all privs');
return 1;
}
PTDEBUG && _d('User does not have all privs');
return 0;
}
sub _d { sub _d {
my ($package, undef, $line) = caller 0; my ($package, undef, $line) = caller 0;
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; } @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }

View File

@@ -27,9 +27,6 @@ if ( !$master_dbh ) {
elsif ( !$slave_dbh ) { elsif ( !$slave_dbh ) {
plan skip_all => 'Cannot connect to sandbox slave'; plan skip_all => 'Cannot connect to sandbox slave';
} }
else {
plan tests => 3;
}
$sb->wipe_clean($master_dbh); $sb->wipe_clean($master_dbh);
$sb->wipe_clean($slave_dbh); $sb->wipe_clean($slave_dbh);
@@ -55,31 +52,18 @@ $slave_dbh->do('insert into issue_907.t values (1)');
# On 5.1 user needs SUPER to set binlog_format, which mk-table-sync does. # On 5.1 user needs SUPER to set binlog_format, which mk-table-sync does.
`/tmp/12345/use -uroot -e "GRANT SUPER, SELECT, SHOW DATABASES ON *.* TO 'test_907'\@'localhost' IDENTIFIED BY 'msandbox'"`; `/tmp/12345/use -uroot -e "GRANT SUPER, SELECT, SHOW DATABASES ON *.* TO 'test_907'\@'localhost' IDENTIFIED BY 'msandbox'"`;
#2) run and get output to see what it's like when it's broken. #2) run again to see what output is like when it works
$output = output( chomp($output = output(
sub { pt_table_sync::main(@args) }, sub { pt_table_sync::main(@args) },
stderr => 1,
);
like(
$output,
qr/User test_907\@localhost does not have all necessary privileges/,
"Can't --print without all privs"
);
#3) run again to see what output is like when it works
$output = output(
sub { pt_table_sync::main(@args, '--no-check-privileges') },
stderr => 1,
trf => \&remove_traces, trf => \&remove_traces,
); ));
is( is(
$output, $output,
"DELETE FROM `issue_907`.`t` WHERE `i`='1' LIMIT 1; "DELETE FROM `issue_907`.`t` WHERE `i`='1' LIMIT 1;",
", "Privs are not checked, can --print without extra options"
"Can --print without all privs and --no-check-privileges"
); );
#4) clean up user #3) clean up user
$master_dbh->do('DROP USER \'test_907\'@\'localhost\''); $master_dbh->do('DROP USER \'test_907\'@\'localhost\'');
# ############################################################################# # #############################################################################
@@ -88,4 +72,5 @@ $master_dbh->do('DROP USER \'test_907\'@\'localhost\'');
$sb->wipe_clean($master_dbh); $sb->wipe_clean($master_dbh);
$sb->wipe_clean($slave_dbh); $sb->wipe_clean($slave_dbh);
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
exit;
done_testing;