Commit 1815e2de authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

Fixed privilege check problem with SELECT ... INTO OUTFILE

parent a4ad0d5d
...@@ -2494,7 +2494,7 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv, ...@@ -2494,7 +2494,7 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
*save_priv=thd->master_access; *save_priv=thd->master_access;
return FALSE; return FALSE;
} }
if ((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL) || if (((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
! db && dont_check_global_grants) ! db && dont_check_global_grants)
{ // We can never grant this { // We can never grant this
if (!no_errors) if (!no_errors)
...@@ -2513,7 +2513,8 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv, ...@@ -2513,7 +2513,8 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
thd->priv_user, db); /* purecov: inspected */ thd->priv_user, db); /* purecov: inspected */
else else
db_access=thd->db_access; db_access=thd->db_access;
want_access &= ~EXTRA_ACL; // Remove SHOW attribute // Remove SHOW attribute and access rights we already have
want_access &= ~(thd->master_access | EXTRA_ACL);
db_access= ((*save_priv=(db_access | thd->master_access)) & want_access); db_access= ((*save_priv=(db_access | thd->master_access)) & want_access);
/* grant_option is set if there exists a single table or column grant */ /* grant_option is set if there exists a single table or column grant */
...@@ -2567,16 +2568,7 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables, ...@@ -2567,16 +2568,7 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables,
} }
else if (check_access(thd,want_access,tables->db,&tables->grant.privilege, else if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
0, no_errors | grant_option)) 0, no_errors | grant_option))
{ return TRUE;
if (grant_option)
{
if ( check_access(thd,want_access & (uint) ~TABLE_ACLS,tables->db,&tables->grant.privilege,
0, no_errors))
return TRUE;
}
else
return TRUE;
}
} }
if (grant_option) if (grant_option)
return check_grant(thd,want_access & ~EXTRA_ACL,org_tables, return check_grant(thd,want_access & ~EXTRA_ACL,org_tables,
......
...@@ -8,9 +8,10 @@ use DBI; ...@@ -8,9 +8,10 @@ use DBI;
use Getopt::Long; use Getopt::Long;
use strict; use strict;
use vars qw($dbh $user_dbh $opt_help $opt_Information $opt_force $opt_debug use vars qw($dbh $user_dbh $opt_help $opt_Information $opt_force $opt_debug
$opt_verbose $opt_server $opt_root_user $opt_password $opt_user $opt_verbose $opt_server $opt_root_user $opt_password $opt_user
$opt_database $opt_host $version $user $tables_cols $columns_cols); $opt_database $opt_host $version $user $tables_cols $columns_cols
$tmp_table);
$version="1.0"; $version="1.0";
$opt_help=$opt_Information=$opt_force=$opt_debug=$opt_verbose=0; $opt_help=$opt_Information=$opt_force=$opt_debug=$opt_verbose=0;
...@@ -35,6 +36,7 @@ $|=1; ...@@ -35,6 +36,7 @@ $|=1;
$tables_cols="Host, Db, User, Table_name, Grantor, Table_priv, Column_priv"; $tables_cols="Host, Db, User, Table_name, Grantor, Table_priv, Column_priv";
$columns_cols="Host, Db, User, Table_name, Column_name, Column_priv"; $columns_cols="Host, Db, User, Table_name, Column_name, Column_priv";
$tmp_table="/tmp/grant-$$.test";
# #
# clear grant tables # clear grant tables
...@@ -294,6 +296,7 @@ safe_query("select $tables_cols from mysql.tables_priv"); ...@@ -294,6 +296,7 @@ safe_query("select $tables_cols from mysql.tables_priv");
safe_query("revoke ALL PRIVILEGES on $opt_database.test from $user"); safe_query("revoke ALL PRIVILEGES on $opt_database.test from $user");
safe_query("select $tables_cols from mysql.tables_priv"); safe_query("select $tables_cols from mysql.tables_priv");
safe_query("revoke GRANT OPTION on $opt_database.test from $user",1); safe_query("revoke GRANT OPTION on $opt_database.test from $user",1);
# #
# Test grants on database level # Test grants on database level
# #
...@@ -387,11 +390,24 @@ safe_query("grant ALL PRIVILEGES on $opt_database.test to $user identified by 'd ...@@ -387,11 +390,24 @@ safe_query("grant ALL PRIVILEGES on $opt_database.test to $user identified by 'd
user_connect(0,"dummy"); user_connect(0,"dummy");
safe_query("grant SELECT on $opt_database.* to $user identified by ''"); safe_query("grant SELECT on $opt_database.* to $user identified by ''");
user_connect(0); user_connect(0);
safe_query("revoke SELECT on $opt_database.* from $user identified by ''");
#
# Test bug reported in SELECT INTO OUTFILE
#
safe_query("create table $opt_database.test3 (a int)");
safe_query("grant SELECT on $opt_database.test3 to $user");
safe_query("grant FILE on *.* to $user");
safe_query("insert into $opt_database.test3 values (1)");
user_connect(0);
user_query("select * into outfile '$tmp_table' from $opt_database.test3");
# #
# Clean up things # Clean up things
# #
unlink($tmp_table);
safe_query("drop database $opt_database"); safe_query("drop database $opt_database");
safe_query("delete from user where user='$opt_user'"); safe_query("delete from user where user='$opt_user'");
safe_query("delete from db where user='$opt_user'"); safe_query("delete from db where user='$opt_user'");
......
...@@ -19,7 +19,7 @@ Access denied for user: 'grant_user@localhost' (Using password: NO) ...@@ -19,7 +19,7 @@ Access denied for user: 'grant_user@localhost' (Using password: NO)
set password FOR grant_user='' set password FOR grant_user=''
Connecting grant_user Connecting grant_user
select * from mysql.user where user = 'grant_user' select * from mysql.user where user = 'grant_user'
localhost grant_user Y N N N N N N N N N N N N N localhost grant_user Y N N N N N N N N N N N N N NONE
select * from mysql.db where user = 'grant_user' select * from mysql.db where user = 'grant_user'
grant select on *.* to grant_user@localhost,grant_user@localhost grant select on *.* to grant_user@localhost,grant_user@localhost
...@@ -48,7 +48,7 @@ Error in execute: The host or user argument to GRANT is too long ...@@ -48,7 +48,7 @@ Error in execute: The host or user argument to GRANT is too long
grant select on grant_test.test to grant_user with grant option grant select on grant_test.test to grant_user with grant option
Error in execute: grant command denied to user: 'grant_user@localhost' for table 'test' Error in execute: grant command denied to user: 'grant_user@localhost' for table 'test'
set password FOR ''@''='' set password FOR ''@''=''
Error in execute: You are using MySQL as an anonymous users and anonymous users are not allowed to change passwords Error in execute: Can't find any matching row in the user table
set password FOR root@localhost = password('test') set password FOR root@localhost = password('test')
Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql' Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql'
revoke select on *.* from grant_user@localhost revoke select on *.* from grant_user@localhost
...@@ -93,7 +93,7 @@ delete from user where user='grant_user' ...@@ -93,7 +93,7 @@ delete from user where user='grant_user'
flush privileges flush privileges
grant select on grant_test.* to grant_user@localhost grant select on grant_test.* to grant_user@localhost
select * from mysql.user where user = 'grant_user' select * from mysql.user where user = 'grant_user'
localhost grant_user N N N N N N N N N N N N N N localhost grant_user N N N N N N N N N N N N N N NONE
select * from mysql.db where user = 'grant_user' select * from mysql.db where user = 'grant_user'
localhost grant_test grant_user Y N N N N N N N N N localhost grant_test grant_user Y N N N N N N N N N
...@@ -152,7 +152,7 @@ insert into mysql.user (host,user) values ('error','grant_user',0) ...@@ -152,7 +152,7 @@ insert into mysql.user (host,user) values ('error','grant_user',0)
Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql' Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql'
revoke ALL PRIVILEGES on grant_test.* from grant_user@localhost revoke ALL PRIVILEGES on grant_test.* from grant_user@localhost
select * from mysql.user where user = 'grant_user' select * from mysql.user where user = 'grant_user'
localhost grant_user N N N N N N N N N N N N N N localhost grant_user N N N N N N N N N N N N N N NONE
select * from mysql.db where user = 'grant_user' select * from mysql.db where user = 'grant_user'
Connecting grant_user Connecting grant_user
...@@ -168,7 +168,7 @@ Error in execute: select command denied to user: 'grant_user@localhost' for tabl ...@@ -168,7 +168,7 @@ Error in execute: select command denied to user: 'grant_user@localhost' for tabl
show keys from test show keys from test
Error in execute: select command denied to user: 'grant_user@localhost' for table 'test' Error in execute: select command denied to user: 'grant_user@localhost' for table 'test'
show columns from test2 show columns from test2
a int(11) 0 a int(11) 0
show keys from test2 show keys from test2
select * from test select * from test
...@@ -311,8 +311,8 @@ revoke GRANT OPTION on grant_test.test from grant_user@localhost ...@@ -311,8 +311,8 @@ revoke GRANT OPTION on grant_test.test from grant_user@localhost
Error in execute: There is no such grant defined for user 'grant_user' on host 'localhost' on table 'test' Error in execute: There is no such grant defined for user 'grant_user' on host 'localhost' on table 'test'
grant select(a) on grant_test.test to grant_user@localhost grant select(a) on grant_test.test to grant_user@localhost
show columns from test show columns from test
a int(11) YES NULL select a int(11) YES NULL
b int(11) YES NULL b int(11) YES NULL
grant insert (b), update (b) on grant_test.test to grant_user@localhost grant insert (b), update (b) on grant_test.test to grant_user@localhost
select count(a) from test select count(a) from test
...@@ -437,6 +437,13 @@ grant ALL PRIVILEGES on grant_test.test to grant_user@localhost identified by 'd ...@@ -437,6 +437,13 @@ grant ALL PRIVILEGES on grant_test.test to grant_user@localhost identified by 'd
Connecting grant_user Connecting grant_user
grant SELECT on grant_test.* to grant_user@localhost identified by '' grant SELECT on grant_test.* to grant_user@localhost identified by ''
Connecting grant_user Connecting grant_user
revoke SELECT on grant_test.* from grant_user@localhost identified by ''
create table grant_test.test3 (a int)
grant SELECT on grant_test.test3 to grant_user@localhost
grant FILE on *.* to grant_user@localhost
insert into grant_test.test3 values (1)
Connecting grant_user
select * into outfile '/tmp/grant-11047.test' from grant_test.test3
drop database grant_test drop database grant_test
delete from user where user='grant_user' delete from user where user='grant_user'
delete from db where user='grant_user' delete from db where user='grant_user'
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment