Commit 40a0199e authored by unknown's avatar unknown

unsufficient privilege checks in GRANT, when a grantor has column-level privileges

parent 4ba981e5
...@@ -121,7 +121,7 @@ create database mysqltest; ...@@ -121,7 +121,7 @@ create database mysqltest;
create table mysqltest.t1 (a int,b int,c int); create table mysqltest.t1 (a int,b int,c int);
grant all on mysqltest.t1 to mysqltest_1@localhost; grant all on mysqltest.t1 to mysqltest_1@localhost;
alter table t1 rename t2; alter table t1 rename t2;
insert command denied to user: 'mysqltest_1@localhost' for table 't2' INSERT,CREATE command denied to user: 'mysqltest_1@localhost' for table 't2'
revoke all privileges on mysqltest.t1 from mysqltest_1@localhost; revoke all privileges on mysqltest.t1 from mysqltest_1@localhost;
delete from mysql.user where user='mysqltest_1'; delete from mysql.user where user='mysqltest_1';
drop database mysqltest; drop database mysqltest;
......
...@@ -198,7 +198,7 @@ GRANT UPDATE (d) ON `mysqltest_2`.`t2` TO 'mysqltest_3'@'localhost' ...@@ -198,7 +198,7 @@ GRANT UPDATE (d) ON `mysqltest_2`.`t2` TO 'mysqltest_3'@'localhost'
update mysqltest_1.t1, mysqltest_1.t2 set q=10 where b=1; update mysqltest_1.t1, mysqltest_1.t2 set q=10 where b=1;
UPDATE command denied to user: 'mysqltest_3@localhost' for column 'q' in table 't1' UPDATE command denied to user: 'mysqltest_3@localhost' for column 'q' in table 't1'
update mysqltest_1.t1, mysqltest_2.t2 set d=20 where d=1; update mysqltest_1.t1, mysqltest_2.t2 set d=20 where d=1;
select command denied to user: 'mysqltest_3@localhost' for table 't1' SELECT command denied to user: 'mysqltest_3@localhost' for table 't1'
update mysqltest_2.t1, mysqltest_1.t2 set c=20 where b=1; update mysqltest_2.t1, mysqltest_1.t2 set c=20 where b=1;
UPDATE command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1' UPDATE command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1'
update mysqltest_2.t1, mysqltest_2.t2 set d=10 where s=2; update mysqltest_2.t1, mysqltest_2.t2 set d=10 where s=2;
......
...@@ -121,7 +121,7 @@ a b c a ...@@ -121,7 +121,7 @@ a b c a
1 1 1 test.t1 1 1 1 test.t1
2 2 2 test.t1 2 2 2 test.t1
select * from t2; select * from t2;
select command denied to user: 'mysqltest_2@localhost' for table 't2' SELECT command denied to user: 'mysqltest_2@localhost' for table 't2'
show status like "Qcache_queries_in_cache"; show status like "Qcache_queries_in_cache";
Variable_name Value Variable_name Value
Qcache_queries_in_cache 6 Qcache_queries_in_cache 6
...@@ -135,7 +135,7 @@ select "user3"; ...@@ -135,7 +135,7 @@ select "user3";
user3 user3
user3 user3
select * from t1; select * from t1;
select command denied to user: 'mysqltest_3@localhost' for column 'b' in table 't1' SELECT command denied to user: 'mysqltest_3@localhost' for column 'b' in table 't1'
select a from t1; select a from t1;
a a
1 1
...@@ -143,7 +143,7 @@ a ...@@ -143,7 +143,7 @@ a
select c from t1; select c from t1;
SELECT command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1' SELECT command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1'
select * from t2; select * from t2;
select command denied to user: 'mysqltest_3@localhost' for table 't2' SELECT command denied to user: 'mysqltest_3@localhost' for table 't2'
select mysqltest.t1.c from test.t1,mysqltest.t1; select mysqltest.t1.c from test.t1,mysqltest.t1;
SELECT command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1' SELECT command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1'
show status like "Qcache_queries_in_cache"; show status like "Qcache_queries_in_cache";
......
...@@ -2134,37 +2134,57 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, ...@@ -2134,37 +2134,57 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (columns.elements && !revoke_grant) if (!revoke_grant)
{ {
TABLE *table; if (columns.elements && !revoke_grant)
class LEX_COLUMN *column;
List_iterator <LEX_COLUMN> column_iter(columns);
if (!(table=open_ltable(thd,table_list,TL_READ)))
DBUG_RETURN(-1);
while ((column = column_iter++))
{ {
if (!find_field_in_table(thd,table,column->column.ptr(), TABLE *table;
column->column.length(),0,0)) class LEX_COLUMN *column;
List_iterator <LEX_COLUMN> column_iter(columns);
if (!(table=open_ltable(thd,table_list,TL_READ)))
DBUG_RETURN(-1);
while ((column = column_iter++))
{ {
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), Field *f= find_field_in_table(thd,table,column->column.ptr(),
column->column.c_ptr(), table_list->alias); column->column.length(),1,0);
DBUG_RETURN(-1); if (!f)
{
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
column->column.c_ptr(), table_list->alias);
DBUG_RETURN(-1);
}
if (f == (Field*)-1)
{
DBUG_RETURN(-1);
}
column_priv|= column->rights;
} }
column_priv|= column->rights; close_thread_tables(thd);
} }
close_thread_tables(thd); else
}
else if (!(rights & CREATE_ACL) && !revoke_grant)
{
char buf[FN_REFLEN];
sprintf(buf,"%s/%s/%s.frm",mysql_data_home, table_list->db,
table_list->real_name);
fn_format(buf,buf,"","",4+16+32);
if (access(buf,F_OK))
{ {
my_error(ER_NO_SUCH_TABLE,MYF(0),table_list->db, table_list->alias); if (!(rights & CREATE_ACL))
DBUG_RETURN(-1); {
char buf[FN_REFLEN];
sprintf(buf,"%s/%s/%s.frm",mysql_data_home, table_list->db,
table_list->real_name);
fn_format(buf,buf,"","",4+16+32);
if (access(buf,F_OK))
{
my_error(ER_NO_SUCH_TABLE,MYF(0),table_list->db, table_list->alias);
DBUG_RETURN(-1);
}
}
if (table_list->grant.want_privilege)
{
char command[128];
get_privilege_desc(command, sizeof(command),
table_list->grant.want_privilege);
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
command, thd->priv_user, thd->host_or_ip, table_list->alias);
DBUG_RETURN(-1);
}
} }
} }
...@@ -2189,7 +2209,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, ...@@ -2189,7 +2209,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
*/ */
if (thd->slave_thread && table_rules_on) if (thd->slave_thread && table_rules_on)
{ {
/* /*
The tables must be marked "updating" so that tables_ok() takes them into The tables must be marked "updating" so that tables_ok() takes them into
account in tests. account in tests.
*/ */
...@@ -2636,25 +2656,8 @@ err: ...@@ -2636,25 +2656,8 @@ err:
pthread_mutex_unlock(&LOCK_grant); pthread_mutex_unlock(&LOCK_grant);
if (!no_errors) // Not a silent skip of table if (!no_errors) // Not a silent skip of table
{ {
const char *command=""; char command[128];
if (want_access & SELECT_ACL) get_privilege_desc(command, sizeof(command), want_access);
command ="select";
else if (want_access & INSERT_ACL)
command = "insert";
else if (want_access & UPDATE_ACL)
command = "update";
else if (want_access & DELETE_ACL)
command = "delete";
else if (want_access & DROP_ACL)
command = "drop";
else if (want_access & CREATE_ACL)
command = "create";
else if (want_access & ALTER_ACL)
command = "alter";
else if (want_access & INDEX_ACL)
command = "index";
else if (want_access & GRANT_ACL)
command = "grant";
net_printf(&thd->net,ER_TABLEACCESS_DENIED_ERROR, net_printf(&thd->net,ER_TABLEACCESS_DENIED_ERROR,
command, command,
thd->priv_user, thd->priv_user,
...@@ -2767,11 +2770,8 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table) ...@@ -2767,11 +2770,8 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
err: err:
pthread_mutex_unlock(&LOCK_grant); pthread_mutex_unlock(&LOCK_grant);
const char *command=""; char command[128];
if (want_access & SELECT_ACL) get_privilege_desc(command, sizeof(command), want_access);
command ="select";
else if (want_access & INSERT_ACL)
command = "insert";
my_printf_error(ER_COLUMNACCESS_DENIED_ERROR, my_printf_error(ER_COLUMNACCESS_DENIED_ERROR,
ER(ER_COLUMNACCESS_DENIED_ERROR), ER(ER_COLUMNACCESS_DENIED_ERROR),
MYF(0), MYF(0),
......
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