From 1d762ee8fe6b2e2b031cfaa95429408479f7eb67 Mon Sep 17 00:00:00 2001 From: Robert Bindar Date: Mon, 8 Mar 2021 17:51:33 +0200 Subject: [PATCH] MDEV-24363 (followup fix) mysql.user view should not be dropped if the DEFINER is custom. Revert changes to MDEV-23102 tests as they were designed to catch this corner case. The explanation for this corner case is that users historically used to tweak the mysql.user table and probably still do even though mysql.user is now a view. Thus, if the DEFINER of the view is not default, i.e. root@localhost or mariadb.sys@localhost, we should avoid dropping the view during upgrade process to not discard potential custom changes. --- mysql-test/main/upgrade_MDEV-23102-1.result | 51 +++++++++++++++++++- mysql-test/main/upgrade_MDEV-23102-1.test | 52 ++++++++++++++++++++- mysql-test/main/upgrade_MDEV-23102-2.result | 51 +++++++++++++++++++- mysql-test/main/upgrade_MDEV-23102-2.test | 52 ++++++++++++++++++++- scripts/mysql_system_tables_fix.sql | 2 +- 5 files changed, 201 insertions(+), 7 deletions(-) diff --git a/mysql-test/main/upgrade_MDEV-23102-1.result b/mysql-test/main/upgrade_MDEV-23102-1.result index 78993550901..8caa49180ee 100644 --- a/mysql-test/main/upgrade_MDEV-23102-1.result +++ b/mysql-test/main/upgrade_MDEV-23102-1.result @@ -16,7 +16,56 @@ use mysql; # make changed definition of gis procedures and user view create user superuser@localhost; grant all privileges on mysql.* to superuser@localhost; -create or replace definer=superuser@localhost sql security definer view user as select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,if(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.password_last_changed'),1) = 0,'Y','N') AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv`;; +drop view user; +CREATE DEFINER='superuser'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS user AS SELECT +Host, +User, +IF(JSON_VALUE(Priv, '$.plugin') IN ('mysql_native_password', 'mysql_old_password'), IFNULL(JSON_VALUE(Priv, '$.authentication_string'), ''), '') AS Password, +IF(JSON_VALUE(Priv, '$.access') & 1, 'Y', 'N') AS Select_priv, +IF(JSON_VALUE(Priv, '$.access') & 2, 'Y', 'N') AS Insert_priv, +IF(JSON_VALUE(Priv, '$.access') & 4, 'Y', 'N') AS Update_priv, +IF(JSON_VALUE(Priv, '$.access') & 8, 'Y', 'N') AS Delete_priv, +IF(JSON_VALUE(Priv, '$.access') & 16, 'Y', 'N') AS Create_priv, +IF(JSON_VALUE(Priv, '$.access') & 32, 'Y', 'N') AS Drop_priv, +IF(JSON_VALUE(Priv, '$.access') & 64, 'Y', 'N') AS Reload_priv, +IF(JSON_VALUE(Priv, '$.access') & 128, 'Y', 'N') AS Shutdown_priv, +IF(JSON_VALUE(Priv, '$.access') & 256, 'Y', 'N') AS Process_priv, +IF(JSON_VALUE(Priv, '$.access') & 512, 'Y', 'N') AS File_priv, +IF(JSON_VALUE(Priv, '$.access') & 1024, 'Y', 'N') AS Grant_priv, +IF(JSON_VALUE(Priv, '$.access') & 2048, 'Y', 'N') AS References_priv, +IF(JSON_VALUE(Priv, '$.access') & 4096, 'Y', 'N') AS Index_priv, +IF(JSON_VALUE(Priv, '$.access') & 8192, 'Y', 'N') AS Alter_priv, +IF(JSON_VALUE(Priv, '$.access') & 16384, 'Y', 'N') AS Show_db_priv, +IF(JSON_VALUE(Priv, '$.access') & 32768, 'Y', 'N') AS Super_priv, +IF(JSON_VALUE(Priv, '$.access') & 65536, 'Y', 'N') AS Create_tmp_table_priv, +IF(JSON_VALUE(Priv, '$.access') & 131072, 'Y', 'N') AS Lock_tables_priv, +IF(JSON_VALUE(Priv, '$.access') & 262144, 'Y', 'N') AS Execute_priv, +IF(JSON_VALUE(Priv, '$.access') & 524288, 'Y', 'N') AS Repl_slave_priv, +IF(JSON_VALUE(Priv, '$.access') & 1048576, 'Y', 'N') AS Repl_client_priv, +IF(JSON_VALUE(Priv, '$.access') & 2097152, 'Y', 'N') AS Create_view_priv, +IF(JSON_VALUE(Priv, '$.access') & 4194304, 'Y', 'N') AS Show_view_priv, +IF(JSON_VALUE(Priv, '$.access') & 8388608, 'Y', 'N') AS Create_routine_priv, +IF(JSON_VALUE(Priv, '$.access') & 16777216, 'Y', 'N') AS Alter_routine_priv, +IF(JSON_VALUE(Priv, '$.access') & 33554432, 'Y', 'N') AS Create_user_priv, +IF(JSON_VALUE(Priv, '$.access') & 67108864, 'Y', 'N') AS Event_priv, +IF(JSON_VALUE(Priv, '$.access') & 134217728, 'Y', 'N') AS Trigger_priv, +IF(JSON_VALUE(Priv, '$.access') & 268435456, 'Y', 'N') AS Create_tablespace_priv, +IF(JSON_VALUE(Priv, '$.access') & 536870912, 'Y', 'N') AS Delete_history_priv, +ELT(IFNULL(JSON_VALUE(Priv, '$.ssl_type'), 0) + 1, '', 'ANY','X509', 'SPECIFIED') AS ssl_type, +IFNULL(JSON_VALUE(Priv, '$.ssl_cipher'), '') AS ssl_cipher, +IFNULL(JSON_VALUE(Priv, '$.x509_issuer'), '') AS x509_issuer, +IFNULL(JSON_VALUE(Priv, '$.x509_subject'), '') AS x509_subject, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_questions'), 0) AS UNSIGNED) AS max_questions, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_updates'), 0) AS UNSIGNED) AS max_updates, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_connections'), 0) AS UNSIGNED) AS max_connections, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, +IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, +IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, +'N' AS password_expired, +ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, +IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time +FROM global_priv; SET sql_mode=''; DROP PROCEDURE IF EXISTS mysql.AddGeometryColumn; DROP PROCEDURE IF EXISTS mysql.DropGeometryColumn; diff --git a/mysql-test/main/upgrade_MDEV-23102-1.test b/mysql-test/main/upgrade_MDEV-23102-1.test index d764a6ca84a..172e0d595b2 100644 --- a/mysql-test/main/upgrade_MDEV-23102-1.test +++ b/mysql-test/main/upgrade_MDEV-23102-1.test @@ -23,9 +23,57 @@ use mysql; create user superuser@localhost; grant all privileges on mysql.* to superuser@localhost; -let $viewdef = `select view_definition from information_schema.views where table_name='user' and table_schema='mysql'`; +drop view user; ---eval create or replace definer=superuser@localhost sql security definer view user as $viewdef; +CREATE DEFINER='superuser'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS user AS SELECT + Host, + User, + IF(JSON_VALUE(Priv, '$.plugin') IN ('mysql_native_password', 'mysql_old_password'), IFNULL(JSON_VALUE(Priv, '$.authentication_string'), ''), '') AS Password, + IF(JSON_VALUE(Priv, '$.access') & 1, 'Y', 'N') AS Select_priv, + IF(JSON_VALUE(Priv, '$.access') & 2, 'Y', 'N') AS Insert_priv, + IF(JSON_VALUE(Priv, '$.access') & 4, 'Y', 'N') AS Update_priv, + IF(JSON_VALUE(Priv, '$.access') & 8, 'Y', 'N') AS Delete_priv, + IF(JSON_VALUE(Priv, '$.access') & 16, 'Y', 'N') AS Create_priv, + IF(JSON_VALUE(Priv, '$.access') & 32, 'Y', 'N') AS Drop_priv, + IF(JSON_VALUE(Priv, '$.access') & 64, 'Y', 'N') AS Reload_priv, + IF(JSON_VALUE(Priv, '$.access') & 128, 'Y', 'N') AS Shutdown_priv, + IF(JSON_VALUE(Priv, '$.access') & 256, 'Y', 'N') AS Process_priv, + IF(JSON_VALUE(Priv, '$.access') & 512, 'Y', 'N') AS File_priv, + IF(JSON_VALUE(Priv, '$.access') & 1024, 'Y', 'N') AS Grant_priv, + IF(JSON_VALUE(Priv, '$.access') & 2048, 'Y', 'N') AS References_priv, + IF(JSON_VALUE(Priv, '$.access') & 4096, 'Y', 'N') AS Index_priv, + IF(JSON_VALUE(Priv, '$.access') & 8192, 'Y', 'N') AS Alter_priv, + IF(JSON_VALUE(Priv, '$.access') & 16384, 'Y', 'N') AS Show_db_priv, + IF(JSON_VALUE(Priv, '$.access') & 32768, 'Y', 'N') AS Super_priv, + IF(JSON_VALUE(Priv, '$.access') & 65536, 'Y', 'N') AS Create_tmp_table_priv, + IF(JSON_VALUE(Priv, '$.access') & 131072, 'Y', 'N') AS Lock_tables_priv, + IF(JSON_VALUE(Priv, '$.access') & 262144, 'Y', 'N') AS Execute_priv, + IF(JSON_VALUE(Priv, '$.access') & 524288, 'Y', 'N') AS Repl_slave_priv, + IF(JSON_VALUE(Priv, '$.access') & 1048576, 'Y', 'N') AS Repl_client_priv, + IF(JSON_VALUE(Priv, '$.access') & 2097152, 'Y', 'N') AS Create_view_priv, + IF(JSON_VALUE(Priv, '$.access') & 4194304, 'Y', 'N') AS Show_view_priv, + IF(JSON_VALUE(Priv, '$.access') & 8388608, 'Y', 'N') AS Create_routine_priv, + IF(JSON_VALUE(Priv, '$.access') & 16777216, 'Y', 'N') AS Alter_routine_priv, + IF(JSON_VALUE(Priv, '$.access') & 33554432, 'Y', 'N') AS Create_user_priv, + IF(JSON_VALUE(Priv, '$.access') & 67108864, 'Y', 'N') AS Event_priv, + IF(JSON_VALUE(Priv, '$.access') & 134217728, 'Y', 'N') AS Trigger_priv, + IF(JSON_VALUE(Priv, '$.access') & 268435456, 'Y', 'N') AS Create_tablespace_priv, + IF(JSON_VALUE(Priv, '$.access') & 536870912, 'Y', 'N') AS Delete_history_priv, + ELT(IFNULL(JSON_VALUE(Priv, '$.ssl_type'), 0) + 1, '', 'ANY','X509', 'SPECIFIED') AS ssl_type, + IFNULL(JSON_VALUE(Priv, '$.ssl_cipher'), '') AS ssl_cipher, + IFNULL(JSON_VALUE(Priv, '$.x509_issuer'), '') AS x509_issuer, + IFNULL(JSON_VALUE(Priv, '$.x509_subject'), '') AS x509_subject, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_questions'), 0) AS UNSIGNED) AS max_questions, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_updates'), 0) AS UNSIGNED) AS max_updates, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_connections'), 0) AS UNSIGNED) AS max_connections, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, + IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, + IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, + 'N' AS password_expired, + ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, + IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time + FROM global_priv; SET sql_mode=''; diff --git a/mysql-test/main/upgrade_MDEV-23102-2.result b/mysql-test/main/upgrade_MDEV-23102-2.result index c7f373dd69d..4702fae812f 100644 --- a/mysql-test/main/upgrade_MDEV-23102-2.result +++ b/mysql-test/main/upgrade_MDEV-23102-2.result @@ -16,7 +16,56 @@ use mysql; # make changed definition of gis procedures and user view create user superuser@localhost; grant all privileges on mysql.* to superuser@localhost; -create or replace definer=superuser@localhost sql security definer view user as select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,if(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.password_last_changed'),1) = 0,'Y','N') AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv`;; +drop view user; +CREATE DEFINER='superuser'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS user AS SELECT +Host, +User, +IF(JSON_VALUE(Priv, '$.plugin') IN ('mysql_native_password', 'mysql_old_password'), IFNULL(JSON_VALUE(Priv, '$.authentication_string'), ''), '') AS Password, +IF(JSON_VALUE(Priv, '$.access') & 1, 'Y', 'N') AS Select_priv, +IF(JSON_VALUE(Priv, '$.access') & 2, 'Y', 'N') AS Insert_priv, +IF(JSON_VALUE(Priv, '$.access') & 4, 'Y', 'N') AS Update_priv, +IF(JSON_VALUE(Priv, '$.access') & 8, 'Y', 'N') AS Delete_priv, +IF(JSON_VALUE(Priv, '$.access') & 16, 'Y', 'N') AS Create_priv, +IF(JSON_VALUE(Priv, '$.access') & 32, 'Y', 'N') AS Drop_priv, +IF(JSON_VALUE(Priv, '$.access') & 64, 'Y', 'N') AS Reload_priv, +IF(JSON_VALUE(Priv, '$.access') & 128, 'Y', 'N') AS Shutdown_priv, +IF(JSON_VALUE(Priv, '$.access') & 256, 'Y', 'N') AS Process_priv, +IF(JSON_VALUE(Priv, '$.access') & 512, 'Y', 'N') AS File_priv, +IF(JSON_VALUE(Priv, '$.access') & 1024, 'Y', 'N') AS Grant_priv, +IF(JSON_VALUE(Priv, '$.access') & 2048, 'Y', 'N') AS References_priv, +IF(JSON_VALUE(Priv, '$.access') & 4096, 'Y', 'N') AS Index_priv, +IF(JSON_VALUE(Priv, '$.access') & 8192, 'Y', 'N') AS Alter_priv, +IF(JSON_VALUE(Priv, '$.access') & 16384, 'Y', 'N') AS Show_db_priv, +IF(JSON_VALUE(Priv, '$.access') & 32768, 'Y', 'N') AS Super_priv, +IF(JSON_VALUE(Priv, '$.access') & 65536, 'Y', 'N') AS Create_tmp_table_priv, +IF(JSON_VALUE(Priv, '$.access') & 131072, 'Y', 'N') AS Lock_tables_priv, +IF(JSON_VALUE(Priv, '$.access') & 262144, 'Y', 'N') AS Execute_priv, +IF(JSON_VALUE(Priv, '$.access') & 524288, 'Y', 'N') AS Repl_slave_priv, +IF(JSON_VALUE(Priv, '$.access') & 1048576, 'Y', 'N') AS Repl_client_priv, +IF(JSON_VALUE(Priv, '$.access') & 2097152, 'Y', 'N') AS Create_view_priv, +IF(JSON_VALUE(Priv, '$.access') & 4194304, 'Y', 'N') AS Show_view_priv, +IF(JSON_VALUE(Priv, '$.access') & 8388608, 'Y', 'N') AS Create_routine_priv, +IF(JSON_VALUE(Priv, '$.access') & 16777216, 'Y', 'N') AS Alter_routine_priv, +IF(JSON_VALUE(Priv, '$.access') & 33554432, 'Y', 'N') AS Create_user_priv, +IF(JSON_VALUE(Priv, '$.access') & 67108864, 'Y', 'N') AS Event_priv, +IF(JSON_VALUE(Priv, '$.access') & 134217728, 'Y', 'N') AS Trigger_priv, +IF(JSON_VALUE(Priv, '$.access') & 268435456, 'Y', 'N') AS Create_tablespace_priv, +IF(JSON_VALUE(Priv, '$.access') & 536870912, 'Y', 'N') AS Delete_history_priv, +ELT(IFNULL(JSON_VALUE(Priv, '$.ssl_type'), 0) + 1, '', 'ANY','X509', 'SPECIFIED') AS ssl_type, +IFNULL(JSON_VALUE(Priv, '$.ssl_cipher'), '') AS ssl_cipher, +IFNULL(JSON_VALUE(Priv, '$.x509_issuer'), '') AS x509_issuer, +IFNULL(JSON_VALUE(Priv, '$.x509_subject'), '') AS x509_subject, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_questions'), 0) AS UNSIGNED) AS max_questions, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_updates'), 0) AS UNSIGNED) AS max_updates, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_connections'), 0) AS UNSIGNED) AS max_connections, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, +IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, +IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, +'N' AS password_expired, +ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, +IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time +FROM global_priv; DROP PROCEDURE IF EXISTS mysql.AddGeometryColumn; DROP PROCEDURE IF EXISTS mysql.DropGeometryColumn; drop user 'mariadb.sys'@'localhost'; diff --git a/mysql-test/main/upgrade_MDEV-23102-2.test b/mysql-test/main/upgrade_MDEV-23102-2.test index 27ee75ea58c..f2d7ac578e0 100644 --- a/mysql-test/main/upgrade_MDEV-23102-2.test +++ b/mysql-test/main/upgrade_MDEV-23102-2.test @@ -23,9 +23,57 @@ use mysql; create user superuser@localhost; grant all privileges on mysql.* to superuser@localhost; -let $viewdef = `select view_definition from information_schema.views where table_name='user' and table_schema='mysql'`; +drop view user; ---eval create or replace definer=superuser@localhost sql security definer view user as $viewdef; +CREATE DEFINER='superuser'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS user AS SELECT + Host, + User, + IF(JSON_VALUE(Priv, '$.plugin') IN ('mysql_native_password', 'mysql_old_password'), IFNULL(JSON_VALUE(Priv, '$.authentication_string'), ''), '') AS Password, + IF(JSON_VALUE(Priv, '$.access') & 1, 'Y', 'N') AS Select_priv, + IF(JSON_VALUE(Priv, '$.access') & 2, 'Y', 'N') AS Insert_priv, + IF(JSON_VALUE(Priv, '$.access') & 4, 'Y', 'N') AS Update_priv, + IF(JSON_VALUE(Priv, '$.access') & 8, 'Y', 'N') AS Delete_priv, + IF(JSON_VALUE(Priv, '$.access') & 16, 'Y', 'N') AS Create_priv, + IF(JSON_VALUE(Priv, '$.access') & 32, 'Y', 'N') AS Drop_priv, + IF(JSON_VALUE(Priv, '$.access') & 64, 'Y', 'N') AS Reload_priv, + IF(JSON_VALUE(Priv, '$.access') & 128, 'Y', 'N') AS Shutdown_priv, + IF(JSON_VALUE(Priv, '$.access') & 256, 'Y', 'N') AS Process_priv, + IF(JSON_VALUE(Priv, '$.access') & 512, 'Y', 'N') AS File_priv, + IF(JSON_VALUE(Priv, '$.access') & 1024, 'Y', 'N') AS Grant_priv, + IF(JSON_VALUE(Priv, '$.access') & 2048, 'Y', 'N') AS References_priv, + IF(JSON_VALUE(Priv, '$.access') & 4096, 'Y', 'N') AS Index_priv, + IF(JSON_VALUE(Priv, '$.access') & 8192, 'Y', 'N') AS Alter_priv, + IF(JSON_VALUE(Priv, '$.access') & 16384, 'Y', 'N') AS Show_db_priv, + IF(JSON_VALUE(Priv, '$.access') & 32768, 'Y', 'N') AS Super_priv, + IF(JSON_VALUE(Priv, '$.access') & 65536, 'Y', 'N') AS Create_tmp_table_priv, + IF(JSON_VALUE(Priv, '$.access') & 131072, 'Y', 'N') AS Lock_tables_priv, + IF(JSON_VALUE(Priv, '$.access') & 262144, 'Y', 'N') AS Execute_priv, + IF(JSON_VALUE(Priv, '$.access') & 524288, 'Y', 'N') AS Repl_slave_priv, + IF(JSON_VALUE(Priv, '$.access') & 1048576, 'Y', 'N') AS Repl_client_priv, + IF(JSON_VALUE(Priv, '$.access') & 2097152, 'Y', 'N') AS Create_view_priv, + IF(JSON_VALUE(Priv, '$.access') & 4194304, 'Y', 'N') AS Show_view_priv, + IF(JSON_VALUE(Priv, '$.access') & 8388608, 'Y', 'N') AS Create_routine_priv, + IF(JSON_VALUE(Priv, '$.access') & 16777216, 'Y', 'N') AS Alter_routine_priv, + IF(JSON_VALUE(Priv, '$.access') & 33554432, 'Y', 'N') AS Create_user_priv, + IF(JSON_VALUE(Priv, '$.access') & 67108864, 'Y', 'N') AS Event_priv, + IF(JSON_VALUE(Priv, '$.access') & 134217728, 'Y', 'N') AS Trigger_priv, + IF(JSON_VALUE(Priv, '$.access') & 268435456, 'Y', 'N') AS Create_tablespace_priv, + IF(JSON_VALUE(Priv, '$.access') & 536870912, 'Y', 'N') AS Delete_history_priv, + ELT(IFNULL(JSON_VALUE(Priv, '$.ssl_type'), 0) + 1, '', 'ANY','X509', 'SPECIFIED') AS ssl_type, + IFNULL(JSON_VALUE(Priv, '$.ssl_cipher'), '') AS ssl_cipher, + IFNULL(JSON_VALUE(Priv, '$.x509_issuer'), '') AS x509_issuer, + IFNULL(JSON_VALUE(Priv, '$.x509_subject'), '') AS x509_subject, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_questions'), 0) AS UNSIGNED) AS max_questions, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_updates'), 0) AS UNSIGNED) AS max_updates, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_connections'), 0) AS UNSIGNED) AS max_connections, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, + IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, + IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, + 'N' AS password_expired, + ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, + IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time + FROM global_priv; DROP PROCEDURE IF EXISTS mysql.AddGeometryColumn; DROP PROCEDURE IF EXISTS mysql.DropGeometryColumn; diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index ac71edccae9..9dd775aaf30 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -824,7 +824,7 @@ IF 'BASE TABLE' = (select table_type from information_schema.tables where table_ DROP TABLE user; END IF// -IF 1 = (SELECT count(*) FROM information_schema.VIEWS WHERE TABLE_CATALOG = 'def' and TABLE_SCHEMA = 'mysql' and TABLE_NAME='user' and (DEFINER = 'root@localhost' or VIEW_DEFINITION LIKE "%'N' AS `password_expired`%")) THEN +IF 1 = (SELECT count(*) FROM information_schema.VIEWS WHERE TABLE_CATALOG = 'def' and TABLE_SCHEMA = 'mysql' and TABLE_NAME='user' and (DEFINER = 'root@localhost' or (DEFINER = 'mariadb.sys@localhost' and VIEW_DEFINITION LIKE "%'N' AS `password_expired`%"))) THEN DROP VIEW IF EXISTS mysql.user; END IF//