summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-10-28 07:46:17 +0100
committerSergei Golubchik <sergii@pisem.net>2013-10-28 07:46:17 +0100
commitfef416699009b78366d9eec937c01822b531f518 (patch)
tree421a09a52cfb608a8a5cffa1b62a49ca51a92fa2
parentd5c9712225b08be9efa19fddd82aed9d7e21938a (diff)
downloadmariadb-git-fef416699009b78366d9eec937c01822b531f518.tar.gz
Don't allow authentication clauses for roles, in particular:
GRANT ... IDENTIFIED BY [ PASSWORD ] ... GRANT ... IDENTIFIED VIA ... [ USING ... ] GRANT ... REQUIRE ... GRANT ... MAX_xxx ... SET PASSWORD FOR ... = ...
-rw-r--r--mysql-test/r/grant2.result2
-rw-r--r--mysql-test/r/plugin_auth_qa.result2
-rw-r--r--mysql-test/suite/roles/password.result34
-rw-r--r--mysql-test/suite/roles/password.test48
-rw-r--r--sql/share/errmsg-utf8.txt4
-rw-r--r--sql/sql_acl.cc53
-rw-r--r--sql/sql_yacc.yy2
7 files changed, 130 insertions, 15 deletions
diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result
index da24f454564..42bde270440 100644
--- a/mysql-test/r/grant2.result
+++ b/mysql-test/r/grant2.result
@@ -36,7 +36,7 @@ select @@sql_mode;
@@sql_mode
NO_AUTO_CREATE_USER
grant select on `my\_1`.* to mysqltest_4@localhost with grant option;
-ERROR 42000: Can't find any matching row in the user table
+ERROR 28000: Can't find any matching row in the user table
grant select on `my\_1`.* to mysqltest_4@localhost identified by 'mypass'
with grant option;
show grants for mysqltest_1@localhost;
diff --git a/mysql-test/r/plugin_auth_qa.result b/mysql-test/r/plugin_auth_qa.result
index 72d21994792..b86a01f6b52 100644
--- a/mysql-test/r/plugin_auth_qa.result
+++ b/mysql-test/r/plugin_auth_qa.result
@@ -303,7 +303,7 @@ grant_user test_plugin_server plug_dest
CREATE USER plug_dest;
DROP USER plug_dest;
GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest;
-ERROR 42000: Can't find any matching row in the user table
+ERROR 28000: Can't find any matching row in the user table
DROP USER grant_user;
GRANT INSERT ON test_user_db.* TO grant_user IDENTIFIED WITH test_plugin_server AS 'plug_dest';
SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
diff --git a/mysql-test/suite/roles/password.result b/mysql-test/suite/roles/password.result
new file mode 100644
index 00000000000..e41816bdef7
--- /dev/null
+++ b/mysql-test/suite/roles/password.result
@@ -0,0 +1,34 @@
+create role r1;
+grant select on *.* to r1 identified by 'foobar';
+ERROR 28000: Can't find any matching row in the user table
+grant select on *.* to r1 identified by '';
+ERROR 28000: Can't find any matching row in the user table
+grant select on mysql.user to r1 identified by password '00000000000000000000000000000000000000000';
+ERROR 28000: Can't find any matching row in the user table
+grant select on *.* to r1 identified via plugin;
+ERROR 28000: Can't find any matching row in the user table
+grant select on mysql.user to r1 identified via plugin using 'param';
+ERROR 28000: Can't find any matching row in the user table
+grant select on *.* to r1 require subject 'foobar';
+ERROR 28000: Can't find any matching row in the user table
+grant select on mysql.user to r1 require issuer 'foobar';
+ERROR 28000: Can't find any matching row in the user table
+grant select on *.* to r1 require cipher 'foobar';
+ERROR 28000: Can't find any matching row in the user table
+grant select on mysql.user to r1 require ssl;
+ERROR 28000: Can't find any matching row in the user table
+grant select on *.* to r1 require x509;
+ERROR 28000: Can't find any matching row in the user table
+grant select on mysql.user to r1 require none;
+ERROR 28000: Can't find any matching row in the user table
+grant select on *.* to r1 with max_queries_per_hour 10;
+ERROR 28000: Can't find any matching row in the user table
+grant select on mysql.user to r1 with max_updates_per_hour 10;
+ERROR 28000: Can't find any matching row in the user table
+grant select on *.* to r1 with max_connections_per_hour 10;
+ERROR 28000: Can't find any matching row in the user table
+grant select on mysql.user to r1 with max_user_connections 10;
+ERROR 28000: Can't find any matching row in the user table
+set password for r1 = '00000000000000000000000000000000000000000';
+ERROR 28000: Can't find any matching row in the user table
+drop role r1;
diff --git a/mysql-test/suite/roles/password.test b/mysql-test/suite/roles/password.test
new file mode 100644
index 00000000000..6b5073fae43
--- /dev/null
+++ b/mysql-test/suite/roles/password.test
@@ -0,0 +1,48 @@
+#
+# setting authentication for roles
+#
+
+--source include/not_embedded.inc
+
+#identified by [password]...
+#identified with ... [using ...]
+#require [subject][issuer][cipher][ssl][x509]
+# max_queries_per_hour | max_updates_per_hour | max_connections_per_hour | max_user_connections
+#set password for ... = ...
+
+create role r1;
+
+--error ER_PASSWORD_NO_MATCH
+grant select on *.* to r1 identified by 'foobar';
+--error ER_PASSWORD_NO_MATCH
+grant select on *.* to r1 identified by '';
+--error ER_PASSWORD_NO_MATCH
+grant select on mysql.user to r1 identified by password '00000000000000000000000000000000000000000';
+--error ER_PASSWORD_NO_MATCH
+grant select on *.* to r1 identified via plugin;
+--error ER_PASSWORD_NO_MATCH
+grant select on mysql.user to r1 identified via plugin using 'param';
+--error ER_PASSWORD_NO_MATCH
+grant select on *.* to r1 require subject 'foobar';
+--error ER_PASSWORD_NO_MATCH
+grant select on mysql.user to r1 require issuer 'foobar';
+--error ER_PASSWORD_NO_MATCH
+grant select on *.* to r1 require cipher 'foobar';
+--error ER_PASSWORD_NO_MATCH
+grant select on mysql.user to r1 require ssl;
+--error ER_PASSWORD_NO_MATCH
+grant select on *.* to r1 require x509;
+--error ER_PASSWORD_NO_MATCH
+grant select on mysql.user to r1 require none;
+--error ER_PASSWORD_NO_MATCH
+grant select on *.* to r1 with max_queries_per_hour 10;
+--error ER_PASSWORD_NO_MATCH
+grant select on mysql.user to r1 with max_updates_per_hour 10;
+--error ER_PASSWORD_NO_MATCH
+grant select on *.* to r1 with max_connections_per_hour 10;
+--error ER_PASSWORD_NO_MATCH
+grant select on mysql.user to r1 with max_user_connections 10;
+--error ER_PASSWORD_NO_MATCH
+set password for r1 = '00000000000000000000000000000000000000000';
+
+drop role r1;
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index cf2aa33f96e..56f9dc09dd3 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -3065,7 +3065,7 @@ ER_PASSWORD_NOT_ALLOWED 42000
spa "Tu debes de tener permiso para actualizar tablas en la base de datos mysql para cambiar las claves para otros"
swe "För att ändra lösenord för andra måste du ha rättigheter att uppdatera mysql-databasen"
ukr "Ви повині мати право на оновлення таблиць у базі данних mysql, аби мати можливість змінювати пароль іншим"
-ER_PASSWORD_NO_MATCH 42000
+ER_PASSWORD_NO_MATCH 28000
cze "V tabulce user nen-Bí žádný odpovídající řádek"
dan "Kan ikke finde nogen tilsvarende poster i bruger tabellen"
nla "Kan geen enkele passende rij vinden in de gebruikers tabel"
@@ -6565,7 +6565,7 @@ ER_NO_SUCH_QUERY
ER_INVALID_ROLE OP000
eng "Invalid role specification %`s."
rum "Rolul %`s este invalid."
-ER_INVALID_CURRENT_USER
+ER_INVALID_CURRENT_USER 0L000
eng "The current user is invalid."
rum "Utilizatorul curent este invalid."
ER_CANNOT_GRANT_ROLE
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 24743ad9168..28628e313f8 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -5289,6 +5289,38 @@ static int merge_role_privileges(ACL_ROLE *role __attribute__((unused)),
End of the role privilege propagation and graph traversal code
******************************************************************/
+bool copy_and_check_auth(LEX_USER *to, LEX_USER *from, LEX *lex)
+{
+ if (to != from)
+ {
+ /* preserve authentication information, if LEX_USER was reallocated */
+ to->password= from->password;
+ to->plugin= from->plugin;
+ to->auth= from->auth;
+ }
+
+ /*
+ Note, that no password is null_lex_str, while no plugin is empty_lex_str.
+ See sql_yacc.yy
+ */
+ bool has_auth= to->password.str || to->plugin.length || to->auth.length ||
+ lex->ssl_type != SSL_TYPE_NOT_SPECIFIED || lex->ssl_cipher ||
+ lex->x509_issuer || lex->x509_subject ||
+ lex->mqh.specified_limits;
+
+ /*
+ Specifying authentication clauses forces the name to be interpreted
+ as a user, not a role. See also check_change_password()
+ */
+ if (to->is_role() && has_auth)
+ {
+ my_error(ER_PASSWORD_NO_MATCH, MYF(0));
+ return true;
+ }
+
+ return false;
+}
+
/*
Store table level and column level grants in the privilege tables
@@ -5462,10 +5494,13 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
continue;
}
/* Create user if needed */
- error=replace_user_table(thd, tables[0].table, *Str,
- 0, revoke_grant, create_new_users,
- test(thd->variables.sql_mode &
- MODE_NO_AUTO_CREATE_USER));
+ if (copy_and_check_auth(Str, tmp_Str, thd->lex))
+ error= -1;
+ else
+ error=replace_user_table(thd, tables[0].table, *Str,
+ 0, revoke_grant, create_new_users,
+ test(thd->variables.sql_mode &
+ MODE_NO_AUTO_CREATE_USER));
if (error)
{
result= TRUE; // Remember error
@@ -6102,14 +6137,10 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
result= TRUE;
continue;
}
- /*
- No User, but a password?
- They did GRANT ... TO CURRENT_USER() IDENTIFIED BY ... !
- Get the current user, and shallow-copy the new password to them!
- */
- if (tmp_Str->user.str == current_user.str && tmp_Str->password.str)
- Str->password= tmp_Str->password;
+ if (copy_and_check_auth(Str, tmp_Str, thd->lex))
+ result= -1;
+ else
if (replace_user_table(thd, tables[0].table, *Str,
(!db ? rights : 0), revoke_grant, create_new_users,
test(thd->variables.sql_mode &
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 38b6d990aa5..f0d68c453be 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -13222,6 +13222,8 @@ user:
if (!($$=(LEX_USER*)thd->calloc(sizeof(LEX_USER))))
MYSQL_YYABORT;
$$->user= current_user;
+ $$->plugin= empty_lex_str;
+ $$->auth= empty_lex_str;
}
;