diff options
42 files changed, 264 insertions, 125 deletions
diff --git a/include/mysql_com.h b/include/mysql_com.h index 784a7782855..1f9d996c457 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -319,10 +319,9 @@ void create_random_string(char *to, uint length, struct rand_struct *rand_st); void hash_password(ulong *to, const char *password); void make_scrambled_password_323(char *to, const char *password); -char *scramble_323(char *to, const char *message, const char *password, - my_bool old_ver); +char *scramble_323(char *to, const char *message, const char *password); my_bool check_scramble_323(const char *, const char *message, - unsigned long *salt, my_bool old_ver); + unsigned long *salt); void get_salt_from_password_323(unsigned long *res, const char *password); void make_password_from_salt_323(char *to, const unsigned long *salt); diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 565c2812c50..341e0144ca3 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -286,4 +286,5 @@ #define ER_REVOKE_GRANTS 1267 #define ER_CANT_AGGREGATE_3COLLATIONS 1268 #define ER_CANT_AGGREGATE_NCOLLATIONS 1269 -#define ER_ERROR_MESSAGES 270 +#define ER_SERVER_IS_IN_SECURE_AUTH_MODE 1270 +#define ER_ERROR_MESSAGES 271 diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 8b83343df8f..1cf4880db24 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -626,8 +626,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, end+= SCRAMBLE_LENGTH; } else - end= scramble_323(end, mysql->scramble_323, passwd, - (my_bool) (mysql->protocol_version == 9)) + 1; + end= scramble_323(end, mysql->scramble_323, passwd); } else *end++= '\0'; // empty password @@ -651,8 +650,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, By sending this very specific reply server asks us to send scrambled password in old format. The reply contains scramble_323. */ - scramble_323(buff, mysql->scramble_323, passwd, - (my_bool) (mysql->protocol_version == 9)); + scramble_323(buff, mysql->scramble_323, passwd); if (my_net_write(net, buff, SCRAMBLE_LENGTH_323 + 1) || net_flush(net)) { net->last_errno= CR_SERVER_LOST; diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result index 9c848c3434f..c0608af0de2 100644 --- a/mysql-test/r/connect.result +++ b/mysql-test/r/connect.result @@ -30,6 +30,7 @@ show tables; Tables_in_test update mysql.user set password=old_password("gambling2") where user="test"; flush privileges; +set password=old_password('gambling3'); show tables; Tables_in_mysql columns_priv diff --git a/mysql-test/r/func_crypt.result b/mysql-test/r/func_crypt.result index 461ae1e7e09..bd4c6d41d39 100644 --- a/mysql-test/r/func_crypt.result +++ b/mysql-test/r/func_crypt.result @@ -1,15 +1,79 @@ select length(encrypt('foo', 'ff')) <> 0; length(encrypt('foo', 'ff')) <> 0 1 -select password("a",""), password("a",NULL), password("","a"), password(NULL,"a"); -password("a","") password("a",NULL) password("","a") password(NULL,"a") -*2517f7235d68d4ba2e5019c93420523101157a792c01 NULL NULL -select password("aaaaaaaaaaaaaaaa","a"), password("a","aaaaaaaaaaaaaaaa"); -password("aaaaaaaaaaaaaaaa","a") password("a","aaaaaaaaaaaaaaaa") -*2cd3b9a44e9a9994789a30f935c92f45a96c5472f381 *37c7c5c794ff144819f2531bf03c57772cd84e40db09 -select old_password('test'), length(password("1")), length(encrypt('test')), encrypt('test','aa'); -old_password('test') length(password("1")) length(encrypt('test')) encrypt('test','aa') -378b243e220ca493 45 13 aaqPiZY5xR5l. -select old_password(""), old_password(NULL), password(""), password(NULL); -old_password("") old_password(NULL) password("") password(NULL) - NULL NULL +select password('abc'); +password('abc') +*0d3ced9bec10a777aec23ccc353a8c08a633045e +select password(''); +password('') + +select old_password('abc'); +old_password('abc') +7cd2b5942be28759 +select old_password(''); +old_password('') + +select password('gabbagabbahey'); +password('gabbagabbahey') +*b0f99d2963660dd7e16b751ec9ee2f17b6a68fa6 +select old_password('idkfa'); +old_password('idkfa') +5c078dc54ca0fcca +select length(password('1')); +length(password('1')) +41 +select length(encrypt('test')); +length(encrypt('test')) +13 +select encrypt('test','aa'); +encrypt('test','aa') +aaqPiZY5xR5l. +select old_password(NULL); +old_password(NULL) +NULL +select password(NULL); +password(NULL) +NULL +set global old_passwords=on; +select password(''); +password('') + +select old_password(''); +old_password('') + +select password('idkfa'); +password('idkfa') +*b669c9dac3aa6f2254b03cdef8dfdd6b2d1054ba +select old_password('idkfa'); +old_password('idkfa') +5c078dc54ca0fcca +set old_passwords=on; +select password('idkfa'); +password('idkfa') +5c078dc54ca0fcca +select old_password('idkfa'); +old_password('idkfa') +5c078dc54ca0fcca +set global old_passwords=off; +select password('idkfa'); +password('idkfa') +5c078dc54ca0fcca +select old_password('idkfa'); +old_password('idkfa') +5c078dc54ca0fcca +set old_passwords=off; +select password('idkfa '); +password('idkfa ') +*2dc31d90647b4c1abc9231563d2236e96c9a2db2 +select password('idkfa'); +password('idkfa') +*b669c9dac3aa6f2254b03cdef8dfdd6b2d1054ba +select password(' idkfa'); +password(' idkfa') +*12b099e56bb7fe8d43c78fd834a9d1d11178d045 +select old_password('idkfa'); +old_password('idkfa') +5c078dc54ca0fcca +select old_password(' i d k f a '); +old_password(' i d k f a ') +5c078dc54ca0fcca diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test index e6ccc52f0d4..7585ff0f608 100644 --- a/mysql-test/t/connect.test +++ b/mysql-test/t/connect.test @@ -48,8 +48,9 @@ flush privileges; #connect (con1,localhost,test,gambling2,""); #show tables; connect (con1,localhost,test,gambling2,mysql); +set password=old_password('gambling3'); show tables; -connect (con1,localhost,test,gambling2,test); +connect (con1,localhost,test,gambling3,test); show tables; # Re enable this one day if error handling on connect will take place @@ -63,7 +64,9 @@ show tables; #connect (con1,localhost,test,zorro,); #--error 1045 + # remove user 'test' so that other tests which may use 'test' # do not depend on this test. + delete from mysql.user where user="test"; flush privileges; diff --git a/mysql-test/t/func_crypt.test b/mysql-test/t/func_crypt.test index c72356bda1a..c1c7090cab3 100644 --- a/mysql-test/t/func_crypt.test +++ b/mysql-test/t/func_crypt.test @@ -4,7 +4,33 @@ select length(encrypt('foo', 'ff')) <> 0; --replace_result $1$aa$4OSUA5cjdx0RUQ08opV27/ aaqPiZY5xR5l. # Test new and old password handling functions -select password("a",""), password("a",NULL), password("","a"), password(NULL,"a"); -select password("aaaaaaaaaaaaaaaa","a"), password("a","aaaaaaaaaaaaaaaa"); -select old_password('test'), length(password("1")), length(encrypt('test')), encrypt('test','aa'); -select old_password(""), old_password(NULL), password(""), password(NULL); +select password('abc'); +select password(''); +select old_password('abc'); +select old_password(''); +select password('gabbagabbahey'); +select old_password('idkfa'); +select length(password('1')); +select length(encrypt('test')); +select encrypt('test','aa'); +select old_password(NULL); +select password(NULL); +set global old_passwords=on; +select password(''); +select old_password(''); +select password('idkfa'); +select old_password('idkfa'); +set old_passwords=on; +select password('idkfa'); +select old_password('idkfa'); +set global old_passwords=off; +select password('idkfa'); +select old_password('idkfa'); + +# this test shows that new scrambles honor spaces in passwords: +set old_passwords=off; +select password('idkfa '); +select password('idkfa'); +select password(' idkfa'); +select old_password('idkfa'); +select old_password(' i d k f a '); diff --git a/sql-common/client.c b/sql-common/client.c index efb71021f8d..9a0b7eb3fe2 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1842,8 +1842,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, end+= SCRAMBLE_LENGTH; } else - end= scramble_323(end, mysql->scramble_323, passwd, - (my_bool) (mysql->protocol_version == 9)) + 1; + end= scramble_323(end, mysql->scramble_323, passwd) + 1; } else *end++= '\0'; /* empty password */ @@ -1880,8 +1879,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, By sending this very specific reply server asks us to send scrambled password in old format. The reply contains scramble_323. */ - scramble_323(buff, mysql->scramble_323, passwd, - (my_bool) (mysql->protocol_version == 9)); + scramble_323(buff, mysql->scramble_323, passwd); if (my_net_write(net, buff, SCRAMBLE_LENGTH_323 + 1) || net_flush(net)) { net->last_errno= CR_SERVER_LOST; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 3e0239cf76a..96e264fd8d2 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -277,7 +277,7 @@ public: /* Item_func_old_password -- PASSWORD() implementation used in MySQL 3.21 - 4.0 compatibility mode. This item is created in sql_yacc.yy when - 'use_old_passwords' session variable is set, and to handle OLD_PASSWORD() + 'old_passwords' session variable is set, and to handle OLD_PASSWORD() function. */ diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 13ff168e553..f8bf197249b 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -748,7 +748,7 @@ 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_readonly; extern my_bool opt_enable_named_pipe; -extern my_bool opt_old_passwords, use_old_passwords; +extern my_bool opt_secure_auth; extern char *shared_memory_base_name, *mysqld_unix_port; extern bool opt_enable_shared_memory; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2677973ff0e..c5f875bfcc8 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -250,9 +250,10 @@ my_bool opt_local_infile, opt_external_locking, opt_slave_compressed_protocol; 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, use_old_passwords=0; +my_bool opt_log_slave_updates= 0; my_bool opt_console= 0, opt_bdb, opt_innodb, opt_isam; my_bool opt_readonly, use_temp_pool, relay_log_purge; +my_bool opt_secure_auth= 0; volatile bool mqh_used = 0; uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options; @@ -3452,7 +3453,8 @@ enum options OPT_EXPIRE_LOGS_DAYS, OPT_DEFAULT_WEEK_FORMAT, OPT_GROUP_CONCAT_MAX_LEN, - OPT_DEFAULT_COLLATION + OPT_DEFAULT_COLLATION, + OPT_SECURE_AUTH }; @@ -3753,9 +3755,10 @@ Does nothing yet.", (gptr*) &opt_no_mix_types, (gptr*) &opt_no_mix_types, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"old-protocol", 'o', "Use the old (3.20) protocol client/server protocol.", - (gptr*) &protocol_version, (gptr*) &protocol_version, 0, GET_UINT, NO_ARG, - PROTOCOL_VERSION, 0, 0, 0, 0, 0}, + {"old-passwords", OPT_OLD_PASSWORDS, "Use old password encryption method (needed for 4.0 and older clients).", + (gptr*) &global_system_variables.old_passwords, + (gptr*) &max_system_variables.old_passwords, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, {"old-rpl-compat", OPT_OLD_RPL_COMPAT, "Use old LOAD DATA format in the binary log (don't save data in file).", (gptr*) &opt_old_rpl_compat, (gptr*) &opt_old_rpl_compat, 0, GET_BOOL, @@ -3824,8 +3827,6 @@ relay logs.", 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 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, "Deprecated option; One should use GRANT SHOW DATABASES instead...", @@ -3835,6 +3836,9 @@ relay logs.", "Don't allow new user creation by the user who has no write privileges to the mysql.user table.", (gptr*) &opt_safe_user_create, (gptr*) &opt_safe_user_create, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"secure-auth", OPT_SECURE_AUTH, "Disallow authentication for accounts that have old (pre-4.1) passwords.", + (gptr*) &opt_secure_auth, (gptr*) &opt_secure_auth, 0, GET_BOOL, NO_ARG, + my_bool(0), 0, 0, 0, 0, 0}, {"server-id", OPT_SERVER_ID, "Uniquely identifies the server instance in the community of replication partners.", (gptr*) &server_id, (gptr*) &server_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0, @@ -4604,7 +4608,8 @@ static void mysql_init_variables(void) opt_log= opt_update_log= opt_bin_log= opt_slow_log= 0; opt_disable_networking= opt_skip_show_db=0; opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname=0; - opt_bootstrap= opt_myisam_log= use_old_passwords= 0; + opt_secure_auth= 0; + opt_bootstrap= opt_myisam_log= 0; mqh_used= 0; segfaulted= kill_in_progress= 0; cleanup_done= 0; @@ -4704,6 +4709,7 @@ static void mysql_init_variables(void) max_system_variables.select_limit= (ulonglong) HA_POS_ERROR; global_system_variables.max_join_size= (ulonglong) HA_POS_ERROR; max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR; + global_system_variables.old_passwords= 0; /* Variables that depends on compile options */ #ifndef DBUG_OFF @@ -4825,9 +4831,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'L': strmake(language, argument, sizeof(language)-1); break; - case 'o': - protocol_version=PROTOCOL_VERSION-1; - break; #ifdef HAVE_REPLICATION case OPT_SLAVE_SKIP_ERRORS: init_slave_skip_errors(argument); diff --git a/sql/password.c b/sql/password.c index bfdb453af01..2e9139c12aa 100644 --- a/sql/password.c +++ b/sql/password.c @@ -89,24 +89,6 @@ void randominit(struct rand_struct *rand_st, ulong seed1, ulong seed2) /* - Old (MySQL 3.20) random generation structure initialization - XXX: is to be deleted very soon! - SYNOPSIS - old_randominit() - rand_st OUT Structure to initialize - seed1 IN First initialization parameter -*/ - -static void old_randominit(struct rand_struct *rand_st, ulong seed1) -{ /* For mysql 3.20.# */ - rand_st->max_value= 0x01FFFFFFL; - rand_st->max_value_dbl=(double) rand_st->max_value; - seed1%=rand_st->max_value; - rand_st->seed1=seed1 ; rand_st->seed2=seed1/2; -} - - -/* Generate random number. SYNOPSIS my_rnd() @@ -178,13 +160,11 @@ void make_scrambled_password_323(char *to, const char *password) message IN Message to scramble. Message must be exactly SRAMBLE_LENGTH_323 long and NULL terminated. password IN Password to use while scrambling - old_ver IN Force old version random number generator RETURN End of scrambled string */ -char *scramble_323(char *to, const char *message, const char *password, - my_bool old_ver) +char *scramble_323(char *to, const char *message, const char *password) { struct rand_struct rand_st; ulong hash_pass[2], hash_message[2]; @@ -194,21 +174,15 @@ char *scramble_323(char *to, const char *message, const char *password, char *to_start=to; hash_password(hash_pass,password); hash_password(hash_message, message); - if (old_ver) - old_randominit(&rand_st,hash_pass[0] ^ hash_message[0]); - else - randominit(&rand_st,hash_pass[0] ^ hash_message[0], - hash_pass[1] ^ hash_message[1]); + randominit(&rand_st,hash_pass[0] ^ hash_message[0], + hash_pass[1] ^ hash_message[1]); while (*message++) *to++= (char) (floor(my_rnd(&rand_st)*31)+64); - if (!old_ver) - { /* Make it harder to break */ - char extra=(char) (floor(my_rnd(&rand_st)*31)); - while (to_start != to) - *(to_start++)^=extra; - } + char extra=(char) (floor(my_rnd(&rand_st)*31)); + while (to_start != to) + *(to_start++)^=extra; } - *to=0; + *to= 0; return to; } @@ -223,7 +197,6 @@ char *scramble_323(char *to, const char *message, const char *password, be exactly SCRAMBLED_LENGTH_323 bytes long and NULL-terminated. hash_pass IN password which should be used for scrambling - old_ver IN force old (3.20) version random number generator RETURN VALUE 0 - password correct !0 - password invalid @@ -231,7 +204,7 @@ char *scramble_323(char *to, const char *message, const char *password, my_bool check_scramble_323(const char *scrambled, const char *message, - ulong *hash_pass, my_bool old_ver) + ulong *hash_pass) { struct rand_struct rand_st; ulong hash_message[2]; @@ -243,18 +216,12 @@ check_scramble_323(const char *scrambled, const char *message, return 1; /* Wrong password */ hash_password(hash_message,message); - if (old_ver) - old_randominit(&rand_st,hash_pass[0] ^ hash_message[0]); - else - randominit(&rand_st,hash_pass[0] ^ hash_message[0], - hash_pass[1] ^ hash_message[1]); + randominit(&rand_st,hash_pass[0] ^ hash_message[0], + hash_pass[1] ^ hash_message[1]); to=buff; for (pos=scrambled ; *pos ; pos++) *to++=(char) (floor(my_rnd(&rand_st)*31)+64); - if (old_ver) - extra=0; - else - extra=(char) (floor(my_rnd(&rand_st)*31)); + extra=(char) (floor(my_rnd(&rand_st)*31)); to=buff; while (*scrambled) { diff --git a/sql/set_var.cc b/sql/set_var.cc index a281fac530a..a4ecf24d09f 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -210,6 +210,7 @@ sys_var_thd_ulong sys_net_retry_count("net_retry_count", &SV::net_retry_count, fix_net_retry_count); sys_var_thd_bool sys_new_mode("new", &SV::new_mode); +sys_var_thd_bool sys_old_passwords("old_passwords", &SV::old_passwords); sys_var_thd_ulong sys_preload_buff_size("preload_buffer_size", &SV::preload_buff_size); sys_var_thd_ulong sys_read_buff_size("read_buffer_size", @@ -236,6 +237,7 @@ sys_var_thd_enum sys_query_cache_type("query_cache_type", &SV::query_cache_type, &query_cache_type_typelib); #endif /* HAVE_QUERY_CACHE */ +sys_var_bool_ptr sys_secure_auth("secure_auth", &opt_secure_auth); sys_var_long_ptr sys_server_id("server_id",&server_id); sys_var_bool_ptr sys_slave_compressed_protocol("slave_compressed_protocol", &opt_slave_compressed_protocol); @@ -425,6 +427,7 @@ sys_var *sys_variables[]= &sys_net_wait_timeout, &sys_net_write_timeout, &sys_new_mode, + &sys_old_passwords, &sys_preload_buff_size, &sys_pseudo_thread_id, &sys_query_cache_size, @@ -443,6 +446,7 @@ sys_var *sys_variables[]= #endif &sys_rpl_recovery_rank, &sys_safe_updates, + &sys_secure_auth, &sys_select_limit, &sys_server_id, #ifdef HAVE_REPLICATION @@ -600,6 +604,7 @@ struct show_var_st init_vars[]= { {sys_net_retry_count.name, (char*) &sys_net_retry_count, SHOW_SYS}, {sys_net_write_timeout.name,(char*) &sys_net_write_timeout, SHOW_SYS}, {sys_new_mode.name, (char*) &sys_new_mode, SHOW_SYS}, + {sys_old_passwords.name, (char*) &sys_old_passwords, SHOW_SYS}, {"open_files_limit", (char*) &open_files_limit, SHOW_LONG}, {"pid_file", (char*) pidfile_name, SHOW_CHAR}, {"log_error", (char*) log_error_file, SHOW_CHAR}, @@ -620,6 +625,7 @@ struct show_var_st init_vars[]= { SHOW_SYS}, {sys_query_cache_size.name, (char*) &sys_query_cache_size, SHOW_SYS}, {sys_query_cache_type.name, (char*) &sys_query_cache_type, SHOW_SYS}, + {"secure_auth", (char*) &sys_secure_auth, SHOW_SYS}, #endif /* HAVE_QUERY_CACHE */ #ifdef HAVE_SMEM {"shared_memory", (char*) &opt_enable_shared_memory, SHOW_MY_BOOL}, diff --git a/sql/set_var.h b/sql/set_var.h index 5a0fbd21809..0622e504499 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -652,3 +652,5 @@ ulong fix_sql_mode(ulong sql_mode); extern sys_var_str sys_charset_system; CHARSET_INFO *get_old_charset_by_name(const char *old_name); + +extern sys_var_thd_bool sys_old_passwords; diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 641b1384e9a..4f1836ef80a 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -275,3 +275,4 @@ v/* "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 574d26b7c1c..138c8c59a39 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -269,3 +269,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index c6c975cb141..f7a79dfa738 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -277,3 +277,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index f39c415fa55..c57527e2578 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -271,3 +271,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index de22d6fd111..e6ade1c7e3d 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -271,3 +271,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 6c1187cd0e4..7ffd834fbcf 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -266,3 +266,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 78d53034a71..2c6343eeeea 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -275,3 +275,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 347370f1ac8..228834f7937 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -266,3 +266,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 313275b3cb6..620234e2321 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -268,3 +268,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 8af7e3ba9f7..8091d3185ba 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -266,3 +266,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 417a03978fb..962505423b1 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -268,3 +268,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 22395d0fb6a..aa0439fcd32 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -266,3 +266,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index de6db62cdce..21dfad648b9 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -268,3 +268,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 28db8caa8bc..e1d7501bca4 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -268,3 +268,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index fdf856c7e56..eaa2395b675 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -270,3 +270,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 397784dc7dd..89aded8afce 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -266,3 +266,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 8f1cdb7b259..e76fd43e841 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -270,3 +270,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index ec41a6acb34..23d20c1b8fe 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -268,3 +268,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Сервер запущен в режиме --secure-auth (безопасной авторизации), но для пользователя '%s@%s' пароль сохранён в старом формате; необходимо обновить формат пароля" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 77d35be2fc9..e0ba1413f5e 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -262,3 +262,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 33cabdfc752..bc8949127fd 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -274,3 +274,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 35e26f35ff7..9a6dcd90a4d 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -267,3 +267,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 9cdcb20db35..3538ba3c47e 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -266,3 +266,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 5a614714de2..9bc07241856 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -271,3 +271,4 @@ "Can't revoke all privileges, grant for one or more of the requested users" "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", +"Server is running in --secure-auth mode, but '%s@%s' has a password in the old format; please change the password to the new format" diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f88799c2843..ee544335a99 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -87,16 +87,33 @@ set_user_salt(ACL_USER *acl_user, const char *password, uint password_len) get_salt_from_password(acl_user->salt, password); acl_user->salt_len= SCRAMBLE_LENGTH; } - else if (password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323 - || password_len == 8 && protocol_version == 9) + else if (password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323) { get_salt_from_password_323((ulong *) acl_user->salt, password); - acl_user->salt_len= password_len/2; + acl_user->salt_len= SCRAMBLE_LENGTH_323; } else acl_user->salt_len= 0; } +/* + This after_update function is used when user.password is less than + SCRAMBLE_LENGTH bytes. +*/ + +static void restrict_update_of_old_passwords_var(THD *thd, + enum_var_type var_type) +{ + if (var_type == OPT_GLOBAL) + { + pthread_mutex_lock(&LOCK_global_system_variables); + global_system_variables.old_passwords= 1; + pthread_mutex_unlock(&LOCK_global_system_variables); + } + else + thd->variables.old_passwords= 1; +} + /* Read grant privileges from the privilege tables in the 'mysql' database. @@ -139,8 +156,6 @@ 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)); @@ -197,24 +212,43 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0); VOID(my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100)); - if (table->field[2]->field_length == 8 && - protocol_version == PROTOCOL_VERSION) + if (table->field[2]->field_length < SCRAMBLED_PASSWORD_CHAR_LENGTH_323) { - sql_print_error("Old 'user' table. " - "(Check README or the Reference manual). " - "Continuing --old-protocol"); /* purecov: tested */ - protocol_version=9; /* purecov: tested */ + sql_print_error("Fatal error: mysql.user table is damaged or in " + "unsupported 3.20 format."); + goto end; } DBUG_PRINT("info",("user table fields: %d, password length: %d", table->fields, table->field[2]->field_length)); - if (table->field[2]->field_length < SCRAMBLED_PASSWORD_CHAR_LENGTH && - !use_old_passwords) + + pthread_mutex_lock(&LOCK_global_system_variables); + if (table->field[2]->field_length < SCRAMBLED_PASSWORD_CHAR_LENGTH) { - 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; + if (opt_secure_auth) + { + pthread_mutex_unlock(&LOCK_global_system_variables); + sql_print_error("Fatal error: mysql.user table is in old format, " + "but server started with --secure-auth option."); + goto end; + } + sys_old_passwords.after_update= restrict_update_of_old_passwords_var; + if (global_system_variables.old_passwords) + pthread_mutex_unlock(&LOCK_global_system_variables); + else + { + global_system_variables.old_passwords= 1; + pthread_mutex_unlock(&LOCK_global_system_variables); + sql_print_error("mysql.user table is not updated to new password format; " + "Disabling new password usage until " + "mysql_fix_privilege_tables is run"); + } + thd->variables.old_passwords= 1; + } + else + { + sys_old_passwords.after_update= 0; + pthread_mutex_unlock(&LOCK_global_system_variables); } allow_all_hosts=0; @@ -229,12 +263,6 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) if (user.salt_len == 0 && password_len != 0) { switch (password_len) { - case 8: /* 3.20: to be removed */ - sql_print_error("Found old style password for user '%s'. " - "Ignoring user. (You may want to restart mysqld " - "using --old-protocol) ", - user.user ? user.user : ""); - break; case 45: /* 4.1: to be removed */ sql_print_error("Found 4.1 style password for user '%s'. " "Ignoring user. " @@ -513,7 +541,6 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b) original random string, passwd_len IN length of passwd, must be one of 0, 8, SCRAMBLE_LENGTH_323, SCRAMBLE_LENGTH - old_version IN if old (3.20) protocol is used RETURN VALUE 0 success: thread data and mqh are updated 1 user not found or authentification failure @@ -521,9 +548,8 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b) -1 user found, has short (3.23) salt, but passwd is in new (4.1.1) format. */ -int -acl_getroot(THD *thd, USER_RESOURCES *mqh, - const char *passwd, uint passwd_len, bool old_version) +int acl_getroot(THD *thd, USER_RESOURCES *mqh, + const char *passwd, uint passwd_len) { DBUG_ENTER("acl_getroot"); @@ -557,7 +583,7 @@ acl_getroot(THD *thd, USER_RESOURCES *mqh, user_i->salt_len == SCRAMBLE_LENGTH && check_scramble(passwd, thd->scramble, user_i->salt) == 0 || check_scramble_323(passwd, thd->scramble_323, - (ulong *) user_i->salt, old_version) == 0) + (ulong *) user_i->salt) == 0) { acl_user= user_i; res= 0; diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 3370797820a..b4ee1a9b15f 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -135,8 +135,8 @@ void acl_reload(THD *thd); void acl_free(bool end=0); ulong acl_get(const char *host, const char *ip, const char *bin_ip, const char *user, const char *db); -int acl_getroot(THD *thd, USER_RESOURCES *mqh, - const char *passwd, uint passwd_len, bool old_ver); +int acl_getroot(THD *thd, USER_RESOURCES *mqh, const char *passwd, + uint passwd_len); bool acl_check_host(const char *host, const char *ip); bool check_change_password(THD *thd, const char *host, const char *user); bool change_password(THD *thd, const char *host, const char *user, diff --git a/sql/sql_class.h b/sql/sql_class.h index d962cc8086e..5e46f44634b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -386,6 +386,7 @@ struct system_variables my_bool log_warnings; my_bool low_priority_updates; my_bool new_mode; + my_bool old_passwords; CHARSET_INFO *character_set_server; CHARSET_INFO *character_set_database; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a6d3121158c..4b7486c7b4f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -204,7 +204,22 @@ static int check_user(THD *thd, enum enum_server_command command, bool check_count) { DBUG_ENTER("check_user"); - + + my_bool opt_secure_auth_local; + pthread_mutex_lock(&LOCK_global_system_variables); + opt_secure_auth_local= opt_secure_auth; + pthread_mutex_unlock(&LOCK_global_system_variables); + + /* + If the server is running in secure auth mode, short scrambles are + forbidden. + */ + if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323) + { + net_printf(thd, ER_NOT_SUPPORTED_AUTH_MODE); + mysql_log.write(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); + DBUG_RETURN(-1); + } if (passwd_len != 0 && passwd_len != SCRAMBLE_LENGTH && passwd_len != SCRAMBLE_LENGTH_323) @@ -220,9 +235,7 @@ static int check_user(THD *thd, enum enum_server_command command, char buff[NAME_LEN + 1]; /* to conditionally save db */ USER_RESOURCES ur; - int res= acl_getroot(thd, &ur, passwd, passwd_len, - protocol_version == 9 || - !(thd->client_capabilities & CLIENT_LONG_PASSWORD)); + int res= acl_getroot(thd, &ur, passwd, passwd_len); if (res == -1) { /* @@ -231,6 +244,14 @@ static int check_user(THD *thd, enum enum_server_command command, scramble_323()). Here we please client to send scrambled_password in old format. */ + if (opt_secure_auth_local) + { + net_printf(thd, ER_SERVER_IS_IN_SECURE_AUTH_MODE, + thd->user, thd->host_or_ip); + mysql_log.write(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE), + thd->user, thd->host_or_ip); + DBUG_RETURN(-1); + } /* save db because network buffer is to hold new packet */ if (db) { @@ -247,8 +268,7 @@ static int check_user(THD *thd, enum enum_server_command command, } /* Final attempt to check the user based on reply */ /* So as passwd is short, errcode is always >= 0 */ - res= acl_getroot(thd, &ur, (char *) net->read_pos, SCRAMBLE_LENGTH_323, - false); + res= acl_getroot(thd, &ur, (char *) net->read_pos, SCRAMBLE_LENGTH_323); } /* here res is always >= 0 */ if (res == 0) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ddf4b71e891..e283991b496 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2517,7 +2517,8 @@ simple_expr: { $$= new Item_func_now($3); Lex->safe_to_cache_query=0;} | PASSWORD '(' expr ')' { - $$= use_old_passwords ? (Item *) new Item_func_old_password($3) : + $$= YYTHD->variables.old_passwords ? + (Item *) new Item_func_old_password($3) : (Item *) new Item_func_password($3); } | OLD_PASSWORD '(' expr ')' @@ -4607,7 +4608,7 @@ text_or_password: TEXT_STRING { $$=$1.str;} | PASSWORD '(' TEXT_STRING ')' { - $$= $3.length ? use_old_passwords ? + $$= $3.length ? YYTHD->variables.old_passwords ? Item_func_old_password::alloc(YYTHD, $3.str) : Item_func_password::alloc(YYTHD, $3.str) : $3.str; @@ -4923,7 +4924,7 @@ grant_user: $$=$1; $1->password=$4; if ($4.length) { - if (use_old_passwords) + if (YYTHD->variables.old_passwords) { char *buff= (char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1); |