summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/grant2.result8
-rw-r--r--mysql-test/r/sql_mode.result2
-rw-r--r--mysql-test/r/strict.result2
-rw-r--r--mysql-test/t/grant2.test9
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/set_var.cc6
-rw-r--r--sql/sql_acl.cc38
-rw-r--r--sql/sql_parse.cc23
9 files changed, 56 insertions, 35 deletions
diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result
index 31e506d2679..c95b86ea831 100644
--- a/mysql-test/r/grant2.result
+++ b/mysql-test/r/grant2.result
@@ -12,6 +12,14 @@ mysqltest_1@localhost
grant all privileges on `my\_1`.* to mysqltest_2@localhost with grant option;
grant all privileges on `my_%`.* to mysqltest_3@localhost with grant option;
ERROR 42000: Access denied for user 'mysqltest_1'@'localhost' to database 'my_%'
+set @@sql_mode='NO_AUTO_CREATE_USER';
+select @@sql_mode;
+@@sql_mode
+NO_AUTO_CREATE_USER
+grant select on `my\_1`.* to mysqltest_4@localhost with grant option;
+ERROR 42000: 'mysqltest_1'@'localhost' is not allowed to create new users
+grant select on `my\_1`.* to mysqltest_4@localhost identified by 'mypass'
+with grant option;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result
index c4731b93d2b..d861e3a5926 100644
--- a/mysql-test/r/sql_mode.result
+++ b/mysql-test/r/sql_mode.result
@@ -74,7 +74,7 @@ t1 CREATE TABLE `t1` (
set sql_mode="postgresql,oracle,mssql,db2,maxdb";
select @@sql_mode;
@@sql_mode
-PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS
+PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER
show create table t1;
Table Create Table
t1 CREATE TABLE "t1" (
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index 31e3d82d52e..19c4def9b32 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -1,7 +1,7 @@
set @@sql_mode='ansi,traditional';
select @@sql_mode;
@@sql_mode
-REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL
+REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (col1 date);
INSERT INTO t1 VALUES('2004-01-01'),('0000-10-31'),('2004-02-29');
diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test
index 3a9afa7453b..6aa47a01753 100644
--- a/mysql-test/t/grant2.test
+++ b/mysql-test/t/grant2.test
@@ -21,6 +21,15 @@ select current_user;
grant all privileges on `my\_1`.* to mysqltest_2@localhost with grant option;
--error 1044
grant all privileges on `my_%`.* to mysqltest_3@localhost with grant option;
+#
+# NO_AUTO_CREATE_USER mode
+#
+set @@sql_mode='NO_AUTO_CREATE_USER';
+select @@sql_mode;
+--error 1211
+grant select on `my\_1`.* to mysqltest_4@localhost with grant option;
+grant select on `my\_1`.* to mysqltest_4@localhost identified by 'mypass'
+with grant option;
disconnect user1;
connection default;
show grants for mysqltest_1@localhost;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index d8916149b77..02dda86f054 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -280,6 +280,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
#define MODE_INVALID_DATES (MODE_NO_ZERO_DATE*2)
#define MODE_ERROR_FOR_DIVISION_BY_ZERO (MODE_INVALID_DATES*2)
#define MODE_TRADITIONAL (MODE_ERROR_FOR_DIVISION_BY_ZERO*2)
+#define MODE_NO_AUTO_CREATE_USER (MODE_TRADITIONAL*2)
#define RAID_BLOCK_SIZE 1024
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index db81b14c9c9..f2d0dadbc17 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -221,7 +221,7 @@ const char *sql_mode_names[] =
"NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
"NO_AUTO_VALUE_ON_ZERO", "NO_BACKSLASH_ESCAPES", "STRICT_TRANS_TABLES", "STRICT_ALL_TABLES",
"NO_ZERO_IN_DATE", "NO_ZERO_DATE", "ALLOW_INVALID_DATES", "ERROR_FOR_DIVISION_BY_ZERO",
- "TRADITIONAL",
+ "TRADITIONAL", "NO_AUTO_CREATE_USER",
NullS
};
TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
diff --git a/sql/set_var.cc b/sql/set_var.cc
index a43a2c13aca..25af3d9c853 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -3077,7 +3077,7 @@ ulong fix_sql_mode(ulong sql_mode)
sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
MODE_IGNORE_SPACE |
MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
- MODE_NO_FIELD_OPTIONS);
+ MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
if (sql_mode & MODE_MSSQL)
sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
MODE_IGNORE_SPACE |
@@ -3097,7 +3097,7 @@ ulong fix_sql_mode(ulong sql_mode)
sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
MODE_IGNORE_SPACE |
MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
- MODE_NO_FIELD_OPTIONS);
+ MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
if (sql_mode & MODE_MYSQL40)
sql_mode|= MODE_NO_FIELD_OPTIONS;
if (sql_mode & MODE_MYSQL323)
@@ -3105,7 +3105,7 @@ ulong fix_sql_mode(ulong sql_mode)
if (sql_mode & MODE_TRADITIONAL)
sql_mode|= (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES |
MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
- MODE_ERROR_FOR_DIVISION_BY_ZERO);
+ MODE_ERROR_FOR_DIVISION_BY_ZERO | MODE_NO_AUTO_CREATE_USER);
return sql_mode;
}
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index df615383ec3..443b925521f 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1550,13 +1550,28 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
(byte*) table->field[0]->ptr,0,
HA_READ_KEY_EXACT))
{
- if (!create_user)
+ /* what == 'N' means revoke */
+ if (what == 'N')
{
- if (what == 'N')
- my_error(ER_NONEXISTING_GRANT, MYF(0), combo.user.str, combo.host.str);
- else
- my_error(ER_NO_PERMISSION_TO_CREATE_USER, MYF(0),
- thd->user, thd->host_or_ip);
+ my_error(ER_NONEXISTING_GRANT, MYF(0), combo.user.str, combo.host.str);
+ goto end;
+ }
+ /*
+ There are four options which affect the process of creation of
+ a new user(mysqld option --safe-create-user, 'insert' privilege
+ on 'mysql.user' table, using 'GRANT' with 'IDENTIFIED BY' and
+ SQL_MODE flag NO_AUTO_CREATE_USER). Below is the simplified rule
+ how it should work.
+ if (safe-user-create && ! INSERT_priv) => reject
+ else if (identified_by) => create
+ else if (no_auto_create_user) => reject
+ else create
+ */
+ else if (((thd->variables.sql_mode & MODE_NO_AUTO_CREATE_USER) &&
+ !password_len) || !create_user)
+ {
+ my_error(ER_NO_PERMISSION_TO_CREATE_USER, MYF(0),
+ thd->user, thd->host_or_ip);
goto end;
}
old_row_exists = 0;
@@ -1570,6 +1585,17 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
}
else
{
+ /*
+ Check that the user isn't trying to change a password for another
+ user if he doesn't have UPDATE privilege to the MySQL database
+ */
+ DBUG_ASSERT(combo.host.str);
+ if (thd->user && combo.password.str &&
+ (strcmp(thd->user,combo.user.str) ||
+ my_strcasecmp(&my_charset_latin1,
+ combo.host.str, thd->host_or_ip)) &&
+ check_access(thd, UPDATE_ACL, "mysql",0,1,0))
+ goto end;
old_row_exists = 1;
store_record(table,record[1]); // Save copy for update
if (combo.password.str) // If password given
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 623c47d4be5..e65c2614a7f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3377,29 +3377,6 @@ purposes internal to the MySQL server", MYF(0));
first_table ? 0 : 1, 0))
goto error;
- /*
- Check that the user isn't trying to change a password for another
- user if he doesn't have UPDATE privilege to the MySQL database
- */
-
- if (thd->user) // If not replication
- {
- LEX_USER *user;
- List_iterator <LEX_USER> user_list(lex->users_list);
- while ((user=user_list++))
- {
- if (user->password.str &&
- (strcmp(thd->user,user->user.str) ||
- user->host.str &&
- my_strcasecmp(&my_charset_latin1,
- user->host.str, thd->host_or_ip)))
- {
- if (check_access(thd, UPDATE_ACL, "mysql",0,1,0))
- goto error;
- break; // We are allowed to do changes
- }
- }
- }
if (specialflag & SPECIAL_NO_RESOLVE)
{
LEX_USER *user;