diff -Nru mariadb-10.0-10.0.29.info/sql/sql_acl.cc mariadb-10.0-10.0.29/sql/sql_acl.cc --- mariadb-10.0-10.0.29.info/sql/sql_acl.cc 2017-03-05 10:36:10.603234750 +0100 +++ mariadb-10.0-10.0.29/sql/sql_acl.cc 2017-03-05 10:38:17.155530562 +0100 @@ -213,11 +213,6 @@ /* Classes */ -struct acl_host_and_ip -{ - char *hostname; - long ip, ip_mask; // Used with masked ip:s -}; #ifndef NO_EMBEDDED_ACCESS_CHECKS static bool compare_hostname(const acl_host_and_ip *, const char *, const char *); @@ -225,12 +220,6 @@ #define compare_hostname(X,Y,Z) 0 #endif -class ACL_ACCESS { -public: - ulong sort; - ulong access; -}; - /* ACL_HOST is used if no host is specified */ class ACL_HOST :public ACL_ACCESS @@ -335,14 +324,6 @@ }; -class ACL_DB :public ACL_ACCESS -{ -public: - acl_host_and_ip host; - char *user,*db; - ulong initial_access; /* access bits present in the table */ -}; - #ifndef DBUG_OFF /* status variables, only visible in SHOW STATUS after -#d,role_merge_stats */ ulong role_global_merges= 0, role_db_merges= 0, role_table_merges= 0, @@ -588,15 +569,6 @@ #define FIRST_NON_YN_FIELD 26 -class acl_entry :public hash_filo_element -{ -public: - ulong access; - uint16 length; - char key[1]; // Key will be stored here -}; - - static uchar* acl_entry_get_key(acl_entry *entry, size_t *length, my_bool not_used __attribute__((unused))) { @@ -714,7 +686,8 @@ /* Flag to mark that on_node was already called for this role */ #define ROLE_OPENED (1L << 3) -static DYNAMIC_ARRAY acl_hosts, acl_users, acl_dbs, acl_proxy_users; +DYNAMIC_ARRAY acl_dbs; +static DYNAMIC_ARRAY acl_hosts, acl_users, acl_proxy_users; static HASH acl_roles; /* An hash containing mappings user <--> role @@ -728,7 +701,7 @@ static bool allow_all_hosts=1; static HASH acl_check_hosts, column_priv_hash, proc_priv_hash, func_priv_hash; static DYNAMIC_ARRAY acl_wild_hosts; -static Hash_filo *acl_cache; +Hash_filo *acl_cache; static uint grant_version=0; /* Version of priv tables. incremented by acl_load */ static ulong get_access(TABLE *form,uint fieldnr, uint *next_field=0); static bool check_is_role(TABLE *form); diff -Nru mariadb-10.0-10.0.29.info/sql/sql_acl.h mariadb-10.0-10.0.29/sql/sql_acl.h --- mariadb-10.0-10.0.29.info/sql/sql_acl.h 2017-03-05 10:35:42.863169909 +0100 +++ mariadb-10.0-10.0.29/sql/sql_acl.h 2017-03-05 10:38:21.203540024 +0100 @@ -19,6 +19,7 @@ #include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */ #include "violite.h" /* SSL_type */ #include "sql_class.h" /* LEX_COLUMN */ +#include "hash_filo.h" #define SELECT_ACL (1L << 0) #define INSERT_ACL (1L << 1) @@ -193,6 +194,36 @@ : ER_ACCESS_DENIED_ERROR; } +class acl_entry :public hash_filo_element +{ +public: + ulong access; + uint16 length; + char key[1]; // Key will be stored here +}; + +class ACL_ACCESS { +public: + ulong sort; + ulong access; +}; + +struct acl_host_and_ip +{ + char *hostname; + long ip, ip_mask; // Used with masked ip:s +}; + +class ACL_DB :public ACL_ACCESS +{ +public: + acl_host_and_ip host; + char *user,*db; + ulong initial_access; /* access bits present in the table */ +}; + +extern DYNAMIC_ARRAY acl_dbs; +extern Hash_filo *acl_cache; /* prototypes */ diff -Nru mariadb-10.0-10.0.29.info/sql/sql_show.cc mariadb-10.0-10.0.29/sql/sql_show.cc --- mariadb-10.0-10.0.29.info/sql/sql_show.cc 2017-03-05 10:36:32.415285735 +0100 +++ mariadb-10.0-10.0.29/sql/sql_show.cc 2017-03-05 10:38:25.451549954 +0100 @@ -59,6 +59,8 @@ #include "debug_sync.h" #include "keycaches.h" +#include "hash_filo.h" + #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" #endif @@ -811,6 +813,14 @@ FIND_FILES_DIR }; +static char *safe_str(char *str) +{ return str ? str : const_cast(""); } + +static const char *safe_str(const char *str) +{ return str ? str : ""; } + + + /* find_files() - find files in a given directory. @@ -849,53 +859,62 @@ if (!db) /* Return databases */ { - for (uint i=0; i < (uint) dirp->number_of_files; i++) +#ifndef NO_EMBEDDED_ACCESS_CHECKS + char bufor[201]; + char *current; + uint counter, i, n; + ACL_DB *acl_db; + char *curr_host= thd->security_ctx->priv_host_name(); + + mysql_mutex_lock(&acl_cache->lock); + + for (counter=0 ; counter < acl_dbs.elements ; counter++) { - FILEINFO *file= dirp->dir_entry+i; -#ifdef USE_SYMDIR - char *ext; - char buff[FN_REFLEN]; - if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym")) - { - /* Only show the sym file if it points to a directory */ - char *end; - *ext=0; /* Remove extension */ - unpack_dirname(buff, file->name); - end= strend(buff); - if (end != buff && end[-1] == FN_LIBCHAR) - end[-1]= 0; // Remove end FN_LIBCHAR - if (!mysql_file_stat(key_file_misc, buff, file->mystat, MYF(0))) - continue; - } -#endif - if (!MY_S_ISDIR(file->mystat->st_mode)) + const char *user, *host; + + acl_db=dynamic_element(&acl_dbs,counter,ACL_DB*); + user= safe_str(acl_db->user); + host= safe_str(acl_db->host.hostname); + + if ((strcmp(thd->security_ctx->priv_user, user) || + my_strcasecmp(system_charset_info, curr_host, host))) continue; - if (is_in_ignore_db_dirs_list(file->name)) + if (is_in_ignore_db_dirs_list(acl_db->db)) continue; - if (tl.add_file(file->name)) + for (i = 0, current = bufor; i < 200; ++i) + { + if (acl_db->db[i] == '\\') continue; + if (acl_db->db[i] == '\0') break; + *current++ = acl_db->db[i]; + } + *current = '\0'; + + if (tl.add_file(bufor)) goto err; } + mysql_mutex_unlock(&acl_cache->lock); tl.sort(); +#endif } else { if (ha_discover_table_names(thd, db, dirp, &tl, false)) - goto err; + goto err2; } - DBUG_PRINT("info",("found: %zu files", files->elements())); my_dirend(dirp); DBUG_RETURN(FIND_FILES_OK); err: + mysql_mutex_unlock(&acl_cache->lock); +err2: my_dirend(dirp); DBUG_RETURN(FIND_FILES_OOM); } - /** An Internal_error_handler that suppresses errors regarding views' underlying tables that occur during privilege checking within SHOW CREATE diff -Nru mariadb-10.0-10.0.29.info/sql/sql_show.h mariadb-10.0-10.0.29/sql/sql_show.h --- mariadb-10.0-10.0.29.info/sql/sql_show.h 2017-03-05 10:36:00.199210431 +0100 +++ mariadb-10.0-10.0.29/sql/sql_show.h 2017-03-05 10:38:07.759508600 +0100 @@ -35,6 +35,8 @@ struct TABLE; typedef struct system_status_var STATUS_VAR; +class ACL_DB; + /* Used by handlers to store things in schema tables */ #define IS_FILES_FILE_ID 0 #define IS_FILES_FILE_NAME 1