WL#1437 :don't create new users with GRANT
This commit is contained in:
parent
81ef1a41d7
commit
efa50b5c03
@ -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\_1`.* to mysqltest_2@localhost with grant option;
|
||||||
grant all privileges on `my_%`.* to mysqltest_3@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_%'
|
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;
|
show grants for mysqltest_1@localhost;
|
||||||
Grants for mysqltest_1@localhost
|
Grants for mysqltest_1@localhost
|
||||||
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
|
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
|
||||||
|
@ -74,7 +74,7 @@ t1 CREATE TABLE `t1` (
|
|||||||
set sql_mode="postgresql,oracle,mssql,db2,maxdb";
|
set sql_mode="postgresql,oracle,mssql,db2,maxdb";
|
||||||
select @@sql_mode;
|
select @@sql_mode;
|
||||||
@@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;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE "t1" (
|
t1 CREATE TABLE "t1" (
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
set @@sql_mode='ansi,traditional';
|
set @@sql_mode='ansi,traditional';
|
||||||
select @@sql_mode;
|
select @@sql_mode;
|
||||||
@@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;
|
DROP TABLE IF EXISTS t1;
|
||||||
CREATE TABLE t1 (col1 date);
|
CREATE TABLE t1 (col1 date);
|
||||||
INSERT INTO t1 VALUES('2004-01-01'),('0000-10-31'),('2004-02-29');
|
INSERT INTO t1 VALUES('2004-01-01'),('0000-10-31'),('2004-02-29');
|
||||||
|
@ -21,6 +21,15 @@ select current_user;
|
|||||||
grant all privileges on `my\_1`.* to mysqltest_2@localhost with grant option;
|
grant all privileges on `my\_1`.* to mysqltest_2@localhost with grant option;
|
||||||
--error 1044
|
--error 1044
|
||||||
grant all privileges on `my_%`.* to mysqltest_3@localhost with grant option;
|
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;
|
disconnect user1;
|
||||||
connection default;
|
connection default;
|
||||||
show grants for mysqltest_1@localhost;
|
show grants for mysqltest_1@localhost;
|
||||||
|
@ -280,6 +280,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
|
|||||||
#define MODE_INVALID_DATES (MODE_NO_ZERO_DATE*2)
|
#define MODE_INVALID_DATES (MODE_NO_ZERO_DATE*2)
|
||||||
#define MODE_ERROR_FOR_DIVISION_BY_ZERO (MODE_INVALID_DATES*2)
|
#define MODE_ERROR_FOR_DIVISION_BY_ZERO (MODE_INVALID_DATES*2)
|
||||||
#define MODE_TRADITIONAL (MODE_ERROR_FOR_DIVISION_BY_ZERO*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
|
#define RAID_BLOCK_SIZE 1024
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ const char *sql_mode_names[] =
|
|||||||
"NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
|
"NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
|
||||||
"NO_AUTO_VALUE_ON_ZERO", "NO_BACKSLASH_ESCAPES", "STRICT_TRANS_TABLES", "STRICT_ALL_TABLES",
|
"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",
|
"NO_ZERO_IN_DATE", "NO_ZERO_DATE", "ALLOW_INVALID_DATES", "ERROR_FOR_DIVISION_BY_ZERO",
|
||||||
"TRADITIONAL",
|
"TRADITIONAL", "NO_AUTO_CREATE_USER",
|
||||||
NullS
|
NullS
|
||||||
};
|
};
|
||||||
TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
|
TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
|
||||||
|
@ -3077,7 +3077,7 @@ ulong fix_sql_mode(ulong sql_mode)
|
|||||||
sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
|
sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
|
||||||
MODE_IGNORE_SPACE |
|
MODE_IGNORE_SPACE |
|
||||||
MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
|
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)
|
if (sql_mode & MODE_MSSQL)
|
||||||
sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
|
sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
|
||||||
MODE_IGNORE_SPACE |
|
MODE_IGNORE_SPACE |
|
||||||
@ -3097,7 +3097,7 @@ ulong fix_sql_mode(ulong sql_mode)
|
|||||||
sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
|
sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
|
||||||
MODE_IGNORE_SPACE |
|
MODE_IGNORE_SPACE |
|
||||||
MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
|
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)
|
if (sql_mode & MODE_MYSQL40)
|
||||||
sql_mode|= MODE_NO_FIELD_OPTIONS;
|
sql_mode|= MODE_NO_FIELD_OPTIONS;
|
||||||
if (sql_mode & MODE_MYSQL323)
|
if (sql_mode & MODE_MYSQL323)
|
||||||
@ -3105,7 +3105,7 @@ ulong fix_sql_mode(ulong sql_mode)
|
|||||||
if (sql_mode & MODE_TRADITIONAL)
|
if (sql_mode & MODE_TRADITIONAL)
|
||||||
sql_mode|= (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES |
|
sql_mode|= (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES |
|
||||||
MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
|
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;
|
return sql_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1550,13 +1550,28 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
|||||||
(byte*) table->field[0]->ptr,0,
|
(byte*) table->field[0]->ptr,0,
|
||||||
HA_READ_KEY_EXACT))
|
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);
|
||||||
my_error(ER_NONEXISTING_GRANT, MYF(0), combo.user.str, combo.host.str);
|
goto end;
|
||||||
else
|
}
|
||||||
my_error(ER_NO_PERMISSION_TO_CREATE_USER, MYF(0),
|
/*
|
||||||
thd->user, thd->host_or_ip);
|
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;
|
goto end;
|
||||||
}
|
}
|
||||||
old_row_exists = 0;
|
old_row_exists = 0;
|
||||||
@ -1570,6 +1585,17 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
|||||||
}
|
}
|
||||||
else
|
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;
|
old_row_exists = 1;
|
||||||
store_record(table,record[1]); // Save copy for update
|
store_record(table,record[1]); // Save copy for update
|
||||||
if (combo.password.str) // If password given
|
if (combo.password.str) // If password given
|
||||||
|
@ -3377,29 +3377,6 @@ purposes internal to the MySQL server", MYF(0));
|
|||||||
first_table ? 0 : 1, 0))
|
first_table ? 0 : 1, 0))
|
||||||
goto error;
|
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)
|
if (specialflag & SPECIAL_NO_RESOLVE)
|
||||||
{
|
{
|
||||||
LEX_USER *user;
|
LEX_USER *user;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user