@@ -4871,6 +4871,7 @@ static my_bool grant_load(THD *thd, TABLE_LIST *tables)
4871
4871
exists.
4872
4872
4873
4873
@param thd A pointer to the thread handler object.
4874
+ @param table A pointer to the table list.
4874
4875
4875
4876
@see grant_reload
4876
4877
@@ -4879,31 +4880,22 @@ static my_bool grant_load(THD *thd, TABLE_LIST *tables)
4879
4880
@retval TRUE An error has occurred.
4880
4881
*/
4881
4882
4882
- static my_bool grant_reload_procs_priv (THD *thd)
4883
+ static my_bool grant_reload_procs_priv (THD *thd, TABLE_LIST *table )
4883
4884
{
4884
4885
HASH old_proc_priv_hash, old_func_priv_hash;
4885
- TABLE_LIST table;
4886
4886
my_bool return_val= FALSE ;
4887
4887
DBUG_ENTER (" grant_reload_procs_priv" );
4888
4888
4889
- table.init_one_table (" mysql" , 5 , " procs_priv" ,
4890
- strlen (" procs_priv" ), " procs_priv" ,
4891
- TL_READ);
4892
- table.open_type = OT_BASE_ONLY;
4893
-
4894
- if (open_and_lock_tables (thd, &table, FALSE , MYSQL_LOCK_IGNORE_TIMEOUT))
4895
- DBUG_RETURN (TRUE );
4896
-
4897
- mysql_rwlock_wrlock (&LOCK_grant);
4898
4889
/* Save a copy of the current hash if we need to undo the grant load */
4899
4890
old_proc_priv_hash= proc_priv_hash;
4900
4891
old_func_priv_hash= func_priv_hash;
4901
4892
4902
- if ((return_val= grant_load_procs_priv (table. table )))
4893
+ if ((return_val= grant_load_procs_priv (table-> table )))
4903
4894
{
4904
4895
/* Error; Reverting to old hash */
4905
4896
DBUG_PRINT (" error" ,(" Reverting to old privileges" ));
4906
- grant_free ();
4897
+ my_hash_free (&proc_priv_hash);
4898
+ my_hash_free (&func_priv_hash);
4907
4899
proc_priv_hash= old_proc_priv_hash;
4908
4900
func_priv_hash= old_func_priv_hash;
4909
4901
}
@@ -4912,9 +4904,7 @@ static my_bool grant_reload_procs_priv(THD *thd)
4912
4904
my_hash_free (&old_proc_priv_hash);
4913
4905
my_hash_free (&old_func_priv_hash);
4914
4906
}
4915
- mysql_rwlock_unlock (&LOCK_grant);
4916
4907
4917
- close_mysql_tables (thd);
4918
4908
DBUG_RETURN (return_val);
4919
4909
}
4920
4910
@@ -4936,7 +4926,7 @@ static my_bool grant_reload_procs_priv(THD *thd)
4936
4926
4937
4927
my_bool grant_reload (THD *thd)
4938
4928
{
4939
- TABLE_LIST tables[2 ];
4929
+ TABLE_LIST tables[3 ];
4940
4930
HASH old_column_priv_hash;
4941
4931
MEM_ROOT old_mem;
4942
4932
my_bool return_val= 1 ;
@@ -4952,15 +4942,57 @@ my_bool grant_reload(THD *thd)
4952
4942
tables[1 ].init_one_table (C_STRING_WITH_LEN (" mysql" ),
4953
4943
C_STRING_WITH_LEN (" columns_priv" ),
4954
4944
" columns_priv" , TL_READ);
4945
+ tables[2 ].init_one_table (C_STRING_WITH_LEN (" mysql" ),
4946
+ C_STRING_WITH_LEN (" procs_priv" ),
4947
+ " procs_priv" , TL_READ);
4948
+
4955
4949
tables[0 ].next_local = tables[0 ].next_global = tables+1 ;
4956
- tables[0 ].open_type = tables[1 ].open_type = OT_BASE_ONLY;
4950
+ tables[1 ].next_local = tables[1 ].next_global = tables+2 ;
4951
+ tables[0 ].open_type = tables[1 ].open_type = tables[2 ].open_type = OT_BASE_ONLY;
4952
+
4953
+ /*
4954
+ Reload will work in the following manner:-
4955
+
4956
+ proc_priv_hash structure
4957
+ / \
4958
+ not initialized initialized
4959
+ / \ |
4960
+ mysql.procs_priv table Server Startup |
4961
+ is missing \ |
4962
+ | open_and_lock_tables()
4963
+ Assume we are working on /success \failure
4964
+ pre 4.1 system tables. Normal Scenario. An error is thrown.
4965
+ A warning is printed Reload column privilege. Retain the old hash.
4966
+ and continue with Reload function and
4967
+ reloading the column procedure privileges,
4968
+ privileges. if available.
4969
+ */
4970
+
4971
+ if (!(my_hash_inited (&proc_priv_hash)))
4972
+ tables[2 ].open_strategy = TABLE_LIST::OPEN_IF_EXISTS;
4957
4973
4958
4974
/*
4959
4975
To avoid deadlocks we should obtain table locks before
4960
4976
obtaining LOCK_grant rwlock.
4961
4977
*/
4962
4978
if (open_and_lock_tables (thd, tables, FALSE , MYSQL_LOCK_IGNORE_TIMEOUT))
4979
+ {
4980
+ if (thd->stmt_da ->is_error ())
4981
+ {
4982
+ sql_print_error (" Fatal error: Can't open and lock privilege tables: %s" ,
4983
+ thd->stmt_da ->message ());
4984
+ }
4963
4985
goto end;
4986
+ }
4987
+
4988
+ if (tables[2 ].table == NULL )
4989
+ {
4990
+ sql_print_warning (" Table 'mysql.procs_priv' does not exist. "
4991
+ " Please run mysql_upgrade." );
4992
+ push_warning_printf (thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NO_SUCH_TABLE,
4993
+ ER (ER_NO_SUCH_TABLE), tables[2 ].db ,
4994
+ tables[2 ].table_name );
4995
+ }
4964
4996
4965
4997
mysql_rwlock_wrlock (&LOCK_grant);
4966
4998
old_column_priv_hash= column_priv_hash;
@@ -4972,33 +5004,31 @@ my_bool grant_reload(THD *thd)
4972
5004
old_mem= memex;
4973
5005
init_sql_alloc (&memex, ACL_ALLOC_BLOCK_SIZE, 0 );
4974
5006
4975
- if ((return_val= grant_load (thd, tables)))
5007
+ /*
5008
+ tables[2].table i.e. procs_priv can be null if we are working with
5009
+ pre 4.1 privilage tables
5010
+ */
5011
+ if ((return_val= (grant_load (thd, tables) ||
5012
+ (tables[2 ].table != NULL &&
5013
+ grant_reload_procs_priv (thd, &tables[2 ])))
5014
+ ))
4976
5015
{ // Error. Revert to old hash
4977
5016
DBUG_PRINT (" error" ,(" Reverting to old privileges" ));
4978
- grant_free (); /* purecov: deadcode */
5017
+ my_hash_free (&column_priv_hash);
5018
+ free_root (&memex,MYF (0 ));
4979
5019
column_priv_hash= old_column_priv_hash; /* purecov: deadcode */
4980
5020
memex= old_mem; /* purecov: deadcode */
4981
5021
}
4982
5022
else
4983
5023
{
4984
5024
my_hash_free (&old_column_priv_hash);
4985
5025
free_root (&old_mem,MYF (0 ));
5026
+ grant_version++;
4986
5027
}
4987
5028
mysql_rwlock_unlock (&LOCK_grant);
4988
- close_mysql_tables (thd);
4989
-
4990
- /*
4991
- It is OK failing to load procs_priv table because we may be
4992
- working with 4.1 privilege tables.
4993
- */
4994
- if (grant_reload_procs_priv (thd))
4995
- return_val= 1 ;
4996
-
4997
- mysql_rwlock_wrlock (&LOCK_grant);
4998
- grant_version++;
4999
- mysql_rwlock_unlock (&LOCK_grant);
5000
5029
5001
5030
end:
5031
+ close_mysql_tables (thd);
5002
5032
DBUG_RETURN (return_val);
5003
5033
}
5004
5034
0 commit comments