Re: [Maria-developers] [Commits] 326db1a: Mdev-14853 Grant does not work correctly when table contains...
Hi Sachin! Did you run this test on embedded server? Usually grant related tests require some form of not_embedded.inc include. (check roles suite for examples) Vicentiu On Thu, 26 Apr 2018 at 00:20 sachin <sachin.setiya@mariadb.com> wrote:
revision-id: 326db1a2aaa9b275a1a21a863e8cd2d9fa1b1d5f (mariadb-10.3.6-46-g326db1a) parent(s): 9477a2a9ba17c0db362e2bb39d5048e369096f39 author: Sachin Setiya committer: Sachin Setiya timestamp: 2018-04-26 12:47:25 +0530 message:
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.
--- mysql-test/main/invisible_field_grant.result | 111 +++++++++++++++++++++++++++ mysql-test/main/invisible_field_grant.test | 77 +++++++++++++++++++ sql/sp_rcontext.cc | 9 ++- sql/sql_acl.cc | 11 ++- sql/sql_acl.h | 2 +- sql/sql_base.cc | 4 +- 6 files changed, 206 insertions(+), 8 deletions(-)
diff --git a/mysql-test/main/invisible_field_grant.result b/mysql-test/main/invisible_field_grant.result new file mode 100644 index 0000000..c3ccbb1 --- /dev/null +++ b/mysql-test/main/invisible_field_grant.result @@ -0,0 +1,111 @@ +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; + +#System_Invisible +set debug_dbug= "+d,test_pseudo_invisible"; +create table t1(a int); +set debug_dbug=@old_debug; +insert into t1 values(1); +select a,invisible from t1; +a invisible +1 9 +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; +invisible a +9 1 +9 2 +9 3 +delete from t1 where a =1; +update t1 set a=1 where a=3; +select * from t1; +a +2 +1 +disconnect con1; + +#Cleanup +connection default; +drop table t1; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1; + +#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 +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; diff --git a/mysql-test/main/invisible_field_grant.test b/mysql-test/main/invisible_field_grant.test new file mode 100644 index 0000000..0d627e5 --- /dev/null +++ b/mysql-test/main/invisible_field_grant.test @@ -0,0 +1,77 @@ +--source include/have_debug.inc +##TEST for invisible coloumn level 2 +set @old_debug= @@debug_dbug; +create user user_1; +show grants for user_1; +--echo # create user +create database d; +use d; + +--echo +--echo #System_Invisible +set debug_dbug= "+d,test_pseudo_invisible"; +create table t1(a int); +set debug_dbug=@old_debug; +insert into t1 values(1); +select a,invisible 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 invisible,a from t1; +delete from t1 where a =1; +update t1 set a=1 where a=3; +select * from t1; +disconnect con1; +--source include/wait_until_disconnected.inc + +--echo +--echo #Cleanup +--connection default +drop table t1; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1; + +--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; +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; diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 2e9ae23..dc103fa 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -196,11 +196,12 @@ bool sp_rcontext::init_var_table(THD *thd, */ static inline bool 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 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 return false; #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, m_column.str, - m_column.length))) + m_column.length, src))) { *def= Column_definition(thd, src, NULL/*No defaults,no constraints*/); 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; Spvar_definition *def; 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= !(def= new (thd->mem_root) Spvar_definition(thd, *src)))) break; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index de4e201..1c154a1 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7775,6 +7775,8 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant, table_ref table reference where to check the field name name of field to check length length of name + fld use fld object to check invisibility when it is + not 0, not_found_field, view_ref_found
DESCRIPTION Check the access rights to a column depending on the type of table @@ -7789,13 +7791,17 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant, */
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; const char *db_name; const char *table_name; Security_context *sctx= table_ref->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) { @@ -7871,6 +7877,9 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
for (; !fields->end_of_fields(); fields->next()) { + if (fields->field() && + fields->field()->invisible >= INVISIBLE_SYSTEM) + continue; LEX_CSTRING *field_name= fields->name();
if (table_name != fields->get_table_name()) diff --git a/sql/sql_acl.h b/sql/sql_acl.h index a608ef0..6da7d4d 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -239,7 +239,7 @@ bool check_grant_column (THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, const char *name, size_t length, Security_context *sctx); 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, Field_iterator_table_ref *fields); bool check_grant_routine(THD *thd, ulong want_access, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0081365..383341c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5880,7 +5880,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check if there are sufficient access rights to the found field. */ 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; else #endif @@ -6057,7 +6057,7 @@ find_field_in_tables(THD *thd, Item_ident *item, #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check if there are sufficient access rights to the found field. */ 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; #endif } _______________________________________________ commits mailing list commits@mariadb.org https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits
Hi Vicentiu, Now, I have run test with embedded mysql server and it passes. May be embedded server does not support advance feature of grant like roles , I dont know. Thanks sachin On Thu, Apr 26, 2018 at 5:39 PM, Vicențiu Ciorbaru <cvicentiu@gmail.com> wrote:
Hi Sachin!
Did you run this test on embedded server? Usually grant related tests require some form of not_embedded.inc include. (check roles suite for examples)
Vicentiu
On Thu, 26 Apr 2018 at 00:20 sachin <sachin.setiya@mariadb.com> wrote:
revision-id: 326db1a2aaa9b275a1a21a863e8cd2d9fa1b1d5f (mariadb-10.3.6-46-g326db1a) parent(s): 9477a2a9ba17c0db362e2bb39d5048e369096f39 author: Sachin Setiya committer: Sachin Setiya timestamp: 2018-04-26 12:47:25 +0530 message:
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.
--- mysql-test/main/invisible_field_grant.result | 111 +++++++++++++++++++++++++++ mysql-test/main/invisible_field_grant.test | 77 +++++++++++++++++++ sql/sp_rcontext.cc | 9 ++- sql/sql_acl.cc | 11 ++- sql/sql_acl.h | 2 +- sql/sql_base.cc | 4 +- 6 files changed, 206 insertions(+), 8 deletions(-)
diff --git a/mysql-test/main/invisible_field_grant.result b/mysql-test/main/invisible_field_grant.result new file mode 100644 index 0000000..c3ccbb1 --- /dev/null +++ b/mysql-test/main/invisible_field_grant.result @@ -0,0 +1,111 @@ +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; + +#System_Invisible +set debug_dbug= "+d,test_pseudo_invisible"; +create table t1(a int); +set debug_dbug=@old_debug; +insert into t1 values(1); +select a,invisible from t1; +a invisible +1 9 +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; +invisible a +9 1 +9 2 +9 3 +delete from t1 where a =1; +update t1 set a=1 where a=3; +select * from t1; +a +2 +1 +disconnect con1; + +#Cleanup +connection default; +drop table t1; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1; + +#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 +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; diff --git a/mysql-test/main/invisible_field_grant.test b/mysql-test/main/invisible_field_grant.test new file mode 100644 index 0000000..0d627e5 --- /dev/null +++ b/mysql-test/main/invisible_field_grant.test @@ -0,0 +1,77 @@ +--source include/have_debug.inc +##TEST for invisible coloumn level 2 +set @old_debug= @@debug_dbug; +create user user_1; +show grants for user_1; +--echo # create user +create database d; +use d; + +--echo +--echo #System_Invisible +set debug_dbug= "+d,test_pseudo_invisible"; +create table t1(a int); +set debug_dbug=@old_debug; +insert into t1 values(1); +select a,invisible 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 invisible,a from t1; +delete from t1 where a =1; +update t1 set a=1 where a=3; +select * from t1; +disconnect con1; +--source include/wait_until_disconnected.inc + +--echo +--echo #Cleanup +--connection default +drop table t1; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1; + +--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; +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; diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 2e9ae23..dc103fa 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -196,11 +196,12 @@ bool sp_rcontext::init_var_table(THD *thd, */ static inline bool 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 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 return false; #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, m_column.str, - m_column.length))) + m_column.length, src))) { *def= Column_definition(thd, src, NULL/*No defaults,no constraints*/); 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; Spvar_definition *def; 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= !(def= new (thd->mem_root) Spvar_definition(thd, *src)))) break; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index de4e201..1c154a1 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7775,6 +7775,8 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant, table_ref table reference where to check the field name name of field to check length length of name + fld use fld object to check invisibility when it is + not 0, not_found_field, view_ref_found
DESCRIPTION Check the access rights to a column depending on the type of table @@ -7789,13 +7791,17 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant, */
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; const char *db_name; const char *table_name; Security_context *sctx= table_ref->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) { @@ -7871,6 +7877,9 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
for (; !fields->end_of_fields(); fields->next()) { + if (fields->field() && + fields->field()->invisible >= INVISIBLE_SYSTEM) + continue; LEX_CSTRING *field_name= fields->name();
if (table_name != fields->get_table_name()) diff --git a/sql/sql_acl.h b/sql/sql_acl.h index a608ef0..6da7d4d 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -239,7 +239,7 @@ bool check_grant_column (THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, const char *name, size_t length, Security_context *sctx); 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, Field_iterator_table_ref *fields); bool check_grant_routine(THD *thd, ulong want_access, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0081365..383341c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5880,7 +5880,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check if there are sufficient access rights to the found field. */ 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; else #endif @@ -6057,7 +6057,7 @@ find_field_in_tables(THD *thd, Item_ident *item, #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check if there are sufficient access rights to the found field. */ 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; #endif } _______________________________________________ commits mailing list commits@mariadb.org https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits
-- Regards Sachin Setiya Software Engineer at MariaDB
participants (2)
-
Sachin Setiya
-
Vicențiu Ciorbaru