mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-14853 Grant does not work correctly when table contains...
SYSTEM_INVISIBLE or COMPLETELY_INVISIBLE This commit does multiple things to solve this mdev 1st add field into the parameter of check_column_grant_in_table_ref, so that we can find out field invisibility. 2nd If field->invisible >= INVISIBLE_SYSTEM skip access check and simple grant access.
This commit is contained in:
68
mysql-test/main/invisible_field_grant_completely.result
Normal file
68
mysql-test/main/invisible_field_grant_completely.result
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
set @old_debug= @@debug_dbug;
|
||||||
|
create user user_1;
|
||||||
|
show grants for user_1;
|
||||||
|
Grants for user_1@%
|
||||||
|
GRANT USAGE ON *.* TO 'user_1'@'%'
|
||||||
|
# create user
|
||||||
|
create database d;
|
||||||
|
use d;
|
||||||
|
|
||||||
|
#Completely Invisible
|
||||||
|
set debug_dbug= "+d,test_completely_invisible";
|
||||||
|
create table t1(a int);
|
||||||
|
insert into t1 values(1);
|
||||||
|
select a,invisible from t1;
|
||||||
|
a invisible
|
||||||
|
1 9
|
||||||
|
set debug_dbug=@old_debug;
|
||||||
|
grant insert(a) on t1 to user_1;
|
||||||
|
grant update(a) on t1 to user_1;
|
||||||
|
grant select(a) on t1 to user_1;
|
||||||
|
grant delete on t1 to user_1;
|
||||||
|
connect con1, localhost, user_1,,test;
|
||||||
|
connection con1;
|
||||||
|
select user();
|
||||||
|
user()
|
||||||
|
user_1@localhost
|
||||||
|
use d;
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
insert into t1 values(2);
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
insert into t1(a) values(3);
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
select invisible,a from t1;
|
||||||
|
ERROR 42S22: Unknown column 'invisible' in 'field list'
|
||||||
|
delete from t1 where a =1;
|
||||||
|
update t1 set a=1 where a=3;
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
2
|
||||||
|
1
|
||||||
|
connection default;
|
||||||
|
REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1;
|
||||||
|
connection con1;
|
||||||
|
select * from t1;
|
||||||
|
ERROR 42000: SELECT command denied to user 'user_1'@'localhost' for table 't1'
|
||||||
|
select invisible from t1;
|
||||||
|
ERROR 42000: SELECT command denied to user 'user_1'@'localhost' for table 't1'
|
||||||
|
disconnect con1;
|
||||||
|
|
||||||
|
#Final Cleanup
|
||||||
|
connection default;
|
||||||
|
set debug_dbug= "+d,test_completely_invisible";
|
||||||
|
select a,invisible from t1;
|
||||||
|
a invisible
|
||||||
|
2 9
|
||||||
|
1 9
|
||||||
|
drop user user_1;
|
||||||
|
drop database d;
|
||||||
|
set @old_debug= @@debug_dbug;
|
57
mysql-test/main/invisible_field_grant_completely.test
Normal file
57
mysql-test/main/invisible_field_grant_completely.test
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# Grant tests not performed with embedded server
|
||||||
|
-- source include/not_embedded.inc
|
||||||
|
|
||||||
|
--source include/have_debug.inc
|
||||||
|
##TEST for invisible coloumn level 3
|
||||||
|
set @old_debug= @@debug_dbug;
|
||||||
|
create user user_1;
|
||||||
|
show grants for user_1;
|
||||||
|
--echo # create user
|
||||||
|
create database d;
|
||||||
|
use d;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo #Completely Invisible
|
||||||
|
set debug_dbug= "+d,test_completely_invisible";
|
||||||
|
create table t1(a int);
|
||||||
|
insert into t1 values(1);
|
||||||
|
select a,invisible from t1;
|
||||||
|
set debug_dbug=@old_debug;
|
||||||
|
grant insert(a) on t1 to user_1;
|
||||||
|
grant update(a) on t1 to user_1;
|
||||||
|
grant select(a) on t1 to user_1;
|
||||||
|
grant delete on t1 to user_1;
|
||||||
|
connect (con1, localhost, user_1,,test);
|
||||||
|
connection con1;
|
||||||
|
select user();
|
||||||
|
use d;
|
||||||
|
select * from t1;
|
||||||
|
insert into t1 values(2);
|
||||||
|
select * from t1;
|
||||||
|
insert into t1(a) values(3);
|
||||||
|
select * from t1;
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
|
select invisible,a from t1;
|
||||||
|
delete from t1 where a =1;
|
||||||
|
update t1 set a=1 where a=3;
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
connection default;
|
||||||
|
REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1;
|
||||||
|
|
||||||
|
connection con1;
|
||||||
|
--error ER_TABLEACCESS_DENIED_ERROR
|
||||||
|
select * from t1;
|
||||||
|
--error ER_TABLEACCESS_DENIED_ERROR
|
||||||
|
select invisible from t1;
|
||||||
|
|
||||||
|
disconnect con1;
|
||||||
|
--source include/wait_until_disconnected.inc
|
||||||
|
--echo
|
||||||
|
--echo #Final Cleanup
|
||||||
|
connection default;
|
||||||
|
set debug_dbug= "+d,test_completely_invisible";
|
||||||
|
select a,invisible from t1;
|
||||||
|
drop user user_1;
|
||||||
|
drop database d;
|
||||||
|
set @old_debug= @@debug_dbug;
|
68
mysql-test/main/invisible_field_grant_system.result
Normal file
68
mysql-test/main/invisible_field_grant_system.result
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
create user user_1;
|
||||||
|
show grants for user_1;
|
||||||
|
Grants for user_1@%
|
||||||
|
GRANT USAGE ON *.* TO 'user_1'@'%'
|
||||||
|
# create user
|
||||||
|
create database d;
|
||||||
|
use d;
|
||||||
|
|
||||||
|
#System_Invisible
|
||||||
|
create table t1(a int) with system versioning;
|
||||||
|
insert into t1 values(1);
|
||||||
|
select a from t1;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
select count(row_start) from t1;
|
||||||
|
count(row_start)
|
||||||
|
1
|
||||||
|
grant insert(a) on t1 to user_1;
|
||||||
|
grant update(a) on t1 to user_1;
|
||||||
|
grant select(a) on t1 to user_1;
|
||||||
|
grant delete on t1 to user_1;
|
||||||
|
connect con1, localhost, user_1,,test;
|
||||||
|
connection con1;
|
||||||
|
select user();
|
||||||
|
user()
|
||||||
|
user_1@localhost
|
||||||
|
use d;
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
insert into t1 values(2);
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
insert into t1(a) values(3);
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
select a from t1;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
select count(row_start) from t1;
|
||||||
|
count(row_start)
|
||||||
|
3
|
||||||
|
delete from t1 where a =1;
|
||||||
|
update t1 set a=1 where a=3;
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
2
|
||||||
|
1
|
||||||
|
connection default;
|
||||||
|
REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1;
|
||||||
|
connection con1;
|
||||||
|
select * from t1;
|
||||||
|
ERROR 42000: SELECT command denied to user 'user_1'@'localhost' for table 't1'
|
||||||
|
select count(row_start) from t1;
|
||||||
|
ERROR 42000: SELECT command denied to user 'user_1'@'localhost' for table 't1'
|
||||||
|
disconnect con1;
|
||||||
|
|
||||||
|
#Cleanup
|
||||||
|
connection default;
|
||||||
|
drop user user_1;
|
||||||
|
drop database d;
|
52
mysql-test/main/invisible_field_grant_system.test
Normal file
52
mysql-test/main/invisible_field_grant_system.test
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# Grant tests not performed with embedded server
|
||||||
|
-- source include/not_embedded.inc
|
||||||
|
|
||||||
|
##TEST for invisible coloumn level 2
|
||||||
|
create user user_1;
|
||||||
|
show grants for user_1;
|
||||||
|
--echo # create user
|
||||||
|
create database d;
|
||||||
|
use d;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo #System_Invisible
|
||||||
|
create table t1(a int) with system versioning;
|
||||||
|
insert into t1 values(1);
|
||||||
|
select a from t1;
|
||||||
|
select count(row_start) from t1;
|
||||||
|
grant insert(a) on t1 to user_1;
|
||||||
|
grant update(a) on t1 to user_1;
|
||||||
|
grant select(a) on t1 to user_1;
|
||||||
|
grant delete on t1 to user_1;
|
||||||
|
connect (con1, localhost, user_1,,test);
|
||||||
|
connection con1;
|
||||||
|
select user();
|
||||||
|
use d;
|
||||||
|
select * from t1;
|
||||||
|
insert into t1 values(2);
|
||||||
|
select * from t1;
|
||||||
|
insert into t1(a) values(3);
|
||||||
|
select * from t1;
|
||||||
|
select a from t1;
|
||||||
|
select count(row_start) from t1;
|
||||||
|
delete from t1 where a =1;
|
||||||
|
update t1 set a=1 where a=3;
|
||||||
|
select * from t1;
|
||||||
|
connection default;
|
||||||
|
REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1;
|
||||||
|
|
||||||
|
connection con1;
|
||||||
|
--error ER_TABLEACCESS_DENIED_ERROR
|
||||||
|
select * from t1;
|
||||||
|
--error ER_TABLEACCESS_DENIED_ERROR
|
||||||
|
select count(row_start) from t1;
|
||||||
|
|
||||||
|
disconnect con1;
|
||||||
|
--source include/wait_until_disconnected.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo #Cleanup
|
||||||
|
--source include/wait_until_disconnected.inc
|
||||||
|
connection default;
|
||||||
|
drop user user_1;
|
||||||
|
drop database d;
|
@ -196,11 +196,12 @@ bool sp_rcontext::init_var_table(THD *thd,
|
|||||||
*/
|
*/
|
||||||
static inline bool
|
static inline bool
|
||||||
check_column_grant_for_type_ref(THD *thd, TABLE_LIST *table_list,
|
check_column_grant_for_type_ref(THD *thd, TABLE_LIST *table_list,
|
||||||
const char *str, size_t length)
|
const char *str, size_t length,
|
||||||
|
Field *fld)
|
||||||
{
|
{
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
table_list->table->grant.want_privilege= SELECT_ACL;
|
table_list->table->grant.want_privilege= SELECT_ACL;
|
||||||
return check_column_grant_in_table_ref(thd, table_list, str, length);
|
return check_column_grant_in_table_ref(thd, table_list, str, length, fld);
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
@ -238,7 +239,7 @@ bool Qualified_column_ident::resolve_type_ref(THD *thd, Column_definition *def)
|
|||||||
{
|
{
|
||||||
if (!(rc= check_column_grant_for_type_ref(thd, table_list,
|
if (!(rc= check_column_grant_for_type_ref(thd, table_list,
|
||||||
m_column.str,
|
m_column.str,
|
||||||
m_column.length)))
|
m_column.length, src)))
|
||||||
{
|
{
|
||||||
*def= Column_definition(thd, src, NULL/*No defaults,no constraints*/);
|
*def= Column_definition(thd, src, NULL/*No defaults,no constraints*/);
|
||||||
def->flags&= (uint) ~NOT_NULL_FLAG;
|
def->flags&= (uint) ~NOT_NULL_FLAG;
|
||||||
@ -302,7 +303,7 @@ bool Table_ident::resolve_table_rowtype_ref(THD *thd,
|
|||||||
LEX_CSTRING tmp= src[0]->field_name;
|
LEX_CSTRING tmp= src[0]->field_name;
|
||||||
Spvar_definition *def;
|
Spvar_definition *def;
|
||||||
if ((rc= check_column_grant_for_type_ref(thd, table_list,
|
if ((rc= check_column_grant_for_type_ref(thd, table_list,
|
||||||
tmp.str, tmp.length)) ||
|
tmp.str, tmp.length,src[0])) ||
|
||||||
(rc= !(src[0]->field_name.str= thd->strmake(tmp.str, tmp.length))) ||
|
(rc= !(src[0]->field_name.str= thd->strmake(tmp.str, tmp.length))) ||
|
||||||
(rc= !(def= new (thd->mem_root) Spvar_definition(thd, *src))))
|
(rc= !(def= new (thd->mem_root) Spvar_definition(thd, *src))))
|
||||||
break;
|
break;
|
||||||
|
@ -7782,6 +7782,8 @@ err:
|
|||||||
table_ref table reference where to check the field
|
table_ref table reference where to check the field
|
||||||
name name of field to check
|
name name of field to check
|
||||||
length length of name
|
length length of name
|
||||||
|
fld use fld object to check invisibility when it is
|
||||||
|
not 0, not_found_field, view_ref_found
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Check the access rights to a column depending on the type of table
|
Check the access rights to a column depending on the type of table
|
||||||
@ -7796,13 +7798,17 @@ err:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
|
bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
|
||||||
const char *name, size_t length)
|
const char *name, size_t length,
|
||||||
|
Field *fld)
|
||||||
{
|
{
|
||||||
GRANT_INFO *grant;
|
GRANT_INFO *grant;
|
||||||
const char *db_name;
|
const char *db_name;
|
||||||
const char *table_name;
|
const char *table_name;
|
||||||
Security_context *sctx= table_ref->security_ctx ?
|
Security_context *sctx= table_ref->security_ctx ?
|
||||||
table_ref->security_ctx : thd->security_ctx;
|
table_ref->security_ctx : thd->security_ctx;
|
||||||
|
if (fld && fld != not_found_field && fld != view_ref_found
|
||||||
|
&& fld->invisible >= INVISIBLE_SYSTEM)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (table_ref->view || table_ref->field_translation)
|
if (table_ref->view || table_ref->field_translation)
|
||||||
{
|
{
|
||||||
@ -7878,6 +7884,9 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
|
|||||||
|
|
||||||
for (; !fields->end_of_fields(); fields->next())
|
for (; !fields->end_of_fields(); fields->next())
|
||||||
{
|
{
|
||||||
|
if (fields->field() &&
|
||||||
|
fields->field()->invisible >= INVISIBLE_SYSTEM)
|
||||||
|
continue;
|
||||||
LEX_CSTRING *field_name= fields->name();
|
LEX_CSTRING *field_name= fields->name();
|
||||||
|
|
||||||
if (table_name != fields->get_table_name())
|
if (table_name != fields->get_table_name())
|
||||||
|
@ -239,7 +239,7 @@ bool check_grant_column (THD *thd, GRANT_INFO *grant,
|
|||||||
const char *db_name, const char *table_name,
|
const char *db_name, const char *table_name,
|
||||||
const char *name, size_t length, Security_context *sctx);
|
const char *name, size_t length, Security_context *sctx);
|
||||||
bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
|
bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
|
||||||
const char *name, size_t length);
|
const char *name, size_t length, Field *fld);
|
||||||
bool check_grant_all_columns(THD *thd, ulong want_access,
|
bool check_grant_all_columns(THD *thd, ulong want_access,
|
||||||
Field_iterator_table_ref *fields);
|
Field_iterator_table_ref *fields);
|
||||||
bool check_grant_routine(THD *thd, ulong want_access,
|
bool check_grant_routine(THD *thd, ulong want_access,
|
||||||
|
@ -5877,7 +5877,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
|||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
/* Check if there are sufficient access rights to the found field. */
|
/* Check if there are sufficient access rights to the found field. */
|
||||||
if (check_privileges &&
|
if (check_privileges &&
|
||||||
check_column_grant_in_table_ref(thd, *actual_table, name, length))
|
check_column_grant_in_table_ref(thd, *actual_table, name, length, fld))
|
||||||
fld= WRONG_GRANT;
|
fld= WRONG_GRANT;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -6054,7 +6054,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
|||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
/* Check if there are sufficient access rights to the found field. */
|
/* Check if there are sufficient access rights to the found field. */
|
||||||
if (found && check_privileges &&
|
if (found && check_privileges &&
|
||||||
check_column_grant_in_table_ref(thd, table_ref, name, length))
|
check_column_grant_in_table_ref(thd, table_ref, name, length, found))
|
||||||
found= WRONG_GRANT;
|
found= WRONG_GRANT;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user