List:Commits« Previous MessageNext Message »
From:Chuck Bell Date:November 25 2009 10:23pm
Subject:bzr commit into mysql-6.0-backup branch (charles.bell:2891) Bug#44787
WL#5172
View as plain text  
#At file:///Users/cbell/source/bzr/mysql-6.0-bug-44787/ based on revid:charles.bell@stripped

 2891 Chuck Bell	2009-11-25 [merge]
      BUG#44787 : Backup: Check privileges before executing BACKUP/RESTORE
      WL#5172 : MySQL Backup elevation options
      
      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. It shall also permit the user
      to turn restore prechecking on or off via a variable. This patch 
      implements the following:
      
      backup_elevation - startup option, global read only variable   
        ON  = turn on backup elevation
        OFF = turn off backup elevation
        Note: Default is ON
      
      restore_elevation - startup option, global read only variable   
        ON  = turn on restore elevation
        OFF = turn off restore elevation  
        Note: Default is ON
      
      restore_precheck - startup option, global and session variable  
        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
        Corrected result file.
     @ mysql-test/suite/backup/r/backup_security.result
        Corrected result file.
     @ mysql-test/suite/backup/r/backup_security_options.result
        New result file.
     @ 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-master.opt
        Option file to disable backup and restore elevation options.
     @ 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/api_types.h
        Added external declarations for compilation.
     @ sql/backup/backup_info.cc
        Added code for backup elevation.
     @ sql/backup/kernel.cc
        Added calls to save original privileges and elevate
        privileges if conditions are met.
     @ sql/backup/restore_info.cc
        New code file.
        Implements prechecking method.
     @ sql/backup/restore_info.h
        Added attribute to determine if it is safe to elevate restore.
        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.

    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-master.opt
      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
      sql/backup/restore_info.cc
    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/api_types.h
      sql/backup/backup_info.cc
      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
=== 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-25 22:23:05 +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

=== 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-25 22:23:05 +0000
@@ -1265,7 +1265,49 @@ backup_id
 # Done.
 #
 #
-# Test case 69 - testing error ER_BACKUP_UNEXPECTED_DATA
+# Ensure prechecking is ON.
+#
+SET restore_precheck = ON;
+#
+# 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.
+#
+#
+# Test case 70 - testing error ER_BACKUP_UNEXPECTED_DATA
 #
 # Set debug SESSION variable for ER_BACKUP_UNEXPECTED_DATA
 #
@@ -1306,7 +1348,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-25 22:23:05 +0000
@@ -0,0 +1,357 @@
+#
+# Show values of backup and restore elevation and precheck
+# variables for clarification of their values.
+#
+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	ON
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+Variable_name	Value
+restore_precheck	ON
+DROP DATABASE IF EXISTS backup_test;
+DROP DATABASE IF EXISTS backup_test_alt;
+#
+# Create users.
+#
+CREATE USER 'joe'@'user';
+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';
+# 
+# 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
+#
+# 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 cannot restore 
+#               the database. Note: we also add CREATE and DROP so
+#               the error will occur in the precheck to show that 
+#               having CREATE + DROP on the database is not enough to
+#               restore the objects in 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 cannot restore  
+#               the database.
+#
+#
+# Connect as root and add privileges.
+#
+REVOKE RESTORE ON backup_test.* FROM 'bup_some_priv'@'localhost';
+REVOKE CREATE, DROP ON backup_test.* 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 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_DENIED_ERROR
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+ERROR HY000: Insufficient privileges. You must have the RESTORE privilege to restore database 'backup_test'.
+SHOW ERRORS;
+Level	Code	Message
+Error	#	Insufficient privileges. You must have the RESTORE privilege to restore database 'backup_test'.
+#
+# 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 SELECT ON backup_test.* 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'.
+#
+# Connect as root and add privileges.
+#
+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_no_proc.bak' OVERWRITE;
+backup_id
+#
+#
+# Test Case 4 : Ensure that a user can restore the database if she
+#               has ALL privileges on the database, ALL privileges
+#               on the system tables (mysql.*), except GRANT, and the
+#               global SUPER privilege.
+#
+#
+# Connect as root and add 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 the TRIGGER_ACL privilege is needed for 
+#               restore when restore_elevation is OFF and
+#               restore_precheck is ON.
+#
+#
+# Perform a backup with only a table and a trigger.
+# No grants either.
+#
+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';
+GRANT ALL ON backup_test_trig.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+REVOKE TRIGGER ON backup_test_trig.* FROM 'bup_some_priv'@'localhost';
+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, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, BACKUP, RESTORE ON `backup_test_trig`.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION
+#
+# Connect as user with only some privileges.
+#
+#
+# Show values of backup and restore elevation and precheck
+# variables for clarification of their values.
+#
+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	ON
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+Variable_name	Value
+restore_precheck	ON
+#
+# 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
+#
+#
+# Connect as root and remove privilege for trigger.
+#
+REVOKE TRIGGER ON backup_test_trig.t1 FROM 'bup_some_priv'@'localhost';
+FLUSH PRIVILEGES;
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should fail with
+# 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	1798	Insufficient privileges. You do not have privileges to restore the object 'trg' from this backup image.
+#
+# Connect as root and cleanup.
+#
+DROP DATABASE backup_test_trig;
+#
+# Cleanup
+#
+DROP USER 'bup_some_priv'@'localhost';
+DROP USER 'joe'@'user';
+DROP DATABASE backup_test;
+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-25 22:23:05 +0000
@@ -1,3 +1,19 @@
+#
+# Show values of backup and restore elevation and precheck
+# variables for clarification of their values.
+#
+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
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+Variable_name	Value
+restore_precheck	ON
 DROP DATABASE IF EXISTS backup_test;
 DROP DATABASE IF EXISTS backup_test_alt;
 #
@@ -53,7 +69,6 @@ CREATE USER 'bup_user1'@'localhost';
 #
 # Setup grants for bup_no_priv
 #
-REVOKE ALL ON *.* FROM 'bup_no_priv'@'localhost';
 GRANT SELECT ON backup_test_alt.* TO 'bup_no_priv'@'localhost';
 #
 # Setup grants for bup_root_user
@@ -63,7 +78,6 @@ GRANT GRANT OPTION ON *.* TO 'bup_root_u
 #
 # Setup grants for bup_user1
 #
-REVOKE ALL ON *.* FROM 'bup_user1'@'localhost';
 GRANT BACKUP, RESTORE ON backup_test.* TO 'bup_user1'@'localhost';
 FLUSH PRIVILEGES;
 # 
@@ -390,24 +404,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-25 22:23:05 +0000
@@ -0,0 +1,467 @@
+DROP DATABASE IF EXISTS backup_test;
+#
+# Show that the variables are all OFF via the options file.
+#
+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
+#
+# Show root user cannot change backup_elevation and restore_elevation
+# but can change restore_precheck.
+#
+SET @@global.backup_elevation = ON;
+ERROR HY000: Variable 'backup_elevation' is a read only variable
+SET @@global.restore_elevation = ON;
+ERROR HY000: Variable 'restore_elevation' is a read only variable
+SET @@global.restore_precheck = ON;
+SET @@global.restore_precheck = OFF;
+#
+# Create users.
+#
+CREATE USER 'joe'@'user';
+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';
+# 
+# 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
+#
+# Connect as user with only some privileges.
+#
+#
+# Show normal user cannot change backup_elevation and restore_elevation
+# but can change restore_precheck at the session level.
+# 
+SET @@global.backup_elevation = ON;
+ERROR HY000: Variable 'backup_elevation' is a read only variable
+SET @@global.restore_elevation = ON;
+ERROR HY000: Variable 'restore_elevation' is a read only variable
+SET restore_precheck = ON;
+SET restore_precheck = OFF;
+#
+# Connect as root and prepare next test case.
+#
+# 
+# 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'
+#
+# 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 BACKUP 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'
+#
+# 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 during the metadata
+#               execution stage).
+#
+REVOKE SUPER 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'
+GRANT 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_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 add CREATE and DROP.
+#
+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_BACKUP_CANT_RESTORE_SROUT
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+ERROR HY000: Could not restore stored routine `backup_test`.`p1`
+SHOW ERRORS;
+Level	Code	Message
+Error	#	Access denied for user 'bup_some_priv'@'localhost' to database 'backup_test'
+Error	#	Could not restore stored routine `backup_test`.`p1`
+#
+# Connect as root and prepare next test case.
+#
+# 
+# Test Case 4 : Show backup_elevation = OFF can succeed if privileges 
+#               granted.
+#
+REVOKE CREATE, DROP ON backup_test.* FROM 'bup_some_priv'@'localhost';
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost';
+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 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 5 : 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 SELECT ON `mysql`.* TO 'bup_some_priv'@'localhost'
+GRANT RESTORE ON `backup_test`.* TO 'bup_some_priv'@'localhost'
+#
+# Connect as user with only some privileges.
+#
+SET restore_precheck = ON;
+#
+# 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 6 : Show restore_elevation = OFF can succeed if privileges 
+#               granted.
+#
+REVOKE RESTORE ON backup_test.* FROM 'bup_some_priv'@'localhost';
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+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 SELECT 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 prepare next test case.
+#
+# 
+# Test Case 7 : 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';
+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 SELECT ON `mysql`.* TO 'bup_some_priv'@'localhost'
+GRANT RESTORE ON `backup_test`.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION
+#
+# Connect as user with only some privileges.
+#
+SET restore_precheck = ON;
+#
+# 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 8 : Ensure restore_precheck = OFF fails for not enough 
+#               privileges (Restore will fail during metadata
+#               execution stage).
+#
+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 SELECT ON `mysql`.* TO 'bup_some_priv'@'localhost'
+GRANT RESTORE 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 
+# 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 add CREATE and DROP.
+#
+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 SELECT ON `mysql`.* TO 'bup_some_priv'@'localhost'
+GRANT CREATE, DROP, RESTORE 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 
+# error ER_BACKUP_CANT_RESTORE_SROUT
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+ERROR HY000: Could not restore stored routine `backup_test`.`p1`
+SHOW ERRORS;
+Level	Code	Message
+Error	#	Access denied for user 'bup_some_priv'@'localhost' to database 'backup_test'
+Error	#	Could not restore stored routine `backup_test`.`p1`
+#
+# Connect as root and prepare next test case.
+#
+# 
+# Test Case 9 : Show restore_precheck = OFF and restore_elevation = OFF
+#               can succeed if privileges granted.
+#
+REVOKE RESTORE, CREATE, DROP 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 SELECT 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 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 SELECT ON `mysql`.* TO 'bup_some_priv'@'localhost'
+GRANT RESTORE 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 
+# 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.
+#
+#
+# Cleanup
+#
+DROP USER 'bup_some_priv'@'localhost';
+DROP USER 'joe'@'user';
+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-25 22:23:05 +0000
@@ -0,0 +1,299 @@
+DROP DATABASE IF EXISTS backup_test;
+#
+# Show values of backup and restore elevation and precheck
+# variables for clarification of their values.
+#
+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
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+Variable_name	Value
+restore_precheck	ON
+#
+# Create users.
+#
+CREATE USER 'joe'@'user';
+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';
+#
+# 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);
+# 
+# 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
+# 
+# Test Case 1 : Show backup_elevation = ON can succeed if only BACKUP 
+#               privileges granted.
+#
+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
+#
+# 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 2 : Show restore_elevation = ON and RESTORE + SUPER succeed. 
+#
+REVOKE BACKUP 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
+#
+# Connect as user with only some privileges.
+#
+#
+# conn_some_priv: Attempting restore. Should succeed
+#
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+backup_id
+#
+#
+# Test Case 3 : Show session variables obey initial values of
+#               global variables.
+#
+#
+# Show variable initial values for clarity.
+#
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+Variable_name	Value
+restore_precheck	ON
+SHOW VARIABLES LIKE 'restore_precheck';
+Variable_name	Value
+restore_precheck	ON
+#
+# Do session change. Set to OFF for session. 
+# Show that global is still ON.
+#
+SET restore_precheck = OFF;
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+Variable_name	Value
+restore_precheck	ON
+SHOW VARIABLES LIKE 'restore_precheck';
+Variable_name	Value
+restore_precheck	OFF
+#
+# Connect as root and change global variables.
+#
+#
+# Do global change and reconnect. 
+# Show that session inherits global.
+#
+SET @@global.restore_precheck = OFF;
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+Variable_name	Value
+restore_precheck	OFF
+SHOW VARIABLES LIKE 'restore_precheck';
+Variable_name	Value
+restore_precheck	ON
+#
+# Connect as user and show variables.
+#
+#
+# Show session obeys global change. Should be OFF.
+#
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+Variable_name	Value
+restore_precheck	OFF
+SHOW VARIABLES LIKE 'restore_precheck';
+Variable_name	Value
+restore_precheck	OFF
+#
+# Change privileges for elevated restore test case.
+#
+#
+# Test Case 4 : 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';
+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'
+#
+# 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 5 : 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';
+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'
+#
+# 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.
+#
+#
+# Cleanup
+#
+DROP USER 'bup_some_priv'@'localhost';
+DROP USER 'joe'@'user';
+SET @@global.restore_precheck = ON;
+DROP DATABASE backup_test;
+DROP DATABASE backup_test_alt;
+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-25 22:23:05 +0000
@@ -20,7 +20,7 @@
 #
 # Part 1 of 3 : covers test cases 01 - 23.
 # Part 2 of 3 : covers test cases 24 - 48.
-# Part 3 of 3 : covers test cases 49 - 70.
+# Part 3 of 3 : covers test cases 49 - 71.
 #
 # The errors to be tested are:
 #
@@ -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,22 @@ LET $errname = ER_BACKUP_PREPARE_DRIVER;
 LET $operation = BACKUP;
 --source suite/backup/include/test_for_error.inc
 
+--echo #
+--echo # Ensure prechecking is ON.
+--echo #
+
+SET restore_precheck = ON;
+
+# 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;
+--source suite/backup/include/test_for_error.inc
+
 # 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 +416,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-master.opt'
--- a/mysql-test/suite/backup/t/backup_restore_security-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_restore_security-master.opt	2009-11-25 22:23:05 +0000
@@ -0,0 +1 @@
+--disable-backup-elevation --disable-restore-elevation

=== 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-25 22:23:05 +0000
@@ -0,0 +1,410 @@
+#
+# This test includes test cases for testing privilege checking on restore.
+#
+# Test Cases
+# ----------
+#  1. Ensure a user with only RESTORE cannot restore the database.
+#  2. Ensure a user with only SELECT cannot restore the database.
+#  3. Show that SUPER is needed when there are objects that use a definer
+#     clause in the backup image.
+#  4. Ensure that a user can restore the database if she has ALL privileges
+#     on the database, ALL privileges on the system tables (mysql.*), except 
+#     GRANT, and the global SUPER privilege.
+#  5. Show the TRIGGER_ACL privilege is needed for restore when 
+#     restore_elevation is OFF and restore_precheck is ON.
+#
+
+--source include/not_embedded.inc
+
+disable_query_log;
+call mtr.add_suppression("Restore: Insufficient privileges");
+enable_query_log;
+
+--echo #
+--echo # Show values of backup and restore elevation and precheck
+--echo # variables for clarification of their values.
+--echo #
+SHOW VARIABLES LIKE 'backup_elevation';
+SHOW VARIABLES LIKE 'restore_elevation';
+SHOW VARIABLES LIKE 'restore_precheck';
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+
+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 'joe'@'user';
+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 # 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 # 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 cannot restore 
+--echo #               the database. Note: we also add CREATE and DROP so
+--echo #               the error will occur in the precheck to show that 
+--echo #               having CREATE + DROP on the database is not enough to
+--echo #               restore the objects in 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 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 RESTORE ON backup_test.* FROM 'bup_some_priv'@'localhost';
+REVOKE CREATE, DROP ON backup_test.* 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_DENIED_ERROR
+--echo #
+--replace_column 1 #
+--error ER_RESTORE_ACCESS_DENIED_ERROR
+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 SELECT ON backup_test.* 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;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and add privileges.
+--echo #
+connect (conn_root,localhost,root,,);
+
+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_no_proc.bak' OVERWRITE;
+
+--echo #
+--echo # Test Case 4 : Ensure that a user can restore the database if she
+--echo #               has ALL privileges on the database, ALL privileges
+--echo #               on the system tables (mysql.*), except GRANT, and the
+--echo #               global SUPER privilege.
+--echo #
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and add privileges.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--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 the TRIGGER_ACL privilege is needed for 
+--echo #               restore when restore_elevation is OFF and
+--echo #               restore_precheck is ON.
+--echo #
+
+--echo #
+--echo # Perform a backup with only a table and a trigger.
+--echo # No grants either.
+--echo #
+
+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';
+
+GRANT ALL ON backup_test_trig.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+REVOKE TRIGGER ON backup_test_trig.* FROM 'bup_some_priv'@'localhost';
+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 # Show values of backup and restore elevation and precheck
+--echo # variables for clarification of their values.
+--echo #
+SHOW VARIABLES LIKE 'backup_elevation';
+SHOW VARIABLES LIKE 'restore_elevation';
+SHOW VARIABLES LIKE 'restore_precheck';
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+
+--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 # Connect as root and remove privilege for trigger.
+--echo #
+connect (conn_root,localhost,root,,);
+
+REVOKE TRIGGER ON backup_test_trig.t1 FROM '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_OBJS_INCOMPLETE
+--echo #
+--replace_column 1 #
+--error ER_RESTORE_ACCESS_OBJS_INCOMPLETE
+RESTORE FROM 'backup_test_trig.bak' OVERWRITE;
+SHOW ERRORS;
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and cleanup.
+--echo #
+connect (conn_root,localhost,root,,);
+
+DROP DATABASE backup_test_trig;
+
+--echo #
+--echo # Cleanup
+--echo #
+
+DROP USER 'bup_some_priv'@'localhost';
+DROP USER 'joe'@'user';
+
+DROP DATABASE backup_test;
+FLUSH PRIVILEGES;
+
+let $MYSQLD_BACKUPDIR= `select @@backupdir`;
+remove_file $MYSQLD_BACKUPDIR/backup_test_orig.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-25 22:23:05 +0000
@@ -9,18 +9,24 @@
 # 4) Show that if a user has BACKUP on one database but not another, the 
 #    user cannot perform a backup of both databases.
 #
-# Note: This test has been modified to only test backup privilege
-#       test cases. A separate test file shall be created to test restore 
-#       privileges. See BUG#44787.
-#
 
 --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;
 
+--echo #
+--echo # Show values of backup and restore elevation and precheck
+--echo # variables for clarification of their values.
+--echo #
+SHOW VARIABLES LIKE 'backup_elevation';
+SHOW VARIABLES LIKE 'restore_elevation';
+SHOW VARIABLES LIKE 'restore_precheck';
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+
 connect (conn_root,localhost,root,,);
 
 --disable_warnings
@@ -55,7 +61,6 @@ CREATE USER 'bup_user1'@'localhost';
 --echo #
 --echo # Setup grants for bup_no_priv
 --echo #
-REVOKE ALL ON *.* FROM 'bup_no_priv'@'localhost';
 GRANT SELECT ON backup_test_alt.* TO 'bup_no_priv'@'localhost';
 
 --echo #
@@ -67,7 +72,6 @@ GRANT GRANT OPTION ON *.* TO 'bup_root_u
 --echo #
 --echo # Setup grants for bup_user1
 --echo #
-REVOKE ALL ON *.* FROM 'bup_user1'@'localhost';
 GRANT BACKUP, RESTORE ON backup_test.* TO 'bup_user1'@'localhost'; 
 
 FLUSH PRIVILEGES;
@@ -184,11 +188,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 +202,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-16 14:10:33 +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-25 22:23:05 +0000
@@ -0,0 +1,567 @@
+#
+# 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
+#
+# This test is a test of turning OFF the MySQL Backup elevation
+# options via the -master.opt file. All are OFF at start of test.
+#
+# 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 during the metadata exection stage).
+#   4. Show backup_elevation = ON can succeed if minimal privileges granted.
+#   5. Ensure restore_elevation = OFF fails for not enough privileges.
+#   6. Show restore_elevation = OFF can succeed if privileges granted.
+#   7. Show restore_elevation = OFF and RESTORE + SUPER still fail.
+#   8. Ensure restore_precheck = OFF fails for not enough privileges 
+#      (Restore will fail during the metadata execution stage).
+#   9. Show restore_precheck = OFF and restore_elevation = OFF can succeed 
+#      if privileges granted.
+#  10. Ensure restore_elevation = OFF and restore_precheck = OFF fails
+#      for not enough privileges.
+#
+
+--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");
+call mtr.add_suppression("Restore: Could not restore stored");
+enable_query_log;
+
+connect (conn_root,localhost,root,,);
+
+--disable_warnings
+DROP DATABASE IF EXISTS backup_test;
+--enable_warnings
+
+--echo #
+--echo # Show that the variables are all OFF via the options file.
+--echo #
+SHOW VARIABLES LIKE 'backup_elevation';
+SHOW VARIABLES LIKE 'restore_elevation';
+SHOW VARIABLES LIKE 'restore_precheck';
+
+--echo #
+--echo # Show root user cannot change backup_elevation and restore_elevation
+--echo # but can change restore_precheck.
+--echo #
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@global.backup_elevation = ON;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@global.restore_elevation = ON;
+SET @@global.restore_precheck = ON;
+SET @@global.restore_precheck = OFF; 
+
+--echo #
+--echo # Create users.
+--echo #
+CREATE USER 'joe'@'user';
+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 # 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';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # Show normal user cannot change backup_elevation and restore_elevation
+--echo # but can change restore_precheck at the session level.
+--echo # 
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@global.backup_elevation = ON;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@global.restore_elevation = ON;
+SET restore_precheck = ON;
+SET restore_precheck = OFF; 
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and prepare next test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--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';
+
+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 BACKUP 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';
+
+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 during the metadata
+--echo #               execution stage).
+--echo #
+
+REVOKE SUPER ON *.* FROM '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_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 add CREATE and DROP.
+--echo #
+connect (conn_root,localhost,root,,);
+
+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_BACKUP_CANT_RESTORE_SROUT
+--echo #
+--replace_column 1 #
+--error ER_BACKUP_CANT_RESTORE_SROUT
+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 4 : Show backup_elevation = OFF can succeed if privileges 
+--echo #               granted.
+--echo #
+
+REVOKE CREATE, DROP ON backup_test.* FROM 'bup_some_priv'@'localhost';
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost';
+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 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 5 : 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';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user with only some privileges.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+SET restore_precheck = ON;
+
+--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 6 : Show restore_elevation = OFF can succeed if privileges 
+--echo #               granted.
+--echo #
+
+REVOKE RESTORE ON backup_test.* FROM 'bup_some_priv'@'localhost';
+GRANT ALL ON backup_test.* TO 'bup_some_priv'@'localhost' WITH GRANT OPTION;
+
+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 prepare next test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo # 
+--echo # Test Case 7 : 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';
+
+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,,);
+
+SET restore_precheck = ON;
+
+--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 8 : Ensure restore_precheck = OFF fails for not enough 
+--echo #               privileges (Restore will fail during metadata
+--echo #               execution stage).
+--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';
+
+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 add CREATE and DROP.
+--echo #
+connect (conn_root,localhost,root,,);
+
+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_BACKUP_CANT_RESTORE_SROUT
+--echo #
+--replace_column 1 #
+--error ER_BACKUP_CANT_RESTORE_SROUT
+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 9 : Show restore_precheck = OFF and restore_elevation = OFF
+--echo #               can succeed if privileges granted.
+--echo #
+
+REVOKE RESTORE, CREATE, DROP 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';
+
+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';
+
+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 # Cleanup
+--echo #
+
+DROP USER 'bup_some_priv'@'localhost';
+DROP USER 'joe'@'user';
+
+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-25 22:23:05 +0000
@@ -0,0 +1,343 @@
+#
+# 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
+#
+# This test is run during the normal mode of all options set to ON. This
+# test includes test cases for checking the minimal requirements for
+# elevation to succeed.
+#
+# Test Cases
+# ----------
+#   1. Show backup_elevation = ON can succeed if minimal privileges granted.
+#   2. Show restore_elevation = ON and RESTORE + SUPER succeed.
+#   3. Show session variable obeys initial values of global variables.
+#   4. Show that user can have only RESTORE + SUPER and perform an
+#      elevated restore.
+#   5. 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("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
+
+--echo #
+--echo # Show values of backup and restore elevation and precheck
+--echo # variables for clarification of their values.
+--echo #
+SHOW VARIABLES LIKE 'backup_elevation';
+SHOW VARIABLES LIKE 'restore_elevation';
+SHOW VARIABLES LIKE 'restore_precheck';
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+
+--echo #
+--echo # Create users.
+--echo #
+CREATE USER 'joe'@'user';
+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 # 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 # 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 # Test Case 1 : Show backup_elevation = ON can succeed if only BACKUP 
+--echo #               privileges granted.
+--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';
+
+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 2 : Show restore_elevation = ON and RESTORE + SUPER succeed. 
+--echo #
+
+REVOKE BACKUP 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 succeed
+--echo #
+--replace_column 1 #
+RESTORE FROM 'backup_test_orig.bak' OVERWRITE;
+
+--echo #
+--echo # Test Case 3 : Show session variables obey initial values of
+--echo #               global variables.
+--echo #
+
+--echo #
+--echo # Show variable initial values for clarity.
+--echo #
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+SHOW VARIABLES LIKE 'restore_precheck';
+
+--echo #
+--echo # Do session change. Set to OFF for session. 
+--echo # Show that global is still ON.
+--echo #
+SET restore_precheck = OFF;
+
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+SHOW VARIABLES LIKE 'restore_precheck';
+
+disconnect conn_some_priv;
+--echo #
+--echo # Connect as root and change global variables.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Do global change and reconnect. 
+--echo # Show that session inherits global.
+--echo #
+SET @@global.restore_precheck = OFF;
+
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+SHOW VARIABLES LIKE 'restore_precheck';
+
+disconnect conn_root;
+--echo #
+--echo # Connect as user and show variables.
+--echo #
+connect (conn_some_priv,localhost,bup_some_priv,,);
+
+--echo #
+--echo # Show session obeys global change. Should be OFF.
+--echo #
+SHOW GLOBAL VARIABLES LIKE 'restore_precheck';
+SHOW VARIABLES LIKE 'restore_precheck';
+
+disconnect conn_some_priv;
+--echo #
+--echo # Change privileges for elevated restore test case.
+--echo #
+connect (conn_root,localhost,root,,);
+
+--echo #
+--echo # Test Case 4 : 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';
+
+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';
+
+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 5 : 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';
+
+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';
+
+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 # Cleanup
+--echo #
+
+DROP USER 'bup_some_priv'@'localhost';
+DROP USER 'joe'@'user';
+
+SET @@global.restore_precheck = ON;
+
+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;

=== 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-16 14:10:33 +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-16 14:10:33 +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/api_types.h'
--- a/sql/backup/api_types.h	2009-10-21 13:32:24 +0000
+++ b/sql/backup/api_types.h	2009-11-25 22:23:05 +0000
@@ -21,6 +21,12 @@
 /// A null string external reference.
 extern const String my_null_string;
 
+/// Global read only variable for backup elevation setting.
+extern my_bool opt_backup_elevation;
+
+/// Global read only variable for restore elevation setting.
+extern my_bool opt_restore_elevation;
+
 namespace backup {
 
 /// Definition of byte type.

=== 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-25 22:23:05 +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,15 @@ 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 (opt_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/kernel.cc'
--- a/sql/backup/kernel.cc	2009-10-23 15:41:56 +0000
+++ b/sql/backup/kernel.cc	2009-11-25 22:23:05 +0000
@@ -639,6 +639,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;
 
@@ -1180,6 +1185,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 +1592,9 @@ int Backup_restore_ctx::do_restore(bool 
   if (report_killed())
     DBUG_RETURN(fatal_error(ER_QUERY_INTERRUPTED));
 
+  if (info.restore_elevation())
+    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())
@@ -1985,6 +1998,18 @@ int bcat_add_item(st_bstream_image_heade
                         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.
+  */
+  if (info->check_restore_privileges(item))
+     return BSTREAM_ERROR; 
+  
   switch (item->type) {
 
   case BSTREAM_IT_TABLESPACE:

=== added file 'sql/backup/restore_info.cc'
--- a/sql/backup/restore_info.cc	1970-01-01 00:00:00 +0000
+++ b/sql/backup/restore_info.cc	2009-11-25 22:23:05 +0000
@@ -0,0 +1,226 @@
+/* Copyright (C) 2008 Sun Microsystems, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/**
+  @file
+
+  Implementation of @c Restore_info class methods. 
+  
+  Method @c check_restore_privileges performs privilege checking for restore.
+*/
+
+#include <backup/restore_info.h>
+
+
+/**
+  Perform privilege checking for restore.
+ 
+  This method checks the known minimal privileges needed to restore each
+  object in the backup image. This method is called once for every object in 
+  the catalog. It ensures there are no privilege-based restrictions that would 
+  prohibit a successful restore. 
+  
+  It begins by checking that the user has RESTORE for each database listed in 
+  the backup image. If the user does not have RESTORE for any database in the 
+  list, an error is generated. Next, specific object-level privilege checking 
+  is performed for all of the objects in the database. 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)
+ 
+  @note Object-level prechecking is skipped if restore_prechecking is
+  turned off or it has been determined it is safe to elevate restore. The
+  actual elevation of restore occurs before metadata creation. 
+ 
+  @param[in] item     The item to check.
+ 
+  @returns 
+    @retval  FALSE    User has privileges for the object.
+    @retval  TRUE     User does not have privileges for object.
+*/
+bool 
+Restore_info::check_restore_privileges(struct st_bstream_item_info *item)
+{
+  using namespace backup;
+  int result= 0;
+  THD *thd= ::current_thd;          
+  Image_info::Db *db= NULL;         // Database object
+  st_bstream_dbitem_info *db_item;  // Database item information
+  TABLE_LIST tbl_list;
+  
+
+  backup::String item_name(item->name.begin, item->name.end);
+  const char *name_str= item_name.c_ptr_safe();
+
+  DBUG_ASSERT(item);
+  
+  /*
+    Check privileges for this database. User must have RESTORE
+    privilege in order to execute a restore.
+  */
+  DEBUG_SYNC(thd, "before_restore_privileges");
+  
+  if (item->type == BSTREAM_IT_DB)
+  {
+    if (check_access(thd, RESTORE_ACL, name_str, 0, 1, 1, 0))
+    {
+      m_log.report_error(ER_RESTORE_ACCESS_DENIED_ERROR, name_str);
+      return TRUE;
+    }
+  }
+
+  /*
+    Since restore_elevation is a global read-only variable, we must turn 
+    result of elevation check off via debug to allow debug error insertion 
+    to work below.
+  */
+  DBUG_EXECUTE_IF("ER_RESTORE_DB_ERROR", m_restore_elevation= FALSE;);
+
+  /*
+    If prechecking is turned off or restore elevation is turned on,
+    skip prechecking.
+  */
+  if (!m_thd->variables.restore_precheck || m_restore_elevation)
+    return FALSE;
+
+  /*
+    Get the database for objects that have a database element.
+  */
+  switch (item->type) 
+  {
+  case BSTREAM_IT_TABLE:
+  case BSTREAM_IT_VIEW:
+  case BSTREAM_IT_SPROC:
+  case BSTREAM_IT_SFUNC:
+  case BSTREAM_IT_EVENT:
+  case BSTREAM_IT_TRIGGER:
+  case BSTREAM_IT_PRIVILEGE:
+    {
+      db_item= (st_bstream_dbitem_info*) item;
+
+      db= get_db(db_item->db->base.pos);
+      DBUG_EXECUTE_IF("ER_RESTORE_DB_ERROR", db= NULL;);
+      if (!db)
+      {
+        m_log.report_error(ER_RESTORE_DB_ERROR, name_str);
+        return TRUE;
+      }
+      break;
+    }
+  default:
+    break;
+  } // switch (item->type)
+
+  /*
+    Check privileges for each object based on type of object.
+  */
+  switch (item->type) 
+  {
+  case BSTREAM_IT_TABLESPACE:
+    {
+      result= !(thd->security_ctx->master_access & CREATE_TABLESPACE_ACL);
+      break;        
+    }
+  case BSTREAM_IT_DB:
+    {
+       result= check_access(thd, CREATE_ACL + DROP_ACL, name_str, 0, 1, 1, 0);
+       break;
+    }
+  case BSTREAM_IT_SPROC:
+  case BSTREAM_IT_SFUNC:
+    {
+      result= check_access(thd, CREATE_PROC_ACL, db->name().ptr(), 0, 1, 1, 0); 
+      break;
+    }
+  case BSTREAM_IT_EVENT:
+    {
+      result= check_access(thd, EVENT_ACL, db->name().ptr(), 0, 1, 1, 0); 
+      break;
+    }
+  case BSTREAM_IT_TRIGGER:
+    {
+      /*
+        Get the table reference for this trigger and check access.
+      */
+      Image_info::Table *tbl= get_table(db_item->snap_num, db_item->pos);
+      
+      /*
+        If the table is not found, revert to checking at the database
+        level.
+      */
+      if (!tbl)
+      {
+        result= check_access(thd, TRIGGER_ACL, db->name().ptr(), 0, 1, 1, 0); 
+      }
+      else 
+      {
+        tbl_list.init_one_table(db->name().ptr(), db->name().length(),
+                                tbl->name().ptr(), tbl->name().length(),
+                                tbl->name().ptr(), TL_READ);
+        result= check_table_access(thd, TRIGGER_ACL, &tbl_list, TRUE, TRUE, 1);
+      }
+      break;
+    }
+  case BSTREAM_IT_PRIVILEGE:
+    {
+      result= check_access(thd, GRANT_ACL, db->name().ptr(), 0, 1, 1, 0); 
+      break;
+    }
+  default:
+    break;
+  } // switch (item->type)
+    
+  // Return error if privilege check fails.
+  if (result)
+  {
+    m_log.report_error(ER_RESTORE_ACCESS_OBJS_INCOMPLETE, name_str);
+    return TRUE;
+  }
+
+  /*
+    Check for SUPER_ACL if any objects exist that have a definer clause.
+  */
+  switch (item->type) 
+  {
+  case BSTREAM_IT_VIEW:
+  case BSTREAM_IT_SPROC:
+  case BSTREAM_IT_SFUNC:
+  case BSTREAM_IT_EVENT:
+  case BSTREAM_IT_TRIGGER:
+    {
+      result= !(thd->security_ctx->master_access & SUPER_ACL);
+      break;
+    }
+  default:
+    break;
+  } // switch (item->type)
+  
+  // Return error if privilege check fails.
+  if (result)
+  {
+    m_log.report_error(ER_RESTORE_ACCESS_DEFINER, db->name().ptr(), name_str);
+    return TRUE;
+  }
+  return FALSE;
+}
+

=== 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-25 22:23:05 +0000
@@ -45,6 +45,12 @@ 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);
+  
+  /// Return whether it is safe to elevate restore.
+  bool restore_elevation() { return m_restore_elevation; }
+  
 private:
 
   /*
@@ -59,6 +65,12 @@ private:
 
   THD *m_thd;
 
+  /**
+    Determines if it is safe to implement restore elevation. Specifically,
+    that the user has SUPER_ACL and restore_elevation is turned on.
+  */
+  bool m_restore_elevation;
+  
   /// A flag to indicate that data has been modified during restore operation.
   bool m_data_changed;
 
@@ -77,7 +89,10 @@ private:
 inline
 Restore_info::Restore_info(backup::Logger &log, THD *thd)
   :m_log(log), m_thd(thd), m_data_changed(FALSE)
-{}
+{
+  m_restore_elevation= (opt_restore_elevation &&
+                        (m_thd->security_ctx->master_access & SUPER_ACL));
+}
 
 
 inline
@@ -117,17 +132,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-25 22:23:05 +0000
@@ -466,6 +466,8 @@ my_bool opt_backup_progress_log;
 my_bool opt_mysql_backup;
 ulong log_output_options;
 ulong log_backup_output_options;
+my_bool opt_backup_elevation= TRUE;
+my_bool opt_restore_elevation= TRUE;
 my_bool opt_log_queries_not_using_indexes= 0;
 bool opt_error_log= IF_WIN(1,0);
 bool opt_disable_networking=0, opt_skip_show_db=0;
@@ -6052,6 +6054,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
 };
 
@@ -6103,6 +6108,9 @@ struct my_option my_long_options[] =
   {"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},
+  {"backup-elevation", OPT_BACKUP_ELEVATION,
+   "Enable|disable privilege elevaton for backup", (uchar**) &opt_backup_elevation,
+   (uchar**) &opt_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 +6687,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**) &opt_restore_elevation,
+   (uchar**) &opt_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-25 22:23:05 +0000
@@ -185,6 +185,9 @@ 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_const    sys_backup_elevation(&vars, "backup_elevation",
+                                             OPT_GLOBAL, SHOW_BOOL,
+                                             (uchar*) &opt_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 +514,11 @@ 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_const    sys_restore_elevation(&vars, "restore_elevation",
+                                              OPT_GLOBAL, SHOW_BOOL,
+                                              (uchar*) &opt_restore_elevation);
+static sys_var_thd_bool sys_restore_precheck(&vars, "restore_precheck",
+                                              &SV::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-16 14:10:33 +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-16 14:10:33 +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-25 22:23:05 +0000
@@ -203,9 +203,6 @@ run_service_interface_sql(THD *thd, Ed_c
                           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
-  
   
   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-16 14:10:33 +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-25 22:23:05 +0000
@@ -448,6 +448,9 @@ struct system_variables
   /* deadlock detection */
   ulong wt_timeout_short, wt_deadlock_search_depth_short;
   ulong wt_timeout_long, wt_deadlock_search_depth_long;
+  
+  /* MySQL Backup privilege variables */
+  my_bool restore_precheck;
 };
 
 
@@ -852,6 +855,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 +877,8 @@ public:
   restore_security_context(THD *thd, Security_context *backup);
 #endif
   bool user_matches(Security_context *);
+private:
+  ulong m_saved_master_access; 
 };
 
 


Attachment: [text/bzr-bundle] bzr/charles.bell@sun.com-20091125222305-a6cvle2442dots5j.bundle
Thread
bzr commit into mysql-6.0-backup branch (charles.bell:2891) Bug#44787WL#5172Chuck Bell25 Nov
  • Re: bzr commit into mysql-6.0-backup branch (charles.bell:2891)Bug#44787 WL#5172Ingo Strüwing30 Nov
    • Re: bzr commit into mysql-6.0-backup branch (charles.bell:2891)Bug#44787 WL#5172Dr. Charles A. Bell30 Nov