diff options
author | peter@mysql.com <> | 2002-11-30 20:58:53 +0300 |
---|---|---|
committer | peter@mysql.com <> | 2002-11-30 20:58:53 +0300 |
commit | a24258375a59e37d728dffae05235c59d283a6ab (patch) | |
tree | d6fd910fa1f2f46f32ad57ff34b8c30051905e04 | |
parent | 54ff0efe7cb79c2f3e7acc84f74905d750e51ba0 (diff) | |
download | mariadb-git-a24258375a59e37d728dffae05235c59d283a6ab.tar.gz |
SCRUM: Montymise code
fix mysql_change_user() for old clients
-rw-r--r-- | include/mysql_com.h | 6 | ||||
-rw-r--r-- | libmysql/libmysql.c | 257 | ||||
-rw-r--r-- | scripts/mysql_fix_privilege_tables.sh | 10 | ||||
-rw-r--r-- | sql/mini_client.cc | 21 | ||||
-rw-r--r-- | sql/mysqld.cc | 3 | ||||
-rw-r--r-- | sql/password.c | 52 | ||||
-rw-r--r-- | sql/sql_acl.cc | 170 | ||||
-rw-r--r-- | sql/sql_class.h | 5 | ||||
-rw-r--r-- | sql/sql_parse.cc | 241 |
9 files changed, 388 insertions, 377 deletions
diff --git a/include/mysql_com.h b/include/mysql_com.h index 09e1db5aeb6..f901ad5ff80 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -29,6 +29,7 @@ #define LOCAL_HOST "localhost" #define LOCAL_HOST_NAMEDPIPE "." + #if defined(__WIN__) && !defined( _CUSTOMCONFIG_) #define MYSQL_NAMEDPIPE "MySQL" #define MYSQL_SERVICENAME "MySql" @@ -44,6 +45,11 @@ enum enum_server_command COM_PREPARE, COM_EXECUTE, COM_LONG_DATA, COM_CLOSE_STMT }; + +#define SCRAMBLE_LENGTH 8 +#define SCRAMBLE41_LENGTH 20 + + #define NOT_NULL_FLAG 1 /* Field can't be NULL */ #define PRI_KEY_FLAG 2 /* Field is part of a primary key */ #define UNIQUE_KEY_FLAG 4 /* Field is part of a unique key */ diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 3f4dc295eb2..842e8fe845d 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -232,9 +232,9 @@ my_bool my_connect(my_socket s, const struct sockaddr *name, FD_ZERO(&sfds); FD_SET(s, &sfds); /* - * select could be interrupted by a signal, and if it is, + * select could be interrupted by a signal, and if it is, * the timeout should be adjusted and the select restarted - * to work around OSes that don't restart select and + * to work around OSes that don't restart select and * implementations of select that don't adjust tv upon * failure to reflect the time remaining */ @@ -346,23 +346,23 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host, } #endif -/* +/* Create new shared memory connection, return handler of connection SYNOPSIS create_shared_memory() mysql Pointer of mysql structure - net Pointer of net structure + net Pointer of net structure connect_timeout Timeout of connection */ #ifdef HAVE_SMEM HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) { ulong smem_buffer_length = shared_memory_buffer_length + 4; -/* - event_connect_request is event object for start connection actions +/* + event_connect_request is event object for start connection actions event_connect_answer is event object for confirm, that server put data - handle_connect_file_map is file-mapping object, use for create shared memory + handle_connect_file_map is file-mapping object, use for create shared memory handle_connect_map is pointer on shared memory handle_map is pointer on shared memory for client event_server_wrote, @@ -382,10 +382,10 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) HANDLE event_client_wrote = NULL; HANDLE event_client_read = NULL; HANDLE handle_file_map = NULL; - ulong connect_number; + ulong connect_number; char connect_number_char[22], *p; char tmp[64]; - char *suffix_pos; + char *suffix_pos; DWORD error_allow = 0; DWORD error_code = 0; char *shared_memory_base_name = mysql->options.shared_memory_base_name; @@ -399,24 +399,24 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) */ suffix_pos = strxmov(tmp,shared_memory_base_name,"_",NullS); strmov(suffix_pos, "CONNECT_REQUEST"); - if ((event_connect_request = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL) + if ((event_connect_request = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL) { error_allow = CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR; goto err; } strmov(suffix_pos, "CONNECT_ANSWER"); - if ((event_connect_answer = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL) + if ((event_connect_answer = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL) { error_allow = CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR; goto err; } strmov(suffix_pos, "CONNECT_DATA"); - if ((handle_connect_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL) + if ((handle_connect_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL) { error_allow = CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR; goto err; } - if ((handle_connect_map = MapViewOfFile(handle_connect_file_map,FILE_MAP_WRITE,0,0,sizeof(DWORD))) == NULL) + if ((handle_connect_map = MapViewOfFile(handle_connect_file_map,FILE_MAP_WRITE,0,0,sizeof(DWORD))) == NULL) { error_allow = CR_SHARED_MEMORY_CONNECT_MAP_ERROR; goto err; @@ -424,7 +424,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) /* Send to server request of connection */ - if (!SetEvent(event_connect_request)) + if (!SetEvent(event_connect_request)) { error_allow = CR_SHARED_MEMORY_CONNECT_SET_ERROR; goto err; @@ -456,7 +456,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) if ((handle_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL) { error_allow = CR_SHARED_MEMORY_FILE_MAP_ERROR; - goto err2; + goto err2; } if ((handle_map = MapViewOfFile(handle_file_map,FILE_MAP_WRITE,0,0,smem_buffer_length)) == NULL) { @@ -496,13 +496,13 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) */ SetEvent(event_server_read); -err2: - if (error_allow == 0) +err2: + if (error_allow == 0) { net->vio = vio_new_win32shared_memory(net,handle_file_map,handle_map,event_server_wrote, - event_server_read,event_client_wrote,event_client_read); - } - else + event_server_read,event_client_wrote,event_client_read); + } + else { error_code = GetLastError(); if (event_server_read) CloseHandle(event_server_read); @@ -518,7 +518,7 @@ err: if (event_connect_answer) CloseHandle(event_connect_answer); if (handle_connect_map) UnmapViewOfFile(handle_connect_map); if (handle_connect_file_map) CloseHandle(handle_connect_file_map); - if (error_allow) + if (error_allow) { net->last_errno=error_allow; if (error_allow == CR_SHARED_MEMORY_EVENT_ERROR) @@ -526,7 +526,7 @@ err: else sprintf(net->last_error,ER(net->last_errno),error_code); return(INVALID_HANDLE_VALUE); - } + } return(handle_map); }; #endif @@ -554,7 +554,7 @@ net_safe_read(MYSQL *mysql) DBUG_PRINT("error",("Wrong connection or packet. fd: %s len: %d", vio_description(net->vio),len)); end_server(mysql); - net->last_errno=(net->last_errno == ER_NET_PACKET_TOO_LARGE ? + net->last_errno=(net->last_errno == ER_NET_PACKET_TOO_LARGE ? CR_NET_PACKET_TOO_LARGE: CR_SERVER_LOST); strmov(net->last_error,ER(net->last_errno)); @@ -1095,7 +1095,7 @@ static void mysql_read_default_options(struct st_mysql_options *options, my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME)); #endif - break; + break; default: DBUG_PRINT("warning",("unknown option: %s",option[0])); } @@ -1161,7 +1161,7 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, field->name= strdup_root(alloc,(char*) row->data[1]); field->length= (uint) uint3korr(row->data[2]); field->type= (enum enum_field_types) (uchar) row->data[3][0]; - + if (server_capabilities & CLIENT_LONG_FLAG) { field->flags= uint2korr(row->data[4]); @@ -1346,7 +1346,7 @@ my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q, } -/* perform query on slave */ +/* perform query on slave */ my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q, unsigned long length) { @@ -1391,7 +1391,7 @@ void STDCALL mysql_disable_rpl_parse(MYSQL* mysql) mysql->options.rpl_parse = 0; } -/* get the value of the parse flag */ +/* get the value of the parse flag */ int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql) { return mysql->options.rpl_parse; @@ -1408,7 +1408,7 @@ void STDCALL mysql_disable_reads_from_master(MYSQL* mysql) mysql->options.no_master_reads = 1; } -/* get the value of the master read flag */ +/* get the value of the master read flag */ my_bool STDCALL mysql_reads_from_master_enabled(MYSQL* mysql) { return !(mysql->options.no_master_reads); @@ -1537,7 +1537,7 @@ my_bool STDCALL mysql_rpl_probe(MYSQL* mysql) the most reliable way to do this is to run SHOW SLAVE STATUS and see if we have a non-empty master host. This is still not fool-proof - it is not a sin to have a master that has a dormant slave thread with - a non-empty master host. However, it is more reliable to check + a non-empty master host. However, it is more reliable to check for empty master than whether the slave thread is actually running */ if (mysql_query(mysql, "SHOW SLAVE STATUS") || @@ -1602,7 +1602,7 @@ STDCALL mysql_rpl_query_type(const char* q, int len) case 'a': /* alter */ return MYSQL_RPL_MASTER; case 'c': /* create or check */ - return my_tolower(system_charset_info,q[1]) == 'h' ? MYSQL_RPL_ADMIN : + return my_tolower(system_charset_info,q[1]) == 'h' ? MYSQL_RPL_ADMIN : MYSQL_RPL_MASTER; case 's': /* select or show */ return my_tolower(system_charset_info,q[1]) == 'h' ? MYSQL_RPL_ADMIN : @@ -1643,7 +1643,7 @@ mysql_init(MYSQL *mysql) By default, we are a replication pivot. The caller must reset it after we return if this is not the case. */ - mysql->rpl_pivot = 1; + mysql->rpl_pivot = 1; #if defined(SIGPIPE) && defined(THREAD) && !defined(__WIN__) if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE)) (void) signal(SIGPIPE,pipe_sig_handler); @@ -1658,7 +1658,7 @@ mysql_init(MYSQL *mysql) #endif #ifdef HAVE_SMEM mysql->options.shared_memory_base_name=(char*)def_shared_memory_base_name; -#endif +#endif return mysql; } @@ -1716,9 +1716,9 @@ static void mysql_once_init() my_bool STDCALL mysql_ssl_set(MYSQL *mysql __attribute__((unused)) , - const char *key __attribute__((unused)), + const char *key __attribute__((unused)), const char *cert __attribute__((unused)), - const char *ca __attribute__((unused)), + const char *ca __attribute__((unused)), const char *capath __attribute__((unused)), const char *cipher __attribute__((unused))) { @@ -1795,7 +1795,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, { char buff[NAME_LEN+USERNAME_LENGTH+100],charset_name_buff[16]; char *end,*host_info,*charset_name; - char password_hash[20]; /* Used for tmp storage of stage1 hash */ + char password_hash[SCRAMBLE41_LENGTH]; /* tmp storage stage1 hash */ my_socket sock; uint32 ip_addr; struct sockaddr_in sock_addr; @@ -1861,7 +1861,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if ((!mysql->options.protocol || mysql->options.protocol == MYSQL_PROTOCOL_MEMORY)&& (!host || !strcmp(host,LOCAL_HOST))) { - if ((create_shared_memory(mysql,net, mysql->options.connect_timeout)) == + if ((create_shared_memory(mysql,net, mysql->options.connect_timeout)) == INVALID_HANDLE_VALUE) { DBUG_PRINT("error", @@ -1871,11 +1871,11 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, (int) mysql->options.shared_memory_base_name, (int) have_tcpip)); if (mysql->options.protocol == MYSQL_PROTOCOL_MEMORY) - goto error; -/* + goto error; +/* Try also with PIPE or TCP/IP */ - } + } else { mysql->options.protocol=MYSQL_PROTOCOL_MEMORY; @@ -1935,9 +1935,9 @@ Try also with PIPE or TCP/IP if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE || (host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) || (unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE))) - goto error; - /* - Try also with TCP/IP + goto error; + /* + Try also with TCP/IP */ } else @@ -2028,7 +2028,7 @@ Try also with PIPE or TCP/IP vio_poll_read(net->vio, mysql->options.connect_timeout)) { net->last_errno= CR_SERVER_LOST; - strmov(net->last_error,ER(net->last_errno)); + strmov(net->last_error,ER(net->last_errno)); goto error; } if ((pkt_length=net_safe_read(mysql)) == packet_error) @@ -2100,7 +2100,7 @@ Try also with PIPE or TCP/IP } goto error; } - + /* Save connection information */ if (!user) user=""; if (!passwd) passwd=""; @@ -2180,7 +2180,7 @@ Try also with PIPE or TCP/IP if (my_net_write(net,buff,(uint) (2)) || net_flush(net)) { net->last_errno= CR_SERVER_LOST; - strmov(net->last_error,ER(net->last_errno)); + strmov(net->last_error,ER(net->last_errno)); goto error; } /* Do the SSL layering. */ @@ -2192,7 +2192,7 @@ Try also with PIPE or TCP/IP options->ssl_cipher))) { net->last_errno= CR_SSL_CONNECTION_ERROR; - strmov(net->last_error,ER(net->last_errno)); + strmov(net->last_error,ER(net->last_errno)); goto error; } DBUG_PRINT("info", ("IO layer change in progress...")); @@ -2201,7 +2201,7 @@ Try also with PIPE or TCP/IP { net->last_errno= CR_SSL_CONNECTION_ERROR; strmov(net->last_error,ER(net->last_errno)); - goto error; + goto error; } DBUG_PRINT("info", ("IO layer change done!")); } @@ -2215,7 +2215,7 @@ Try also with PIPE or TCP/IP strmake(buff+5,user,32); /* Max user name */ else read_user_name((char*) buff+5); - /* We have to handle different version of handshake here */ + /* We have to handle different version of handshake here */ #ifdef _CUSTOMCONFIG_ #include "_cust_libmysql.h"; #endif @@ -2232,7 +2232,7 @@ Try also with PIPE or TCP/IP end=scramble(strend(buff+5)+1, mysql->scramble_buff,"\1~MySQL#!\2", (my_bool) (mysql->protocol_version == 9)); } - else /* For empty password*/ + else /* For empty password*/ { end=strend(buff+5)+1; *end=0; /* Store zero length scramble */ @@ -2243,23 +2243,23 @@ Try also with PIPE or TCP/IP end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd, (my_bool) (mysql->protocol_version == 9)); - /* Add database if needed */ + /* Add database if needed */ if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB)) { end=strmake(end+1,db,NAME_LEN); mysql->db=my_strdup(db,MYF(MY_WME)); db=0; } - /* Write authentication package */ + /* Write authentication package */ if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net)) { - net->last_errno= CR_SERVER_LOST; - strmov(net->last_error,ER(net->last_errno)); + net->last_errno= CR_SERVER_LOST; + strmov(net->last_error,ER(net->last_errno)); goto error; } - - /* We shall only query sever if it expect us to do so */ - + + /* We shall only query sever if it expect us to do so */ + if ( (pkt_length=net_safe_read(mysql)) == packet_error) goto error; @@ -2269,46 +2269,47 @@ Try also with PIPE or TCP/IP if (pkt_length==24) /* We have new hash back */ { /* Old passwords will have zero at the first byte of hash */ - if (net->read_pos[0]) + if (net->read_pos[0]) { - /* Build full password hash as it is required to decode scramble */ - password_hash_stage1(buff, passwd); + /* Build full password hash as it is required to decode scramble */ + password_hash_stage1(buff, passwd); /* Store copy as we'll need it later */ - memcpy(password_hash,buff,20); + memcpy(password_hash,buff,SCRAMBLE41_LENGTH); /* Finally hash complete password using hash we got from server */ password_hash_stage2(password_hash,net->read_pos); /* Decypt and store scramble 4 = hash for stage2 */ - password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash,20); - mysql->scramble_buff[20]=0; + password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash, + SCRAMBLE41_LENGTH); + mysql->scramble_buff[SCRAMBLE41_LENGTH]=0; /* Encode scramble with password. Recycle buffer */ - password_crypt(mysql->scramble_buff,buff,buff,20); + password_crypt(mysql->scramble_buff,buff,buff,SCRAMBLE41_LENGTH); } else { /* Create password to decode scramble */ create_key_from_old_password(passwd,password_hash); /* Decypt and store scramble 4 = hash for stage2 */ - password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash,20); - mysql->scramble_buff[20]=0; - /* Finally scramble decoded scramble with password */ - scramble(buff, mysql->scramble_buff, passwd, - (my_bool) (mysql->protocol_version == 9)); - } + password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash, + SCRAMBLE41_LENGTH); + mysql->scramble_buff[SCRAMBLE41_LENGTH]=0; + /* Finally scramble decoded scramble with password */ + scramble(buff, mysql->scramble_buff, passwd,0); + } /* Write second package of authentication */ - if (my_net_write(net,buff,20) || net_flush(net)) + if (my_net_write(net,buff,SCRAMBLE41_LENGTH) || net_flush(net)) { - net->last_errno= CR_SERVER_LOST; - strmov(net->last_error,ER(net->last_errno)); + net->last_errno= CR_SERVER_LOST; + strmov(net->last_error,ER(net->last_errno)); goto error; } - /* Read What server thinks about out new auth message report */ + /* Read What server thinks about out new auth message report */ if (net_safe_read(mysql) == packet_error) goto error; } } - - /* End of authentication part of handshake */ - + + /* End of authentication part of handshake */ + if (client_flag & CLIENT_COMPRESS) /* We will use compression */ net->compress=1; if (db && mysql_select_db(mysql,db)) @@ -2395,7 +2396,7 @@ static my_bool mysql_reconnect(MYSQL *mysql) mysql->free_me=0; mysql_close(mysql); *mysql=tmp_mysql; - mysql_fix_pointers(mysql, &tmp_mysql); /* adjust connection pointers */ + mysql_fix_pointers(mysql, &tmp_mysql); /* adjust connection pointers */ net_clear(&mysql->net); mysql->affected_rows= ~(my_ulonglong) 0; DBUG_RETURN(0); @@ -2403,28 +2404,28 @@ static my_bool mysql_reconnect(MYSQL *mysql) /************************************************************************** - Change user and database + Change user and database **************************************************************************/ -my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, +my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, const char *passwd, const char *db) { char buff[512],*end=buff; ulong pkt_length; - char password_hash[20]; /* Used for tmp storage of stage1 hash */ + char password_hash[SCRAMBLE41_LENGTH]; /* Used for tmp storage of stage1 hash */ NET *net= &mysql->net; - + DBUG_ENTER("mysql_change_user"); if (!user) user=""; if (!passwd) passwd=""; - + /* Store user into the buffer */ end=strmov(end,user)+1; - - /* + + /* We always start with old type handshake the only difference is message sent If server handles secure connection type we'll not send the real scramble */ @@ -2434,24 +2435,24 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, { /* Use something for not empty password not to match it against empty one */ end=scramble(end, mysql->scramble_buff,"\1~MySQL#!\2", - (my_bool) (mysql->protocol_version == 9)); - } - else /* For empty password*/ + (my_bool) (mysql->protocol_version == 9)); + } + else /* For empty password*/ *end=0; /* Store zero length scramble */ } /* Real scramble is sent only for servers. This is to be blocked by option */ else end=scramble(end, mysql->scramble_buff, passwd, (my_bool) (mysql->protocol_version == 9)); - - /* Add database if needed */ + + /* Add database if needed */ end=strmov(end+1,db ? db : ""); - - /* Write authentication package */ - + + /* Write authentication package */ + simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (end-buff),1); - - /* We shall only query sever if it expect us to do so */ + + /* We shall only query sever if it expect us to do so */ if ( (pkt_length=net_safe_read(mysql)) == packet_error) goto error; @@ -2461,44 +2462,46 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, if (pkt_length==24) /* We have new hash back */ { /* Old passwords will have zero at the first byte of hash */ - if (net->read_pos[0]) + if (net->read_pos[0]) { - /* Build full password hash as it is required to decode scramble */ - password_hash_stage1(buff, passwd); + /* Build full password hash as it is required to decode scramble */ + password_hash_stage1(buff, passwd); /* Store copy as we'll need it later */ - memcpy(password_hash,buff,20); + memcpy(password_hash,buff,SCRAMBLE41_LENGTH); /* Finally hash complete password using hash we got from server */ password_hash_stage2(password_hash,net->read_pos); /* Decypt and store scramble 4 = hash for stage2 */ - password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash,20); - mysql->scramble_buff[20]=0; + password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash, + SCRAMBLE41_LENGTH); + mysql->scramble_buff[SCRAMBLE41_LENGTH]=0; /* Encode scramble with password. Recycle buffer */ - password_crypt(mysql->scramble_buff,buff,buff,20); + password_crypt(mysql->scramble_buff,buff,buff,SCRAMBLE41_LENGTH); } else { /* Create password to decode scramble */ create_key_from_old_password(passwd,password_hash); /* Decypt and store scramble 4 = hash for stage2 */ - password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash,20); - mysql->scramble_buff[20]=0; - /* Finally scramble decoded scramble with password */ + password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash, + SCRAMBLE41_LENGTH); + mysql->scramble_buff[SCRAMBLE41_LENGTH]=0; + /* Finally scramble decoded scramble with password */ scramble(buff, mysql->scramble_buff, passwd, - (my_bool) (mysql->protocol_version == 9)); - } + (my_bool) (mysql->protocol_version == 9)); + } /* Write second package of authentication */ - if (my_net_write(net,buff,20) || net_flush(net)) + if (my_net_write(net,buff,SCRAMBLE41_LENGTH) || net_flush(net)) { - net->last_errno= CR_SERVER_LOST; - strmov(net->last_error,ER(net->last_errno)); + net->last_errno= CR_SERVER_LOST; + strmov(net->last_error,ER(net->last_errno)); goto error; } - /* Read What server thinks about out new auth message report */ + /* Read What server thinks about out new auth message report */ if (net_safe_read(mysql) == packet_error) goto error; } } - + my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR)); @@ -2507,10 +2510,10 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, mysql->passwd=my_strdup(passwd,MYF(MY_WME)); mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0; DBUG_RETURN(0); - + error: DBUG_RETURN(1); - + } @@ -2598,7 +2601,7 @@ mysql_close(MYSQL *mysql) { next_element= element->next; stmt_close((MYSQL_STMT *)element->data, 0); - } + } } if (mysql != mysql->master) mysql_close(mysql->master); @@ -2686,7 +2689,7 @@ STDCALL mysql_add_slave(MYSQL* mysql, const char* host, Send the query and return so we can do something else. Needs to be followed by mysql_read_query_result() when we want to finish processing it. -*/ +*/ int STDCALL mysql_send_query(MYSQL* mysql, const char* query, ulong length) @@ -4024,12 +4027,12 @@ static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param) DBUG_ENTER("store_param"); DBUG_PRINT("enter",("type: %d, buffer:%lx, length: %d", param->buffer_type, param->buffer ? param->buffer : "0", *param->length)); - + if (param->is_null || param->buffer_type == MYSQL_TYPE_NULL) store_param_null(net, param); else { - /* Allocate for worst case (long string) */ + /* Allocate for worst case (long string) */ if ((my_realloc_str(net, 9 + *param->length))) DBUG_RETURN(1); (*param->store_param_func)(net, param); @@ -4205,14 +4208,14 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind) param->param_number); DBUG_RETURN(1); } - + /* If param->length is not given, change it to point to bind_length. This way we can always use *param->length to get the length of data */ if (!param->length) param->length= ¶m->bind_length; - + /* Setup data copy functions for the different supported types */ switch (param->buffer_type) { case MYSQL_TYPE_NULL: @@ -4358,7 +4361,7 @@ static void fetch_result_tinyint(MYSQL_BIND *param, uchar **row) static void fetch_result_short(MYSQL_BIND *param, uchar **row) { short value= *(short *)row; - int2store(param->buffer, value); + int2store(param->buffer, value); *row+=2; } @@ -4462,7 +4465,7 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind) sprintf(stmt->last_error, ER(stmt->last_errno= CR_UNSUPPORTED_PARAM_TYPE), param->buffer_type, param->param_number); DBUG_RETURN(1); - } + } if (!param->length) param->length= ¶m->bind_length; } @@ -4479,10 +4482,10 @@ stmt_fetch_row(MYSQL_STMT *stmt, uchar **row) { MYSQL_BIND *bind, *end; uchar *null_ptr= (uchar*) *row, bit; - - *row+= (stmt->field_count+7)/8; + + *row+= (stmt->field_count+7)/8; bit=1; - + /* Copy complete row to application buffers */ for (bind= stmt->bind, end= (MYSQL_BIND *) bind + stmt->field_count; bind < end; @@ -4505,7 +4508,7 @@ stmt_fetch_row(MYSQL_STMT *stmt, uchar **row) } static int read_binary_data(MYSQL *mysql) -{ +{ if (packet_error == net_safe_read(mysql)) return -1; if (mysql->net.read_pos[0]) @@ -4532,9 +4535,9 @@ int STDCALL mysql_fetch(MYSQL_STMT *stmt) DBUG_RETURN((int) stmt_fetch_row(stmt,(uchar **) &mysql->net.read_pos+1)); DBUG_RETURN(0); } - DBUG_PRINT("info", ("end of data")); + DBUG_PRINT("info", ("end of data")); mysql->status= MYSQL_STATUS_READY; - + if (res < 0) /* Network error */ { set_stmt_errmsg(stmt,(char *)mysql->net.last_error, diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh index a65aca3c1fc..3ed295170ad 100644 --- a/scripts/mysql_fix_privilege_tables.sh +++ b/scripts/mysql_fix_privilege_tables.sh @@ -170,12 +170,20 @@ fi @bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA alter table user -change password password char(45) not null, add max_questions int(11) NOT NULL AFTER x509_subject, add max_updates int(11) unsigned NOT NULL AFTER max_questions, add max_connections int(11) unsigned NOT NULL AFTER max_updates; END_OF_DATA +# Increase password length to handle new passwords + +@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA +alter table user +change password password char(45) not null; +END_OF_DATA + + + # # Add Create_tmp_table_priv and Lock_tables_priv to db and host # diff --git a/sql/mini_client.cc b/sql/mini_client.cc index 7d3b10a34a9..27d6255d82a 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -490,7 +490,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, uint net_read_timeout) { char buff[NAME_LEN+USERNAME_LENGTH+100],*end,*host_info; - char password_hash[20]; + char password_hash[SCRAMBLE41_LENGTH]; my_socket sock; ulong ip_addr; struct sockaddr_in sock_addr; @@ -856,28 +856,29 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, /* Build full password hash as it is required to decode scramble */ password_hash_stage1(buff, passwd); /* Store copy as we'll need it later */ - memcpy(password_hash,buff,20); + memcpy(password_hash,buff,SCRAMBLE41_LENGTH); /* Finally hash complete password using hash we got from server */ password_hash_stage2(password_hash,(char*)net->read_pos); /* Decypt and store scramble 4 = hash for stage2 */ - password_crypt((char*)net->read_pos+4,mysql->scramble_buff,password_hash,20); - mysql->scramble_buff[20]=0; + password_crypt((char*)net->read_pos+4,mysql->scramble_buff,password_hash, + SCRAMBLE41_LENGTH); + mysql->scramble_buff[SCRAMBLE41_LENGTH]=0; /* Encode scramble with password. Recycle buffer */ - password_crypt(mysql->scramble_buff,buff,buff,20); + password_crypt(mysql->scramble_buff,buff,buff,SCRAMBLE41_LENGTH); } else { /* Create password to decode scramble */ create_key_from_old_password(passwd,password_hash); /* Decypt and store scramble 4 = hash for stage2 */ - password_crypt((char*)net->read_pos+4,mysql->scramble_buff,password_hash,20); - mysql->scramble_buff[20]=0; + password_crypt((char*)net->read_pos+4,mysql->scramble_buff,password_hash, + SCRAMBLE41_LENGTH); + mysql->scramble_buff[SCRAMBLE41_LENGTH]=0; /* Finally scramble decoded scramble with password */ - scramble(buff, mysql->scramble_buff, passwd, - (my_bool) (mysql->protocol_version == 9)); + scramble(buff, mysql->scramble_buff, passwd,0); } /* Write second package of authentication */ - if (my_net_write(net,buff,20) || net_flush(net)) + if (my_net_write(net,buff,SCRAMBLE41_LENGTH) || net_flush(net)) { net->last_errno= CR_SERVER_LOST; strmov(net->last_error,ER(net->last_errno)); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a82ec7a3a0a..c7e854611b9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2496,6 +2496,9 @@ static void create_new_thread(THD *thd) for (uint i=0; i < 8 ; i++) // Generate password teststring thd->scramble[i]= (char) (rnd(&sql_rand)*94+33); thd->scramble[8]=0; + // Back it up as old clients may need it + memcpy(thd->old_scramble,thd->scramble,9); + thd->real_id=pthread_self(); // Keep purify happy diff --git a/sql/password.c b/sql/password.c index 98cac1e07d0..7a3831d67b7 100644 --- a/sql/password.c +++ b/sql/password.c @@ -66,7 +66,6 @@ #define PVERSION41_CHAR '*' /* Scramble length for new password version */ -#define SCRAMBLE41_LENGTH 20 /* @@ -175,17 +174,12 @@ void create_random_string(int length,struct rand_struct *rand_st,char* target) none */ -inline void password_crypt(const char* from,char* to, const char* password,int length) +void password_crypt(const char* from,char* to, const char* password,int length) { const char *from_end=from+length; - while(from<from_end) - { - *to=*from^*password; - from++; - to++; - password++; - } + while (from < from_end) + *to++= *(from++) ^* (password++); } @@ -286,7 +280,9 @@ void password_hash_stage2(char *to,const char *salt) none */ -void make_scrambled_password(char *to,const char *password,my_bool force_old_scramble,struct rand_struct *rand_st) +void make_scrambled_password(char *to,const char *password, + my_bool force_old_scramble, + struct rand_struct *rand_st) { ulong hash_res[2]; /* Used for pre 4.1 password hashing */ unsigned short salt; /* Salt for 4.1 version password */ @@ -336,7 +332,6 @@ void get_salt_from_bin_password(ulong *res,unsigned char *password,ulong salt) unsigned char* password_end=password+SCRAMBLE41_LENGTH; *res=salt; res++; - bzero(res,5*sizeof(res[0])); /* Process password of known length*/ while (password<password_end) @@ -364,12 +359,14 @@ void get_salt_from_bin_password(ulong *res,unsigned char *password,ulong salt) !0 for invalid password */ -my_bool validate_password(const char* password, const char* message, ulong* salt) +my_bool validate_password(const char* password, const char* message, + ulong* salt) { char buffer[SCRAMBLE41_LENGTH]; /* Used for password validation */ char tmpsalt[8]; /* Temporary value to convert salt to string form */ - int i; ulong salt_candidate[6]; /* Computed candidate salt */ + ulong* sc=salt_candidate; /* we need to be able to increment */ + ulong* salt_end; /* Now we shall get stage1 encrypted password in buffer*/ password_crypt(password,buffer,message,SCRAMBLE41_LENGTH); @@ -381,9 +378,11 @@ my_bool validate_password(const char* password, const char* message, ulong* salt /* Convert password to salt to compare */ get_salt_from_bin_password(salt_candidate,buffer,salt[0]); - /* Now we shall get exactly the same password as we have stored for user */ - for(i=1;i<6;i++) - if (salt[i]!=salt_candidate[i]) return 1; + /* Now we shall get exactly the same password as we have stored for user */ + for (salt_end=salt+5 ; salt < salt_end; ) + if (*++salt != *++sc) + return 1; + /* Or password correct*/ return 0; } @@ -400,11 +399,9 @@ my_bool validate_password(const char* password, const char* message, ulong* salt password length >0 */ -inline int get_password_length(my_bool force_old_scramble) +int get_password_length(my_bool force_old_scramble) { - if (force_old_scramble) - return 16; - else return SHA1_HASH_SIZE*2+4+1; + return (force_old_scramble) ? 16 : SHA1_HASH_SIZE*2+4+1; } @@ -420,9 +417,9 @@ inline int get_password_length(my_bool force_old_scramble) !0 password version char for newer passwords */ -inline char get_password_version(const char* password) +char get_password_version(const char* password) { - if (password==NULL) return 0; + if (password==NULL) return 0; if (password[0]==PVERSION41_CHAR) return PVERSION41_CHAR; return 0; } @@ -467,7 +464,6 @@ inline uint char_val(char X) void get_salt_from_password(ulong *res,const char *password) { - bzero(res,6*sizeof(res[0])); if (password) /* zero salt corresponds to empty password */ { if (password[0]==PVERSION41_CHAR) /* if new password */ @@ -553,19 +549,17 @@ void get_hash_and_password(ulong* salt, uint8 pversion, char* hash, unsigned cha if (pversion) /* New password version assumed */ { - salt_end=salt+6; + salt_end=salt+5; sprintf(hash,"%04x",(unsigned short)salt[0]); - salt++; /* position to the second element */ while (salt<salt_end) /* Iterate over these elements*/ { - val=*salt; - for(t=3;t>=0;t--) + val=*(++salt); + for (t=3; t>=0; t--) { bin_password[t]=val%256; val>>=8; /* Scroll 8 bits to get next part*/ } bin_password+=4; /* Get to next 4 chars*/ - salt++; } } else @@ -611,7 +605,7 @@ void get_hash_and_password(ulong* salt, uint8 pversion, char* hash, unsigned cha void create_key_from_old_password(const char* passwd, char* key) { - char buffer[20]; /* Buffer for various needs */ + char buffer[SCRAMBLE41_LENGTH]; /* Buffer for various needs */ ulong salt[6]; /* Salt (large for safety) */ /* At first hash password to the string stored in password */ make_scrambled_password(buffer,passwd,1,(struct rand_struct *)NULL); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3ebd3fdbd3b..47b641bc519 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -102,10 +102,10 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) if (dont_read_acl_tables) { DBUG_RETURN(0); /* purecov: tested */ - } - + } + priv_version++; /* Priveleges updated */ - + /* To be able to run this from boot, we allocate a temporary THD */ @@ -205,7 +205,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) continue; /* purecov: tested */ } } - get_salt_from_password(user.salt,user.password); + get_salt_from_password(user.salt,user.password); user.access=get_access(table,3) & GLOBAL_ACLS; user.sort=get_sort(2,user.host.hostname,user.user); user.hostname_length= (user.host.hostname ? @@ -263,7 +263,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) sizeof(ACL_USER),(qsort_cmp) acl_compare); end_read_record(&read_record_info); freeze_size(&acl_users); - + init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0); VOID(my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100)); while (!(read_record_info.read_record(&read_record_info))) @@ -452,17 +452,17 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b) Prepare crypted scramble to be sent to the client */ -void prepare_scramble(THD* thd, ACL_USER *acl_user,char* prepared_scramble) +void prepare_scramble(THD *thd, ACL_USER *acl_user,char* prepared_scramble) { /* Binary password format to be used for generation*/ - char bin_password[20]; + char bin_password[SCRAMBLE41_LENGTH]; /* Generate new long scramble for the thread */ - create_random_string(20,&thd->rand,thd->scramble); - thd->scramble[20]=0; + create_random_string(SCRAMBLE41_LENGTH,&thd->rand,thd->scramble); + thd->scramble[SCRAMBLE41_LENGTH]=0; /* Get binary form, First 4 bytes of prepared scramble is salt */ get_hash_and_password(acl_user->salt,acl_user->pversion,prepared_scramble,(unsigned char*)bin_password); /* Finally encrypt password to get prepared scramble */ - password_crypt(thd->scramble,prepared_scramble+4,bin_password,20); + password_crypt(thd->scramble,prepared_scramble+4,bin_password,SCRAMBLE41_LENGTH); } @@ -472,11 +472,11 @@ void prepare_scramble(THD* thd, ACL_USER *acl_user,char* prepared_scramble) /* Get master privilges for user (priviliges for all tables). Required before connecting to MySQL - + as we have 2 stage handshake now we cache user not to lookup - it second time. At the second stage we do not lookup user in case + it second time. At the second stage we do not lookup user in case we already know it; - + */ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, @@ -488,7 +488,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, *priv_user=(char*) user; bool password_correct=0; ACL_USER *acl_user=NULL; - + DBUG_ENTER("acl_getroot"); bzero(mqh,sizeof(USER_RESOURCES)); @@ -498,18 +498,18 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, DBUG_RETURN((ulong) ~NO_ACCESS); /* purecov: tested */ } VOID(pthread_mutex_lock(&acl_cache->lock)); - - + + /* Get possible access from user_list. This is or'ed to others not fully specified - + If we have cached user use it, in other case look it up. */ - + if (stage && (*cur_priv_version==priv_version)) acl_user=*hint_user; - else + else for (uint i=0 ; i < acl_users.elements ; i++) { ACL_USER *acl_user_search=dynamic_element(&acl_users,i,ACL_USER*); @@ -517,30 +517,30 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, { if (compare_hostname(&acl_user_search->host,host,ip)) { - /* Found mathing user */ + /* Found mathing user */ acl_user=acl_user_search; /* Store it as a cache */ *hint_user=acl_user; *cur_priv_version=priv_version; break; - } + } } - } - - + } + + /* Now we have acl_user found and may start our checks */ - - if (acl_user) - { - /* Password should present for both or absend for both */ + + if (acl_user) + { + /* Password should present for both or absend for both */ if (!acl_user->password && !*password || (acl_user->password && *password)) - { + { /* Quick check and accept for empty passwords*/ if (!acl_user->password && !*password) password_correct=1; else /* Normal password presents */ - { + { /* New version password is checked differently */ if (acl_user->pversion) { @@ -548,40 +548,40 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, { if (!validate_password(password,message,acl_user->salt)) password_correct=1; - } + } else /* First stage - just prepare scramble */ prepare_scramble(thd,acl_user,prepared_scramble); } /* Old way to check password */ - else + else { - /* Checking the scramble at any stage. First - old clients */ + /* Checking the scramble at any stage. First - old clients */ if (!check_scramble(password,message,acl_user->salt, (my_bool) old_ver)) password_correct=1; - else /* Password incorrect */ + else /* Password incorrect */ /* At the first stage - prepare scramble */ if (!stage) - prepare_scramble(thd,acl_user,prepared_scramble); - } + prepare_scramble(thd,acl_user,prepared_scramble); + } } } } - + /* If user not found password_correct will also be zero */ - if (!password_correct) - goto unlock_and_exit; - + if (!password_correct) + goto unlock_and_exit; + /* OK. User found and password checked continue validation */ - - + + #ifdef HAVE_OPENSSL Vio *vio=thd->net.vio; /* - In this point we know that user is allowed to connect - from given host by given username/password pair. Now - we check if SSL is required, if user is using SSL and - if X509 certificate attributes are OK + In this point we know that user is allowed to connect + from given host by given username/password pair. Now + we check if SSL is required, if user is using SSL and + if X509 certificate attributes are OK */ switch (acl_user->ssl_type) { case SSL_TYPE_NOT_SPECIFIED: // Impossible @@ -594,8 +594,8 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, break; case SSL_TYPE_X509: /* Client should have any valid certificate. */ /* - Connections with non-valid certificates are dropped already - in sslaccept() anyway, so we do not check validity here. + Connections with non-valid certificates are dropped already + in sslaccept() anyway, so we do not check validity here. */ if (SSL_get_peer_certificate(vio->ssl_)) user_access=acl_user->access; @@ -624,7 +624,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, X509* cert=SSL_get_peer_certificate(vio->ssl_); DBUG_PRINT("info",("checkpoint 2")); /* If X509 issuer is speified, we check it... */ - if (acl_user->x509_issuer) + if (acl_user->x509_issuer) { DBUG_PRINT("info",("checkpoint 3")); char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); @@ -660,7 +660,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, *mqh=acl_user->user_resource; if (!acl_user->user) *priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */ - + unlock_and_exit: VOID(pthread_mutex_unlock(&acl_cache->lock)); DBUG_RETURN(user_access); @@ -675,12 +675,12 @@ static byte* check_get_key(ACL_USER *buff,uint *length, } static void acl_update_user(const char *user, const char *host, - const char *password, + const char *password, enum SSL_type ssl_type, const char *ssl_cipher, const char *x509_issuer, const char *x509_subject, - USER_RESOURCES *mqh, + USER_RESOURCES *mqh, ulong privileges) { for (uint i=0 ; i < acl_users.elements ; i++) @@ -716,8 +716,8 @@ static void acl_update_user(const char *user, const char *host, if (!password[0]) /* If password is empty set it to null */ { acl_user->password=0; - acl_user->pversion=0; // just initialize - } + acl_user->pversion=0; // just initialize + } else { acl_user->password=(char*) ""; // Just point at something @@ -733,7 +733,7 @@ static void acl_update_user(const char *user, const char *host, static void acl_insert_user(const char *user, const char *host, - const char *password, + const char *password, enum SSL_type ssl_type, const char *ssl_cipher, const char *x509_issuer, @@ -926,7 +926,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr) { if (*wildstr == wild_prefix && wildstr[1]) wildstr++; - if (my_toupper(cs, *wildstr++) != + if (my_toupper(cs, *wildstr++) != my_toupper(cs, *str++)) DBUG_RETURN(1); } if (! *wildstr ) DBUG_RETURN (*str != 0); @@ -1091,7 +1091,7 @@ bool check_change_password(THD *thd, const char *host, const char *user) RETURN VALUES 0 ok 1 ERROR; In this case the error is sent to the client. -*/ +*/ bool change_password(THD *thd, const char *host, const char *user, char *new_password) @@ -1107,7 +1107,7 @@ bool change_password(THD *thd, const char *host, const char *user, /* password should always be 0,16 or 45 chars; simple hack to avoid cracking */ length=(uint) strlen(new_password); - + if (length!=45) new_password[length & 16]=0; @@ -1133,8 +1133,8 @@ bool change_password(THD *thd, const char *host, const char *user, if (!new_password[0]) acl_user->password=0; else - acl_user->password=(char*) ""; // Point at something - + acl_user->password=(char*) ""; // Point at something + acl_cache->clear(1); // Clear locked hostname cache VOID(pthread_mutex_unlock(&acl_cache->lock)); @@ -1321,7 +1321,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, if (combo.password.str && combo.password.str[0]) { - if ((combo.password.length != HASH_PASSWORD_LENGTH) + if ((combo.password.length != HASH_PASSWORD_LENGTH) && combo.password.length != HASH_OLD_PASSWORD_LENGTH) { my_error(ER_PASSWORD_NO_MATCH,MYF(0)); @@ -1329,7 +1329,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, } password=combo.password.str; } - + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); table->field[1]->store(combo.user.str,combo.user.length, system_charset_info); table->file->index_init(0); @@ -1742,9 +1742,9 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip, } else { - if ((host && !wild_case_compare(system_charset_info, + if ((host && !wild_case_compare(system_charset_info, host,grant_table->host)) || - (ip && !wild_case_compare(system_charset_info, + (ip && !wild_case_compare(system_charset_info, ip,grant_table->host))) found=grant_table; // Host ok } @@ -2676,9 +2676,9 @@ bool check_grant_db(THD *thd,const char *db) GRANT_TABLE *grant_table = (GRANT_TABLE*) hash_element(&hash_tables,idx); if (len < grant_table->key_length && !memcmp(grant_table->hash_key,helping,len) && - (thd->host && !wild_case_compare(system_charset_info, + (thd->host && !wild_case_compare(system_charset_info, thd->host,grant_table->host) || - (thd->ip && !wild_case_compare(system_charset_info, + (thd->ip && !wild_case_compare(system_charset_info, thd->ip,grant_table->host)))) { error=0; // Found match @@ -2764,7 +2764,7 @@ static uint command_lengths[]= }; -int mysql_show_grants(THD *thd,LEX_USER *lex_user) +int mysql_show_grants(THD *thd,LEX_USER *lex_user) { ulong want_access; uint counter,index; @@ -2803,7 +2803,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) !my_strcasecmp(system_charset_info, lex_user->host.str, host)) break; } - if (counter == acl_users.elements) + if (counter == acl_users.elements) { my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT), MYF(0),lex_user->user.str,lex_user->host.str); @@ -2836,13 +2836,13 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) global.append("ALL PRIVILEGES",14); else if (!(want_access & ~GRANT_ACL)) global.append("USAGE",5); - else + else { bool found=0; ulong j,test_access= want_access & ~GRANT_ACL; for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1) { - if (test_access & j) + if (test_access & j) { if (found) global.append(", ",2); @@ -2852,7 +2852,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) } } global.append (" ON *.* TO '",12); - global.append(lex_user->user.str,lex_user->user.length); + global.append(lex_user->user.str,lex_user->user.length); global.append ("'@'",3); global.append(lex_user->host.str,lex_user->host.length); global.append ('\''); @@ -2901,9 +2901,9 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) (acl_user->user_resource.questions | acl_user->user_resource.updates | acl_user->user_resource.connections)) { - global.append(" WITH",5); + global.append(" WITH",5); if (want_access & GRANT_ACL) - global.append(" GRANT OPTION",13); + global.append(" GRANT OPTION",13); if (acl_user->user_resource.questions) { char buff[22], *p; // just as in int2str @@ -2950,7 +2950,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) !my_strcasecmp(system_charset_info, lex_user->host.str, host)) { want_access=acl_db->access; - if (want_access) + if (want_access) { String db(buff,sizeof(buff),system_charset_info); db.length(0); @@ -2976,10 +2976,10 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) db.append (" ON `",5); db.append(acl_db->db); db.append ("`.* TO '",8); - db.append(lex_user->user.str,lex_user->user.length); + db.append(lex_user->user.str,lex_user->user.length); db.append ("'@'",3); db.append(lex_user->host.str, lex_user->host.length); - db.append ('\''); + db.append ('\''); if (want_access & GRANT_ACL) db.append(" WITH GRANT OPTION",18); thd->packet.length(0); @@ -2998,7 +2998,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) for (index=0 ; index < hash_tables.records ; index++) { const char *user,*host; - GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&hash_tables,index); + GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&hash_tables,index); if (!(user=grant_table->user)) user=""; @@ -3017,21 +3017,21 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) if (test_all_bits(grant_table->privs,(TABLE_ACLS & ~GRANT_ACL))) global.append("ALL PRIVILEGES",14); - else + else { int found=0; ulong j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL; for (counter=0, j = SELECT_ACL;j <= TABLE_ACLS; counter++,j <<= 1) { - if (test_access & j) + if (test_access & j) { if (found) global.append(", ",2); found = 1; global.append(command_array[counter],command_lengths[counter]); - if (grant_table->cols) + if (grant_table->cols) { uint found_col=0; for (uint col_index=0 ; @@ -3040,9 +3040,9 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) { GRANT_COLUMN *grant_column = (GRANT_COLUMN*) hash_element(&grant_table->hash_columns,col_index); - if (grant_column->rights & j) + if (grant_column->rights & j) { - if (!found_col) + if (!found_col) { global.append(" (",2); found_col=1; @@ -3064,12 +3064,12 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) global.append(".",1); global.append(grant_table->tname); global.append(" TO '",5); - global.append(lex_user->user.str,lex_user->user.length); + global.append(lex_user->user.str,lex_user->user.length); global.append("'@'",3); - global.append(lex_user->host.str,lex_user->host.length); + global.append(lex_user->host.str,lex_user->host.length); global.append('\''); if (want_access & GRANT_ACL) - global.append(" WITH GRANT OPTION",18); + global.append(" WITH GRANT OPTION",18); thd->packet.length(0); net_store_data(&thd->packet,global.ptr(),global.length()); if (my_net_write(&thd->net,(char*) thd->packet.ptr(), diff --git a/sql/sql_class.h b/sql/sql_class.h index ed97a3fffde..89be4741e5d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -499,7 +499,10 @@ public: uint check_loops_counter; //last id used to check loops /* variables.transaction_isolation is reset to this after each commit */ enum_tx_isolation session_tx_isolation; - char scramble[21]; // extend scramble to handle new auth + // extend scramble to handle new auth + char scramble[SCRAMBLE41_LENGTH+1]; + // old scramble is needed to handle old clients + char old_scramble[SCRAMBLE_LENGTH+1]; uint8 query_cache_type; // type of query cache processing bool slave_thread; bool set_query_id,locked,count_cuted_fields,some_tables_deleted; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index bdb074b304d..cfca7420237 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -44,8 +44,6 @@ #else #define MIN_HANDSHAKE_SIZE 6 #endif /* HAVE_OPENSSL */ -#define SCRAMBLE_LENGTH 8 -#define SCRAMBLE41_LENGTH 20 #define MEM_ROOT_BLOCK_SIZE 8192 #define MEM_ROOT_PREALLOC 8192 @@ -129,7 +127,7 @@ extern pthread_mutex_t LOCK_user_conn; static int get_or_create_user_conn(THD *thd, const char *user, const char *host, - USER_RESOURCES *mqh) + USER_RESOURCES *mqh) { int return_val=0; uint temp_len, user_len, host_len; @@ -163,7 +161,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, uc->connections = 1; uc->questions=uc->updates=uc->conn_per_hour=0; uc->user_resources=*mqh; - if (max_user_connections && mqh->connections > max_user_connections) + if (max_user_connections && mqh->connections > max_user_connections) uc->user_resources.connections = max_user_connections; uc->intime=thd->thr_create_time; if (hash_insert(&hash_user_connections, (byte*) uc)) @@ -178,7 +176,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, end: (void) pthread_mutex_unlock(&LOCK_user_conn); return return_val; - + } @@ -189,16 +187,16 @@ end: */ static int check_user(THD *thd,enum_server_command command, const char *user, - const char *passwd, const char *db, bool check_count, + const char *passwd, const char *db, bool check_count, bool do_send_error, char* crypted_scramble,int stage, - bool had_password,uint *cur_priv_version, + bool had_password,uint *cur_priv_version, ACL_USER** hint_user) { thd->db=0; thd->db_length=0; USER_RESOURCES ur; - - /* We shall avoid dupplicate user allocations here */ + + /* We shall avoid dupplicate user allocations here */ if (!(thd->user)) if (!(thd->user = my_strdup(user, MYF(0)))) { @@ -211,15 +209,15 @@ static int check_user(THD *thd,enum_server_command command, const char *user, !(thd->client_capabilities & CLIENT_LONG_PASSWORD),&ur,crypted_scramble, stage,cur_priv_version,hint_user); - + DBUG_PRINT("info", ("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'", thd->client_capabilities, thd->max_client_packet_length, thd->host_or_ip, thd->priv_user, had_password ? "yes": "no", thd->master_access, thd->db ? thd->db : "*none*")); - - /* in case we're going to retry we should not send error message at this point */ + + /* in case we're going to retry we should not send error message at this point */ if (thd->master_access & NO_ACCESS) { if (do_send_error) @@ -233,11 +231,11 @@ static int check_user(THD *thd,enum_server_command command, const char *user, thd->host_or_ip, had_password ? ER(ER_YES) : ER(ER_NO)); return(1); // Error already given - } - else + } + else return(-1); // do not report error in special handshake } - + if (check_count) { VOID(pthread_mutex_lock(&LOCK_thread_count)); @@ -262,16 +260,16 @@ static int check_user(THD *thd,enum_server_command command, const char *user, if ((ur.questions || ur.updates || ur.connections) && get_or_create_user_conn(thd,user,thd->host_or_ip,&ur)) return -1; - if (thd->user_connect && thd->user_connect->user_resources.connections && + if (thd->user_connect && thd->user_connect->user_resources.connections && check_for_max_user_connections(thd, thd->user_connect)) return -1; - + if (db && db[0]) { bool error=test(mysql_change_db(thd,db)); if (error && thd->user_connect) decrease_user_connections(thd->user_connect); - return error; + return error; } else send_ok(thd); // Ready to handle questions @@ -296,7 +294,7 @@ extern "C" void free_user(struct user_conn *uc) my_free((char*) uc,MYF(0)); } -void init_max_user_conn(void) +void init_max_user_conn(void) { (void) hash_init(&hash_user_connections,system_charset_info,max_connections, 0,0, @@ -309,7 +307,7 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc) { int error=0; DBUG_ENTER("check_for_max_user_connections"); - + if (max_user_connections && (max_user_connections <= (uint) uc->connections)) { @@ -317,7 +315,7 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc) error=1; goto end; } - uc->connections++; + uc->connections++; if (uc->user_resources.connections && uc->conn_per_hour++ >= uc->user_resources.connections) { @@ -441,7 +439,7 @@ static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them=false) { (void) pthread_mutex_lock(&LOCK_user_conn); - if (lu) // for GRANT + if (lu) // for GRANT { USER_CONN *uc; uint temp_len=lu->user.length+lu->host.length+2; @@ -530,9 +528,9 @@ check_connections(THD *thd) ulong pkt_len=0; { /* buff[] needs to big enough to hold the server_version variable */ - char buff[SERVER_VERSION_LENGTH + + char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH+64],*end; - int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB | + int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB | CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION; if (opt_using_transactions) @@ -555,7 +553,7 @@ check_connections(THD *thd) int2store(end+3,thd->server_status); bzero(end+5,13); end+=18; - + // At this point we write connection message and read reply if (net_write_command(net,(uchar) protocol_version, "", 0, buff, (uint) (end-buff)) || @@ -588,7 +586,7 @@ check_connections(THD *thd) DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)", pkt_len)); inc_host_errors(&thd->remote.sin_addr); - return(ER_HANDSHAKE_ERROR); + return(ER_HANDSHAKE_ERROR); } DBUG_PRINT("info", ("Reading user information over SSL layer")); if ((pkt_len=my_net_read(net)) == packet_error || @@ -615,81 +613,73 @@ check_connections(THD *thd) char *user= (char*) net->read_pos+5; char *passwd= strend(user)+1; char *db=0; - if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB) - db=strend(passwd)+1; - + if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB) + db=strend(passwd)+1; + /* We can get only old hash at this point */ - if (passwd[0] && strlen(passwd)!=SCRAMBLE_LENGTH) + if (passwd[0] && strlen(passwd)!=SCRAMBLE_LENGTH) return ER_HANDSHAKE_ERROR; - + if (thd->client_capabilities & CLIENT_INTERACTIVE) thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout; if ((thd->client_capabilities & CLIENT_TRANSACTIONS) && opt_using_transactions) thd->net.return_status= &thd->server_status; net->read_timeout=(uint) thd->variables.net_read_timeout; - + char prepared_scramble[SCRAMBLE41_LENGTH+4]; /* Buffer for scramble and hash */ - + ACL_USER* cached_user; uint cur_priv_version; - + /* Simple connect only for old clients. New clients always use secure auth */ bool simple_connect=(!(thd->client_capabilities & CLIENT_SECURE_CONNECTION)); - + /* Store information if we used password. passwd will be dammaged */ bool using_password=test(passwd[0]); - + /* Check user permissions. If password failure we'll get scramble back */ if (check_user(thd,COM_CONNECT, user, passwd, db, 1, simple_connect, prepared_scramble,0,using_password,&cur_priv_version,&cached_user)<0) - { + { /* If The client is old we just have to return error */ if (simple_connect) - return -1; - + return -1; + /* Store current used and database as they are erased with next packet */ - + char tmp_user[USERNAME_LENGTH+1]; char tmp_db[NAME_LEN+1]; + tmp_user[0]=0; if (user) - { - strncpy(tmp_user,user,USERNAME_LENGTH+1); - /* Extra safety if we have too long data */ - tmp_user[USERNAME_LENGTH]=0; - } - else - tmp_user[0]=0; + strmake(tmp_user,user,USERNAME_LENGTH); + + tmp_db[0]=0; if (db) - { - strncpy(tmp_db,db,NAME_LEN+1); - tmp_db[NAME_LEN]=0; - } - else - tmp_db[0]=0; - + strmake(tmp_db,db,NAME_LEN); + /* Write hash and encrypted scramble to client */ - if (my_net_write(net,prepared_scramble,SCRAMBLE41_LENGTH+4) - || net_flush(net)) + if (my_net_write(net,prepared_scramble,SCRAMBLE41_LENGTH+4) + || net_flush(net)) { inc_host_errors(&thd->remote.sin_addr); return ER_HANDSHAKE_ERROR; - } - /* Reading packet back */ - if ((pkt_len=my_net_read(net)) == packet_error) + } + /* Reading packet back */ + if ((pkt_len=my_net_read(net)) == packet_error) { inc_host_errors(&thd->remote.sin_addr); return ER_HANDSHAKE_ERROR; } - /* We have to get very specific packet size */ - if (pkt_len!=SCRAMBLE41_LENGTH) + /* We have to get very specific packet size */ + if (pkt_len!=SCRAMBLE41_LENGTH) { inc_host_errors(&thd->remote.sin_addr); - return ER_HANDSHAKE_ERROR; + return ER_HANDSHAKE_ERROR; } - /* Final attempt to check the user based on reply */ - if (check_user(thd,COM_CONNECT, tmp_user, (char*)net->read_pos, + /* Final attempt to check the user based on reply */ + if (check_user(thd,COM_CONNECT, tmp_user, (char*)net->read_pos, tmp_db, 1, 1,prepared_scramble,1,using_password,&cur_priv_version, &cached_user)) return -1; @@ -796,7 +786,7 @@ pthread_handler_decl(handle_one_connection,arg) send_error(thd,net->last_errno,NullS); statistic_increment(aborted_threads,&LOCK_status); } - + end_thread: close_connection(net); end_thread(thd,1); @@ -854,7 +844,7 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg) while (fgets(buff, thd->net.max_packet, file)) { uint length=(uint) strlen(buff); - while (length && (my_isspace(system_charset_info, buff[length-1]) || + while (length && (my_isspace(system_charset_info, buff[length-1]) || buff[length-1] == ';')) length--; buff[length]=0; @@ -1043,7 +1033,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, char *user= (char*) packet; char *passwd= strend(user)+1; char *db= strend(passwd)+1; - + /* Save user and privileges */ uint save_master_access=thd->master_access; uint save_db_access= thd->db_access; @@ -1055,43 +1045,46 @@ bool dispatch_command(enum enum_server_command command, THD *thd, USER_CONN *save_uc= thd->user_connect; bool simple_connect; bool using_password; - + ulong pkt_len=0; /* Length of reply packet */ - + /* Small check for incomming packet */ if ((uint) ((uchar*) db - net->read_pos) > packet_length) goto restore_user_err; - + /* Now we shall basically perform authentication again */ - + /* We can get only old hash at this point */ - if (passwd[0] && strlen(passwd)!=SCRAMBLE_LENGTH) + if (passwd[0] && strlen(passwd)!=SCRAMBLE_LENGTH) goto restore_user_err; - - char prepared_scramble[SCRAMBLE41_LENGTH+4];/* Buffer for scramble,hash */ + + char prepared_scramble[SCRAMBLE41_LENGTH+4];/* Buffer for scramble,hash */ ACL_USER* cached_user; /* Cached user */ uint cur_priv_version; /* Cached grant version */ - + /* Simple connect only for old clients. New clients always use sec. auth*/ simple_connect=(!(thd->client_capabilities & CLIENT_SECURE_CONNECTION)); - + /* Store information if we used password. passwd will be dammaged */ using_password=test(passwd[0]); - - /* - Check user permissions. If password failure we'll get scramble back - Do not retry if we already have sent error (result>0) - */ + + if (simple_connect) /* Restore scramble for old clients */ + memcpy(thd->scramble,thd->old_scramble,9); + + /* + Check user permissions. If password failure we'll get scramble back + Do not retry if we already have sent error (result>0) + */ if (check_user(thd,COM_CHANGE_USER, user, passwd, db, 0, simple_connect, - prepared_scramble,0,using_password,&cur_priv_version,&cached_user)<0) + prepared_scramble,0,using_password,&cur_priv_version,&cached_user)<0) { /* If The client is old we just have to have auth failure */ if (simple_connect) goto restore_user; /* Error is already reported */ - + /* Store current used and database as they are erased with next packet */ - + char tmp_user[USERNAME_LENGTH+1]; char tmp_db[NAME_LEN+1]; @@ -1099,33 +1092,33 @@ bool dispatch_command(enum enum_server_command command, THD *thd, { strncpy(tmp_user,user,USERNAME_LENGTH+1); /* Extra safety if we have too long data */ - tmp_user[USERNAME_LENGTH]=0; - } + tmp_user[USERNAME_LENGTH]=0; + } else - tmp_user[0]=0; + tmp_user[0]=0; if (db) { strncpy(tmp_db,db,NAME_LEN+1); tmp_db[NAME_LEN]=0; - } - else + } + else tmp_db[0]=0; - + /* Write hash and encrypted scramble to client */ - if (my_net_write(net,prepared_scramble,SCRAMBLE41_LENGTH+4) - || net_flush(net)) - goto restore_user_err; - - /* Reading packet back */ - if ((pkt_len=my_net_read(net)) == packet_error) + if (my_net_write(net,prepared_scramble,SCRAMBLE41_LENGTH+4) + || net_flush(net)) goto restore_user_err; - - /* We have to get very specific packet size */ - if (pkt_len!=SCRAMBLE41_LENGTH) + + /* Reading packet back */ + if ((pkt_len=my_net_read(net)) == packet_error) + goto restore_user_err; + + /* We have to get very specific packet size */ + if (pkt_len!=SCRAMBLE41_LENGTH) goto restore_user; - - /* Final attempt to check the user based on reply */ - if (check_user(thd,COM_CONNECT, tmp_user, (char*)net->read_pos, + + /* Final attempt to check the user based on reply */ + if (check_user(thd,COM_CONNECT, tmp_user, (char*)net->read_pos, tmp_db, 0, 1,prepared_scramble,1,using_password,&cur_priv_version, &cached_user)) goto restore_user; @@ -1137,11 +1130,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, x_free((gptr) save_user); thd->password=using_password; break; - + /* Bad luck we shall restore old user */ restore_user_err: send_error(thd, ER_UNKNOWN_COM_ERROR); - + restore_user: x_free(thd->user); x_free(thd->db); @@ -1150,10 +1143,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->db=save_db; thd->db_length=save_db_length; thd->user=save_user; - thd->priv_user=save_priv_user; + thd->priv_user=save_priv_user; break; } - + case COM_EXECUTE: { mysql_stmt_execute(thd, packet); @@ -1444,7 +1437,7 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length) packet_length--; } char *pos=packet+packet_length; // Point at end null - while (packet_length > 0 && + while (packet_length > 0 && (pos[-1] == ';' || my_isspace(system_charset_info,pos[-1]))) { pos--; @@ -1496,7 +1489,7 @@ mysql_execute_command(THD *thd) if (thd->slave_thread) { - /* + /* Skip if we are in the slave thread, some table rules have been given and the table list says the query should not be replicated */ @@ -1515,7 +1508,7 @@ mysql_execute_command(THD *thd) } #endif } - + /* TODO: make derived tables processing 'inside' SELECT processing. TODO: solve problem with depended derived tables in subselects @@ -1532,13 +1525,13 @@ mysql_execute_command(THD *thd) (SELECT_LEX_UNIT *) cursor->derived, cursor))) - { + { if (res < 0 || thd->net.report_error) send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); DBUG_VOID_RETURN; } } - if ((&lex->select_lex != lex->all_selects_list && + if ((&lex->select_lex != lex->all_selects_list && lex->unit.create_total_list(thd, lex, &tables)) || (table_rules_on && tables && thd->slave_thread && !tables_ok(thd,tables))) @@ -1568,7 +1561,7 @@ mysql_execute_command(THD *thd) unit->offset_limit_cnt= (ha_rows) unit->global_parameters->offset_limit; unit->select_limit_cnt= (ha_rows) (unit->global_parameters->select_limit+ unit->global_parameters->offset_limit); - if (unit->select_limit_cnt < + if (unit->select_limit_cnt < (ha_rows) unit->global_parameters->select_limit) unit->select_limit_cnt= HA_POS_ERROR; // no limit if (unit->select_limit_cnt == HA_POS_ERROR) @@ -1714,7 +1707,7 @@ mysql_execute_command(THD *thd) res = show_binlog_info(thd); break; } - + case SQLCOM_LOAD_MASTER_DATA: // sync with master if (check_global_access(thd, SUPER_ACL)) goto error; @@ -1723,7 +1716,7 @@ mysql_execute_command(THD *thd) else res = load_master_data(thd); break; - + #ifdef HAVE_INNOBASE_DB case SQLCOM_SHOW_INNODB_STATUS: { @@ -1899,7 +1892,7 @@ mysql_execute_command(THD *thd) select_lex->db=tables->db; if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege) || check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv) || - check_merge_table_access(thd, tables->db, + check_merge_table_access(thd, tables->db, (TABLE_LIST *) lex->create_info.merge_list.first)) goto error; /* purecov: inspected */ @@ -1981,7 +1974,7 @@ mysql_execute_command(THD *thd) res = show_binlogs(thd); break; } -#endif +#endif case SQLCOM_SHOW_CREATE: #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ @@ -2611,7 +2604,7 @@ mysql_execute_command(THD *thd) if (user->password.str && (strcmp(thd->user,user->user.str) || user->host.str && - my_strcasecmp(system_charset_info, + my_strcasecmp(system_charset_info, user->host.str, thd->host_or_ip))) { if (check_access(thd, UPDATE_ACL, "mysql",0,1)) @@ -3012,7 +3005,7 @@ mysql_init_query(THD *thd) lex->select_lex.init_query(); lex->value_list.empty(); lex->param_list.empty(); - lex->unit.global_parameters= lex->unit.slave= lex->current_select= + lex->unit.global_parameters= lex->unit.slave= lex->current_select= lex->all_selects_list= &lex->select_lex; lex->select_lex.master= &lex->unit; lex->select_lex.prev= &lex->unit.slave; @@ -3020,7 +3013,7 @@ mysql_init_query(THD *thd) lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list); lex->olap=lex->describe=0; lex->derived_tables= false; - thd->check_loops_counter= thd->select_number= + thd->check_loops_counter= thd->select_number= lex->select_lex.select_number= 1; thd->free_list= 0; thd->total_warn_count=0; // Warnings for this query @@ -3037,7 +3030,7 @@ mysql_init_select(LEX *lex) SELECT_LEX *select_lex= lex->current_select->select_lex(); DBUG_ASSERT(select_lex->linkage != GLOBAL_OPTIONS_TYPE); select_lex->init_select(); - select_lex->master_unit()->select_limit= select_lex->select_limit= + select_lex->master_unit()->select_limit= select_lex->select_limit= lex->thd->variables.select_limit; lex->exchange= 0; lex->result= 0; @@ -3067,7 +3060,7 @@ mysql_new_select(LEX *lex, bool move_down) } else select_lex->include_neighbour(lex->current_select); - + select_lex->master_unit()->global_parameters= select_lex; DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE); select_lex->include_global((st_select_lex_node**)&lex->all_selects_list); @@ -3577,10 +3570,10 @@ TABLE_LIST *st_select_lex::add_table_to_list(Table_ident *table, if (!alias) /* Alias is case sensitive */ if (!(alias_str=thd->memdup(alias_str,table->table.length+1))) DBUG_RETURN(0); - + if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST)))) DBUG_RETURN(0); /* purecov: inspected */ - if (table->db.str) + if (table->db.str) { ptr->db= table->db.str; ptr->db_length= table->db.length; @@ -3596,7 +3589,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(Table_ident *table, ptr->db= empty_c_string; ptr->db_length= 0; } - + ptr->alias= alias_str; if (lower_case_table_names) { |