diff options
Diffstat (limited to 'sql/sql_acl.cc')
-rw-r--r-- | sql/sql_acl.cc | 122 |
1 files changed, 89 insertions, 33 deletions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f8f13c35e35..724af69bdca 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -58,7 +58,8 @@ class ACL_USER :public ACL_ACCESS { public: acl_host_and_ip host; - uint hostname_length, questions, updates; + uint hostname_length; + USER_RESOURCES user_resource; char *user,*password; ulong salt[2]; #ifdef HAVE_OPENSSL @@ -110,6 +111,32 @@ static void update_hostname(acl_host_and_ip *host, const char *hostname); static bool compare_hostname(const acl_host_and_ip *host, const char *hostname, const char *ip); +extern char uc_update_queries[SQLCOM_END]; + +static void init_update_queries(void) +{ + uc_update_queries[SQLCOM_CREATE_TABLE]=1; + uc_update_queries[SQLCOM_CREATE_INDEX]=1; + uc_update_queries[SQLCOM_ALTER_TABLE]=1; + uc_update_queries[SQLCOM_UPDATE]=1; + uc_update_queries[SQLCOM_INSERT]=1; + uc_update_queries[SQLCOM_INSERT_SELECT]=1; + uc_update_queries[SQLCOM_DELETE]=1; + uc_update_queries[SQLCOM_TRUNCATE]=1; + uc_update_queries[SQLCOM_DROP_TABLE]=1; + uc_update_queries[SQLCOM_LOAD]=1; + uc_update_queries[SQLCOM_CREATE_DB]=1; + uc_update_queries[SQLCOM_DROP_DB]=1; + uc_update_queries[SQLCOM_REPLACE]=1; + uc_update_queries[SQLCOM_REPLACE_SELECT]=1; + uc_update_queries[SQLCOM_RENAME_TABLE]=1; + uc_update_queries[SQLCOM_BACKUP_TABLE]=1; + uc_update_queries[SQLCOM_RESTORE_TABLE]=1; + uc_update_queries[SQLCOM_DELETE_MULTI]=1; + uc_update_queries[SQLCOM_DROP_INDEX]=1; + uc_update_queries[SQLCOM_MULTI_UPDATE]=1; +} + int acl_init(bool dont_read_acl_tables) { THD *thd; @@ -163,7 +190,7 @@ int acl_init(bool dont_read_acl_tables) init_sql_alloc(&mem,1024,0); init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0); - VOID(init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50)); + VOID(my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50)); while (!(read_record_info.read_record(&read_record_info))) { ACL_HOST host; @@ -187,7 +214,7 @@ int acl_init(bool dont_read_acl_tables) freeze_size(&acl_hosts); init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0); - VOID(init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100)); + VOID(my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100)); if (table->field[2]->field_length == 8 && protocol_version == PROTOCOL_VERSION) { @@ -247,14 +274,16 @@ int acl_init(bool dont_read_acl_tables) { /* Table has new MySQL usage limits */ char *ptr = get_field(&mem, table, 21); - user.questions=atoi(ptr); + user.user_resource.questions=atoi(ptr); ptr = get_field(&mem, table, 22); - user.updates=atoi(ptr); - if (user.questions) + user.user_resource.updates=atoi(ptr); + ptr = get_field(&mem, table, 23); + user.user_resource.connections=atoi(ptr); + if (user.user_resource.questions || user.user_resource.updates || user.user_resource.connections) mqh_used=1; } else - user.questions=user.updates=0; + bzero(&(user.user_resource),sizeof(user.user_resource)); #ifndef TO_BE_REMOVED if (table->fields <= 13) { // Without grant @@ -273,7 +302,7 @@ int acl_init(bool dont_read_acl_tables) freeze_size(&acl_users); init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0); - VOID(init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100)); + VOID(my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100)); while (!(read_record_info.read_record(&read_record_info))) { ACL_DB db; @@ -299,6 +328,7 @@ int acl_init(bool dont_read_acl_tables) init_check_host(); mysql_unlock_tables(thd, lock); + init_update_queries(); thd->version--; // Force close to free memory close_thread_tables(thd); delete thd; @@ -442,13 +472,13 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b) uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user, const char *password,const char *message,char **priv_user, - bool old_ver, uint *max_questions) + bool old_ver, USER_RESOURCES *mqh) { uint user_access=NO_ACCESS; *priv_user=(char*) user; char *ptr=0; - *max_questions=0; + bzero(mqh,sizeof(USER_RESOURCES)); if (!initialized) return (uint) ~NO_ACCESS; // If no data allow anything /* purecov: tested */ VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -556,7 +586,7 @@ uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user, #else /* HAVE_OPENSSL */ user_access=acl_user->access; #endif /* HAVE_OPENSSL */ - *max_questions=acl_user->questions; + *mqh=acl_user->user_resource; if (!acl_user->user) *priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */ break; @@ -590,7 +620,7 @@ static void acl_update_user(const char *user, const char *host, const char *ssl_cipher, const char *x509_issuer, const char *x509_subject, - unsigned int mqh, + USER_RESOURCES *mqh, uint privileges) { for (uint i=0 ; i < acl_users.elements ; i++) @@ -604,8 +634,8 @@ static void acl_update_user(const char *user, const char *host, acl_user->host.hostname && !strcmp(host,acl_user->host.hostname)) { acl_user->access=privileges; - acl_user->questions=mqh; -#ifdef HAVE_OPENSSL + acl_user->user_resource=*mqh; +#ifdef HAVE_OPENSSL acl_user->ssl_type=ssl_type; acl_user->ssl_cipher=ssl_cipher; acl_user->x509_issuer=x509_issuer; @@ -634,7 +664,7 @@ static void acl_insert_user(const char *user, const char *host, const char *ssl_cipher, const char *x509_issuer, const char *x509_subject, - unsigned int mqh, + USER_RESOURCES *mqh, uint privileges) { ACL_USER acl_user; @@ -642,7 +672,7 @@ static void acl_insert_user(const char *user, const char *host, update_hostname(&acl_user.host,strdup_root(&mem,host)); acl_user.password=0; acl_user.access=privileges; - acl_user.questions=mqh; + acl_user.user_resource = *mqh; acl_user.sort=get_sort(2,acl_user.host.hostname,acl_user.user); acl_user.hostname_length=(uint) strlen(acl_user.host.hostname); #ifdef HAVE_OPENSSL @@ -847,7 +877,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr) static void init_check_host(void) { DBUG_ENTER("init_check_host"); - VOID(init_dynamic_array(&acl_wild_hosts,sizeof(struct acl_host_and_ip), + VOID(my_init_dynamic_array(&acl_wild_hosts,sizeof(struct acl_host_and_ip), acl_users.elements,1)); VOID(hash_init(&acl_check_hosts,system_charset_info,acl_users.elements,0,0, (hash_get_key) check_get_key,0,HASH_CASE_INSENSITIVE)); @@ -1153,12 +1183,17 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, char *password,empty_string[1]; DBUG_ENTER("replace_user_table"); + password=empty_string; + empty_string[0]=0; + if (combo.password.str && combo.password.str[0]) - password=combo.password.str; - else { - password=empty_string; - empty_string[0]=0; + if (combo.password.length != HASH_PASSWORD_LENGTH) + { + my_error(ER_PASSWORD_NO_MATCH,MYF(0)); + DBUG_RETURN(-1); + } + password=combo.password.str; } table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); @@ -1236,10 +1271,16 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, } } #endif /* HAVE_OPENSSL */ - if (table->fields >= 23 && thd->lex.mqh) + if (table->fields >= 23) { - table->field[21]->store((longlong) thd->lex.mqh); - mqh_used=1; + USER_RESOURCES mqh = thd->lex.mqh; + if (mqh.questions) + table->field[21]->store((longlong) mqh.questions); + if (mqh.updates) + table->field[22]->store((longlong) mqh.updates); + if (mqh.connections) + table->field[23]->store((longlong) mqh.connections); + mqh_used = mqh_used || mqh.questions || mqh.updates || mqh.connections; } if (old_row_exists) { @@ -1279,7 +1320,7 @@ end: thd->lex.ssl_cipher, thd->lex.x509_issuer, thd->lex.x509_subject, - thd->lex.mqh, + &thd->lex.mqh, rights); else acl_insert_user(combo.user.str,combo.host.str,password, @@ -1287,7 +1328,7 @@ end: thd->lex.ssl_cipher, thd->lex.x509_issuer, thd->lex.x509_subject, - thd->lex.mqh, + &thd->lex.mqh, rights); } table->file->index_end(); @@ -2701,11 +2742,25 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) #endif /* HAVE_OPENSSL */ if (want_access & GRANT_ACL) global.append(" WITH GRANT OPTION",18); - else if (acl_user->questions) + if (acl_user->user_resource.questions) { char buff[65], *p; // just as in int2str global.append(" WITH MAX_QUERIES_PER_HOUR = ",29); - p=int2str(acl_user->questions,buff,10); + p=int2str(acl_user->user_resource.questions,buff,10); + global.append(buff,p-buff); + } + if (acl_user->user_resource.updates) + { + char buff[65], *p; // just as in int2str + global.append(" WITH MAX_UPDATES_PER_HOUR = ",29); + p=int2str(acl_user->user_resource.updates,buff,10); + global.append(buff,p-buff); + } + if (acl_user->user_resource.connections) + { + char buff[65], *p; // just as in int2str + global.append(" WITH MAX_CONNECTIONS_PER_HOUR = ",33); + p=int2str(acl_user->user_resource.connections,buff,10); global.append(buff,p-buff); } thd->packet.length(0); @@ -2870,16 +2925,17 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) } -uint get_mqh(const char *user, const char *host) +void get_mqh(const char *user, const char *host, USER_CONN *uc) { - if (!initialized) return 0; - ACL_USER *acl_user; - acl_user= find_acl_user(host,user); - return (acl_user) ? acl_user->questions : 0; + if (initialized && (acl_user= find_acl_user(host,user))) + uc->user_resources= acl_user->user_resource; + else + bzero((char*) &uc->user_resources, sizeof(uc->user_resources)); } + /***************************************************************************** ** Instantiate used templates *****************************************************************************/ |