#include "slave.h"Include dependency graph for sql_acl.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
Classes | |
| struct | acl_host_and_ip |
| class | ACL_ACCESS |
| class | ACL_HOST |
| class | ACL_USER |
| class | ACL_DB |
Defines | |
| #define | SELECT_ACL (1L << 0) |
| #define | INSERT_ACL (1L << 1) |
| #define | UPDATE_ACL (1L << 2) |
| #define | DELETE_ACL (1L << 3) |
| #define | CREATE_ACL (1L << 4) |
| #define | DROP_ACL (1L << 5) |
| #define | RELOAD_ACL (1L << 6) |
| #define | SHUTDOWN_ACL (1L << 7) |
| #define | PROCESS_ACL (1L << 8) |
| #define | FILE_ACL (1L << 9) |
| #define | GRANT_ACL (1L << 10) |
| #define | REFERENCES_ACL (1L << 11) |
| #define | INDEX_ACL (1L << 12) |
| #define | ALTER_ACL (1L << 13) |
| #define | SHOW_DB_ACL (1L << 14) |
| #define | SUPER_ACL (1L << 15) |
| #define | CREATE_TMP_ACL (1L << 16) |
| #define | LOCK_TABLES_ACL (1L << 17) |
| #define | EXECUTE_ACL (1L << 18) |
| #define | REPL_SLAVE_ACL (1L << 19) |
| #define | REPL_CLIENT_ACL (1L << 20) |
| #define | CREATE_VIEW_ACL (1L << 21) |
| #define | SHOW_VIEW_ACL (1L << 22) |
| #define | CREATE_PROC_ACL (1L << 23) |
| #define | ALTER_PROC_ACL (1L << 24) |
| #define | CREATE_USER_ACL (1L << 25) |
| #define | EVENT_ACL (1L << 26) |
| #define | TRIGGER_ACL (1L << 27) |
| #define | EXTRA_ACL (1L << 29) |
| #define | NO_ACCESS (1L << 30) |
| #define | DB_ACLS |
| #define | TABLE_ACLS |
| #define | COL_ACLS (SELECT_ACL | INSERT_ACL | UPDATE_ACL | REFERENCES_ACL) |
| #define | PROC_ACLS (ALTER_PROC_ACL | EXECUTE_ACL | GRANT_ACL) |
| #define | SHOW_PROC_ACLS (ALTER_PROC_ACL | EXECUTE_ACL | CREATE_PROC_ACL) |
| #define | GLOBAL_ACLS |
| #define | DEFAULT_CREATE_PROC_ACLS (ALTER_PROC_ACL | EXECUTE_ACL) |
| #define | DB_CHUNK0 |
| #define | DB_CHUNK1 (GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL) |
| #define | DB_CHUNK2 (CREATE_TMP_ACL | LOCK_TABLES_ACL) |
| #define | DB_CHUNK3 |
| #define | DB_CHUNK4 (EXECUTE_ACL) |
| #define | DB_CHUNK5 (EVENT_ACL | TRIGGER_ACL) |
| #define | fix_rights_for_db(A) |
| #define | get_rights_for_db(A) |
| #define | TBL_CHUNK0 DB_CHUNK0 |
| #define | TBL_CHUNK1 DB_CHUNK1 |
| #define | TBL_CHUNK2 (CREATE_VIEW_ACL | SHOW_VIEW_ACL) |
| #define | TBL_CHUNK3 TRIGGER_ACL |
| #define | fix_rights_for_table(A) |
| #define | get_rights_for_table(A) |
| #define | fix_rights_for_column(A) (((A) & 7) | (((A) & ~7) << 8)) |
| #define | get_rights_for_column(A) (((A) & 7) | ((A) >> 8)) |
| #define | fix_rights_for_procedure(A) |
| #define | get_rights_for_procedure(A) |
Enumerations | |
| enum | mysql_db_table_field { MYSQL_DB_FIELD_HOST = 0, MYSQL_DB_FIELD_DB, MYSQL_DB_FIELD_USER, MYSQL_DB_FIELD_SELECT_PRIV, MYSQL_DB_FIELD_INSERT_PRIV, MYSQL_DB_FIELD_UPDATE_PRIV, MYSQL_DB_FIELD_DELETE_PRIV, MYSQL_DB_FIELD_CREATE_PRIV, MYSQL_DB_FIELD_DROP_PRIV, MYSQL_DB_FIELD_GRANT_PRIV, MYSQL_DB_FIELD_REFERENCES_PRIV, MYSQL_DB_FIELD_INDEX_PRIV, MYSQL_DB_FIELD_ALTER_PRIV, MYSQL_DB_FIELD_CREATE_TMP_TABLE_PRIV, MYSQL_DB_FIELD_LOCK_TABLES_PRIV, MYSQL_DB_FIELD_CREATE_VIEW_PRIV, MYSQL_DB_FIELD_SHOW_VIEW_PRIV, MYSQL_DB_FIELD_CREATE_ROUTINE_PRIV, MYSQL_DB_FIELD_ALTER_ROUTINE_PRIV, MYSQL_DB_FIELD_EXECUTE_PRIV, MYSQL_DB_FIELD_EVENT_PRIV, MYSQL_DB_FIELD_TRIGGER_PRIV, MYSQL_DB_FIELD_COUNT } |
Functions | |
| bool | hostname_requires_resolving (const char *hostname) |
| my_bool | acl_init (bool dont_read_acl_tables) |
| my_bool | acl_reload (THD *thd) |
| void | acl_free (bool end=0) |
| ulong | acl_get (const char *host, const char *ip, const char *user, const char *db, my_bool db_is_pattern) |
| int | acl_getroot (THD *thd, USER_RESOURCES *mqh, const char *passwd, uint passwd_len) |
| bool | acl_getroot_no_password (Security_context *sctx, char *user, char *host, char *ip, char *db) |
| bool | acl_check_host (const char *host, const char *ip) |
| bool | check_change_password (THD *thd, const char *host, const char *user, char *password, uint password_len) |
| bool | change_password (THD *thd, const char *host, const char *user, char *password) |
| bool | mysql_grant (THD *thd, const char *db, List< LEX_USER > &user_list, ulong rights, bool revoke) |
| bool | mysql_table_grant (THD *thd, TABLE_LIST *table, List< LEX_USER > &user_list, List< LEX_COLUMN > &column_list, ulong rights, bool revoke) |
| bool | mysql_routine_grant (THD *thd, TABLE_LIST *table, bool is_proc, List< LEX_USER > &user_list, ulong rights, bool revoke, bool no_error) |
| my_bool | grant_init () |
| void | grant_free (void) |
| my_bool | grant_reload (THD *thd) |
| bool | check_grant (THD *thd, ulong want_access, TABLE_LIST *tables, uint show_command, uint number, bool dont_print_error) |
| bool | check_grant_column (THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, const char *name, uint length, Security_context *sctx) |
| bool | check_column_grant_in_table_ref (THD *thd, TABLE_LIST *table_ref, const char *name, uint length) |
| bool | check_grant_all_columns (THD *thd, ulong want_access, GRANT_INFO *grant, const char *db_name, const char *table_name, Field_iterator *fields) |
| bool | check_grant_routine (THD *thd, ulong want_access, TABLE_LIST *procs, bool is_proc, bool no_error) |
| bool | check_grant_db (THD *thd, const char *db) |
| ulong | get_table_grant (THD *thd, TABLE_LIST *table) |
| ulong | get_column_grant (THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, const char *field_name) |
| bool | mysql_show_grants (THD *thd, LEX_USER *user) |
| void | get_privilege_desc (char *to, uint max_length, ulong access) |
| void | get_mqh (const char *user, const char *host, USER_CONN *uc) |
| bool | mysql_create_user (THD *thd, List< LEX_USER > &list) |
| bool | mysql_drop_user (THD *thd, List< LEX_USER > &list) |
| bool | mysql_rename_user (THD *thd, List< LEX_USER > &list) |
| bool | mysql_revoke_all (THD *thd, List< LEX_USER > &list) |
| void | fill_effective_table_privileges (THD *thd, GRANT_INFO *grant, const char *db, const char *table) |
| bool | sp_revoke_privileges (THD *thd, const char *sp_db, const char *sp_name, bool is_proc) |
| bool | sp_grant_privileges (THD *thd, const char *sp_db, const char *sp_name, bool is_proc) |
| bool | check_routine_level_acl (THD *thd, const char *db, const char *name, bool is_proc) |
| bool | is_acl_user (const char *host, const char *user) |
Variables | |
| TABLE_FIELD_W_TYPE | mysql_db_table_fields [] |
| time_t | mysql_db_table_last_check |
| #define ALTER_ACL (1L << 13) |
| #define ALTER_PROC_ACL (1L << 24) |
| #define COL_ACLS (SELECT_ACL | INSERT_ACL | UPDATE_ACL | REFERENCES_ACL) |
Definition at line 69 of file sql_acl.h.
Referenced by check_grant(), get_schema_column_record(), mysql_table_grant(), and replace_column_table().
| #define CREATE_ACL (1L << 4) |
Definition at line 23 of file sql_acl.h.
Referenced by acl_load(), create_table_precheck(), dispatch_command(), mysql_execute_command(), and mysql_table_grant().
| #define CREATE_PROC_ACL (1L << 23) |
| #define CREATE_TMP_ACL (1L << 16) |
| #define CREATE_USER_ACL (1L << 25) |
Definition at line 44 of file sql_acl.h.
Referenced by acl_load(), mysql_execute_command(), and test_if_create_new_users().
| #define CREATE_VIEW_ACL (1L << 21) |
| #define DB_ACLS |
Value:
(UPDATE_ACL | SELECT_ACL | INSERT_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | \ LOCK_TABLES_ACL | EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | \ CREATE_PROC_ACL | ALTER_PROC_ACL | EVENT_ACL | TRIGGER_ACL)
Definition at line 58 of file sql_acl.h.
Referenced by check_access(), fill_schema_schema_privileges(), fill_schema_shemata(), get_all_tables(), mysql_change_db(), mysql_grant(), mysql_show_grants(), and mysqld_show_create_db().
| #define DB_CHUNK0 |
Value:
(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | \ CREATE_ACL | DROP_ACL)
| #define DB_CHUNK1 (GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL) |
| #define DB_CHUNK3 |
Value:
| #define DEFAULT_CREATE_PROC_ACLS (ALTER_PROC_ACL | EXECUTE_ACL) |
Definition at line 86 of file sql_acl.h.
Referenced by mysql_execute_command(), and sp_grant_privileges().
| #define DELETE_ACL (1L << 3) |
Definition at line 22 of file sql_acl.h.
Referenced by check_merge_table_access(), delete_precheck(), insert_precheck(), multi_delete_precheck(), mysql_execute_command(), mysql_multi_delete_prepare(), and mysql_prepare_delete().
| #define DROP_ACL (1L << 5) |
Definition at line 24 of file sql_acl.h.
Referenced by dispatch_command(), mysql_create_view(), and mysql_execute_command().
| #define EVENT_ACL (1L << 26) |
Definition at line 45 of file sql_acl.h.
Referenced by acl_load(), copy_event_to_schema_table(), Event_timed::execute(), fill_schema_events(), and mysql_execute_command().
| #define EXECUTE_ACL (1L << 18) |
Definition at line 37 of file sql_acl.h.
Referenced by acl_load(), Item_func_sp::find_and_check_access(), mysql_execute_command(), and set_routine_security_ctx().
| #define EXTRA_ACL (1L << 29) |
Definition at line 56 of file sql_acl.h.
Referenced by check_access(), check_table_access(), get_schema_column_record(), list_open_tables(), mysql_execute_command(), and prepare_schema_table().
| #define FILE_ACL (1L << 9) |
Definition at line 28 of file sql_acl.h.
Referenced by acl_load(), check_table_access(), mysql_execute_command(), mysql_test_select(), and Item_load_file::val_str().
Definition at line 128 of file sql_acl.h.
Referenced by GRANT_TABLE::GRANT_TABLE(), replace_column_table(), and replace_table_table().
| #define fix_rights_for_db | ( | A | ) |
| #define fix_rights_for_procedure | ( | A | ) |
Value:
((((A) << 18) & EXECUTE_ACL) | \ (((A) << 23) & ALTER_PROC_ACL) | \ (((A) << 8) & GRANT_ACL))
Definition at line 130 of file sql_acl.h.
Referenced by grant_load(), and replace_routine_table().
| #define fix_rights_for_table | ( | A | ) |
Value:
(((A) & TBL_CHUNK0) | \ (((A) << 4) & TBL_CHUNK1) | \ (((A) << 11) & TBL_CHUNK2) | \ (((A) << 15) & TBL_CHUNK3))
Definition at line 120 of file sql_acl.h.
Referenced by GRANT_NAME::GRANT_NAME(), and replace_table_table().
Definition at line 129 of file sql_acl.h.
Referenced by replace_column_table(), and replace_table_table().
| #define get_rights_for_db | ( | A | ) |
| #define get_rights_for_procedure | ( | A | ) |
Value:
((((A) & EXECUTE_ACL) >> 18) | \ (((A) & ALTER_PROC_ACL) >> 23) | \ (((A) & GRANT_ACL) >> 8))
Definition at line 133 of file sql_acl.h.
Referenced by replace_routine_table().
| #define get_rights_for_table | ( | A | ) |
Value:
(((A) & TBL_CHUNK0) | \ (((A) & TBL_CHUNK1) >> 4) | \ (((A) & TBL_CHUNK2) >> 11) | \ (((A) & TBL_CHUNK3) >> 15))
Definition at line 124 of file sql_acl.h.
Referenced by replace_table_table().
| #define GLOBAL_ACLS |
Value:
(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ RELOAD_ACL | SHUTDOWN_ACL | PROCESS_ACL | FILE_ACL | GRANT_ACL | \ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | SHOW_DB_ACL | SUPER_ACL | \ CREATE_TMP_ACL | LOCK_TABLES_ACL | REPL_SLAVE_ACL | REPL_CLIENT_ACL | \ EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | \ ALTER_PROC_ACL | CREATE_USER_ACL | EVENT_ACL | TRIGGER_ACL)
Definition at line 78 of file sql_acl.h.
Referenced by acl_load(), check_user(), fill_schema_user_privileges(), and mysql_show_grants().
| #define GRANT_ACL (1L << 10) |
Definition at line 29 of file sql_acl.h.
Referenced by acl_load(), check_access(), fill_schema_column_privileges(), fill_schema_schema_privileges(), fill_schema_table_privileges(), fill_schema_user_privileges(), mysql_execute_command(), mysql_show_grants(), and show_routine_grants().
| #define INDEX_ACL (1L << 12) |
| #define INSERT_ACL (1L << 1) |
Definition at line 20 of file sql_acl.h.
Referenced by check_insert_fields(), insert_precheck(), mysql_execute_command(), mysql_install_plugin(), mysql_load(), and test_if_create_new_users().
| #define LOCK_TABLES_ACL (1L << 17) |
| #define NO_ACCESS (1L << 30) |
Definition at line 57 of file sql_acl.h.
Referenced by acl_getroot(), check_user(), fill_effective_table_privileges(), and st_table_list::prepare_security().
| #define PROC_ACLS (ALTER_PROC_ACL | EXECUTE_ACL | GRANT_ACL) |
Definition at line 72 of file sql_acl.h.
Referenced by check_access(), mysql_execute_command(), mysql_routine_grant(), and show_routine_grants().
| #define PROCESS_ACL (1L << 8) |
Definition at line 27 of file sql_acl.h.
Referenced by acl_load(), dispatch_command(), fill_schema_processlist(), and mysql_execute_command().
| #define REFERENCES_ACL (1L << 11) |
| #define RELOAD_ACL (1L << 6) |
Definition at line 25 of file sql_acl.h.
Referenced by dispatch_command(), and mysql_execute_command().
| #define REPL_CLIENT_ACL (1L << 20) |
| #define REPL_SLAVE_ACL (1L << 19) |
Definition at line 38 of file sql_acl.h.
Referenced by acl_load(), dispatch_command(), and mysql_execute_command().
| #define SELECT_ACL (1L << 0) |
Definition at line 19 of file sql_acl.h.
Referenced by check_access(), check_insert_fields(), check_merge_table_access(), check_one_table_access(), check_show_routine_access(), check_table_access(), create_table_precheck(), delete_precheck(), dispatch_command(), fill_schema_column_privileges(), fill_schema_proc(), fill_schema_schema_privileges(), fill_schema_table_privileges(), fill_schema_user_privileges(), get_all_tables(), get_schema_column_record(), insert_fields(), list_open_tables(), multi_delete_precheck(), multi_update_precheck(), my_tz_check_n_skip_implicit_tables(), mysql_change_db(), mysql_create_view(), mysql_derived_prepare(), mysql_execute_command(), mysql_make_view(), mysql_prepare_insert_check_table(), mysql_prepare_update(), mysql_schema_table(), mysql_show_grants(), mysql_table_dump(), mysql_test_do_fields(), mysql_test_select(), mysql_test_set_fields(), JOIN::prepare(), prepare_schema_table(), replace_user_table(), sp_lex_keeper::reset_lex_and_exec_core(), Item_trigger_field::set_required_privilege(), and show_routine_grants().
| #define SHOW_DB_ACL (1L << 14) |
Definition at line 33 of file sql_acl.h.
Referenced by acl_load(), fill_schema_shemata(), get_all_tables(), and prepare_schema_table().
| #define SHOW_PROC_ACLS (ALTER_PROC_ACL | EXECUTE_ACL | CREATE_PROC_ACL) |
Definition at line 75 of file sql_acl.h.
Referenced by check_routine_level_acl(), and check_some_routine_access().
| #define SHOW_VIEW_ACL (1L << 22) |
Definition at line 41 of file sql_acl.h.
Referenced by acl_load(), check_grant(), check_table_access(), mysql_make_view(), and st_table_list::register_want_access().
| #define SHUTDOWN_ACL (1L << 7) |
| #define SUPER_ACL (1L << 15) |
Definition at line 34 of file sql_acl.h.
Referenced by acl_load(), sys_var_thd_dbug::check(), set_var::check(), check_log_update(), check_pseudo_thread_id(), check_user(), Table_triggers_list::create_trigger(), db_create_routine(), dispatch_command(), LOGGER::general_log_print(), handle_one_connection(), kill_one_thread(), set_var::light_check(), mysql_create_or_drop_trigger(), mysql_create_view(), mysql_execute_command(), mysql_insert(), Event_scheduler::stop_all_running_events(), sys_check_ftb_syntax(), and Item_func_des_decrypt::val_str().
| #define TABLE_ACLS |
Value:
(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | \ SHOW_VIEW_ACL | TRIGGER_ACL)
Definition at line 64 of file sql_acl.h.
Referenced by check_access(), fill_schema_column_privileges(), fill_schema_table_privileges(), find_files(), mysql_show_grants(), and mysql_table_grant().
| #define TRIGGER_ACL (1L << 27) |
Definition at line 46 of file sql_acl.h.
Referenced by acl_load(), mysql_create_or_drop_trigger(), and Table_triggers_list::process_triggers().
| #define UPDATE_ACL (1L << 2) |
Definition at line 21 of file sql_acl.h.
Referenced by check_change_password(), check_merge_table_access(), insert_precheck(), multi_update_precheck(), mysql_execute_command(), mysql_load(), mysql_multi_update_prepare(), mysql_prepare_update(), Item_trigger_field::set_required_privilege(), and update_precheck().
| enum mysql_db_table_field |
Definition at line 137 of file sql_acl.h.
00138 { 00139 MYSQL_DB_FIELD_HOST = 0, 00140 MYSQL_DB_FIELD_DB, 00141 MYSQL_DB_FIELD_USER, 00142 MYSQL_DB_FIELD_SELECT_PRIV, 00143 MYSQL_DB_FIELD_INSERT_PRIV, 00144 MYSQL_DB_FIELD_UPDATE_PRIV, 00145 MYSQL_DB_FIELD_DELETE_PRIV, 00146 MYSQL_DB_FIELD_CREATE_PRIV, 00147 MYSQL_DB_FIELD_DROP_PRIV, 00148 MYSQL_DB_FIELD_GRANT_PRIV, 00149 MYSQL_DB_FIELD_REFERENCES_PRIV, 00150 MYSQL_DB_FIELD_INDEX_PRIV, 00151 MYSQL_DB_FIELD_ALTER_PRIV, 00152 MYSQL_DB_FIELD_CREATE_TMP_TABLE_PRIV, 00153 MYSQL_DB_FIELD_LOCK_TABLES_PRIV, 00154 MYSQL_DB_FIELD_CREATE_VIEW_PRIV, 00155 MYSQL_DB_FIELD_SHOW_VIEW_PRIV, 00156 MYSQL_DB_FIELD_CREATE_ROUTINE_PRIV, 00157 MYSQL_DB_FIELD_ALTER_ROUTINE_PRIV, 00158 MYSQL_DB_FIELD_EXECUTE_PRIV, 00159 MYSQL_DB_FIELD_EVENT_PRIV, 00160 MYSQL_DB_FIELD_TRIGGER_PRIV, 00161 MYSQL_DB_FIELD_COUNT 00162 };
| bool acl_check_host | ( | const char * | host, | |
| const char * | ip | |||
| ) |
Definition at line 1469 of file sql_acl.cc.
References acl_cache, acl_check_hosts, acl_wild_hosts, allow_all_hosts, compare_hostname(), dynamic_element, st_dynamic_array::elements, hash_search(), hash_filo::lock, pthread_mutex_lock, pthread_mutex_unlock, strlen(), and VOID.
Referenced by check_connection().
01470 { 01471 if (allow_all_hosts) 01472 return 0; 01473 VOID(pthread_mutex_lock(&acl_cache->lock)); 01474 01475 if (host && hash_search(&acl_check_hosts,(byte*) host,(uint) strlen(host)) || 01476 ip && hash_search(&acl_check_hosts,(byte*) ip,(uint) strlen(ip))) 01477 { 01478 VOID(pthread_mutex_unlock(&acl_cache->lock)); 01479 return 0; // Found host 01480 } 01481 for (uint i=0 ; i < acl_wild_hosts.elements ; i++) 01482 { 01483 acl_host_and_ip *acl=dynamic_element(&acl_wild_hosts,i,acl_host_and_ip*); 01484 if (compare_hostname(acl, host, ip)) 01485 { 01486 VOID(pthread_mutex_unlock(&acl_cache->lock)); 01487 return 0; // Host ok 01488 } 01489 } 01490 VOID(pthread_mutex_unlock(&acl_cache->lock)); 01491 return 1; // Host is not allowed 01492 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void acl_free | ( | bool | end = 0 |
) |
Definition at line 630 of file sql_acl.cc.
References acl_cache, acl_check_hosts, acl_dbs, acl_hosts, acl_users, acl_wild_hosts, hash_filo::clear(), delete_dynamic(), free_root(), hash_free(), mem, and MYF.
Referenced by acl_reload(), and clean_up().
00631 { 00632 free_root(&mem,MYF(0)); 00633 delete_dynamic(&acl_hosts); 00634 delete_dynamic(&acl_users); 00635 delete_dynamic(&acl_dbs); 00636 delete_dynamic(&acl_wild_hosts); 00637 hash_free(&acl_check_hosts); 00638 if (!end) 00639 acl_cache->clear(1); /* purecov: inspected */ 00640 else 00641 { 00642 delete acl_cache; 00643 acl_cache=0; 00644 } 00645 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulong acl_get | ( | const char * | host, | |
| const char * | ip, | |||
| const char * | user, | |||
| const char * | db, | |||
| my_bool | db_is_pattern | |||
| ) |
Definition at line 1319 of file sql_acl.cc.
References acl_cache, acl_dbs, ACL_KEY_LENGTH, compare_hostname(), DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, dynamic_element, st_dynamic_array::elements, exit, files_charset_info, key, key_length, hash_filo::lock, lower_case_table_names, my_casedn_str, pthread_mutex_lock, pthread_mutex_unlock, hash_filo::search(), strcmp(), strmov(), VOID, and wild_compare().
Referenced by check_access(), fill_effective_table_privileges(), fill_schema_shemata(), get_all_tables(), mysql_change_db(), mysqld_show_create_db(), and test_if_create_new_users().
01321 { 01322 ulong host_access= ~(ulong)0, db_access= 0; 01323 uint i,key_length; 01324 char key[ACL_KEY_LENGTH],*tmp_db,*end; 01325 acl_entry *entry; 01326 DBUG_ENTER("acl_get"); 01327 01328 VOID(pthread_mutex_lock(&acl_cache->lock)); 01329 end=strmov((tmp_db=strmov(strmov(key, ip ? ip : "")+1,user)+1),db); 01330 if (lower_case_table_names) 01331 { 01332 my_casedn_str(files_charset_info, tmp_db); 01333 db=tmp_db; 01334 } 01335 key_length=(uint) (end-key); 01336 if (!db_is_pattern && (entry=(acl_entry*) acl_cache->search(key,key_length))) 01337 { 01338 db_access=entry->access; 01339 VOID(pthread_mutex_unlock(&acl_cache->lock)); 01340 DBUG_PRINT("exit", ("access: 0x%lx", db_access)); 01341 DBUG_RETURN(db_access); 01342 } 01343 01344 /* 01345 Check if there are some access rights for database and user 01346 */ 01347 for (i=0 ; i < acl_dbs.elements ; i++) 01348 { 01349 ACL_DB *acl_db=dynamic_element(&acl_dbs,i,ACL_DB*); 01350 if (!acl_db->user || !strcmp(user,acl_db->user)) 01351 { 01352 if (compare_hostname(&acl_db->host,host,ip)) 01353 { 01354 if (!acl_db->db || !wild_compare(db,acl_db->db,db_is_pattern)) 01355 { 01356 db_access=acl_db->access; 01357 if (acl_db->host.hostname) 01358 goto exit; // Fully specified. Take it 01359 break; /* purecov: tested */ 01360 } 01361 } 01362 } 01363 } 01364 if (!db_access) 01365 goto exit; // Can't be better 01366 01367 /* 01368 No host specified for user. Get hostdata from host table 01369 */ 01370 host_access=0; // Host must be found 01371 for (i=0 ; i < acl_hosts.elements ; i++) 01372 { 01373 ACL_HOST *acl_host=dynamic_element(&acl_hosts,i,ACL_HOST*); 01374 if (compare_hostname(&acl_host->host,host,ip)) 01375 { 01376 if (!acl_host->db || !wild_compare(db,acl_host->db,db_is_pattern)) 01377 { 01378 host_access=acl_host->access; // Fully specified. Take it 01379 break; 01380 } 01381 } 01382 } 01383 exit: 01384 /* Save entry in cache for quick retrieval */ 01385 if (!db_is_pattern && 01386 (entry= (acl_entry*) malloc(sizeof(acl_entry)+key_length))) 01387 { 01388 entry->access=(db_access & host_access); 01389 entry->length=key_length; 01390 memcpy((gptr) entry->key,key,key_length); 01391 acl_cache->add(entry); 01392 } 01393 VOID(pthread_mutex_unlock(&acl_cache->lock)); 01394 DBUG_PRINT("exit", ("access: 0x%lx", db_access & host_access)); 01395 DBUG_RETURN(db_access & host_access); 01396 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int acl_getroot | ( | THD * | thd, | |
| USER_RESOURCES * | mqh, | |||
| const char * | passwd, | |||
| uint | passwd_len | |||
| ) |
Definition at line 862 of file sql_acl.cc.
References acl_cache, acl_users, bzero, check_scramble(), check_scramble_323(), compare_hostname(), DBUG_ENTER, DBUG_RETURN, dynamic_element, st_dynamic_array::elements, hash_filo::lock, NO_ACCESS, pthread_mutex_lock, SCRAMBLE_LENGTH, strcmp(), and VOID.
Referenced by check_user().
00864 { 00865 ulong user_access= NO_ACCESS; 00866 int res= 1; 00867 ACL_USER *acl_user= 0; 00868 Security_context *sctx= thd->security_ctx; 00869 DBUG_ENTER("acl_getroot"); 00870 00871 if (!initialized) 00872 { 00873 /* 00874 here if mysqld's been started with --skip-grant-tables option. 00875 */ 00876 sctx->skip_grants(); 00877 bzero((char*) mqh, sizeof(*mqh)); 00878 DBUG_RETURN(0); 00879 } 00880 00881 VOID(pthread_mutex_lock(&acl_cache->lock)); 00882 00883 /* 00884 Find acl entry in user database. Note, that find_acl_user is not the same, 00885 because it doesn't take into account the case when user is not empty, 00886 but acl_user->user is empty 00887 */ 00888 00889 for (uint i=0 ; i < acl_users.elements ; i++) 00890 { 00891 ACL_USER *acl_user_tmp= dynamic_element(&acl_users,i,ACL_USER*); 00892 if (!acl_user_tmp->user || !strcmp(sctx->user, acl_user_tmp->user)) 00893 { 00894 if (compare_hostname(&acl_user_tmp->host, sctx->host, sctx->ip)) 00895 { 00896 /* check password: it should be empty or valid */ 00897 if (passwd_len == acl_user_tmp->salt_len) 00898 { 00899 if (acl_user_tmp->salt_len == 0 || 00900 (acl_user_tmp->salt_len == SCRAMBLE_LENGTH ? 00901 check_scramble(passwd, thd->scramble, acl_user_tmp->salt) : 00902 check_scramble_323(passwd, thd->scramble, 00903 (ulong *) acl_user_tmp->salt)) == 0) 00904 { 00905 acl_user= acl_user_tmp; 00906 res= 0; 00907 } 00908 } 00909 else if (passwd_len == SCRAMBLE_LENGTH && 00910 acl_user_tmp->salt_len == SCRAMBLE_LENGTH_323) 00911 res= -1; 00912 else if (passwd_len == SCRAMBLE_LENGTH_323 && 00913 acl_user_tmp->salt_len == SCRAMBLE_LENGTH) 00914 res= 2; 00915 /* linear search complete: */ 00916 break; 00917 } 00918 } 00919 } 00920 /* 00921 This was moved to separate tree because of heavy HAVE_OPENSSL case. 00922 If acl_user is not null, res is 0. 00923 */ 00924 00925 if (acl_user) 00926 { 00927 /* OK. User found and password checked continue validation */ 00928 #ifdef HAVE_OPENSSL 00929 Vio *vio=thd->net.vio; 00930 SSL *ssl= (SSL*) vio->ssl_arg; 00931 #endif 00932 00933 /* 00934 At this point we know that user is allowed to connect 00935 from given host by given username/password pair. Now 00936 we check if SSL is required, if user is using SSL and 00937 if X509 certificate attributes are OK 00938 */ 00939 switch (acl_user->ssl_type) { 00940 case SSL_TYPE_NOT_SPECIFIED: // Impossible 00941 case SSL_TYPE_NONE: // SSL is not required 00942 user_access= acl_user->access; 00943 break; 00944 #ifdef HAVE_OPENSSL 00945 case SSL_TYPE_ANY: // Any kind of SSL is ok 00946 if (vio_type(vio) == VIO_TYPE_SSL) 00947 user_access= acl_user->access; 00948 break; 00949 case SSL_TYPE_X509: /* Client should have any valid certificate. */ 00950 /* 00951 Connections with non-valid certificates are dropped already 00952 in sslaccept() anyway, so we do not check validity here. 00953 00954 We need to check for absence of SSL because without SSL 00955 we should reject connection. 00956 */ 00957 if (vio_type(vio) == VIO_TYPE_SSL && 00958 SSL_get_verify_result(ssl) == X509_V_OK && 00959 SSL_get_peer_certificate(ssl)) 00960 user_access= acl_user->access; 00961 break; 00962 case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */ 00963 /* 00964 We do not check for absence of SSL because without SSL it does 00965 not pass all checks here anyway. 00966 If cipher name is specified, we compare it to actual cipher in 00967 use. 00968 */ 00969 X509 *cert; 00970 if (vio_type(vio) != VIO_TYPE_SSL || 00971 SSL_get_verify_result(ssl) != X509_V_OK) 00972 break; 00973 if (acl_user->ssl_cipher) 00974 { 00975 DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'", 00976 acl_user->ssl_cipher,SSL_get_cipher(ssl))); 00977 if (!strcmp(acl_user->ssl_cipher,SSL_get_cipher(ssl))) 00978 user_access= acl_user->access; 00979 else 00980 { 00981 if (global_system_variables.log_warnings) 00982 sql_print_information("X509 ciphers mismatch: should be '%s' but is '%s'", 00983 acl_user->ssl_cipher, 00984 SSL_get_cipher(ssl)); 00985 break; 00986 } 00987 } 00988 /* Prepare certificate (if exists) */ 00989 DBUG_PRINT("info",("checkpoint 1")); 00990 if (!(cert= SSL_get_peer_certificate(ssl))) 00991 { 00992 user_access=NO_ACCESS; 00993 break; 00994 } 00995 DBUG_PRINT("info",("checkpoint 2")); 00996 /* If X509 issuer is specified, we check it... */ 00997 if (acl_user->x509_issuer) 00998 { 00999 DBUG_PRINT("info",("checkpoint 3")); 01000 char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); 01001 DBUG_PRINT("info",("comparing issuers: '%s' and '%s'", 01002 acl_user->x509_issuer, ptr)); 01003 if (strcmp(acl_user->x509_issuer, ptr)) 01004 { 01005 if (global_system_variables.log_warnings) 01006 sql_print_information("X509 issuer mismatch: should be '%s' " 01007 "but is '%s'", acl_user->x509_issuer, ptr); 01008 free(ptr); 01009 break; 01010 } 01011 user_access= acl_user->access; 01012 free(ptr); 01013 } 01014 DBUG_PRINT("info",("checkpoint 4")); 01015 /* X509 subject is specified, we check it .. */ 01016 if (acl_user->x509_subject) 01017 { 01018 char *ptr= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); 01019 DBUG_PRINT("info",("comparing subjects: '%s' and '%s'", 01020 acl_user->x509_subject, ptr)); 01021 if (strcmp(acl_user->x509_subject,ptr)) 01022 { 01023 if (global_system_variables.log_warnings) 01024 sql_print_information("X509 subject mismatch: '%s' vs '%s'", 01025 acl_user->x509_subject, ptr); 01026 } 01027 else 01028 user_access= acl_user->access; 01029 free(ptr); 01030 } 01031 break; 01032 #else /* HAVE_OPENSSL */ 01033 default: 01034 /* 01035 If we don't have SSL but SSL is required for this user the 01036 authentication should fail. 01037 */ 01038 break; 01039 #endif /* HAVE_OPENSSL */ 01040 } 01041 sctx->master_access= user_access; 01042 sctx->priv_user= acl_user->user ? sctx->user : (char *) ""; 01043 *mqh= acl_user->user_resource; 01044 01045 if (acl_user->host.hostname) 01046 strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME); 01047 else 01048 *sctx->priv_host= 0; 01049 } 01050 VOID(pthread_mutex_unlock(&acl_cache->lock)); 01051 DBUG_RETURN(res); 01052 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool acl_getroot_no_password | ( | Security_context * | sctx, | |
| char * | user, | |||
| char * | host, | |||
| char * | ip, | |||
| char * | db | |||
| ) |
Definition at line 1072 of file sql_acl.cc.
References acl_cache, acl_users, compare_hostname(), DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, dynamic_element, st_dynamic_array::elements, FALSE, ACL_USER::host, initialized, hash_filo::lock, pthread_mutex_lock, strcmp(), ACL_USER::user, and VOID.
Referenced by change_security_context(), st_table_list::prepare_view_securety_context(), and sp_change_security_context().
01074 { 01075 int res= 1; 01076 uint i; 01077 ACL_USER *acl_user= 0; 01078 DBUG_ENTER("acl_getroot_no_password"); 01079 01080 DBUG_PRINT("enter", ("Host: '%s', Ip: '%s', User: '%s', db: '%s'", 01081 (host ? host : "(NULL)"), (ip ? ip : "(NULL)"), 01082 user, (db ? db : "(NULL)"))); 01083 sctx->user= user; 01084 sctx->host= host; 01085 sctx->ip= ip; 01086 sctx->host_or_ip= host ? host : (ip ? ip : ""); 01087 01088 if (!initialized) 01089 { 01090 /* 01091 here if mysqld's been started with --skip-grant-tables option. 01092 */ 01093 sctx->skip_grants(); 01094 DBUG_RETURN(FALSE); 01095 } 01096 01097 VOID(pthread_mutex_lock(&acl_cache->lock)); 01098 01099 sctx->master_access= 0; 01100 sctx->db_access= 0; 01101 sctx->priv_user= (char *) ""; 01102 *sctx->priv_host= 0; 01103 01104 /* 01105 Find acl entry in user database. 01106 This is specially tailored to suit the check we do for CALL of 01107 a stored procedure; user is set to what is actually a 01108 priv_user, which can be ''. 01109 */ 01110 for (i=0 ; i < acl_users.elements ; i++) 01111 { 01112 acl_user= dynamic_element(&acl_users,i,ACL_USER*); 01113 if ((!acl_user->user && !user[0]) || 01114 (acl_user->user && strcmp(user, acl_user->user) == 0)) 01115 { 01116 if (compare_hostname(&acl_user->host, host, ip)) 01117 { 01118 res= 0; 01119 break; 01120 } 01121 } 01122 } 01123 01124 if (acl_user) 01125 { 01126 for (i=0 ; i < acl_dbs.elements ; i++) 01127 { 01128 ACL_DB *acl_db= dynamic_element(&acl_dbs, i, ACL_DB*); 01129 if (!acl_db->user || 01130 (user && user[0] && !strcmp(user, acl_db->user))) 01131 { 01132 if (compare_hostname(&acl_db->host, host, ip)) 01133 { 01134 if (!acl_db->db || (db && !wild_compare(db, acl_db->db, 0))) 01135 { 01136 sctx->db_access= acl_db->access; 01137 break; 01138 } 01139 } 01140 } 01141 } 01142 sctx->master_access= acl_user->access; 01143 sctx->priv_user= acl_user->user ? user : (char *) ""; 01144 01145 if (acl_user->host.hostname) 01146 strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME); 01147 else 01148 *sctx->priv_host= 0; 01149 } 01150 VOID(pthread_mutex_unlock(&acl_cache->lock)); 01151 DBUG_RETURN(res); 01152 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 258 of file sql_acl.cc.
References acl_cache, ACL_CACHE_SIZE, acl_entry_get_key(), acl_reload(), DBUG_ENTER, DBUG_RETURN, free, lower_case_file_system, my_charset_bin, my_pthread_setspecific_ptr, and system_charset_info.
Referenced by main().
00259 { 00260 THD *thd; 00261 my_bool return_val; 00262 DBUG_ENTER("acl_init"); 00263 00264 acl_cache= new hash_filo(ACL_CACHE_SIZE, 0, 0, 00265 (hash_get_key) acl_entry_get_key, 00266 (hash_free_key) free, 00267 lower_case_file_system ? 00268 system_charset_info : &my_charset_bin); 00269 if (dont_read_acl_tables) 00270 { 00271 DBUG_RETURN(0); /* purecov: tested */ 00272 } 00273 00274 /* 00275 To be able to run this from boot, we allocate a temporary THD 00276 */ 00277 if (!(thd=new THD)) 00278 DBUG_RETURN(1); /* purecov: inspected */ 00279 thd->thread_stack= (char*) &thd; 00280 thd->store_globals(); 00281 /* 00282 It is safe to call acl_reload() since acl_* arrays and hashes which 00283 will be freed there are global static objects and thus are initialized 00284 by zeros at startup. 00285 */ 00286 return_val= acl_reload(thd); 00287 delete thd; 00288 /* Remember that we don't have a THD */ 00289 my_pthread_setspecific_ptr(THR_THD, 0); 00290 DBUG_RETURN(return_val); 00291 }
Here is the call graph for this function:

Here is the caller graph for this function:

| my_bool acl_reload | ( | THD * | thd | ) |
Definition at line 667 of file sql_acl.cc.
References acl_cache, acl_check_hosts, acl_dbs, acl_free(), acl_hosts, acl_load(), acl_users, acl_wild_hosts, bzero, close_thread_tables(), DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, delete_dynamic(), free_root(), hash_free(), init_check_host(), hash_filo::lock, mem, MYF, pthread_mutex_lock, pthread_mutex_unlock, simple_open_n_lock_tables(), sql_print_error(), TL_READ, and VOID.
Referenced by acl_init(), and reload_acl_and_cache().
00668 { 00669 TABLE_LIST tables[3]; 00670 DYNAMIC_ARRAY old_acl_hosts,old_acl_users,old_acl_dbs; 00671 MEM_ROOT old_mem; 00672 bool old_initialized; 00673 my_bool return_val= 1; 00674 DBUG_ENTER("acl_reload"); 00675 00676 if (thd->locked_tables) 00677 { // Can't have locked tables here 00678 thd->lock=thd->locked_tables; 00679 thd->locked_tables=0; 00680 close_thread_tables(thd); 00681 } 00682 00683 /* 00684 To avoid deadlocks we should obtain table locks before 00685 obtaining acl_cache->lock mutex. 00686 */ 00687 bzero((char*) tables, sizeof(tables)); 00688 tables[0].alias= tables[0].table_name= (char*) "host"; 00689 tables[1].alias= tables[1].table_name= (char*) "user"; 00690 tables[2].alias= tables[2].table_name= (char*) "db"; 00691 tables[0].db=tables[1].db=tables[2].db=(char*) "mysql"; 00692 tables[0].next_local= tables[0].next_global= tables+1; 00693 tables[1].next_local= tables[1].next_global= tables+2; 00694 tables[0].lock_type=tables[1].lock_type=tables[2].lock_type=TL_READ; 00695 00696 if (simple_open_n_lock_tables(thd, tables)) 00697 { 00698 sql_print_error("Fatal error: Can't open and lock privilege tables: %s", 00699 thd->net.last_error); 00700 goto end; 00701 } 00702 00703 if ((old_initialized=initialized)) 00704 VOID(pthread_mutex_lock(&acl_cache->lock)); 00705 00706 old_acl_hosts=acl_hosts; 00707 old_acl_users=acl_users; 00708 old_acl_dbs=acl_dbs; 00709 old_mem=mem; 00710 delete_dynamic(&acl_wild_hosts); 00711 hash_free(&acl_check_hosts); 00712 00713 if ((return_val= acl_load(thd, tables))) 00714 { // Error. Revert to old list 00715 DBUG_PRINT("error",("Reverting to old privileges")); 00716 acl_free(); /* purecov: inspected */ 00717 acl_hosts=old_acl_hosts; 00718 acl_users=old_acl_users; 00719 acl_dbs=old_acl_dbs; 00720 mem=old_mem; 00721 init_check_host(); 00722 } 00723 else 00724 { 00725 free_root(&old_mem,MYF(0)); 00726 delete_dynamic(&old_acl_hosts); 00727 delete_dynamic(&old_acl_users); 00728 delete_dynamic(&old_acl_dbs); 00729 } 00730 if (old_initialized) 00731 VOID(pthread_mutex_unlock(&acl_cache->lock)); 00732 end: 00733 close_thread_tables(thd); 00734 DBUG_RETURN(return_val); 00735 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool change_password | ( | THD * | thd, | |
| const char * | host, | |||
| const char * | user, | |||
| char * | password | |||
| ) |
Definition at line 1561 of file sql_acl.cc.
References acl_cache, bzero, check_change_password(), hash_filo::clear(), close_thread_tables(), DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, ER, ER_PASSWORD_NO_MATCH, FALSE, find_acl_user(), ACL_USER::host, acl_host_and_ip::hostname, Rpl_filter::is_on(), MYSQL_LOG::is_open(), hash_filo::lock, my_message(), my_sprintf, MYF, mysql_bin_log, open_ltable(), pthread_mutex_lock, pthread_mutex_unlock, rpl_filter, set_user_salt(), strlen(), Rpl_filter::tables_ok(), TL_WRITE, TRUE, update_user_table(), ACL_USER::user, and VOID.
Referenced by set_var_password::update().
01563 { 01564 TABLE_LIST tables; 01565 TABLE *table; 01566 /* Buffer should be extended when password length is extended. */ 01567 char buff[512]; 01568 ulong query_length; 01569 uint new_password_len= strlen(new_password); 01570 bool result= 1; 01571 DBUG_ENTER("change_password"); 01572 DBUG_PRINT("enter",("host: '%s' user: '%s' new_password: '%s'", 01573 host,user,new_password)); 01574 DBUG_ASSERT(host != 0); // Ensured by parent 01575 01576 if (check_change_password(thd, host, user, new_password, new_password_len)) 01577 DBUG_RETURN(1); 01578 01579 bzero((char*) &tables, sizeof(tables)); 01580 tables.alias= tables.table_name= (char*) "user"; 01581 tables.db= (char*) "mysql"; 01582 01583 #ifdef HAVE_REPLICATION 01584 /* 01585 GRANT and REVOKE are applied the slave in/exclusion rules as they are 01586 some kind of updates to the mysql.% tables. 01587 */ 01588 if (thd->slave_thread && rpl_filter->is_on()) 01589 { 01590 /* 01591 The tables must be marked "updating" so that tables_ok() takes them into 01592 account in tests. It's ok to leave 'updating' set after tables_ok. 01593 */ 01594 tables.updating= 1; 01595 /* Thanks to bzero, tables.next==0 */ 01596 if (!(thd->spcont || rpl_filter->tables_ok(0, &tables))) 01597 DBUG_RETURN(0); 01598 } 01599 #endif 01600 01601 if (!(table= open_ltable(thd, &tables, TL_WRITE))) 01602 DBUG_RETURN(1); 01603 01604 VOID(pthread_mutex_lock(&acl_cache->lock)); 01605 ACL_USER *acl_user; 01606 if (!(acl_user= find_acl_user(host, user, TRUE))) 01607 { 01608 VOID(pthread_mutex_unlock(&acl_cache->lock)); 01609 my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), MYF(0)); 01610 goto end; 01611 } 01612 /* update loaded acl entry: */ 01613 set_user_salt(acl_user, new_password, new_password_len); 01614 01615 if (update_user_table(thd, table, 01616 acl_user->host.hostname ? acl_user->host.hostname : "", 01617 acl_user->user ? acl_user->user : "", 01618 new_password, new_password_len)) 01619 { 01620 VOID(pthread_mutex_unlock(&acl_cache->lock)); /* purecov: deadcode */ 01621 goto end; 01622 } 01623 01624 acl_cache->clear(1); // Clear locked hostname cache 01625 VOID(pthread_mutex_unlock(&acl_cache->lock)); 01626 result= 0; 01627 if (mysql_bin_log.is_open()) 01628 { 01629 query_length= 01630 my_sprintf(buff, 01631 (buff,"SET PASSWORD FOR \"%-.120s\"@\"%-.120s\"=\"%-.120s\"", 01632 acl_user->user ? acl_user->user : "", 01633 acl_user->host.hostname ? acl_user->host.hostname : "", 01634 new_password)); 01635 thd->clear_error(); 01636 thd->binlog_query(THD::MYSQL_QUERY_TYPE, buff, query_length, FALSE, FALSE); 01637 } 01638 end: 01639 close_thread_tables(thd); 01640 DBUG_RETURN(result); 01641 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool check_change_password | ( | THD * | thd, | |
| const char * | host, | |||
| const char * | user, | |||
| char * | password, | |||
| uint | password_len | |||
| ) |
Definition at line 1513 of file sql_acl.cc.
References check_access(), ER, ER_OPTION_PREVENTS_STATEMENT, ER_PASSWD_LENGTH, ER_PASSWORD_ANONYMOUS_USER, initialized, my_error(), my_message(), my_strcasecmp, MYF, SCRAMBLED_PASSWORD_CHAR_LENGTH, SCRAMBLED_PASSWORD_CHAR_LENGTH_323, strcmp(), strlen(), system_charset_info, and UPDATE_ACL.
Referenced by change_password(), and set_var_password::check().
01515 { 01516 if (!initialized) 01517 { 01518 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables"); 01519 return(1); 01520 } 01521 if (!thd->slave_thread && 01522 (strcmp(thd->security_ctx->user, user) || 01523 my_strcasecmp(system_charset_info, host, 01524 thd->security_ctx->priv_host))) 01525 { 01526 if (check_access(thd, UPDATE_ACL, "mysql",0,1,0,0)) 01527 return(1); 01528 } 01529 if (!thd->slave_thread && !thd->security_ctx->user[0]) 01530 { 01531 my_message(ER_PASSWORD_ANONYMOUS_USER, ER(ER_PASSWORD_ANONYMOUS_USER), 01532 MYF(0)); 01533 return(1); 01534 } 01535 uint len=strlen(new_password); 01536 if (len && len != SCRAMBLED_PASSWORD_CHAR_LENGTH && 01537 len != SCRAMBLED_PASSWORD_CHAR_LENGTH_323) 01538 { 01539 my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH); 01540 return -1; 01541 } 01542 return(0); 01543 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool check_column_grant_in_table_ref | ( | THD * | thd, | |
| TABLE_LIST * | table_ref, | |||
| const char * | name, | |||
| uint | length | |||
| ) |
Definition at line 3923 of file sql_acl.cc.
References st_table_list::allowed_show, st_table_list::belong_to_view, check_grant_column(), st_table_share::db, ER, ER_VIEW_NO_EXPLAIN, FALSE, st_table_list::field_translation, get_column_grant(), st_table::grant, st_table_list::grant, my_message(), MYF, st_table::s, st_table_list::security_ctx, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_FIELDS, LEX_STRING::str, st_table_list::table, st_table_share::table_name, test, TRUE, st_table_list::view, VIEW_ANY_ACL, st_table_list::view_db, st_table_list::view_name, and st_grant_info::want_privilege.
Referenced by find_field_in_table_ref().
03925 { 03926 GRANT_INFO *grant; 03927 const char *db_name; 03928 const char *table_name; 03929 Security_context *sctx= test(table_ref->security_ctx) ? 03930 table_ref->security_ctx : thd->security_ctx; 03931 03932 if (table_ref->view || table_ref->field_translation) 03933 { 03934 /* View or derived information schema table. */ 03935 ulong view_privs; 03936 grant= &(table_ref->grant); 03937 db_name= table_ref->view_db.str; 03938 table_name= table_ref->view_name.str; 03939 if (table_ref->belong_to_view && 03940 (thd->lex->sql_command == SQLCOM_SHOW_FIELDS || 03941 thd->lex->sql_command == SQLCOM_SHOW_CREATE)) 03942 { 03943 view_privs= get_column_grant(thd, grant, db_name, table_name, name); 03944 if (view_privs & VIEW_ANY_ACL) 03945 { 03946 table_ref->belong_to_view->allowed_show= TRUE; 03947 return FALSE; 03948 } 03949 table_ref->belong_to_view->allowed_show= FALSE; 03950 my_message(ER_VIEW_NO_EXPLAIN, ER(ER_VIEW_NO_EXPLAIN), MYF(0)); 03951 return TRUE; 03952 } 03953 } 03954 else 03955 { 03956 /* Normal or temporary table. */ 03957 TABLE *table= table_ref->table; 03958 grant= &(table->grant); 03959 db_name= table->s->db.str; 03960 table_name= table->s->table_name.str; 03961 } 03962 03963 if (grant->want_privilege) 03964 return check_grant_column(thd, grant, db_name, table_name, name, 03965 length, sctx); 03966 else 03967 return FALSE; 03968 03969 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool check_grant | ( | THD * | thd, | |
| ulong | want_access, | |||
| TABLE_LIST * | tables, | |||
| uint | show_command, | |||
| uint | number, | |||
| bool | dont_print_error | |||
| ) |
Definition at line 3730 of file sql_acl.cc.
References COL_ACLS, st_table_list::db, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, st_table_list::derived, ER_TABLEACCESS_DENIED_ERROR, err, get_privilege_desc(), st_table_list::grant, st_grant_info::grant_table, grant_version, LOCK_grant, my_error(), MYF, st_table_list::next_global, st_grant_info::orig_want_privilege, st_grant_info::privilege, st_table_list::referencing_view, rw_rdlock, rw_unlock, st_table_list::schema_table, st_table_list::security_ctx, SHOW_VIEW_ACL, table_hash_search(), st_table_list::table_name, test, st_grant_info::version, and st_grant_info::want_privilege.
Referenced by check_single_table_access(), check_some_access(), create_table_precheck(), dispatch_command(), find_files(), multi_update_precheck(), mysql_create_view(), mysql_execute_command(), prepare_schema_table(), and test_if_create_new_users().
03732 { 03733 TABLE_LIST *table, *first_not_own_table= thd->lex->first_not_own_table(); 03734 Security_context *sctx= thd->security_ctx; 03735 uint i; 03736 ulong orig_want_access= want_access; 03737 DBUG_ENTER("check_grant"); 03738 DBUG_ASSERT(number > 0); 03739 03740 /* 03741 Walk through the list of tables that belong to the query and save the 03742 requested access (orig_want_privilege) to be able to use it when 03743 checking access rights to the underlying tables of a view. Our grant 03744 system gradually eliminates checked bits from want_privilege and thus 03745 after all checks are done we can no longer use it. 03746 The check that first_not_own_table is not reached is for the case when 03747 the given table list refers to the list for prelocking (contains tables 03748 of other queries). For simple queries first_not_own_table is 0. 03749 */ 03750 for (i= 0, table= tables; 03751 table != first_not_own_table && i < number; 03752 table= table->next_global, i++) 03753 { 03754 /* Remove SHOW_VIEW_ACL, because it will be checked during making view */ 03755 table->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL); 03756 } 03757 03758 rw_rdlock(&LOCK_grant); 03759 for (table= tables; 03760 table && number-- && table != first_not_own_table; 03761 table= table->next_global) 03762 { 03763 GRANT_TABLE *grant_table; 03764 sctx = test(table->security_ctx) ? 03765 table->security_ctx : thd->security_ctx; 03766 03767 want_access= orig_want_access; 03768 want_access&= ~sctx->master_access; 03769 if (!want_access) 03770 continue; // ok 03771 03772 if (!(~table->grant.privilege & want_access) || 03773 table->derived || table->schema_table) 03774 { 03775 /* 03776 It is subquery in the FROM clause. VIEW set table->derived after 03777 table opening, but this function always called before table opening. 03778 */ 03779 if (!table->referencing_view) 03780 { 03781 /* 03782 If it's a temporary table created for a subquery in the FROM 03783 clause, or an INFORMATION_SCHEMA table, drop the request for 03784 a privilege. 03785 */ 03786 table->grant.want_privilege= 0; 03787 } 03788 continue; 03789 } 03790 if (!(grant_table= table_hash_search(sctx->host, sctx->ip, 03791 table->db, sctx->priv_user, 03792 table->table_name,0))) 03793 { 03794 want_access &= ~table->grant.privilege; 03795 goto err; // No grants 03796 } 03797 if (show_table) 03798 continue; // We have some priv on this 03799 03800 table->grant.grant_table=grant_table; // Remember for column test 03801 table->grant.version=grant_version; 03802 table->grant.privilege|= grant_table->privs; 03803 table->grant.want_privilege= ((want_access & COL_ACLS) 03804 & ~table->grant.privilege); 03805 03806 if (!(~table->grant.privilege & want_access)) 03807 continue; 03808 03809 if (want_access & ~(grant_table->cols | table->grant.privilege)) 03810 { 03811 want_access &= ~(grant_table->cols | table->grant.privilege); 03812 goto err; // impossible 03813 } 03814 } 03815 rw_unlock(&LOCK_grant); 03816 DBUG_RETURN(0); 03817 03818 err: 03819 rw_unlock(&LOCK_grant); 03820 if (!no_errors) // Not a silent skip of table 03821 { 03822 char command[128]; 03823 get_privilege_desc(command, sizeof(command), want_access); 03824 my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), 03825 command, 03826 sctx->priv_user, 03827 sctx->host_or_ip, 03828 table ? table->table_name : "unknown"); 03829 } 03830 DBUG_RETURN(1); 03831 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool check_grant_all_columns | ( | THD * | thd, | |
| ulong | want_access, | |||
| GRANT_INFO * | grant, | |||
| const char * | db_name, | |||
| const char * | table_name, | |||
| Field_iterator * | fields | |||
| ) |
Definition at line 3972 of file sql_acl.cc.
References column_hash_search(), Field_iterator::end_of_fields(), ER_COLUMNACCESS_DENIED_ERROR, err, get_privilege_desc(), grant_option, st_grant_info::grant_table, grant_version, LOCK_grant, my_error(), MYF, Field_iterator::name(), Field_iterator::next(), st_grant_info::privilege, GRANT_COLUMN::rights, rw_rdlock, rw_unlock, strlen(), table_hash_search(), and st_grant_info::version.
Referenced by check_insert_fields(), and insert_fields().
03975 { 03976 Security_context *sctx= thd->security_ctx; 03977 GRANT_TABLE *grant_table; 03978 GRANT_COLUMN *grant_column; 03979 03980 want_access &= ~grant->privilege; 03981 if (!want_access) 03982 return 0; // Already checked 03983 if (!grant_option) 03984 goto err2; 03985 03986 rw_rdlock(&LOCK_grant); 03987 03988 /* reload table if someone has modified any grants */ 03989 03990 if (grant->version != grant_version) 03991 { 03992 grant->grant_table= 03993 table_hash_search(sctx->host, sctx->ip, db_name, 03994 sctx->priv_user, 03995 table_name, 0); /* purecov: inspected */ 03996 grant->version= grant_version; /* purecov: inspected */ 03997 } 03998 /* The following should always be true */ 03999 if (!(grant_table= grant->grant_table)) 04000 goto err; /* purecov: inspected */ 04001 04002 for (; !fields->end_of_fields(); fields->next()) 04003 { 04004 const char *field_name= fields->name(); 04005 grant_column= column_hash_search(grant_table, field_name, 04006 (uint) strlen(field_name)); 04007 if (!grant_column || (~grant_column->rights & want_access)) 04008 goto err; 04009 } 04010 rw_unlock(&LOCK_grant); 04011 return 0; 04012 04013 err: 04014 rw_unlock(&LOCK_grant); 04015 err2: 04016 char command[128]; 04017 get_privilege_desc(command, sizeof(command), want_access); 04018 my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), 04019 command, 04020 sctx->priv_user, 04021 sctx->host_or_ip, 04022 fields->name(), 04023 table_name); 04024 return 1; 04025 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool check_grant_column | ( | THD * | thd, | |
| GRANT_INFO * | grant, | |||
| const char * | db_name, | |||
| const char * | table_name, | |||
| const char * | name, | |||
| uint | length, | |||
| Security_context * | sctx | |||
| ) |
Definition at line 3852 of file sql_acl.cc.
References column_hash_search(), DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, ER_COLUMNACCESS_DENIED_ERROR, err, get_privilege_desc(), st_grant_info::grant_table, grant_version, LOCK_grant, my_error(), MYF, st_grant_info::privilege, GRANT_COLUMN::rights, rw_rdlock, rw_unlock, table_hash_search(), st_grant_info::version, and st_grant_info::want_privilege.
Referenced by check_column_grant_in_table_ref(), and Item_trigger_field::fix_fields().
03855 { 03856 GRANT_TABLE *grant_table; 03857 GRANT_COLUMN *grant_column; 03858 ulong want_access= grant->want_privilege & ~grant->privilege; 03859 DBUG_ENTER("check_grant_column"); 03860 DBUG_PRINT("enter", ("table: %s want_access: %u", table_name, want_access)); 03861 03862 if (!want_access) 03863 DBUG_RETURN(0); // Already checked 03864 03865 rw_rdlock(&LOCK_grant); 03866 03867 /* reload table if someone has modified any grants */ 03868 03869 if (grant->version != grant_version) 03870 { 03871 grant->grant_table= 03872 table_hash_search(sctx->host, sctx->ip, db_name, 03873 sctx->priv_user, 03874 table_name, 0); /* purecov: inspected */ 03875 grant->version= grant_version; /* purecov: inspected */ 03876 } 03877 if (!(grant_table= grant->grant_table)) 03878 goto err; /* purecov: deadcode */ 03879 03880 grant_column=column_hash_search(grant_table, name, length); 03881 if (grant_column && !(~grant_column->rights & want_access)) 03882 { 03883 rw_unlock(&LOCK_grant); 03884 DBUG_RETURN(0); 03885 } 03886 03887 err: 03888 rw_unlock(&LOCK_grant); 03889 char command[128]; 03890 get_privilege_desc(command, sizeof(command), want_access); 03891 my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), 03892 command, 03893 sctx->priv_user, 03894 sctx->host_or_ip, 03895 name, 03896 table_name); 03897 DBUG_RETURN(1); 03898 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool check_grant_db | ( | THD * | thd, | |
| const char * | db | |||
| ) |
Definition at line 4034 of file sql_acl.cc.
References column_priv_hash, compare_hostname(), error, hash_element(), key_length, LOCK_grant, memcmp(), NAME_LEN, st_hash::records, rw_rdlock, strmov(), and USERNAME_LENGTH.
Referenced by fill_schema_shemata(), get_all_tables(), mysql_change_db(), mysqld_show_create_db(), and prepare_schema_table().
04035 { 04036 Security_context *sctx= thd->security_ctx; 04037 char helping [NAME_LEN+USERNAME_LENGTH+2]; 04038 uint len; 04039 bool error= 1; 04040 04041 len= (uint) (strmov(strmov(helping, sctx->priv_user) + 1, db) - helping) + 1; 04042 rw_rdlock(&LOCK_grant); 04043 04044 for (uint idx=0 ; idx < column_priv_hash.records ; idx++) 04045 { 04046 GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&column_priv_hash, 04047 idx); 04048 if (len < grant_table->key_length && 04049 !memcmp(grant_table->hash_key,helping,len) && 04050 compare_hostname(&grant_table->host, sctx->host, sctx->ip)) 04051 { 04052 error=0; // Found match 04053 break; 04054 } 04055 } 04056 rw_unlock(&LOCK_grant); 04057 return error; 04058 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool check_grant_routine | ( | THD * | thd, | |
| ulong | want_access, | |||
| TABLE_LIST * | procs, | |||
| bool | is_proc, | |||
| bool | no_error | |||
| ) |
Definition at line 4078 of file sql_acl.cc.
References st_table_list::db, DBUG_ENTER, DBUG_RETURN, err, st_table_list::grant, host, LOCK_grant, st_table_list::next_global, st_grant_info::privilege, routine_hash_search(), rw_rdlock, st_table_list::table_name, and user.
Referenced by check_routine_access(), and mysql_execute_command().
04080 { 04081 TABLE_LIST *table; 04082 Security_context *sctx= thd->security_ctx; 04083 char *user= sctx->priv_user; 04084 char *host= sctx->priv_host; 04085 DBUG_ENTER("check_grant_routine"); 04086 04087 want_access&= ~sctx->master_access; 04088 if (!want_access) 04089 DBUG_RETURN(0); // ok 04090 04091 rw_rdlock(&LOCK_grant); 04092 for (table= procs; table; table= table->next_global) 04093 { 04094 GRANT_NAME *grant_proc; 04095 if ((grant_proc= routine_hash_search(host, sctx->ip, table->db, user, 04096 table->table_name, is_proc, 0))) 04097 table->grant.privilege|= grant_proc->privs; 04098 04099 if (want_access & ~table->grant.privilege) 04100 { 04101 want_access &= ~table->grant.privilege; 04102 goto err; 04103 } 04104 } 04105 rw_unlock(&LOCK_grant); 04106 DBUG_RETURN(0); 04107 err: 04108 rw_unlock(&LOCK_grant); 04109 if (!no_errors) 04110 { 04111 char buff[1024]; 04112 const char *command=""; 04113 if (table) 04114 strxmov(buff, table->db, ".", table->table_name, NullS); 04115 if (want_access & EXECUTE_ACL) 04116 command= "execute"; 04117 else if (want_access & ALTER_PROC_ACL) 04118 command= "alter routine"; 04119 else if (want_access & GRANT_ACL) 04120 command= "grant"; 04121 my_error(ER_PROCACCESS_DENIED_ERROR, MYF(0), 04122 command, user, host, table ? buff : "unknown"); 04123 } 04124 DBUG_RETURN(1); 04125 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 4143 of file sql_acl.cc.
References grant_option, LOCK_grant, GRANT_NAME::privs, routine_hash_search(), rw_rdlock, rw_unlock, and SHOW_PROC_ACLS.
Referenced by check_some_routine_access().
04145 { 04146 bool no_routine_acl= 1; 04147 if (grant_option) 04148 { 04149 GRANT_NAME *grant_proc; 04150 Security_context *sctx= thd->security_ctx; 04151 rw_rdlock(&LOCK_grant); 04152 if ((grant_proc= routine_hash_search(sctx->priv_host, 04153 sctx->ip, db, 04154 sctx->priv_user, 04155 name, is_proc, 0))) 04156 no_routine_acl= !(grant_proc->privs & SHOW_PROC_ACLS); 04157 rw_unlock(&LOCK_grant); 04158 } 04159 return no_routine_acl; 04160 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void fill_effective_table_privileges | ( | THD * | thd, | |
| GRANT_INFO * | grant, | |||
| const char * | db, | |||
| const char * | table | |||
| ) |
Definition at line 6271 of file sql_acl.cc.
References acl_get(), DBUG_ENTER, DBUG_PRINT, DBUG_VOID_RETURN, grant_option, st_grant_info::grant_table, grant_version, initialized, LOCK_grant, NO_ACCESS, st_grant_info::privilege, GRANT_NAME::privs, rw_rdlock, rw_unlock, table_hash_search(), and st_grant_info::version.
Referenced by mysql_create_view(), st_table_list::prepare_security(), and Table_triggers_list::process_triggers().
06273 { 06274 Security_context *sctx= thd->security_ctx; 06275 DBUG_ENTER("fill_effective_table_privileges"); 06276 DBUG_PRINT("enter", ("Host: '%s', Ip: '%s', User: '%s', table: `%s`.`%s`", 06277 sctx->priv_host, (sctx->ip ? sctx->ip : "(NULL)"), 06278 (sctx->priv_user ? sctx->priv_user : "(NULL)"), 06279 db, table)); 06280 /* --skip-grants */ 06281 if (!initialized) 06282 { 06283 DBUG_PRINT("info", ("skip grants")); 06284 grant->privilege= ~NO_ACCESS; // everything is allowed 06285 DBUG_PRINT("info", ("privilege 0x%lx", grant->privilege)); 06286 DBUG_VOID_RETURN; 06287 } 06288 06289 /* global privileges */ 06290 grant->privilege= sctx->master_access; 06291 06292 if (!sctx->priv_user) 06293 { 06294 DBUG_PRINT("info", ("privilege 0x%lx", grant->privilege)); 06295 DBUG_VOID_RETURN; // it is slave 06296 } 06297 06298 /* db privileges */ 06299 grant->privilege|= acl_get(sctx->host, sctx->ip, sctx->priv_user, db, 0); 06300 06301 if (!grant_option) 06302 { 06303 DBUG_PRINT("info", ("privilege 0x%lx", grant->privilege)); 06304 DBUG_VOID_RETURN; 06305 } 06306 06307 /* table privileges */ 06308 rw_rdlock(&LOCK_grant); 06309 if (grant->version != grant_version) 06310 { 06311 grant->grant_table= 06312 table_hash_search(sctx->host, sctx->ip, db, 06313 sctx->priv_user, 06314 table, 0); /* purecov: inspected */ 06315 grant->version= grant_version; /* purecov: inspected */ 06316 } 06317 if (grant->grant_table != 0) 06318 { 06319 grant->privilege|= grant->grant_table->privs; 06320 } 06321 rw_unlock(&LOCK_grant); 06322 06323 DBUG_PRINT("info", ("privilege 0x%lx", grant->privilege)); 06324 DBUG_VOID_RETURN; 06325 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulong get_column_grant | ( | THD * | thd, | |
| GRANT_INFO * | grant, | |||
| const char * | db_name, | |||
| const char * | table_name, | |||
| const char * | field_name | |||
| ) |
Definition at line 4209 of file sql_acl.cc.
References column_hash_search(), st_grant_info::grant_table, grant_version, LOCK_grant, st_grant_info::privilege, GRANT_NAME::privs, GRANT_COLUMN::rights, rw_rdlock, rw_unlock, strlen(), table_hash_search(), and st_grant_info::version.
Referenced by check_column_grant_in_table_ref(), Item_field::fix_fields(), get_schema_column_record(), and insert_fields().
04212 { 04213 GRANT_TABLE *grant_table; 04214 GRANT_COLUMN *grant_column; 04215 ulong priv; 04216 04217 rw_rdlock(&LOCK_grant); 04218 /* reload table if someone has modified any grants */ 04219 if (grant->version != grant_version) 04220 { 04221 Security_context *sctx= thd->security_ctx; 04222 grant->grant_table= 04223 table_hash_search(sctx->host, sctx->ip, 04224 db_name, sctx->priv_user, 04225 table_name, 0); /* purecov: inspected */ 04226 grant->version= grant_version; /* purecov: inspected */ 04227 } 04228 04229 if (!(grant_table= grant->grant_table)) 04230 priv= grant->privilege; 04231 else 04232 { 04233 grant_column= column_hash_search(grant_table, field_name, 04234 (uint) strlen(field_name)); 04235 if (!grant_column) 04236 priv= (grant->privilege | grant_table->privs); 04237 else 04238 priv= (grant->privilege | grant_table->privs | grant_column->rights); 04239 } 04240 rw_unlock(&LOCK_grant); 04241 return priv; 04242 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void get_mqh | ( | const char * | user, | |
| const char * | host, | |||
| USER_CONN * | uc | |||
| ) |
Definition at line 4750 of file sql_acl.cc.
References acl_cache, bzero, FALSE, find_acl_user(), initialized, hash_filo::lock, pthread_mutex_lock, pthread_mutex_unlock, ACL_USER::user_resource, and user_conn::user_resources.
Referenced by reset_mqh().
04751 { 04752 ACL_USER *acl_user; 04753 04754 pthread_mutex_lock(&acl_cache->lock); 04755 04756 if (initialized && (acl_user= find_acl_user(host,user, FALSE))) 04757 uc->user_resources= acl_user->user_resource; 04758 else 04759 bzero((char*) &uc->user_resources, sizeof(uc->user_resources)); 04760 04761 pthread_mutex_unlock(&acl_cache->lock); 04762 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 4726 of file sql_acl.cc.
References command_array, command_lengths, DBUG_ASSERT, pos(), start(), and strmov().
Referenced by check_global_access(), check_grant(), check_grant_all_columns(), check_grant_column(), mysql_table_grant(), and Table_triggers_list::process_triggers().
04727 { 04728 uint pos; 04729 char *start=to; 04730 DBUG_ASSERT(max_length >= 30); // For end ',' removal 04731 04732 if (access) 04733 { 04734 max_length--; // Reserve place for end-zero 04735 for (pos=0 ; access ; pos++, access>>=1) 04736 { 04737 if ((access & 1) && 04738 command_lengths[pos] + (uint) (to-start) < max_length) 04739 { 04740 to= strmov(to, command_array[pos]); 04741 *to++=','; 04742 } 04743 } 04744 to--; // Remove end ',' 04745 } 04746 *to=0; 04747 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulong get_table_grant | ( | THD * | thd, | |
| TABLE_LIST * | table | |||
| ) |
Definition at line 4167 of file sql_acl.cc.
References st_table_list::db, db, st_table_list::grant, st_grant_info::grant_table, grant_version, LOCK_grant, NULL, st_grant_info::privilege, GRANT_NAME::privs, rw_rdlock, rw_unlock, table_hash_search(), st_table_list::table_name, and st_grant_info::version.
04168 { 04169 ulong privilege; 04170 Security_context *sctx= thd->security_ctx; 04171 const char *db = table->db ? table->db : thd->db; 04172 GRANT_TABLE *grant_table; 04173 04174 rw_rdlock(&LOCK_grant); 04175 #ifdef EMBEDDED_LIBRARY 04176 grant_table= NULL; 04177 #else 04178 grant_table= table_hash_search(sctx->host, sctx->ip, db, sctx->priv_user, 04179 table->table_name, 0); 04180 #endif 04181 table->grant.grant_table=grant_table; // Remember for column test 04182 table->grant.version=grant_version; 04183 if (grant_table) 04184 table->grant.privilege|= grant_table->privs; 04185 privilege= table->grant.privilege; 04186 rw_unlock(&LOCK_grant); 04187 return privilege; 04188 }
Here is the call graph for this function:

| void grant_free | ( | void | ) |
Definition at line 3431 of file sql_acl.cc.
References column_priv_hash, DBUG_ENTER, DBUG_VOID_RETURN, FALSE, free_root(), func_priv_hash, grant_option, hash_free(), memex, MYF, and proc_priv_hash.
Referenced by clean_up(), and grant_reload().
03432 { 03433 DBUG_ENTER("grant_free"); 03434 grant_option = FALSE; 03435 hash_free(&column_priv_hash); 03436 hash_free(&proc_priv_hash); 03437 hash_free(&func_priv_hash); 03438 free_root(&memex,MYF(0)); 03439 DBUG_VOID_RETURN; 03440 }
Here is the call graph for this function:

Here is the caller graph for this function:

| my_bool grant_init | ( | ) |
Definition at line 3455 of file sql_acl.cc.
References DBUG_ENTER, DBUG_RETURN, grant_reload(), and my_pthread_setspecific_ptr.
Referenced by main().
03456 { 03457 THD *thd; 03458 my_bool return_val; 03459 DBUG_ENTER("grant_init"); 03460 03461 if (!(thd= new THD)) 03462 DBUG_RETURN(1); /* purecov: deadcode */ 03463 thd->thread_stack= (char*) &thd; 03464 thd->store_globals(); 03465 return_val= grant_reload(thd); 03466 delete thd; 03467 /* Remember that we don't have a THD */ 03468 my_pthread_setspecific_ptr(THR_THD, 0); 03469 DBUG_RETURN(return_val); 03470 }
Here is the call graph for this function:

Here is the caller graph for this function:

| my_bool grant_reload | ( | THD * | thd | ) |
Definition at line 3642 of file sql_acl.cc.
References bzero, close_thread_tables(), column_priv_hash, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, free_root(), func_priv_hash, grant_free(), grant_load(), grant_option, grant_version, hash_free(), initialized, LOCK_grant, memex, MYF, proc_priv_hash, rw_unlock, rw_wrlock, simple_open_n_lock_tables(), and TL_READ.
Referenced by grant_init(), and reload_acl_and_cache().
03643 { 03644 TABLE_LIST tables[3]; 03645 HASH old_column_priv_hash, old_proc_priv_hash, old_func_priv_hash; 03646 bool old_grant_option; 03647 MEM_ROOT old_mem; 03648 my_bool return_val= 1; 03649 DBUG_ENTER("grant_reload"); 03650 03651 /* Don't do anything if running with --skip-grant-tables */ 03652 if (!initialized) 03653 DBUG_RETURN(0); 03654 03655 bzero((char*) tables, sizeof(tables)); 03656 tables[0].alias= tables[0].table_name= (char*) "tables_priv"; 03657 tables[1].alias= tables[1].table_name= (char*) "columns_priv"; 03658 tables[2].alias= tables[2].table_name= (char*) "procs_priv"; 03659 tables[0].db= tables[1].db= tables[2].db= (char *) "mysql"; 03660 tables[0].next_local= tables[0].next_global= tables+1; 03661 tables[1].next_local= tables[1].next_global= tables+2; 03662 tables[0].lock_type= tables[1].lock_type= tables[2].lock_type= TL_READ; 03663 03664 /* 03665 To avoid deadlocks we should obtain table locks before 03666 obtaining LOCK_grant rwlock. 03667 */ 03668 if (simple_open_n_lock_tables(thd, tables)) 03669 goto end; 03670 03671 rw_wrlock(&LOCK_grant); 03672 grant_version++; 03673 old_column_priv_hash= column_priv_hash; 03674 old_proc_priv_hash= proc_priv_hash; 03675 old_func_priv_hash= func_priv_hash; 03676 old_grant_option= grant_option; 03677 old_mem= memex; 03678 03679 if ((return_val= grant_load(tables))) 03680 { // Error. Revert to old hash 03681 DBUG_PRINT("error",("Reverting to old privileges")); 03682 grant_free(); /* purecov: deadcode */ 03683 column_priv_hash= old_column_priv_hash; /* purecov: deadcode */ 03684 proc_priv_hash= old_proc_priv_hash; 03685 func_priv_hash= old_func_priv_hash; 03686 grant_option= old_grant_option; /* purecov: deadcode */ 03687 memex= old_mem; /* purecov: deadcode */ 03688 } 03689 else 03690 { 03691 hash_free(&old_column_priv_hash); 03692 hash_free(&old_proc_priv_hash); 03693 hash_free(&old_func_priv_hash); 03694 free_root(&old_mem,MYF(0)); 03695 } 03696 rw_unlock(&LOCK_grant); 03697 end: 03698 close_thread_tables(thd); 03699 DBUG_RETURN(return_val); 03700 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool hostname_requires_resolving | ( | const char * | hostname | ) |
Definition at line 1765 of file sql_acl.cc.
References FALSE, my_localhost, my_strnncoll, strlen(), system_charset_info, and TRUE.
Referenced by acl_load(), grant_load(), and mysql_execute_command().
01766 { 01767 char cur; 01768 if (!hostname) 01769 return FALSE; 01770 int namelen= strlen(hostname); 01771 int lhlen= strlen(my_localhost); 01772 if ((namelen == lhlen) && 01773 !my_strnncoll(system_charset_info, (const uchar *)hostname, namelen, 01774 (const uchar *)my_localhost, strlen(my_localhost))) 01775 return FALSE; 01776 for (; (cur=*hostname); hostname++) 01777 { 01778 if ((cur != '%') && (cur != '_') && (cur != '.') && (cur != '/') && 01779 ((cur < '0') || (cur > '9'))) 01780 return TRUE; 01781 } 01782 return FALSE; 01783 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool is_acl_user | ( | const char * | host, | |
| const char * | user | |||
| ) |
Definition at line 1657 of file sql_acl.cc.
References acl_cache, find_acl_user(), initialized, hash_filo::lock, NULL, pthread_mutex_lock, pthread_mutex_unlock, TRUE, and VOID.
Referenced by Table_triggers_list::create_trigger(), mysql_create_view(), and mysql_execute_command().
01658 { 01659 bool res; 01660 01661 /* --skip-grants */ 01662 if (!initialized) 01663 return TRUE; 01664 01665 VOID(pthread_mutex_lock(&acl_cache->lock)); 01666 res= find_acl_user(host, user, TRUE) != NULL; 01667 VOID(pthread_mutex_unlock(&acl_cache->lock)); 01668 return res; 01669 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5387 of file sql_acl.cc.
References acl_cache, append_user(), String::c_ptr_safe(), close_thread_tables(), DBUG_ENTER, DBUG_RETURN, ER_CANNOT_USER, get_current_user(), GRANT_TABLES, handle_grant_data(), st_lex_user::host, HOSTNAME_LENGTH, LEX_STRING::length, list(), hash_filo::lock, LOCK_grant, my_error(), MYF, NULL, open_grant_tables(), pthread_mutex_lock, pthread_mutex_unlock, replace_user_table(), rw_unlock, rw_wrlock, TRUE, st_lex_user::user, USERNAME_LENGTH, and VOID.
Referenced by mysql_execute_command().
05388 { 05389 int result; 05390 String wrong_users; 05391 ulong sql_mode; 05392 LEX_USER *user_name, *tmp_user_name; 05393 List_iterator <LEX_USER> user_list(list); 05394 TABLE_LIST tables[GRANT_TABLES]; 05395 DBUG_ENTER("mysql_create_user"); 05396 05397 /* CREATE USER may be skipped on replication client. */ 05398 if ((result= open_grant_tables(thd, tables))) 05399 DBUG_RETURN(result != 1); 05400 05401 rw_wrlock(&LOCK_grant); 05402 VOID(pthread_mutex_lock(&acl_cache->lock)); 05403 05404 while ((tmp_user_name= user_list++)) 05405 { 05406 if (!(user_name= get_current_user(thd, tmp_user_name))) 05407 { 05408 result= TRUE; 05409 continue; 05410 } 05411 05412 if (user_name->host.length > HOSTNAME_LENGTH || 05413 user_name->user.length > USERNAME_LENGTH) 05414 { 05415 append_user(&wrong_users, user_name); 05416 result= TRUE; 05417 continue; 05418 } 05419 05420 /* 05421 Search all in-memory structures and grant tables 05422 for a mention of the new user name. 05423 */ 05424 if (handle_grant_data(tables, 0, user_name, NULL)) 05425 { 05426 append_user(&wrong_users, user_name); 05427 result= TRUE; 05428 continue; 05429 } 05430 05431 sql_mode= thd->variables.sql_mode; 05432 if (replace_user_table(thd, tables[0].table, *user_name, 0, 0, 1, 0)) 05433 { 05434 append_user(&wrong_users, user_name); 05435 result= TRUE; 05436 } 05437 } 05438 05439 VOID(pthread_mutex_unlock(&acl_cache->lock)); 05440 rw_unlock(&LOCK_grant); 05441 close_thread_tables(thd); 05442 if (result) 05443 my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr_safe()); 05444 DBUG_RETURN(result); 05445 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5461 of file sql_acl.cc.
References acl_cache, append_user(), String::c_ptr_safe(), close_thread_tables(), DBUG_ENTER, DBUG_RETURN, ER_CANNOT_USER, get_current_user(), GRANT_TABLES, handle_grant_data(), list(), hash_filo::lock, LOCK_grant, my_error(), MYF, NULL, open_grant_tables(), pthread_mutex_lock, pthread_mutex_unlock, rebuild_check_host(), rw_unlock, rw_wrlock, TRUE, and VOID.
Referenced by mysql_execute_command().
05462 { 05463 int result; 05464 String wrong_users; 05465 LEX_USER *user_name, *tmp_user_name; 05466 List_iterator <LEX_USER> user_list(list); 05467 TABLE_LIST tables[GRANT_TABLES]; 05468 DBUG_ENTER("mysql_drop_user"); 05469 05470 /* DROP USER may be skipped on replication client. */ 05471 if ((result= open_grant_tables(thd, tables))) 05472 DBUG_RETURN(result != 1); 05473 05474 rw_wrlock(&LOCK_grant); 05475 VOID(pthread_mutex_lock(&acl_cache->lock)); 05476 05477 while ((tmp_user_name= user_list++)) 05478 { 05479 user_name= get_current_user(thd, tmp_user_name); 05480 if (!(user_name= get_current_user(thd, tmp_user_name))) 05481 { 05482 result= TRUE; 05483 continue; 05484 } 05485 if (handle_grant_data(tables, 1, user_name, NULL) <= 0) 05486 { 05487 append_user(&wrong_users, user_name); 05488 result= TRUE; 05489 } 05490 } 05491 05492 /* Rebuild 'acl_check_hosts' since 'acl_users' has been modified */ 05493 rebuild_check_host(); 05494 05495 VOID(pthread_mutex_unlock(&acl_cache->lock)); 05496 rw_unlock(&LOCK_grant); 05497 close_thread_tables(thd); 05498 if (result) 05499 my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe()); 05500 DBUG_RETURN(result); 05501 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool mysql_grant | ( | THD * | thd, | |
| const char * | db, | |||
| List< LEX_USER > & | user_list, | |||
| ulong | rights, | |||
| bool | revoke | |||
| ) |
Definition at line 3320 of file sql_acl.cc.
References acl_cache, bzero, close_thread_tables(), DB_ACLS, DBUG_ENTER, DBUG_RETURN, ER, ER_GRANT_WRONG_HOST_OR_USER, ER_OPTION_PREVENTS_STATEMENT, ER_WRONG_USAGE, FALSE, files_charset_info, get_current_user(), grant_version, HOSTNAME_LENGTH, initialized, Rpl_filter::is_on(), list(), hash_filo::lock, LOCK_grant, lower_case_table_names, MODE_NO_AUTO_CREATE_USER, my_casedn_str, my_error(), my_message(), MYF, NAME_LEN, pthread_mutex_lock, pthread_mutex_unlock, replace_db_table(), replace_user_table(), rpl_filter, rw_unlock, rw_wrlock, send_ok(), simple_open_n_lock_tables(), Str, strmov(), Rpl_filter::tables_ok(), test, test_if_create_new_users(), TL_WRITE, TRUE, USERNAME_LENGTH, and VOID.
Referenced by mysql_execute_command().
03322 { 03323 List_iterator <LEX_USER> str_list (list); 03324 LEX_USER *Str, *tmp_Str; 03325 char tmp_db[NAME_LEN+1]; 03326 bool create_new_users=0; 03327 TABLE_LIST tables[2]; 03328 DBUG_ENTER("mysql_grant"); 03329 if (!initialized) 03330 { 03331 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), 03332 "--skip-grant-tables"); /* purecov: tested */ 03333 DBUG_RETURN(TRUE); /* purecov: tested */ 03334 } 03335 03336 if (lower_case_table_names && db) 03337 { 03338 strmov(tmp_db,db); 03339 my_casedn_str(files_charset_info, tmp_db); 03340 db=tmp_db; 03341 } 03342 03343 /* open the mysql.user and mysql.db tables */ 03344 bzero((char*) &tables,sizeof(tables)); 03345 tables[0].alias=tables[0].table_name=(char*) "user"; 03346 tables[1].alias=tables[1].table_name=(char*) "db"; 03347 tables[0].next_local= tables[0].next_global= tables+1; 03348 tables[0].lock_type=tables[1].lock_type=TL_WRITE; 03349 tables[0].db=tables[1].db=(char*) "mysql"; 03350 03351 #ifdef HAVE_REPLICATION 03352 /* 03353 GRANT and REVOKE are applied the slave in/exclusion rules as they are 03354 some kind of updates to the mysql.% tables. 03355 */ 03356 if (thd->slave_thread && rpl_filter->is_on()) 03357 { 03358 /* 03359 The tables must be marked "updating" so that tables_ok() takes them into 03360 account in tests. 03361 */ 03362 tables[0].updating= tables[1].updating= 1; 03363 if (!(thd->spcont || rpl_filter->tables_ok(0, tables))) 03364 DBUG_RETURN(FALSE); 03365 } 03366 #endif 03367 03368 if (simple_open_n_lock_tables(thd,tables)) 03369 { // This should never happen 03370 close_thread_tables(thd); /* purecov: deadcode */ 03371 DBUG_RETURN(TRUE); /* purecov: deadcode */ 03372 } 03373 03374 if (!revoke_grant) 03375 create_new_users= test_if_create_new_users(thd); 03376 03377 /* go through users in user_list */ 03378 rw_wrlock(&LOCK_grant); 03379 VOID(pthread_mutex_lock(&acl_cache->lock)); 03380 grant_version++; 03381 03382 int result=0; 03383 while ((tmp_Str = str_list++)) 03384 { 03385 if (!(Str= get_current_user(thd, tmp_Str))) 03386 { 03387 result= TRUE; 03388 continue; 03389 } 03390 if (Str->host.length > HOSTNAME_LENGTH || 03391 Str->user.length > USERNAME_LENGTH) 03392 { 03393 my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER), 03394 MYF(0)); 03395 result= -1; 03396 continue; 03397 } 03398 if (replace_user_table(thd, tables[0].table, *Str, 03399 (!db ? rights : 0), revoke_grant, create_new_users, 03400 test(thd->variables.sql_mode & 03401 MODE_NO_AUTO_CREATE_USER))) 03402 result= -1; 03403 else if (db) 03404 { 03405 ulong db_rights= rights & DB_ACLS; 03406 if (db_rights == rights) 03407 { 03408 if (replace_db_table(tables[1].table, db, *Str, db_rights, 03409 revoke_grant)) 03410 result= -1; 03411 } 03412 else 03413 { 03414 my_error(ER_WRONG_USAGE, MYF(0), "DB GRANT", "GLOBAL PRIVILEGES"); 03415 result= -1; 03416 } 03417 } 03418 } 03419 VOID(pthread_mutex_unlock(&acl_cache->lock)); 03420 rw_unlock(&LOCK_grant); 03421 close_thread_tables(thd); 03422 03423 if (!result) 03424 send_ok(thd); 03425 DBUG_RETURN(result); 03426 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5517 of file sql_acl.cc.
References acl_cache, append_user(), String::c_ptr_safe(), close_thread_tables(), DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, ER_CANNOT_USER, get_current_user(), GRANT_TABLES, handle_grant_data(), list(), hash_filo::lock, LOCK_grant, my_error(), MYF, NULL, open_grant_tables(), pthread_mutex_lock, pthread_mutex_unlock, rebuild_check_host(), rw_unlock, rw_wrlock, TRUE, and VOID.
Referenced by mysql_execute_command().
05518 { 05519 int result; 05520 String wrong_users; 05521 LEX_USER *user_from, *tmp_user_from; 05522 LEX_USER *user_to, *tmp_user_to; 05523 List_iterator <LEX_USER> user_list(list); 05524 TABLE_LIST tables[GRANT_TABLES]; 05525 DBUG_ENTER("mysql_rename_user"); 05526 05527 /* RENAME USER may be skipped on replication client. */ 05528 if ((result= open_grant_tables(thd, tables))) 05529 DBUG_RETURN(result != 1); 05530 05531 rw_wrlock(&LOCK_grant); 05532 VOID(pthread_mutex_lock(&acl_cache->lock)); 05533 05534 while ((tmp_user_from= user_list++)) 05535 { 05536 if (!(user_from= get_current_user(thd, tmp_user_from))) 05537 { 05538 result= TRUE; 05539 continue; 05540 } 05541 tmp_user_to= user_list++; 05542 if (!(user_to= get_current_user(thd, tmp_user_to))) 05543 { 05544 result= TRUE; 05545 continue; 05546 } 05547 DBUG_ASSERT(user_to != 0); /* Syntax enforces pairs of users. */ 05548 05549 /* 05550 Search all in-memory structures and grant tables 05551 for a mention of the new user name. 05552 */ 05553 if (handle_grant_data(tables, 0, user_to, NULL) || 05554 handle_grant_data(tables, 0, user_from, user_to) <= 0) 05555 { 05556 append_user(&wrong_users, user_from); 05557 result= TRUE; 05558 } 05559 } 05560 05561 /* Rebuild 'acl_check_hosts' since 'acl_users' has been modified */ 05562 rebuild_check_host(); 05563 05564 VOID(pthread_mutex_unlock(&acl_cache->lock)); 05565 rw_unlock(&LOCK_grant); 05566 close_thread_tables(thd); 05567 if (result) 05568 my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe()); 05569 DBUG_RETURN(result); 05570 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5587 of file sql_acl.cc.
References acl_cache, acl_dbs, column_priv_hash, counter, GRANT_NAME::db, ACL_DB::db, DBUG_ENTER, DBUG_RETURN, dynamic_element, st_dynamic_array::elements, find_acl_user(), get_current_user(), GRANT_TABLES, hash_element(), GRANT_NAME::host, ACL_DB::host, host, st_lex_user::host, acl_host_and_ip::hostname, list(), hash_filo::lock, LOCK_grant, my_strcasecmp, open_grant_tables(), pthread_mutex_lock, st_hash::records, replace_column_table(), replace_db_table(), replace_table_table(), replace_user_table(), rw_wrlock, sql_print_error(), LEX_STRING::str, strcmp(), system_charset_info, GRANT_NAME::tname, TRUE, GRANT_NAME::user, ACL_DB::user, user, st_lex_user::user, and VOID.
Referenced by mysql_execute_command().
05588 { 05589 uint counter, revoked, is_proc; 05590 int result; 05591 ACL_DB *acl_db; 05592 TABLE_LIST tables[GRANT_TABLES]; 05593 DBUG_ENTER("mysql_revoke_all"); 05594 05595 if ((result= open_grant_tables(thd, tables))) 05596 DBUG_RETURN(result != 1); 05597 05598 rw_wrlock(&LOCK_grant); 05599 VOID(pthread_mutex_lock(&acl_cache->lock)); 05600 05601 LEX_USER *lex_user, *tmp_lex_user; 05602 List_iterator <LEX_USER> user_list(list); 05603 while ((tmp_lex_user= user_list++)) 05604 { 05605 if (!(lex_user= get_current_user(thd, tmp_lex_user))) 05606 { 05607 result= -1; 05608 continue; 05609 } 05610 if (!find_acl_user(lex_user->host.str, lex_user->user.str, TRUE)) 05611 { 05612 sql_print_error("REVOKE ALL PRIVILEGES, GRANT: User '%s'@'%s' does not " 05613 "exists", lex_user->user.str, lex_user->host.str); 05614 result= -1; 05615 continue; 05616 } 05617 05618 if (replace_user_table(thd, tables[0].table, 05619 *lex_user, ~(ulong)0, 1, 0, 0)) 05620 { 05621 result= -1; 05622 continue; 05623 } 05624 05625 /* Remove db access privileges */ 05626 /* 05627 Because acl_dbs and column_priv_hash shrink and may re-order 05628 as privileges are removed, removal occurs in a repeated loop 05629 until no more privileges are revoked. 05630 */ 05631 do 05632 { 05633 for (counter= 0, revoked= 0 ; counter < acl_dbs.elements ; ) 05634 { 05635 const char *user,*host; 05636 05637 acl_db=dynamic_element(&acl_dbs,counter,ACL_DB*); 05638 if (!(user=acl_db->user)) 05639 user= ""; 05640 if (!(host=acl_db->host.hostname)) 05641 host= ""; 05642 05643 if (!strcmp(lex_user->user.str,user) && 05644 !my_strcasecmp(system_charset_info, lex_user->host.str, host)) 05645 { 05646 if (!replace_db_table(tables[1].table, acl_db->db, *lex_user, 05647 ~(ulong)0, 1)) 05648 { 05649 /* 05650 Don't increment counter as replace_db_table deleted the 05651 current element in acl_dbs. 05652 */ 05653 revoked= 1; 05654 continue; 05655 } 05656 result= -1; // Something went wrong 05657 } 05658 counter++; 05659 } 05660 } while (revoked); 05661 05662 /* Remove column access */ 05663 do 05664 { 05665 for (counter= 0, revoked= 0 ; counter < column_priv_hash.records ; ) 05666 { 05667 const char *user,*host; 05668 GRANT_TABLE *grant_table= (GRANT_TABLE*)hash_element(&column_priv_hash, 05669 counter); 05670 if (!(user=grant_table->user)) 05671 user= ""; 05672 if (!(host=grant_table->host.hostname)) 05673 host= ""; 05674 05675 if (!strcmp(lex_user->user.str,user) && 05676 !my_strcasecmp(system_charset_info, lex_user->host.str, host)) 05677 { 05678 if (replace_table_table(thd,grant_table,tables[2].table,*lex_user, 05679 grant_table->db, 05680 grant_table->tname, 05681 ~(ulong)0, 0, 1)) 05682 { 05683 result= -1; 05684 } 05685 else 05686 { 05687 if (!grant_table->cols) 05688 { 05689 revoked= 1; 05690 continue; 05691 } 05692 List<LEX_COLUMN> columns; 05693 if (!replace_column_table(grant_table,tables[3].table, *lex_user, 05694 columns, 05695 grant_table->db, 05696 grant_table->tname, 05697 ~(ulong)0, 1)) 05698 { 05699 revoked= 1; 05700 continue; 05701 } 05702 result= -1; 05703 } 05704 } 05705 counter++; 05706 } 05707 } while (revoked); 05708 05709 /* Remove procedure access */ 05710 for (is_proc=0; is_proc<2; is_proc++) do { 05711 HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash; 05712 for (counter= 0, revoked= 0 ; counter < hash->records ; ) 05713 { 05714 const char *user,*host; 05715 GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(hash, counter); 05716 if (!(user=grant_proc->user)) 05717 user= ""; 05718 if (!(host=grant_proc->host.hostname)) 05719 host= ""; 05720 05721 if (!strcmp(lex_user->user.str,user) && 05722 !my_strcasecmp(system_charset_info, lex_user->host.str, host)) 05723 { 05724 if (!replace_routine_table(thd,grant_proc,tables[4].table,*lex_user, 05725 grant_proc->db, 05726 grant_proc->tname, 05727 is_proc, 05728 ~(ulong)0, 1)) 05729 { 05730 revoked= 1; 05731 continue; 05732 } 05733 result= -1; // Something went wrong 05734 } 05735 counter++; 05736 } 05737 } while (revoked); 05738 } 05739 05740 VOID(pthread_mutex_unlock(&acl_cache->lock)); 05741 rw_unlock(&LOCK_grant); 05742 close_thread_tables(thd); 05743 05744 if (result) 05745 my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0)); 05746 05747 DBUG_RETURN(result); 05748 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool mysql_routine_grant | ( | THD * | thd, | |
| TABLE_LIST * | table, | |||
| bool | is_proc, | |||
| List< LEX_USER > & | user_list, | |||
| ulong | rights, | |||
| bool | revoke, | |||
| bool | no_error | |||
| ) |
Definition at line 3174 of file sql_acl.cc.
References acl_cache, bzero, close_thread_tables(), st_table_list::db, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, ER, ER_GRANT_WRONG_HOST_OR_USER, ER_ILLEGAL_GRANT_FOR_TABLE, ER_NONEXISTING_PROC_GRANT, ER_OPTION_PREVENTS_STATEMENT, error, FALSE, func_priv_hash, get_current_user(), grant_option, HOSTNAME_LENGTH, initialized, Rpl_filter::is_on(), hash_filo::lock, LOCK_grant, memex, MODE_NO_AUTO_CREATE_USER, my_error(), my_hash_insert(), my_message(), MYF, NullS, PROC_ACLS, proc_priv_hash, pthread_mutex_lock, pthread_mutex_unlock, replace_routine_table(), replace_user_table(), routine_hash_search(), rpl_filter, rw_unlock, rw_wrlock, send_ok(), simple_open_n_lock_tables(), sp_exist_routines(), Str, st_table_list::table_name, Rpl_filter::tables_ok(), test, test_if_create_new_users(), TL_WRITE, TRUE, and USERNAME_LENGTH.
Referenced by mysql_execute_command(), and sp_grant_privileges().
03177 { 03178 List_iterator <LEX_USER> str_list (user_list); 03179 LEX_USER *Str, *tmp_Str; 03180 TABLE_LIST tables[2]; 03181 bool create_new_users=0, result=0; 03182 char *db_name, *table_name; 03183 DBUG_ENTER("mysql_routine_grant"); 03184 03185 if (!initialized) 03186 { 03187 if (!no_error) 03188 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), 03189 "--skip-grant-tables"); 03190 DBUG_RETURN(TRUE); 03191 } 03192 if (rights & ~PROC_ACLS) 03193 { 03194 if (!no_error) 03195 my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE), 03196 MYF(0)); 03197 DBUG_RETURN(TRUE); 03198 } 03199 03200 if (!revoke_grant) 03201 { 03202 if (sp_exist_routines(thd, table_list, is_proc, no_error)<0) 03203 DBUG_RETURN(TRUE); 03204 } 03205 03206 /* open the mysql.user and mysql.procs_priv tables */ 03207 03208 bzero((char*) &tables,sizeof(tables)); 03209 tables[0].alias=tables[0].table_name= (char*) "user"; 03210 tables[1].alias=tables[1].table_name= (char*) "procs_priv"; 03211 tables[0].next_local= tables[0].next_global= tables+1; 03212 tables[0].lock_type=tables[1].lock_type=TL_WRITE; 03213 tables[0].db=tables[1].db=(char*) "mysql"; 03214 03215 #ifdef HAVE_REPLICATION 03216 /* 03217 GRANT and REVOKE are applied the slave in/exclusion rules as they are 03218 some kind of updates to the mysql.% tables. 03219 */ 03220 if (thd->slave_thread && rpl_filter->is_on()) 03221 { 03222 /* 03223 The tables must be marked "updating" so that tables_ok() takes them into 03224 account in tests. 03225 */ 03226 tables[0].updating= tables[1].updating= 1; 03227 if (!(thd->spcont || rpl_filter->tables_ok(0, tables))) 03228 DBUG_RETURN(FALSE); 03229 } 03230 #endif 03231 03232 if (simple_open_n_lock_tables(thd,tables)) 03233 { // Should never happen 03234 close_thread_tables(thd); 03235 DBUG_RETURN(TRUE); 03236 } 03237 03238 if (!revoke_grant) 03239 create_new_users= test_if_create_new_users(thd); 03240 rw_wrlock(&LOCK_grant); 03241 pthread_mutex_lock(&acl_cache->lock); 03242 MEM_ROOT *old_root= thd->mem_root; 03243 thd->mem_root= &memex; 03244 03245 DBUG_PRINT("info",("now time to iterate and add users")); 03246 03247 while ((tmp_Str= str_list++)) 03248 { 03249 int error; 03250 GRANT_NAME *grant_name; 03251 if (!(Str= get_current_user(thd, tmp_Str))) 03252 { 03253 result= TRUE; 03254 continue; 03255 } 03256 if (Str->host.length > HOSTNAME_LENGTH || 03257 Str->user.length > USERNAME_LENGTH) 03258 { 03259 if (!no_error) 03260 my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER), 03261 MYF(0)); 03262 result= TRUE; 03263 continue; 03264 } 03265 /* Create user if needed */ 03266 error=replace_user_table(thd, tables[0].table, *Str, 03267 0, revoke_grant, create_new_users, 03268 test(thd->variables.sql_mode & 03269 MODE_NO_AUTO_CREATE_USER)); 03270 if (error) 03271 { 03272 result= TRUE; // Remember error 03273 continue; // Add next user 03274 } 03275 03276 db_name= table_list->db; 03277 table_name= table_list->table_name; 03278 03279 grant_name= routine_hash_search(Str->host.str, NullS, db_name, 03280 Str->user.str, table_name, is_proc, 1); 03281 if (!grant_name) 03282 { 03283 if (revoke_grant) 03284 { 03285 if (!no_error) 03286 my_error(ER_NONEXISTING_PROC_GRANT, MYF(0), 03287 Str->user.str, Str->host.str, table_name); 03288 result= TRUE; 03289 continue; 03290 } 03291 grant_name= new GRANT_NAME(Str->host.str, db_name, 03292 Str->user.str, table_name, 03293 rights); 03294 if (!grant_name) 03295 { 03296 result= TRUE; 03297 continue; 03298 } 03299 my_hash_insert(is_proc ? &proc_priv_hash : &func_priv_hash,(byte*) grant_name); 03300 } 03301 03302 if (replace_routine_table(thd, grant_name, tables[1].table, *Str, 03303 db_name, table_name, is_proc, rights, revoke_grant)) 03304 { 03305 result= TRUE; 03306 continue; 03307 } 03308 } 03309 grant_option=TRUE; 03310 thd->mem_root= old_root; 03311 pthread_mutex_unlock(&acl_cache->lock); 03312 rw_unlock(&LOCK_grant); 03313 if (!result && !no_error) 03314 send_ok(thd); 03315 /* Tables are automatically closed */ 03316 DBUG_RETURN(result); 03317 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 4289 of file sql_acl.cc.
References ACL_ACCESS::access, acl_cache, acl_dbs, add_user_option(), String::append(), append_identifier(), String::charset(), GRANT_TABLE::cols, column_priv_hash, user_resources::conn_per_hour, counter, ACL_DB::db, db, DB_ACLS, DBUG_ENTER, DBUG_RETURN, dynamic_element, st_dynamic_array::elements, ER, ER_GRANT_WRONG_HOST_OR_USER, ER_NONEXISTING_GRANT, ER_OPTION_PREVENTS_STATEMENT, error, find_acl_user(), GLOBAL_ACLS, GRANT_ACL, GRANT_TABLE::hash_columns, hash_element(), GRANT_NAME::host, ACL_DB::host, host, st_lex_user::host, acl_host_and_ip::hostname, HOSTNAME_LENGTH, index(), initialized, String::length(), LEX_STRING::length, LINT_INIT, hash_filo::lock, LOCK_grant, make_password_from_salt(), make_password_from_salt_323(), Item::max_length, my_charset_latin1, my_error(), my_message(), my_strcasecmp, MYF, Item::name, NullS, Protocol::prepare_for_resend(), GRANT_NAME::privs, pthread_mutex_lock, pthread_mutex_unlock, String::ptr(), List< T >::push_back(), user_resources::questions, st_hash::records, rw_rdlock, rw_unlock, ACL_USER::salt, ACL_USER::salt_len, SCRAMBLE_LENGTH, SCRAMBLED_PASSWORD_CHAR_LENGTH, SELECT_ACL, Protocol::SEND_EOF, Protocol::send_fields(), Protocol::SEND_NUM_ROWS, ACL_USER::ssl_cipher, ACL_USER::ssl_type, SSL_TYPE_ANY, SSL_TYPE_SPECIFIED, SSL_TYPE_X509, Protocol::store(), LEX_STRING::str, strcmp(), STRING_WITH_LEN, strlen(), strxmov(), system_charset_info, TABLE_ACLS, test_all_bits, TRUE, user_resources::updates, GRANT_NAME::user, ACL_DB::user, user, st_lex_user::user, user_resources::user_conn, ACL_USER::user_resource, USERNAME_LENGTH, VOID, Protocol::write(), ACL_USER::x509_issuer, and ACL_USER::x509_subject.
Referenced by mysql_execute_command().
04290 { 04291 ulong want_access; 04292 uint counter,index; 04293 int error = 0; 04294 ACL_USER *acl_user; 04295 ACL_DB *acl_db; 04296 char buff[1024]; 04297 Protocol *protocol= thd->protocol; 04298 DBUG_ENTER("mysql_show_grants"); 04299 04300 LINT_INIT(acl_user); 04301 if (!initialized) 04302 { 04303 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables"); 04304 DBUG_RETURN(TRUE); 04305 } 04306 04307 if (lex_user->host.length > HOSTNAME_LENGTH || 04308 lex_user->user.length > USERNAME_LENGTH) 04309 { 04310 my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER), 04311 MYF(0)); 04312 DBUG_RETURN(TRUE); 04313 } 04314 04315 rw_rdlock(&LOCK_grant); 04316 VOID(pthread_mutex_lock(&acl_cache->lock)); 04317 04318 acl_user= find_acl_user(lex_user->host.str, lex_user->user.str, TRUE); 04319 if (!acl_user) 04320 { 04321 VOID(pthread_mutex_unlock(&acl_cache->lock)); 04322 rw_unlock(&LOCK_grant); 04323 04324 my_error(ER_NONEXISTING_GRANT, MYF(0), 04325 lex_user->user.str, lex_user->host.str); 04326 DBUG_RETURN(TRUE); 04327 } 04328 04329 Item_string *field=new Item_string("",0,&my_charset_latin1); 04330 List<Item> field_list; 04331 field->name=buff; 04332 field->max_length=1024; 04333 strxmov(buff,"Grants for ",lex_user->user.str,"@", 04334 lex_user->host.str,NullS); 04335 field_list.push_back(field); 04336 if (protocol->send_fields(&field_list, 04337 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) 04338 { 04339 VOID(pthread_mutex_unlock(&acl_cache->lock)); 04340 rw_unlock(&LOCK_grant); 04341 04342 DBUG_RETURN(TRUE); 04343 } 04344 04345 /* Add first global access grants */ 04346 { 04347 String global(buff,sizeof(buff),system_charset_info); 04348 global.length(0); 04349 global.append(STRING_WITH_LEN("GRANT ")); 04350 04351 want_access= acl_user->access; 04352 if (test_all_bits(want_access, (GLOBAL_ACLS & ~ GRANT_ACL))) 04353 global.append(STRING_WITH_LEN("ALL PRIVILEGES")); 04354 else if (!(want_access & ~GRANT_ACL)) 04355 global.append(STRING_WITH_LEN("USAGE")); 04356 else 04357 { 04358 bool found=0; 04359 ulong j,test_access= want_access & ~GRANT_ACL; 04360 for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1) 04361 { 04362 if (test_access & j) 04363 { 04364 if (found) 04365 global.append(STRING_WITH_LEN(", ")); 04366 found=1; 04367 global.append(command_array[counter],command_lengths[counter]); 04368 } 04369 } 04370 } 04371 global.append (STRING_WITH_LEN(" ON *.* TO '")); 04372 global.append(lex_user->user.str, lex_user->user.length, 04373 system_charset_info); 04374 global.append (STRING_WITH_LEN("'@'")); 04375 global.append(lex_user->host.str,lex_user->host.length, 04376 system_charset_info); 04377 global.append ('\''); 04378 if (acl_user->salt_len) 04379 { 04380 char passwd_buff[SCRAMBLED_PASSWORD_CHAR_LENGTH+1]; 04381 if (acl_user->salt_len == SCRAMBLE_LENGTH) 04382 make_password_from_salt(passwd_buff, acl_user->salt); 04383 else 04384 make_password_from_salt_323(passwd_buff, (ulong *) acl_user->salt); 04385 global.append(STRING_WITH_LEN(" IDENTIFIED BY PASSWORD '")); 04386 global.append(passwd_buff); 04387 global.append('\''); 04388 } 04389 /* "show grants" SSL related stuff */ 04390 if (acl_user->ssl_type == SSL_TYPE_ANY) 04391 global.append(STRING_WITH_LEN(" REQUIRE SSL")); 04392 else if (acl_user->ssl_type == SSL_TYPE_X509) 04393 global.append(STRING_WITH_LEN(" REQUIRE X509")); 04394 else if (acl_user->ssl_type == SSL_TYPE_SPECIFIED) 04395 { 04396 int ssl_options = 0; 04397 global.append(STRING_WITH_LEN(" REQUIRE ")); 04398 if (acl_user->x509_issuer) 04399 { 04400 ssl_options++; 04401 global.append(STRING_WITH_LEN("ISSUER \'")); 04402 global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer)); 04403 global.append('\''); 04404 } 04405 if (acl_user->x509_subject) 04406 { 04407 if (ssl_options++) 04408 global.append(' '); 04409 global.append(STRING_WITH_LEN("SUBJECT \'")); 04410 global.append(acl_user->x509_subject,strlen(acl_user->x509_subject), 04411 system_charset_info); 04412 global.append('\''); 04413 } 04414 if (acl_user->ssl_cipher) 04415 { 04416 if (ssl_options++) 04417 global.append(' '); 04418 global.append(STRING_WITH_LEN("CIPHER '")); 04419 global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher), 04420 system_charset_info); 04421 global.append('\''); 04422 } 04423 } 04424 if ((want_access & GRANT_ACL) || 04425 (acl_user->user_resource.questions || 04426 acl_user->user_resource.updates || 04427 acl_user->user_resource.conn_per_hour || 04428 acl_user->user_resource.user_conn)) 04429 { 04430 global.append(STRING_WITH_LEN(" WITH")); 04431 if (want_access & GRANT_ACL) 04432 global.append(STRING_WITH_LEN(" GRANT OPTION")); 04433 add_user_option(&global, acl_user->user_resource.questions, 04434 "MAX_QUERIES_PER_HOUR"); 04435 add_user_option(&global, acl_user->user_resource.updates, 04436 "MAX_UPDATES_PER_HOUR"); 04437 add_user_option(&global, acl_user->user_resource.conn_per_hour, 04438 "MAX_CONNECTIONS_PER_HOUR"); 04439 add_user_option(&global, acl_user->user_resource.user_conn, 04440 "MAX_USER_CONNECTIONS"); 04441 } 04442 protocol->prepare_for_resend(); 04443 protocol->store(global.ptr(),global.length(),global.charset()); 04444 if (protocol->write()) 04445 { 04446 error= -1; 04447 goto end; 04448 } 04449 } 04450 04451 /* Add database access */ 04452 for (counter=0 ; counter < acl_dbs.elements ; counter++) 04453 { 04454 const char *user, *host; 04455 04456 acl_db=dynamic_element(&acl_dbs,counter,ACL_DB*); 04457 if (!(user=acl_db->user)) 04458 user= ""; 04459 if (!(host=acl_db->host.hostname)) 04460 host= ""; 04461 04462 if (!strcmp(lex_user->user.str,user) && 04463 !my_strcasecmp(system_charset_info, lex_user->host.str, host)) 04464 { 04465 want_access=acl_db->access; 04466 if (want_access) 04467 { 04468 String db(buff,sizeof(buff),system_charset_info); 04469 db.length(0); 04470 db.append(STRING_WITH_LEN("GRANT ")); 04471 04472 if (test_all_bits(want_access,(DB_ACLS & ~GRANT_ACL))) 04473 db.append(STRING_WITH_LEN("ALL PRIVILEGES")); 04474 else if (!(want_access & ~GRANT_ACL)) 04475 db.append(STRING_WITH_LEN("USAGE")); 04476 else 04477 { 04478 int found=0, cnt; 04479 ulong j,test_access= want_access & ~GRANT_ACL; 04480 for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1) 04481 { 04482 if (test_access & j) 04483 { 04484 if (found) 04485 db.append(STRING_WITH_LEN(", ")); 04486 found = 1; 04487 db.append(command_array[cnt],command_lengths[cnt]); 04488 } 04489 } 04490 } 04491 db.append (STRING_WITH_LEN(" ON ")); 04492 append_identifier(thd, &db, acl_db->db, strlen(acl_db->db)); 04493 db.append (STRING_WITH_LEN(".* TO '")); 04494 db.append(lex_user->user.str, lex_user->user.length, 04495 system_charset_info); 04496 db.append (STRING_WITH_LEN("'@'")); 04497 db.append(lex_user->host.str, lex_user->host.length, 04498 system_charset_info); 04499 db.append ('\''); 04500 if (want_access & GRANT_ACL) 04501 db.append(STRING_WITH_LEN(" WITH GRANT OPTION")); 04502 protocol->prepare_for_resend(); 04503 protocol->store(db.ptr(),db.length(),db.charset()); 04504 if (protocol->write()) 04505 { 04506 error= -1; 04507 goto end; 04508 } 04509 } 04510 } 04511 } 04512 04513 /* Add table & column access */ 04514 for (index=0 ; index < column_priv_hash.records ; index++) 04515 { 04516 const char *user, *host; 04517 GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&column_priv_hash, 04518 index); 04519 04520 if (!(user=grant_table->user)) 04521 user= ""; 04522 if (!(host= grant_table->host.hostname)) 04523 host= ""; 04524 04525 if (!strcmp(lex_user->user.str,user) && 04526 !my_strcasecmp(system_charset_info, lex_user->host.str, host)) 04527 { 04528 ulong table_access= grant_table->privs; 04529 if ((table_access | grant_table->cols) != 0) 04530 { 04531 String global(buff, sizeof(buff), system_charset_info); 04532 ulong test_access= (table_access | grant_table->cols) & ~GRANT_ACL; 04533 04534 global.length(0); 04535 global.append(STRING_WITH_LEN("GRANT ")); 04536 04537 if (test_all_bits(table_access, (TABLE_ACLS & ~GRANT_ACL))) 04538 global.append(STRING_WITH_LEN("ALL PRIVILEGES")); 04539 else if (!test_access) 04540 global.append(STRING_WITH_LEN("USAGE")); 04541 else 04542 { 04543 /* Add specific column access */ 04544 int found= 0; 04545 ulong j; 04546 04547 for (counter= 0, j= SELECT_ACL; j <= TABLE_ACLS; counter++, j<<= 1) 04548 { 04549 if (test_access & j) 04550 { 04551 if (found) 04552 global.append(STRING_WITH_LEN(", ")); 04553 found= 1; 04554 global.append(command_array[counter],command_lengths[counter]); 04555 04556 if (grant_table->cols) 04557 { 04558 uint found_col= 0; 04559 for (uint col_index=0 ; 04560 col_index < grant_table->hash_columns.records ; 04561 col_index++) 04562 { 04563 GRANT_COLUMN *grant_column = (GRANT_COLUMN*) 04564 hash_element(&grant_table->hash_columns,col_index); 04565 if (grant_column->rights & j) 04566 { 04567 if (!found_col) 04568 { 04569 found_col= 1; 04570 /* 04571 If we have a duplicated table level privilege, we 04572 must write the access privilege name again. 04573 */ 04574 if (table_access & j) 04575 { 04576 global.append(STRING_WITH_LEN(", ")); 04577 global.append(command_array[counter], 04578 command_lengths[counter]); 04579 } 04580 global.append(STRING_WITH_LEN(" (")); 04581 } 04582 else 04583 global.append(STRING_WITH_LEN(", ")); 04584 global.append(grant_column->column, 04585 grant_column->key_length, 04586 system_charset_info); 04587 } 04588 } 04589 if (found_col) 04590 global.append(')'); 04591 } 04592 } 04593 } 04594 } 04595 global.append(STRING_WITH_LEN(" ON ")); 04596 append_identifier(thd, &global, grant_table->db, 04597 strlen(grant_table->db)); 04598 global.append('.'); 04599 append_identifier(thd, &global, grant_table->tname, 04600 strlen(grant_table->tname)); 04601 global.append(STRING_WITH_LEN(" TO '")); 04602 global.append(lex_user->user.str, lex_user->user.length, 04603 system_charset_info); 04604 global.append(STRING_WITH_LEN("'@'")); 04605 global.append(lex_user->host.str,lex_user->host.length, 04606 system_charset_info); 04607 global.append('\''); 04608 if (table_access & GRANT_ACL) 04609 global.append(STRING_WITH_LEN(" WITH GRANT OPTION")); 04610 protocol->prepare_for_resend(); 04611 protocol->store(global.ptr(),global.length(),global.charset()); 04612 if (protocol->write()) 04613 { 04614 error= -1; 04615 break; 04616 } 04617 } 04618 } 04619 } 04620 04621 if (show_routine_grants(thd, lex_user, &proc_priv_hash, 04622 STRING_WITH_LEN("PROCEDURE"), buff, sizeof(buff))) 04623 { 04624 error= -1; 04625 goto end; 04626 } 04627 04628 if (show_routine_grants(thd, lex_user, &func_priv_hash, 04629 STRING_WITH_LEN("FUNCTION"), buff, sizeof(buff))) 04630 { 04631 error= -1; 04632 goto end; 04633 } 04634 04635 end: 04636 VOID(pthread_mutex_unlock(&acl_cache->lock)); 04637 rw_unlock(&LOCK_grant); 04638 04639 send_eof(thd); 04640 DBUG_RETURN(error); 04641 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool mysql_table_grant | ( | THD * | thd, | |
| TABLE_LIST * | table, | |||
| List< LEX_USER > & | user_list, | |||
| List< LEX_COLUMN > & | column_list, | |||
| ulong | rights, | |||
| bool | revoke | |||
| ) |
Definition at line 2902 of file sql_acl.cc.
References access, acl_cache, st_table_list::alias, buf, build_table_filename(), bzero, String::c_ptr(), close_thread_tables(), COL_ACLS, GRANT_TABLE::cols, LEX_COLUMN::column, column_hash_search(), column_priv_hash, CREATE_ACL, st_table_list::db, DBUG_ENTER, DBUG_RETURN, base_list::elements, ER, ER_BAD_FIELD_ERROR, ER_GRANT_WRONG_HOST_OR_USER, ER_ILLEGAL_GRANT_FOR_TABLE, ER_NO_SUCH_TABLE, ER_NONEXISTING_TABLE_GRANT, ER_OPTION_PREVENTS_STATEMENT, ER_TABLEACCESS_DENIED_ERROR, error, f, F_OK, FALSE, find_field_in_table_ref(), fn_format(), FN_REFLEN, get_current_user(), get_privilege_desc(), st_table_list::grant, grant_option, grant_version, GRANT_TABLE::hash_columns, hash_element(), HOSTNAME_LENGTH, initialized, Rpl_filter::is_on(), LEX_STRING::length, String::length(), hash_filo::lock, LOCK_grant, memex, MODE_NO_AUTO_CREATE_USER, MY_APPEND_EXT, my_error(), my_hash_insert(), my_message(), MY_RESOLVE_SYMLINKS, MY_RETURN_REAL_PATH, MY_UNPACK_FILENAME, MYF, NO_CACHED_FIELD_INDEX, NULL, NullS, open_and_lock_tables(), pthread_mutex_lock, pthread_mutex_unlock, String::ptr(), st_hash::records, reg_ext, replace_column_table(), replace_table_table(), replace_user_table(), GRANT_COLUMN::rights, rpl_filter, rw_unlock, rw_wrlock, send_ok(), simple_open_n_lock_tables(), LEX_STRING::str, Str, TABLE_ACLS, table_hash_search(), st_table_list::table_name, Rpl_filter::tables_ok(), test, test_if_create_new_users(), TL_WRITE, TRUE, USERNAME_LENGTH, st_table_list::view_db, st_table_list::view_name, and st_grant_info::want_privilege.
Referenced by mysql_execute_command().
02906 { 02907 ulong column_priv= 0; 02908 List_iterator <LEX_USER> str_list (user_list); 02909 LEX_USER *Str, *tmp_Str; 02910 TABLE_LIST tables[3]; 02911 bool create_new_users=0; 02912 char *db_name, *table_name; 02913 DBUG_ENTER("mysql_table_grant"); 02914 02915 if (!initialized) 02916 { 02917 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), 02918 "--skip-grant-tables"); /* purecov: inspected */ 02919 DBUG_RETURN(TRUE); /* purecov: inspected */ 02920 } 02921 if (rights & ~TABLE_ACLS) 02922 { 02923 my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE), 02924 MYF(0)); 02925 DBUG_RETURN(TRUE); 02926 } 02927 02928 if (!revoke_grant) 02929 { 02930 if (columns.elements) 02931 { 02932 class LEX_COLUMN *column; 02933 List_iterator <LEX_COLUMN> column_iter(columns); 02934 02935 if (open_and_lock_tables(thd, table_list)) 02936 DBUG_RETURN(TRUE); 02937 02938 while ((column = column_iter++)) 02939 { 02940 uint unused_field_idx= NO_CACHED_FIELD_INDEX; 02941 TABLE_LIST *dummy; 02942 Field *f=find_field_in_table_ref(thd, table_list, column->column.ptr(), 02943 column->column.length(), 02944 column->column.ptr(), NULL, NULL, 02945 NULL, TRUE, FALSE, 02946 &unused_field_idx, FALSE, &dummy); 02947 if (f == (Field*)0) 02948 { 02949 my_error(ER_BAD_FIELD_ERROR, MYF(0), 02950 column->column.c_ptr(), table_list->alias); 02951 DBUG_RETURN(TRUE); 02952 } 02953 if (f == (Field *)-1) 02954 DBUG_RETURN(TRUE); 02955 column_priv|= column->rights; 02956 } 02957 close_thread_tables(thd); 02958 } 02959 else 02960 { 02961 if (!(rights & CREATE_ACL)) 02962 { 02963 char buf[FN_REFLEN]; 02964 build_table_filename(buf, sizeof(buf), table_list->db, 02965 table_list->table_name, reg_ext, 0); 02966 fn_format(buf, buf, "", "", MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS | 02967 MY_RETURN_REAL_PATH | MY_APPEND_EXT); 02968 if (access(buf,F_OK)) 02969 { 02970 my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias); 02971 DBUG_RETURN(TRUE); 02972 } 02973 } 02974 if (table_list->grant.want_privilege) 02975 { 02976 char command[128]; 02977 get_privilege_desc(command, sizeof(command), 02978 table_list->grant.want_privilege); 02979 my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), 02980 command, thd->security_ctx->priv_user, 02981 thd->security_ctx->host_or_ip, table_list->alias); 02982 DBUG_RETURN(-1); 02983 } 02984 } 02985 } 02986 02987 /* open the mysql.tables_priv and mysql.columns_priv tables */ 02988 02989 bzero((char*) &tables,sizeof(tables)); 02990 tables[0].alias=tables[0].table_name= (char*) "user"; 02991 tables[1].alias=tables[1].table_name= (char*) "tables_priv"; 02992 tables[2].alias=tables[2].table_name= (char*) "columns_priv"; 02993 tables[0].next_local= tables[0].next_global= tables+1; 02994 /* Don't open column table if we don't need it ! */ 02995 tables[1].next_local= 02996 tables[1].next_global= ((column_priv || 02997 (revoke_grant && 02998 ((rights & COL_ACLS) || columns.elements))) 02999 ? tables+2 : 0); 03000 tables[0].lock_type=tables[1].lock_type=tables[2].lock_type=TL_WRITE; 03001 tables[0].db=tables[1].db=tables[2].db=(char*) "mysql"; 03002 03003 #ifdef HAVE_REPLICATION 03004 /* 03005 GRANT and REVOKE are applied the slave in/exclusion rules as they are 03006 some kind of updates to the mysql.% tables. 03007 */ 03008 if (thd->slave_thread && rpl_filter->is_on()) 03009 { 03010 /* 03011 The tables must be marked "updating" so that tables_ok() takes them into 03012 account in tests. 03013 */ 03014 tables[0].updating= tables[1].updating= tables[2].updating= 1; 03015 if (!(thd->spcont || rpl_filter->tables_ok(0, tables))) 03016 DBUG_RETURN(FALSE); 03017 } 03018 #endif 03019 03020 if (simple_open_n_lock_tables(thd,tables)) 03021 { // Should never happen 03022 close_thread_tables(thd); /* purecov: deadcode */ 03023 DBUG_RETURN(TRUE); /* purecov: deadcode */ 03024 } 03025 03026 if (!revoke_grant) 03027 create_new_users= test_if_create_new_users(thd); 03028 bool result= FALSE; 03029 rw_wrlock(&LOCK_grant); 03030 pthread_mutex_lock(&acl_cache->lock); 03031 MEM_ROOT *old_root= thd->mem_root; 03032 thd->mem_root= &memex; 03033 grant_version++; 03034 03035 while ((tmp_Str = str_list++)) 03036 { 03037 int error; 03038 GRANT_TABLE *grant_table; 03039 if (!(Str= get_current_user(thd, tmp_Str))) 03040 { 03041 result= TRUE; 03042 continue; 03043 } 03044 if (Str->host.length > HOSTNAME_LENGTH || 03045 Str->user.length > USERNAME_LENGTH) 03046 { 03047 my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER), 03048 MYF(0)); 03049 result= TRUE; 03050 continue; 03051 } 03052 /* Create user if needed */ 03053 error=replace_user_table(thd, tables[0].table, *Str, 03054 0, revoke_grant, create_new_users, 03055 test(thd->variables.sql_mode & 03056 MODE_NO_AUTO_CREATE_USER)); 03057 if (error) 03058 { 03059 result= TRUE; // Remember error 03060 continue; // Add next user 03061 } 03062 03063 db_name= (table_list->view_db.length ? 03064 table_list->view_db.str : 03065 table_list->db); 03066 table_name= (table_list->view_name.length ? 03067 table_list->view_name.str : 03068 table_list->table_name); 03069 03070 /* Find/create cached table grant */ 03071 grant_table= table_hash_search(Str->host.str, NullS, db_name, 03072 Str->user.str, table_name, 1); 03073 if (!grant_table) 03074 { 03075 if (revoke_grant) 03076 { 03077 my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0), 03078 Str->user.str, Str->host.str, table_list->table_name); 03079 result= TRUE; 03080 continue; 03081 } 03082 grant_table = new GRANT_TABLE (Str->host.str, db_name, 03083 Str->user.str, table_name, 03084 rights, 03085 column_priv); 03086 if (!grant_table) // end of memory 03087 { 03088 result= TRUE; /* purecov: deadcode */ 03089 continue; /* purecov: deadcode */ 03090 } 03091 my_hash_insert(&column_priv_hash,(byte*) grant_table); 03092 } 03093 03094 /* If revoke_grant, calculate the new column privilege for tables_priv */ 03095 if (revoke_grant) 03096 { 03097 class LEX_COLUMN *column; 03098 List_iterator <LEX_COLUMN> column_iter(columns); 03099 GRANT_COLUMN *grant_column; 03100 03101 /* Fix old grants */ 03102 while ((column = column_iter++)) 03103 { 03104 grant_column = column_hash_search(grant_table, 03105 column->column.ptr(), 03106 column->column.length()); 03107 if (grant_column) 03108 grant_column->rights&= ~(column->rights | rights); 03109 } 03110 /* scan trough all columns to get new column grant */ 03111 column_priv= 0; 03112 for (uint idx=0 ; idx < grant_table->hash_columns.records ; idx++) 03113 { 03114 grant_column= (GRANT_COLUMN*) hash_element(&grant_table->hash_columns, 03115 idx); 03116 grant_column->rights&= ~rights; // Fix other columns 03117 column_priv|= grant_column->rights; 03118 } 03119 } 03120 else 03121 { 03122 column_priv|= grant_table->cols; 03123 } 03124 03125 03126 /* update table and columns */ 03127 03128 if (replace_table_table(thd, grant_table, tables[1].table, *Str, 03129 db_name, table_name, 03130 rights, column_priv, revoke_grant)) 03131 { 03132 /* Should only happen if table is crashed */ 03133 result= TRUE; /* purecov: deadcode */ 03134 } 03135 else if (tables[2].table) 03136 { 03137 if ((replace_column_table(grant_table, tables[2].table, *Str, 03138 columns, 03139 db_name, table_name, 03140 rights, revoke_grant))) 03141 { 03142 result= TRUE; 03143 } 03144 } 03145 } 03146 grant_option=TRUE; 03147 thd->mem_root= old_root; 03148 pthread_mutex_unlock(&acl_cache->lock); 03149 rw_unlock(&LOCK_grant); 03150 if (!result) 03151 send_ok(thd); 03152 /* Tables are automatically closed */ 03153 DBUG_RETURN(result); 03154 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5834 of file sql_acl.cc.
References acl_cache, bzero, DBUG_ENTER, DBUG_RETURN, DEFAULT_CREATE_PROC_ACLS, base_list::empty(), ER_PASSWD_LENGTH, FALSE, find_acl_user(), st_lex_user::host, LEX_STRING::length, hash_filo::lock, make_password_from_salt(), make_password_from_salt_323(), my_error(), MYF, mysql_routine_grant(), st_lex_user::password, pthread_mutex_lock, pthread_mutex_unlock, List< T >::push_back(), ACL_USER::salt, ACL_USER::salt_len, SCRAMBLE_LENGTH, SCRAMBLE_LENGTH_323, SCRAMBLED_PASSWORD_CHAR_LENGTH, SCRAMBLED_PASSWORD_CHAR_LENGTH_323, SSL_TYPE_NOT_SPECIFIED, LEX_STRING::str, strlen(), TRUE, st_lex_user::user, and VOID.
Referenced by mysql_execute_command().
05836 { 05837 Security_context *sctx= thd->security_ctx; 05838 LEX_USER *combo; 05839 TABLE_LIST tables[1]; 05840 List<LEX_USER> user_list; 05841 bool result; 05842 ACL_USER *au; 05843 char passwd_buff[SCRAMBLED_PASSWORD_CHAR_LENGTH+1]; 05844 DBUG_ENTER("sp_grant_privileges"); 05845 05846 if (!(combo=(LEX_USER*) thd->alloc(sizeof(st_lex_user)))) 05847 DBUG_RETURN(TRUE); 05848 05849 combo->user.str= sctx->user; 05850 05851 VOID(pthread_mutex_lock(&acl_cache->lock)); 05852 05853 if ((au= find_acl_user(combo->host.str=(char*)sctx->host_or_ip,combo->user.str,FALSE))) 05854 goto found_acl; 05855 if ((au= find_acl_user(combo->host.str=(char*)sctx->host, combo->user.str,FALSE))) 05856 goto found_acl; 05857 if ((au= find_acl_user(combo->host.str=(char*)sctx->ip, combo->user.str,FALSE))) 05858 goto found_acl; 05859 if((au= find_acl_user(combo->host.str=(char*)"%", combo->user.str, FALSE))) 05860 goto found_acl; 05861 05862 VOID(pthread_mutex_unlock(&acl_cache->lock)); 05863 DBUG_RETURN(TRUE); 05864 05865 found_acl: 05866 VOID(pthread_mutex_unlock(&acl_cache->lock)); 05867 05868 bzero((char*)tables, sizeof(TABLE_LIST)); 05869 user_list.empty(); 05870 05871 tables->db= (char*)sp_db; 05872 tables->table_name= tables->alias= (char*)sp_name; 05873 05874 combo->host.length= strlen(combo->host.str); 05875 combo->user.length= strlen(combo->user.str); 05876 combo->host.str= thd->strmake(combo->host.str,combo->host.length); 05877 combo->user.str= thd->strmake(combo->user.str,combo->user.length); 05878 05879 05880 if(au && au->salt_len) 05881 { 05882 if (au->salt_len == SCRAMBLE_LENGTH) 05883 { 05884 make_password_from_salt(passwd_buff, au->salt); 05885 combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH; 05886 } 05887 else if (au->salt_len == SCRAMBLE_LENGTH_323) 05888 { 05889 make_password_from_salt_323(passwd_buff, (ulong *) au->salt); 05890 combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; 05891 } 05892 else 05893 { 05894 my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH); 05895 return -1; 05896 } 05897 combo->password.str= passwd_buff; 05898 } 05899 else 05900 { 05901 combo->password.str= (char*)""; 05902 combo->password.length= 0; 05903 } 05904 05905 if (user_list.push_back(combo)) 05906 DBUG_RETURN(TRUE); 05907 05908 thd->lex->ssl_type= SSL_TYPE_NOT_SPECIFIED; 05909 bzero((char*) &thd->lex->mqh, sizeof(thd->lex->mqh)); 05910 05911 result= mysql_routine_grant(thd, tables, is_proc, user_list, 05912 DEFAULT_CREATE_PROC_ACLS, 0, 1); 05913 DBUG_RETURN(result); 05914 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5765 of file sql_acl.cc.
References acl_cache, counter, GRANT_NAME::db, DBUG_ENTER, DBUG_RETURN, func_priv_hash, GRANT_TABLES, hash(), hash_element(), GRANT_NAME::host, acl_host_and_ip::hostname, hash_filo::lock, LOCK_grant, my_strcasecmp, open_grant_tables(), proc_priv_hash, pthread_mutex_lock, replace_routine_table(), rw_wrlock, strlen(), system_charset_info, GRANT_NAME::tname, GRANT_NAME::user, and VOID.
Referenced by mysql_execute_command().
05767 { 05768 uint counter, revoked; 05769 int result; 05770 TABLE_LIST tables[GRANT_TABLES]; 05771 HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash; 05772 DBUG_ENTER("sp_revoke_privileges"); 05773 05774 if ((result= open_grant_tables(thd, tables))) 05775 DBUG_RETURN(result != 1); 05776 05777 rw_wrlock(&LOCK_grant); 05778 VOID(pthread_mutex_lock(&acl_cache->lock)); 05779 05780 /* Remove procedure access */ 05781 do 05782 { 05783 for (counter= 0, revoked= 0 ; counter < hash->records ; ) 05784 { 05785 GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(hash, counter); 05786 if (!my_strcasecmp(system_charset_info, grant_proc->db, sp_db) && 05787 !my_strcasecmp(system_charset_info, grant_proc->tname, sp_name)) 05788 { 05789 LEX_USER lex_user; 05790 lex_user.user.str= grant_proc->user; 05791 lex_user.user.length= strlen(grant_proc->user); 05792 lex_user.host.str= grant_proc->host.hostname ? 05793 grant_proc->host.hostname : (char*)""; 05794 lex_user.host.length= grant_proc->host.hostname ? 05795 strlen(grant_proc->host.hostname) : 0; 05796 if (!replace_routine_table(thd,grant_proc,tables[4].table,lex_user, 05797 grant_proc->db, grant_proc->tname, 05798 is_proc, ~(ulong)0, 1)) 05799 { 05800 revoked= 1; 05801 continue; 05802 } 05803 result= -1; // Something went wrong 05804 } 05805 counter++; 05806 } 05807 } while (revoked); 05808 05809 VOID(pthread_mutex_unlock(&acl_cache->lock)); 05810 rw_unlock(&LOCK_grant); 05811 close_thread_tables(thd); 05812 05813 if (result) 05814 my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0)); 05815 05816 DBUG_RETURN(result); 05817 }
Here is the call graph for this function:

Here is the caller graph for this function:

| time_t mysql_db_table_last_check |
1.4.7

