summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2020-02-12 18:26:18 +0400
committerAlexander Barkov <bar@mariadb.com>2020-02-28 15:58:31 +0400
commite26056e181e92332eb622ae096f7faa4e333b4f3 (patch)
treef6dda57f6c071ddcca953c8d664eee7a1ad69260
parent0c35e80dc9ff24bcb8e710cb8cb16428c8c9986f (diff)
downloadmariadb-git-e26056e181e92332eb622ae096f7faa4e333b4f3.tar.gz
MDEV-21704 Add a new JSON field "version_id" into mysql.global_priv.priv
-rw-r--r--mysql-test/main/system_mysql_db_error_log-master.opt1
-rw-r--r--mysql-test/main/system_mysql_db_error_log.result111
-rw-r--r--mysql-test/main/system_mysql_db_error_log.test109
-rw-r--r--mysql-test/suite/funcs_1/r/is_user_privileges.result33
-rw-r--r--mysql-test/suite/funcs_1/t/is_user_privileges.test26
-rw-r--r--mysql-test/suite/plugins/r/multiauth.result1
-rw-r--r--mysql-test/suite/plugins/t/multiauth.test6
-rw-r--r--sql/privilege.h13
-rw-r--r--sql/sql_acl.cc63
9 files changed, 340 insertions, 23 deletions
diff --git a/mysql-test/main/system_mysql_db_error_log-master.opt b/mysql-test/main/system_mysql_db_error_log-master.opt
new file mode 100644
index 00000000000..37a865d29e0
--- /dev/null
+++ b/mysql-test/main/system_mysql_db_error_log-master.opt
@@ -0,0 +1 @@
+--log-error=$MYSQLTEST_VARDIR/tmp/system_mysql_db_error_log.err
diff --git a/mysql-test/main/system_mysql_db_error_log.result b/mysql-test/main/system_mysql_db_error_log.result
new file mode 100644
index 00000000000..dc0a75b6f91
--- /dev/null
+++ b/mysql-test/main/system_mysql_db_error_log.result
@@ -0,0 +1,111 @@
+#
+# MDEV-21704 Add a new JSON field "version_id" into mysql.global_priv.priv
+#
+SET @super_acl_100500= 1 << 15;
+SELECT HEX(@super_acl_100500);
+HEX(@super_acl_100500)
+8000
+SET @all_known_privileges_100500= (1 << 30) - 1;
+SELECT HEX(@all_known_privileges_100500);
+HEX(@all_known_privileges_100500)
+3FFFFFFF
+SET @all_known_privileges_current= (1 << 30) - 1;
+SELECT HEX(@all_known_privileges_current);
+HEX(@all_known_privileges_current)
+3FFFFFFF
+CREATE USER bad_access1@localhost;
+UPDATE
+mysql.global_priv
+SET
+Priv=json_set(Priv, '$.access',@all_known_privileges_current+1)
+WHERE
+host='localhost' and user='bad_access1';
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR bad_access1@localhost;
+Grants for bad_access1@localhost
+GRANT USAGE ON *.* TO `bad_access1`@`localhost`
+DROP USER bad_access1@localhost;
+CREATE USER bad_version_id_1000000@localhost;
+GRANT ALL PRIVILEGES ON *.* to bad_version_id_1000000@localhost;
+SHOW GRANTS FOR bad_version_id_1000000@localhost;
+Grants for bad_version_id_1000000@localhost
+GRANT ALL PRIVILEGES ON *.* TO `bad_version_id_1000000`@`localhost`
+UPDATE
+mysql.global_priv
+SET
+Priv=json_set(Priv, '$.version_id',1000000)
+WHERE
+host='localhost' and user='bad_version_id_1000000';
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR bad_version_id_1000000@localhost;
+Grants for bad_version_id_1000000@localhost
+GRANT USAGE ON *.* TO `bad_version_id_1000000`@`localhost`
+DROP USER bad_version_id_1000000@localhost;
+CREATE USER bad_version_id_minus_3@localhost;
+GRANT ALL PRIVILEGES ON *.* to bad_version_id_minus_3@localhost;
+SHOW GRANTS FOR bad_version_id_minus_3@localhost;
+Grants for bad_version_id_minus_3@localhost
+GRANT ALL PRIVILEGES ON *.* TO `bad_version_id_minus_3`@`localhost`
+UPDATE
+mysql.global_priv
+SET
+Priv=json_set(Priv, '$.version_id',-3)
+WHERE
+host='localhost' and user='bad_version_id_minus_3';
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR bad_version_id_minus_3@localhost;
+Grants for bad_version_id_minus_3@localhost
+GRANT USAGE ON *.* TO `bad_version_id_minus_3`@`localhost`
+DROP USER bad_version_id_minus_3@localhost;
+CREATE USER bad_version_id_100300@localhost;
+GRANT ALL PRIVILEGES ON *.* to bad_version_id_100300@localhost;
+SHOW GRANTS FOR bad_version_id_100300@localhost;
+Grants for bad_version_id_100300@localhost
+GRANT ALL PRIVILEGES ON *.* TO `bad_version_id_100300`@`localhost`
+UPDATE
+mysql.global_priv
+SET
+Priv=json_set(Priv, '$.version_id',100300)
+WHERE
+host='localhost' and user='bad_version_id_100300';
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR bad_version_id_100300@localhost;
+Grants for bad_version_id_100300@localhost
+GRANT USAGE ON *.* TO `bad_version_id_100300`@`localhost`
+DROP USER bad_version_id_100300@localhost;
+CREATE USER good_version_id_100400@localhost;
+GRANT ALL PRIVILEGES ON *.* to good_version_id_100400@localhost;
+SHOW GRANTS FOR good_version_id_100400@localhost;
+Grants for good_version_id_100400@localhost
+GRANT ALL PRIVILEGES ON *.* TO `good_version_id_100400`@`localhost`
+UPDATE
+mysql.global_priv
+SET
+Priv=json_set(Priv, '$.version_id',100400, '$.access', @all_known_privileges_100500)
+WHERE
+host='localhost' and user='good_version_id_100400';
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR good_version_id_100400@localhost;
+Grants for good_version_id_100400@localhost
+GRANT ALL PRIVILEGES ON *.* TO `good_version_id_100400`@`localhost` WITH GRANT OPTION
+DROP USER good_version_id_100400@localhost;
+CREATE USER good_version_id_100500@localhost;
+GRANT SUPER ON *.* to good_version_id_100500@localhost;
+SHOW GRANTS FOR good_version_id_100500@localhost;
+Grants for good_version_id_100500@localhost
+GRANT SUPER ON *.* TO `good_version_id_100500`@`localhost`
+UPDATE
+mysql.global_priv
+SET
+Priv=json_set(Priv, '$.version_id',100500)
+WHERE
+host='localhost' and user='good_version_id_100500';
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR good_version_id_100500@localhost;
+Grants for good_version_id_100500@localhost
+GRANT SUPER ON *.* TO `good_version_id_100500`@`localhost`
+DROP USER good_version_id_100500@localhost;
+FOUND 1 /Warning.*'user' entry 'bad_access1@localhost' has a wrong 'access' value.*version_id=/ in system_mysql_db_error_log.err
+FOUND 1 /Warning.*'user' entry 'bad_version_id_1000000@localhost' has a wrong 'version_id' value 1000000/ in system_mysql_db_error_log.err
+FOUND 1 /Warning.*'user' entry 'bad_version_id_minus_3@localhost' has a wrong 'version_id' value -3/ in system_mysql_db_error_log.err
+FOUND 1 /Warning.*'user' entry 'bad_version_id_100300@localhost' has a wrong 'version_id' value 100300/ in system_mysql_db_error_log.err
diff --git a/mysql-test/main/system_mysql_db_error_log.test b/mysql-test/main/system_mysql_db_error_log.test
new file mode 100644
index 00000000000..6ec75e0d5e2
--- /dev/null
+++ b/mysql-test/main/system_mysql_db_error_log.test
@@ -0,0 +1,109 @@
+--source include/not_embedded.inc
+
+--echo #
+--echo # MDEV-21704 Add a new JSON field "version_id" into mysql.global_priv.priv
+--echo #
+
+SET @super_acl_100500= 1 << 15;
+SELECT HEX(@super_acl_100500);
+
+SET @all_known_privileges_100500= (1 << 30) - 1;
+SELECT HEX(@all_known_privileges_100500);
+
+SET @all_known_privileges_current= (1 << 30) - 1;
+SELECT HEX(@all_known_privileges_current);
+
+CREATE USER bad_access1@localhost;
+UPDATE
+ mysql.global_priv
+SET
+ Priv=json_set(Priv, '$.access',@all_known_privileges_current+1)
+WHERE
+ host='localhost' and user='bad_access1';
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR bad_access1@localhost;
+DROP USER bad_access1@localhost;
+
+
+CREATE USER bad_version_id_1000000@localhost;
+GRANT ALL PRIVILEGES ON *.* to bad_version_id_1000000@localhost;
+SHOW GRANTS FOR bad_version_id_1000000@localhost;
+UPDATE
+ mysql.global_priv
+SET
+ Priv=json_set(Priv, '$.version_id',1000000)
+WHERE
+ host='localhost' and user='bad_version_id_1000000';
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR bad_version_id_1000000@localhost;
+DROP USER bad_version_id_1000000@localhost;
+
+
+CREATE USER bad_version_id_minus_3@localhost;
+GRANT ALL PRIVILEGES ON *.* to bad_version_id_minus_3@localhost;
+SHOW GRANTS FOR bad_version_id_minus_3@localhost;
+UPDATE
+ mysql.global_priv
+SET
+ Priv=json_set(Priv, '$.version_id',-3)
+WHERE
+ host='localhost' and user='bad_version_id_minus_3';
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR bad_version_id_minus_3@localhost;
+DROP USER bad_version_id_minus_3@localhost;
+
+CREATE USER bad_version_id_100300@localhost;
+GRANT ALL PRIVILEGES ON *.* to bad_version_id_100300@localhost;
+SHOW GRANTS FOR bad_version_id_100300@localhost;
+UPDATE
+ mysql.global_priv
+SET
+ Priv=json_set(Priv, '$.version_id',100300)
+WHERE
+ host='localhost' and user='bad_version_id_100300';
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR bad_version_id_100300@localhost;
+DROP USER bad_version_id_100300@localhost;
+
+
+CREATE USER good_version_id_100400@localhost;
+GRANT ALL PRIVILEGES ON *.* to good_version_id_100400@localhost;
+SHOW GRANTS FOR good_version_id_100400@localhost;
+UPDATE
+ mysql.global_priv
+SET
+ Priv=json_set(Priv, '$.version_id',100400, '$.access', @all_known_privileges_100500)
+WHERE
+ host='localhost' and user='good_version_id_100400';
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR good_version_id_100400@localhost;
+DROP USER good_version_id_100400@localhost;
+
+
+CREATE USER good_version_id_100500@localhost;
+GRANT SUPER ON *.* to good_version_id_100500@localhost;
+SHOW GRANTS FOR good_version_id_100500@localhost;
+UPDATE
+ mysql.global_priv
+SET
+ Priv=json_set(Priv, '$.version_id',100500)
+WHERE
+ host='localhost' and user='good_version_id_100500';
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR good_version_id_100500@localhost;
+DROP USER good_version_id_100500@localhost;
+
+
+--let SEARCH_FILE=$MYSQLTEST_VARDIR/tmp/system_mysql_db_error_log.err
+
+--let SEARCH_PATTERN= Warning.*'user' entry 'bad_access1@localhost' has a wrong 'access' value.*version_id=
+--source include/search_pattern_in_file.inc
+
+--let SEARCH_PATTERN= Warning.*'user' entry 'bad_version_id_1000000@localhost' has a wrong 'version_id' value 1000000
+--source include/search_pattern_in_file.inc
+
+--let SEARCH_PATTERN= Warning.*'user' entry 'bad_version_id_minus_3@localhost' has a wrong 'version_id' value -3
+--source include/search_pattern_in_file.inc
+
+--let SEARCH_PATTERN= Warning.*'user' entry 'bad_version_id_100300@localhost' has a wrong 'version_id' value 100300
+--source include/search_pattern_in_file.inc
diff --git a/mysql-test/suite/funcs_1/r/is_user_privileges.result b/mysql-test/suite/funcs_1/r/is_user_privileges.result
index f7a83dd3ddb..27bb2b3de83 100644
--- a/mysql-test/suite/funcs_1/r/is_user_privileges.result
+++ b/mysql-test/suite/funcs_1/r/is_user_privileges.result
@@ -90,6 +90,7 @@ host localhost
user testuser1
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -98,6 +99,7 @@ host localhost
user testuser2
json_detailed(priv) {
"access": 6,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -106,6 +108,7 @@ host localhost
user testuser3
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -138,6 +141,7 @@ host localhost
user testuser1
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -146,6 +150,7 @@ host localhost
user testuser2
json_detailed(priv) {
"access": 6,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -154,6 +159,7 @@ host localhost
user testuser3
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -172,6 +178,7 @@ host localhost
user testuser1
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -180,6 +187,7 @@ host localhost
user testuser2
json_detailed(priv) {
"access": 6,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -188,6 +196,7 @@ host localhost
user testuser3
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -228,6 +237,7 @@ host localhost
user testuser1
json_detailed(priv) {
"access": 1,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -236,6 +246,7 @@ host localhost
user testuser2
json_detailed(priv) {
"access": 6,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -244,6 +255,7 @@ host localhost
user testuser3
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -276,6 +288,7 @@ host localhost
user testuser1
json_detailed(priv) {
"access": 1025,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -284,6 +297,7 @@ host localhost
user testuser2
json_detailed(priv) {
"access": 6,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -292,6 +306,7 @@ host localhost
user testuser3
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -310,6 +325,7 @@ host localhost
user testuser1
json_detailed(priv) {
"access": 1025,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -318,6 +334,7 @@ host localhost
user testuser2
json_detailed(priv) {
"access": 6,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -326,6 +343,7 @@ host localhost
user testuser3
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -396,6 +414,7 @@ host localhost
user testuser1
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -404,6 +423,7 @@ host localhost
user testuser2
json_detailed(priv) {
"access": 6,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -412,6 +432,7 @@ host localhost
user testuser3
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -477,6 +498,7 @@ host localhost
user testuser1
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -485,6 +507,7 @@ host localhost
user testuser2
json_detailed(priv) {
"access": 6,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -493,6 +516,7 @@ host localhost
user testuser3
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -511,6 +535,7 @@ host localhost
user testuser1
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -519,6 +544,7 @@ host localhost
user testuser2
json_detailed(priv) {
"access": 6,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -527,6 +553,7 @@ host localhost
user testuser3
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -552,6 +579,7 @@ host localhost
user testuser1
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -560,6 +588,7 @@ host localhost
user testuser2
json_detailed(priv) {
"access": 6,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -568,6 +597,7 @@ host localhost
user testuser3
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -608,6 +638,7 @@ host localhost
user testuser1
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -616,6 +647,7 @@ host localhost
user testuser2
json_detailed(priv) {
"access": 6,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
@@ -624,6 +656,7 @@ host localhost
user testuser3
json_detailed(priv) {
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "",
"password_last_changed": #
diff --git a/mysql-test/suite/funcs_1/t/is_user_privileges.test b/mysql-test/suite/funcs_1/t/is_user_privileges.test
index 4293c4e16fb..3af56ad2533 100644
--- a/mysql-test/suite/funcs_1/t/is_user_privileges.test
+++ b/mysql-test/suite/funcs_1/t/is_user_privileges.test
@@ -25,6 +25,10 @@ let $other_engine_type = MyISAM;
let $is_table = USER_PRIVILEGES;
+let $REGEX_VERSION_ID=/$mysql_get_server_version/VERSION_ID/;
+let $REGEX_PASSWORD_LAST_CHANGED=/password_last_changed": [0-9]*/password_last_changed": #/;
+let $REGEX_GLOBAL_PRIV=$REGEX_PASSWORD_LAST_CHANGED $REGEX_VERSION_ID;
+
# The table INFORMATION_SCHEMA.USER_PRIVILEGES must exist
eval SHOW TABLES FROM information_schema LIKE '$is_table';
@@ -103,7 +107,7 @@ WHERE user LIKE 'testuser%' ORDER BY host, user;
let $my_show= SHOW GRANTS;
--vertical_results
eval $my_select1;
---replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
+--replace_regex $REGEX_GLOBAL_PRIV
eval $my_select2;
--horizontal_results
@@ -112,7 +116,7 @@ eval $my_select2;
GRANT UPDATE ON db_datadict.* TO 'testuser1'@'localhost' WITH GRANT OPTION;
--vertical_results
eval $my_select1;
---replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
+--replace_regex $REGEX_GLOBAL_PRIV
eval $my_select2;
--horizontal_results
@@ -120,7 +124,7 @@ eval $my_select2;
connect (testuser1, localhost, testuser1, , db_datadict);
--vertical_results
eval $my_select1;
---replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
+--replace_regex $REGEX_GLOBAL_PRIV
eval $my_select2;
--horizontal_results
eval $my_show;
@@ -134,7 +138,7 @@ GRANT SELECT ON *.* TO 'testuser1'@'localhost';
--echo # Here <SELECT NO> is shown correctly for testuser1;
--vertical_results
eval $my_select1;
---replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
+--replace_regex $REGEX_GLOBAL_PRIV
eval $my_select2;
--horizontal_results
@@ -143,7 +147,7 @@ GRANT SELECT ON *.* TO 'testuser1'@'localhost' WITH GRANT OPTION;
--echo # Here <SELECT YES> is shown correctly for testuser1;
--vertical_results
eval $my_select1;
---replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
+--replace_regex $REGEX_GLOBAL_PRIV
eval $my_select2;
--horizontal_results
@@ -151,7 +155,7 @@ eval $my_select2;
connection testuser1;
--vertical_results
eval $my_select1;
---replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
+--replace_regex $REGEX_GLOBAL_PRIV
eval $my_select2;
--horizontal_results
eval $my_show;
@@ -180,7 +184,7 @@ connection default;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'testuser1'@'localhost';
--vertical_results
eval $my_select1;
---replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
+--replace_regex $REGEX_GLOBAL_PRIV
eval $my_select2;
--horizontal_results
@@ -213,14 +217,14 @@ GRANT ALL ON db_datadict.* TO 'testuser1'@'localhost' WITH GRANT OPTION;
GRANT SELECT ON mysql.global_priv TO 'testuser1'@'localhost';
--vertical_results
eval $my_select1;
---replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
+--replace_regex $REGEX_GLOBAL_PRIV
eval $my_select2;
--horizontal_results
connection testuser1;
--vertical_results
eval $my_select1;
---replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
+--replace_regex $REGEX_GLOBAL_PRIV
eval $my_select2;
--horizontal_results
eval $my_show;
@@ -233,7 +237,7 @@ CREATE TABLE db_datadict.tb_56 ( c1 TEXT );
USE db_datadict;
--vertical_results
eval $my_select1;
---replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
+--replace_regex $REGEX_GLOBAL_PRIV
eval $my_select2;
--horizontal_results
eval $my_show;
@@ -248,7 +252,7 @@ connection default;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'testuser1'@'localhost';
--vertical_results
eval $my_select1;
---replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
+--replace_regex $REGEX_GLOBAL_PRIV
eval $my_select2;
--horizontal_results
diff --git a/mysql-test/suite/plugins/r/multiauth.result b/mysql-test/suite/plugins/r/multiauth.result
index 4b9a603867c..6ec30ac44d1 100644
--- a/mysql-test/suite/plugins/r/multiauth.result
+++ b/mysql-test/suite/plugins/r/multiauth.result
@@ -106,6 +106,7 @@ select json_detailed(priv) from mysql.global_priv where user='mysqltest1';
json_detailed(priv)
{
"access": 0,
+ "version_id": VERSION_ID,
"plugin": "mysql_native_password",
"authentication_string": "*7D8C3DF236D9163B6C274A9D47704BC496988460",
"auth_or":
diff --git a/mysql-test/suite/plugins/t/multiauth.test b/mysql-test/suite/plugins/t/multiauth.test
index ffd4851c20d..d6d3fc587cd 100644
--- a/mysql-test/suite/plugins/t/multiauth.test
+++ b/mysql-test/suite/plugins/t/multiauth.test
@@ -1,3 +1,7 @@
+let $REGEX_VERSION_ID=/$mysql_get_server_version/VERSION_ID/;
+let $REGEX_PASSWORD_LAST_CHANGED=/password_last_changed": [0-9]*/password_last_changed": #/;
+let $REGEX_GLOBAL_PRIV=$REGEX_PASSWORD_LAST_CHANGED $REGEX_VERSION_ID;
+
#
# MDEV-11340 Allow multiple alternative authentication methods for the same user
#
@@ -130,7 +134,7 @@ drop user mysqltest1;
#
create user mysqltest1 identified via ed25519 as password("good") OR unix_socket OR mysql_native_password as password("works");
show grants for mysqltest1;
---replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
+--replace_regex $REGEX_GLOBAL_PRIV
select json_detailed(priv) from mysql.global_priv where user='mysqltest1';
select password,plugin,authentication_string from mysql.user where user='mysqltest1';
flush privileges;
diff --git a/sql/privilege.h b/sql/privilege.h
index 6f12546796e..5dbc0b6dbdf 100644
--- a/sql/privilege.h
+++ b/sql/privilege.h
@@ -58,7 +58,7 @@ enum privilege_t: unsigned long long
EVENT_ACL = (1UL << 26),
TRIGGER_ACL = (1UL << 27),
CREATE_TABLESPACE_ACL = (1UL << 28),
- DELETE_HISTORY_ACL = (1UL << 29),
+ DELETE_HISTORY_ACL = (1UL << 29), // Added in 10.3.4
/*
don't forget to update
1. static struct show_privileges_st sys_privileges[]
@@ -66,12 +66,19 @@ enum privilege_t: unsigned long long
3. mysql_system_tables.sql and mysql_system_tables_fix.sql
4. acl_init() or whatever - to define behaviour for old privilege tables
5. sql_yacc.yy - for GRANT/REVOKE to work
- 6. ALL_KNOWN_ACL
+ 6. Add a new ALL_KNOWN_ACL_VERSION
+ 7. Change ALL_KNOWN_ACL to ALL_KNOWN_ACL_VERSION
+ 8. Update User_table_json::get_access()
*/
- ALL_KNOWN_ACL = (1UL << 30) - 1 // A combination of all defined bits
+
+ // A combination of all bits defined in 10.3.4 (and earlier)
+ ALL_KNOWN_ACL_100304 = (1UL << 30) - 1
};
+constexpr privilege_t ALL_KNOWN_ACL= ALL_KNOWN_ACL_100304;
+
+
// Unary operators
static inline constexpr ulonglong operator~(privilege_t access)
{
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 1af5d531cea..0a6e3cfb0d8 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1470,15 +1470,65 @@ class User_table_json: public User_table
set_str_value("authentication_string",
u.auth[i].auth_string.str, u.auth[i].auth_string.length);
}
+
+ void print_warning_bad_version_id(ulonglong version_id) const
+ {
+ sql_print_warning("'user' entry '%s@%s' has a wrong 'version_id' value %lld",
+ safe_str(get_user(current_thd->mem_root)),
+ safe_str(get_host(current_thd->mem_root)),
+ version_id);
+ }
+
+ void print_warning_bad_access(ulonglong version_id,
+ privilege_t mask,
+ ulonglong access) const
+ {
+ sql_print_warning("'user' entry '%s@%s' "
+ "has a wrong 'access' value 0x%llx "
+ "(allowed mask is 0x%llx, version_id=%lld)",
+ safe_str(get_user(current_thd->mem_root)),
+ safe_str(get_host(current_thd->mem_root)),
+ access, mask, version_id);
+ }
+
+ privilege_t adjust_access(ulonglong version_id, ulonglong access) const
+ {
+ privilege_t mask= ALL_KNOWN_ACL_100304;
+ if (access & ~mask)
+ {
+ print_warning_bad_access(version_id, mask, access);
+ return NO_ACL;
+ }
+ return access & mask;
+ }
+
privilege_t get_access() const
{
+ ulonglong version_id= (ulonglong) get_int_value("version_id");
+ ulonglong access= (ulonglong) get_int_value("access");
+
+ /*
+ Special case:
+ mysql_system_tables_data.sql populates "ALL PRIVILEGES"
+ for the super user this way:
+ {"access":18446744073709551615}
+ */
+ if (access == (ulonglong) ~0)
+ return GLOBAL_ACLS;
+
/*
- when new privileges will be added, we'll start storing GLOBAL_ACLS
- (or, for example, my_count_bits(GLOBAL_ACLS))
- in the json too, and it'll allow us to do privilege upgrades
+ Reject obviously bad (negative and too large) version_id values.
+ Also reject versions before 10.4.0 (when JSON table was added).
*/
- return get_access_value("access") & GLOBAL_ACLS;
+ if ((longlong) version_id < 0 || version_id > 999999 ||
+ (version_id > 0 && version_id < 100400))
+ {
+ print_warning_bad_version_id(version_id);
+ return NO_ACL;
+ }
+ return adjust_access(version_id, access) & GLOBAL_ACLS;
}
+
void set_access(const privilege_t rights, bool revoke) const
{
privilege_t access= get_access();
@@ -1487,6 +1537,7 @@ class User_table_json: public User_table
else
access|= rights;
set_int_value("access", (longlong) (access & GLOBAL_ACLS));
+ set_int_value("version_id", (longlong) MYSQL_VERSION_ID);
}
const char *unsafe_str(const char *s) const
{ return s[0] ? s : NULL; }
@@ -1607,10 +1658,6 @@ class User_table_json: public User_table
const char *value_end= value_start + value_len;
return my_strtoll10(value_start, (char**)&value_end, &err);
}
- privilege_t get_access_value(const char *key) const
- {
- return privilege_t(ALL_KNOWN_ACL & (ulonglong) get_int_value(key));
- }
double get_double_value(const char *key) const
{
int err;