From c77336c2607bb28236664205aec0f2e480cf24d8 Mon Sep 17 00:00:00 2001 From: "kroki@mysql.com" <> Date: Mon, 24 Apr 2006 18:06:43 +0400 Subject: [PATCH 1/6] Bug#16501: IS_USED_LOCK does not appear to work Update User_level_lock::thread_id on acquiring an existing lock, and reset it on lock release. --- mysql-test/r/func_misc.result | 36 +++++++++++++++++++++++++++++++++ mysql-test/t/func_misc.test | 38 +++++++++++++++++++++++++++++++++++ sql/item_func.cc | 2 ++ 3 files changed, 76 insertions(+) diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 181ecf7b65b..a5beef859f0 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -57,3 +57,39 @@ t1 CREATE TABLE `t1` ( `length(uuid())` int(10) NOT NULL default '0' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (conn CHAR(7), connection_id INT); +INSERT INTO t1 VALUES ('default', CONNECTION_ID()); +SELECT GET_LOCK('bug16501',600); +GET_LOCK('bug16501',600) +1 +INSERT INTO t1 VALUES ('con1', CONNECTION_ID()); +SELECT IS_USED_LOCK('bug16501') = connection_id +FROM t1 +WHERE conn = 'default'; +IS_USED_LOCK('bug16501') = connection_id +1 + SELECT GET_LOCK('bug16501',600); +SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID(); +IS_USED_LOCK('bug16501') = CONNECTION_ID() +1 +SELECT RELEASE_LOCK('bug16501'); +RELEASE_LOCK('bug16501') +1 +SELECT IS_USED_LOCK('bug16501') = connection_id +FROM t1 +WHERE conn = 'con1'; +IS_USED_LOCK('bug16501') = connection_id +1 +GET_LOCK('bug16501',600) +1 +SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID(); +IS_USED_LOCK('bug16501') = CONNECTION_ID() +1 +SELECT RELEASE_LOCK('bug16501'); +RELEASE_LOCK('bug16501') +1 +SELECT IS_USED_LOCK('bug16501'); +IS_USED_LOCK('bug16501') +NULL +DROP TABLE t1; diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 87d9d601c87..9c706161ba9 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -43,4 +43,42 @@ create table t1 as select uuid(), length(uuid()); show create table t1; drop table t1; + +# +# Bug#16501: IS_USED_LOCK does not appear to work +# +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (conn CHAR(7), connection_id INT); +INSERT INTO t1 VALUES ('default', CONNECTION_ID()); + +SELECT GET_LOCK('bug16501',600); + +connect (con1,localhost,root,,); +INSERT INTO t1 VALUES ('con1', CONNECTION_ID()); +SELECT IS_USED_LOCK('bug16501') = connection_id +FROM t1 +WHERE conn = 'default'; +send SELECT GET_LOCK('bug16501',600); + +connection default; +SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID(); +SELECT RELEASE_LOCK('bug16501'); +SELECT IS_USED_LOCK('bug16501') = connection_id +FROM t1 +WHERE conn = 'con1'; + +connection con1; +reap; +SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID(); +SELECT RELEASE_LOCK('bug16501'); +SELECT IS_USED_LOCK('bug16501'); + +disconnect con1; +connection default; + +DROP TABLE t1; + # End of 4.1 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index 174a8c55d01..1f170242113 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1972,6 +1972,7 @@ void item_user_lock_free(void) void item_user_lock_release(User_level_lock *ull) { ull->locked=0; + ull->thread_id= 0; if (mysql_bin_log.is_open()) { char buf[256]; @@ -2170,6 +2171,7 @@ longlong Item_func_get_lock::val_int() { ull->locked=1; ull->thread=thd->real_id; + ull->thread_id= thd->thread_id; thd->ull=ull; error=0; } From 9318ac9ae128fdb1f15eeca7cc5d7ea2ea18f3bc Mon Sep 17 00:00:00 2001 From: "kroki@mysql.com" <> Date: Thu, 27 Apr 2006 14:54:36 +0400 Subject: [PATCH 2/6] Bug#16372: Server crashes when test 'conc_sys' is running Concurrent read and update of privilege structures (like simultaneous run of SHOW GRANTS and ADD USER) could result in server crash. Ensure that proper locking of ACL structures is done. No test case is provided because this bug can't be reproduced deterministically. --- sql/sql_acl.cc | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 4626e5892a4..204a38dfb64 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -894,6 +894,8 @@ static void acl_update_user(const char *user, const char *host, USER_RESOURCES *mqh, ulong privileges) { + safe_mutex_assert_owner(&acl_cache->lock); + for (uint i=0 ; i < acl_users.elements ; i++) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); @@ -942,6 +944,9 @@ static void acl_insert_user(const char *user, const char *host, ulong privileges) { ACL_USER acl_user; + + safe_mutex_assert_owner(&acl_cache->lock); + acl_user.user=*user ? strdup_root(&mem,user) : 0; update_hostname(&acl_user.host, *host ? strdup_root(&mem, host): 0); acl_user.access=privileges; @@ -973,6 +978,8 @@ static void acl_insert_user(const char *user, const char *host, static void acl_update_db(const char *user, const char *host, const char *db, ulong privileges) { + safe_mutex_assert_owner(&acl_cache->lock); + for (uint i=0 ; i < acl_dbs.elements ; i++) { ACL_DB *acl_db=dynamic_element(&acl_dbs,i,ACL_DB*); @@ -1358,6 +1365,9 @@ find_acl_user(const char *host, const char *user, my_bool exact) { DBUG_ENTER("find_acl_user"); DBUG_PRINT("enter",("host: '%s' user: '%s'",host,user)); + + safe_mutex_assert_owner(&acl_cache->lock); + for (uint i=0 ; i < acl_users.elements ; i++) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); @@ -1370,7 +1380,7 @@ find_acl_user(const char *host, const char *user, my_bool exact) if (!acl_user->user && !user[0] || acl_user->user && !strcmp(user,acl_user->user)) { - if (exact ? !my_strcasecmp(&my_charset_latin1, host, + if (exact ? !my_strcasecmp(system_charset_info, host, acl_user->host.hostname ? acl_user->host.hostname : "") : compare_hostname(&acl_user->host,host,host)) @@ -2445,6 +2455,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, create_new_users= test_if_create_new_users(thd); int result=0; rw_wrlock(&LOCK_grant); + pthread_mutex_lock(&acl_cache->lock); MEM_ROOT *old_root= thd->mem_root; thd->mem_root= &memex; @@ -2460,10 +2471,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, continue; } /* Create user if needed */ - pthread_mutex_lock(&acl_cache->lock); error=replace_user_table(thd, tables[0].table, *Str, 0, revoke_grant, create_new_users); - pthread_mutex_unlock(&acl_cache->lock); if (error) { result= -1; // Remember error @@ -2552,6 +2561,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, } grant_option=TRUE; thd->mem_root= old_root; + pthread_mutex_unlock(&acl_cache->lock); rw_unlock(&LOCK_grant); if (!result) send_ok(thd); @@ -3203,6 +3213,9 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) DBUG_RETURN(-1); } + rw_rdlock(&LOCK_grant); + VOID(pthread_mutex_lock(&acl_cache->lock)); + for (counter=0 ; counter < acl_users.elements ; counter++) { const char *user,*host; @@ -3217,6 +3230,9 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) } if (counter == acl_users.elements) { + VOID(pthread_mutex_unlock(&acl_cache->lock)); + rw_unlock(&LOCK_grant); + my_error(ER_NONEXISTING_GRANT, MYF(0), lex_user->user.str, lex_user->host.str); DBUG_RETURN(-1); @@ -3230,10 +3246,12 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) lex_user->host.str,NullS); field_list.push_back(field); if (protocol->send_fields(&field_list,1)) - DBUG_RETURN(-1); + { + VOID(pthread_mutex_unlock(&acl_cache->lock)); + rw_unlock(&LOCK_grant); - rw_wrlock(&LOCK_grant); - VOID(pthread_mutex_lock(&acl_cache->lock)); + DBUG_RETURN(-1); + } /* Add first global access grants */ { @@ -3540,10 +3558,15 @@ void get_privilege_desc(char *to, uint max_length, ulong access) void get_mqh(const char *user, const char *host, USER_CONN *uc) { ACL_USER *acl_user; + + pthread_mutex_lock(&acl_cache->lock); + if (initialized && (acl_user= find_acl_user(host,user, FALSE))) uc->user_resources= acl_user->user_resource; else bzero((char*) &uc->user_resources, sizeof(uc->user_resources)); + + pthread_mutex_unlock(&acl_cache->lock); } int open_grant_tables(THD *thd, TABLE_LIST *tables) @@ -3602,6 +3625,8 @@ ACL_USER *check_acl_user(LEX_USER *user_name, ACL_USER *acl_user= 0; uint counter; + safe_mutex_assert_owner(&acl_cache->lock); + for (counter= 0 ; counter < acl_users.elements ; counter++) { const char *user,*host; From 2842d28d148252036c02c6e3efff47313e65da0d Mon Sep 17 00:00:00 2001 From: "paul@polar.kitebird.com" <> Date: Thu, 4 May 2006 16:14:19 -0500 Subject: [PATCH 3/6] .del-changelog-4.0.xml~8f56ee8a913e848b: Delete: Docs/changelog-4.0.xml --- Docs/changelog-4.0.xml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100755 Docs/changelog-4.0.xml diff --git a/Docs/changelog-4.0.xml b/Docs/changelog-4.0.xml deleted file mode 100755 index f0f9aa881f1..00000000000 --- a/Docs/changelog-4.0.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - Changes in release 4.0.x - - - - This is a dummy changelog file. Don't use it yet. - - - From a1e6218461418e885540db5093d63043ad291ad9 Mon Sep 17 00:00:00 2001 From: "paul@polar.kitebird.com" <> Date: Thu, 4 May 2006 16:16:18 -0500 Subject: [PATCH 4/6] .del-changelog-4.1.xml~8aa496ebed09d868: Delete: Docs/changelog-4.1.xml --- Docs/changelog-4.1.xml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100755 Docs/changelog-4.1.xml diff --git a/Docs/changelog-4.1.xml b/Docs/changelog-4.1.xml deleted file mode 100755 index 644f2940d0f..00000000000 --- a/Docs/changelog-4.1.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - Changes in release 4.1.x - - - - This is a dummy changelog file. Don't use it yet. - - - From 3ad0cac41b3239940221f6e886b200d5f8b06eca Mon Sep 17 00:00:00 2001 From: "kroki@mysql.com" <> Date: Sat, 6 May 2006 11:25:59 +0400 Subject: [PATCH 5/6] Reapply fix for bug#16372 (Server crashes when test 'conc_sys' is running) after merge. Concurrent read and update of privilege structures (like simultaneous run of SHOW GRANTS and ADD USER) could result in server crash. Ensure that proper locking of ACL structures is done. No test case is provided because this bug can't be reproduced deterministically. --- sql/sql_acl.cc | 108 ++++++++++++++++++++++++++--------------------- sql/sql_acl.h | 1 - sql/sql_parse.cc | 4 +- 3 files changed, 63 insertions(+), 50 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d66a631dbcc..ec1caba0b5d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1027,6 +1027,8 @@ static void acl_update_user(const char *user, const char *host, USER_RESOURCES *mqh, ulong privileges) { + safe_mutex_assert_owner(&acl_cache->lock); + for (uint i=0 ; i < acl_users.elements ; i++) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); @@ -1077,6 +1079,9 @@ static void acl_insert_user(const char *user, const char *host, ulong privileges) { ACL_USER acl_user; + + safe_mutex_assert_owner(&acl_cache->lock); + acl_user.user=*user ? strdup_root(&mem,user) : 0; update_hostname(&acl_user.host, *host ? strdup_root(&mem, host): 0); acl_user.access=privileges; @@ -1106,6 +1111,8 @@ static void acl_insert_user(const char *user, const char *host, static void acl_update_db(const char *user, const char *host, const char *db, ulong privileges) { + safe_mutex_assert_owner(&acl_cache->lock); + for (uint i=0 ; i < acl_dbs.elements ; i++) { ACL_DB *acl_db=dynamic_element(&acl_dbs,i,ACL_DB*); @@ -1532,6 +1539,9 @@ find_acl_user(const char *host, const char *user, my_bool exact) { DBUG_ENTER("find_acl_user"); DBUG_PRINT("enter",("host: '%s' user: '%s'",host,user)); + + safe_mutex_assert_owner(&acl_cache->lock); + for (uint i=0 ; i < acl_users.elements ; i++) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); @@ -1544,7 +1554,7 @@ find_acl_user(const char *host, const char *user, my_bool exact) if (!acl_user->user && !user[0] || acl_user->user && !strcmp(user,acl_user->user)) { - if (exact ? !my_strcasecmp(&my_charset_latin1, host, + if (exact ? !my_strcasecmp(system_charset_info, host, acl_user->host.hostname ? acl_user->host.hostname : "") : compare_hostname(&acl_user->host,host,host)) @@ -2868,6 +2878,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, create_new_users= test_if_create_new_users(thd); bool result= FALSE; rw_wrlock(&LOCK_grant); + pthread_mutex_lock(&acl_cache->lock); MEM_ROOT *old_root= thd->mem_root; thd->mem_root= &memex; grant_version++; @@ -2885,12 +2896,10 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, continue; } /* Create user if needed */ - pthread_mutex_lock(&acl_cache->lock); error=replace_user_table(thd, tables[0].table, *Str, 0, revoke_grant, create_new_users, test(thd->variables.sql_mode & MODE_NO_AUTO_CREATE_USER)); - pthread_mutex_unlock(&acl_cache->lock); if (error) { result= TRUE; // Remember error @@ -2982,6 +2991,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, } grant_option=TRUE; thd->mem_root= old_root; + pthread_mutex_unlock(&acl_cache->lock); rw_unlock(&LOCK_grant); if (!result) send_ok(thd); @@ -3074,6 +3084,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, if (!revoke_grant) create_new_users= test_if_create_new_users(thd); rw_wrlock(&LOCK_grant); + pthread_mutex_lock(&acl_cache->lock); MEM_ROOT *old_root= thd->mem_root; thd->mem_root= &memex; @@ -3093,12 +3104,10 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, continue; } /* Create user if needed */ - pthread_mutex_lock(&acl_cache->lock); error=replace_user_table(thd, tables[0].table, *Str, 0, revoke_grant, create_new_users, test(thd->variables.sql_mode & MODE_NO_AUTO_CREATE_USER)); - pthread_mutex_unlock(&acl_cache->lock); if (error) { result= TRUE; // Remember error @@ -3140,6 +3149,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, } grant_option=TRUE; thd->mem_root= old_root; + pthread_mutex_unlock(&acl_cache->lock); rw_unlock(&LOCK_grant); if (!result && !no_error) send_ok(thd); @@ -4116,20 +4126,15 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) DBUG_RETURN(TRUE); } - for (counter=0 ; counter < acl_users.elements ; counter++) - { - const char *user,*host; - acl_user=dynamic_element(&acl_users,counter,ACL_USER*); - if (!(user=acl_user->user)) - user= ""; - if (!(host=acl_user->host.hostname)) - host= ""; - if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(system_charset_info, lex_user->host.str, host)) - break; - } - if (counter == acl_users.elements) + rw_rdlock(&LOCK_grant); + VOID(pthread_mutex_lock(&acl_cache->lock)); + + acl_user= find_acl_user(lex_user->host.str, lex_user->user.str, TRUE); + if (!acl_user) { + VOID(pthread_mutex_unlock(&acl_cache->lock)); + rw_unlock(&LOCK_grant); + my_error(ER_NONEXISTING_GRANT, MYF(0), lex_user->user.str, lex_user->host.str); DBUG_RETURN(TRUE); @@ -4144,10 +4149,12 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) field_list.push_back(field); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(TRUE); + { + VOID(pthread_mutex_unlock(&acl_cache->lock)); + rw_unlock(&LOCK_grant); - rw_wrlock(&LOCK_grant); - VOID(pthread_mutex_lock(&acl_cache->lock)); + DBUG_RETURN(TRUE); + } /* Add first global access grants */ { @@ -4555,10 +4562,15 @@ void get_privilege_desc(char *to, uint max_length, ulong access) void get_mqh(const char *user, const char *host, USER_CONN *uc) { ACL_USER *acl_user; + + pthread_mutex_lock(&acl_cache->lock); + if (initialized && (acl_user= find_acl_user(host,user, FALSE))) uc->user_resources= acl_user->user_resource; else bzero((char*) &uc->user_resources, sizeof(uc->user_resources)); + + pthread_mutex_unlock(&acl_cache->lock); } /* @@ -4638,31 +4650,6 @@ int open_grant_tables(THD *thd, TABLE_LIST *tables) DBUG_RETURN(0); } -ACL_USER *check_acl_user(LEX_USER *user_name, - uint *acl_acl_userdx) -{ - ACL_USER *acl_user= 0; - uint counter; - - for (counter= 0 ; counter < acl_users.elements ; counter++) - { - const char *user,*host; - acl_user= dynamic_element(&acl_users, counter, ACL_USER*); - if (!(user=acl_user->user)) - user= ""; - if (!(host=acl_user->host.hostname)) - host= ""; - if (!strcmp(user_name->user.str,user) && - !my_strcasecmp(system_charset_info, user_name->host.str, host)) - break; - } - if (counter == acl_users.elements) - return 0; - - *acl_acl_userdx= counter; - return acl_user; -} - /* Modify a privilege table. @@ -4907,6 +4894,8 @@ static int handle_grant_struct(uint struct_no, bool drop, LINT_INIT(acl_db); LINT_INIT(grant_name); + safe_mutex_assert_owner(&acl_cache->lock); + /* Get the number of elements in the in-memory structure. */ switch (struct_no) { case 0: @@ -5370,7 +5359,7 @@ bool mysql_revoke_all(THD *thd, List &list) List_iterator user_list(list); while ((lex_user=user_list++)) { - if (!check_acl_user(lex_user, &counter)) + if (!find_acl_user(lex_user->host.str, lex_user->user.str, TRUE)) { sql_print_error("REVOKE ALL PRIVILEGES, GRANT: User '%s'@'%s' does not " "exists", lex_user->user.str, lex_user->host.str); @@ -5606,6 +5595,7 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, combo->user.str= sctx->user; + VOID(pthread_mutex_lock(&acl_cache->lock)); if (!find_acl_user(combo->host.str=(char*)sctx->host_or_ip, combo->user.str, FALSE) && !find_acl_user(combo->host.str=(char*)sctx->host, combo->user.str, @@ -5613,7 +5603,11 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, !find_acl_user(combo->host.str=(char*)sctx->ip, combo->user.str, FALSE) && !find_acl_user(combo->host.str=(char*)"%", combo->user.str, FALSE)) + { + VOID(pthread_mutex_unlock(&acl_cache->lock)); DBUG_RETURN(TRUE); + } + VOID(pthread_mutex_unlock(&acl_cache->lock)); bzero((char*)tables, sizeof(TABLE_LIST)); user_list.empty(); @@ -5731,6 +5725,8 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) char *curr_host= thd->security_ctx->priv_host_name(); DBUG_ENTER("fill_schema_user_privileges"); + pthread_mutex_lock(&acl_cache->lock); + for (counter=0 ; counter < acl_users.elements ; counter++) { const char *user,*host, *is_grantable="YES"; @@ -5766,6 +5762,9 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) } } } + + pthread_mutex_unlock(&acl_cache->lock); + DBUG_RETURN(0); #else return(0); @@ -5785,6 +5784,8 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) char *curr_host= thd->security_ctx->priv_host_name(); DBUG_ENTER("fill_schema_schema_privileges"); + pthread_mutex_lock(&acl_cache->lock); + for (counter=0 ; counter < acl_dbs.elements ; counter++) { const char *user, *host, *is_grantable="YES"; @@ -5823,6 +5824,9 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) } } } + + pthread_mutex_unlock(&acl_cache->lock); + DBUG_RETURN(0); #else return (0); @@ -5840,6 +5844,8 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) char *curr_host= thd->security_ctx->priv_host_name(); DBUG_ENTER("fill_schema_table_privileges"); + rw_rdlock(&LOCK_grant); + for (index=0 ; index < column_priv_hash.records ; index++) { const char *user, *is_grantable= "YES"; @@ -5885,6 +5891,9 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) } } } + + rw_unlock(&LOCK_grant); + DBUG_RETURN(0); #else return (0); @@ -5902,6 +5911,8 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) char *curr_host= thd->security_ctx->priv_host_name(); DBUG_ENTER("fill_schema_table_privileges"); + rw_rdlock(&LOCK_grant); + for (index=0 ; index < column_priv_hash.records ; index++) { const char *user, *is_grantable= "YES"; @@ -5953,6 +5964,9 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) } } } + + rw_unlock(&LOCK_grant); + DBUG_RETURN(0); #else return (0); diff --git a/sql/sql_acl.h b/sql/sql_acl.h index c8fadb73b0c..e1737f79ce7 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -196,7 +196,6 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table, List &user_list, bool mysql_routine_grant(THD *thd, TABLE_LIST *table, bool is_proc, List &user_list, ulong rights, bool revoke, bool no_error); -ACL_USER *check_acl_user(LEX_USER *user_name, uint *acl_acl_userdx); my_bool grant_init(); void grant_free(void); my_bool grant_reload(THD *thd); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 196e723299a..a8de7ff0154 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3835,7 +3835,6 @@ end_with_restore_list: if (thd->security_ctx->user) // If not replication { LEX_USER *user; - uint counter; List_iterator user_list(lex->users_list); while ((user= user_list++)) @@ -3853,7 +3852,8 @@ end_with_restore_list: user->host.str, thd->security_ctx->host_or_ip)) { // TODO: use check_change_password() - if (check_acl_user(user, &counter) && user->password.str && + if (is_acl_user(user->host.str, user->user.str) && + user->password.str && check_access(thd, UPDATE_ACL,"mysql",0,1,1,0)) { my_message(ER_PASSWORD_NOT_ALLOWED, From bf9ccde948d07aaaec0e78f67ed981071056e550 Mon Sep 17 00:00:00 2001 From: "kroki@mysql.com" <> Date: Sat, 6 May 2006 18:24:41 +0400 Subject: [PATCH 6/6] Fix race condition in the test for bug#16501. --- mysql-test/r/func_misc.result | 4 ++-- mysql-test/t/func_misc.test | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index a5beef859f0..8bcdd8b7cbc 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -76,13 +76,13 @@ IS_USED_LOCK('bug16501') = CONNECTION_ID() SELECT RELEASE_LOCK('bug16501'); RELEASE_LOCK('bug16501') 1 +GET_LOCK('bug16501',600) +1 SELECT IS_USED_LOCK('bug16501') = connection_id FROM t1 WHERE conn = 'con1'; IS_USED_LOCK('bug16501') = connection_id 1 -GET_LOCK('bug16501',600) -1 SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID(); IS_USED_LOCK('bug16501') = CONNECTION_ID() 1 diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 9c706161ba9..e2641f8d6cd 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -66,12 +66,14 @@ send SELECT GET_LOCK('bug16501',600); connection default; SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID(); SELECT RELEASE_LOCK('bug16501'); +connection con1; +reap; +connection default; SELECT IS_USED_LOCK('bug16501') = connection_id FROM t1 WHERE conn = 'con1'; connection con1; -reap; SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID(); SELECT RELEASE_LOCK('bug16501'); SELECT IS_USED_LOCK('bug16501');