Loading Docs/manual.texi +71 −9 Original line number Diff line number Diff line Loading @@ -36191,15 +36191,6 @@ SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL Sets the transaction isolation level for the global, whole session or the next transaction. The default behavior is to set the isolation level for the next (not started) transaction. If you use the @code{GLOBAL} keyword, the statement sets the default transaction level globally for all new connections created from that point on. You will need the @strong{process} privilege to do do this. Using the @code{SESSION} keyword sets the default transaction level for all future transactions performed on the current connection. You can set the default global isolation level for @code{mysqld} with @code{--transaction-isolation=...}. @xref{Command-line options}. @node Fulltext Search, Query Cache, Transactional Commands, Reference Loading Loading @@ -49215,6 +49206,77 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. @itemize @bullet @item Fixed bug in DROP DATABASE with symlink @item Fixed bug in EXPLAIN with LIMIT offset != 0 @item New feature : Management of user resources So far, the only available method of limiting user usage of MySQL server resources has been setting max_user_connections startup variable to some non-zero value at MySQL startup. But this method is strictly a global one and does not allow management of individual users, which could be of paricular interest to Interent Service Providers. Therefore, management of three resources is introduced on the individual user level : * number of all queries per hour * number of all updates per hour * number of connections made per hour Small clarification : By the updates in the above sense is considered any command that changes any table or database. Queries in the above context comprehend all commands that could be run by user. User in the above context comprehends a single entry in user table, which is uniquely identified by user and host columns. All users are by default not limited in using the above resources, unless the limits are GRANTed to them. These limits can be granted ONLY by global GRANT (*.*) and with a following syntax : GRANT ... WITH MAX_QUERIES_PER_HOUR = N1 MAX_UPDATES_PER_HOUR = N2 MAX_CONNECTIONS_PER_HOUR = N3; It is not required that all three resources are specified. One or two can be specified also. N1,N2 and N3 are intergers and should limit number of times user can execute any command, update command or can login that many times per hour. If user reaches any of the above limits withing one hour, his connection will be broken or refused and the appropriate error message shall be issued. Current values of particular user resources can be flushed (set to zero) by issuing a grant statement with any of the above limiting clauses, including a GRANT statement with current value(s) of tha resource(s). Also, current values for all users will be flushed if privileges are reloaded or if a new flush command is issued : flush user_resources. Also, current values for all users will be flushed with mysqladmin reload command. This new feature is enabled as soon as single user is GRANTed with some of the limiting GRANT clauses. As a prerequisite for enabling this features, user table in mysql database must have the additional columns, just as defined in table creation scripts mysql_install_db and mysql_install_db.sh in scripts/ directory. @item New configure option --without-query-cache. @item Memory allocation strategy for 'root memory' changed. Block size now grows ======= Fixed bug in phrase operator @code{"..."} in boolean full-text search. @item Fixed bug that caused duplicated rows when using truncation operator include/mysql_com.h +1 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY, #define REFRESH_QUERY_CACHE 65536 #define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */ #define REFRESH_DES_KEY_FILE 0x40000L #define REFRESH_USER_RESOURCES 0x80000L #define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */ #define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */ Loading sql/lex.h +3 −0 Original line number Diff line number Diff line Loading @@ -229,6 +229,8 @@ static SYMBOL symbols[] = { { "MASTER_USER", SYM(MASTER_USER_SYM),0,0}, { "MAX_ROWS", SYM(MAX_ROWS),0,0}, { "MAX_QUERIES_PER_HOUR", SYM(MAX_QUERIES_PER_HOUR), 0,0}, { "MAX_UPDATES_PER_HOUR", SYM(MAX_UPDATES_PER_HOUR), 0,0}, { "MAX_CONNECTIONS_PER_HOUR", SYM(MAX_CONNECTIONS_PER_HOUR), 0,0}, { "MATCH", SYM(MATCH),0,0}, { "MEDIUMBLOB", SYM(MEDIUMBLOB),0,0}, { "MEDIUMTEXT", SYM(MEDIUMTEXT),0,0}, Loading Loading @@ -290,6 +292,7 @@ static SYMBOL symbols[] = { { "REPEATABLE", SYM(REPEATABLE_SYM),0,0}, { "REQUIRE", SYM(REQUIRE_SYM),0,0}, { "RESET", SYM(RESET_SYM),0,0}, { "USER_RESOURCES", SYM(RESOURCES),0,0}, { "RESTORE", SYM(RESTORE_SYM),0,0}, { "RESTRICT", SYM(RESTRICT),0,0}, { "RETURNS", SYM(UDF_RETURNS_SYM),0,0}, Loading sql/sql_acl.cc +83 −25 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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)); Loading Loading @@ -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; Loading Loading @@ -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++) Loading @@ -604,7 +634,7 @@ 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; acl_user->user_resource=*mqh; #ifdef HAVE_OPENSSL acl_user->ssl_type=ssl_type; acl_user->ssl_cipher=ssl_cipher; Loading Loading @@ -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; Loading @@ -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 Loading Loading @@ -1151,7 +1181,14 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, DBUG_ENTER("replace_user_table"); if (combo.password.str && combo.password.str[0]) { if (combo.password.length <= HASH_PASSWORD_LENGTH) { send_error(&thd->net, ER_PASSWORD_NO_MATCH); DBUG_RETURN(1); } password=combo.password.str; } else { password=empty_string; Loading Loading @@ -1233,10 +1270,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) { Loading Loading @@ -1276,7 +1319,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, 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, Loading @@ -1284,7 +1327,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, thd->lex.ssl_cipher, thd->lex.x509_issuer, thd->lex.x509_subject, thd->lex.mqh, &thd->lex.mqh, rights); } table->file->index_end(); Loading Loading @@ -2691,11 +2734,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); Loading Loading @@ -2860,16 +2917,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 *****************************************************************************/ Loading sql/sql_acl.h +2 −2 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ uint acl_get(const char *host, const char *ip, const char *bin_ip, const char *user, const char *db); uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user, const char *password,const char *scramble,char **priv_user, bool old_ver, uint *max); bool old_ver, USER_RESOURCES *max); bool acl_check_host(const char *host, const char *ip); bool change_password(THD *thd, const char *host, const char *user, char *password); Loading @@ -82,4 +82,4 @@ bool check_grant_db(THD *thd,const char *db); uint get_table_grant(THD *thd, TABLE_LIST *table); uint get_column_grant(THD *thd, TABLE_LIST *table, Field *field); int mysql_show_grants(THD *thd, LEX_USER *user); uint get_mqh(const char *user, const char *host); void get_mqh(const char *user, const char *host, USER_CONN *uc); Loading
Docs/manual.texi +71 −9 Original line number Diff line number Diff line Loading @@ -36191,15 +36191,6 @@ SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL Sets the transaction isolation level for the global, whole session or the next transaction. The default behavior is to set the isolation level for the next (not started) transaction. If you use the @code{GLOBAL} keyword, the statement sets the default transaction level globally for all new connections created from that point on. You will need the @strong{process} privilege to do do this. Using the @code{SESSION} keyword sets the default transaction level for all future transactions performed on the current connection. You can set the default global isolation level for @code{mysqld} with @code{--transaction-isolation=...}. @xref{Command-line options}. @node Fulltext Search, Query Cache, Transactional Commands, Reference Loading Loading @@ -49215,6 +49206,77 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. @itemize @bullet @item Fixed bug in DROP DATABASE with symlink @item Fixed bug in EXPLAIN with LIMIT offset != 0 @item New feature : Management of user resources So far, the only available method of limiting user usage of MySQL server resources has been setting max_user_connections startup variable to some non-zero value at MySQL startup. But this method is strictly a global one and does not allow management of individual users, which could be of paricular interest to Interent Service Providers. Therefore, management of three resources is introduced on the individual user level : * number of all queries per hour * number of all updates per hour * number of connections made per hour Small clarification : By the updates in the above sense is considered any command that changes any table or database. Queries in the above context comprehend all commands that could be run by user. User in the above context comprehends a single entry in user table, which is uniquely identified by user and host columns. All users are by default not limited in using the above resources, unless the limits are GRANTed to them. These limits can be granted ONLY by global GRANT (*.*) and with a following syntax : GRANT ... WITH MAX_QUERIES_PER_HOUR = N1 MAX_UPDATES_PER_HOUR = N2 MAX_CONNECTIONS_PER_HOUR = N3; It is not required that all three resources are specified. One or two can be specified also. N1,N2 and N3 are intergers and should limit number of times user can execute any command, update command or can login that many times per hour. If user reaches any of the above limits withing one hour, his connection will be broken or refused and the appropriate error message shall be issued. Current values of particular user resources can be flushed (set to zero) by issuing a grant statement with any of the above limiting clauses, including a GRANT statement with current value(s) of tha resource(s). Also, current values for all users will be flushed if privileges are reloaded or if a new flush command is issued : flush user_resources. Also, current values for all users will be flushed with mysqladmin reload command. This new feature is enabled as soon as single user is GRANTed with some of the limiting GRANT clauses. As a prerequisite for enabling this features, user table in mysql database must have the additional columns, just as defined in table creation scripts mysql_install_db and mysql_install_db.sh in scripts/ directory. @item New configure option --without-query-cache. @item Memory allocation strategy for 'root memory' changed. Block size now grows ======= Fixed bug in phrase operator @code{"..."} in boolean full-text search. @item Fixed bug that caused duplicated rows when using truncation operator
include/mysql_com.h +1 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY, #define REFRESH_QUERY_CACHE 65536 #define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */ #define REFRESH_DES_KEY_FILE 0x40000L #define REFRESH_USER_RESOURCES 0x80000L #define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */ #define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */ Loading
sql/lex.h +3 −0 Original line number Diff line number Diff line Loading @@ -229,6 +229,8 @@ static SYMBOL symbols[] = { { "MASTER_USER", SYM(MASTER_USER_SYM),0,0}, { "MAX_ROWS", SYM(MAX_ROWS),0,0}, { "MAX_QUERIES_PER_HOUR", SYM(MAX_QUERIES_PER_HOUR), 0,0}, { "MAX_UPDATES_PER_HOUR", SYM(MAX_UPDATES_PER_HOUR), 0,0}, { "MAX_CONNECTIONS_PER_HOUR", SYM(MAX_CONNECTIONS_PER_HOUR), 0,0}, { "MATCH", SYM(MATCH),0,0}, { "MEDIUMBLOB", SYM(MEDIUMBLOB),0,0}, { "MEDIUMTEXT", SYM(MEDIUMTEXT),0,0}, Loading Loading @@ -290,6 +292,7 @@ static SYMBOL symbols[] = { { "REPEATABLE", SYM(REPEATABLE_SYM),0,0}, { "REQUIRE", SYM(REQUIRE_SYM),0,0}, { "RESET", SYM(RESET_SYM),0,0}, { "USER_RESOURCES", SYM(RESOURCES),0,0}, { "RESTORE", SYM(RESTORE_SYM),0,0}, { "RESTRICT", SYM(RESTRICT),0,0}, { "RETURNS", SYM(UDF_RETURNS_SYM),0,0}, Loading
sql/sql_acl.cc +83 −25 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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)); Loading Loading @@ -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; Loading Loading @@ -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++) Loading @@ -604,7 +634,7 @@ 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; acl_user->user_resource=*mqh; #ifdef HAVE_OPENSSL acl_user->ssl_type=ssl_type; acl_user->ssl_cipher=ssl_cipher; Loading Loading @@ -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; Loading @@ -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 Loading Loading @@ -1151,7 +1181,14 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, DBUG_ENTER("replace_user_table"); if (combo.password.str && combo.password.str[0]) { if (combo.password.length <= HASH_PASSWORD_LENGTH) { send_error(&thd->net, ER_PASSWORD_NO_MATCH); DBUG_RETURN(1); } password=combo.password.str; } else { password=empty_string; Loading Loading @@ -1233,10 +1270,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) { Loading Loading @@ -1276,7 +1319,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, 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, Loading @@ -1284,7 +1327,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, thd->lex.ssl_cipher, thd->lex.x509_issuer, thd->lex.x509_subject, thd->lex.mqh, &thd->lex.mqh, rights); } table->file->index_end(); Loading Loading @@ -2691,11 +2734,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); Loading Loading @@ -2860,16 +2917,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 *****************************************************************************/ Loading
sql/sql_acl.h +2 −2 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ uint acl_get(const char *host, const char *ip, const char *bin_ip, const char *user, const char *db); uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user, const char *password,const char *scramble,char **priv_user, bool old_ver, uint *max); bool old_ver, USER_RESOURCES *max); bool acl_check_host(const char *host, const char *ip); bool change_password(THD *thd, const char *host, const char *user, char *password); Loading @@ -82,4 +82,4 @@ bool check_grant_db(THD *thd,const char *db); uint get_table_grant(THD *thd, TABLE_LIST *table); uint get_column_grant(THD *thd, TABLE_LIST *table, Field *field); int mysql_show_grants(THD *thd, LEX_USER *user); uint get_mqh(const char *user, const char *host); void get_mqh(const char *user, const char *host, USER_CONN *uc);