#At file:///Users/cbell/source/bzr/mysql-6.0-bug-44787/ based on revid:ritheesh.vedire@stripped
2889 Chuck Bell 2009-11-13
BUG#44787 : Backup: Check privileges before executing BACKUP/RESTORE
There are three problems that have been identified for this bug.
1) Restore can fail in the middle if the user does not have
sufficient privileges to create and populate all of the
objects. This patch implements a privilege precheck step to check
all objects for proper access. If any object fails the
privilege check, restore halts with an error. The object-level
privileges checked include the following.
RESTORE,CREATE,DROP on db.*
CREATE on db.x (if table or view x)
CREATE_TABLESPACE on *.* (if tablespace)
SUPER on *.* (if view, stored routine, event or trigger)
CREATE_PROC on db.* (if stored routine)
EVENT on db.* (if event)
GRANT on db.* (if privilege)
TRIGGER on db.* (if trigger but table not found)
TRIGGER on db.t (if trigger on t)
2) The backup system must be changed to permit the
elevation of privileges for backup if the user has the
BACKUP_ACL privilege and elevation of privileges for restore
if the user has the RESTORE_ACL on all databases and the
global SUPER_ACL privilege. This patch implements the privilege
elevation change for backup as well as privilege elevation for
restore. The restore will fall back to object-level privilege
checking if the conditions for restore are not met.
3) The backup system must be changed to allow users to adjust the
privilege behavior of MySQL Backup by allowing them
to turn off backup elevation, restore elevation, and restore
prechecking using startup options and/or variables. This patch
implements startup options and variables to do the following:
backup_elevation
ON = turn on backup elevation
OFF = turn off backup elevation
Note: Default is ON
restore_elevation
ON = turn on restore elevation
OFF = turn off restore elevation
Note: Default is ON
restore_precheck
ON = turn on restore precheck
OFF = turn off restore precheck
Note: Default is ON
@ mysql-test/suite/backup/include/error_name_to_number.inc
Added new error code for debug testing.
@ mysql-test/suite/backup/r/backup_errors_debug_3.result
Corrected result file.
@ mysql-test/suite/backup/r/backup_restore_security.result
New result file.
@ mysql-test/suite/backup/r/backup_security.result
Corrected result file.
@ mysql-test/suite/backup/r/backup_security_options.result
New test for testing startup options.
@ mysql-test/suite/backup/r/backup_security_var.result
New result file.
@ mysql-test/suite/backup/t/backup_errors_debug_3.test
Added new test cases for debug error testing of new errors.
@ mysql-test/suite/backup/t/backup_restore_security.test
New test for testing restore security prechecks.
@ mysql-test/suite/backup/t/backup_security.test
Corrected errors now that restore prechecking is complete.
@ mysql-test/suite/backup/t/backup_security_options-master.opt
Option file to disable all options.
@ mysql-test/suite/backup/t/backup_security_options.test
New test for testing startup options.
@ mysql-test/suite/backup/t/backup_security_var.test
New test for testing new variables.
@ sql/backup/CMakeLists.txt
Added new source file.
@ sql/backup/Makefile.am
Added new source file.
@ sql/backup/backup_info.cc
Added code for backup elevation.
@ sql/backup/backup_kernel.h
Added parameter for checking elevation.
@ sql/backup/kernel.cc
Added calls to save original privileges and elevate
privileges if conditions are met.
Included checks for options and variables to turn off
prechecking, backup elevation, and restore elevation.
@ sql/backup/restore_info.h
Added parameter for controlling prechecking.
Moved privilege checking to new prechecking method.
@ sql/mysqld.cc
Added startup options.
@ sql/set_var.cc
Added variable classes.
@ sql/share/errmsg-utf8.txt
New error messages.
@ sql/share/errmsg.txt
New error messages.
@ sql/si_objects.cc
Removed privilege elevation from si_objects code.
@ sql/sql_class.cc
Added variable classes.
@ sql/sql_class.h
Added variable declarations.
@ sql/sql_parse.cc
Added parameter for skipping prechecking.
added:
mysql-test/suite/backup/r/backup_restore_security.result
mysql-test/suite/backup/r/backup_security_options.result
mysql-test/suite/backup/r/backup_security_var.result
mysql-test/suite/backup/t/backup_restore_security.test
mysql-test/suite/backup/t/backup_security_options-master.opt
mysql-test/suite/backup/t/backup_security_options.test
mysql-test/suite/backup/t/backup_security_var.test
modified:
mysql-test/suite/backup/include/error_name_to_number.inc
mysql-test/suite/backup/r/backup_errors_debug_3.result
mysql-test/suite/backup/r/backup_security.result
mysql-test/suite/backup/t/backup_errors_debug_3.test
mysql-test/suite/backup/t/backup_security.test
sql/backup/CMakeLists.txt
sql/backup/Makefile.am
sql/backup/backup_info.cc
sql/backup/backup_kernel.h
sql/backup/kernel.cc
sql/backup/restore_info.h
sql/mysqld.cc
sql/set_var.cc
sql/share/errmsg-utf8.txt
sql/share/errmsg.txt
sql/si_objects.cc
sql/sql_class.cc
sql/sql_class.h
sql/sql_parse.cc
=== modified file 'mysql-test/suite/backup/include/error_name_to_number.inc'
--- a/mysql-test/suite/backup/include/error_name_to_number.inc 2009-09-10 13:31:31 +0000
+++ b/mysql-test/suite/backup/include/error_name_to_number.inc 2009-11-13 18:19:21 +0000
@@ -123,3 +123,4 @@
--LET $ER_BACKUP_ACCESS_DENIED_ERROR = 1793
--LET $ER_BACKUP_ACCESS_DBS_INCOMPLETE = 1795
--LET $ER_BACKUP_ACCESS_OBJS_INCOMPLETE = 1796
+--LET $ER_RESTORE_DB_ERROR = 1800
\ No newline at end of file
=== modified file 'mysql-test/suite/backup/r/backup_errors_debug_3.result'
--- a/mysql-test/suite/backup/r/backup_errors_debug_3.result 2009-09-10 13:31:31 +0000
+++ b/mysql-test/suite/backup/r/backup_errors_debug_3.result 2009-11-13 18:19:21 +0000
@@ -1264,8 +1264,54 @@ backup_id
#
# Done.
#
+SET @@global.restore_elevation = OFF;
+SHOW GLOBAL VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation OFF
+SHOW VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation OFF
#
-# Test case 69 - testing error ER_BACKUP_UNEXPECTED_DATA
+# Test case 69 - testing error ER_RESTORE_DB_ERROR
+#
+# Set debug SESSION variable for ER_RESTORE_DB_ERROR
+#
+SET SESSION debug="+d,ER_RESTORE_DB_ERROR";
+#
+# Execute restore
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+ERROR HY000: The database for object 't1' was not found in the catalog.
+#
+# Test case for error ER_RESTORE_DB_ERROR PASSED.
+#
+#
+# Show warning/error from progress and history log
+# if they exist.
+#
+SELECT * FROM mysql.backup_progress WHERE error_num <> 0;
+backup_id object error_num notes
+# #### The database for object 't1' was not found in the catalog.
+PURGE BACKUP LOGS;
+#
+# Turn off debug SESSION.
+#
+SET SESSION debug="-d";
+#
+# Now demonstrate that the command will work without the
+# debug session tag.
+#
+# Running restore - should not fail.
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+backup_id
+#
+#
+# Done.
+#
+SET @@global.restore_elevation = ON;
+#
+# Test case 70 - testing error ER_BACKUP_UNEXPECTED_DATA
#
# Set debug SESSION variable for ER_BACKUP_UNEXPECTED_DATA
#
@@ -1306,7 +1352,7 @@ DROP DATABASE test_empty;
# Done.
#
#
-# Test case 70 - testing error ER_BACKUP_WRONG_TABLE_BE
+# Test case 71 - testing error ER_BACKUP_WRONG_TABLE_BE
#
# Set debug SESSION variable for ER_BACKUP_WRONG_TABLE_BE
#
=== added file 'mysql-test/suite/backup/r/backup_restore_security.result'
--- a/mysql-test/suite/backup/r/backup_restore_security.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_restore_security.result 2009-11-13 18:19:21 +0000
@@ -0,0 +1,402 @@
+DROP DATABASE IF EXISTS backup_test;
+DROP DATABASE IF EXISTS backup_test_alt;
+#
+# Create users.
+#
+CREATE USER 'bup_some_priv'@'localhost';
+CREATE USER 'joe'@'user';
+#
+# Use the basic data setup in backup_test database.
+#
+#
+# Create database and data to test.
+#
+CREATE DATABASE backup_test;
+CREATE TABLE backup_test.t1 (a char(30)) ENGINE=MEMORY;
+INSERT INTO backup_test.t1 VALUES ("01 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("02 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("03 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("04 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("05 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("06 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("07 Test Basic database example");
+CREATE TABLE backup_test.t2 (a char(30)) ENGINE=MYISAM;
+INSERT INTO backup_test.t2 VALUES ("11 Test Basic database example");
+INSERT INTO backup_test.t2 VALUES ("12 Test Basic database example");
+INSERT INTO backup_test.t2 VALUES ("13 Test Basic database example");
+#
+# Now create more database objects for test.
+#
+CREATE PROCEDURE backup_test.p1(p1 CHAR(20))
+INSERT INTO backup_test.t1 VALUES ("50");
+CREATE TRIGGER backup_test.trg AFTER INSERT ON backup_test.t1 FOR EACH ROW
+INSERT INTO backup_test.t1 VALUES('Test objects count');
+CREATE FUNCTION backup_test.f1() RETURNS INT RETURN (SELECT 1);
+CREATE VIEW backup_test.v1 as SELECT * FROM backup_test.t1;
+CREATE EVENT backup_test.e1 ON SCHEDULE EVERY 1 YEAR DO
+DELETE FROM backup_test.t1 WHERE a = "not there";
+#
+# Now we need some privileges
+#
+GRANT ALL ON backup_test.* TO 'joe'@'user';
+#
+# Create a second database for testing multiple database privilege
+# checking.
+#
+CREATE DATABASE backup_test_alt;
+CREATE TABLE backup_test_alt.t1 (a int);
+INSERT INTO backup_test_alt.t1 VALUES (10), (11), (12);
+#
+# Revoke grants for bup_some_priv
+#
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT USAGE ON *.* TO 'bup_some_priv'@'localhost'
+#
+# conn_root_user: Do backup of database with root user for later tests.
+#
+BACKUP DATABASE backup_test to 'backup_test_orig.bak';
+backup_id
+#
+BACKUP DATABASE backup_test, backup_test_alt to 'backup_test_orig_alt1.bak';
+backup_id
+#
+BACKUP DATABASE backup_test_alt, backup_test to 'backup_test_orig_alt2.bak';
+backup_id
+#
+#
+# Show list of all objects in the database.
+#
+SHOW FULL TABLES FROM backup_test;
+Tables_in_backup_test Table_type
+t1 BASE TABLE
+t2 BASE TABLE
+v1 VIEW
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'backup_test';
+event_name
+e1
+SELECT routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_schema = 'backup_test';
+routine_name
+f1
+p1
+SELECT trigger_name FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'backup_test';
+trigger_name
+trg
+#
+# conn_root_user: Do backup of database with root user without
+# stored procedures for later tests.
+#
+DROP PROCEDURE backup_test.p1;
+DROP FUNCTION backup_test.f1;
+BACKUP DATABASE backup_test to 'backup_test_no_proc.bak';
+backup_id
+#
+#
+# Test Case 1 : Ensure a user with only RESTORE on db1.* cannot restore
+# the database.
+#
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+GRANT CREATE, DROP ON backup_test.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT USAGE ON *.* TO 'bup_some_priv'@'localhost'
+GRANT CREATE, DROP, RESTORE ON `backup_test`.* TO 'bup_some_priv'@'localhost'
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should fail with
+# error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+ERROR HY000: Insufficient privileges. You do not have privileges to restore the object 'p1' from this backup image.
+SHOW ERRORS;
+Level Code Message
+Error # Insufficient privileges. You do not have privileges to restore the object 'p1' from this backup image.
+#
+# Test Case 2 : Ensure a user with only SELECT on db1.* cannot restore
+# the database.
+#
+#
+# Connect as root and add privileges.
+#
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT SELECT ON backup_test.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT USAGE ON *.* TO 'bup_some_priv'@'localhost'
+GRANT SELECT, CREATE, DROP, RESTORE ON `backup_test`.* TO 'bup_some_priv'@'localhost'
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should fail with
+# error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+ERROR HY000: Insufficient privileges. You do not have privileges to restore the object 'p1' from this backup image.
+SHOW ERRORS;
+Level Code Message
+Error # Insufficient privileges. You do not have privileges to restore the object 'p1' from this backup image.
+#
+# Test Case 3 : Show that SUPER is needed to complete restore
+# when there are objects with definer clauses.
+#
+#
+# Connect as root and add privileges.
+#
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+GRANT ALL ON mysql.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT USAGE ON *.* TO 'bup_some_priv'@'localhost'
+GRANT ALL PRIVILEGES ON `mysql`.* TO 'bup_some_priv'@'localhost'
+GRANT ALL PRIVILEGES ON `backup_test`.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should fail with
+# ER_RESTORE_ACCESS_DEFINER
+#
+RESTORE FROM 'backup_test_no_proc.bak' OVERWRITE;
+ERROR HY000: Insufficient privileges. You must have the SUPER privilege to restore the object 'backup_test'.'v1'.
+SHOW ERRORS;
+Level Code Message
+Error # Insufficient privileges. You must have the SUPER privilege to restore the object 'backup_test'.'v1'.
+#
+# Test Case 4 : Ensure a user can only restore the database if and only
+# if she has all of the required permissions to create and
+# populate all objects.
+#
+#
+# Connect as root and add privileges.
+#
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+GRANT SELECT ON mysql.* TO 'bup_some_priv'@'localhost';
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost'
+GRANT ALL PRIVILEGES ON `mysql`.* TO 'bup_some_priv'@'localhost'
+GRANT ALL PRIVILEGES ON `backup_test`.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should succeed.
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+backup_id
+#
+#
+# Connect as root and cleanup.
+#
+#
+# Test Case 5 : Show that the privilege check on TRIGGER is required to
+# restore a table with a trigger.
+#
+# Perform a backup with only a table and a trigger.
+# No grants either.
+#
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+DROP USER 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+CREATE DATABASE backup_test_trig;
+CREATE TABLE backup_test_trig.t1 (a char(30)) ENGINE=MEMORY;
+CREATE TRIGGER backup_test_trig.trg AFTER INSERT ON backup_test_trig.t1 FOR EACH ROW
+INSERT INTO backup_test_trig.t1 VALUES('Test objects count');
+BACKUP DATABASE backup_test_trig TO 'backup_test_trig.bak';
+backup_id
+#
+CREATE USER 'bup_some_priv'@'localhost';
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT INSERT, UPDATE, DELETE, BACKUP, RESTORE, SELECT, CREATE, DROP
+ON backup_test_trig.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+GRANT SELECT ON mysql.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT USAGE ON *.* TO 'bup_some_priv'@'localhost'
+GRANT SELECT ON `mysql`.* TO 'bup_some_priv'@'localhost'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, BACKUP, RESTORE ON `backup_test_trig`.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should fail with
+# error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+#
+RESTORE FROM 'backup_test_trig.bak' OVERWRITE;
+ERROR HY000: Insufficient privileges. You do not have privileges to restore the object 'trg' from this backup image.
+SHOW ERRORS;
+Level Code Message
+Error # Insufficient privileges. You do not have privileges to restore the object 'trg' from this backup image.
+#
+# Connect as root and add privilege for trigger.
+#
+GRANT TRIGGER ON backup_test_trig.t1 TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should fail with
+# ER_RESTORE_ACCESS_DEFINER
+#
+RESTORE FROM 'backup_test_trig.bak' OVERWRITE;
+ERROR HY000: Insufficient privileges. You must have the SUPER privilege to restore the object 'backup_test_trig'.'trg'.
+SHOW ERRORS;
+Level Code Message
+Error 1799 Insufficient privileges. You must have the SUPER privilege to restore the object 'backup_test_trig'.'trg'.
+#
+# Connect as root and add privilege for trigger.
+# In this case, we must add SUPER to overcome limitation with
+# the definer clause.
+#
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should succeed.
+#
+RESTORE FROM 'backup_test_trig.bak' OVERWRITE;
+backup_id
+#
+#
+# Change privileges for elevated restore test case.
+#
+DROP DATABASE backup_test_trig;
+#
+# Test Case 8 : Show that user can have only RESTORE + SUPER and
+# perform an elevated restore.
+#
+DROP USER 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+CREATE USER 'bup_some_priv'@'localhost';
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should succeed.
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+backup_id
+#
+#
+# Change privileges for elevated restore test case.
+#
+#
+# Test Case 9 : Show that users who have RESTORE + SUPER for db1 but not
+# for db2 cannot restore the image.
+#
+DROP USER 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+CREATE USER 'bup_some_priv'@'localhost';
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should fail with
+# error ER_RESTORE_ACCESS_DENIED_ERROR
+#
+RESTORE FROM 'backup_test_orig_alt1.bak' OVERWRITE;
+ERROR HY000: Insufficient privileges. You must have the RESTORE privilege to restore database 'backup_test_alt'.
+SHOW ERRORS;
+Level Code Message
+Error 1794 Insufficient privileges. You must have the RESTORE privilege to restore database 'backup_test_alt'.
+#
+# conn_some_priv: Attempting restore. Should fail with
+# error ER_RESTORE_ACCESS_DENIED_ERROR
+#
+RESTORE FROM 'backup_test_orig_alt2.bak' OVERWRITE;
+ERROR HY000: Insufficient privileges. You must have the RESTORE privilege to restore database 'backup_test_alt'.
+SHOW ERRORS;
+Level Code Message
+Error 1794 Insufficient privileges. You must have the RESTORE privilege to restore database 'backup_test_alt'.
+#
+# Change privileges for elevated restore test case.
+#
+GRANT RESTORE ON backup_test_alt.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should succeed.
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+backup_id
+#
+#
+# Connect as root and cleanup.
+#
+#
+# Compare to original backup image file.
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+backup_id
+#
+#
+# Show list of all objects in the database.
+#
+SHOW FULL TABLES FROM backup_test;
+Tables_in_backup_test Table_type
+t1 BASE TABLE
+t2 BASE TABLE
+v1 VIEW
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'backup_test';
+event_name
+e1
+SELECT routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_schema = 'backup_test';
+routine_name
+f1
+p1
+SELECT trigger_name FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'backup_test';
+trigger_name
+trg
+#
+# Cleanup
+#
+DROP USER 'bup_some_priv'@'localhost';
+DROP USER 'joe'@'user';
+DROP DATABASE backup_test;
+DROP DATABASE backup_test_alt;
+FLUSH PRIVILEGES;
=== modified file 'mysql-test/suite/backup/r/backup_security.result'
--- a/mysql-test/suite/backup/r/backup_security.result 2009-10-23 21:26:11 +0000
+++ b/mysql-test/suite/backup/r/backup_security.result 2009-11-13 18:19:21 +0000
@@ -390,24 +390,24 @@ Tables_in_backup_test
# the user to backup the database but not restore it.
#
#
-# conn_user1: Attempting restore. Should fail with one of the restore
-# catalog errors.
+# conn_user1: Attempting restore. Should fail with
+# error ER_RESTORE_ACCESS_OBJS_INCOMPLETE.
#
RESTORE FROM 'bup_user1.bak' OVERWRITE;
-Got one of the listed errors
+ERROR HY000: Insufficient privileges. You do not have privileges to restore the object 'backup_test' from this backup image.
#
# Test 4 - Show that if a user has BACKUP on one database but not
# another, the user cannot perform a backup of both databases.
#
#
# conn_user1: Attempting backup. Should fail with
-# error ER_BACKUP_ACCESS_DENIED_ERROR
+# error ER_BAD_DB_ERROR
#
BACKUP DATABASE backup_test_alt to 'bup_no_priv.bak';
-ERROR HY000: Insufficient privileges. You must have the BACKUP privilege to backup database 'backup_test_alt'.
+ERROR 42000: Unknown database 'backup_test_alt'
SHOW ERRORS;
Level Code Message
-Error # Insufficient privileges. You must have the BACKUP privilege to backup database 'backup_test_alt'.
+Error # Unknown database 'backup_test_alt'
#
# conn_user1: Attempting backup. Should fail with
# error ER_BACKUP_ACCESS_DENIED_ERROR
=== added file 'mysql-test/suite/backup/r/backup_security_options.result'
--- a/mysql-test/suite/backup/r/backup_security_options.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_security_options.result 2009-11-13 18:19:21 +0000
@@ -0,0 +1,230 @@
+DROP DATABASE IF EXISTS backup_test;
+SHOW VARIABLES LIKE 'backup_elevation';
+Variable_name Value
+backup_elevation OFF
+SHOW VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation OFF
+SHOW VARIABLES LIKE 'restore_precheck';
+Variable_name Value
+restore_precheck OFF
+#
+# Create users.
+#
+CREATE USER 'bup_some_priv'@'localhost';
+#
+# Use the basic data setup in backup_test database.
+#
+#
+# Create database and data to test.
+#
+CREATE DATABASE backup_test;
+CREATE TABLE backup_test.t1 (a char(30)) ENGINE=MEMORY;
+INSERT INTO backup_test.t1 VALUES ("01 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("02 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("03 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("04 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("05 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("06 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("07 Test Basic database example");
+CREATE TABLE backup_test.t2 (a char(30)) ENGINE=MYISAM;
+INSERT INTO backup_test.t2 VALUES ("11 Test Basic database example");
+INSERT INTO backup_test.t2 VALUES ("12 Test Basic database example");
+INSERT INTO backup_test.t2 VALUES ("13 Test Basic database example");
+#
+# Now create more database objects for test.
+#
+CREATE PROCEDURE backup_test.p1(p1 CHAR(20))
+INSERT INTO backup_test.t1 VALUES ("50");
+CREATE TRIGGER backup_test.trg AFTER INSERT ON backup_test.t1 FOR EACH ROW
+INSERT INTO backup_test.t1 VALUES('Test objects count');
+CREATE FUNCTION backup_test.f1() RETURNS INT RETURN (SELECT 1);
+CREATE VIEW backup_test.v1 as SELECT * FROM backup_test.t1;
+CREATE EVENT backup_test.e1 ON SCHEDULE EVERY 1 YEAR DO
+DELETE FROM backup_test.t1 WHERE a = "not there";
+#
+# Now we need some privileges
+#
+GRANT ALL ON backup_test.* TO 'joe'@'user';
+#
+# Revoke grants for bup_some_priv
+#
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+REVOKE ALL ON backup_test.* FROM 'joe'@'user';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT USAGE ON *.* TO 'bup_some_priv'@'localhost'
+#
+# conn_root_user: Do backup of database with root user for later tests.
+#
+BACKUP DATABASE backup_test to 'backup_test_orig.bak';
+backup_id
+#
+#
+# Show list of all objects in the database.
+#
+SHOW FULL TABLES FROM backup_test;
+Tables_in_backup_test Table_type
+t1 BASE TABLE
+t2 BASE TABLE
+v1 VIEW
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'backup_test';
+event_name
+e1
+SELECT routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_schema = 'backup_test';
+routine_name
+f1
+p1
+SELECT trigger_name FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'backup_test';
+trigger_name
+trg
+#
+# Test Case 1 : Ensure backup_elevation = OFF fails for not enough
+# privileges.
+#
+GRANT BACKUP ON backup_test.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT USAGE ON *.* TO 'bup_some_priv'@'localhost'
+GRANT BACKUP ON `backup_test`.* TO 'bup_some_priv'@'localhost'
+SHOW VARIABLES LIKE 'backup_elevation';
+Variable_name Value
+backup_elevation OFF
+SET @@global.backup_elevation = OFF;
+SHOW VARIABLES LIKE 'backup_elevation';
+Variable_name Value
+backup_elevation OFF
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting backup. Should fail with
+# error ER_BACKUP_ACCESS_OBJS_INCOMPLETE
+#
+BACKUP DATABASE backup_test TO 'backup_test_fail.bak';
+ERROR HY000: Insufficient privileges. You do not have privileges to backup database 'backup_test'.
+SHOW ERRORS;
+Level Code Message
+Error # Insufficient privileges. You do not have privileges to backup database 'backup_test'.
+#
+# Connect as root and prepare next test case.
+#
+#
+# Test Case 2 : Ensure restore_elevation = OFF fails for not enough
+# privileges.
+#
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost'
+GRANT RESTORE ON `backup_test`.* TO 'bup_some_priv'@'localhost'
+SHOW VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation OFF
+SET @@global.restore_elevation = OFF;
+SHOW VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation OFF
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should fail with
+# error ER_BACKUP_CANT_RESTORE_DB
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+ERROR HY000: Could not restore database `backup_test`
+SHOW ERRORS;
+Level Code Message
+Error # Access denied for user 'bup_some_priv'@'localhost' to database 'backup_test'
+Error # Could not restore database `backup_test`
+#
+# Connect as root and prepare next test case.
+#
+#
+# Test Case 3 : Ensure restore_precheck = OFF fails for not enough
+# privileges (Restore will fail in the middle).
+#
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+REVOKE SUPER ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT USAGE ON *.* TO 'bup_some_priv'@'localhost'
+GRANT RESTORE ON `backup_test`.* TO 'bup_some_priv'@'localhost'
+SHOW VARIABLES LIKE 'restore_precheck';
+Variable_name Value
+restore_precheck OFF
+SET @@global.restore_elevation = OFF;
+SET @@global.restore_precheck = OFF;
+SHOW VARIABLES LIKE 'restore_precheck';
+Variable_name Value
+restore_precheck OFF
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should fail with
+# error ER_BACKUP_CANT_RESTORE_DB
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+ERROR HY000: Could not restore database `backup_test`
+SHOW ERRORS;
+Level Code Message
+Error # Access denied for user 'bup_some_priv'@'localhost' to database 'backup_test'
+Error # Could not restore database `backup_test`
+#
+# Connect as root and cleanup.
+#
+#
+# Compare to original backup image file.
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+backup_id
+#
+#
+# Show list of all objects in the database.
+#
+SHOW FULL TABLES FROM backup_test;
+Tables_in_backup_test Table_type
+t1 BASE TABLE
+t2 BASE TABLE
+v1 VIEW
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'backup_test';
+event_name
+e1
+SELECT routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_schema = 'backup_test';
+routine_name
+f1
+p1
+SELECT trigger_name FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'backup_test';
+trigger_name
+trg
+#
+# Cleanup
+#
+DROP USER 'bup_some_priv'@'localhost';
+DROP USER 'joe'@'user';
+SET @@global.backup_elevation = OFF;
+SET @@global.restore_elevation = OFF;
+SET @@global.restore_precheck = OFF;
+DROP DATABASE backup_test;
+FLUSH PRIVILEGES;
=== added file 'mysql-test/suite/backup/r/backup_security_var.result'
--- a/mysql-test/suite/backup/r/backup_security_var.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_security_var.result 2009-11-13 18:19:21 +0000
@@ -0,0 +1,482 @@
+DROP DATABASE IF EXISTS backup_test;
+SHOW VARIABLES LIKE 'backup_elevation';
+Variable_name Value
+backup_elevation ON
+SHOW VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation ON
+SHOW VARIABLES LIKE 'restore_precheck';
+Variable_name Value
+restore_precheck ON
+#
+# Create users.
+#
+CREATE USER 'bup_some_priv'@'localhost';
+#
+# Use the basic data setup in backup_test database.
+#
+#
+# Create database and data to test.
+#
+CREATE DATABASE backup_test;
+CREATE TABLE backup_test.t1 (a char(30)) ENGINE=MEMORY;
+INSERT INTO backup_test.t1 VALUES ("01 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("02 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("03 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("04 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("05 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("06 Test Basic database example");
+INSERT INTO backup_test.t1 VALUES ("07 Test Basic database example");
+CREATE TABLE backup_test.t2 (a char(30)) ENGINE=MYISAM;
+INSERT INTO backup_test.t2 VALUES ("11 Test Basic database example");
+INSERT INTO backup_test.t2 VALUES ("12 Test Basic database example");
+INSERT INTO backup_test.t2 VALUES ("13 Test Basic database example");
+#
+# Now create more database objects for test.
+#
+CREATE PROCEDURE backup_test.p1(p1 CHAR(20))
+INSERT INTO backup_test.t1 VALUES ("50");
+CREATE TRIGGER backup_test.trg AFTER INSERT ON backup_test.t1 FOR EACH ROW
+INSERT INTO backup_test.t1 VALUES('Test objects count');
+CREATE FUNCTION backup_test.f1() RETURNS INT RETURN (SELECT 1);
+CREATE VIEW backup_test.v1 as SELECT * FROM backup_test.t1;
+CREATE EVENT backup_test.e1 ON SCHEDULE EVERY 1 YEAR DO
+DELETE FROM backup_test.t1 WHERE a = "not there";
+#
+# Now we need some privileges
+#
+GRANT ALL ON backup_test.* TO 'joe'@'user';
+#
+# Revoke grants for bup_some_priv
+#
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+REVOKE ALL ON backup_test.* FROM 'joe'@'user';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT USAGE ON *.* TO 'bup_some_priv'@'localhost'
+#
+# conn_root_user: Do backup of database with root user for later tests.
+#
+BACKUP DATABASE backup_test to 'backup_test_orig.bak';
+backup_id
+#
+#
+# Show list of all objects in the database.
+#
+SHOW FULL TABLES FROM backup_test;
+Tables_in_backup_test Table_type
+t1 BASE TABLE
+t2 BASE TABLE
+v1 VIEW
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'backup_test';
+event_name
+e1
+SELECT routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_schema = 'backup_test';
+routine_name
+f1
+p1
+SELECT trigger_name FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'backup_test';
+trigger_name
+trg
+#
+# Test Case 1 : Ensure backup_elevation = OFF fails for not enough
+# privileges.
+#
+GRANT BACKUP ON backup_test.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT USAGE ON *.* TO 'bup_some_priv'@'localhost'
+GRANT BACKUP ON `backup_test`.* TO 'bup_some_priv'@'localhost'
+SHOW VARIABLES LIKE 'backup_elevation';
+Variable_name Value
+backup_elevation ON
+SET @@global.backup_elevation = OFF;
+SHOW VARIABLES LIKE 'backup_elevation';
+Variable_name Value
+backup_elevation OFF
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting backup. Should fail with
+# error ER_BACKUP_ACCESS_OBJS_INCOMPLETE
+#
+BACKUP DATABASE backup_test TO 'backup_test_fail.bak';
+ERROR HY000: Insufficient privileges. You do not have privileges to backup database 'backup_test'.
+SHOW ERRORS;
+Level Code Message
+Error # Insufficient privileges. You do not have privileges to backup database 'backup_test'.
+#
+# Connect as root and prepare next test case.
+#
+#
+# Test Case 2 : Show backup_elevation = OFF can succeed if privileges
+# granted.
+#
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost';
+GRANT ALL ON mysql.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT USAGE ON *.* TO 'bup_some_priv'@'localhost'
+GRANT ALL PRIVILEGES ON `mysql`.* TO 'bup_some_priv'@'localhost'
+GRANT ALL PRIVILEGES ON `backup_test`.* TO 'bup_some_priv'@'localhost'
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting backup. Should succeed
+#
+BACKUP DATABASE backup_test TO 'backup_test_fail.bak';
+backup_id
+#
+#
+# Connect as root and prepare next test case.
+#
+#
+# Test Case 3 : Show backup_elevation = ON can succeed if minimal
+# privileges granted.
+#
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+REVOKE ALL ON mysql.* FROM 'bup_some_priv'@'localhost';
+GRANT BACKUP ON backup_test.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT USAGE ON *.* TO 'bup_some_priv'@'localhost'
+GRANT BACKUP ON `backup_test`.* TO 'bup_some_priv'@'localhost'
+SHOW VARIABLES LIKE 'backup_elevation';
+Variable_name Value
+backup_elevation OFF
+SET @@global.backup_elevation = ON;
+SHOW VARIABLES LIKE 'backup_elevation';
+Variable_name Value
+backup_elevation ON
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting backup. Should succeed
+#
+BACKUP DATABASE backup_test TO 'backup_test_fail.bak';
+backup_id
+#
+#
+# Connect as root and prepare next test case.
+#
+#
+# Test Case 4 : Ensure restore_elevation = OFF fails for not enough
+# privileges.
+#
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost'
+GRANT RESTORE ON `backup_test`.* TO 'bup_some_priv'@'localhost'
+SHOW VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation ON
+SET @@global.restore_elevation = OFF;
+SHOW VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation OFF
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should fail with
+# error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+ERROR HY000: Insufficient privileges. You do not have privileges to restore the object 'backup_test' from this backup image.
+SHOW ERRORS;
+Level Code Message
+Error # Insufficient privileges. You do not have privileges to restore the object 'backup_test' from this backup image.
+#
+# Connect as root and prepare next test case.
+#
+#
+# Test Case 5 : Show restore_elevation = OFF can succeed if privileges
+# granted.
+#
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost'
+GRANT ALL PRIVILEGES ON `backup_test`.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION
+SHOW VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation OFF
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should succeed
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+backup_id
+#
+#
+# Connect as root and prepare next test case.
+#
+#
+# Test Case 6 : Show restore_elevation = OFF and RESTORE + SUPER still
+# fail.
+#
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost'
+GRANT RESTORE ON `backup_test`.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION
+SHOW VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation OFF
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should fail with
+# error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+ERROR HY000: Insufficient privileges. You do not have privileges to restore the object 'backup_test' from this backup image.
+SHOW ERRORS;
+Level Code Message
+Error # Insufficient privileges. You do not have privileges to restore the object 'backup_test' from this backup image.
+#
+# Connect as root and prepare next test case.
+#
+#
+# Test Case 7 : Show restore_elevation = ON and RESTORE + SUPER succeed.
+#
+SHOW VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation OFF
+SET @@global.restore_elevation = ON;
+SHOW VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation ON
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should succeed
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+backup_id
+#
+#
+# Connect as root and prepare next test case.
+#
+#
+# Test Case 8 : Ensure restore_precheck = OFF fails for not enough
+# privileges (Restore will fail in the middle).
+#
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+REVOKE SUPER ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT USAGE ON *.* TO 'bup_some_priv'@'localhost'
+GRANT RESTORE ON `backup_test`.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION
+SHOW VARIABLES LIKE 'restore_precheck';
+Variable_name Value
+restore_precheck ON
+SET @@global.restore_elevation = OFF;
+SET @@global.restore_precheck = OFF;
+SHOW VARIABLES LIKE 'restore_precheck';
+Variable_name Value
+restore_precheck OFF
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should fail with
+# error ER_BACKUP_CANT_RESTORE_DB
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+ERROR HY000: Could not restore database `backup_test`
+SHOW ERRORS;
+Level Code Message
+Error # Access denied for user 'bup_some_priv'@'localhost' to database 'backup_test'
+Error # Could not restore database `backup_test`
+#
+# Connect as root and prepare next test case.
+#
+SET @@global.restore_elevation = ON;
+SET @@global.restore_precheck = OFF;
+#
+# Test Case 9 : Show restore_precheck = OFF can succeed if privileges
+# granted.
+#
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost'
+GRANT ALL PRIVILEGES ON `backup_test`.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION
+SHOW VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation ON
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should succeed
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+backup_id
+#
+#
+# Connect as root and prepare next test case.
+#
+#
+# Test Case 10 : Ensure restore_elevation = OFF and
+# restore_precheck = OFF fails
+# for not enough privileges.
+#
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+REVOKE SUPER ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT USAGE ON *.* TO 'bup_some_priv'@'localhost'
+GRANT RESTORE ON `backup_test`.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION
+SET @@global.restore_elevation = OFF;
+SET @@global.restore_precheck = OFF;
+SHOW VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation OFF
+SHOW VARIABLES LIKE 'restore_precheck';
+Variable_name Value
+restore_precheck OFF
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should fail with
+# error ER_BACKUP_CANT_RESTORE_DB
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+ERROR HY000: Could not restore database `backup_test`
+SHOW ERRORS;
+Level Code Message
+Error # Access denied for user 'bup_some_priv'@'localhost' to database 'backup_test'
+Error # Could not restore database `backup_test`
+#
+# Connect as root and prepare next test case.
+#
+#
+# Test Case 11 : Ensure restore_elevation = OFF and
+# restore_precheck = OFF can succeed
+# if privileges granted.
+#
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+REVOKE SUPER ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Show grants for user.
+#
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+Grants for bup_some_priv@localhost
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost'
+GRANT ALL PRIVILEGES ON `backup_test`.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION
+SHOW VARIABLES LIKE 'restore_elevation';
+Variable_name Value
+restore_elevation OFF
+SHOW VARIABLES LIKE 'restore_precheck';
+Variable_name Value
+restore_precheck OFF
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should succeed
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+backup_id
+#
+#
+# Connect as root and cleanup.
+#
+#
+# Compare to original backup image file.
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+backup_id
+#
+#
+# Show list of all objects in the database.
+#
+SHOW FULL TABLES FROM backup_test;
+Tables_in_backup_test Table_type
+t1 BASE TABLE
+t2 BASE TABLE
+v1 VIEW
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'backup_test';
+event_name
+e1
+SELECT routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_schema = 'backup_test';
+routine_name
+f1
+p1
+SELECT trigger_name FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'backup_test';
+trigger_name
+trg
+#
+# Cleanup
+#
+DROP USER 'bup_some_priv'@'localhost';
+DROP USER 'joe'@'user';
+SET @@global.backup_elevation = ON;
+SET @@global.restore_elevation = ON;
+SET @@global.restore_precheck = ON;
+DROP DATABASE backup_test;
+FLUSH PRIVILEGES;
=== modified file 'mysql-test/suite/backup/t/backup_errors_debug_3.test'
--- a/mysql-test/suite/backup/t/backup_errors_debug_3.test 2009-09-08 18:48:16 +0000
+++ b/mysql-test/suite/backup/t/backup_errors_debug_3.test 2009-11-13 18:19:21 +0000
@@ -49,11 +49,12 @@
# 66. ER_BACKUP_LOGGER_INIT
# 67. ER_BACKUP_READ_LOC
# 68. ER_BACKUP_PREPARE_DRIVER
+# 69. ER_RESTORE_DB_ERROR
#
# Debug Insertion
# ---------------
-# 69. ER_BACKUP_UNEXPECTED_DATA
-# 70. ER_BACKUP_WRONG_TABLE_BE
+# 70. ER_BACKUP_UNEXPECTED_DATA
+# 71. ER_BACKUP_WRONG_TABLE_BE
#
--source include/not_embedded.inc
@@ -350,9 +351,24 @@ LET $errname = ER_BACKUP_PREPARE_DRIVER;
LET $operation = BACKUP;
--source suite/backup/include/test_for_error.inc
+# Test for error ER_RESTORE_DB_ERROR.
+LET $caseno = 69;
+LET $errno = $ER_RESTORE_DB_ERROR;
+LET $errname = ER_RESTORE_DB_ERROR;
+LET $operation = RESTORE;
+
+SET @@global.restore_elevation = OFF;
+
+SHOW GLOBAL VARIABLES LIKE 'restore_elevation';
+SHOW VARIABLES LIKE 'restore_elevation';
+
+--source suite/backup/include/test_for_error.inc
+
+SET @@global.restore_elevation = ON;
+
# Test for error ER_BACKUP_UNEXPECTED_DATA.
--echo #
---echo # Test case 69 - testing error ER_BACKUP_UNEXPECTED_DATA
+--echo # Test case 70 - testing error ER_BACKUP_UNEXPECTED_DATA
--echo #
--echo # Set debug SESSION variable for ER_BACKUP_UNEXPECTED_DATA
--echo #
@@ -402,7 +418,7 @@ DROP DATABASE test_empty;
--echo #
# Test for error ER_BACKUP_WRONG_TABLE_BE.
-LET $caseno = 70;
+LET $caseno = 71;
LET $errno = $ER_BACKUP_WRONG_TABLE_BE;
LET $errname = ER_BACKUP_WRONG_TABLE_BE;
LET $operation = RESTORE;
=== added file 'mysql-test/suite/backup/t/backup_restore_security.test'
--- a/mysql-test/suite/backup/t/backup_restore_security.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_restore_security.test 2009-11-13 18:19:21 +0000
@@ -0,0 +1,492 @@
+#
+# This test includes test cases for testing privilege checking on restore.
+#
+# Test Cases
+# ----------
+# 1. Ensure a user with only RESTORE on db1.* cannot restore the database.
+# 2. Ensure a user with only SELECT on db1.* cannot restore the database.
+# 3. Show that SUPER is needed when there are object that use a definer
+# clause are in the backup image.
+# 4. Ensure a user can only restore the database if and only if she has
+# all of the required permissions to create and populate all objects.
+# 5. Show that having TRIGGER on a specific table is required to restore
+# a table with a trigger.
+# 8. Show that user can have only RESTORE + SUPER and perform an
+# elevated restore.
+# 9. Show that users who have RESTORE + SUPER for db1 but not for db2
+# cannot restore the image.
+#
+
+--source include/not_embedded.inc
+
+disable_query_log;
+call mtr.add_suppression("Restore: Insufficient privileges");
+enable_query_log;
+
+connect (conn_root,localhost,root,,);
+
+--disable_warnings
+DROP DATABASE IF EXISTS backup_test;
+DROP DATABASE IF EXISTS backup_test_alt;
+--enable_warnings
+
+--echo #
+--echo # Create users.
+--echo #
+CREATE USER 'bup_some_priv'@'localhost';
+CREATE USER 'joe'@'user';
+
+--echo #
+--echo # Use the basic data setup in backup_test database.
+--echo #
+--source suite/backup/include/basic_data.inc
+
+--echo #
+--echo # Create a second database for testing multiple database privilege
+--echo # checking.
+--echo #
+
+CREATE DATABASE backup_test_alt;
+CREATE TABLE backup_test_alt.t1 (a int);
+INSERT INTO backup_test_alt.t1 VALUES (10), (11), (12);
+
+--echo #
+--echo # Revoke grants for bup_some_priv
+--echo #
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+--echo #
+--echo # conn_root_user: Do backup of database with root user for later tests.
+--echo #
+
+--replace_column 1 #
+BACKUP DATABASE backup_test to 'backup_test_orig.bak';
+
+--replace_column 1 #
+BACKUP DATABASE backup_test, backup_test_alt to 'backup_test_orig_alt1.bak';
+
+--replace_column 1 #
+BACKUP DATABASE backup_test_alt, backup_test to 'backup_test_orig_alt2.bak';
+
+--echo #
+--echo # Show list of all objects in the database.
+--echo #
+SHOW FULL TABLES FROM backup_test;
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'backup_test';
+SELECT routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_schema = 'backup_test';
+SELECT trigger_name FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'backup_test';
+
+--echo #
+--echo # conn_root_user: Do backup of database with root user without
+--echo # stored procedures for later tests.
+--echo #
+
+DROP PROCEDURE backup_test.p1;
+DROP FUNCTION backup_test.f1;
+
+--replace_column 1 #
+BACKUP DATABASE backup_test to 'backup_test_no_proc.bak';
+
+--echo #
+--echo # Test Case 1 : Ensure a user with only RESTORE on db1.* cannot restore
+--echo # the database.
+--echo #
+
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+GRANT CREATE, DROP ON backup_test.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should fail with
+--echo # error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+--echo #
+--replace_column 1 #
+--error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+--replace_column 2 #
+SHOW ERRORS;
+
+--echo #
+--echo # Test Case 2 : Ensure a user with only SELECT on db1.* cannot restore
+--echo # the database.
+--echo #
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and add privileges.
+--echo #
+connect (conn_root,localhost,root,,);
+
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT SELECT ON backup_test.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should fail with
+--echo # error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+--echo #
+--replace_column 1 #
+--error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+--replace_column 2 #
+SHOW ERRORS;
+
+--echo #
+--echo # Test Case 3 : Show that SUPER is needed to complete restore
+--echo # when there are objects with definer clauses.
+--echo #
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and add privileges.
+--echo #
+connect (conn_root,localhost,root,,);
+
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+GRANT ALL ON mysql.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should fail with
+--echo # ER_RESTORE_ACCESS_DEFINER
+--echo #
+--replace_column 1 #
+--error ER_RESTORE_ACCESS_DEFINER
+RESTORE FROM 'backup_test_no_proc.bak' OVERWRITE;
+--replace_column 2 #
+SHOW ERRORS;
+
+--echo #
+--echo # Test Case 4 : Ensure a user can only restore the database if and only
+--echo # if she has all of the required permissions to create and
+--echo # populate all objects.
+--echo #
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and add privileges.
+--echo #
+connect (conn_root,localhost,root,,);
+
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+GRANT SELECT ON mysql.* TO 'bup_some_priv'@'localhost';
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should succeed.
+--echo #
+--replace_column 1 #
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and cleanup.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Test Case 5 : Show that the privilege check on TRIGGER is required to
+--echo # restore a table with a trigger.
+
+--echo #
+--echo # Perform a backup with only a table and a trigger.
+--echo # No grants either.
+--echo #
+
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+DROP USER 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+CREATE DATABASE backup_test_trig;
+CREATE TABLE backup_test_trig.t1 (a char(30)) ENGINE=MEMORY;
+CREATE TRIGGER backup_test_trig.trg AFTER INSERT ON backup_test_trig.t1 FOR EACH ROW
+ INSERT INTO backup_test_trig.t1 VALUES('Test objects count');
+
+--replace_column 1 #
+BACKUP DATABASE backup_test_trig TO 'backup_test_trig.bak';
+
+CREATE USER 'bup_some_priv'@'localhost';
+
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+
+GRANT INSERT, UPDATE, DELETE, BACKUP, RESTORE, SELECT, CREATE, DROP
+ ON backup_test_trig.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+GRANT SELECT ON mysql.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should fail with
+--echo # error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+--echo #
+--replace_column 1 #
+--error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+RESTORE FROM 'backup_test_trig.bak' OVERWRITE;
+--replace_column 2 #
+SHOW ERRORS;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and add privilege for trigger.
+--echo #
+connect (conn_root,localhost,root,,);
+
+GRANT TRIGGER ON backup_test_trig.t1 TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should fail with
+--echo # ER_RESTORE_ACCESS_DEFINER
+--echo #
+--replace_column 1 #
+--error ER_RESTORE_ACCESS_DEFINER
+RESTORE FROM 'backup_test_trig.bak' OVERWRITE;
+SHOW ERRORS;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and add privilege for trigger.
+--echo # In this case, we must add SUPER to overcome limitation with
+--echo # the definer clause.
+--echo #
+connect (conn_root,localhost,root,,);
+
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should succeed.
+--echo #
+--replace_column 1 #
+RESTORE FROM 'backup_test_trig.bak' OVERWRITE;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Change privileges for elevated restore test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+DROP DATABASE backup_test_trig;
+
+--echo #
+--echo # Test Case 8 : Show that user can have only RESTORE + SUPER and
+--echo # perform an elevated restore.
+--echo #
+
+DROP USER 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+CREATE USER 'bup_some_priv'@'localhost';
+
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should succeed.
+--echo #
+--replace_column 1 #
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Change privileges for elevated restore test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Test Case 9 : Show that users who have RESTORE + SUPER for db1 but not
+--echo # for db2 cannot restore the image.
+--echo #
+
+DROP USER 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+CREATE USER 'bup_some_priv'@'localhost';
+
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should fail with
+--echo # error ER_RESTORE_ACCESS_DENIED_ERROR
+--echo #
+--replace_column 1 #
+--error ER_RESTORE_ACCESS_DENIED_ERROR
+RESTORE FROM 'backup_test_orig_alt1.bak' OVERWRITE;
+SHOW ERRORS;
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should fail with
+--echo # error ER_RESTORE_ACCESS_DENIED_ERROR
+--echo #
+--replace_column 1 #
+--error ER_RESTORE_ACCESS_DENIED_ERROR
+RESTORE FROM 'backup_test_orig_alt2.bak' OVERWRITE;
+SHOW ERRORS;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Change privileges for elevated restore test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+GRANT RESTORE ON backup_test_alt.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should succeed.
+--echo #
+--replace_column 1 #
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and cleanup.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Compare to original backup image file.
+--echo #
+
+--replace_column 1 #
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+
+--echo #
+--echo # Show list of all objects in the database.
+--echo #
+SHOW FULL TABLES FROM backup_test;
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'backup_test';
+SELECT routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_schema = 'backup_test';
+SELECT trigger_name FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'backup_test';
+
+--echo #
+--echo # Cleanup
+--echo #
+
+DROP USER 'bup_some_priv'@'localhost';
+DROP USER 'joe'@'user';
+
+DROP DATABASE backup_test;
+DROP DATABASE backup_test_alt;
+FLUSH PRIVILEGES;
+
+let $MYSQLD_BACKUPDIR= `select @@backupdir`;
+remove_file $MYSQLD_BACKUPDIR/backup_test_orig.bak;
+remove_file $MYSQLD_BACKUPDIR/backup_test_orig_alt1.bak;
+remove_file $MYSQLD_BACKUPDIR/backup_test_orig_alt2.bak;
+remove_file $MYSQLD_BACKUPDIR/backup_test_trig.bak;
+remove_file $MYSQLD_BACKUPDIR/backup_test_no_proc.bak;
=== modified file 'mysql-test/suite/backup/t/backup_security.test'
--- a/mysql-test/suite/backup/t/backup_security.test 2009-10-23 21:26:11 +0000
+++ b/mysql-test/suite/backup/t/backup_security.test 2009-11-13 18:19:21 +0000
@@ -17,8 +17,9 @@
--source include/not_embedded.inc
disable_query_log;
-call mtr.add_suppression("Backup:");
-call mtr.add_suppression("Restore:");
+call mtr.add_suppression("Backup: Insufficient privileges");
+call mtr.add_suppression("Restore: Insufficient privileges");
+call mtr.add_suppression("Backup: Unknown database");
enable_query_log;
connect (conn_root,localhost,root,,);
@@ -184,11 +185,11 @@ SHOW TABLES FROM backup_test;
--echo #
--echo #
---echo # conn_user1: Attempting restore. Should fail with one of the restore
---echo # catalog errors.
+--echo # conn_user1: Attempting restore. Should fail with
+--echo # error ER_RESTORE_ACCESS_OBJS_INCOMPLETE.
--echo #
--replace_column 1 #
---error ER_BACKUP_CANT_RESTORE_DB, ER_BACKUP_CANT_RESTORE_TABLE, ER_BACKUP_CANT_RESTORE_VIEW, ER_BACKUP_CANT_RESTORE_SROUT, ER_BACKUP_CANT_RESTORE_EVENT, ER_BACKUP_CANT_RESTORE_TRIGGER
+--error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
eval RESTORE FROM 'bup_user1.bak' OVERWRITE;
--echo #
@@ -198,10 +199,10 @@ eval RESTORE FROM 'bup_user1.bak' OVERWR
--echo #
--echo # conn_user1: Attempting backup. Should fail with
---echo # error ER_BACKUP_ACCESS_DENIED_ERROR
+--echo # error ER_BAD_DB_ERROR
--echo #
--replace_column 1 #
---error ER_BACKUP_ACCESS_DENIED_ERROR
+--error ER_BAD_DB_ERROR
BACKUP DATABASE backup_test_alt to 'bup_no_priv.bak';
--replace_column 2 #
SHOW ERRORS;
=== added file 'mysql-test/suite/backup/t/backup_security_options-master.opt'
--- a/mysql-test/suite/backup/t/backup_security_options-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_security_options-master.opt 2009-11-13 18:19:21 +0000
@@ -0,0 +1 @@
+--disable-backup-elevation --disable-restore-elevation --disable-restore-precheck
=== added file 'mysql-test/suite/backup/t/backup_security_options.test'
--- a/mysql-test/suite/backup/t/backup_security_options.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_security_options.test 2009-11-13 18:19:21 +0000
@@ -0,0 +1,237 @@
+#
+# This test includes test cases for testing privilege checking in backup
+# and restore using the following system startup options.
+#
+# backup_elevation - turns elevation on backup on or off
+# Note: default is ON
+# restore_elevation - turns elevation on restore on or off
+# Note: default is ON
+# restore_precheck - turns privilege prechecking on restore on or off
+# Note: default is ON
+#
+# Test Cases
+# ----------
+# 1. Ensure backup_elevation = OFF fails for not enough privileges.
+# 2. Ensure restore_elevation = OFF fails for not enough privileges.
+# 3. Ensure restore_precheck = OFF fails for not enough privileges
+# (Restore will fail in the middle).
+#
+
+--source include/not_embedded.inc
+
+disable_query_log;
+call mtr.add_suppression("Backup: Insufficient privileges");
+call mtr.add_suppression("Restore: Insufficient privileges");
+call mtr.add_suppression("Restore: Could not restore database");
+enable_query_log;
+
+connect (conn_root,localhost,root,,);
+
+--disable_warnings
+DROP DATABASE IF EXISTS backup_test;
+--enable_warnings
+
+SHOW VARIABLES LIKE 'backup_elevation';
+SHOW VARIABLES LIKE 'restore_elevation';
+SHOW VARIABLES LIKE 'restore_precheck';
+
+--echo #
+--echo # Create users.
+--echo #
+CREATE USER 'bup_some_priv'@'localhost';
+
+--echo #
+--echo # Use the basic data setup in backup_test database.
+--echo #
+--source suite/backup/include/basic_data.inc
+
+--echo #
+--echo # Revoke grants for bup_some_priv
+--echo #
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+REVOKE ALL ON backup_test.* FROM 'joe'@'user';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+--echo #
+--echo # conn_root_user: Do backup of database with root user for later tests.
+--echo #
+
+--replace_column 1 #
+BACKUP DATABASE backup_test to 'backup_test_orig.bak';
+
+--echo #
+--echo # Show list of all objects in the database.
+--echo #
+SHOW FULL TABLES FROM backup_test;
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'backup_test';
+SELECT routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_schema = 'backup_test';
+SELECT trigger_name FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'backup_test';
+
+--echo #
+--echo # Test Case 1 : Ensure backup_elevation = OFF fails for not enough
+--echo # privileges.
+--echo #
+
+GRANT BACKUP ON backup_test.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+SHOW VARIABLES LIKE 'backup_elevation';
+
+SET @@global.backup_elevation = OFF;
+
+SHOW VARIABLES LIKE 'backup_elevation';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting backup. Should fail with
+--echo # error ER_BACKUP_ACCESS_OBJS_INCOMPLETE
+--echo #
+--replace_column 1 #
+--error ER_BACKUP_ACCESS_OBJS_INCOMPLETE
+BACKUP DATABASE backup_test TO 'backup_test_fail.bak';
+--replace_column 2 #
+SHOW ERRORS;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and prepare next test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Test Case 2 : Ensure restore_elevation = OFF fails for not enough
+--echo # privileges.
+--echo #
+
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+SHOW VARIABLES LIKE 'restore_elevation';
+
+SET @@global.restore_elevation = OFF;
+
+SHOW VARIABLES LIKE 'restore_elevation';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should fail with
+--echo # error ER_BACKUP_CANT_RESTORE_DB
+--echo #
+--replace_column 1 #
+--error ER_BACKUP_CANT_RESTORE_DB
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+--replace_column 2 #
+SHOW ERRORS;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and prepare next test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Test Case 3 : Ensure restore_precheck = OFF fails for not enough
+--echo # privileges (Restore will fail in the middle).
+--echo #
+
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+REVOKE SUPER ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+SHOW VARIABLES LIKE 'restore_precheck';
+
+SET @@global.restore_elevation = OFF;
+SET @@global.restore_precheck = OFF;
+
+SHOW VARIABLES LIKE 'restore_precheck';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should fail with
+--echo # error ER_BACKUP_CANT_RESTORE_DB
+--echo #
+--replace_column 1 #
+--error ER_BACKUP_CANT_RESTORE_DB
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+--replace_column 2 #
+SHOW ERRORS;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and cleanup.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Compare to original backup image file.
+--echo #
+
+--replace_column 1 #
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+
+--echo #
+--echo # Show list of all objects in the database.
+--echo #
+SHOW FULL TABLES FROM backup_test;
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'backup_test';
+SELECT routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_schema = 'backup_test';
+SELECT trigger_name FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'backup_test';
+
+--echo #
+--echo # Cleanup
+--echo #
+
+DROP USER 'bup_some_priv'@'localhost';
+DROP USER 'joe'@'user';
+
+SET @@global.backup_elevation = OFF;
+SET @@global.restore_elevation = OFF;
+SET @@global.restore_precheck = OFF;
+
+DROP DATABASE backup_test;
+FLUSH PRIVILEGES;
+
+let $MYSQLD_BACKUPDIR= `select @@backupdir`;
+remove_file $MYSQLD_BACKUPDIR/backup_test_orig.bak;
=== added file 'mysql-test/suite/backup/t/backup_security_var.test'
--- a/mysql-test/suite/backup/t/backup_security_var.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_security_var.test 2009-11-13 18:19:21 +0000
@@ -0,0 +1,553 @@
+#
+# This test includes test cases for testing privilege checking in backup
+# and restore using the following system variables.
+#
+# backup_elevation - turns elevation on backup on or off
+# Note: default is ON
+# restore_elevation - turns elevation on restore on or off
+# Note: default is ON
+# restore_precheck - turns privilege prechecking on restore on or off
+# Note: default is ON
+#
+# Test Cases
+# ----------
+# 1. Ensure backup_elevation = OFF fails for not enough privileges.
+# 2. Show backup_elevation = OFF can succeed if privileges granted.
+# 3. Show backup_elevation = ON can succeed if minimal privileges granted.
+# 4. Ensure restore_elevation = OFF fails for not enough privileges.
+# 5. Show restore_elevation = OFF can succeed if privileges granted.
+# 6. Show restore_elevation = OFF and RESTORE + SUPER still fail.
+# 7. Show restore_elevation = ON and RESTORE + SUPER succeed.
+# 8. Ensure restore_precheck = OFF fails for not enough privileges
+# (Restore will fail in the middle).
+# 9. Show restore_precheck = OFF can succeed if privileges granted.
+# 10. Ensure restore_elevation = OFF and restore_precheck = OFF fails
+# for not enough privileges.
+# 11. Show restore_elevation = OFF and restore_precheck = OFF can succeed
+# if privileges granted.
+#
+
+--source include/not_embedded.inc
+
+disable_query_log;
+call mtr.add_suppression("Backup: Insufficient privileges");
+call mtr.add_suppression("Restore: Insufficient privileges");
+call mtr.add_suppression("Restore: Could not restore database");
+enable_query_log;
+
+connect (conn_root,localhost,root,,);
+
+--disable_warnings
+DROP DATABASE IF EXISTS backup_test;
+--enable_warnings
+
+SHOW VARIABLES LIKE 'backup_elevation';
+SHOW VARIABLES LIKE 'restore_elevation';
+SHOW VARIABLES LIKE 'restore_precheck';
+
+--echo #
+--echo # Create users.
+--echo #
+CREATE USER 'bup_some_priv'@'localhost';
+
+--echo #
+--echo # Use the basic data setup in backup_test database.
+--echo #
+--source suite/backup/include/basic_data.inc
+
+--echo #
+--echo # Revoke grants for bup_some_priv
+--echo #
+REVOKE ALL ON *.* FROM 'bup_some_priv'@'localhost';
+REVOKE ALL ON backup_test.* FROM 'joe'@'user';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+--echo #
+--echo # conn_root_user: Do backup of database with root user for later tests.
+--echo #
+
+--replace_column 1 #
+BACKUP DATABASE backup_test to 'backup_test_orig.bak';
+
+--echo #
+--echo # Show list of all objects in the database.
+--echo #
+SHOW FULL TABLES FROM backup_test;
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'backup_test';
+SELECT routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_schema = 'backup_test';
+SELECT trigger_name FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'backup_test';
+
+--echo #
+--echo # Test Case 1 : Ensure backup_elevation = OFF fails for not enough
+--echo # privileges.
+--echo #
+
+GRANT BACKUP ON backup_test.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+SHOW VARIABLES LIKE 'backup_elevation';
+
+SET @@global.backup_elevation = OFF;
+
+SHOW VARIABLES LIKE 'backup_elevation';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting backup. Should fail with
+--echo # error ER_BACKUP_ACCESS_OBJS_INCOMPLETE
+--echo #
+--replace_column 1 #
+--error ER_BACKUP_ACCESS_OBJS_INCOMPLETE
+BACKUP DATABASE backup_test TO 'backup_test_fail.bak';
+--replace_column 2 #
+SHOW ERRORS;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and prepare next test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Test Case 2 : Show backup_elevation = OFF can succeed if privileges
+--echo # granted.
+--echo #
+
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost';
+GRANT ALL ON mysql.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting backup. Should succeed
+--echo #
+--replace_column 1 #
+BACKUP DATABASE backup_test TO 'backup_test_fail.bak';
+
+let $MYSQLD_BACKUPDIR= `select @@backupdir`;
+remove_file $MYSQLD_BACKUPDIR/backup_test_fail.bak;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and prepare next test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Test Case 3 : Show backup_elevation = ON can succeed if minimal
+--echo # privileges granted.
+--echo #
+
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+REVOKE ALL ON mysql.* FROM 'bup_some_priv'@'localhost';
+GRANT BACKUP ON backup_test.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+SHOW VARIABLES LIKE 'backup_elevation';
+
+SET @@global.backup_elevation = ON;
+
+SHOW VARIABLES LIKE 'backup_elevation';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting backup. Should succeed
+--echo #
+--replace_column 1 #
+BACKUP DATABASE backup_test TO 'backup_test_fail.bak';
+
+let $MYSQLD_BACKUPDIR= `select @@backupdir`;
+remove_file $MYSQLD_BACKUPDIR/backup_test_fail.bak;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and prepare next test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Test Case 4 : Ensure restore_elevation = OFF fails for not enough
+--echo # privileges.
+--echo #
+
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+SHOW VARIABLES LIKE 'restore_elevation';
+
+SET @@global.restore_elevation = OFF;
+
+SHOW VARIABLES LIKE 'restore_elevation';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should fail with
+--echo # error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+--echo #
+--replace_column 1 #
+--error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+--replace_column 2 #
+SHOW ERRORS;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and prepare next test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Test Case 5 : Show restore_elevation = OFF can succeed if privileges
+--echo # granted.
+--echo #
+
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+SHOW VARIABLES LIKE 'restore_elevation';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should succeed
+--echo #
+--replace_column 1 #
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and prepare next test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Test Case 6 : Show restore_elevation = OFF and RESTORE + SUPER still
+--echo # fail.
+--echo #
+
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+SHOW VARIABLES LIKE 'restore_elevation';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should fail with
+--echo # error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+--echo #
+--replace_column 1 #
+--error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+--replace_column 2 #
+SHOW ERRORS;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and prepare next test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Test Case 7 : Show restore_elevation = ON and RESTORE + SUPER succeed.
+--echo #
+
+SHOW VARIABLES LIKE 'restore_elevation';
+
+SET @@global.restore_elevation = ON;
+
+SHOW VARIABLES LIKE 'restore_elevation';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should succeed
+--echo #
+--replace_column 1 #
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and prepare next test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Test Case 8 : Ensure restore_precheck = OFF fails for not enough
+--echo # privileges (Restore will fail in the middle).
+--echo #
+
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+REVOKE SUPER ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+SHOW VARIABLES LIKE 'restore_precheck';
+
+SET @@global.restore_elevation = OFF;
+SET @@global.restore_precheck = OFF;
+
+SHOW VARIABLES LIKE 'restore_precheck';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should fail with
+--echo # error ER_BACKUP_CANT_RESTORE_DB
+--echo #
+--replace_column 1 #
+--error ER_BACKUP_CANT_RESTORE_DB
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+--replace_column 2 #
+SHOW ERRORS;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and prepare next test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+SET @@global.restore_elevation = ON;
+SET @@global.restore_precheck = OFF;
+
+--echo #
+--echo # Test Case 9 : Show restore_precheck = OFF can succeed if privileges
+--echo # granted.
+--echo #
+
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+SHOW VARIABLES LIKE 'restore_elevation';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should succeed
+--echo #
+--replace_column 1 #
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and prepare next test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Test Case 10 : Ensure restore_elevation = OFF and
+--echo # restore_precheck = OFF fails
+--echo # for not enough privileges.
+--echo #
+
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+REVOKE SUPER ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT RESTORE ON backup_test.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+SET @@global.restore_elevation = OFF;
+SET @@global.restore_precheck = OFF;
+
+SHOW VARIABLES LIKE 'restore_elevation';
+SHOW VARIABLES LIKE 'restore_precheck';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should fail with
+--echo # error ER_BACKUP_CANT_RESTORE_DB
+--echo #
+--replace_column 1 #
+--error ER_BACKUP_CANT_RESTORE_DB
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+--replace_column 2 #
+SHOW ERRORS;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and prepare next test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Test Case 11 : Ensure restore_elevation = OFF and
+--echo # restore_precheck = OFF can succeed
+--echo # if privileges granted.
+--echo #
+
+REVOKE ALL ON backup_test.* FROM 'bup_some_priv'@'localhost';
+REVOKE SUPER ON *.* FROM 'bup_some_priv'@'localhost';
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+GRANT SUPER ON *.* TO 'bup_some_priv'@'localhost';
+
+FLUSH PRIVILEGES;
+
+--echo #
+--echo # Show grants for user.
+--echo #
+SHOW GRANTS FOR 'bup_some_priv'@'localhost';
+
+SHOW VARIABLES LIKE 'restore_elevation';
+SHOW VARIABLES LIKE 'restore_precheck';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # conn_some_priv: Attempting restore. Should succeed
+--echo #
+--replace_column 1 #
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and cleanup.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Compare to original backup image file.
+--echo #
+
+--replace_column 1 #
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+
+--echo #
+--echo # Show list of all objects in the database.
+--echo #
+SHOW FULL TABLES FROM backup_test;
+SELECT event_name FROM INFORMATION_SCHEMA.EVENTS WHERE event_schema = 'backup_test';
+SELECT routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_schema = 'backup_test';
+SELECT trigger_name FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'backup_test';
+
+--echo #
+--echo # Cleanup
+--echo #
+
+DROP USER 'bup_some_priv'@'localhost';
+DROP USER 'joe'@'user';
+
+SET @@global.backup_elevation = ON;
+SET @@global.restore_elevation = ON;
+SET @@global.restore_precheck = ON;
+
+DROP DATABASE backup_test;
+FLUSH PRIVILEGES;
+
+let $MYSQLD_BACKUPDIR= `select @@backupdir`;
+remove_file $MYSQLD_BACKUPDIR/backup_test_orig.bak;
=== modified file 'sql/backup/CMakeLists.txt'
--- a/sql/backup/CMakeLists.txt 2008-11-05 10:19:19 +0000
+++ b/sql/backup/CMakeLists.txt 2009-11-13 18:19:21 +0000
@@ -23,7 +23,8 @@ SET(BACKUP_SOURCES stream.cc logger.cc k
image_info.cc backup_info.cc data_backup.cc
be_default.cc buffer_iterator.cc
be_snapshot.cc be_thread.cc
- backup_test.cc be_nodata.cc)
+ backup_test.cc be_nodata.cc
+ restore_info.cc)
IF(NOT SOURCE_SUBLIBS)
ADD_LIBRARY(backup ${BACKUP_SOURCES})
=== modified file 'sql/backup/Makefile.am'
--- a/sql/backup/Makefile.am 2009-01-07 10:58:33 +0000
+++ b/sql/backup/Makefile.am 2009-11-13 18:19:21 +0000
@@ -37,7 +37,8 @@ libbackup_la_SOURCES = \
be_nodata.cc \
buffer_iterator.cc \
be_thread.cc \
- backup_test.cc
+ backup_test.cc \
+ restore_info.cc
libbackup_la_LIBADD = libbackupstream.la
=== modified file 'sql/backup/backup_info.cc'
--- a/sql/backup/backup_info.cc 2009-10-23 15:41:56 +0000
+++ b/sql/backup/backup_info.cc 2009-11-13 18:19:21 +0000
@@ -665,7 +665,11 @@ backup::Image_info::Db* Backup_info::add
/*
Check privileges for this database. User must have BACKUP
privilege in order to execute a backup.
+
+ We must turn privilege checking back on first.
*/
+ m_thd->security_ctx->restore_global_privileges();
+
DEBUG_SYNC(m_thd, "before_backup_privileges");
if (check_access(m_thd, BACKUP_ACL, name->ptr(), 0, 1, 1, 0))
{
@@ -673,6 +677,16 @@ backup::Image_info::Db* Backup_info::add
return NULL;
}
+ /*
+ The base check for BACKUP_ACL for this database is satisfied,
+ ok to elevate by turning off privilege checking.
+
+ Only do the elevation if backup_elevation is turned on.
+ */
+ if (m_thd->variables.backup_elevation &&
+ global_system_variables.backup_elevation)
+ m_thd->security_ctx->set_all_global_privileges();
+
// Check to see if the user can see all of the objects in the database.
if (obs::check_user_access(m_thd, name))
{
=== modified file 'sql/backup/backup_kernel.h'
--- a/sql/backup/backup_kernel.h 2009-10-21 13:32:24 +0000
+++ b/sql/backup/backup_kernel.h 2009-11-13 18:19:21 +0000
@@ -82,7 +82,7 @@ public:
const char*, bool, bool);
Restore_info* prepare_for_restore(String *location,
LEX_STRING orig_loc,
- const char*, bool);
+ const char*, bool, bool);
int do_backup();
int do_restore(bool overwrite);
=== modified file 'sql/backup/kernel.cc'
--- a/sql/backup/kernel.cc 2009-10-23 15:41:56 +0000
+++ b/sql/backup/kernel.cc 2009-11-13 18:19:21 +0000
@@ -190,7 +190,8 @@ execute_backup_command(THD *thd,
LEX *lex,
String *backupdir,
bool overwrite,
- bool skip_gap_event)
+ bool skip_gap_event,
+ bool skip_privilege_check)
{
int res= 0;
@@ -281,7 +282,8 @@ execute_backup_command(THD *thd,
DEBUG_SYNC(thd, "before_restore_prepare");
Restore_info *info= context.prepare_for_restore(backupdir, lex->backup_dir,
- thd->query(), skip_gap_event);
+ thd->query(), skip_gap_event,
+ skip_privilege_check);
// Error code insertion for ER_BACKUP_RESTORE_PREPARE.
DBUG_EXECUTE_IF("ER_BACKUP_RESTORE_PREPARE_2", info= 0;);
@@ -639,6 +641,11 @@ int Backup_restore_ctx::prepare_path(::S
int Backup_restore_ctx::prepare(::String *backupdir, LEX_STRING location)
{
+ /*
+ Save privilege information for restoring later.
+ */
+ m_thd->security_ctx->save_global_privileges();
+
if (m_error)
return m_error;
@@ -861,6 +868,9 @@ Backup_restore_ctx::prepare_for_backup(S
@param[in] orig_loc path as specified on command line for backup image
@param[in] query RESTORE query starting the operation
@param[in] skip_gap_event TRUE means do not write gap event
+ @param[in] skip_privilege_check TRUE means that no privilege checks will be
+ done before restore starts (except for checking RESTORE
+ privilege on each database).
@returns Pointer to a @c Restore_info instance containing catalogue of the
backup image (read from the image). NULL if errors were detected.
@@ -872,7 +882,8 @@ Restore_info*
Backup_restore_ctx::prepare_for_restore(String *backupdir,
LEX_STRING orig_loc,
const char *query,
- bool skip_gap_event)
+ bool skip_gap_event,
+ bool skip_privilege_check)
{
using namespace backup;
@@ -945,8 +956,14 @@ Backup_restore_ctx::prepare_for_restore(
/* Create restore catalogue. */
+ if (m_thd->variables.restore_elevation &&
+ global_system_variables.restore_elevation)
+ if (m_thd->security_ctx->master_access & SUPER_ACL)
+ skip_privilege_check= TRUE;
+
DEBUG_SYNC(m_thd, "before_restore_catalog");
- Restore_info *info= new Restore_info(*this, m_thd); // Reports errors.
+ // Reports errors.
+ Restore_info *info= new Restore_info(*this, m_thd, skip_privilege_check);
m_catalog= info;
if (!info || is_killed())
@@ -968,7 +985,7 @@ Backup_restore_ctx::prepare_for_restore(
}
info->save_start_time(when);
-
+
/* Read header and catalogue from the input stream. */
DEBUG_SYNC(m_thd, "before_restore_read_header");
@@ -1180,6 +1197,11 @@ int Backup_restore_ctx::close()
{
int res= 0;
+ /*
+ Restore privilege information.
+ */
+ m_thd->security_ctx->restore_global_privileges();
+
if (m_state == CLOSED)
return 0;
@@ -1582,6 +1604,11 @@ int Backup_restore_ctx::do_restore(bool
if (report_killed())
DBUG_RETURN(fatal_error(ER_QUERY_INTERRUPTED));
+ if (m_thd->variables.restore_elevation &&
+ global_system_variables.restore_elevation)
+ if (m_thd->security_ctx->master_access & SUPER_ACL)
+ m_thd->security_ctx->set_all_global_privileges();
+
DEBUG_SYNC(m_thd, "before_restore_read_metadata");
err= read_meta_data(m_thd, info, s); // Can log errors via callback functions.
if (err || is_killed())
@@ -1984,7 +2011,23 @@ int bcat_add_item(st_bstream_image_heade
item->name.begin,
item->type,
item->pos));
-
+
+ /*
+ Do object-level privilege checking for all objects being restored.
+ The user must have, at a minimum, the ability to create each object
+ plus any specific privileges for the object type (e.g. functions,
+ triggers).
+
+ An error is returned if the user does not have the correct privileges
+ to create the object.
+
+ Only perform the precheck if restore_precheck is turned on.
+ */
+ if (global_system_variables.restore_precheck &&
+ info->m_thd->variables.restore_precheck)
+ if (info->check_restore_privileges(item))
+ return BSTREAM_ERROR;
+
switch (item->type) {
case BSTREAM_IT_TABLESPACE:
=== modified file 'sql/backup/restore_info.h'
--- a/sql/backup/restore_info.h 2009-10-21 13:32:24 +0000
+++ b/sql/backup/restore_info.h 2009-11-13 18:19:21 +0000
@@ -45,13 +45,16 @@ public:
Image_info::Db* add_db(const ::String&, uint);
Image_info::Table* add_table(Image_info::Db&, const ::String&,
backup::Snapshot_info&, ulong);
+
+ bool check_restore_privileges(struct st_bstream_item_info *item);
+
private:
/*
Note: constructor is private because instances of this class are supposed
to be created only with Backup_restore_ctx::prepare_for_restore() method.
*/
- Restore_info(backup::Logger&, THD*);
+ Restore_info(backup::Logger&, THD*, bool);
// Prevent copying/assignments.
Restore_info(const Restore_info&);
@@ -61,6 +64,7 @@ private:
/// A flag to indicate that data has been modified during restore operation.
bool m_data_changed;
+ bool m_skip_precheck;
friend int backup::restore_table_data(THD*, Restore_info&,
backup::Input_stream&);
@@ -75,8 +79,10 @@ private:
inline
-Restore_info::Restore_info(backup::Logger &log, THD *thd)
- :m_log(log), m_thd(thd), m_data_changed(FALSE)
+Restore_info::Restore_info(backup::Logger &log, THD *thd,
+ bool skip_privilege_check)
+ :m_log(log), m_thd(thd), m_data_changed(FALSE),
+ m_skip_precheck(skip_privilege_check)
{}
@@ -117,17 +123,6 @@ inline
backup::Image_info::Db*
Restore_info::add_db(const ::String &name, uint pos)
{
- /*
- Check privileges for this database. User must have RESTORE
- privilege in order to execute a restore.
- */
- DEBUG_SYNC(m_thd, "before_restore_privileges");
- if (check_access(m_thd, RESTORE_ACL, name.ptr(), 0, 1, 1, 0))
- {
- m_log.report_error(ER_RESTORE_ACCESS_DENIED_ERROR, name.ptr());
- return NULL;
- }
-
Db *db= Image_info::add_db(name, pos);
if (!db)
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2009-10-29 21:33:17 +0000
+++ b/sql/mysqld.cc 2009-11-13 18:19:21 +0000
@@ -6052,6 +6052,9 @@ enum options_mysqld
OPT_BACKUP_HISTORY_LOG_FILE,
OPT_BACKUP_PROGRESS_LOG_FILE,
OPT_MYSQL_BACKUP,
+ OPT_BACKUP_ELEVATION,
+ OPT_RESTORE_ELEVATION,
+ OPT_RESTORE_PRECHECK,
OPT_IGNORE_BUILTIN_INNODB
};
@@ -6101,8 +6104,11 @@ struct my_option my_long_options[] =
"Enable|disable backup progress log", (uchar**) &opt_backup_progress_log,
(uchar**) &opt_backup_progress_log, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
{"mysql-backup", OPT_MYSQL_BACKUP,
- "Enable|disable MySQL Backup system", (uchar**) &opt_mysql_backup,
- (uchar**) &opt_mysql_backup, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ "Enable|disable MySQL Backup system", (uchar**) &opt_mysql_backup,
+ (uchar**) &opt_mysql_backup, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"backup-elevation", OPT_BACKUP_ELEVATION,
+ "Enable|disable privilege elevaton for backup", (uchar**) &global_system_variables.backup_elevation,
+ (uchar**) &global_system_variables.backup_elevation, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
{"basedir", 'b',
"Path to installation directory. All paths are usually resolved relative to this.",
(uchar**) &mysql_home_ptr, (uchar**) &mysql_home_ptr, 0, GET_STR, REQUIRED_ARG,
@@ -6679,6 +6685,12 @@ relay logs.",
thread is in the relay logs.",
(uchar**) &relay_log_info_file, (uchar**) &relay_log_info_file, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"restore-elevation", OPT_RESTORE_ELEVATION,
+ "Enable|disable privilege elevaton for restore", (uchar**) &global_system_variables.restore_elevation,
+ (uchar**) &global_system_variables.restore_elevation, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
+ {"restore-precheck", OPT_RESTORE_PRECHECK,
+ "Enable|disable privilege prechecking for restore", (uchar**) &global_system_variables.restore_precheck,
+ (uchar**) &global_system_variables.restore_precheck, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
{"replicate-do-db", OPT_REPLICATE_DO_DB,
"Tells the slave thread to restrict replication to the specified database. To specify more than one database, use the directive multiple times, once for each database. Note that this will only work if you do not use cross-database queries such as UPDATE some_db.some_table SET foo='bar' while having selected a different or no database. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-do-table=db_name.%.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2009-10-27 10:03:00 +0000
+++ b/sql/set_var.cc 2009-11-13 18:19:21 +0000
@@ -185,6 +185,8 @@ static sys_var_bool_ptr sys_automatic_sp
static sys_var_const sys_back_log(&vars, "back_log",
OPT_GLOBAL, SHOW_LONG,
(uchar*) &back_log);
+static sys_var_bool_ptr sys_backup_elevation(&vars, "backup_elevation",
+ (my_bool *) &global_system_variables.backup_elevation);
static sys_var_const_os_str sys_basedir(&vars, "basedir", mysql_home);
static sys_var_long_ptr sys_binlog_cache_size(&vars, "binlog_cache_size",
&binlog_cache_size);
@@ -511,6 +513,10 @@ static sys_var_thd_ulong sys_read_rnd_bu
&SV::read_rnd_buff_size);
static sys_var_thd_ulong sys_div_precincrement(&vars, "div_precision_increment",
&SV::div_precincrement);
+static sys_var_bool_ptr sys_restore_elevation(&vars, "restore_elevation",
+ (my_bool*) &global_system_variables.restore_elevation);
+static sys_var_bool_ptr sys_restore_precheck(&vars, "restore_precheck",
+ (my_bool*) &global_system_variables.restore_precheck);
static sys_var_long_ptr sys_rpl_recovery_rank(&vars, "rpl_recovery_rank",
&rpl_recovery_rank);
static sys_var_thd_ulong sys_range_alloc_block_size(&vars, "range_alloc_block_size",
=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt 2009-10-12 09:08:34 +0000
+++ b/sql/share/errmsg-utf8.txt 2009-11-13 18:19:21 +0000
@@ -6562,3 +6562,9 @@ ER_BACKUP_ACCESS_OBJS_INCOMPLETE
eng "Insufficient privileges. You do not have privileges to backup database '%s'."
ER_WARN_I_S_SKIPPED_TABLE
eng "Table '%s'.'%s' was skipped since its definition is being modified by concurrent DDL statement."
+ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+ eng "Insufficient privileges. You do not have privileges to restore the object '%s' from this backup image."
+ER_RESTORE_ACCESS_DEFINER
+ eng "Insufficient privileges. You must have the SUPER privilege to restore the object '%s'.'%s'."
+ER_RESTORE_DB_ERROR
+ eng "The database for object '%s' was not found in the catalog."
=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt 2009-10-26 14:02:26 +0000
+++ b/sql/share/errmsg.txt 2009-11-13 18:19:21 +0000
@@ -6562,3 +6562,9 @@ ER_BACKUP_ACCESS_OBJS_INCOMPLETE
eng "Insufficient privileges. You do not have privileges to backup database '%s'."
ER_WARN_I_S_SKIPPED_TABLE
eng "Table '%s'.'%s' was skipped since its definition is being modified by concurrent DDL statement."
+ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+ eng "Insufficient privileges. You do not have privileges to restore the object '%s' from this backup image."
+ER_RESTORE_ACCESS_DEFINER
+ eng "Insufficient privileges. You must have the SUPER privilege to restore the object '%s'.'%s'."
+ER_RESTORE_DB_ERROR
+ eng "The database for object '%s' was not found in the catalog."
=== modified file 'sql/si_objects.cc'
--- a/sql/si_objects.cc 2009-11-09 10:56:12 +0000
+++ b/sql/si_objects.cc 2009-11-13 18:19:21 +0000
@@ -202,10 +202,7 @@ bool
run_service_interface_sql(THD *thd, Ed_connection *ed_connection,
const LEX_STRING *query, bool get_warnings)
{
- Si_session_context session_context;
- ulong saved_master_access; // Saved master access ACLs
- ulong saved_db_access; // Saved db access ACLs
-
+ Si_session_context session_context;
DBUG_ENTER("run_service_interface_sql");
DBUG_PRINT("run_service_interface_sql",
@@ -215,25 +212,6 @@ run_service_interface_sql(THD *thd, Ed_c
session_context.save_si_ctx(thd);
session_context.reset_si_ctx(thd);
- /*
- We only elevate for SELECT or SHOW CREATE queries.
- */
- my_bool elevate= strncmp(query->str, "SELECT", 6) == 0 ||
- strncmp(query->str, "(SELECT", 7) == 0 ||
- strncmp(query->str, "SHOW CREATE", 11) == 0 ? TRUE : FALSE;
-
- /*
- Temporarily give user SELECT privilege so operations on
- mysql and information_schema can succeed.
- */
- if (elevate)
- {
- saved_master_access= thd->security_ctx->master_access;
- saved_db_access= thd->security_ctx->db_access;
- thd->security_ctx->master_access |= (SELECT_ACL | SHOW_VIEW_ACL |
- TRIGGER_ACL | PROC_ACLS | EVENT_ACL);
- }
-
bool rc= ed_connection->execute_direct(*query);
if (get_warnings)
@@ -242,15 +220,6 @@ run_service_interface_sql(THD *thd, Ed_c
thd->warning_info->append_warnings(thd, ed_connection->get_warn_list());
}
- /*
- Remove elevated privilege.
- */
- if (elevate)
- {
- thd->security_ctx->master_access= saved_master_access;
- thd->security_ctx->db_access= saved_db_access;
- }
-
session_context.restore_si_ctx(thd);
DBUG_RETURN(rc);
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2009-10-26 14:02:26 +0000
+++ b/sql/sql_class.cc 2009-11-13 18:19:21 +0000
@@ -2991,6 +2991,24 @@ void Security_context::skip_grants()
*priv_host= '\0';
}
+// Turns off grants but keeps user context.
+void Security_context::set_all_global_privileges()
+{
+ master_access= (ulong)~NO_ACCESS;
+}
+
+// Saves current privilege settings.
+void Security_context::save_global_privileges()
+{
+ /* save the values for restoring later with reset_grant_info() */
+ m_saved_master_access= master_access;
+}
+
+// Turns grants back on.
+void Security_context::restore_global_privileges()
+{
+ master_access= m_saved_master_access;
+}
bool Security_context::set_user(char *user_arg)
{
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2009-10-28 15:45:46 +0000
+++ b/sql/sql_class.h 2009-11-13 18:19:21 +0000
@@ -337,6 +337,7 @@ struct system_variables
ha_rows select_limit;
ha_rows max_join_size;
ulong auto_increment_increment, auto_increment_offset;
+ ulong backup_elevation, restore_elevation, restore_precheck;
ulong bulk_insert_buff_size;
ulong join_buff_size;
ulong join_cache_level;
@@ -852,6 +853,9 @@ public:
void init();
void destroy();
void skip_grants();
+ void set_all_global_privileges();
+ void save_global_privileges();
+ void restore_global_privileges();
inline char *priv_host_name()
{
return (*priv_host ? priv_host : (char *)"%");
@@ -871,6 +875,8 @@ public:
restore_security_context(THD *thd, Security_context *backup);
#endif
bool user_matches(Security_context *);
+private:
+ ulong m_saved_master_access;
};
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2009-11-02 14:05:19 +0000
+++ b/sql/sql_parse.cc 2009-11-13 18:19:21 +0000
@@ -43,7 +43,7 @@
@defgroup Runtime_Environment Runtime Environment
@{
*/
-int execute_backup_command(THD*, LEX*, String*, bool, bool);
+int execute_backup_command(THD*, LEX*, String*, bool, bool, bool);
/* Used in error handling only */
#define SP_TYPE_STRING(LP) \
@@ -2477,7 +2477,7 @@ mysql_execute_command(THD *thd)
(either ok, result set or error message).
*/
res= execute_backup_command(thd, lex, &backupdir, overwrite_option,
- skip_gap_event);
+ skip_gap_event, FALSE);
thd->backup_in_progress= saved_backup_in_progress;
if (res)
goto error;
Attachment: [text/bzr-bundle] bzr/charles.bell@sun.com-20091113181921-s4ci1wyp5rr6o9bh.bundle
| Thread |
|---|
| • bzr commit into mysql-6.0-backup branch (charles.bell:2889) Bug#44787 | Chuck Bell | 13 Nov |