Commit f4576479 authored by tim@donna.mysql.com's avatar tim@donna.mysql.com

Merge donna.mysql.com:/home/my/bk/mysql

into donna.mysql.com:/home/tim/my/work
parents 94276214 70a627a1
...@@ -11,7 +11,8 @@ extra_configs="$pentium_configs $debug_configs" ...@@ -11,7 +11,8 @@ extra_configs="$pentium_configs $debug_configs"
# Use the debug version if it exists # Use the debug version if it exists
if test -d /usr/local/BerkeleyDB-dbug/ if test -d /usr/local/BerkeleyDB-dbug/
then then
extra_configs="$extra_configs --with-berkeley-db=/usr/local/BerkeleyDB-dbug/ --with-innobase" extra_configs="$extra_configs --with-berkeley-db=/usr/local/BerkeleyDB-dbug/"
fi fi
extra_configs="$extra_configs --with-innobase"
. "$path/FINISH.sh" . "$path/FINISH.sh"
...@@ -9579,6 +9579,7 @@ uses: ...@@ -9579,6 +9579,7 @@ uses:
@findex command-line options @findex command-line options
@cindex options, command-line @cindex options, command-line
@cindex mysqld options
@node Command-line options, Option files, Automatic start, Post-installation @node Command-line options, Option files, Automatic start, Post-installation
@subsection Command-line Options @subsection Command-line Options
...@@ -11522,6 +11523,11 @@ in the grant tables. In principle, the @code{--secure} option to ...@@ -11522,6 +11523,11 @@ in the grant tables. In principle, the @code{--secure} option to
@code{mysqld} should make hostnames safe. In any case, you should be very @code{mysqld} should make hostnames safe. In any case, you should be very
careful about creating grant table entries using hostname values that careful about creating grant table entries using hostname values that
contain wild cards! contain wild cards!
@item
If you want to restrict the number of connections for a single user, you
can do this by setting the @code{max_user_connections} variable in
@code{mysqld}.
@end itemize @end itemize
@node Privileges options, What Privileges, Security, Privilege system @node Privileges options, What Privileges, Security, Privilege system
...@@ -21048,6 +21054,9 @@ The number of bytes to use when sorting @code{BLOB} or @code{TEXT} ...@@ -21048,6 +21054,9 @@ The number of bytes to use when sorting @code{BLOB} or @code{TEXT}
values (only the first @code{max_sort_length} bytes of each value values (only the first @code{max_sort_length} bytes of each value
are used; the rest are ignored). are used; the rest are ignored).
@item @code{max_user_connections}
The maximum number of active connections for a single user (0 = no limit).
@item @code{max_tmp_tables} @item @code{max_tmp_tables}
(This option doesn't yet do anything.) (This option doesn't yet do anything.)
Maximum number of temporary tables a client can keep open at the same time. Maximum number of temporary tables a client can keep open at the same time.
...@@ -41585,6 +41594,8 @@ not yet 100 % confident in this code. ...@@ -41585,6 +41594,8 @@ not yet 100 % confident in this code.
@appendixsubsec Changes in release 3.23.34 @appendixsubsec Changes in release 3.23.34
@itemize @bullet @itemize @bullet
@item @item
Added option @code{max_user_connections} to @code{mysqld}.
@item
Limit query length for replication by max_allowed_packet, not the arbitrary Limit query length for replication by max_allowed_packet, not the arbitrary
limit of 4 MB limit of 4 MB
@item @item
...@@ -521,7 +521,7 @@ extern uint protocol_version,dropping_tables; ...@@ -521,7 +521,7 @@ extern uint protocol_version,dropping_tables;
extern ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size, extern ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size,
max_join_size,join_buff_size,tmp_table_size, max_join_size,join_buff_size,tmp_table_size,
max_connections,max_connect_errors,long_query_time, max_connections,max_connect_errors,long_query_time,
max_insert_delayed_threads, max_insert_delayed_threads, max_user_connections,
long_query_count,net_wait_timeout,net_interactive_timeout, long_query_count,net_wait_timeout,net_interactive_timeout,
net_read_timeout,net_write_timeout, net_read_timeout,net_write_timeout,
what_to_log,flush_time, what_to_log,flush_time,
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <thr_alarm.h> #include <thr_alarm.h>
#include <myisam.h> #include <myisam.h>
#include <my_dir.h> #include <my_dir.h>
#include <assert.h>
#define SCRAMBLE_LENGTH 8 #define SCRAMBLE_LENGTH 8
...@@ -32,6 +33,9 @@ extern "C" pthread_mutex_t THR_LOCK_keycache; ...@@ -32,6 +33,9 @@ extern "C" pthread_mutex_t THR_LOCK_keycache;
extern "C" int gethostname(char *name, int namelen); extern "C" int gethostname(char *name, int namelen);
#endif #endif
static int check_for_max_user_connections(const char *user, int u_length,
const char *host);
static void decrease_user_connections(const char *user, const char *host);
static bool check_table_access(THD *thd,uint want_access, TABLE_LIST *tables); static bool check_table_access(THD *thd,uint want_access, TABLE_LIST *tables);
static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_db_used(THD *thd,TABLE_LIST *tables);
static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables);
...@@ -145,13 +149,134 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, ...@@ -145,13 +149,134 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
thd->host ? thd->host : thd->ip ? thd->ip : "unknown ip", thd->host ? thd->host : thd->ip ? thd->ip : "unknown ip",
db ? db : (char*) ""); db ? db : (char*) "");
thd->db_access=0; thd->db_access=0;
if (max_user_connections &&
check_for_max_user_connections(user, strlen(user), thd->host))
return -1;
if (db && db[0]) if (db && db[0])
return test(mysql_change_db(thd,db)); {
bool error=test(mysql_change_db(thd,db));
if (error)
decrease_user_connections(user,thd->host);
return error;
}
else else
send_ok(net); // Ready to handle questions send_ok(net); // Ready to handle questions
return 0; // ok return 0; // ok
} }
/*
** check for maximum allowable user connections
** if mysql server is started with corresponding
** variable that is greater then 0
*/
static HASH hash_user_connections;
static DYNAMIC_ARRAY user_conn_array;
extern pthread_mutex_t LOCK_user_conn;
struct user_conn {
char user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
int connections, len;
};
static byte* get_key_conn(user_conn *buff, uint *length,
my_bool not_used __attribute__((unused)))
{
*length=buff->len;
return (byte*) buff->user;
}
#define DEF_USER_COUNT 50
void init_max_user_conn(void)
{
(void) hash_init(&hash_user_connections,DEF_USER_COUNT,0,0,
(hash_get_key) get_key_conn,0, 0);
(void) init_dynamic_array(&user_conn_array,sizeof(user_conn),
DEF_USER_COUNT, DEF_USER_COUNT);
}
static int check_for_max_user_connections(const char *user, int u_length,
const char *host)
{
uint temp_len;
char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
struct user_conn *uc;
if (!user)
user="";
if (!host)
host="";
temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user), user, "@", host,
NullS) - temp_user);
(void) pthread_mutex_lock(&LOCK_user_conn);
uc = (struct user_conn *) hash_search(&hash_user_connections,
(byte*) temp_user, temp_len);
if (uc) /* user found ; check for no. of connections */
{
if (max_user_connections == uc->connections)
{
net_printf(&(current_thd->net),ER_TOO_MANY_USER_CONNECTIONS, temp_user);
pthread_mutex_unlock(&LOCK_user_conn);
return 1;
}
uc->connections++;
}
else
{
/* the user is not found in the cache; Insert it */
struct user_conn uc;
memcpy(uc.user,temp_user,temp_len+1);
uc.len = temp_len;
uc.connections = 1;
if (!insert_dynamic(&user_conn_array, (char *) &uc))
{
hash_insert(&hash_user_connections,
(byte *) dynamic_array_ptr(&user_conn_array,
user_conn_array.elements - 1));
}
}
(void) pthread_mutex_unlock(&LOCK_user_conn);
return 0;
}
static void decrease_user_connections(const char *user, const char *host)
{
char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
int temp_len;
struct user_conn uucc, *uc;
if (!user)
user="";
if (!host)
host="";
temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user), user, "@", host,
NullS) - temp_user);
(void) pthread_mutex_lock(&LOCK_user_conn);
uc = (struct user_conn *) hash_search(&hash_user_connections,
(byte*) temp_user, temp_len);
dbug_assert(uc != 0); // We should always find the user
if (!uc)
goto end; // Safety; Something went wrong
if (! --uc->connections)
{
/* Last connection for user; Delete it */
(void) hash_delete(&hash_user_connections,(char *) uc);
uint element= ((uint) ((byte*) uc - (byte*) user_conn_array.buffer) /
user_conn_array.size_of_element);
delete_dynamic_element(&user_conn_array,element);
}
end:
(void) pthread_mutex_unlock(&LOCK_user_conn);
}
void free_max_user_conn(void)
{
delete_dynamic(&user_conn_array);
hash_free(&hash_user_connections);
}
/* /*
** check connnetion and get priviliges ** check connnetion and get priviliges
...@@ -417,6 +542,8 @@ pthread_handler_decl(handle_one_connection,arg) ...@@ -417,6 +542,8 @@ pthread_handler_decl(handle_one_connection,arg)
thread_safe_increment(aborted_threads,&LOCK_thread_count); thread_safe_increment(aborted_threads,&LOCK_thread_count);
} }
if (max_user_connections)
decrease_user_connections(thd->user,thd->host);
end_thread: end_thread:
close_connection(net); close_connection(net);
end_thread(thd,1); end_thread(thd,1);
...@@ -641,7 +768,7 @@ bool do_command(THD *thd) ...@@ -641,7 +768,7 @@ bool do_command(THD *thd)
send_error(net, ER_UNKNOWN_COM_ERROR); send_error(net, ER_UNKNOWN_COM_ERROR);
break; break;
} }
if (check_user(thd, COM_CHANGE_USER, user, passwd, db,0)) if (check_user(thd, COM_CHANGE_USER, user, passwd, db, 0))
{ // Restore old user { // Restore old user
x_free(thd->user); x_free(thd->user);
x_free(thd->db); x_free(thd->db);
...@@ -652,6 +779,7 @@ bool do_command(THD *thd) ...@@ -652,6 +779,7 @@ bool do_command(THD *thd)
thd->priv_user=save_priv_user; thd->priv_user=save_priv_user;
break; break;
} }
decrease_user_connections (save_user, thd->host);
x_free((gptr) save_db); x_free((gptr) save_db);
x_free((gptr) save_user); x_free((gptr) save_user);
thd->password=test(passwd[0]); thd->password=test(passwd[0]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment