diff options
-rw-r--r-- | client/mysql.cc | 14 | ||||
-rw-r--r-- | include/config-win.h | 7 | ||||
-rw-r--r-- | include/mysql.h | 8 | ||||
-rw-r--r-- | libmysql/libmysql.c | 64 | ||||
-rw-r--r-- | libmysqld/libmysqld.c | 14 | ||||
-rw-r--r-- | myisam/rt_mbr.c | 69 | ||||
-rw-r--r-- | mysql-test/r/rpl_loaddata.result | 4 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 15 | ||||
-rw-r--r-- | sql/item_strfunc.h | 5 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/mysqld.cc | 4 | ||||
-rw-r--r-- | sql/sql_acl.cc | 57 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 46 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 6 | ||||
-rw-r--r-- | strings/ctype-utf8.c | 45 | ||||
-rw-r--r-- | strings/ctype-win1250ch.c | 52 | ||||
-rw-r--r-- | tests/grant.res | 36 |
18 files changed, 242 insertions, 207 deletions
diff --git a/client/mysql.cc b/client/mysql.cc index 58aee617107..567a905ac6e 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2387,14 +2387,12 @@ com_use(String *buffer __attribute__((unused)), char *line) items in the array to zero first. */ -enum quote_type { NO_QUOTE, SQUOTE, DQUOTE, BTICK }; - char *get_arg(char *line, my_bool get_next_arg) { char *ptr; my_bool quoted= 0, valid_arg= 0; uint count= 0; - enum quote_type qtype= NO_QUOTE; + char qtype= 0; ptr= line; if (get_next_arg) @@ -2415,10 +2413,9 @@ char *get_arg(char *line, my_bool get_next_arg) } while (my_isspace(system_charset_info, *ptr)) ptr++; - if ((*ptr == '\'' && (qtype= SQUOTE)) || - (*ptr == '\"' && (qtype= DQUOTE)) || - (*ptr == '`' && (qtype= BTICK))) + if (*ptr == '\'' || *ptr == '\"' || *ptr == '`') { + qtype= *ptr; quoted= 1; ptr++; } @@ -2435,10 +2432,7 @@ char *get_arg(char *line, my_bool get_next_arg) ptr= line; ptr+= count; } - else if ((!quoted && *ptr == ' ') || - (*ptr == '\'' && qtype == SQUOTE) || - (*ptr == '\"' && qtype == DQUOTE) || - (*ptr == '`' && qtype == BTICK)) + else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype)) { *ptr= 0; break; diff --git a/include/config-win.h b/include/config-win.h index 9c1c1ae4830..dce543cd2b0 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -152,7 +152,9 @@ typedef uint rf_SetTimer; #define access(A,B) _access(A,B) #endif -#if defined(__cplusplus) +#if !defined(__cplusplus) +#define inline __inline +#endif /* __cplusplus */ inline double rint(double nr) { @@ -175,9 +177,6 @@ inline double ulonglong2double(ulonglong value) } #define my_off_t2double(A) ulonglong2double(A) #endif /* _WIN64 */ -#else -#define inline __inline -#endif /* __cplusplus */ #if SIZEOF_OFF_T > 4 #define lseek(A,B,C) _lseeki64((A),(longlong) (B),(C)) diff --git a/include/mysql.h b/include/mysql.h index f25ccf79cf6..57ae0c3da40 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -117,7 +117,8 @@ typedef struct st_mysql_data { } MYSQL_DATA; struct st_mysql_options { - unsigned int connect_timeout,client_flag; + unsigned int connect_timeout; + unsigned long client_flag; unsigned int port; char *host,*user,*password,*unix_socket,*db; struct st_dynamic_array *init_commands; @@ -191,7 +192,8 @@ typedef struct st_mysql my_ulonglong extra_info; /* Used by mysqlshow */ unsigned long thread_id; /* Id for connection in server */ unsigned long packet_length; - unsigned int port,client_flag,server_capabilities; + unsigned int port; + unsigned long client_flag,server_capabilities; unsigned int protocol_version; unsigned int field_count; unsigned int server_status; @@ -314,7 +316,7 @@ MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host, const char *db, unsigned int port, const char *unix_socket, - unsigned int clientflag); + unsigned long clientflag); void STDCALL mysql_close(MYSQL *sock); int STDCALL mysql_select_db(MYSQL *mysql, const char *db); int STDCALL mysql_query(MYSQL *mysql, const char *q); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 37eed9ab1b2..a2bd668aca9 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1003,6 +1003,7 @@ static void mysql_read_default_options(struct st_mysql_options *options, break; case 3: /* compress */ options->compress=1; + options->client_flag|= CLIENT_COMPRESS; break; case 4: /* password */ if (opt_arg) @@ -1828,7 +1829,7 @@ mysql_connect(MYSQL *mysql,const char *host, MYSQL * STDCALL mysql_real_connect(MYSQL *mysql,const char *host, const char *user, const char *passwd, const char *db, - uint port, const char *unix_socket,uint client_flag) + uint port, const char *unix_socket,ulong client_flag) { char buff[NAME_LEN+USERNAME_LENGTH+100],charset_name_buff[16]; char *end,*host_info,*charset_name; @@ -1899,7 +1900,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, (!host || !strcmp(host,LOCAL_HOST))) { if ((create_shared_memory(mysql,net, mysql->options.connect_timeout)) == - INVALID_HANDLE_VALUE) + INVALID_HANDLE_VALUE) { DBUG_PRINT("error", ("host: '%s' socket: '%s' shared memory: %s have_tcpip: %d", @@ -2178,32 +2179,28 @@ Try also with PIPE or TCP/IP #endif /* HAVE_OPENSSL */ if (db) client_flag|=CLIENT_CONNECT_WITH_DB; -#ifdef HAVE_COMPRESS - if ((mysql->server_capabilities & CLIENT_COMPRESS) && - (mysql->options.compress || (client_flag & CLIENT_COMPRESS))) - client_flag|=CLIENT_COMPRESS; /* We will use compression */ - else + /* Remove options that server doesn't support */ + client_flag= ((client_flag & + ~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)) | + (client_flag & mysql->server_capabilities)); + +#ifndef HAVE_COMPRESS + client_flag&= ~CLIENT_COMPRESS; #endif - client_flag&= ~CLIENT_COMPRESS; -#ifdef HAVE_OPENSSL - if ((mysql->server_capabilities & CLIENT_SSL) && - (mysql->options.use_ssl || (client_flag & CLIENT_SSL))) + if (client_flag & CLIENT_PROTOCOL_41) { - DBUG_PRINT("info", ("Changing IO layer to SSL")); - client_flag |= CLIENT_SSL; + /* 4.1 server and 4.1 client has a 4 byte option flag */ + int4store(buff,client_flag); + int4store(buff+4,max_allowed_packet); + end= buff+8; } else { - if (client_flag & CLIENT_SSL) - { - DBUG_PRINT("info", ("Leaving IO layer intact because server doesn't support SSL")); - } - client_flag &= ~CLIENT_SSL; + int2store(buff,client_flag); + int3store(buff+2,max_allowed_packet); + end= buff+5; } -#endif /* HAVE_OPENSSL */ - - int2store(buff,client_flag); mysql->client_flag=client_flag; #ifdef HAVE_OPENSSL @@ -2214,7 +2211,7 @@ Try also with PIPE or TCP/IP if (client_flag & CLIENT_SSL) { struct st_mysql_options *options= &mysql->options; - if (my_net_write(net,buff,(uint) (2)) || net_flush(net)) + if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net)) { net->last_errno= CR_SERVER_LOST; strmov(net->last_error,ER(net->last_errno)); @@ -2233,8 +2230,8 @@ Try also with PIPE or TCP/IP goto error; } DBUG_PRINT("info", ("IO layer change in progress...")); - if(sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd), - mysql->net.vio, (long) (mysql->options.connect_timeout))) + if (sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd), + mysql->net.vio, (long) (mysql->options.connect_timeout))) { net->last_errno= CR_SSL_CONNECTION_ERROR; strmov(net->last_error,ER(net->last_errno)); @@ -2244,20 +2241,19 @@ Try also with PIPE or TCP/IP } #endif /* HAVE_OPENSSL */ - DBUG_PRINT("info",("Server version = '%s' capabilites: %ld status: %d client_flag: %d", + DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu", mysql->server_version,mysql->server_capabilities, mysql->server_status, client_flag)); /* This needs to be changed as it's not useful with big packets */ - int3store(buff+2,max_allowed_packet); if (user && user[0]) - strmake(buff+5,user,32); /* Max user name */ + strmake(end,user,32); /* Max user name */ else - read_user_name((char*) buff+5); + read_user_name((char*) end); /* We have to handle different version of handshake here */ #ifdef _CUSTOMCONFIG_ #include "_cust_libmysql.h"; #endif - DBUG_PRINT("info",("user: %s",buff+5)); + DBUG_PRINT("info",("user: %s",end)); /* 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 @@ -2267,25 +2263,26 @@ Try also with PIPE or TCP/IP if (passwd[0]) { /* Prepare false scramble */ - end=strend(buff+5)+1; + end=strend(end)+1; bfill(end, SCRAMBLE_LENGTH, 'x'); end+=SCRAMBLE_LENGTH; *end=0; } else /* For empty password*/ { - end=strend(buff+5)+1; + end=strend(end)+1; *end=0; /* Store zero length scramble */ } } else + { /* Real scramble is only sent to old servers. This can be blocked by calling mysql_options(MYSQL *, MYSQL_SECURE_CONNECT, (char*) &1); */ - end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd, + end=scramble(strend(end)+1, mysql->scramble_buff, passwd, (my_bool) (mysql->protocol_version == 9)); - + } /* Add database if needed */ if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB)) { @@ -3380,6 +3377,7 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg) break; case MYSQL_OPT_COMPRESS: mysql->options.compress= 1; /* Remember for connect */ + mysql->options.client_flag|= CLIENT_COMPRESS; break; case MYSQL_OPT_NAMED_PIPE: mysql->options.protocol=MYSQL_PROTOCOL_PIPE; /* Force named pipe */ diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index de8efd9d2f4..e8a2f4989a5 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -834,7 +834,7 @@ mysql_connect(MYSQL *mysql,const char *host, MYSQL * STDCALL mysql_real_connect(MYSQL *mysql,const char *host, const char *user, const char *passwd, const char *db, - uint port, const char *unix_socket,uint client_flag) + uint port, const char *unix_socket,ulong client_flag) { char buff[100],charset_name_buff[16],*end,*host_info, *charset_name; uint pkt_length; @@ -991,20 +991,20 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, client_flag&= ~CLIENT_COMPRESS; if (db) client_flag|=CLIENT_CONNECT_WITH_DB; - int2store(buff,client_flag); + int4store(buff,client_flag); mysql->client_flag=client_flag; max_allowed_packet=net->max_packet_size; - int3store(buff+2,max_allowed_packet); + int4store(buff+4,max_allowed_packet); if (user && user[0]) - strmake(buff+5,user,32); + strmake(buff+8,user,32); else - read_user_name((char*) buff+5); + read_user_name((char*) buff+8); #ifdef _CUSTOMCONFIG_ #include "_cust_libmysql.h"; #endif - DBUG_PRINT("info",("user: %s",buff+5)); - end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd, + DBUG_PRINT("info",("user: %s",buff+8)); + end=scramble(strend(buff+8)+1, mysql->scramble_buff, passwd, (my_bool) (mysql->protocol_version == 9)); if (db) diff --git a/myisam/rt_mbr.c b/myisam/rt_mbr.c index a6467500183..e9cf7a6176e 100644 --- a/myisam/rt_mbr.c +++ b/myisam/rt_mbr.c @@ -161,25 +161,25 @@ end: return 0; } -#define RT_VOL_KORR(type, korr_func, len) \ +#define RT_VOL_KORR(type, korr_func, len, cast) \ { \ type amin, amax; \ amin = korr_func(a); \ a += len; \ amax = korr_func(a); \ a += len; \ - res *= ((double)amax - (double)amin); \ + res *= (cast(amax) - cast(amin)); \ break; \ } -#define RT_VOL_GET(type, get_func, len) \ +#define RT_VOL_GET(type, get_func, len, cast) \ { \ type amin, amax; \ get_func(amin, a); \ a += len; \ get_func(amax, a); \ a += len; \ - res *= ((double)amax - (double)amin); \ + res *= (cast(amax) - cast(amin)); \ break; \ } @@ -213,27 +213,27 @@ double rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length) break; } case HA_KEYTYPE_SHORT_INT: - RT_VOL_KORR(int16, mi_sint2korr, 2); + RT_VOL_KORR(int16, mi_sint2korr, 2, (double)); case HA_KEYTYPE_USHORT_INT: - RT_VOL_KORR(uint16, mi_uint2korr, 2); + RT_VOL_KORR(uint16, mi_uint2korr, 2, (double)); case HA_KEYTYPE_INT24: - RT_VOL_KORR(int32, mi_sint3korr, 3); + RT_VOL_KORR(int32, mi_sint3korr, 3, (double)); case HA_KEYTYPE_UINT24: - RT_VOL_KORR(uint32, mi_uint3korr, 3); + RT_VOL_KORR(uint32, mi_uint3korr, 3, (double)); case HA_KEYTYPE_LONG_INT: - RT_VOL_KORR(int32, mi_sint4korr, 4); + RT_VOL_KORR(int32, mi_sint4korr, 4, (double)); case HA_KEYTYPE_ULONG_INT: - RT_VOL_KORR(uint32, mi_uint4korr, 4); + RT_VOL_KORR(uint32, mi_uint4korr, 4, (double)); #ifdef HAVE_LONG_LONG case HA_KEYTYPE_LONGLONG: - RT_VOL_KORR(longlong, mi_sint8korr, 8); + RT_VOL_KORR(longlong, mi_sint8korr, 8, (double)); case HA_KEYTYPE_ULONGLONG: - RT_VOL_KORR(ulonglong, mi_uint8korr, 8); + RT_VOL_KORR(ulonglong, mi_uint8korr, 8, ulonglong2double); #endif case HA_KEYTYPE_FLOAT: - RT_VOL_GET(float, mi_float4get, 4); + RT_VOL_GET(float, mi_float4get, 4, (double)); case HA_KEYTYPE_DOUBLE: - RT_VOL_GET(double, mi_float8get, 8); + RT_VOL_GET(double, mi_float8get, 8, (double)); case HA_KEYTYPE_END: key_length = 0; break; @@ -242,27 +242,27 @@ double rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length) return res; } -#define RT_D_MBR_KORR(type, korr_func, len) \ +#define RT_D_MBR_KORR(type, korr_func, len, cast) \ { \ type amin, amax; \ amin = korr_func(a); \ a += len; \ amax = korr_func(a); \ a += len; \ - *res++ = (double)amin; \ - *res++ = (double)amax; \ + *res++ = cast(amin); \ + *res++ = cast(amax); \ break; \ } -#define RT_D_MBR_GET(type, get_func, len) \ +#define RT_D_MBR_GET(type, get_func, len, cast) \ { \ type amin, amax; \ get_func(amin, a); \ a += len; \ get_func(amax, a); \ a += len; \ - *res++ = (double)amin; \ - *res++ = (double)amax; \ + *res++ = cast(amin); \ + *res++ = cast(amax); \ break; \ } @@ -296,27 +296,27 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res) break; } case HA_KEYTYPE_SHORT_INT: - RT_D_MBR_KORR(int16, mi_sint2korr, 2); + RT_D_MBR_KORR(int16, mi_sint2korr, 2, (double)); case HA_KEYTYPE_USHORT_INT: - RT_D_MBR_KORR(uint16, mi_uint2korr, 2); + RT_D_MBR_KORR(uint16, mi_uint2korr, 2, (double)); case HA_KEYTYPE_INT24: - RT_D_MBR_KORR(int32, mi_sint3korr, 3); + RT_D_MBR_KORR(int32, mi_sint3korr, 3, (double)); case HA_KEYTYPE_UINT24: - RT_D_MBR_KORR(uint32, mi_uint3korr, 3); + RT_D_MBR_KORR(uint32, mi_uint3korr, 3, (double)); case HA_KEYTYPE_LONG_INT: - RT_D_MBR_KORR(int32, mi_sint4korr, 4); + RT_D_MBR_KORR(int32, mi_sint4korr, 4, (double)); case HA_KEYTYPE_ULONG_INT: - RT_D_MBR_KORR(uint32, mi_uint4korr, 4); + RT_D_MBR_KORR(uint32, mi_uint4korr, 4, (double)); #ifdef HAVE_LONG_LONG case HA_KEYTYPE_LONGLONG: - RT_D_MBR_KORR(longlong, mi_sint8korr, 8); + RT_D_MBR_KORR(longlong, mi_sint8korr, 8, (double)); case HA_KEYTYPE_ULONGLONG: - RT_D_MBR_KORR(ulonglong, mi_uint8korr, 8); + RT_D_MBR_KORR(ulonglong, mi_uint8korr, 8, ulonglong2double); #endif case HA_KEYTYPE_FLOAT: - RT_D_MBR_GET(float, mi_float4get, 4); + RT_D_MBR_GET(float, mi_float4get, 4, (double)); case HA_KEYTYPE_DOUBLE: - RT_D_MBR_GET(double, mi_float8get, 8); + RT_D_MBR_GET(double, mi_float8get, 8, (double)); case HA_KEYTYPE_END: key_length = 0; break; @@ -362,12 +362,13 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res) } /* -Creates common minimal bounding rectungle -for two input rectagnles a and b -Result is written to c + Creates common minimal bounding rectungle + for two input rectagnles a and b + Result is written to c */ + int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c, - uint key_length) + uint key_length) { for ( ; (int) key_length > 0 ; keyseg += 2) diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result index 27f3d185f63..8735cae47d5 100644 --- a/mysql-test/r/rpl_loaddata.result +++ b/mysql-test/r/rpl_loaddata.result @@ -1,9 +1,9 @@ -slave stop; +stop slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -slave start; +start slave; create table t1(a int not null auto_increment, b int, primary key(a) ); load data infile '../../std_data/rpl_loaddata.dat' into table t1; select * from t1; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 2b9bdfe9a1e..748ef096dbe 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1274,8 +1274,13 @@ String *Item_func_trim::val_str(String *str) return &tmp_value; } +void Item_func_password::fix_length_and_dec() +{ + max_length= get_password_length(use_old_passwords); +} + /* - Password() function can have 2 args now. Second argument can be used + Password() function has 2 arguments. Second argument can be used to make results repeatable */ @@ -1292,9 +1297,9 @@ String *Item_func_password::val_str(String *str) { if (res->length() == 0) return &empty_string; - make_scrambled_password(tmp_value,res->c_ptr(),opt_old_passwords, + make_scrambled_password(tmp_value,res->c_ptr(),use_old_passwords, ¤t_thd->rand); - str->set(tmp_value,get_password_length(opt_old_passwords),res->charset()); + str->set(tmp_value,get_password_length(use_old_passwords),res->charset()); return str; } else @@ -1323,9 +1328,9 @@ String *Item_func_password::val_str(String *str) /* Use constants which allow nice random values even with small seed */ randominit(&rand_st,seed*111111+33333333L,seed*1111+55555555L); - make_scrambled_password(tmp_value,res->c_ptr(),opt_old_passwords, + make_scrambled_password(tmp_value,res->c_ptr(),use_old_passwords, &rand_st); - str->set(tmp_value,get_password_length(opt_old_passwords),res->charset()); + str->set(tmp_value,get_password_length(use_old_passwords),res->charset()); return str; } } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index c90ff6e2295..c56c59bcaef 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -21,9 +21,6 @@ #pragma interface /* gcc class implementation */ #endif -extern my_bool opt_old_passwords; /* Need this variable for some functions */ - - class Item_str_func :public Item_func { public: @@ -264,7 +261,7 @@ public: Item_func_password(Item *a) :Item_str_func(a) {} Item_func_password(Item *a, Item *b) :Item_str_func(a,b) {} String *val_str(String *); - void fix_length_and_dec() { max_length = get_password_length(opt_old_passwords); } + void fix_length_and_dec(); const char *func_name() const { return "password"; } }; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index fc34cce8882..7a354ef5ff1 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -718,6 +718,7 @@ extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types; extern my_bool opt_safe_show_db, opt_local_infile, lower_case_table_names; extern my_bool opt_slave_compressed_protocol, use_temp_pool; extern my_bool opt_enable_named_pipe; +extern my_bool opt_old_passwords, use_old_passwords; extern char *shared_memory_base_name; extern bool opt_enable_shared_memory; extern char f_fyllchar; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1ed33d5c9db..8a2dfe50d54 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -288,7 +288,7 @@ static my_bool opt_noacl=0, opt_bootstrap=0, opt_myisam_log=0; my_bool opt_safe_user_create = 0, opt_no_mix_types = 0; my_bool lower_case_table_names, opt_old_rpl_compat; my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0; -my_bool opt_log_slave_updates= 0, opt_old_passwords=0; +my_bool opt_log_slave_updates= 0, opt_old_passwords=0, use_old_passwords=0; volatile bool mqh_used = 0; FILE *bootstrap_file=0; @@ -3560,7 +3560,7 @@ struct my_option my_long_options[] = GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"old-passwords", OPT_OLD_PASSWORDS, "Use old password encryption method (needed for old clients)", + {"old-passwords", OPT_OLD_PASSWORDS, "Use old password encryption method (needed for 4.0 and older clients)", (gptr*) &opt_old_passwords, (gptr*) &opt_old_passwords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifndef TO_BE_DELETED {"safe-show-database", OPT_SAFE_SHOW_DB, diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 6148df13902..30477cf4e99 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -55,7 +55,7 @@ static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs; static MEM_ROOT mem, memex; static bool initialized=0; static bool allow_all_hosts=1; -static HASH acl_check_hosts, hash_tables; +static HASH acl_check_hosts, column_priv_hash; static DYNAMIC_ARRAY acl_wild_hosts; static hash_filo *acl_cache; static uint grant_version=0; @@ -104,7 +104,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) DBUG_RETURN(0); /* purecov: tested */ } - priv_version++; /* Priveleges updated */ + priv_version++; /* Privileges updated */ /* To be able to run this from boot, we allocate a temporary THD @@ -112,6 +112,8 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) if (!(thd=new THD)) DBUG_RETURN(1); /* purecov: inspected */ thd->store_globals(); + /* Use passwords according to command line option */ + use_old_passwords= opt_old_passwords; acl_cache->clear(1); // Clear locked hostname cache thd->db= my_strdup("mysql",MYF(0)); @@ -176,7 +178,14 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) protocol_version=9; /* purecov: tested */ } - DBUG_PRINT("info",("user table fields: %d",table->fields)); + DBUG_PRINT("info",("user table fields: %d, password length: %d", + table->fields, table->field[2]->field_length)); + if (table->field[2]->field_length < 45 && !use_old_passwords) + { + sql_print_error("mysql.user table is not updated to new password format; Disabling new password usage until mysql_fix_privilege_tables is run"); + use_old_passwords= 1; + } + allow_all_hosts=0; while (!(read_record_info.read_record(&read_record_info))) { @@ -192,7 +201,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) "Found old style password for user '%s'. Ignoring user. (You may want to restart mysqld using --old-protocol)", user.user ? user.user : ""); /* purecov: tested */ } - else /* non emptpy and not short passwords */ + else /* non empty and not short passwords */ { user.pversion=get_password_version(user.password); /* Only passwords of specific lengths depending on version are allowed */ @@ -358,6 +367,7 @@ void acl_reload(THD *thd) if (acl_init(thd, 0)) { // Error. Revert to old list + DBUG_PRINT("error",("Reverting to old privileges")); acl_free(); /* purecov: inspected */ acl_hosts=old_acl_hosts; acl_users=old_acl_users; @@ -1733,10 +1743,12 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip, GRANT_TABLE *grant_table,*found=0; len = (uint) (strmov(strmov(strmov(helping,user)+1,db)+1,tname)-helping)+ 1; - for (grant_table=(GRANT_TABLE*) hash_search(&hash_tables,(byte*) helping, + for (grant_table=(GRANT_TABLE*) hash_search(&column_priv_hash, + (byte*) helping, len) ; grant_table ; - grant_table= (GRANT_TABLE*) hash_next(&hash_tables,(byte*) helping,len)) + grant_table= (GRANT_TABLE*) hash_next(&column_priv_hash,(byte*) helping, + len)) { if (exact) { @@ -2033,7 +2045,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } else { - hash_delete(&hash_tables,(byte*) grant_table); + hash_delete(&column_priv_hash,(byte*) grant_table); } DBUG_RETURN(0); @@ -2179,7 +2191,7 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list, result= -1; /* purecov: deadcode */ continue; /* purecov: deadcode */ } - hash_insert(&hash_tables,(byte*) grant_table); + hash_insert(&column_priv_hash,(byte*) grant_table); } /* If revoke_grant, calculate the new column privilege for tables_priv */ @@ -2334,7 +2346,7 @@ void grant_free(void) { DBUG_ENTER("grant_free"); grant_option = FALSE; - hash_free(&hash_tables); + hash_free(&column_priv_hash); free_root(&memex,MYF(0)); DBUG_VOID_RETURN; } @@ -2352,7 +2364,7 @@ my_bool grant_init(THD *org_thd) DBUG_ENTER("grant_init"); grant_option = FALSE; - (void) hash_init(&hash_tables,my_charset_latin1, + (void) hash_init(&column_priv_hash,my_charset_latin1, 0,0,0, (hash_get_key) get_grant_table, (hash_free_key) free_grant_table,0); init_sql_alloc(&memex,1024,0); @@ -2387,6 +2399,7 @@ my_bool grant_init(THD *org_thd) if (t_table->file->index_first(t_table->record[0])) { t_table->file->index_end(); + return_val= 0; goto end_unlock; } grant_option= TRUE; @@ -2398,7 +2411,7 @@ my_bool grant_init(THD *org_thd) { GRANT_TABLE *mem_check; if (!(mem_check=new GRANT_TABLE(t_table,c_table)) || - mem_check->ok() && hash_insert(&hash_tables,(byte*) mem_check)) + mem_check->ok() && hash_insert(&column_priv_hash,(byte*) mem_check)) { /* This could only happen if we are out memory */ grant_option = FALSE; /* purecov: deadcode */ @@ -2427,11 +2440,12 @@ end: } -/* Reload grant array if possible */ +/* Reload grant array (table and column privileges) if possible */ void grant_reload(THD *thd) { - HASH old_hash_tables;bool old_grant_option; + HASH old_column_priv_hash; + bool old_grant_option; MEM_ROOT old_mem; DBUG_ENTER("grant_reload"); @@ -2439,20 +2453,21 @@ void grant_reload(THD *thd) rw_wrlock(&LOCK_grant); grant_version++; - old_hash_tables=hash_tables; + old_column_priv_hash= column_priv_hash; old_grant_option = grant_option; old_mem = memex; if (grant_init(thd)) { // Error. Revert to old hash + DBUG_PRINT("error",("Reverting to old privileges")); grant_free(); /* purecov: deadcode */ - hash_tables=old_hash_tables; /* purecov: deadcode */ + column_priv_hash= old_column_priv_hash; /* purecov: deadcode */ grant_option = old_grant_option; /* purecov: deadcode */ memex = old_mem; /* purecov: deadcode */ } else { - hash_free(&old_hash_tables); + hash_free(&old_column_priv_hash); free_root(&old_mem,MYF(0)); } rw_unlock(&LOCK_grant); @@ -2676,9 +2691,10 @@ bool check_grant_db(THD *thd,const char *db) len = (uint) (strmov(strmov(helping,thd->priv_user)+1,db)-helping)+ 1; rw_rdlock(&LOCK_grant); - for (uint idx=0 ; idx < hash_tables.records ; idx++) + for (uint idx=0 ; idx < column_priv_hash.records ; idx++) { - GRANT_TABLE *grant_table = (GRANT_TABLE*) hash_element(&hash_tables,idx); + GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&column_priv_hash, + idx); if (len < grant_table->key_length && !memcmp(grant_table->hash_key,helping,len) && (thd->host && !wild_case_compare(my_charset_latin1, @@ -3000,10 +3016,11 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) } /* Add column access */ - for (index=0 ; index < hash_tables.records ; index++) + for (index=0 ; index < column_priv_hash.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(&column_priv_hash, + index); if (!(user=grant_table->user)) user=""; diff --git a/sql/sql_class.h b/sql/sql_class.h index 227d541807a..e682bf5741a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -430,7 +430,7 @@ public: /* points to host if host is available, otherwise points to ip */ const char *host_or_ip; - uint client_capabilities; /* What the client supports */ + ulong client_capabilities; /* What the client supports */ /* Determines if which non-standard SQL behaviour should be enabled */ ulong max_client_packet_length; ulong master_access; /* Global privileges from mysql.user */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1e2ce9e9a86..8c76118a526 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -206,10 +206,11 @@ static int check_user(THD *thd,enum_server_command command, const char *user, } thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user, passwd, thd->scramble, &thd->priv_user, - protocol_version == 9 || - !(thd->client_capabilities & - CLIENT_LONG_PASSWORD),&ur,crypted_scramble, - cur_priv_version,hint_user); + (protocol_version == 9 || + !(thd->client_capabilities & + CLIENT_LONG_PASSWORD)), + &ur,crypted_scramble, + cur_priv_version,hint_user); DBUG_PRINT("info", ("Capabilities: %d packet_length: %ld Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'", @@ -493,11 +494,11 @@ check_connections(THD *thd) { uint connect_errors=0; NET *net= &thd->net; - /* Store the connection details */ + char *end; DBUG_PRINT("info", (("check_connections called by thread %d"), - thd->thread_id)); + thd->thread_id)); DBUG_PRINT("info",("New connection received on %s", - vio_description(net->vio))); + vio_description(net->vio))); if (!thd->host) // If TCP/IP connection { char ip[30]; @@ -542,8 +543,7 @@ check_connections(THD *thd) ulong pkt_len=0; { /* buff[] needs to big enough to hold the server_version variable */ - char buff[SERVER_VERSION_LENGTH + - SCRAMBLE_LENGTH+64],*end; + char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH+64]; int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB | CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION; @@ -587,6 +587,18 @@ check_connections(THD *thd) return(ER_OUT_OF_RESOURCES); thd->client_capabilities=uint2korr(net->read_pos); + if (thd->client_capabilities & CLIENT_PROTOCOL_41) + { + thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16; + thd->max_client_packet_length= uint4korr(net->read_pos+4); + end= (char*) net->read_pos+8; + } + else + { + thd->max_client_packet_length= uint3korr(net->read_pos+2); + end= (char*) net->read_pos+5; + } + if (thd->client_capabilities & CLIENT_IGNORE_SPACE) thd->variables.sql_mode|= MODE_IGNORE_SPACE; #ifdef HAVE_OPENSSL @@ -612,19 +624,15 @@ check_connections(THD *thd) return(ER_HANDSHAKE_ERROR); } } - else +#endif + + if (end >= (char*) net->read_pos+ pkt_len +2) { - DBUG_PRINT("info", ("Leaving IO layer intact")); - if (pkt_len < NORMAL_HANDSHAKE_SIZE) - { - inc_host_errors(&thd->remote.sin_addr); - return ER_HANDSHAKE_ERROR; - } + inc_host_errors(&thd->remote.sin_addr); + return(ER_HANDSHAKE_ERROR); } -#endif - thd->max_client_packet_length=uint3korr(net->read_pos+2); - char *user= (char*) net->read_pos+5; + char *user= end; char *passwd= strend(user)+1; char *db=0; if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f4ae45373f8..a424aefd45f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4108,7 +4108,8 @@ text_or_password: else { char *buff=(char*) YYTHD->alloc(HASH_PASSWORD_LENGTH+1); - make_scrambled_password(buff,$3.str,opt_old_passwords,¤t_thd->rand); + make_scrambled_password(buff,$3.str,use_old_passwords, + &YYTHD->rand); $$=buff; } } @@ -4410,7 +4411,8 @@ grant_user: char *buff=(char*) YYTHD->alloc(HASH_PASSWORD_LENGTH+1); if (buff) { - make_scrambled_password(buff,$4.str,opt_old_passwords,¤t_thd->rand); + make_scrambled_password(buff,$4.str,use_old_passwords, + &YYTHD->rand); $1->password.str=buff; $1->password.length=HASH_PASSWORD_LENGTH; } diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 435121c1056..a237b6f14a0 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -2460,9 +2460,9 @@ long my_strntol_ucs2(CHARSET_INFO *cs, register unsigned int cutlim; register ulong cutoff; register ulong res; - register const char *s=nptr; - register const char *e=nptr+l; - const char *save; + register const uchar *s= (const uchar*) nptr; + register const uchar *e= (const uchar*) nptr+l; + const uchar *save; *err= 0; do @@ -2490,7 +2490,7 @@ long my_strntol_ucs2(CHARSET_INFO *cs, bs: -#if 0 +#ifdef NOT_USED if (base <= 0 || base == 1 || base > 36) base = 10; #endif @@ -2575,9 +2575,9 @@ ulong my_strntoul_ucs2(CHARSET_INFO *cs, register unsigned int cutlim; register ulong cutoff; register ulong res; - register const char *s=nptr; - register const char *e=nptr+l; - const char *save; + register const uchar *s= (const uchar*) nptr; + register const uchar *e= (const uchar*) nptr+l; + const uchar *save; *err= 0; do @@ -2605,7 +2605,7 @@ ulong my_strntoul_ucs2(CHARSET_INFO *cs, bs: -#if 0 +#ifdef NOT_USED if (base <= 0 || base == 1 || base > 36) base = 10; #endif @@ -2616,7 +2616,8 @@ bs: cutoff = ((ulong)~0L) / (unsigned long int) base; cutlim = (uint) (((ulong)~0L) % (unsigned long int) base); - do { + do + { if ((cnv=cs->mb_wc(cs,&wc,s,e))>0) { s+=cnv; @@ -2684,9 +2685,9 @@ longlong my_strntoll_ucs2(CHARSET_INFO *cs, register ulonglong cutoff; register unsigned int cutlim; register ulonglong res; - register const char *s=nptr; - register const char *e=nptr+l; - const char *save; + register const uchar *s= (const uchar*) nptr; + register const uchar *e= (const uchar*) nptr+l; + const uchar *save; *err= 0; do @@ -2714,7 +2715,7 @@ longlong my_strntoll_ucs2(CHARSET_INFO *cs, bs: -#if 0 +#ifdef NOT_USED if (base <= 0 || base == 1 || base > 36) base = 10; #endif @@ -2801,9 +2802,9 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs, register ulonglong cutoff; register unsigned int cutlim; register ulonglong res; - register const char *s=nptr; - register const char *e=nptr+l; - const char *save; + register const uchar *s= (const uchar*) nptr; + register const uchar *e= (const uchar*) nptr+l; + const uchar *save; *err= 0; do @@ -2831,7 +2832,7 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs, bs: -#if 0 +#ifdef NOT_USED if (base <= 0 || base == 1 || base > 36) base = 10; #endif @@ -2905,8 +2906,8 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), char buf[256]; double res; register char *b=buf; - register const char *s=nptr; - register const char *end; + register const uchar *s= (const uchar*) nptr; + register const uchar *end; my_wc_t wc; int cnv; @@ -2914,7 +2915,7 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), /* Cut too long strings */ if (length >= sizeof(buf)) length= sizeof(buf)-1; - end=nptr+length; + end= s+length; while ((cnv=cs->mb_wc(cs,&wc,s,end)) > 0) { @@ -2976,7 +2977,7 @@ int my_l10tostr_ucs2(CHARSET_INFO *cs, for ( db=dst, de=dst+len ; (dst<de) && *p ; p++) { - int cnvres=cs->wc_mb(cs,(my_wc_t)p[0],dst,de); + int cnvres=cs->wc_mb(cs,(my_wc_t)p[0],(uchar*) dst, (uchar*) de); if (cnvres>0) dst+=cnvres; else @@ -3035,7 +3036,7 @@ cnv: for ( db=dst, de=dst+len ; (dst<de) && *p ; p++) { - int cnvres=cs->wc_mb(cs,(my_wc_t)p[0],dst,de); + int cnvres=cs->wc_mb(cs, (my_wc_t) p[0], (uchar*) dst, (uchar*) de); if (cnvres>0) dst+=cnvres; else diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 86ddb82e1a2..b6e78368dde 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -1,23 +1,33 @@ -/* - File strings/ctype-win1250ch.c for MySQL. +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - Copyright: (C) 2001 Jan Pazdziora. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - This software is released under the terms of GNU General - Public License. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - Development of this software was supported by Neocortex, s.r.o. +/* + Shared, independent copyright: (C) 2001 Jan Pazdziora. - Bug reports and suggestions are always welcome. + Development of this software was supported by Neocortex, s.r.o. + MySQL AB expresses its gratitude to Jan for for giving us this software. - This file implements the collating sequence for Windows-1250 - character set. It merely extends the binary sorting of US-ASCII - by adding characters with diacritical marks into proper places. - In addition, it sorts 'ch' between 'h' and 'i', and the sorting - is case sensitive, with uppercase being sorted first, in the - second pass. + Bug reports and suggestions are always welcome. - Bug reports and suggestions are always welcome. + This file implements the collating sequence for Windows-1250 + character set. It merely extends the binary sorting of US-ASCII + by adding characters with diacritical marks into proper places. + In addition, it sorts 'ch' between 'h' and 'i', and the sorting + is case sensitive, with uppercase being sorted first, in the + second pass. */ /* @@ -388,16 +398,16 @@ static uchar NEAR _sort_order_win1250ch2[] = { }; struct wordvalue { - const char * word; + const uchar * word; uchar pass1; uchar pass2; }; static struct wordvalue doubles[] = { - { "ch", 0xad, 0x03 }, - { "c", 0xa6, 0x02 }, - { "Ch", 0xad, 0x02 }, - { "CH", 0xad, 0x01 }, - { "C", 0xa6, 0x01 }, + { (uchar*) "ch", 0xad, 0x03 }, + { (uchar*) "c", 0xa6, 0x02 }, + { (uchar*) "Ch", 0xad, 0x02 }, + { (uchar*) "CH", 0xad, 0x01 }, + { (uchar*) "C", 0xa6, 0x01 }, }; #define NEXT_CMP_VALUE(src, p, pass, value, len) \ @@ -412,7 +422,7 @@ static struct wordvalue doubles[] = { int i; \ for (i = 0; i < (int) sizeof(doubles); i++) { \ const uchar * patt = doubles[i].word; \ - const uchar * q = (const char *) p; \ + const uchar * q = (const uchar *) p; \ while (*patt \ && !(IS_END(q, src, len)) \ && (*patt == *q)) { \ diff --git a/tests/grant.res b/tests/grant.res index 3359f970225..2a5e4db3e33 100644 --- a/tests/grant.res +++ b/tests/grant.res @@ -27,11 +27,11 @@ show grants for grant_user@localhost GRANT SELECT ON *.* TO 'grant_user'@'localhost' insert into mysql.user (host,user) values ('error','grant_user') -Error in execute: insert command denied to user: 'grant_user@localhost' for table 'user' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql' update mysql.user set host='error' WHERE user='grant_user' -Error in execute: update command denied to user: 'grant_user@localhost' for table 'user' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql' create table grant_test.test (a int,b int) -Error in execute: create command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' grant select on *.* to grant_user2@localhost Error in execute: Access denied for user: 'grant_user@localhost' (Using password: NO) revoke select on grant_test.test from grant_user@opt_host @@ -106,21 +106,21 @@ select count(*) from grant_test.test 2 select * from mysql.user where user = 'grant_user' -Error in execute: select command denied to user: 'grant_user@localhost' for table 'user' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql' insert into grant_test.test values (4,0) -Error in execute: insert command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' update grant_test.test set a=1 -Error in execute: update command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' delete from grant_test.test -Error in execute: delete command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' create table grant_test.test2 (a int) -Error in execute: create command denied to user: 'grant_user@localhost' for table 'test2' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' ALTER TABLE grant_test.test add c int -Error in execute: alter command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' CREATE INDEX dummy ON grant_test.test (a) -Error in execute: index command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' drop table grant_test.test -Error in execute: drop command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' grant ALL PRIVILEGES on grant_test.* to grant_user2@localhost Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' grant ALL PRIVILEGES on grant_test.* to grant_user@localhost WITH GRANT OPTION @@ -133,14 +133,14 @@ REVOKE ALL PRIVILEGES on grant_test.* from grant_user@localhost REVOKE ALL PRIVILEGES on grant_test.* from grant_user@localhost Connecting grant_user insert into grant_test.test values (6,0) -Error in execute: insert command denied to user: 'grant_user@localhost' for table 'test' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test' REVOKE GRANT OPTION on grant_test.* from grant_user@localhost Connecting grant_user Access denied for user: 'grant_user@localhost' to database 'grant_test' grant ALL PRIVILEGES on grant_test.* to grant_user@localhost Connecting grant_user select * from mysql.user where user = 'grant_user' -Error in execute: select command denied to user: 'grant_user@localhost' for table 'user' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql' insert into grant_test.test values (7,0) update grant_test.test set a=3 where a=2 delete from grant_test.test where a=3 @@ -152,7 +152,7 @@ show tables from grant_test test insert into mysql.user (host,user) values ('error','grant_user',0) -Error in execute: insert command denied to user: 'grant_user@localhost' for table 'user' +Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql' revoke ALL PRIVILEGES on grant_test.* from grant_user@localhost select * from mysql.user where user = 'grant_user' localhost grant_user N N N N N N N N N N N N N N N N N N N N N 0 0 0 @@ -171,7 +171,7 @@ Error in execute: select command denied to user: 'grant_user@localhost' for tabl show keys from test Error in execute: select command denied to user: 'grant_user@localhost' for table 'test' show columns from test2 -a int(11) 0 +a int(11) binary 0 show keys from test2 select * from test @@ -228,7 +228,7 @@ Error in execute: select command denied to user: 'grant_user@localhost' for tabl select count(*) from test,test2 Error in execute: select command denied to user: 'grant_user@localhost' for table 'test2' replace into test2 SELECT a from test -Error in execute: update command denied to user: 'grant_user@localhost' for table 'test2' +Error in execute: delete command denied to user: 'grant_user@localhost' for table 'test2' grant update on grant_test.test2 to grant_user@localhost replace into test2 SELECT a,a from test Error in execute: delete command denied to user: 'grant_user@localhost' for table 'test2' @@ -314,8 +314,8 @@ revoke GRANT OPTION on grant_test.test from grant_user@localhost Error in execute: There is no such grant defined for user 'grant_user' on host 'localhost' on table 'test' grant select(a) on grant_test.test to grant_user@localhost show full columns from test -a int(11) YES NULL select -b int(11) YES NULL +a int(11) binary YES NULL select +b int(11) binary YES NULL grant insert (b), update (b) on grant_test.test to grant_user@localhost select count(a) from test |