[Commits] 326db1a: Mdev-14853 Grant does not work correctly when table contains...

sachin sachin.setiya at mariadb.com
Thu Apr 26 10:19:46 EEST 2018


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 at 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 at 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
     }


More information about the commits mailing list