List:Commits« Previous MessageNext Message »
From:Georgi Kodinov Date:November 19 2010 2:13pm
Subject:bzr commit into mysql-5.5-bugteam branch (Georgi.Kodinov:3128) Bug#57551
View as plain text  
#At file:///home/kgeorge/mysql/work/B57551-5.5-bugteam/ based on revid:davi.arnaut@stripped

 3128 Georgi Kodinov	2010-11-19
      Bug #57551: Live upgrade fails between 5.1.52 -> 5.5.7-rc
      
      Updated the server to treat a missing mysql.proxies_priv table 
      as empty. 
      Added some grants to make sure tables are correctly opened
      when they must be opened.
      Fixed a mysql_upgrade omission not adding rights to root to 
      execute GRANT PROXY on other users.
      Removed a redundant CREATE TABLE from 
      mysql_system_tables_fix.sql since it's always executed after
      mysql_system_tables.sql and the first file has CREATE TABLE 
      in it. 
      Added a test case for the above.
      Fixed error handling code to close the cursor

    modified:
      mysql-test/r/plugin_auth.result
      mysql-test/t/plugin_auth.test
      scripts/mysql_system_tables_fix.sql
      sql/sql_acl.cc
=== modified file 'mysql-test/r/plugin_auth.result'
--- a/mysql-test/r/plugin_auth.result	2010-11-03 11:47:22 +0000
+++ b/mysql-test/r/plugin_auth.result	2010-11-19 14:13:11 +0000
@@ -255,3 +255,64 @@ GRANT PROXY ON standard_user TO ''@'';
 DROP USER ''@'';
 DROP USER standard_user;
 DROP DATABASE shared;
+#
+# Bug #57551 : Live upgrade fails between 5.1.52 -> 5.5.7-rc
+#
+CALL mtr.add_suppression("Missing system table mysql.proxies_priv.");
+DROP TABLE mysql.proxies_priv;
+# Must come back with mysql.proxies_priv absent.
+SELECT * FROM mysql.proxies_priv;
+ERROR 42S02: Table 'mysql.proxies_priv' doesn't exist
+CREATE USER u1@localhost;
+GRANT ALL PRIVILEGES ON *.* TO u1@localhost;
+REVOKE ALL PRIVILEGES ON *.* FROM u1@localhost;
+GRANT ALL PRIVILEGES ON *.* TO u1@localhost;
+CREATE USER u2@localhost;
+GRANT ALL PRIVILEGES ON *.* TO u2@localhost;
+# access denied because of no privileges to root
+GRANT PROXY ON u2@localhost TO u1@localhost;
+ERROR 28000: Access denied for user 'root'@'localhost'
+# access denied because of no privileges to root
+REVOKE PROXY ON u2@localhost FROM u1@localhost;
+ERROR 28000: Access denied for user 'root'@'localhost'
+# go try graning proxy on itself, so that it will need the table
+GRANT PROXY ON u2@localhost TO u1@localhost;
+ERROR 42S02: Table 'mysql.proxies_priv' doesn't exist
+REVOKE PROXY ON u2@localhost FROM u1@localhost;
+ERROR 42S02: Table 'mysql.proxies_priv' doesn't exist
+REVOKE ALL PRIVILEGES ON *.* FROM u1@localhost, u2@localhost;
+DROP USER u1@localhost,u2@localhost;
+FLUSH PRIVILEGES;
+mtr.global_suppressions                            OK
+mtr.test_suppressions                              OK
+mysql.columns_priv                                 OK
+mysql.db                                           OK
+mysql.event                                        OK
+mysql.func                                         OK
+mysql.general_log                                  OK
+mysql.help_category                                OK
+mysql.help_keyword                                 OK
+mysql.help_relation                                OK
+mysql.help_topic                                   OK
+mysql.host                                         OK
+mysql.ndb_binlog_index                             OK
+mysql.plugin                                       OK
+mysql.proc                                         OK
+mysql.procs_priv                                   OK
+mysql.servers                                      OK
+mysql.slow_log                                     OK
+mysql.tables_priv                                  OK
+mysql.time_zone                                    OK
+mysql.time_zone_leap_second                        OK
+mysql.time_zone_name                               OK
+mysql.time_zone_transition                         OK
+mysql.time_zone_transition_type                    OK
+mysql.user                                         OK
+SELECT Host,User,Proxied_host,Proxied_user,With_grant FROM mysql.proxies_priv;
+Host	localhost
+User	root
+Proxied_host	
+Proxied_user	
+With_grant	1
+FLUSH PRIVILEGES;
+End of 5.5 tests

=== modified file 'mysql-test/t/plugin_auth.test'
--- a/mysql-test/t/plugin_auth.test	2010-11-03 11:47:22 +0000
+++ b/mysql-test/t/plugin_auth.test	2010-11-19 14:13:11 +0000
@@ -1,5 +1,6 @@
 --source include/have_plugin_auth.inc
 --source include/not_embedded.inc
+--source include/mysql_upgrade_preparation.inc
 
 query_vertical SELECT PLUGIN_STATUS, PLUGIN_TYPE, PLUGIN_DESCRIPTION
   FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='test_plugin_server';
@@ -335,3 +336,62 @@ GRANT PROXY ON standard_user TO ''@'';
 DROP USER ''@'';
 DROP USER standard_user;
 DROP DATABASE shared;
+
+
+--echo #
+--echo # Bug #57551 : Live upgrade fails between 5.1.52 -> 5.5.7-rc
+--echo #
+
+CALL mtr.add_suppression("Missing system table mysql.proxies_priv.");
+
+DROP TABLE mysql.proxies_priv;
+
+--echo # Must come back with mysql.proxies_priv absent.
+--source include/restart_mysqld.inc
+
+--error ER_NO_SUCH_TABLE
+SELECT * FROM mysql.proxies_priv;
+
+CREATE USER u1@localhost;
+GRANT ALL PRIVILEGES ON *.* TO u1@localhost;
+REVOKE ALL PRIVILEGES ON *.* FROM u1@localhost;
+GRANT ALL PRIVILEGES ON *.* TO u1@localhost;
+
+CREATE USER u2@localhost;
+GRANT ALL PRIVILEGES ON *.* TO u2@localhost;
+
+--echo # access denied because of no privileges to root
+--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR
+GRANT PROXY ON u2@localhost TO u1@localhost;
+
+--echo # access denied because of no privileges to root
+--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR
+REVOKE PROXY ON u2@localhost FROM u1@localhost;
+
+--echo # go try graning proxy on itself, so that it will need the table
+connect(proxy_granter_con,localhost,u2,);
+connection proxy_granter_con;
+
+--error ER_NO_SUCH_TABLE
+GRANT PROXY ON u2@localhost TO u1@localhost;
+--error ER_NO_SUCH_TABLE
+REVOKE PROXY ON u2@localhost FROM u1@localhost;
+
+connection default;
+disconnect proxy_granter_con;
+
+--echo # test if REVOKE works without the proxies_priv table
+REVOKE ALL PRIVILEGES ON *.* FROM u1@localhost, u2@localhost;
+
+--echo # test if DROP USER work without the proxies_priv table
+DROP USER u1@localhost,u2@localhost;
+
+--echo # test if FLUSH PRIVILEGES works without the proxies_priv table
+FLUSH PRIVILEGES;
+
+--exec $MYSQL_UPGRADE --skip-verbose --force 2>&1
+--query_vertical SELECT Host,User,Proxied_host,Proxied_user,With_grant FROM mysql.proxies_priv
+
+FLUSH PRIVILEGES;
+
+--echo End of 5.5 tests

=== modified file 'scripts/mysql_system_tables_fix.sql'
--- a/scripts/mysql_system_tables_fix.sql	2010-11-02 15:45:26 +0000
+++ b/scripts/mysql_system_tables_fix.sql	2010-11-19 14:13:11 +0000
@@ -643,7 +643,14 @@ drop procedure mysql.die;
 ALTER TABLE user ADD plugin char(60) DEFAULT '' NOT NULL,  ADD authentication_string TEXT NOT NULL;
 ALTER TABLE user MODIFY plugin char(60) DEFAULT '' NOT NULL;
 
-CREATE TABLE IF NOT EXISTS proxies_priv (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Proxied_host char(60) binary DEFAULT '' NOT NULL, Proxied_user char(16) binary DEFAULT '' NOT NULL, With_grant BOOL DEFAULT 0 NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp, PRIMARY KEY Host (Host,User,Proxied_host,Proxied_user), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User proxy privileges';
+-- Need to pre-fill mysql.proxies_priv with access for root even when upgrading from
+-- older versions
+
+CREATE TEMPORARY TABLE tmp_proxies_priv LIKE proxies_priv;
+INSERT INTO tmp_proxies_priv VALUES ('localhost', 'root', '', '', TRUE, '', now());
+INSERT INTO proxies_priv SELECT * FROM tmp_proxies_priv WHERE @had_proxies_priv_table=0;
+DROP TABLE tmp_proxies_priv;
+
 
 # Activate the new, possible modified privilege tables
 # This should not be needed, but gives us some extra testing that the above

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2010-11-02 15:45:26 +0000
+++ b/sql/sql_acl.cc	2010-11-19 14:13:11 +0000
@@ -1029,24 +1029,35 @@ static my_bool acl_load(THD *thd, TABLE_
   end_read_record(&read_record_info);
   freeze_size(&acl_dbs);
 
-  init_read_record(&read_record_info, thd, table= tables[3].table, NULL, 1, 
-                   0, FALSE);
-  table->use_all_columns();
   (void) my_init_dynamic_array(&acl_proxy_users, sizeof(ACL_PROXY_USER), 
                                50, 100);
-  while (!(read_record_info.read_record(&read_record_info)))
+  if (tables[3].table)
   {
-    ACL_PROXY_USER proxy;
-    proxy.init(table, &mem);
-    if (proxy.check_validity(check_no_resolve))
-      continue;
-    if (push_dynamic(&acl_proxy_users, (uchar*) &proxy))
-      return TRUE;
+    init_read_record(&read_record_info, thd, table= tables[3].table, NULL, 1, 
+                     0, FALSE);
+    table->use_all_columns();
+    while (!(read_record_info.read_record(&read_record_info)))
+    {
+      ACL_PROXY_USER proxy;
+      proxy.init(table, &mem);
+      if (proxy.check_validity(check_no_resolve))
+        continue;
+      if (push_dynamic(&acl_proxy_users, (uchar*) &proxy))
+      {
+        end_read_record(&read_record_info);
+        goto end;
+      }
+    }
+    my_qsort((uchar*) dynamic_element(&acl_proxy_users, 0, ACL_PROXY_USER*),
+             acl_proxy_users.elements,
+             sizeof(ACL_PROXY_USER), (qsort_cmp) acl_compare);
+    end_read_record(&read_record_info);
+  }
+  else
+  {
+    sql_print_error("Missing system table mysql.proxies_priv; "
+                    "please run mysql_upgrade to create it");
   }
-  my_qsort((uchar*) dynamic_element(&acl_proxy_users, 0, ACL_PROXY_USER*),
-           acl_proxy_users.elements,
-           sizeof(ACL_PROXY_USER), (qsort_cmp) acl_compare);
-  end_read_record(&read_record_info);
   freeze_size(&acl_proxy_users);
 
   init_check_host();
@@ -1127,6 +1138,7 @@ my_bool acl_reload(THD *thd)
   tables[2].next_local= tables[2].next_global= tables + 3;
   tables[0].open_type= tables[1].open_type= tables[2].open_type= 
   tables[3].open_type= OT_BASE_ONLY;
+  tables[3].open_strategy= TABLE_LIST::OPEN_IF_EXISTS;
 
   if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
   {
@@ -5703,6 +5715,8 @@ int open_grant_tables(THD *thd, TABLE_LI
   (tables+5)->init_one_table(C_STRING_WITH_LEN("mysql"),
                              C_STRING_WITH_LEN("proxies_priv"),
                              "proxies_priv", TL_WRITE);
+  tables[5].open_strategy= TABLE_LIST::OPEN_IF_EXISTS;
+
   tables->next_local= tables->next_global= tables + 1;
   (tables+1)->next_local= (tables+1)->next_global= tables + 2;
   (tables+2)->next_local= (tables+2)->next_global= tables + 3;
@@ -6295,17 +6309,20 @@ static int handle_grant_data(TABLE_LIST 
   }
 
   /* Handle proxies_priv table. */
-  if ((found= handle_grant_table(tables, 5, drop, user_from, user_to)) < 0)
+  if (tables[5].table)
   {
-    /* Handle of table failed, don't touch the in-memory array. */
-    result= -1;
-  }
-  else
-  {
-    /* Handle proxies_priv array. */
-    if ((handle_grant_struct(5, drop, user_from, user_to) && !result) ||
-        found)
-      result= 1; /* At least one record/element found. */
+    if ((found= handle_grant_table(tables, 5, drop, user_from, user_to)) < 0)
+    {
+      /* Handle of table failed, don't touch the in-memory array. */
+      result= -1;
+    }
+    else
+    {
+      /* Handle proxies_priv array. */
+      if ((handle_grant_struct(5, drop, user_from, user_to) && !result) ||
+          found)
+        result= 1; /* At least one record/element found. */
+    }
   }
  end:
   DBUG_RETURN(result);


Attachment: [text/bzr-bundle] bzr/georgi.kodinov@oracle.com-20101119141311-vqrhriflc680fys5.bundle
Thread
bzr commit into mysql-5.5-bugteam branch (Georgi.Kodinov:3128) Bug#57551Georgi Kodinov19 Nov