List:Commits« Previous MessageNext Message »
From:Kristofer Pettersson Date:June 8 2012 1:20pm
Subject:bzr push into mysql-trunk branch (kristofer.pettersson:3974 to 3975)
View as plain text  
 3975 Kristofer Pettersson	2012-06-08 [merge]
      WL5602 Providing password hashing with appropriate strength
      
      Features:
      * New authentication plugin 'sha256_password' which requires
        either SSL or RSA key exchange.
      * The plugin uses a new password store which uses a salted
        SHA-256 based hash digest.
      * Introduction of default authentication plugin server side option.
      
      Misc:
      * Some refactoring of legacy code related to passwords and 
       the user table.

    added:
      include/crypt_genhash_impl.h
      include/mysql/client_authentication.h
      mysql-test/r/plugin_auth_sha256_server_default_tls.result
      mysql-test/r/plugin_auth_sha256_tls.result
      mysql-test/std_data/rsa_private_key.pem
      mysql-test/std_data/rsa_public_key.pem
      mysql-test/suite/sha256_auth/
      mysql-test/suite/sha256_auth/inc/
      mysql-test/suite/sha256_auth/r/
      mysql-test/suite/sha256_auth/r/plugin_auth_sha256.result
      mysql-test/suite/sha256_auth/r/plugin_auth_sha256_2.result
      mysql-test/suite/sha256_auth/r/plugin_auth_sha256_server_default.result
      mysql-test/suite/sha256_auth/r/plugin_auth_sha256_tls.result
      mysql-test/suite/sha256_auth/t/
      mysql-test/suite/sha256_auth/t/plugin_auth_sha256-master.opt
      mysql-test/suite/sha256_auth/t/plugin_auth_sha256.test
      mysql-test/suite/sha256_auth/t/plugin_auth_sha256_2-master.opt
      mysql-test/suite/sha256_auth/t/plugin_auth_sha256_2.test
      mysql-test/suite/sha256_auth/t/plugin_auth_sha256_server_default-master.opt
      mysql-test/suite/sha256_auth/t/plugin_auth_sha256_server_default.test
      mysql-test/suite/sha256_auth/t/plugin_auth_sha256_tls.test
      mysql-test/suite/sys_vars/r/sha256_password_private_key_path_basic.result
      mysql-test/suite/sys_vars/r/sha256_password_public_key_path_basic.result
      mysql-test/suite/sys_vars/t/sha256_password_private_key_path_basic.test
      mysql-test/suite/sys_vars/t/sha256_password_public_key_path_basic.test
      mysql-test/t/plugin_auth_sha256_server_default_tls-master.opt
      mysql-test/t/plugin_auth_sha256_server_default_tls.test
      mysql-test/t/plugin_auth_sha256_tls.test
      sql-common/client_authentication.cc
      sql-common/crypt_genhash_impl.cc
    modified:
      client/client_priv.h
      client/mysql.cc
      client/mysqltest.cc
      include/mysql.h
      include/mysql.h.pp
      include/mysql_com.h
      include/password.h
      include/sql_common.h
      libmysql/CMakeLists.txt
      libmysql/client_settings.h
      mysql-test/include/mysqld--help.inc
      mysql-test/r/change_user.result
      mysql-test/r/connect.result
      mysql-test/r/ctype_ucs.result
      mysql-test/r/func_crypt.result
      mysql-test/r/grant.result
      mysql-test/r/mysql_upgrade.result
      mysql-test/r/mysqld--help-notwin.result
      mysql-test/r/mysqld--help-win.result
      mysql-test/r/openssl_1.result
      mysql-test/r/plugin_auth.result
      mysql-test/r/plugin_auth_qa.result
      mysql-test/r/plugin_auth_qa_1.result
      mysql-test/r/plugin_auth_qa_2.result
      mysql-test/suite/funcs_1/r/is_user_privileges.result
      mysql-test/suite/rpl/r/rpl_master_connection.result
      mysql-test/suite/sys_vars/r/old_passwords_basic.result
      mysql-test/suite/sys_vars/r/old_passwords_func.result
      mysql-test/suite/sys_vars/r/secure_auth_func.result
      mysql-test/suite/sys_vars/t/old_passwords_basic.test
      mysql-test/suite/sys_vars/t/old_passwords_func.test
      mysql-test/suite/sys_vars/t/secure_auth_func.test
      mysql-test/t/change_user.test
      mysql-test/t/connect.test
      mysql-test/t/ctype_ucs.test
      mysql-test/t/disabled.def
      mysql-test/t/func_crypt.test
      mysql-test/t/mysql_upgrade.test
      mysql-test/t/openssl_1.test
      mysql-test/t/plugin_auth.test
      mysql-test/t/plugin_auth_qa.test
      sql-common/client.c
      sql/CMakeLists.txt
      sql/client_settings.h
      sql/item_strfunc.cc
      sql/item_strfunc.h
      sql/mysqld.cc
      sql/mysqld.h
      sql/password.c
      sql/set_var.cc
      sql/share/errmsg-utf8.txt
      sql/sql_acl.cc
      sql/sql_acl.h
      sql/sql_class.h
      sql/sql_parse.cc
      sql/sql_rewrite.cc
      sql/sql_yacc.yy
      sql/structs.h
      sql/sys_vars.cc
 3974 Hemant Kumar	2012-06-08
      Added "mysql-test/collections/mysql-trunk.release" combination file here,which will be used by mysql-trunk-release branch.

    added:
      mysql-test/collections/mysql-trunk.release
=== modified file 'client/client_priv.h'
--- a/client/client_priv.h	2012-05-31 15:33:21 +0000
+++ b/client/client_priv.h	2012-06-04 15:35:18 +0000
@@ -96,7 +96,8 @@ enum options_client
   OPT_MYSQLBINLOG_INCLUDE_GTIDS,
   OPT_MYSQLBINLOG_EXCLUDE_GTIDS,
   OPT_REMOTE_PROTO,
-  OPT_CONFIG_ALL
+  OPT_CONFIG_ALL,
+  OPT_SERVER_PUBLIC_KEY
 };
 
 /**

=== modified file 'client/mysql.cc'
--- a/client/mysql.cc	2012-05-31 15:33:21 +0000
+++ b/client/mysql.cc	2012-06-04 15:35:18 +0000
@@ -173,6 +173,7 @@ static STATUS status;
 static ulong select_limit,max_join_size,opt_connect_timeout=0;
 static char mysql_charsets_dir[FN_REFLEN+1];
 static char *opt_plugin_dir= 0, *opt_default_auth= 0;
+static char *opt_server_public_key= 0;
 static const char *xmlmeta[] = {
   "&", "&",
   "<", "&lt;",
@@ -1708,6 +1709,10 @@ static struct my_option my_long_options[
    "piped to mysql or loaded using the 'source' command). This is necessary "
    "when processing output from mysqlbinlog that may contain blobs.",
    &opt_binary_mode, &opt_binary_mode, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+  {"server-public-key", OPT_SERVER_PUBLIC_KEY,
+   "File path to the server public RSA key in PEM format.",
+   &opt_server_public_key, &opt_server_public_key, 0,
+   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 
@@ -4512,6 +4517,9 @@ sql_real_connect(char *host,char *databa
   if (opt_default_auth && *opt_default_auth)
     mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
 
+  if (opt_server_public_key && *opt_server_public_key)
+    mysql_options(&mysql, MYSQL_SERVER_PUBLIC_KEY, opt_server_public_key);
+
   mysql_options(&mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
   mysql_options4(&mysql, MYSQL_OPT_CONNECT_ATTR_ADD, 
                  "program_name", "mysql");

=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc	2012-05-31 15:33:21 +0000
+++ b/client/mysqltest.cc	2012-06-04 15:35:18 +0000
@@ -127,6 +127,7 @@ static my_bool is_windows= 0;
 static char **default_argv;
 static const char *load_default_groups[]= { "mysqltest", "client", 0 };
 static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer;
+static const char *opt_server_public_key= 0;
 
 /* Info on properties that can be set with --enable_X and --disable_X */
 
@@ -5602,6 +5603,11 @@ void do_connect(struct st_command *comma
   if (ds_default_auth.length)
     mysql_options(&con_slot->mysql, MYSQL_DEFAULT_AUTH, ds_default_auth.str);
 
+  /* Set server public_key */
+  if (opt_server_public_key && *opt_server_public_key)
+    mysql_options(&con_slot->mysql, MYSQL_SERVER_PUBLIC_KEY,
+                  opt_server_public_key);
+  
   /* Special database to allow one to connect without a database name */
   if (ds_database.length && !strcmp(ds_database.str,"*NO-ONE*"))
     dynstr_set(&ds_database, "");
@@ -6558,6 +6564,10 @@ static struct my_option my_long_options[
   {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
     &opt_plugin_dir, &opt_plugin_dir, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"server_public_key", OPT_SERVER_PUBLIC_KEY,
+   "File path to the server public RSA key in PEM format.",
+   &opt_server_public_key, &opt_server_public_key, 0,
+   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 

=== added file 'include/crypt_genhash_impl.h'
--- a/include/crypt_genhash_impl.h	1970-01-01 00:00:00 +0000
+++ b/include/crypt_genhash_impl.h	2012-04-20 00:14:27 +0000
@@ -0,0 +1,33 @@
+#ifndef CRYPT_HASHGEN_IMPL_H
+#define CRYPT_HASHGEN_IMPL_H
+#define	ROUNDS_DEFAULT	5000
+#define	ROUNDS_MIN	1000
+#define	ROUNDS_MAX	999999999
+#define	MIXCHARS	32
+#define CRYPT_SALT_LENGTH  20
+#define CRYPT_MAGIC_LENGTH  3
+#define CRYPT_PARAM_LENGTH 13
+#define SHA256_HASH_LENGTH 43
+#define CRYPT_MAX_PASSWORD_SIZE (CRYPT_SALT_LENGTH + \
+                                 SHA256_HASH_LENGTH + \
+                                 CRYPT_MAGIC_LENGTH + \
+                                 CRYPT_PARAM_LENGTH)
+
+#include <stddef.h>
+#include <my_global.h>
+
+int extract_user_salt(char **salt_begin,
+                      char **salt_end);
+C_MODE_START
+char *
+my_crypt_genhash(char *ctbuffer,
+                 size_t ctbufflen,
+                 const char *plaintext,
+                 int plaintext_len,
+                 const char *switchsalt,
+                 const char **params);
+void generate_user_salt(char *buffer, int buffer_len);
+void xor_string(char *to, int to_len, char *pattern, int pattern_len);
+
+C_MODE_END
+#endif

=== modified file 'include/mysql.h'
--- a/include/mysql.h	2012-03-30 16:01:10 +0000
+++ b/include/mysql.h	2012-06-04 15:35:18 +0000
@@ -172,7 +172,8 @@ enum mysql_option 
   MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CAPATH, MYSQL_OPT_SSL_CIPHER,
   MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH,
   MYSQL_OPT_CONNECT_ATTR_RESET, MYSQL_OPT_CONNECT_ATTR_ADD,
-  MYSQL_OPT_CONNECT_ATTR_DELETE
+  MYSQL_OPT_CONNECT_ATTR_DELETE,
+  MYSQL_SERVER_PUBLIC_KEY
 };
 
 /**

=== modified file 'include/mysql.h.pp'
--- a/include/mysql.h.pp	2012-03-30 16:01:10 +0000
+++ b/include/mysql.h.pp	2012-06-04 15:35:18 +0000
@@ -269,7 +269,8 @@ enum mysql_option
   MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CAPATH, MYSQL_OPT_SSL_CIPHER,
   MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH,
   MYSQL_OPT_CONNECT_ATTR_RESET, MYSQL_OPT_CONNECT_ATTR_ADD,
-  MYSQL_OPT_CONNECT_ATTR_DELETE
+  MYSQL_OPT_CONNECT_ATTR_DELETE,
+  MYSQL_SERVER_PUBLIC_KEY
 };
 struct st_mysql_options_extention;
 struct st_mysql_options {

=== added file 'include/mysql/client_authentication.h'
--- a/include/mysql/client_authentication.h	1970-01-01 00:00:00 +0000
+++ b/include/mysql/client_authentication.h	2012-03-23 15:42:27 +0000
@@ -0,0 +1,14 @@
+#ifndef CLIENT_AUTHENTICATION_H
+#define CLIENT_AUTHENTICATION_H
+#include <my_global.h>
+#include "mysql.h"
+#include "mysql/client_plugin.h"
+
+C_MODE_START
+int sha256_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
+int sha256_password_init(char *, size_t, int, va_list);
+int sha256_password_deinit(void);
+C_MODE_END
+
+#endif
+

=== modified file 'include/mysql_com.h'
--- a/include/mysql_com.h	2012-05-28 10:46:55 +0000
+++ b/include/mysql_com.h	2012-06-04 15:35:18 +0000
@@ -175,6 +175,9 @@ enum enum_server_command
 #define CLIENT_PLUGIN_AUTH  (1UL << 19) /* Client supports plugin authentication */
 #define CLIENT_CONNECT_ATTRS (1UL << 20) /* Client supports connection attributes */
 
+/* Enable authentication response packet to be larger than 255 bytes. */
+#define CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA (1UL << 20)
+
 #define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30)
 #define CLIENT_REMEMBER_OPTIONS (1UL << 31)
 
@@ -207,6 +210,7 @@ enum enum_server_command
                            CLIENT_SSL_VERIFY_SERVER_CERT | \
                            CLIENT_REMEMBER_OPTIONS | \
                            CLIENT_PLUGIN_AUTH | \
+                           CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA | \
                            CLIENT_CONNECT_ATTRS)
 
 /*

=== modified file 'include/password.h'
--- a/include/password.h	2011-06-30 15:46:53 +0000
+++ b/include/password.h	2011-11-25 19:27:44 +0000
@@ -18,12 +18,18 @@
 
 #include "my_global.h"
 
+struct rand_struct *get_sql_rand();
+                           
 C_MODE_START
 
 void my_make_scrambled_password_323(char *to, const char *password,
                                     size_t pass_len);
 void my_make_scrambled_password(char *to, const char *password,
                                 size_t pass_len);
+void my_make_scrambled_password_sha1(char *to, const char *password,
+                                     size_t pass_len);
+void my_make_scrambled_password_323(char *to, const char *password,
+                                    size_t pass_len);
 
 void hash_password(ulong *result, const char *password, uint password_len);
 

=== modified file 'include/sql_common.h'
--- a/include/sql_common.h	2012-03-30 16:01:10 +0000
+++ b/include/sql_common.h	2012-06-04 15:35:18 +0000
@@ -35,6 +35,7 @@ struct st_mysql_options_extention {
   char *ssl_crl;				/* PEM CRL file */
   char *ssl_crlpath;				/* PEM directory of CRL-s? */
   HASH connection_attributes;
+  char *server_public_key_path;
   size_t connection_attributes_length;
 };
 

=== modified file 'libmysql/CMakeLists.txt'
--- a/libmysql/CMakeLists.txt	2012-05-31 15:33:21 +0000
+++ b/libmysql/CMakeLists.txt	2012-06-04 15:35:18 +0000
@@ -144,6 +144,8 @@ SET(CLIENT_SOURCES
   ../sql-common/client.c 
   ../sql-common/my_time.c 
   ../sql-common/client_plugin.c 
+  ../sql-common/crypt_genhash_impl.cc
+  ../sql-common/client_authentication.cc
   ../sql/net_serv.cc
   ../sql-common/pack.c 
   ../sql/md5.cc

=== modified file 'libmysql/client_settings.h'
--- a/libmysql/client_settings.h	2012-03-30 16:01:10 +0000
+++ b/libmysql/client_settings.h	2012-06-04 15:35:18 +0000
@@ -35,6 +35,7 @@ extern char *	mysql_unix_port;
                              CLIENT_MULTI_RESULTS | \
                              CLIENT_PS_MULTI_RESULTS | \
                              CLIENT_PLUGIN_AUTH | \
+                             CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA | \
                              CLIENT_CONNECT_ATTRS)
 
 sig_handler my_pipe_sig_handler(int sig);

=== modified file 'mysql-test/include/mysqld--help.inc'
--- a/mysql-test/include/mysqld--help.inc	2011-11-15 13:30:43 +0000
+++ b/mysql-test/include/mysqld--help.inc	2012-04-26 12:56:00 +0000
@@ -22,7 +22,8 @@ perl;
 
   # Plugins which may or may not be there:
   @plugins=qw/innodb ndb ndbinfo archive blackhole federated partition ndbcluster debug temp-pool ssl des-key-file
-              thread-concurrency super-large-pages mutex-deadlock-detector null-audit/;
+              thread-concurrency super-large-pages mutex-deadlock-detector null-audit
+              sha256-password-private-key-path sha256-password-public-key-path/;
 
   # And substitute the content some environment variables with their
   # names:

=== modified file 'mysql-test/r/change_user.result'
--- a/mysql-test/r/change_user.result	2012-01-31 11:00:26 +0000
+++ b/mysql-test/r/change_user.result	2012-03-22 18:28:07 +0000
@@ -2,6 +2,7 @@ SET GLOBAL secure_auth = OFF;
 Warnings:
 Warning	1287	'pre-4.1 password hash' is deprecated and will be removed in a future release. Please use post-4.1 password hash instead
 grant select on test.* to test_nopw;
+create user test_oldpw identified with 'mysql_old_password';
 grant select on test.* to test_oldpw identified by password "09301740536db389";
 grant select on test.* to test_newpw identified by "newpw";
 select user(), current_user(), database();

=== modified file 'mysql-test/r/connect.result'
--- a/mysql-test/r/connect.result	2012-05-28 09:09:33 +0000
+++ b/mysql-test/r/connect.result	2012-06-04 15:35:18 +0000
@@ -82,11 +82,11 @@ ERROR 28000: Access denied for user 'tes
 SET GLOBAL secure_auth = OFF;
 Warnings:
 Warning	1287	'pre-4.1 password hash' is deprecated and will be removed in a future release. Please use post-4.1 password hash instead
-update mysql.user set password=old_password("gambling2") where user=_binary"test";
+update mysql.user set password=old_password("gambling2"), plugin="mysql_old_password" where user=_binary"test";
 flush privileges;
 set password="";
 set password='gambling3';
-ERROR HY000: Password hash should be a 41-digit hexadecimal number
+ERROR HY000: Password hash should be a 16-digit hexadecimal number
 set password=old_password('gambling3');
 Warnings:
 Warning	1287	'pre-4.1 password hash' is deprecated and will be removed in a future release. Please use post-4.1 password hash instead
@@ -250,9 +250,10 @@ SET GLOBAL event_scheduler = OFF;
 SELECT @@global.secure_auth;
 @@global.secure_auth
 1
-SET old_passwords=true;
+SET old_passwords=1;
 #Expect deprecation warning
-CREATE USER old_pwd@localhost IDENTIFIED BY 'aha';
+CREATE USER old_pwd@localhost IDENTIFIED WITH 'mysql_old_password';
+SET PASSWORD FOR old_pwd@localhost= OLD_PASSWORD('aha');
 Warnings:
 Warning	1287	'pre-4.1 password hash' is deprecated and will be removed in a future release. Please use post-4.1 password hash instead
 #Expect deprecation warning

=== modified file 'mysql-test/r/ctype_ucs.result'
--- a/mysql-test/r/ctype_ucs.result	2012-05-24 22:21:16 +0000
+++ b/mysql-test/r/ctype_ucs.result	2012-06-04 15:35:18 +0000
@@ -1046,14 +1046,6 @@ t2	CREATE TABLE `t2` (
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 ALTER TABLE t2 ADD a int NOT NULL AFTER status;
 DROP TABLE t1,t2;
-select password(name) from bug20536;
-password(name)
-*286C12C0F32248BD65B30EE65F3ECFB2AA3F7849
-*947A5674312754578F132655C74A11533B105FF6
-select old_password(name) from bug20536;
-old_password(name)
-10e155cb44e2adb5
-14e500b131773991
 select quote(name) from bug20536;
 quote(name)
 'test1'

=== modified file 'mysql-test/r/func_crypt.result'
--- a/mysql-test/r/func_crypt.result	2011-07-19 15:11:15 +0000
+++ b/mysql-test/r/func_crypt.result	2011-11-28 15:15:21 +0000
@@ -43,8 +43,8 @@ old_password(NULL)
 NULL
 select password(NULL);
 password(NULL)
-NULL
-set global old_passwords=on;
+
+set global old_passwords=1;
 select password('');
 password('')
 
@@ -57,21 +57,21 @@ password('idkfa')
 select old_password('idkfa');
 old_password('idkfa')
 5c078dc54ca0fcca
-set old_passwords=on;
+set old_passwords=1;
 select password('idkfa');
 password('idkfa')
 5c078dc54ca0fcca
 select old_password('idkfa');
 old_password('idkfa')
 5c078dc54ca0fcca
-set global old_passwords=off;
+set global old_passwords=0;
 select password('idkfa');
 password('idkfa')
 5c078dc54ca0fcca
 select old_password('idkfa');
 old_password('idkfa')
 5c078dc54ca0fcca
-set old_passwords=off;
+set old_passwords=0;
 select password('idkfa ');
 password('idkfa ')
 *2DC31D90647B4C1ABC9231563D2236E96C9A2DB2

=== modified file 'mysql-test/r/grant.result'
--- a/mysql-test/r/grant.result	2012-05-28 09:09:33 +0000
+++ b/mysql-test/r/grant.result	2012-06-04 15:35:18 +0000
@@ -53,8 +53,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 show grants for mysqltest_1@localhost;
 Grants for mysqltest_1@localhost
@@ -125,8 +125,8 @@ max_questions	10
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 show grants for mysqltest_1@localhost;
 Grants for mysqltest_1@localhost
@@ -173,8 +173,8 @@ max_questions	10
 max_updates	20
 max_connections	30
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 show grants for mysqltest_1@localhost;
 Grants for mysqltest_1@localhost

=== modified file 'mysql-test/r/mysql_upgrade.result'
--- a/mysql-test/r/mysql_upgrade.result	2012-01-30 15:43:32 +0000
+++ b/mysql-test/r/mysql_upgrade.result	2012-03-28 13:10:10 +0000
@@ -316,7 +316,7 @@ mysql.user                              
 # Bug# 13586336: issue deprecation warning
 #   for legacy authentication method
 #
-CREATE USER 'bug13586336'@'localhost';
+CREATE USER 'bug13586336'@'localhost' IDENTIFIED WITH 'mysql_old_password';
 SET PASSWORD FOR 'bug13586336'@'localhost' = OLD_PASSWORD('a');
 Warnings:
 Warning	1287	'pre-4.1 password hash' is deprecated and will be removed in a future release. Please use post-4.1 password hash instead

=== modified file 'mysql-test/r/mysqld--help-notwin.result'
--- a/mysql-test/r/mysqld--help-notwin.result	2012-06-01 08:45:46 +0000
+++ b/mysql-test/r/mysqld--help-notwin.result	2012-06-05 07:56:01 +0000
@@ -135,6 +135,9 @@ The following options may be given as th
  --date-format=name  The DATE format (ignored)
  --datetime-format=name 
  The DATETIME format (ignored)
+ --default-authentication-plugin=name 
+ Defines what password- and authentication algorithm to
+ use per default
  --default-storage-engine=name 
  The default storage engine for new tables
  --default-time-zone=name 
@@ -444,8 +447,8 @@ The following options may be given as th
  -n, --new           Use very new possible "unsafe" functions
  --old               Use compatible behavior
  --old-alter-table   Use old, non-optimized alter table
- --old-passwords     Use old password encryption method (needed for 4.0 and
- older clients)
+ --old-passwords=#   Determine which hash algorithm to use when generating
+ passwords using the PASSWORD() function
  --old-style-user-limits 
  Enable old-style user limits (before 5.0.3, user
  resources were counted per each user+host vs. per
@@ -1090,7 +1093,7 @@ net-write-timeout 60
 new FALSE
 old FALSE
 old-alter-table FALSE
-old-passwords FALSE
+old-passwords 0
 old-style-user-limits FALSE
 optimizer-prune-level 1
 optimizer-search-depth 62

=== modified file 'mysql-test/r/mysqld--help-win.result'
--- a/mysql-test/r/mysqld--help-win.result	2012-06-01 08:45:46 +0000
+++ b/mysql-test/r/mysqld--help-win.result	2012-06-05 07:56:01 +0000
@@ -135,6 +135,9 @@ The following options may be given as th
  --date-format=name  The DATE format (ignored)
  --datetime-format=name 
  The DATETIME format (ignored)
+ --default-authentication-plugin=name 
+ Defines what password- and authentication algorithm to
+ use per default
  --default-storage-engine=name 
  The default storage engine for new tables
  --default-time-zone=name 
@@ -444,8 +447,8 @@ The following options may be given as th
  -n, --new           Use very new possible "unsafe" functions
  --old               Use compatible behavior
  --old-alter-table   Use old, non-optimized alter table
- --old-passwords     Use old password encryption method (needed for 4.0 and
- older clients)
+ --old-passwords=#   Determine which hash algorithm to use when generating
+ passwords using the PASSWORD() function
  --old-style-user-limits 
  Enable old-style user limits (before 5.0.3, user
  resources were counted per each user+host vs. per
@@ -1098,7 +1101,7 @@ net-write-timeout 60
 new FALSE
 old FALSE
 old-alter-table FALSE
-old-passwords FALSE
+old-passwords 0
 old-style-user-limits FALSE
 optimizer-prune-level 1
 optimizer-search-depth 62

=== modified file 'mysql-test/r/openssl_1.result'
--- a/mysql-test/r/openssl_1.result	2011-09-07 10:08:09 +0000
+++ b/mysql-test/r/openssl_1.result	2012-04-26 11:49:14 +0000
@@ -44,9 +44,9 @@ ERROR 42000: DELETE command denied to us
 drop user ssl_user1@localhost, ssl_user2@localhost,
 ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost;
 drop table t1;
-mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation
-mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation
-mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation
+mysqltest: Could not open connection 'default': 2026 SSL connection error: xxxx
+mysqltest: Could not open connection 'default': 2026 SSL connection error: xxxx
+mysqltest: Could not open connection 'default': 2026 SSL connection error: xxxx
 SSL error: Unable to get private key from ''
 mysqltest: Could not open connection 'default': 2026 SSL connection error: Unable to get private key
 SSL error: Unable to get certificate from ''

=== modified file 'mysql-test/r/plugin_auth.result'
--- a/mysql-test/r/plugin_auth.result	2011-11-15 14:27:21 +0000
+++ b/mysql-test/r/plugin_auth.result	2012-03-22 18:28:07 +0000
@@ -40,6 +40,7 @@ select USER(),CURRENT_USER();
 USER()	CURRENT_USER()
 plug@localhost	plug_dest@%
 ## test SET PASSWORD
+Setting password is allowed but it won't affect the authentication mechanism.
 SET PASSWORD = PASSWORD('plug_dest');
 Warnings:
 Note	1699	SET PASSWORD has no significance for users authenticating via plugins
@@ -89,9 +90,9 @@ CREATE TABLE t1 (a INT);
 DROP TABLE t1;
 DROP USER new_grant_user;
 # try re-create existing user via GRANT IDENTIFIED WITH
+GRANTS which don't affect current plugin are allowed!
 GRANT ALL PRIVILEGES ON test_grant_db.* TO plug
 IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
-ERROR HY000: GRANT with IDENTIFIED WITH is illegal because the user plug already exists
 GRANT ALL PRIVILEGES ON test_grant_db.* TO plug_dest
 IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
 ERROR HY000: GRANT with IDENTIFIED WITH is illegal because the user plug_dest already exists

=== modified file 'mysql-test/r/plugin_auth_qa.result'
--- a/mysql-test/r/plugin_auth_qa.result	2011-03-18 14:16:17 +0000
+++ b/mysql-test/r/plugin_auth_qa.result	2011-11-25 19:27:44 +0000
@@ -105,7 +105,7 @@ CREATE USER plug_dest IDENTIFIED BY 'plu
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
 plug	test_plugin_server	plug_dest
-plug_dest		NULL
+plug_dest	mysql_native_password	
 DROP USER plug, plug_dest;
 CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
@@ -115,7 +115,7 @@ DROP USER plug;
 CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-plug_dest		NULL
+plug_dest	mysql_native_password	
 DROP USER plug_dest;
 GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
@@ -125,7 +125,7 @@ CREATE USER plug_dest IDENTIFIED BY 'plu
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
 plug	test_plugin_server	plug_dest
-plug_dest		NULL
+plug_dest	mysql_native_password	
 DROP USER plug, plug_dest;
 GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
@@ -135,7 +135,7 @@ DROP USER plug;
 CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-plug_dest		NULL
+plug_dest	mysql_native_password	
 DROP USER plug_dest;
 CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
@@ -145,7 +145,7 @@ GRANT ALL PRIVILEGES ON test_user_db.* T
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
 plug	test_plugin_server	plug_dest
-plug_dest		NULL
+plug_dest	mysql_native_password	
 DROP USER plug, plug_dest;
 CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
@@ -155,13 +155,13 @@ DROP USER plug;
 GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_dest_passwd';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-plug_dest		NULL
+plug_dest	mysql_native_password	
 DROP USER plug_dest;
 CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
+GRANTs which doesn't change the plugin are allowed
 GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
-ERROR HY000: GRANT with IDENTIFIED WITH is illegal because the user plug already exists
+GRANTs which doesn't change the plugin are allowed
 GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server';
-ERROR HY000: GRANT with IDENTIFIED WITH is illegal because the user plug already exists
 DROP USER plug;
 GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest';
 CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
@@ -176,7 +176,7 @@ plug	test_plugin_server	plug_dest	
 GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED BY 'plug_dest_passwd';
 SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string	password
-plug	test_plugin_server	plug_dest	*939AEE68989794C0F408277411C26055CDF41119
+plug	test_plugin_server	plug_dest	
 DROP USER plug;
 GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest';
 CREATE USER plug IDENTIFIED BY 'plug_dest_passwd';
@@ -210,7 +210,7 @@ DROP USER plüg;
 CREATE USER plüg_dest IDENTIFIED BY 'plug_dest_passwd';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-plüg_dest		NULL
+plüg_dest	mysql_native_password	
 DROP USER plüg_dest;
 SET NAMES ascii;
 CREATE USER 'plüg' IDENTIFIED WITH 'test_plugin_server' AS 'plüg_dest';
@@ -221,7 +221,7 @@ DROP USER 'plüg';
 CREATE USER 'plüg_dest' IDENTIFIED BY 'plug_dest_passwd';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-pl??g_dest		NULL
+pl??g_dest	mysql_native_password	
 DROP USER 'plüg_dest';
 SET NAMES latin1;
 ========== test 1.1.1.5 ====================================
@@ -235,7 +235,7 @@ DROP USER 'plug';
 CREATE USER 'plüg_dest' IDENTIFIED BY 'plug_dest_passwd';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-plüg_dest		NULL
+plüg_dest	mysql_native_password	
 DROP USER 'plüg_dest';
 SET NAMES utf8;
 CREATE USER plüg IDENTIFIED WITH 'test_plügin_server' AS 'plüg_dest';
@@ -248,7 +248,7 @@ DROP USER 'plüg';
 CREATE USER 'plüg_dest' IDENTIFIED BY 'plug_dest_passwd';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-plüg_dest		NULL
+plüg_dest	mysql_native_password	
 DROP USER 'plüg_dest';
 CREATE USER plüg IDENTIFIED WITH test_plugin_server AS 'plüg_dest';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
@@ -258,7 +258,7 @@ DROP USER plüg;
 CREATE USER plüg_dest IDENTIFIED BY 'plug_dest_passwd';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-plüg_dest		NULL
+plüg_dest	mysql_native_password	
 DROP USER pl=============
 SET @auth_name= 'test_plugin_server';
@@ -278,7 +278,7 @@ DROP USER plug;
 CREATE USER 'hh''s_plug_dest' IDENTIFIED BY 'plug_dest_passwd';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-hh's_plug_dest		NULL
+hh's_plug_dest	mysql_native_password	
 DROP USER 'hh''s_plug_dest';
 ========== test 1.1.1.4 ====================================
 CREATE USER plug IDENTIFIED WITH hh''s_test_plugin_server AS 'plug_dest';
@@ -294,7 +294,7 @@ GRANT ALL PRIVILEGES ON test_user_db.* T
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
 grant_user	test_plugin_server	plug_dest
-plug_dest		NULL
+plug_dest	mysql_native_password	
 DROP USER grant_user,plug_dest;
 set @save_sql_mode= @@sql_mode;
 SET @@sql_mode=no_auto_create_user;
@@ -315,13 +315,13 @@ CREATE USER plug_dest IDENTIFIED BY 'plu
 SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string	password
 grant_user	test_plugin_server	plug_dest	
-plug_dest		NULL	*939AEE68989794C0F408277411C26055CDF41119
+plug_dest	mysql_native_password		*939AEE68989794C0F408277411C26055CDF41119
 DROP USER plug_dest;
 GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_user_passwd';
 SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string	password
 grant_user	test_plugin_server	plug_dest	
-plug_dest		NULL	*560881EB651416CEF77314D07D55EDCD5FC1BD6D
+plug_dest	mysql_native_password		*560881EB651416CEF77314D07D55EDCD5FC1BD6D
 DROP USER grant_user,plug_dest;
 set @@sql_mode= @save_sql_mode;
 DROP DATABASE test_user_db;

=== modified file 'mysql-test/r/plugin_auth_qa_1.result'
--- a/mysql-test/r/plugin_auth_qa_1.result	2011-11-15 14:27:21 +0000
+++ b/mysql-test/r/plugin_auth_qa_1.result	2012-03-22 18:28:07 +0000
@@ -23,7 +23,7 @@ GRANT ALL PRIVILEGES ON test_user_db.* T
 GRANT PROXY ON plug_dest TO plug_user;
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-plug_dest		NULL
+plug_dest	mysql_native_password	
 plug_user	test_plugin_server	plug_dest
 1)
 Warning: Using a password on the command line interface can be insecure.
@@ -84,7 +84,7 @@ Warning: Using a password on the command
 ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES)
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-new_dest		NULL
+new_dest	mysql_native_password	
 plug_user	test_plugin_server	plug_dest
 DROP USER plug_user,new_dest;
 CREATE USER plug_user
@@ -106,7 +106,7 @@ Warning: Using a password on the command
 ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES)
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-new_dest		NULL
+new_dest	mysql_native_password	
 plug_user	test_plugin_server	plug_dest
 DROP USER plug_user,new_dest;
 CREATE USER plug_user
@@ -128,13 +128,13 @@ connection default;
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
 new_user	test_plugin_server	plug_dest
-plug_dest		NULL
+plug_dest	mysql_native_password	
 disconnect plug_user;
 UPDATE mysql.user SET user='plug_user' WHERE user='new_user';
 FLUSH PRIVILEGES;
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-plug_dest		NULL
+plug_dest	mysql_native_password	
 plug_user	test_plugin_server	plug_dest
 DROP USER plug_dest,plug_user;
 ========== test 1.3 ========================================
@@ -150,26 +150,26 @@ connection default;
 disconnect plug_user;
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-plug_dest		NULL
+plug_dest	mysql_native_password	
 plug_user	test_plugin_server	plug_dest
 UPDATE mysql.user SET user='new_user' WHERE user='plug_user';
 FLUSH PRIVILEGES;
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
 new_user	test_plugin_server	plug_dest
-plug_dest		NULL
+plug_dest	mysql_native_password	
 UPDATE mysql.user SET authentication_string='new_dest' WHERE user='new_user';
 FLUSH PRIVILEGES;
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
 new_user	test_plugin_server	new_dest
-plug_dest		NULL
+plug_dest	mysql_native_password	
 UPDATE mysql.user SET plugin='new_plugin_server' WHERE user='new_user';
 FLUSH PRIVILEGES;
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
 new_user	new_plugin_server	new_dest
-plug_dest		NULL
+plug_dest	mysql_native_password	
 connect(plug_user,localhost,new_user,new_dest);
 ERROR HY000: Plugin 'new_plugin_server' is not loaded
 UPDATE mysql.user SET plugin='test_plugin_server' WHERE user='new_user';
@@ -178,7 +178,7 @@ FLUSH PRIVILEGES;
 GRANT PROXY ON new_dest TO new_user;
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-new_dest		NULL
+new_dest	mysql_native_password	
 new_user	test_plugin_server	new_dest
 connect(plug_user,localhost,new_user,new_dest);
 select USER(),CURRENT_USER();
@@ -191,9 +191,9 @@ FLUSH PRIVILEGES;
 CREATE USER new_dest IDENTIFIED BY 'new_dest_passwd';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-new_dest		NULL
+new_dest	mysql_native_password	
 new_user	test_plugin_server	new_dest
-plug_dest		NULL
+plug_dest	mysql_native_password	
 GRANT ALL PRIVILEGES ON test.* TO new_user;
 connect(plug_user,localhost,new_dest,new_dest_passwd);
 select USER(),CURRENT_USER();
@@ -208,7 +208,7 @@ CREATE USER proxied_user IDENTIFIED BY '
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
 	test_plugin_server	proxied_user
-proxied_user		NULL
+proxied_user	mysql_native_password	
 connect(proxy_con,localhost,proxied_user,proxied_user_passwd);
 SELECT USER(),CURRENT_USER();
 USER()	CURRENT_USER()
@@ -245,7 +245,7 @@ CREATE USER proxied_user IDENTIFIED BY '
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
 	test_plugin_server	proxied_user
-proxied_user		NULL
+proxied_user	mysql_native_password	
 connect(proxy_con,localhost,proxied_user,proxied_user_passwd);
 SELECT USER(),CURRENT_USER();
 USER()	CURRENT_USER()
@@ -288,11 +288,11 @@ GRANT PROXY ON proxied_user_5 TO ''@'';
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
 	test_plugin_server	proxied_user
-proxied_user_1		NULL
-proxied_user_2		NULL
-proxied_user_3		NULL
-proxied_user_4		NULL
-proxied_user_5		NULL
+proxied_user_1	mysql_native_password	
+proxied_user_2	mysql_native_password	
+proxied_user_3	mysql_native_password	
+proxied_user_4	mysql_native_password	
+proxied_user_5	mysql_native_password	
 connect(proxy_con_1,localhost,proxied_user_1,'proxied_user_1_pwd');
 connect(proxy_con_2,localhost,proxied_user_2,proxied_user_2_pwd);
 connect(proxy_con_3,localhost,proxied_user_3,proxied_user_3_pwd);

=== modified file 'mysql-test/r/plugin_auth_qa_2.result'
--- a/mysql-test/r/plugin_auth_qa_2.result	2011-11-15 14:27:21 +0000
+++ b/mysql-test/r/plugin_auth_qa_2.result	2012-03-22 18:28:07 +0000
@@ -7,7 +7,7 @@ GRANT ALL PRIVILEGES ON test_user_db.* T
 GRANT PROXY ON qa_test_1_dest TO qa_test_1_user;
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-qa_test_1_dest		NULL
+qa_test_1_dest	mysql_native_password	
 qa_test_1_user	qa_auth_interface	qa_test_1_dest
 SELECT @@proxy_user;
 @@proxy_user
@@ -21,7 +21,7 @@ current_user()	user()	@@local.proxy_user
 qa_test_1_user@%	qa_test_1_user@localhost	NULL	NULL
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-qa_test_1_dest		NULL
+qa_test_1_dest	mysql_native_password	
 qa_test_1_user	qa_auth_interface	qa_test_1_dest
 DROP USER qa_test_1_user;
 DROP USER qa_test_1_dest;
@@ -34,8 +34,8 @@ GRANT PROXY ON qa_test_2_dest TO qa_test
 GRANT PROXY ON authenticated_as TO qa_test_2_user;
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-authenticated_as		NULL
-qa_test_2_dest		NULL
+authenticated_as	mysql_native_password	
+qa_test_2_dest	mysql_native_password	
 qa_test_2_user	qa_auth_interface	qa_test_2_dest
 SELECT @@proxy_user;
 @@proxy_user
@@ -49,8 +49,8 @@ current_user()	user()	@@local.proxy_user
 authenticated_as@%	user_name@localhost	'qa_test_2_user'@'%'	'qa_test_2_user'@'%'
 SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string
-authenticated_as		NULL
-qa_test_2_dest		NULL
+authenticated_as	mysql_native_password	
+qa_test_2_dest	mysql_native_password	
 qa_test_2_user	qa_auth_interface	qa_test_2_dest
 DROP USER qa_test_2_user;
 DROP USER qa_test_2_dest;
@@ -87,8 +87,8 @@ GRANT PROXY ON qa_test_5_dest TO qa_test
 GRANT PROXY ON qa_test_5_dest TO ''@'localhost';
 SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root';
 user	plugin	authentication_string	password
-		NULL	*DFCACE76914AD7BD801FC1A1ECF6562272621A22
-qa_test_5_dest		NULL	*DFCACE76914AD7BD801FC1A1ECF6562272621A22
+	mysql_native_password		*DFCACE76914AD7BD801FC1A1ECF6562272621A22
+qa_test_5_dest	mysql_native_password		*DFCACE76914AD7BD801FC1A1ECF6562272621A22
 qa_test_5_user	qa_auth_interface	qa_test_5_dest	
 exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_5_user  --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1
 Warning: Using a password on the command line interface can be insecure.
@@ -103,7 +103,7 @@ GRANT ALL PRIVILEGES ON test_user_db.* T
 GRANT PROXY ON qa_test_6_dest TO qa_test_6_user;
 SELECT user,plugin,authentication_string,password FROM mysql.user;
 user	plugin	authentication_string	password
-qa_test_6_dest		NULL	*DFCACE76914AD7BD801FC1A1ECF6562272621A22
+qa_test_6_dest	mysql_native_password		*DFCACE76914AD7BD801FC1A1ECF6562272621A22
 qa_test_6_user	qa_auth_interface	qa_test_6_dest	
 root			
 root			
@@ -115,7 +115,7 @@ ERROR 1045 (28000): Access denied for us
 GRANT PROXY ON qa_test_6_dest TO root IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest';
 SELECT user,plugin,authentication_string,password FROM mysql.user;
 user	plugin	authentication_string	password
-qa_test_6_dest		NULL	*DFCACE76914AD7BD801FC1A1ECF6562272621A22
+qa_test_6_dest	mysql_native_password		*DFCACE76914AD7BD801FC1A1ECF6562272621A22
 qa_test_6_user	qa_auth_interface	qa_test_6_dest	
 root			
 root			
@@ -128,7 +128,7 @@ ERROR 1045 (28000): Access denied for us
 REVOKE PROXY ON qa_test_6_dest FROM root;
 SELECT user,plugin,authentication_string FROM mysql.user;
 user	plugin	authentication_string
-qa_test_6_dest		NULL
+qa_test_6_dest	mysql_native_password	
 qa_test_6_user	qa_auth_interface	qa_test_6_dest
 root		
 root		

=== added file 'mysql-test/r/plugin_auth_sha256_server_default_tls.result'
--- a/mysql-test/r/plugin_auth_sha256_server_default_tls.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/plugin_auth_sha256_server_default_tls.result	2012-05-31 11:48:21 +0000
@@ -0,0 +1,63 @@
+CREATE USER 'kristofer';
+SET PASSWORD FOR 'kristofer'=PASSWORD('secret');
+SELECT user, plugin FROM mysql.user;
+user	plugin
+root	
+root	
+root	
+root	
+kristofer	sha256_password
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@%
+DROP USER 'kristofer';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+GRANT ALL ON *.* TO 'kristofer2'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('secret2');
+SET PASSWORD FOR 'kristofer2'@'localhost'=PASSWORD('secret2');
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@localhost
+SHOW GRANTS FOR 'kristofer'@'localhost';
+Grants for kristofer@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<non-deterministic-password-hash>'
+Change user (should succeed)
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer2@localhost	kristofer2@localhost
+**** Client default_auth=sha_256_password and server default auth=sha256_password
+#### Test is disabled because it requires RSA-keys and this only works 
+#### with OpenSSL. The reason is that the current client library
+#### framework can't know if SSL was attempted or not when the default
+#### client auth is switched and hence it will only report that the 
+#### connection is unencrypted.
+**** Client default_auth=native and server default auth=sha256_password
+user()	current_user()
+kristofer@localhost	kristofer@localhost
+DROP USER 'kristofer'@'localhost';
+DROP USER 'kristofer2'@'localhost';
+GRANT ALL ON *.* TO 'kristofer'@'localhost';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('');
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@localhost
+SHOW GRANTS FOR 'kristofer'@'localhost';
+Grants for kristofer@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<non-deterministic-password-hash>'
+DROP USER 'kristofer'@'localhost';
+GRANT ALL ON *.* TO 'kristofer'@'33.33.33.33';
+SET PASSWORD FOR 'kristofer'@'33.33.33.33'=PASSWORD('');
+Connection should fail for localhost
+ERROR 28000: Access denied for user 'kristofer'@'localhost' (using password: NO)
+DROP USER 'kristofer'@'33.33.33.33';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY 'awesomeness';
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@localhost
+SHOW GRANTS FOR 'kristofer'@'localhost';
+Grants for kristofer@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<non-deterministic-password-hash>'
+SET @@OLD_PASSWORDS= 0;
+SET PASSWORD FOR 'kristofer'@'localhost'= PASSWORD('error');
+ERROR HY000: The password hash doesn't have the expected format. Check if the correct password algorithm is being used with the PASSWORD() function.
+DROP USER 'kristofer'@'localhost';

=== added file 'mysql-test/r/plugin_auth_sha256_tls.result'
--- a/mysql-test/r/plugin_auth_sha256_tls.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/plugin_auth_sha256_tls.result	2012-05-31 11:48:21 +0000
@@ -0,0 +1,32 @@
+SHOW STATUS LIKE 'Ssl_cipher';
+Variable_name	Value
+Ssl_cipher	DHE-RSA-AES256-SHA
+CREATE USER 'kristofer' IDENTIFIED WITH 'sha256_password';
+SET GLOBAL old_passwords= 2;
+SET SESSION old_passwords= 2;
+SET PASSWORD FOR 'kristofer'=PASSWORD('secret');
+DROP USER 'kristofer';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('secret2');
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@localhost
+SHOW GRANTS FOR 'kristofer'@'localhost';
+Grants for kristofer@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<non-deterministic-password-hash>'
+DROP USER 'kristofer'@'localhost';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('');
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@localhost
+SHOW GRANTS FOR 'kristofer'@'localhost';
+Grants for kristofer@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<non-deterministic-password-hash>'
+DROP USER 'kristofer'@'localhost';
+GRANT ALL ON *.* TO 'kristofer'@'33.33.33.33' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'33.33.33.33'=PASSWORD('');
+Connection should fail for localhost
+ERROR 28000: Access denied for user 'kristofer'@'localhost' (using password: NO)
+DROP USER 'kristofer'@'33.33.33.33';
+SET GLOBAL old_passwords= default;

=== added file 'mysql-test/std_data/rsa_private_key.pem'
--- a/mysql-test/std_data/rsa_private_key.pem	1970-01-01 00:00:00 +0000
+++ b/mysql-test/std_data/rsa_private_key.pem	2011-11-29 09:47:34 +0000
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEAvV2VNbsQPG0Bh0KC8F4zCGXvMNcSicCiLXxeLWrJsmKZl0gg
+f2ydymYUUewq+dVxDdh85sdSvxEmtIWvKSRK+RRCAURztq2Succd+24SF5IZYjlI
+JE/U0AYUxHzUcOsannfzui60IaTHpcBFHTJK6myxGx9MORZmhfv580mfvz4yvgLj
+S5yGOIS6rlxD9YV1Y04Rx3SXQQBnC7rDBL91ktNWvbclsonfytY19N9p+Gprms30
+yRT+BmPFB7TqpReeZa3ivg15g/z3BLNyvj3YKiQM3cd7ENJC2x2LRxL5pG684cFN
+StSjT4FvA+oh45UnU45aOSEjrxNkBG8ci0e+VKX539rK+nDzTE/MHpnvfHp4DB+k
+SYBPuKHY2Eaw31NwPpfLWwEJPiDrktJJmRZqENMHLXksdiqGhvYmI33wZaZAfjbD
+ZFMfPF5yBMBGDZ3aeNz5Le7uqS6g6XMOoiz/d2S5RzRrCol1yqCBPtODjfFPC4K8
+GGYVkWZgSCf/PRt/DgDnZOfZSSYIQNeyr21emqgqQ+yhXEGKVjcDTKcbSLiWAdA+
+GkAzLAXXhafM8mrhpnGKdO4Or6ySz7G1vk2Jt2ZSdP740oVSJi59P9NEgXcbd3c4
+FzjXSOOsxfhPQfobUk3ikt55lN3fBX3mBvUduxNhAcQ02ZD5zXrX6+loiV8CAwEA
+AQKCAgAfFO45zIOEt4uprOQbGgscVMbm6FZVn/W+q4w1vjJvAjodl6wl3ikkII8z
+RyViroMI98DAjHTrgaAtv0eZ5CgeLBINbTPlByZvMdyc+Vsk3UknUymhNC1FG8pq
+2eZwxlYvLpcltya/4vEWJrHxceDUC5UiU4fKUv/u/AXxxeLfnBDuGUE/luh8/GQ7
+3E8XTJmQ/C5045E0DSHczgHWlKpyuBejuh0I6hJ+k5x1nfoh2S3iUe3c14I+gD/F
+3Q8qm+7W16zA7ytD29Cbx+yMh1Ak0pf+CxELGMf6eSX0O4wYTkjYcUcDglVv5lnX
+daWsWj4DO/lZKTRXN0KSa75uqg72Q1FjK//UNEigO99HYMsOWHBtaRzAwkklY5Da
+5WHn3sxmfotlFDiyT30R/T0dpAjvgH18A235KOpgLnM7Kaxc3kjMmorIJrkD25oG
+OmRRTvdZ5rQ+IuBzaGUOD4ZwTwQ9HMieMjjLCcmkhhzzIZni1eNMva7MJyws4qcH
+tjOPQvtb8m8ZXzT77nnkKirbJLVk+FqzL93/w1Kp/BRgVVChrXhdDFW2KSI8sx7Z
+T7J8Dir4Oz2JFgpuBLKTz2Bnu6EDNEdGmomP79DO2IGoPNwhhBRDNM2oYR2nPTME
+0f9moTJBghsi6rutgxkf1KDY6z2oysJKoJowegEYaUh0J0aHqQKCAQEA8hEL2y5C
+iq2fzLRulXEVLG4di6ZZ0ZcyuV6rwQRWrhqv//+csagNmvguz6mFF9iNciv8FT2Z
+crIgJUPefslKXuqqm/zEhhafDBXypMHsk4yReIdlxQDkmnamoGJZRd3CSsNFm68a
+52hkl3gniMprMp8wWyr2UNeahD9cgtooyua/hyaXewh57L9pJGHlLayvqEn6Rs0V
+0lpSzMTJWqFrDPuSc+ufsd3sk1MfvdnDw5oh7cHjZhlHJVtPSrjneCTbEnNpXIr/
+yGL+qamZD+a8a318KMz72y3RwA0VMkhhkAYFYV+S5qYrlbFxjacVOS0Zi0LOklrl
+jGMj6RzcD2W35QKCAQEAyEP27OgVTkaEr3bmNHYMBqYZ2snYMUgJF5GOitfLGSGM
+55Io++BO6NMDbcNyCtWu2RYbHfdF1qjlTxPHjqsy6z4+tpxjpnPQEbO5eN1PG3iZ
++YO6z1yXLMwglkK4Acv1YWkMZ6l2V55MyntdiCWG/UYOlVw1kxqxlhgzmyq1ZMj5
+4IOGqjsjPsMs2ZVANE54y/SriocnM/2Z08440SElOtheu5G/PfTF2j3ZZRBvuggu
+MVnl2+5c0PpT1DGS74327WhRWDixmgEPEgLTd9hSpCWN/5nj67zskHKv6pmOLS+I
+jd+rpzrnqDallDmTm/DqcLLDuaxsxEV/788pRllf8wKCAQEAoxcfENZTGNIv9yCd
+3OvqoxuxplQ28cJX95K0T4BX0kfCyszySrP6Lq4GA/2n4VASxJij57+v8hnXFKRs
+dKm0BM1Ak4Yy9lCpaeAjsiPB/AtaO4Wl6JxYaUWFsEty8GKfs/VqoaDRlJW+KFtY
+743JubqNPu9sMz2AKpfyAWtwznu3ERzMNKWaWAsCkPOwEBzn4I+vIyKsECSw4qu3
+KevVj1Kz8owO9SybZws7OJNOlSv0rhbS2ggv6hhiDOsVcNoMC5tconA4M0+XWsIc
+kR0ZV6adD3REQADX7/ggjtc7fGjCGT/mXqYYeWurIRAweWxMaIpjWTIKtJJbMIU0
+Mt+KjQKCAQAbtzw/QUdhk+TdG8l0TToQ2YAOhYzEFUIc3uopUQAstDX5/oJpiXui
+QUHiOQBZe4U9Sg/qr8QclzdVIFmn5w2e/PhU8YPhD3omWQc8MPS3ypMUsyRxelD5
+xC5mXUl2BjIpjw5Gcm+MZL4f777cDsWF2+I8zYwklbcqHKNXwCtmjWH3rnw+pvyT
+vRNB8aP3GT0ijPQIsfe8/EYDyDCY0MuEP1ms/9jFzFBtic3CbOnphyRNdDGZpH13
+9o0PeuTo/m7EIIHRgdcihy78wSNfHLMjQIdMbpHamETtINIz15iTrFZrvB7XgBF7
+eESmJOnG1Sq8+iCYW8KZzzyLhdIiiE/9AoIBAQDGZG7/r8feIMKUWGJmm+uWDAEi
+FRn0gZap3HZRDkmgYE6Xwr6CwUBp1YWvjQGQdln9BSrc6kXazOQrX+wpaNmW5x90
+EMinO3Ekg+c5ivYgw1IxN26bbOnlDUpeUDH2mp4OV9MhMmPB6EfRWbztflK7545j
+SJ0sOADajDCq5WeR3IyXT9Pq99wZ1BI4qw/MD7HUzx38n7G3qa/BOQcdyETN1L1l
+BZgRlbpzktD2AjX71p8FaVfeRA2R4/BWPAzBEhGdLgitXL1UVZDC/TzZBKwQcwpG
+JvKExITQBoOQmIOPbEYoLZ7UAiiOmCi/QlOjswP94gTKW4YHEqu6dqMHaaw+
+-----END RSA PRIVATE KEY-----

=== added file 'mysql-test/std_data/rsa_public_key.pem'
--- a/mysql-test/std_data/rsa_public_key.pem	1970-01-01 00:00:00 +0000
+++ b/mysql-test/std_data/rsa_public_key.pem	2011-11-29 09:47:34 +0000
@@ -0,0 +1,14 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvV2VNbsQPG0Bh0KC8F4z
+CGXvMNcSicCiLXxeLWrJsmKZl0ggf2ydymYUUewq+dVxDdh85sdSvxEmtIWvKSRK
++RRCAURztq2Succd+24SF5IZYjlIJE/U0AYUxHzUcOsannfzui60IaTHpcBFHTJK
+6myxGx9MORZmhfv580mfvz4yvgLjS5yGOIS6rlxD9YV1Y04Rx3SXQQBnC7rDBL91
+ktNWvbclsonfytY19N9p+Gprms30yRT+BmPFB7TqpReeZa3ivg15g/z3BLNyvj3Y
+KiQM3cd7ENJC2x2LRxL5pG684cFNStSjT4FvA+oh45UnU45aOSEjrxNkBG8ci0e+
+VKX539rK+nDzTE/MHpnvfHp4DB+kSYBPuKHY2Eaw31NwPpfLWwEJPiDrktJJmRZq
+ENMHLXksdiqGhvYmI33wZaZAfjbDZFMfPF5yBMBGDZ3aeNz5Le7uqS6g6XMOoiz/
+d2S5RzRrCol1yqCBPtODjfFPC4K8GGYVkWZgSCf/PRt/DgDnZOfZSSYIQNeyr21e
+mqgqQ+yhXEGKVjcDTKcbSLiWAdA+GkAzLAXXhafM8mrhpnGKdO4Or6ySz7G1vk2J
+t2ZSdP740oVSJi59P9NEgXcbd3c4FzjXSOOsxfhPQfobUk3ikt55lN3fBX3mBvUd
+uxNhAcQ02ZD5zXrX6+loiV8CAwEAAQ==
+-----END PUBLIC KEY-----

=== modified file 'mysql-test/suite/funcs_1/r/is_user_privileges.result'
--- a/mysql-test/suite/funcs_1/r/is_user_privileges.result	2012-05-28 09:09:33 +0000
+++ b/mysql-test/suite/funcs_1/r/is_user_privileges.result	2012-06-04 15:35:18 +0000
@@ -127,8 +127,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser2
@@ -170,8 +170,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser3
@@ -213,8 +213,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 #
 # Add GRANT OPTION db_datadict.* to testuser1;
@@ -280,8 +280,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser2
@@ -323,8 +323,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser3
@@ -366,8 +366,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 # Establish connection testuser1 (user=testuser1)
 SELECT * FROM information_schema.user_privileges
@@ -419,8 +419,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser2
@@ -462,8 +462,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser3
@@ -505,8 +505,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 SHOW GRANTS;
 Grants for testuser1@localhost
@@ -580,8 +580,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser2
@@ -623,8 +623,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser3
@@ -666,8 +666,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 GRANT SELECT ON *.* TO 'testuser1'@'localhost' WITH GRANT OPTION;
 #
@@ -733,8 +733,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser2
@@ -776,8 +776,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser3
@@ -819,8 +819,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 # Switch to connection testuser1
 SELECT * FROM information_schema.user_privileges
@@ -872,8 +872,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser2
@@ -915,8 +915,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser3
@@ -958,8 +958,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 SHOW GRANTS;
 Grants for testuser1@localhost
@@ -1063,8 +1063,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser2
@@ -1106,8 +1106,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser3
@@ -1149,8 +1149,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 # Switch to connection testuser1
 SELECT * FROM information_schema.user_privileges
@@ -1249,8 +1249,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser2
@@ -1292,8 +1292,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser3
@@ -1335,8 +1335,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 # Switch to connection testuser1
 SELECT * FROM information_schema.user_privileges
@@ -1388,8 +1388,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser2
@@ -1431,8 +1431,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser3
@@ -1474,8 +1474,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 SHOW GRANTS;
 Grants for testuser1@localhost
@@ -1534,8 +1534,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser2
@@ -1577,8 +1577,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser3
@@ -1620,8 +1620,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 SHOW GRANTS;
 Grants for testuser1@localhost
@@ -1695,8 +1695,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser2
@@ -1738,8 +1738,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 Host	localhost
 User	testuser3
@@ -1781,8 +1781,8 @@ max_questions	0
 max_updates	0
 max_connections	0
 max_user_connections	0
-plugin	
-authentication_string	NULL
+plugin	mysql_native_password
+authentication_string	
 password_expired	N
 # Switch to connection testuser1
 SELECT * FROM information_schema.user_privileges

=== modified file 'mysql-test/suite/rpl/r/rpl_master_connection.result'
--- a/mysql-test/suite/rpl/r/rpl_master_connection.result	2012-03-23 20:11:19 +0000
+++ b/mysql-test/suite/rpl/r/rpl_master_connection.result	2012-04-20 15:14:24 +0000
@@ -16,10 +16,10 @@ SELECT user, plugin, authentication_stri
 user	plugin	authentication_string	password
 plug_user_p	test_plugin_server	proxy_user_p	
 plug_user_wp	test_plugin_server	proxy_user_wp	
-proxy_user_p		NULL	*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19
-proxy_user_wp		NULL	
-regular_user_p		NULL	*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19
-regular_user_wp		NULL	
+proxy_user_p	mysql_native_password		*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19
+proxy_user_wp	mysql_native_password		
+regular_user_p	mysql_native_password		*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19
+regular_user_wp	mysql_native_password		
 GRANT PROXY ON proxy_user_p to plug_user_p;
 GRANT PROXY ON proxy_user_wp to plug_user_wp;
 GRANT REPLICATION SLAVE ON *.* TO proxy_user_p;

=== added directory 'mysql-test/suite/sha256_auth'
=== added directory 'mysql-test/suite/sha256_auth/inc'
=== added directory 'mysql-test/suite/sha256_auth/r'
=== added file 'mysql-test/suite/sha256_auth/r/plugin_auth_sha256.result'
--- a/mysql-test/suite/sha256_auth/r/plugin_auth_sha256.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sha256_auth/r/plugin_auth_sha256.result	2012-04-17 15:18:24 +0000
@@ -0,0 +1,103 @@
+CREATE USER 'kristofer' IDENTIFIED WITH 'sha256_password';
+SET GLOBAL old_passwords= 2;
+SET SESSION old_passwords= 2;
+SET PASSWORD FOR 'kristofer'=PASSWORD('secret');
+SELECT user, plugin FROM mysql.user;
+user	plugin
+root	
+root	
+root	
+root	
+kristofer	sha256_password
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@%
+DROP USER 'kristofer';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+GRANT ALL ON *.* TO 'kristofer2'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('secret2');
+SET PASSWORD FOR 'kristofer2'@'localhost'=PASSWORD('secret2');
+ERROR 28000: Access denied for user 'kristofer'@'localhost' (using password: YES)
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@localhost
+SHOW GRANTS FOR 'kristofer'@'localhost';
+Grants for kristofer@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<non-deterministic-password-hash>'
+Change user (should succeed)
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer2@localhost	kristofer2@localhost
+**** Client default_auth=sha_256_password and server default auth=native
+user()	current_user()
+kristofer@localhost	kristofer@localhost
+**** Client default_auth=native and server default auth=native
+user()	current_user()
+kristofer@localhost	kristofer@localhost
+**** Client default_auth=sha_256_password + public key on file.
+user()	current_user()
+kristofer@localhost	kristofer@localhost
+DROP USER 'kristofer'@'localhost';
+DROP USER 'kristofer2'@'localhost';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('');
+ERROR 28000: Access denied for user 'kristofer'@'localhost' (using password: YES)
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@localhost
+SHOW GRANTS FOR 'kristofer'@'localhost';
+Grants for kristofer@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<non-deterministic-password-hash>'
+DROP USER 'kristofer'@'localhost';
+GRANT ALL ON *.* TO 'kristofer'@'33.33.33.33' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'33.33.33.33'=PASSWORD('');
+Connection should fail for localhost
+ERROR 28000: Access denied for user 'kristofer'@'localhost' (using password: NO)
+DROP USER 'kristofer'@'33.33.33.33';
+SET GLOBAL old_passwords= 2;
+SET SESSION old_passwords= 2;
+CREATE TABLE t1 (c1 VARCHAR(10) );
+INSERT INTO t1 VALUES ('secret');
+SELECT HEX(PASSWORD(c1)) FROM t1;
+HEX(PASSWORD(c1))
+success
+DROP TABLE t1;
+SELECT PASSWORD(NULL), PASSWORD('');
+PASSWORD(NULL)	PASSWORD('')
+	
+CREATE TABLE t1( c1 text, c2 varchar (2));
+INSERT INTO t1 VALUES (NULL,''),(NULL,''),(NULL,'');
+SELECT PASSWORD(c1), PASSWORD(c2) FROM t1;
+PASSWORD(c1)	PASSWORD(c2)
+	
+	
+	
+DROP TABLE t1;
+CREATE USER 'kristofer' IDENTIFIED WITH 'sha256_password';
+SET GLOBAL old_passwords= 2;
+SET SESSION old_passwords= 2;
+SET PASSWORD FOR 'kristofer'=PASSWORD('secret');
+SELECT user, plugin FROM mysql.user;
+user	plugin
+root	
+root	
+root	
+root	
+kristofer	sha256_password
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@%
+UPDATE mysql.user SET authentication_string= '$' WHERE user='kristofer';
+FLUSH PRIVILEGES;
+SELECT user,authentication_string,password,plugin FROM mysql.user WHERE user='kristofer';
+user	authentication_string	password	plugin
+kristofer	$		sha256_password
+ERROR 28000: Access denied for user 'kristofer'@'localhost' (using password: YES)
+UPDATE mysql.user SET authentication_string= '$5$asd' WHERE user='kristofer';
+FLUSH PRIVILEGES;
+SELECT user,authentication_string,password,plugin FROM mysql.user WHERE user='kristofer';
+user	authentication_string	password	plugin
+kristofer	$5$asd		sha256_password
+ERROR 28000: Access denied for user 'kristofer'@'localhost' (using password: YES)
+DROP USER kristofer;
+SET GLOBAL old_passwords= default;

=== added file 'mysql-test/suite/sha256_auth/r/plugin_auth_sha256_2.result'
--- a/mysql-test/suite/sha256_auth/r/plugin_auth_sha256_2.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sha256_auth/r/plugin_auth_sha256_2.result	2012-03-23 15:03:42 +0000
@@ -0,0 +1,41 @@
+CREATE USER 'kristofer' IDENTIFIED BY 'secret';
+SELECT user, plugin FROM mysql.user;
+user	plugin
+root	
+root	
+root	
+root	
+kristofer	sha256_password
+user()	current_user()
+kristofer@localhost	kristofer@%
+user()	current_user()
+kristofer@localhost	kristofer@%
+user()	current_user()
+kristofer@localhost	kristofer@%
+DROP USER 'kristofer';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY 'secret2';
+user()	current_user()
+kristofer@localhost	kristofer@localhost
+user()	current_user()
+kristofer@localhost	kristofer@localhost
+user()	current_user()
+kristofer@localhost	kristofer@localhost
+SHOW GRANTS FOR 'kristofer'@'localhost';
+Grants for kristofer@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<non-deterministic-password-hash>'
+DROP USER 'kristofer'@'localhost';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY '';
+user()	current_user()
+kristofer@localhost	kristofer@localhost
+user()	current_user()
+kristofer@localhost	kristofer@localhost
+user()	current_user()
+kristofer@localhost	kristofer@localhost
+SHOW GRANTS FOR 'kristofer'@'localhost';
+Grants for kristofer@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<non-deterministic-password-hash>'
+DROP USER 'kristofer'@'localhost';
+GRANT ALL ON *.* TO 'kristofer'@'33.33.33.33' IDENTIFIED BY '';
+Connection should fail for localhost
+ERROR 28000: Access denied for user 'kristofer'@'localhost' (using password: NO)
+DROP USER 'kristofer'@'33.33.33.33';

=== added file 'mysql-test/suite/sha256_auth/r/plugin_auth_sha256_server_default.result'
--- a/mysql-test/suite/sha256_auth/r/plugin_auth_sha256_server_default.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sha256_auth/r/plugin_auth_sha256_server_default.result	2012-04-17 15:18:24 +0000
@@ -0,0 +1,63 @@
+CREATE USER 'kristofer';
+SET PASSWORD FOR 'kristofer'=PASSWORD('secret');
+SELECT user, plugin FROM mysql.user;
+user	plugin
+root	
+root	
+root	
+root	
+kristofer	sha256_password
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@%
+DROP USER 'kristofer';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+GRANT ALL ON *.* TO 'kristofer2'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('secret2');
+SET PASSWORD FOR 'kristofer2'@'localhost'=PASSWORD('secret2');
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@localhost
+SHOW GRANTS FOR 'kristofer'@'localhost';
+Grants for kristofer@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<non-deterministic-password-hash>'
+Change user (should succeed)
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer2@localhost	kristofer2@localhost
+**** Client default_auth=sha_256_password and server default auth=native
+user()	current_user()
+kristofer@localhost	kristofer@localhost
+**** Client default_auth=native and server default auth=native
+user()	current_user()
+kristofer@localhost	kristofer@localhost
+**** Client default_auth=sha_256_password + public key on file.
+user()	current_user()
+kristofer@localhost	kristofer@localhost
+DROP USER 'kristofer'@'localhost';
+DROP USER 'kristofer2'@'localhost';
+GRANT ALL ON *.* TO 'kristofer'@'localhost';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('');
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@localhost
+SHOW GRANTS FOR 'kristofer'@'localhost';
+Grants for kristofer@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<non-deterministic-password-hash>'
+DROP USER 'kristofer'@'localhost';
+GRANT ALL ON *.* TO 'kristofer'@'33.33.33.33';
+SET PASSWORD FOR 'kristofer'@'33.33.33.33'=PASSWORD('');
+Connection should fail for localhost
+ERROR 28000: Access denied for user 'kristofer'@'localhost' (using password: NO)
+DROP USER 'kristofer'@'33.33.33.33';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY 'awesomeness';
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@localhost
+SHOW GRANTS FOR 'kristofer'@'localhost';
+Grants for kristofer@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<non-deterministic-password-hash>'
+SET @@OLD_PASSWORDS= 0;
+SET PASSWORD FOR 'kristofer'@'localhost'= PASSWORD('error');
+ERROR HY000: The password hash doesn't have the expected format. Check if the correct password algorithm is being used with the PASSWORD() function.
+DROP USER 'kristofer'@'localhost';

=== added file 'mysql-test/suite/sha256_auth/r/plugin_auth_sha256_tls.result'
--- a/mysql-test/suite/sha256_auth/r/plugin_auth_sha256_tls.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sha256_auth/r/plugin_auth_sha256_tls.result	2012-03-23 15:03:42 +0000
@@ -0,0 +1,32 @@
+SHOW STATUS LIKE 'Ssl_cipher';
+Variable_name	Value
+Ssl_cipher	DHE-RSA-AES256-SHA
+CREATE USER 'kristofer' IDENTIFIED WITH 'sha256_password';
+SET GLOBAL old_passwords= 2;
+SET SESSION old_passwords= 2;
+SET PASSWORD FOR 'kristofer'=PASSWORD('secret');
+DROP USER 'kristofer';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('secret2');
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@localhost
+SHOW GRANTS FOR 'kristofer'@'localhost';
+Grants for kristofer@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<non-deterministic-password-hash>'
+DROP USER 'kristofer'@'localhost';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('');
+SELECT USER(),CURRENT_USER();
+USER()	CURRENT_USER()
+kristofer@localhost	kristofer@localhost
+SHOW GRANTS FOR 'kristofer'@'localhost';
+Grants for kristofer@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<non-deterministic-password-hash>'
+DROP USER 'kristofer'@'localhost';
+GRANT ALL ON *.* TO 'kristofer'@'33.33.33.33' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'33.33.33.33'=PASSWORD('');
+Connection should fail for localhost
+ERROR 28000: Access denied for user 'kristofer'@'localhost' (using password: NO)
+DROP USER 'kristofer'@'33.33.33.33';
+SET GLOBAL old_passwords= default;

=== added directory 'mysql-test/suite/sha256_auth/t'
=== added file 'mysql-test/suite/sha256_auth/t/plugin_auth_sha256-master.opt'
--- a/mysql-test/suite/sha256_auth/t/plugin_auth_sha256-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sha256_auth/t/plugin_auth_sha256-master.opt	2012-03-23 15:03:42 +0000
@@ -0,0 +1,2 @@
+--loose-sha256_password_private_key_path=$MYSQL_TEST_DIR/std_data/rsa_private_key.pem
+--loose-sha256_password_public_key_path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem

=== added file 'mysql-test/suite/sha256_auth/t/plugin_auth_sha256.test'
--- a/mysql-test/suite/sha256_auth/t/plugin_auth_sha256.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sha256_auth/t/plugin_auth_sha256.test	2012-05-21 23:00:55 +0000
@@ -0,0 +1,134 @@
+--source include/not_embedded.inc
+--source include/mysql_upgrade_preparation.inc
+
+# This test will intentionally generate errors in the server error log
+# when a broken password is inserted into the mysql.user table.
+# The below suppression is to clear those errors.
+--disable_query_log
+call mtr.add_suppression(".*Password salt for user.*");
+--enable_query_log
+
+CREATE USER 'kristofer' IDENTIFIED WITH 'sha256_password';
+SET GLOBAL old_passwords= 2;
+SET SESSION old_passwords= 2;
+SET PASSWORD FOR 'kristofer'=PASSWORD('secret');
+SELECT user, plugin FROM mysql.user;
+connect(con1,localhost,kristofer,secret,,);
+connection con1;
+SELECT USER(),CURRENT_USER();
+connection default;
+disconnect con1;
+# Make sure authentication also works if client default_auth is changed and that
+# it possible to select a local public key fil using client options.
+DROP USER 'kristofer';
+
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+GRANT ALL ON *.* TO 'kristofer2'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('secret2');
+SET PASSWORD FOR 'kristofer2'@'localhost'=PASSWORD('secret2');
+--disable_query_log
+--error ER_ACCESS_DENIED_ERROR
+connect(con2,localhost,kristofer,badpassword,,);
+--enable_query_log
+connect(con2,localhost,kristofer,secret2,,);
+connection con2;
+SELECT USER(),CURRENT_USER();
+--replace_regex /PASSWORD .*$/PASSWORD '<non-deterministic-password-hash>'/
+SHOW GRANTS FOR 'kristofer'@'localhost';
+
+--echo Change user (should succeed)
+change_user kristofer2,secret2;
+SELECT USER(),CURRENT_USER();
+
+connection default;
+disconnect con2;
+--echo **** Client default_auth=sha_256_password and server default auth=native
+--exec $MYSQL -ukristofer -psecret2 --default_auth=sha256_password -e "select user(), current_user()"
+--echo **** Client default_auth=native and server default auth=native
+--exec $MYSQL -ukristofer -psecret2 --default_auth=mysql_native_password -e "select user(), current_user()"
+--echo **** Client default_auth=sha_256_password + public key on file.
+--exec $MYSQL -ukristofer -psecret2 --default_auth=sha256_password --server_public_key=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "select user(), current_user()"
+DROP USER 'kristofer'@'localhost';
+DROP USER 'kristofer2'@'localhost';
+
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('');
+--disable_query_log
+--error ER_ACCESS_DENIED_ERROR
+connect(con3,localhost,kristofer,wrongpass,,);
+--enable_query_log
+connect(con3,localhost,kristofer,,,);
+connection con3;
+SELECT USER(),CURRENT_USER();
+--replace_regex /PASSWORD .*$/PASSWORD '<non-deterministic-password-hash>'/
+SHOW GRANTS FOR 'kristofer'@'localhost';
+connection default;
+disconnect con3;
+DROP USER 'kristofer'@'localhost';
+
+GRANT ALL ON *.* TO 'kristofer'@'33.33.33.33' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'33.33.33.33'=PASSWORD('');
+--echo Connection should fail for localhost
+--replace_result $MASTER_MYSOCK MASTER_MYSOCK
+--disable_query_log
+--error ER_ACCESS_DENIED_ERROR
+connect(con4,127.0.0.1,kristofer,,,);
+--enable_query_log
+DROP USER 'kristofer'@'33.33.33.33';
+
+#
+# Test with non const arguments
+#
+SET GLOBAL old_passwords= 2;
+SET SESSION old_passwords= 2;
+CREATE TABLE t1 (c1 VARCHAR(10) );
+INSERT INTO t1 VALUES ('secret');
+--replace_regex /2435.*00/success/
+SELECT HEX(PASSWORD(c1)) FROM t1;
+DROP TABLE t1;
+
+#
+# Test null argument
+# PASSWORD(NULL) should produce empty "" values.
+#
+SELECT PASSWORD(NULL), PASSWORD('');
+CREATE TABLE t1( c1 text, c2 varchar (2));
+INSERT INTO t1 VALUES (NULL,''),(NULL,''),(NULL,'');
+SELECT PASSWORD(c1), PASSWORD(c2) FROM t1;
+DROP TABLE t1;
+
+#
+# test bad password formats
+#
+CREATE USER 'kristofer' IDENTIFIED WITH 'sha256_password';
+SET GLOBAL old_passwords= 2;
+SET SESSION old_passwords= 2;
+SET PASSWORD FOR 'kristofer'=PASSWORD('secret');
+SELECT user, plugin FROM mysql.user;
+--disable_query_log
+connect(con1,localhost,kristofer,secret);
+--enable_query_log
+connection con1;
+SELECT USER(),CURRENT_USER();
+connection default;
+disconnect con1;
+UPDATE mysql.user SET authentication_string= '$' WHERE user='kristofer';
+FLUSH PRIVILEGES;
+SELECT user,authentication_string,password,plugin FROM mysql.user WHERE user='kristofer';
+--disable_query_log
+--error ER_ACCESS_DENIED_ERROR
+connect(con1,localhost,kristofer,secret);
+--enable_query_log
+
+UPDATE mysql.user SET authentication_string= '$5$asd' WHERE user='kristofer';
+FLUSH PRIVILEGES;
+SELECT user,authentication_string,password,plugin FROM mysql.user WHERE user='kristofer';
+--disable_query_log
+--error ER_ACCESS_DENIED_ERROR
+connect(con1,localhost,kristofer,secret);
+--enable_query_log
+DROP USER kristofer;
+
+# Restore default value for old_passwords
+SET GLOBAL old_passwords= default;
+

=== added file 'mysql-test/suite/sha256_auth/t/plugin_auth_sha256_2-master.opt'
--- a/mysql-test/suite/sha256_auth/t/plugin_auth_sha256_2-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sha256_auth/t/plugin_auth_sha256_2-master.opt	2012-03-23 15:03:42 +0000
@@ -0,0 +1,3 @@
+--loose-sha256_password_private_key_path=$MYSQL_TEST_DIR/std_data/rsa_private_key.pem
+--loose-sha256_password_public_key_path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem
+--default_authentication=sha256_password

=== added file 'mysql-test/suite/sha256_auth/t/plugin_auth_sha256_2.test'
--- a/mysql-test/suite/sha256_auth/t/plugin_auth_sha256_2.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sha256_auth/t/plugin_auth_sha256_2.test	2012-05-21 23:00:55 +0000
@@ -0,0 +1,36 @@
+--source include/not_embedded.inc
+--source include/mysql_upgrade_preparation.inc
+
+CREATE USER 'kristofer' IDENTIFIED BY 'secret';
+SELECT user, plugin FROM mysql.user;
+--exec $MYSQL -ukristofer -psecret --default_auth=sha256_password -e "select user(), current_user()"
+--exec $MYSQL -ukristofer -psecret --default_auth=mysql_native_password -e "select user(), current_user()"
+--exec $MYSQL -ukristofer -psecret --default_auth=sha256_password --server_public_key=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "select user(), current_user()"
+DROP USER 'kristofer';
+
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY 'secret2';
+--exec $MYSQL -ukristofer -psecret2 --default_auth=sha256_password -e "select user(), current_user()"
+--exec $MYSQL -ukristofer -psecret2 --default_auth=mysql_native_password -e "select user(), current_user()"
+--exec $MYSQL -ukristofer -psecret2 --default_auth=sha256_password --server_public_key=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "select user(), current_user()"
+--replace_regex /PASSWORD .*$/PASSWORD '<non-deterministic-password-hash>'/
+SHOW GRANTS FOR 'kristofer'@'localhost';
+DROP USER 'kristofer'@'localhost';
+
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY '';
+--exec $MYSQL -ukristofer --default_auth=sha256_password -e "select user(), current_user()"
+--exec $MYSQL -ukristofer --default_auth=mysql_native_password -e "select user(), current_user()"
+--exec $MYSQL -ukristofer --default_auth=sha256_password --server_public_key=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "select user(), current_user()"
+--replace_regex /PASSWORD .*$/PASSWORD '<non-deterministic-password-hash>'/
+SHOW GRANTS FOR 'kristofer'@'localhost';
+DROP USER 'kristofer'@'localhost';
+
+GRANT ALL ON *.* TO 'kristofer'@'33.33.33.33' IDENTIFIED BY '';
+--echo Connection should fail for localhost
+--replace_result $MASTER_MYSOCK MASTER_MYSOCK
+--disable_query_log
+--error ER_ACCESS_DENIED_ERROR
+connect(con4,127.0.0.1,kristofer,,,);
+--enable_query_log
+DROP USER 'kristofer'@'33.33.33.33';
+
+

=== added file 'mysql-test/suite/sha256_auth/t/plugin_auth_sha256_server_default-master.opt'
--- a/mysql-test/suite/sha256_auth/t/plugin_auth_sha256_server_default-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sha256_auth/t/plugin_auth_sha256_server_default-master.opt	2012-03-23 15:03:42 +0000
@@ -0,0 +1,3 @@
+--sha256_password_private_key_path=$MYSQL_TEST_DIR/std_data/rsa_private_key.pem
+--sha256_password_public_key_path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem
+--default_authentication_plugin=sha256_password

=== added file 'mysql-test/suite/sha256_auth/t/plugin_auth_sha256_server_default.test'
--- a/mysql-test/suite/sha256_auth/t/plugin_auth_sha256_server_default.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sha256_auth/t/plugin_auth_sha256_server_default.test	2012-05-21 23:00:55 +0000
@@ -0,0 +1,74 @@
+--source include/not_embedded.inc
+--source include/mysql_upgrade_preparation.inc
+
+CREATE USER 'kristofer';
+SET PASSWORD FOR 'kristofer'=PASSWORD('secret');
+SELECT user, plugin FROM mysql.user;
+connect(con1,localhost,kristofer,secret,,);
+connection con1;
+SELECT USER(),CURRENT_USER();
+connection default;
+disconnect con1;
+DROP USER 'kristofer';
+
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+GRANT ALL ON *.* TO 'kristofer2'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('secret2');
+SET PASSWORD FOR 'kristofer2'@'localhost'=PASSWORD('secret2');
+connect(con2,localhost,kristofer,secret2,,);
+connection con2;
+SELECT USER(),CURRENT_USER();
+--replace_regex /PASSWORD .*$/PASSWORD '<non-deterministic-password-hash>'/
+SHOW GRANTS FOR 'kristofer'@'localhost';
+
+--echo Change user (should succeed)
+change_user kristofer2,secret2;
+SELECT USER(),CURRENT_USER();
+
+connection default;
+disconnect con2;
+--echo **** Client default_auth=sha_256_password and server default auth=native
+--exec $MYSQL -ukristofer -psecret2 --default_auth=sha256_password -e "select user(), current_user()"
+--echo **** Client default_auth=native and server default auth=native
+--exec $MYSQL -ukristofer -psecret2 --default_auth=mysql_native_password -e "select user(), current_user()"
+--echo **** Client default_auth=sha_256_password + public key on file.
+--exec $MYSQL -ukristofer -psecret2 --default_auth=sha256_password --server_public_key=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "select user(), current_user()"
+DROP USER 'kristofer'@'localhost';
+DROP USER 'kristofer2'@'localhost';
+
+GRANT ALL ON *.* TO 'kristofer'@'localhost';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('');
+connect(con3,localhost,kristofer,,,);
+connection con3;
+SELECT USER(),CURRENT_USER();
+--replace_regex /PASSWORD .*$/PASSWORD '<non-deterministic-password-hash>'/
+SHOW GRANTS FOR 'kristofer'@'localhost';
+connection default;
+disconnect con3;
+DROP USER 'kristofer'@'localhost';
+
+GRANT ALL ON *.* TO 'kristofer'@'33.33.33.33';
+SET PASSWORD FOR 'kristofer'@'33.33.33.33'=PASSWORD('');
+--echo Connection should fail for localhost
+--replace_result $MASTER_MYSOCK MASTER_MYSOCK
+--disable_query_log
+--error ER_ACCESS_DENIED_ERROR
+connect(con4,127.0.0.1,kristofer,,,);
+--enable_query_log
+DROP USER 'kristofer'@'33.33.33.33';
+
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY 'awesomeness';
+connect(con3,localhost,kristofer,awesomeness,,);
+connection con3;
+SELECT USER(),CURRENT_USER();
+--replace_regex /PASSWORD .*$/PASSWORD '<non-deterministic-password-hash>'/
+SHOW GRANTS FOR 'kristofer'@'localhost';
+connection default;
+disconnect con3;
+# Setting password for kristofer@localhost using old_passwords=0 will fail.
+SET @@OLD_PASSWORDS= 0;
+--error ER_PASSWORD_FORMAT
+SET PASSWORD FOR 'kristofer'@'localhost'= PASSWORD('error');
+DROP USER 'kristofer'@'localhost';
+
+

=== added file 'mysql-test/suite/sha256_auth/t/plugin_auth_sha256_tls.test'
--- a/mysql-test/suite/sha256_auth/t/plugin_auth_sha256_tls.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sha256_auth/t/plugin_auth_sha256_tls.test	2012-03-23 15:03:42 +0000
@@ -0,0 +1,53 @@
+--source include/not_embedded.inc
+--source include/mysql_upgrade_preparation.inc
+--source include/have_ssl_communication.inc
+
+
+connect (ssl_con,localhost,root,,,,,SSL);
+SHOW STATUS LIKE 'Ssl_cipher';
+
+CREATE USER 'kristofer' IDENTIFIED WITH 'sha256_password';
+SET GLOBAL old_passwords= 2;
+SET SESSION old_passwords= 2;
+SET PASSWORD FOR 'kristofer'=PASSWORD('secret');
+connect(con1,localhost,kristofer,secret,,,,SSL);
+connection con1;
+connection ssl_con;
+disconnect con1;
+DROP USER 'kristofer';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('secret2');
+connect(con2,localhost,kristofer,secret2,,,,SSL);
+connection con2;
+SELECT USER(),CURRENT_USER();
+--replace_regex /PASSWORD .*$/PASSWORD '<non-deterministic-password-hash>'/
+SHOW GRANTS FOR 'kristofer'@'localhost';
+connection ssl_con;
+disconnect con2;
+DROP USER 'kristofer'@'localhost';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('');
+connect(con3,localhost,kristofer,,,,,SSL);
+connection con3;
+SELECT USER(),CURRENT_USER();
+--replace_regex /PASSWORD .*$/PASSWORD '<non-deterministic-password-hash>'/
+SHOW GRANTS FOR 'kristofer'@'localhost';
+connection ssl_con;
+disconnect con3;
+DROP USER 'kristofer'@'localhost';
+
+GRANT ALL ON *.* TO 'kristofer'@'33.33.33.33' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'33.33.33.33'=PASSWORD('');
+--echo Connection should fail for localhost
+--replace_result $MASTER_MYSOCK MASTER_MYSOCK
+--disable_query_log
+--error ER_ACCESS_DENIED_ERROR
+connect(con4,127.0.0.1,kristofer,,,,,SSL);
+--enable_query_log
+DROP USER 'kristofer'@'33.33.33.33';
+# Restore default value to old_passwords
+SET GLOBAL old_passwords= default;
+connection default;
+disconnect ssl_con;
+
+

=== modified file 'mysql-test/suite/sys_vars/r/old_passwords_basic.result'
--- a/mysql-test/suite/sys_vars/r/old_passwords_basic.result	2009-12-22 09:35:56 +0000
+++ b/mysql-test/suite/sys_vars/r/old_passwords_basic.result	2011-11-25 19:27:44 +0000
@@ -7,12 +7,12 @@ SELECT @start_session_value;
 @start_session_value
 0
 '#--------------------FN_DYNVARS_114_01-------------------------#'
-SET @@global.old_passwords = ON;
+SET @@global.old_passwords = 1;
 SET @@global.old_passwords = DEFAULT;
 SELECT @@global.old_passwords;
 @@global.old_passwords
 0
-SET @@session.old_passwords = ON;
+SET @@session.old_passwords = 1;
 SET @@session.old_passwords = DEFAULT;
 SELECT @@session.old_passwords;
 @@session.old_passwords
@@ -27,14 +27,6 @@ SELECT @@session.old_passwords = FALSE;
 @@session.old_passwords = FALSE
 1
 '#--------------------FN_DYNVARS_114_03-------------------------#'
-SET @@global.old_passwords = ON;
-SELECT @@global.old_passwords;
-@@global.old_passwords
-1
-SET @@global.old_passwords = OFF;
-SELECT @@global.old_passwords;
-@@global.old_passwords
-0
 SET @@global.old_passwords = 0;
 SELECT @@global.old_passwords;
 @@global.old_passwords
@@ -43,20 +35,7 @@ SET @@global.old_passwords = 1;
 SELECT @@global.old_passwords;
 @@global.old_passwords
 1
-SET @@global.old_passwords = TRUE;
-SELECT @@global.old_passwords;
-@@global.old_passwords
-1
-SET @@global.old_passwords = FALSE;
-SELECT @@global.old_passwords;
-@@global.old_passwords
-0
 '#--------------------FN_DYNVARS_114_04-------------------------#'
-SET @@session.old_passwords = ON;
-SELECT @@session.old_passwords;
-@@session.old_passwords
-1
-SET @@session.old_passwords = OFF;
 SELECT @@session.old_passwords;
 @@session.old_passwords
 0
@@ -68,67 +47,46 @@ SET @@session.old_passwords = 1;
 SELECT @@session.old_passwords;
 @@session.old_passwords
 1
-SET @@session.old_passwords = TRUE;
-SELECT @@session.old_passwords;
-@@session.old_passwords
-1
-SET @@session.old_passwords = FALSE;
-SELECT @@session.old_passwords;
-@@session.old_passwords
-0
 '#------------------FN_DYNVARS_114_05-----------------------#'
-SET @@global.old_passwords = 'ONN';
-ERROR 42000: Variable 'old_passwords' can't be set to the value of 'ONN'
-SET @@global.old_passwords = "OFFF";
-ERROR 42000: Variable 'old_passwords' can't be set to the value of 'OFFF'
-SET @@global.old_passwords = TTRUE;
-ERROR 42000: Variable 'old_passwords' can't be set to the value of 'TTRUE'
-SET @@global.old_passwords = FELSE;
-ERROR 42000: Variable 'old_passwords' can't be set to the value of 'FELSE'
 SET @@global.old_passwords = -1024;
-ERROR 42000: Variable 'old_passwords' can't be set to the value of '-1024'
+Warnings:
+Warning	1292	Truncated incorrect old_passwords value: '-1024'
+SELECT @@global.old_passwords;
+@@global.old_passwords
+0
 SET @@global.old_passwords = 65536;
-ERROR 42000: Variable 'old_passwords' can't be set to the value of '65536'
+Warnings:
+Warning	1292	Truncated incorrect old_passwords value: '65536'
+SELECT @@global.old_passwords;
+@@global.old_passwords
+2
 SET @@global.old_passwords = 65530.34;
 ERROR 42000: Incorrect argument type to variable 'old_passwords'
-SET @@global.old_passwords = test;
-ERROR 42000: Variable 'old_passwords' can't be set to the value of 'test'
-SET @@session.old_passwords = ONN;
-ERROR 42000: Variable 'old_passwords' can't be set to the value of 'ONN'
-SET @@session.old_passwords = ONF;
-ERROR 42000: Variable 'old_passwords' can't be set to the value of 'ONF'
-SET @@session.old_passwords = OF;
-ERROR 42000: Variable 'old_passwords' can't be set to the value of 'OF'
-SET @@session.old_passwords = 'OFN';
-ERROR 42000: Variable 'old_passwords' can't be set to the value of 'OFN'
-SET @@session.old_passwords = -2;
-ERROR 42000: Variable 'old_passwords' can't be set to the value of '-2'
-SET @@session.old_passwords = 65530.34;
-ERROR 42000: Incorrect argument type to variable 'old_passwords'
-SET @@session.old_passwords = 65550;
-ERROR 42000: Variable 'old_passwords' can't be set to the value of '65550'
+SELECT @@global.old_passwords;
+@@global.old_passwords
+2
 SET @@session.old_passwords = test;
-ERROR 42000: Variable 'old_passwords' can't be set to the value of 'test'
+ERROR 42000: Incorrect argument type to variable 'old_passwords'
 '#------------------FN_DYNVARS_114_06-----------------------#'
-SELECT IF(@@global.old_passwords, "ON", "OFF") = VARIABLE_VALUE 
+SELECT IF(@@global.old_passwords, "1", "0") = VARIABLE_VALUE 
 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES 
 WHERE VARIABLE_NAME='old_passwords';
-IF(@@global.old_passwords, "ON", "OFF") = VARIABLE_VALUE
-1
+IF(@@global.old_passwords, "1", "0") = VARIABLE_VALUE
+0
 '#------------------FN_DYNVARS_114_07-----------------------#'
-SELECT IF(@@session.old_passwords, "ON", "OFF") = VARIABLE_VALUE 
+SELECT IF(@@session.old_passwords, "1", "0") = VARIABLE_VALUE 
 FROM INFORMATION_SCHEMA.SESSION_VARIABLES 
 WHERE VARIABLE_NAME='old_passwords';
-IF(@@session.old_passwords, "ON", "OFF") = VARIABLE_VALUE
+IF(@@session.old_passwords, "1", "0") = VARIABLE_VALUE
 1
 '#---------------------FN_DYNVARS_114_08----------------------#'
-SET @@old_passwords = OFF;
-SET @@global.old_passwords = ON;
+SET @@old_passwords = 0;
+SET @@global.old_passwords = 1;
 SELECT @@old_passwords = @@global.old_passwords;
 @@old_passwords = @@global.old_passwords
 0
 '#---------------------FN_DYNVARS_114_09----------------------#'
-SET @@old_passwords = ON;
+SET @@old_passwords = 1;
 SELECT @@old_passwords = @@local.old_passwords;
 @@old_passwords = @@local.old_passwords
 1

=== modified file 'mysql-test/suite/sys_vars/r/old_passwords_func.result'
--- a/mysql-test/suite/sys_vars/r/old_passwords_func.result	2012-01-30 15:43:32 +0000
+++ b/mysql-test/suite/sys_vars/r/old_passwords_func.result	2012-03-28 13:10:10 +0000
@@ -5,9 +5,10 @@ SET @global_secure_auth = @@GLOBAL.secur
 ** Connection default **
 CREATE USER 'userNewPass1'@'localhost' IDENTIFIED BY 'pass1';
 CREATE USER 'userNewPass2'@'localhost' IDENTIFIED BY 'pass2';
-SET GLOBAL old_passwords = TRUE;
-SET SESSION old_passwords = TRUE;
-CREATE USER 'userOldPass'@'localhost' IDENTIFIED BY 'pass3';
+SET GLOBAL old_passwords = 1;
+SET SESSION old_passwords = 1;
+CREATE USER 'userOldPass'@'localhost' IDENTIFIED WITH 'mysql_old_password';
+SET PASSWORD FOR 'userOldPass'@'localhost'= PASSWORD('pass3');
 Warnings:
 Warning	1287	'pre-4.1 password hash' is deprecated and will be removed in a future release. Please use post-4.1 password hash instead
 SET GLOBAL secure_auth = FALSE;

=== modified file 'mysql-test/suite/sys_vars/r/secure_auth_func.result'
--- a/mysql-test/suite/sys_vars/r/secure_auth_func.result	2012-01-30 15:43:32 +0000
+++ b/mysql-test/suite/sys_vars/r/secure_auth_func.result	2012-03-28 13:10:10 +0000
@@ -14,15 +14,25 @@ CREATE USER 'testUser'@'localhost' IDENT
 ** Connecting con_user1 using testUser **
 ** Connection default**
 SET PASSWORD FOR 'testUser'@'localhost' = OLD_PASSWORD('newpass');
+ERROR HY000: Password hash should be a 41-digit hexadecimal number
+DROP USER 'testUser'@'localhost';
+CREATE USER 'testUser'@'localhost' identified with 'mysql_old_password';
+SET PASSWORD FOR 'testUser'@'localhost'= OLD_PASSWORD('newpass');
 Warnings:
 Warning	1287	'pre-4.1 password hash' is deprecated and will be removed in a future release. Please use post-4.1 password hash instead
 ** Connecting con_user2 using testUser **
 ** Connection default**
 '#--------------------FN_DYNVARS_144_03-------------------------#'
 SET GLOBAL secure_auth = ON;
+UPDATE mysql.user SET plugin='mysql_native_password' WHERE user='testUser' AND
+host='localhost';
+FLUSH PRIVILEGES;
 SET PASSWORD FOR 'testUser'@'localhost' = PASSWORD('newpass');
 ** Connecting con_user3 using testUser **
 ** Connection default **
+UPDATE mysql.user SET plugin='mysql_old_password' WHERE user='testUser' AND
+host='localhost';
+FLUSH PRIVILEGES;
 SET PASSWORD FOR 'testUser'@'localhost' = OLD_PASSWORD('newpass');
 Warnings:
 Warning	1287	'pre-4.1 password hash' is deprecated and will be removed in a future release. Please use post-4.1 password hash instead
@@ -30,6 +40,9 @@ Warning	1287	'pre-4.1 password hash' is 
 ERROR HY000: Server is running in --secure-auth mode, but 'testUser'@'localhost' has a password in the old format; please change the password to the new format
 Expected error "Server is in secure auth mode"
 ** Connection default**
+UPDATE mysql.user SET plugin='mysql_native_password' WHERE user='testUser' AND
+host='localhost';
+FLUSH PRIVILEGES;
 SET PASSWORD FOR 'testUser'@'localhost' = PASSWORD('newpass');
 ** Connecting con_user4 using testUser **
 ** Connection default **

=== added file 'mysql-test/suite/sys_vars/r/sha256_password_private_key_path_basic.result'
--- a/mysql-test/suite/sys_vars/r/sha256_password_private_key_path_basic.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/sha256_password_private_key_path_basic.result	2012-04-26 12:52:56 +0000
@@ -0,0 +1 @@
+Intentionally left empty

=== added file 'mysql-test/suite/sys_vars/r/sha256_password_public_key_path_basic.result'
--- a/mysql-test/suite/sys_vars/r/sha256_password_public_key_path_basic.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/sha256_password_public_key_path_basic.result	2012-04-26 12:52:56 +0000
@@ -0,0 +1 @@
+Intentionally left empty

=== modified file 'mysql-test/suite/sys_vars/t/old_passwords_basic.test'
--- a/mysql-test/suite/sys_vars/t/old_passwords_basic.test	2009-12-22 09:35:56 +0000
+++ b/mysql-test/suite/sys_vars/t/old_passwords_basic.test	2011-11-25 19:27:44 +0000
@@ -44,11 +44,11 @@ SELECT @start_session_value;
 #     Display the DEFAULT value of old_passwords  #
 ###################################################
 
-SET @@global.old_passwords = ON;
+SET @@global.old_passwords = 1;
 SET @@global.old_passwords = DEFAULT;
 SELECT @@global.old_passwords;
 
-SET @@session.old_passwords = ON;
+SET @@session.old_passwords = 1;
 SET @@session.old_passwords = DEFAULT;
 SELECT @@session.old_passwords;
 
@@ -70,38 +70,21 @@ SELECT @@session.old_passwords = FALSE;
 # Change the value of old_passwords to a valid value for GLOBAL Scope #
 #######################################################################
 
-SET @@global.old_passwords = ON;
-SELECT @@global.old_passwords;
-SET @@global.old_passwords = OFF;
-SELECT @@global.old_passwords;
 SET @@global.old_passwords = 0;
 SELECT @@global.old_passwords;
 SET @@global.old_passwords = 1;
 SELECT @@global.old_passwords;
-SET @@global.old_passwords = TRUE;
-SELECT @@global.old_passwords;
-SET @@global.old_passwords = FALSE;
-SELECT @@global.old_passwords;
-
-
 
 --echo '#--------------------FN_DYNVARS_114_04-------------------------#'
 ########################################################################
 # Change the value of old_passwords to a valid value for SESSION Scope #
 ########################################################################
  
-SET @@session.old_passwords = ON;
-SELECT @@session.old_passwords;
-SET @@session.old_passwords = OFF;
 SELECT @@session.old_passwords;
 SET @@session.old_passwords = 0;
 SELECT @@session.old_passwords;
 SET @@session.old_passwords = 1;
 SELECT @@session.old_passwords;
-SET @@session.old_passwords = TRUE;
-SELECT @@session.old_passwords;
-SET @@session.old_passwords = FALSE;
-SELECT @@session.old_passwords;
 
 
 --echo '#------------------FN_DYNVARS_114_05-----------------------#'
@@ -109,39 +92,14 @@ SELECT @@session.old_passwords;
 # Change the value of old_passwords to an invalid value #
 #########################################################
 
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@global.old_passwords = 'ONN';
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@global.old_passwords = "OFFF";
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@global.old_passwords = TTRUE;
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@global.old_passwords = FELSE;
---Error ER_WRONG_VALUE_FOR_VAR
 SET @@global.old_passwords = -1024;
---Error ER_WRONG_VALUE_FOR_VAR
+SELECT @@global.old_passwords;
 SET @@global.old_passwords = 65536;
+SELECT @@global.old_passwords;
 --Error ER_WRONG_TYPE_FOR_VAR
 SET @@global.old_passwords = 65530.34;
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@global.old_passwords = test;
-
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@session.old_passwords = ONN;
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@session.old_passwords = ONF;
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@session.old_passwords = OF;
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@session.old_passwords = 'OFN';
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@session.old_passwords = -2;
+SELECT @@global.old_passwords;
 --Error ER_WRONG_TYPE_FOR_VAR
-SET @@session.old_passwords = 65530.34;
---Error ER_WRONG_VALUE_FOR_VAR
-SET @@session.old_passwords = 65550;
-
---Error ER_WRONG_VALUE_FOR_VAR
 SET @@session.old_passwords = test;
 
 
@@ -151,7 +109,7 @@ SET @@session.old_passwords = test;
 ####################################################################
 
 
-SELECT IF(@@global.old_passwords, "ON", "OFF") = VARIABLE_VALUE 
+SELECT IF(@@global.old_passwords, "1", "0") = VARIABLE_VALUE 
 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES 
 WHERE VARIABLE_NAME='old_passwords';
 
@@ -160,7 +118,7 @@ WHERE VARIABLE_NAME='old_passwords';
 #  Check if the value in SESSION Table matches value in variable   #
 ####################################################################
 
-SELECT IF(@@session.old_passwords, "ON", "OFF") = VARIABLE_VALUE 
+SELECT IF(@@session.old_passwords, "1", "0") = VARIABLE_VALUE 
 FROM INFORMATION_SCHEMA.SESSION_VARIABLES 
 WHERE VARIABLE_NAME='old_passwords';
 
@@ -170,8 +128,8 @@ WHERE VARIABLE_NAME='old_passwords';
 #  Check if global and session variable are independent of each other         #
 ###############################################################################
 
-SET @@old_passwords = OFF;
-SET @@global.old_passwords = ON;
+SET @@old_passwords = 0;
+SET @@global.old_passwords = 1;
 SELECT @@old_passwords = @@global.old_passwords;
 
 
@@ -181,7 +139,7 @@ SELECT @@old_passwords = @@global.old_pa
 #    to same session variable                                                 #
 ###############################################################################
 
-SET @@old_passwords = ON;
+SET @@old_passwords = 1;
 SELECT @@old_passwords = @@local.old_passwords;
 SELECT @@local.old_passwords = @@session.old_passwords;
 

=== modified file 'mysql-test/suite/sys_vars/t/old_passwords_func.test'
--- a/mysql-test/suite/sys_vars/t/old_passwords_func.test	2008-12-19 15:12:15 +0000
+++ b/mysql-test/suite/sys_vars/t/old_passwords_func.test	2011-11-25 19:27:44 +0000
@@ -43,14 +43,14 @@ connection default;
 CREATE USER 'userNewPass1'@'localhost' IDENTIFIED BY 'pass1';
 CREATE USER 'userNewPass2'@'localhost' IDENTIFIED BY 'pass2';
 
-SET GLOBAL old_passwords = TRUE;
-SET SESSION old_passwords = TRUE;
+SET GLOBAL old_passwords = 1;
+SET SESSION old_passwords = 1;
 
 #
-# 1 User with TRUE value
+# 1 User with old_passwords value of 1
 #
-
-CREATE USER 'userOldPass'@'localhost' IDENTIFIED BY 'pass3';
+CREATE USER 'userOldPass'@'localhost' IDENTIFIED WITH 'mysql_old_password';
+SET PASSWORD FOR 'userOldPass'@'localhost'= PASSWORD('pass3');
 
 SET GLOBAL secure_auth = FALSE;
 

=== modified file 'mysql-test/suite/sys_vars/t/secure_auth_func.test'
--- a/mysql-test/suite/sys_vars/t/secure_auth_func.test	2008-12-19 15:12:15 +0000
+++ b/mysql-test/suite/sys_vars/t/secure_auth_func.test	2011-11-25 19:27:44 +0000
@@ -65,7 +65,11 @@ connection default;
 #
 # Setting password in OLD format
 #
+--error ER_PASSWD_LENGTH
 SET PASSWORD FOR 'testUser'@'localhost' = OLD_PASSWORD('newpass');
+DROP USER 'testUser'@'localhost';
+CREATE USER 'testUser'@'localhost' identified with 'mysql_old_password';
+SET PASSWORD FOR 'testUser'@'localhost'= OLD_PASSWORD('newpass');
 
 --echo ** Connecting con_user2 using testUser **
 connect (con_user2,localhost,testUser,newpass,);
@@ -82,6 +86,9 @@ SET GLOBAL secure_auth = ON;
 #
 # Setting password in NEW format
 #
+UPDATE mysql.user SET plugin='mysql_native_password' WHERE user='testUser' AND
+  host='localhost';
+FLUSH PRIVILEGES;
 SET PASSWORD FOR 'testUser'@'localhost' = PASSWORD('newpass');
 
 --echo ** Connecting con_user3 using testUser **
@@ -92,6 +99,9 @@ connection default;
 #
 # Setting password in OLD format
 #
+UPDATE mysql.user SET plugin='mysql_old_password' WHERE user='testUser' AND
+  host='localhost';
+FLUSH PRIVILEGES;
 SET PASSWORD FOR 'testUser'@'localhost' = OLD_PASSWORD('newpass');
 
 --echo ** Connecting con_user4 using testUser **
@@ -107,6 +117,9 @@ connection default;
 #
 # Setting password back in NEW format
 #
+UPDATE mysql.user SET plugin='mysql_native_password' WHERE user='testUser' AND
+  host='localhost';
+FLUSH PRIVILEGES;
 SET PASSWORD FOR 'testUser'@'localhost' = PASSWORD('newpass');
 
 --echo ** Connecting con_user4 using testUser **

=== added file 'mysql-test/suite/sys_vars/t/sha256_password_private_key_path_basic.test'
--- a/mysql-test/suite/sys_vars/t/sha256_password_private_key_path_basic.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/sha256_password_private_key_path_basic.test	2012-04-26 12:52:56 +0000
@@ -0,0 +1,2 @@
+--echo Intentionally left empty
+

=== added file 'mysql-test/suite/sys_vars/t/sha256_password_public_key_path_basic.test'
--- a/mysql-test/suite/sys_vars/t/sha256_password_public_key_path_basic.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/sha256_password_public_key_path_basic.test	2012-04-26 12:52:56 +0000
@@ -0,0 +1 @@
+--echo Intentionally left empty

=== modified file 'mysql-test/t/change_user.test'
--- a/mysql-test/t/change_user.test	2012-01-31 11:00:26 +0000
+++ b/mysql-test/t/change_user.test	2012-03-22 18:28:07 +0000
@@ -4,6 +4,7 @@
 
 SET GLOBAL secure_auth = OFF;
 grant select on test.* to test_nopw;
+create user test_oldpw identified with 'mysql_old_password';
 # need to suppress the deprecation warnings because they're absent in embedded
 --disable_warnings
 grant select on test.* to test_oldpw identified by password "09301740536db389";

=== modified file 'mysql-test/t/connect.test'
--- a/mysql-test/t/connect.test	2012-05-28 09:09:33 +0000
+++ b/mysql-test/t/connect.test	2012-06-04 15:35:18 +0000
@@ -66,9 +66,8 @@ connect (fail_con,localhost,test,zorro,)
 
 # check if old password version also works
 SET GLOBAL secure_auth = OFF;
-update mysql.user set password=old_password("gambling2") where user=_binary"test";
+update mysql.user set password=old_password("gambling2"), plugin="mysql_old_password" where user=_binary"test";
 flush privileges;
-
 connect (con10,localhost,test,gambling2,);
 connect (con5,localhost,test,gambling2,mysql);
 connection con5;
@@ -307,10 +306,11 @@ SET GLOBAL event_scheduler = OFF;
 --echo #Expect 1
 SELECT @@global.secure_auth;
 
-SET old_passwords=true;
+SET old_passwords=1;
 
 --echo #Expect deprecation warning
-CREATE USER old_pwd@localhost IDENTIFIED BY 'aha';
+CREATE USER old_pwd@localhost IDENTIFIED WITH 'mysql_old_password';
+SET PASSWORD FOR old_pwd@localhost= OLD_PASSWORD('aha');
 
 --echo #Expect deprecation warning
 SET PASSWORD FOR old_pwd@localhost = OLD_PASSWORD('aha2');

=== modified file 'mysql-test/t/ctype_ucs.test'
--- a/mysql-test/t/ctype_ucs.test	2012-05-07 08:29:18 +0000
+++ b/mysql-test/t/ctype_ucs.test	2012-05-09 13:23:49 +0000
@@ -501,8 +501,11 @@ DROP TABLE t1,t2;
 
 # PASSWORD and OLD_PASSWORD don't work with UCS2 strings, but to fix it would
 # not be backwards compatible in all cases, so it's best to leave it alone
-select password(name) from bug20536;
-select old_password(name) from bug20536;
+# 2011-11-08 update: change in behavior caused by refactoring of
+#   Item_func_password() but since the below test doesn't show correct behavior
+#   anyway it is removed.
+# select password(name) from bug20536;
+# select old_password(name) from bug20536;
 
 # Disable test case as encrypt relies on 'crypt' function.
 # "decrypt" is noramlly tested in func_crypt.test which have a

=== modified file 'mysql-test/t/disabled.def'
--- a/mysql-test/t/disabled.def	2012-06-07 11:12:50 +0000
+++ b/mysql-test/t/disabled.def	2012-06-08 11:39:00 +0000
@@ -17,5 +17,4 @@ log_tables-big           : Bug#11756699 
 ds_mrr-big @solaris      : Bug#14168107 2012-04-03 Hemant disabled new test added by Olav Sandstå,since this leads to timeout on Solaris on slow sparc servers
 partition_locking_4	 : Bug#13924750 2012-04-04 lost connection.
 mysql_embedded_client_test	: Bug#13964673 2012-04-16 amitbha since most of the test cases are failing
-openssl_1                : Bug#13784804, Mayank: Error no is same but message is messed up.
 variables-notembedded    : Bug#13431369 2012-05-24 tnuernberg POSIX shutdown() broken on Windows, need workaround

=== modified file 'mysql-test/t/func_crypt.test'
--- a/mysql-test/t/func_crypt.test	2009-05-27 10:20:57 +0000
+++ b/mysql-test/t/func_crypt.test	2011-11-25 19:27:44 +0000
@@ -27,20 +27,20 @@ select length(encrypt('test'));
 select encrypt('test','aa');
 select old_password(NULL);
 select password(NULL);
-set global old_passwords=on;
+set global old_passwords=1;
 select password('');
 select old_password('');
 select password('idkfa');
 select old_password('idkfa');
-set old_passwords=on;
+set old_passwords=1;
 select password('idkfa');
 select old_password('idkfa');
-set global old_passwords=off;
+set global old_passwords=0;
 select password('idkfa');
 select old_password('idkfa');
 
 # this test shows that new scrambles honor spaces in passwords:
-set old_passwords=off;
+set old_passwords=0;
 select password('idkfa ');
 select password('idkfa');
 select password(' idkfa');

=== modified file 'mysql-test/t/mysql_upgrade.test'
--- a/mysql-test/t/mysql_upgrade.test	2012-01-30 15:43:32 +0000
+++ b/mysql-test/t/mysql_upgrade.test	2012-03-28 13:10:10 +0000
@@ -133,7 +133,7 @@ let $MYSQLD_DATADIR= `select @@datadir`;
 --echo #   for legacy authentication method
 --echo #
 
-CREATE USER 'bug13586336'@'localhost';
+CREATE USER 'bug13586336'@'localhost' IDENTIFIED WITH 'mysql_old_password';
 SET PASSWORD FOR 'bug13586336'@'localhost' = OLD_PASSWORD('a');
 --echo Run mysql_upgrade with all privileges on a user
 --exec $MYSQL_UPGRADE --skip-verbose --force 2>&1

=== modified file 'mysql-test/t/openssl_1.test'
--- a/mysql-test/t/openssl_1.test	2010-10-27 11:32:32 +0000
+++ b/mysql-test/t/openssl_1.test	2012-04-26 11:49:14 +0000
@@ -73,22 +73,28 @@ drop table t1;
 # a different cacert
 #
 --exec echo "this query should not execute;" > $MYSQLTEST_VARDIR/tmp/test.sql
+--replace_regex /2026 SSL connection error: .*/2026 SSL connection error: xxxx/
 --error 1
 --exec $MYSQL_TEST --ssl-ca=$MYSQL_TEST_DIR/std_data/untrusted-cacert.pem --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
+--echo
 
 #
 # Test that we can't open connection to server if we are using
 # a blank ca
 #
+--replace_regex /2026 SSL connection error: .*/2026 SSL connection error: xxxx/
 --error 1
 --exec $MYSQL_TEST --ssl-ca= --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
+--echo
 
 #
 # Test that we can't open connection to server if we are using
 # a nonexistent ca file
 #
+--replace_regex /2026 SSL connection error: .*/2026 SSL connection error: xxxx/
 --error 1
 --exec $MYSQL_TEST --ssl-ca=nonexisting_file.pem --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
+--echo
 
 #
 # Test that we can't open connection to server if we are using

=== modified file 'mysql-test/t/plugin_auth.test'
--- a/mysql-test/t/plugin_auth.test	2011-10-12 13:40:11 +0000
+++ b/mysql-test/t/plugin_auth.test	2011-11-25 19:27:44 +0000
@@ -14,9 +14,7 @@ SET GLOBAL general_log=       'ON';
 
 CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
 CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd';
-
 SELECT plugin,authentication_string FROM mysql.user WHERE User='plug';
-
 --echo ## test plugin auth
 --disable_query_log
 --error ER_ACCESS_DENIED_ERROR : this should fail : no grant
@@ -37,6 +35,7 @@ select USER(),CURRENT_USER();
 
 --echo ## test SET PASSWORD
 #--error ER_SET_PASSWORD_AUTH_PLUGIN
+--echo Setting password is allowed but it won't affect the authentication mechanism.
 SET PASSWORD = PASSWORD('plug_dest');
 
 connection default;
@@ -68,7 +67,6 @@ SET @@sql_mode=no_auto_create_user;
 GRANT INSERT ON TEST.* TO grant_user IDENTIFIED WITH 'test_plugin_server';
 SET @@sql_mode=default;
 DROP USER grant_user;
-
 --echo ## test utf-8 user name
 CREATE USER `Ÿ` IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
 
@@ -88,8 +86,7 @@ CREATE DATABASE test_grant_db;
 
 --echo # create new user via GRANT WITH
 GRANT ALL PRIVILEGES ON test_grant_db.* TO new_grant_user 
-  IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
-
+IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
 GRANT PROXY ON plug_dest TO new_grant_user;  
 
 connect(plug_con_grant,localhost,new_grant_user,plug_dest);
@@ -111,7 +108,6 @@ GRANT ALL PRIVILEGES ON test_grant_db.* 
 --error ER_ACCESS_DENIED_ERROR
 connect(plug_con_grant_deny,localhost,new_grant_user,unused_password);
 --enable_query_log
-
 --echo #make sure plugin auth still available
 connect(plug_con_grant,localhost,new_grant_user,plug_dest);
 connection plug_con_grant;
@@ -125,8 +121,8 @@ disconnect plug_con_grant;
 DROP USER new_grant_user;
 
 --echo # try re-create existing user via GRANT IDENTIFIED WITH
-
---error ER_GRANT_PLUGIN_USER_EXISTS
+#--error ER_GRANT_PLUGIN_USER_EXISTS
+--echo GRANTS which don't affect current plugin are allowed!
 GRANT ALL PRIVILEGES ON test_grant_db.* TO plug
   IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
 
@@ -350,7 +346,6 @@ DROP USER ''@'';
 DROP USER standard_user;
 DROP DATABASE shared;
 
-
 --echo #
 --echo # Bug #57551 : Live upgrade fails between 5.1.52 -> 5.5.7-rc
 --echo #
@@ -404,7 +399,6 @@ FLUSH PRIVILEGES;
 
 --exec $MYSQL_UPGRADE --skip-verbose --force 2>&1
 --query_vertical SELECT Host,User,Proxied_host,Proxied_user,With_grant FROM mysql.proxies_priv
-
 FLUSH PRIVILEGES;
 
 --echo #
@@ -524,7 +518,6 @@ SELECT IS_NULLABLE, COLUMN_NAME FROM INF
     COLUMN_NAME IN ('plugin', 'authentication_string')
   ORDER BY COLUMN_NAME;
 
-
 --echo #
 --echo # Bug #12610784: SET PASSWORD INCORRECTLY KEEP AN OLD EMPTY PASSWORD
 --echo #

=== modified file 'mysql-test/t/plugin_auth_qa.test'
--- a/mysql-test/t/plugin_auth_qa.test	2010-10-20 14:56:09 +0000
+++ b/mysql-test/t/plugin_auth_qa.test	2011-11-25 19:27:44 +0000
@@ -166,9 +166,11 @@ SELECT user,plugin,authentication_string
 DROP USER plug_dest;
 # 
 CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
---error 1700
+#--error 1700
+--echo GRANTs which doesn't change the plugin are allowed
 GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
---error 1700
+#--error 1700
+--echo GRANTs which doesn't change the plugin are allowed
 GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server';
 DROP USER plug;
 #

=== added file 'mysql-test/t/plugin_auth_sha256_server_default_tls-master.opt'
--- a/mysql-test/t/plugin_auth_sha256_server_default_tls-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/plugin_auth_sha256_server_default_tls-master.opt	2012-05-31 11:48:21 +0000
@@ -0,0 +1 @@
+--default_authentication_plugin=sha256_password

=== added file 'mysql-test/t/plugin_auth_sha256_server_default_tls.test'
--- a/mysql-test/t/plugin_auth_sha256_server_default_tls.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/plugin_auth_sha256_server_default_tls.test	2012-05-31 11:48:21 +0000
@@ -0,0 +1,78 @@
+--source include/not_embedded.inc
+--source include/have_ssl.inc
+
+CREATE USER 'kristofer';
+SET PASSWORD FOR 'kristofer'=PASSWORD('secret');
+SELECT user, plugin FROM mysql.user;
+connect(con1,localhost,kristofer,secret,,,,SSL);
+connection con1;
+SELECT USER(),CURRENT_USER();
+connection default;
+disconnect con1;
+DROP USER 'kristofer';
+
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+GRANT ALL ON *.* TO 'kristofer2'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('secret2');
+SET PASSWORD FOR 'kristofer2'@'localhost'=PASSWORD('secret2');
+connect(con2,localhost,kristofer,secret2,,,,SSL);
+connection con2;
+SELECT USER(),CURRENT_USER();
+--replace_regex /PASSWORD .*$/PASSWORD '<non-deterministic-password-hash>'/
+SHOW GRANTS FOR 'kristofer'@'localhost';
+
+--echo Change user (should succeed)
+change_user kristofer2,secret2;
+SELECT USER(),CURRENT_USER();
+
+connection default;
+disconnect con2;
+--echo **** Client default_auth=sha_256_password and server default auth=sha256_password
+--echo #### Test is disabled because it requires RSA-keys and this only works 
+--echo #### with OpenSSL. The reason is that the current client library
+--echo #### framework can't know if SSL was attempted or not when the default
+--echo #### client auth is switched and hence it will only report that the 
+--echo #### connection is unencrypted.
+# --exec xterm -e gdb --args $MYSQL -ukristofer -psecret2 --default_auth=sha256_password --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem -e "select user(), current_user()"
+--echo **** Client default_auth=native and server default auth=sha256_password
+--exec $MYSQL -ukristofer -psecret2 --default_auth=mysql_native_password --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem -e "select user(), current_user()"
+
+DROP USER 'kristofer'@'localhost';
+DROP USER 'kristofer2'@'localhost';
+
+GRANT ALL ON *.* TO 'kristofer'@'localhost';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('');
+connect(con3,localhost,kristofer,,,,,SSL);
+connection con3;
+SELECT USER(),CURRENT_USER();
+--replace_regex /PASSWORD .*$/PASSWORD '<non-deterministic-password-hash>'/
+SHOW GRANTS FOR 'kristofer'@'localhost';
+connection default;
+disconnect con3;
+DROP USER 'kristofer'@'localhost';
+
+GRANT ALL ON *.* TO 'kristofer'@'33.33.33.33';
+SET PASSWORD FOR 'kristofer'@'33.33.33.33'=PASSWORD('');
+--echo Connection should fail for localhost
+--replace_result $MASTER_MYSOCK MASTER_MYSOCK
+--disable_query_log
+--error ER_ACCESS_DENIED_ERROR
+connect(con4,127.0.0.1,kristofer,,,,,SSL);
+--enable_query_log
+DROP USER 'kristofer'@'33.33.33.33';
+
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY 'awesomeness';
+connect(con3,localhost,kristofer,awesomeness,,,,SSL);
+connection con3;
+SELECT USER(),CURRENT_USER();
+--replace_regex /PASSWORD .*$/PASSWORD '<non-deterministic-password-hash>'/
+SHOW GRANTS FOR 'kristofer'@'localhost';
+connection default;
+disconnect con3;
+# Setting password for kristofer@localhost using old_passwords=0 will fail.
+SET @@OLD_PASSWORDS= 0;
+--error ER_PASSWORD_FORMAT
+SET PASSWORD FOR 'kristofer'@'localhost'= PASSWORD('error');
+DROP USER 'kristofer'@'localhost';
+
+

=== added file 'mysql-test/t/plugin_auth_sha256_tls.test'
--- a/mysql-test/t/plugin_auth_sha256_tls.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/plugin_auth_sha256_tls.test	2012-05-31 11:48:21 +0000
@@ -0,0 +1,51 @@
+--source include/not_embedded.inc
+--source include/have_ssl.inc
+
+connect (ssl_con,localhost,root,,,,,SSL);
+SHOW STATUS LIKE 'Ssl_cipher';
+
+CREATE USER 'kristofer' IDENTIFIED WITH 'sha256_password';
+SET GLOBAL old_passwords= 2;
+SET SESSION old_passwords= 2;
+SET PASSWORD FOR 'kristofer'=PASSWORD('secret');
+connect(con1,localhost,kristofer,secret,,,,SSL);
+connection con1;
+connection ssl_con;
+disconnect con1;
+DROP USER 'kristofer';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('secret2');
+connect(con2,localhost,kristofer,secret2,,,,SSL);
+connection con2;
+SELECT USER(),CURRENT_USER();
+--replace_regex /PASSWORD .*$/PASSWORD '<non-deterministic-password-hash>'/
+SHOW GRANTS FOR 'kristofer'@'localhost';
+connection ssl_con;
+disconnect con2;
+DROP USER 'kristofer'@'localhost';
+GRANT ALL ON *.* TO 'kristofer'@'localhost' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'localhost'=PASSWORD('');
+connect(con3,localhost,kristofer,,,,,SSL);
+connection con3;
+SELECT USER(),CURRENT_USER();
+--replace_regex /PASSWORD .*$/PASSWORD '<non-deterministic-password-hash>'/
+SHOW GRANTS FOR 'kristofer'@'localhost';
+connection ssl_con;
+disconnect con3;
+DROP USER 'kristofer'@'localhost';
+
+GRANT ALL ON *.* TO 'kristofer'@'33.33.33.33' IDENTIFIED WITH 'sha256_password';
+SET PASSWORD FOR 'kristofer'@'33.33.33.33'=PASSWORD('');
+--echo Connection should fail for localhost
+--replace_result $MASTER_MYSOCK MASTER_MYSOCK
+--disable_query_log
+--error ER_ACCESS_DENIED_ERROR
+connect(con4,127.0.0.1,kristofer,,,,,SSL);
+--enable_query_log
+DROP USER 'kristofer'@'33.33.33.33';
+# Restore default value to old_passwords
+SET GLOBAL old_passwords= default;
+connection default;
+disconnect ssl_con;
+
+

=== modified file 'sql-common/client.c'
--- a/sql-common/client.c	2012-05-31 15:33:21 +0000
+++ b/sql-common/client.c	2012-06-05 07:47:55 +0000
@@ -32,9 +32,9 @@
 */ 
 
 #include <my_global.h>
-
 #include "mysql.h"
 #include "hash.h"
+#include "mysql/client_authentication.h"
 
 /* Remove client convenience wrappers */
 #undef max_allowed_packet
@@ -2252,6 +2252,23 @@ static auth_plugin_t clear_password_clie
   clear_password_auth_client
 };
 
+#if defined(HAVE_OPENSSL)
+static auth_plugin_t sha256_password_client_plugin=
+{
+  MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
+  MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
+  "sha256_password",
+  "Oracle Inc",
+  "SHA256 based authentication with salt",
+  {1, 0, 0},
+  "GPL",
+  NULL,
+  sha256_password_init,
+  sha256_password_deinit,
+  NULL,
+  sha256_password_auth_client
+};
+#endif
 #ifdef AUTHENTICATION_WIN
 extern auth_plugin_t win_auth_client_plugin;
 #endif
@@ -2261,6 +2278,9 @@ struct st_mysql_client_plugin *mysql_cli
   (struct st_mysql_client_plugin *)&native_password_client_plugin,
   (struct st_mysql_client_plugin *)&old_password_client_plugin,
   (struct st_mysql_client_plugin *)&clear_password_client_plugin,
+#if defined(HAVE_OPENSSL)
+  (struct st_mysql_client_plugin *) &sha256_password_client_plugin,
+#endif
 #ifdef AUTHENTICATION_WIN
   (struct st_mysql_client_plugin *)&win_auth_client_plugin,
 #endif
@@ -2269,7 +2289,7 @@ struct st_mysql_client_plugin *mysql_cli
 
 
 static uchar *
-write_length_encoded_string(uchar *buf, char *string, size_t length)
+write_length_encoded_string3(uchar *buf, char *string, size_t length)
 {
   buf= net_store_length(buf, length);
   memcpy(buf, string, length);
@@ -2307,8 +2327,8 @@ send_client_connect_attrs(MYSQL *mysql, 
         /* we can't have zero length keys */
         DBUG_ASSERT(key->length);
 
-        buf= write_length_encoded_string(buf, key->str, key->length);
-        buf= write_length_encoded_string(buf, value->str, value->length);
+        buf= write_length_encoded_string3(buf, key->str, key->length);
+        buf= write_length_encoded_string3(buf, value->str, value->length);
       }
     }
   }
@@ -2346,6 +2366,30 @@ typedef struct {
   int last_read_packet_len;         /**< the length of the last *read* packet */
 } MCPVIO_EXT;
 
+
+/*
+  Write 1-8 bytes of string length header infromation to dest depending on
+  value of src_len, then copy src_len bytes from src to dest.
+ 
+ @param dest Destination buffer of size src_len+8
+ @param dest_end One byte past the end of the dest buffer
+ @param src Source buff of size src_len
+ @param src_end One byte past the end of the src buffer
+ 
+ @return pointer dest+src_len+header size or NULL if 
+*/
+
+char *write_length_encoded_string4(char *dest, char *dest_end, char *src,
+                                  char *src_end)
+{
+  size_t src_len= (size_t)(src_end - src);
+  uchar *to= net_store_length((uchar*) dest, src_len);
+  if ((char*)(to + src_len) >= dest_end)
+    return NULL;
+  memcpy(to, src, src_len);
+  return (char*)(to + src_len);
+}
+
 /**
   sends a COM_CHANGE_USER command with a caller provided payload
 
@@ -2448,7 +2492,7 @@ error:
     1           charset number
     23          reserved (always 0)
     n           user name, \0-terminated
-    n           plugin auth data (e.g. scramble), length (1 byte) coded
+    n           plugin auth data (e.g. scramble), length encoded
     n           database name, \0-terminated
                 (if CLIENT_CONNECT_WITH_DB is set in the capabilities)
     n           client auth plugin name - \0-terminated string,
@@ -2463,6 +2507,7 @@ static int send_client_reply_packet(MCPV
   MYSQL *mysql= mpvio->mysql;
   NET *net= &mysql->net;
   char *buff, *end;
+  size_t buff_size;
   size_t connect_attrs_len=
     (mysql->server_capabilities & CLIENT_CONNECT_ATTRS &&
      mysql->options.extension) ?
@@ -2470,9 +2515,13 @@ static int send_client_reply_packet(MCPV
 
   DBUG_ASSERT(connect_attrs_len < MAX_CONNECTION_ATTR_STORAGE_LENGTH);
 
-  /* see end= buff+32 below, fixed size of the packet is 32 bytes */
-  buff= my_alloca(33 + USERNAME_LENGTH + data_len + NAME_LEN + NAME_LEN +
-                  connect_attrs_len + 9 /* for the length of the attrs */);
+  
+  /*
+    see end= buff+32 below, fixed size of the packet is 32 bytes.
+     +9 because data is a length encoded binary where meta data size is max 9.
+  */
+  buff_size= 33 + USERNAME_LENGTH + data_len + 9 + NAME_LEN + NAME_LEN + connect_attrs_len + 9;
+  buff= my_alloca(buff_size);
 
   mysql->client_flag|= mysql->options.client_flag;
   mysql->client_flag|= CLIENT_CAPABILITIES;
@@ -2603,9 +2652,11 @@ static int send_client_reply_packet(MCPV
   {
     if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
     {
-      *end++= data_len;
-      memcpy(end, data, data_len);
-      end+= data_len;
+      end= write_length_encoded_string4(end, (char *)(buff + buff_size),
+                                       (char *) data,
+                                       (char *)(data + data_len));
+      if (end == NULL)
+        goto error;
     }
     else
     {
@@ -4272,6 +4323,9 @@ mysql_options(MYSQL *mysql,enum mysql_op
   case MYSQL_OPT_SSL_CRLPATH:  EXTENSION_SET_SSL_STRING(&mysql->options,
                                                         ssl_crlpath, arg);
                                break;
+  case MYSQL_SERVER_PUBLIC_KEY:
+    EXTENSION_SET_STRING(&mysql->options, server_public_key_path, arg);
+    break;
 
   case MYSQL_OPT_CONNECT_ATTR_RESET:
     ENSURE_EXTENSIONS_PRESENT(&mysql->options);

=== added file 'sql-common/client_authentication.cc'
--- a/sql-common/client_authentication.cc	1970-01-01 00:00:00 +0000
+++ b/sql-common/client_authentication.cc	2012-05-31 11:48:21 +0000
@@ -0,0 +1,233 @@
+#if defined(HAVE_OPENSSL)
+#include "crypt_genhash_impl.h"
+#include "mysql/client_authentication.h"
+#include "m_ctype.h"
+#include "sql_common.h"
+#include "errmsg.h"
+#include "sql_string.h"
+
+#include <string.h>
+#include <stdarg.h>
+#if !defined(HAVE_YASSL)
+#include <openssl/rsa.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#if defined(_WIN32) && !defined(_OPENSSL_Applink)
+#include <openssl/applink.c>
+#endif
+#endif
+#include "mysql/service_my_plugin_log.h"
+
+#define MAX_CIPHER_LENGTH 1024
+
+#if !defined(HAVE_YASSL)
+mysql_mutex_t g_public_key_mutex;
+#endif
+
+int sha256_password_init(char *a, size_t b, int c, va_list d)
+{
+#if !defined(HAVE_YASSL)
+  mysql_mutex_init(0,&g_public_key_mutex, MY_MUTEX_INIT_SLOW);
+#endif
+  return 0;
+}
+
+int sha256_password_deinit(void)
+{
+#if !defined(HAVE_YASSL)
+  mysql_mutex_destroy(&g_public_key_mutex);
+#endif
+  return 0;
+}
+
+
+#if !defined(HAVE_YASSL)
+/**
+  Reads and parse RSA public key data from a file.
+
+  @param mysql connection handle with file path data
+ 
+  @return Pointer to the RSA public key storage buffer
+*/
+
+RSA *rsa_init(MYSQL *mysql)
+{
+  static RSA *g_public_key= NULL;
+  RSA *key= NULL;
+
+  mysql_mutex_lock(&g_public_key_mutex);
+  key= g_public_key;
+  mysql_mutex_unlock(&g_public_key_mutex);
+
+  if (key != NULL)
+    return key;
+
+  FILE *pub_key_file= NULL;
+
+  if (mysql->options.extension != NULL &&
+      mysql->options.extension->server_public_key_path != NULL &&
+      mysql->options.extension->server_public_key_path != '\0')
+  {
+    pub_key_file= fopen(mysql->options.extension->server_public_key_path,
+                        "r");
+  }
+  /* No public key is used; return 0 without errors to indicate this. */
+  else
+    return 0;
+
+  if (pub_key_file == NULL)
+  {
+    /*
+      If a key path was submitted but no key located then we print an error
+      message. Else we just report that there is no public key.
+    */
+    fprintf(stderr,"Can't locate server public key '%s'\n",
+              mysql->options.extension->server_public_key_path);
+
+    return 0;
+  }
+  
+  mysql_mutex_lock(&g_public_key_mutex);
+  key= g_public_key= PEM_read_RSA_PUBKEY(pub_key_file, 0, 0, 0);
+  mysql_mutex_unlock(&g_public_key_mutex);
+  fclose(pub_key_file);
+  if (g_public_key == NULL)
+  {
+    fprintf(stderr, "Public key is not in PEM format: '%s'\n",
+            mysql->options.extension->server_public_key_path);
+    return 0;
+  }
+
+  return key;
+}
+#endif // !defined(HAVE_YASSL)
+
+/**
+  Authenticate the client using the RSA or TLS and a SHA256 salted password.
+ 
+  @param vio Provides plugin access to communication channel
+  @param mysql Client connection handler
+
+  @return Error status
+    @retval CR_ERROR An error occurred.
+    @retval CR_OK Authentication succeeded.
+*/
+
+extern "C"
+int sha256_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
+{
+  bool uses_password= mysql->passwd[0] != 0;
+#if !defined(HAVE_YASSL)
+  unsigned char encrypted_password[MAX_CIPHER_LENGTH];
+  static char request_public_key= '\1';
+  RSA *public_key= NULL;
+  bool got_public_key_from_server= false;
+#endif
+  bool connection_is_secure= false;
+  unsigned char scramble_pkt[20];
+  unsigned char *pkt;
+
+
+  DBUG_ENTER("sha256_password_auth_client");
+
+  /*
+    Get the scramble from the server because we need it when sending encrypted
+    password.
+  */
+  if (vio->read_packet(vio, &pkt) != SCRAMBLE_LENGTH)
+  {
+    DBUG_PRINT("info",("Scramble is not of correct length."));
+    DBUG_RETURN(CR_ERROR);
+  }
+  /*
+    Copy the scramble to the stack or it will be lost on the next use of the 
+    net buffer.
+  */
+  memcpy(scramble_pkt, pkt, SCRAMBLE_LENGTH);
+
+  if (mysql_get_ssl_cipher(mysql) != NULL)
+    connection_is_secure= true;
+  
+  /* If connection isn't secure attempt to get the RSA public key file */
+  if (!connection_is_secure)
+  {
+ #if !defined(HAVE_YASSL)
+    public_key= rsa_init(mysql);
+#endif
+  }
+
+  if (!uses_password)
+  {
+    /* We're not using a password */
+    static const unsigned char zero_byte= '\0'; 
+    if (vio->write_packet(vio, (const unsigned char *) &zero_byte, 1))
+      DBUG_RETURN(CR_ERROR);
+  }
+  else
+  {
+    /* Password is a 0-terminated byte array ('\0' character included) */
+    unsigned int passwd_len= strlen(mysql->passwd) + 1;
+    if (!connection_is_secure)
+    {
+#if !defined(HAVE_YASSL)
+      /*
+        If no public key; request one from the server.
+      */
+      if (public_key == NULL)
+      {
+        if (vio->write_packet(vio, (const unsigned char *) &request_public_key,
+                              1))
+          DBUG_RETURN(CR_ERROR);
+      
+        int pkt_len= 0;
+        unsigned char *pkt;
+        if ((pkt_len= vio->read_packet(vio, &pkt)) == -1)
+          DBUG_RETURN(CR_ERROR);
+        BIO* bio= BIO_new_mem_buf(pkt, pkt_len);
+        public_key= PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
+        BIO_free(bio);
+        if (public_key == 0)
+          DBUG_RETURN(CR_ERROR);
+        got_public_key_from_server= true;
+      }
+      
+      /* Obfuscate the plain text password with the session scramble */
+      xor_string(mysql->passwd, strlen(mysql->passwd), (char *) scramble_pkt,
+                 SCRAMBLE_LENGTH);
+      /* Encrypt the password and send it to the server */
+      int cipher_length= RSA_size(public_key);
+      /*
+        When using RSA_PKCS1_OAEP_PADDING the password length must be less
+        than RSA_size(rsa) - 41.
+      */
+      if (passwd_len + 41 >= (unsigned) cipher_length)
+      {
+        /* password message is to long */
+        DBUG_RETURN(CR_ERROR);
+      }
+      RSA_public_encrypt(passwd_len, (unsigned char *) mysql->passwd,
+                         encrypted_password,
+                         public_key, RSA_PKCS1_OAEP_PADDING);
+      if (got_public_key_from_server)
+        RSA_free(public_key);
+
+      if (vio->write_packet(vio, (uchar*) encrypted_password, cipher_length))
+        DBUG_RETURN(CR_ERROR);
+#else
+      DBUG_RETURN(CR_ERROR); // If no yassl support
+#endif
+    }
+    else
+    {
+      /* The vio is encrypted already; just send the plain text passwd */
+      if (vio->write_packet(vio, (uchar*) mysql->passwd, passwd_len))
+        DBUG_RETURN(CR_ERROR);
+    }
+    
+    memset(mysql->passwd, 0, passwd_len);
+  }
+    
+  DBUG_RETURN(CR_OK);
+}
+
+#endif

=== added file 'sql-common/crypt_genhash_impl.cc'
--- a/sql-common/crypt_genhash_impl.cc	1970-01-01 00:00:00 +0000
+++ b/sql-common/crypt_genhash_impl.cc	2012-05-21 23:00:55 +0000
@@ -0,0 +1,454 @@
+#ifdef HAVE_OPENSSL
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef HAVE_YASSL
+#include <sha.hpp>
+#include <openssl/ssl.h>
+#else
+#include <openssl/sha.h>
+#include <openssl/rand.h>
+#endif
+
+#include "crypt_genhash_impl.h"
+
+/* Pre VS2010 compilers doesn't support stdint.h */
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+#ifndef uint32_t
+typedef unsigned long uint32_t;
+#endif
+#ifndef uint8_t
+typedef unsigned char uint8_t;
+#endif
+#endif // !HAVE_STDINT_H
+
+#include <time.h>
+#include <string.h>
+
+
+
+#ifndef HAVE_YASSL
+#define	DIGEST_CTX	SHA256_CTX
+#define	DIGESTInit	SHA256_Init
+#define	DIGESTUpdate	SHA256_Update
+#define	DIGESTFinal	SHA256_Final
+#define	DIGEST_LEN	SHA256_DIGEST_LENGTH
+#else
+#define DIGEST_CTX TaoCrypt::SHA256
+#define DIGEST_LEN 32
+void DIGESTInit(DIGEST_CTX *ctx)
+{
+  ctx->Init();
+}
+
+void DIGESTUpdate(DIGEST_CTX *ctx, const void *plaintext, int len)
+{
+  ctx->Update((const TaoCrypt::byte *)plaintext, len);
+}
+
+void DIGESTFinal(void *txt, DIGEST_CTX *ctx)
+{
+  ctx->Final((TaoCrypt::byte *)txt);
+}
+
+#endif // HAVE_YASSL
+
+static const char crypt_alg_magic[] = "$5";
+
+#ifndef MAX
+#define MAX(a, b)  (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a, b)  (((a) < (b)) ? (a) : (b))
+#endif
+
+
+/**
+  Size-bounded string copying and concatenation
+  This is a replacement for STRLCPY(3)
+*/
+
+size_t
+strlcat(char *dst, const char *src, size_t siz)
+{
+  char *d= dst;
+  const char *s= src;
+  size_t n= siz;
+  size_t dlen;
+  /* Find the end of dst and adjust bytes left but don't go past end */
+  while (n-- != 0 && *d != '\0')
+    d++;
+  dlen= d - dst;
+  n= siz - dlen;
+  if (n == 0)
+    return(dlen + siz);
+  while (*s != '\0')
+  {
+    if (n != 1)
+    {
+      *d++= *s;
+      n--;
+    }
+    s++;
+  }
+  *d= '\0';
+  return(dlen + (s - src));       /* count does not include NUL */
+}
+
+static const int crypt_alg_magic_len = sizeof (crypt_alg_magic) - 1;
+
+static unsigned char b64t[] =		/* 0 ... 63 => ascii - 64 */
+	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+#define	b64_from_24bit(B2, B1, B0, N) \
+{ \
+	uint32_t w = ((B2) << 16) | ((B1) << 8) | (B0); \
+	int n = (N); \
+	while (--n >= 0 && ctbufflen > 0) { \
+		*p++ = b64t[w & 0x3f]; \
+		w >>= 6; \
+		ctbufflen--; \
+} \
+}
+
+#define	ROUNDS		"rounds="
+#define	ROUNDSLEN	(sizeof (ROUNDS) - 1)
+
+/**
+  Get the integer value after rounds= where ever it occurs in the string.
+  if the last char after the int is a , or $ that is fine anything else is an
+  error.
+*/
+static uint getrounds(const char *s)
+{
+  const char *r;
+  const char *p;
+  char *e;
+  long val;
+
+  if (s == NULL)
+    return (0);
+
+  if ((r = strstr(s, ROUNDS)) == NULL)
+  {
+    return (0);
+  }
+
+  if (strncmp(r, ROUNDS, ROUNDSLEN) != 0)
+  {
+    return (0);
+  }
+
+  p= r + ROUNDSLEN;
+  errno= 0;
+  val= strtol(p, &e, 10);
+  /*
+    An error occurred or there is non-numeric stuff at the end
+    which isn't one of the crypt(3c) special chars ',' or '$'
+  */
+  if (errno != 0 || val < 0 || !(*e == '\0' || *e == ',' || *e == '$'))
+  {
+    return (0);
+  }
+
+  return ((uint32_t) val);
+}
+
+/**
+  Finds the interval which envelopes the user salt in a crypt password
+  The crypt format is assumed to be $a$bbbb$cccccc\0 and the salt is found
+  by counting the delimiters and marking begin and end.
+
+   @param salt_being[in]  Pointer to start of crypt passwd
+   @param salt_being[out] Pointer to first byte of the salt
+   @param salt_end[in]    Pointer to the last byte in passwd
+   @param salt_end[out]   Pointer to the byte immediatly following the salt ($)
+
+   @return The size of the salt identified
+*/
+
+int extract_user_salt(char **salt_begin,
+                      char **salt_end)
+{
+  char *it= *salt_begin;
+  int delimiter_count= 0;
+  while(it != *salt_end)
+  {
+    if (*it == '$')
+    {
+      ++delimiter_count;
+      if (delimiter_count == 2)
+      {
+        *salt_begin= it + 1;
+      }
+      if (delimiter_count == 3)
+        break;
+    }
+    ++it;
+  }
+  *salt_end= it;
+  return *salt_end - *salt_begin;
+}
+
+const char *sha256_find_digest(char *pass)
+{
+  int sz= strlen(pass);
+  return pass + sz - SHA256_HASH_LENGTH;
+}
+
+/*
+ * Portions of the below code come from crypt_bsdmd5.so (bsdmd5.c) :
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@stripped> wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $FreeBSD: crypt.c,v 1.5 1996/10/14 08:34:02 phk Exp $
+ *
+ */
+
+/*
+ * The below code implements the specification from:
+ *
+ * From http://people.redhat.com/drepper/SHA-crypt.txt
+ *
+ * Portions of the code taken from inspired by or verified against the
+ * source in the above document which is licensed as:
+ *
+ * "Released into the Public Domain by Ulrich Drepper <drepper@stripped>."
+ */
+ 
+/*
+  Due to a Solaris namespace bug DS is a reserved word. To work around this
+  DS is undefined.
+*/
+#undef DS
+
+/* ARGSUSED4 */
+extern "C"
+char *
+my_crypt_genhash(char *ctbuffer,
+                   size_t ctbufflen,
+                   const char *plaintext,
+                   int plaintext_len,
+                   const char *switchsalt,
+                   const char **params)
+{
+  int salt_len, i;
+  char *salt;
+  unsigned char A[DIGEST_LEN];
+  unsigned char B[DIGEST_LEN];
+  unsigned char DP[DIGEST_LEN];
+  unsigned char DS[DIGEST_LEN];
+  DIGEST_CTX ctxA, ctxB, ctxC, ctxDP, ctxDS;
+  int rounds = ROUNDS_DEFAULT;
+  int srounds = 0;
+  bool custom_rounds= false;
+  char *p;
+  char *P, *Pp;
+  char *S, *Sp;
+
+  /* Refine the salt */
+  salt = (char *)switchsalt;
+
+  /* skip our magic string */
+  if (strncmp((char *)salt, crypt_alg_magic, crypt_alg_magic_len) == 0)
+  {
+          salt += crypt_alg_magic_len + 1;
+  }
+
+  srounds = getrounds(salt);
+  if (srounds != 0) {
+          rounds = MAX(ROUNDS_MIN, MIN(srounds, ROUNDS_MAX));
+          custom_rounds= true;
+          p = strchr(salt, '$');
+          if (p != NULL)
+                  salt = p + 1;
+  }
+
+  salt_len = MIN(strcspn(salt, "$"), CRYPT_SALT_LENGTH);
+  //plaintext_len = strlen(plaintext);
+
+  /* 1. */
+  DIGESTInit(&ctxA);
+
+  /* 2. The password first, since that is what is most unknown */
+  DIGESTUpdate(&ctxA, plaintext, plaintext_len);
+
+  /* 3. Then the raw salt */
+  DIGESTUpdate(&ctxA, salt, salt_len);
+
+  /* 4. - 8. */
+  DIGESTInit(&ctxB);
+  DIGESTUpdate(&ctxB, plaintext, plaintext_len);
+  DIGESTUpdate(&ctxB, salt, salt_len);
+  DIGESTUpdate(&ctxB, plaintext, plaintext_len);
+  DIGESTFinal(B, &ctxB);
+
+  /* 9. - 10. */
+  for (i= plaintext_len; i > MIXCHARS; i -= MIXCHARS)
+    DIGESTUpdate(&ctxA, B, MIXCHARS);
+  DIGESTUpdate(&ctxA, B, i);
+
+  /* 11. */
+  for (i= plaintext_len; i > 0; i >>= 1) {
+    if ((i & 1) != 0)
+    {
+      DIGESTUpdate(&ctxA, B, MIXCHARS);
+    }
+    else
+    {
+      DIGESTUpdate(&ctxA, plaintext, plaintext_len);
+    }
+  }
+
+  /* 12. */
+  DIGESTFinal(A, &ctxA);
+
+  /* 13. - 15. */
+  DIGESTInit(&ctxDP);
+  for (i= 0; i < plaintext_len; i++)
+          DIGESTUpdate(&ctxDP, plaintext, plaintext_len);
+  DIGESTFinal(DP, &ctxDP);
+
+  /* 16. */
+  Pp= P= (char *)alloca(plaintext_len);
+  for (i= plaintext_len; i >= MIXCHARS; i -= MIXCHARS)
+  {
+          Pp= (char *)(memcpy(Pp, DP, MIXCHARS)) + MIXCHARS;
+  }
+  (void) memcpy(Pp, DP, i);
+
+  /* 17. - 19. */
+  DIGESTInit(&ctxDS);
+  for (i= 0; i < 16 + (uint8_t)A[0]; i++)
+          DIGESTUpdate(&ctxDS, salt, salt_len);
+  DIGESTFinal(DS, &ctxDS);
+
+  /* 20. */
+  Sp= S= (char *)alloca(salt_len);
+  for (i= salt_len; i >= MIXCHARS; i -= MIXCHARS)
+  {
+          Sp= (char *)(memcpy(Sp, DS, MIXCHARS)) + MIXCHARS;
+  }
+  (void) memcpy(Sp, DS, i);
+
+  /*  21. */
+  for (i= 0; i < rounds; i++)
+  {
+  DIGESTInit(&ctxC);
+
+    if ((i & 1) != 0)
+    {
+      DIGESTUpdate(&ctxC, P, plaintext_len);
+    }
+    else
+    {
+      if (i == 0)
+        DIGESTUpdate(&ctxC, A, MIXCHARS);
+      else
+        DIGESTUpdate(&ctxC, DP, MIXCHARS);
+    }
+
+    if (i % 3 != 0) {
+      DIGESTUpdate(&ctxC, S, salt_len);
+    }
+
+    if (i % 7 != 0) {
+      DIGESTUpdate(&ctxC, P, plaintext_len);
+    }
+
+    if ((i & 1) != 0)
+    {
+      if (i == 0)
+        DIGESTUpdate(&ctxC, A, MIXCHARS);
+      else
+        DIGESTUpdate(&ctxC, DP, MIXCHARS);
+    }
+    else
+    {
+        DIGESTUpdate(&ctxC, P, plaintext_len);
+    }
+    DIGESTFinal(DP, &ctxC);
+  }
+
+  /* 22. Now make the output string */
+  if (custom_rounds)
+  {
+    (void) snprintf(ctbuffer, ctbufflen,
+                    "%s$rounds=%zu$", crypt_alg_magic, (size_t)rounds);
+  }
+  else
+  {
+    (void) snprintf(ctbuffer, ctbufflen,
+                    "%s$", crypt_alg_magic);
+  }
+  (void) strncat(ctbuffer, (const char *)salt, salt_len);
+  (void) strlcat(ctbuffer, "$", ctbufflen);
+
+  p= ctbuffer + strlen(ctbuffer);
+  ctbufflen -= strlen(ctbuffer);
+
+  b64_from_24bit(DP[ 0], DP[10], DP[20], 4);
+  b64_from_24bit(DP[21], DP[ 1], DP[11], 4);
+  b64_from_24bit(DP[12], DP[22], DP[ 2], 4);
+  b64_from_24bit(DP[ 3], DP[13], DP[23], 4);
+  b64_from_24bit(DP[24], DP[ 4], DP[14], 4);
+  b64_from_24bit(DP[15], DP[25], DP[ 5], 4);
+  b64_from_24bit(DP[ 6], DP[16], DP[26], 4);
+  b64_from_24bit(DP[27], DP[ 7], DP[17], 4);
+  b64_from_24bit(DP[18], DP[28], DP[ 8], 4);
+  b64_from_24bit(DP[ 9], DP[19], DP[29], 4);
+  b64_from_24bit(0, DP[31], DP[30], 3);
+  *p= '\0';
+
+  (void) memset(A, 0, sizeof (A));
+  (void) memset(B, 0, sizeof (B));
+  (void) memset(DP, 0, sizeof (DP));
+  (void) memset(DS, 0, sizeof (DS));
+
+  return (ctbuffer);
+}
+
+
+/**
+  Generate a random string using ASCII characters but avoid seperator character.
+  Stdlib rand and srand are used to produce pseudo random numbers between 
+  with about 7 bit worth of entropty between 1-127.
+*/
+extern "C"
+void generate_user_salt(char *buffer, int buffer_len)
+{
+  char *end= buffer + buffer_len - 1;
+#ifdef HAVE_YASSL
+  yaSSL::RAND_bytes((unsigned char *) buffer, buffer_len);
+#else
+  RAND_bytes((unsigned char *) buffer, buffer_len);
+#endif
+      
+  /* Sequence must be a legal UTF8 string */
+  for (; buffer < end; buffer++)
+  { 
+    *buffer &= 0x7f;
+    if (*buffer == '\0' || *buffer == '$')
+      *buffer= *buffer + 1;
+  }
+  /* Make sure the buffer is terminated properly */
+  *end= '\0';
+}
+
+void xor_string(char *to, int to_len, char *pattern, int pattern_len)
+{
+  int loop= 0;
+  while(loop <= to_len)
+  {
+    *(to + loop) ^= *(pattern + loop % pattern_len);
+    ++loop;
+  }
+}
+
+#endif // HAVE_OPENSSL

=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt	2012-05-31 15:33:21 +0000
+++ b/sql/CMakeLists.txt	2012-06-04 15:35:18 +0000
@@ -99,6 +99,7 @@ SET(SQL_SHARED_SOURCES
   parse_file.cc
   partition_info.cc
   password.c
+  ../sql-common/crypt_genhash_impl.cc
   procedure.cc 
   protocol.cc
   records.cc
@@ -199,6 +200,7 @@ SET(SQL_SOURCE
   ../sql-common/my_time.c
   ../sql-common/my_user.c 
   ../sql-common/pack.c
+  ../sql-common/client_authentication.cc
   event_data_objects.cc
   event_db_repository.cc 
   event_parse_data.cc

=== modified file 'sql/client_settings.h'
--- a/sql/client_settings.h	2012-03-30 16:01:10 +0000
+++ b/sql/client_settings.h	2012-06-04 15:35:18 +0000
@@ -35,6 +35,7 @@
                              CLIENT_PROTOCOL_41 |   \
                              CLIENT_SECURE_CONNECTION | \
                              CLIENT_PLUGIN_AUTH | \
+                             CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA | \
                              CLIENT_CONNECT_ATTRS)
 
 #define read_user_name(A) {}

=== modified file 'sql/item_strfunc.cc'
--- a/sql/item_strfunc.cc	2012-05-30 09:18:58 +0000
+++ b/sql/item_strfunc.cc	2012-06-04 15:35:18 +0000
@@ -45,6 +45,7 @@
 #include "des_key_file.h"       // st_des_keyschedule, st_des_keyblock
 #include "password.h"           // my_make_scrambled_password,
                                 // my_make_scrambled_password_323
+#include "crypt_genhash_impl.h"
 #include <m_ctype.h>
 #include <base64.h>
 #include "my_md5.h"
@@ -1917,33 +1918,123 @@ void Item_func_trim::print(String *str, 
 }
 
 
+/**
+  Helper function for calculating a new password. Used in 
+  Item_func_password::fix_length_and_dec() for const parameters and in 
+  Item_func_password::val_str_ascii() for non-const parameters.
+  @param str The plain text password which should be digested
+  @param buffer a pointer to the buffer where the digest will be stored.
+
+  @note The buffer must be of at least CRYPT_MAX_PASSWORD_SIZE size.
+
+  @return Size of the password.
+*/
+
+static int calculate_password(String *str, char *buffer)
+{
+  DBUG_ASSERT(str);
+  if (str->length() == 0) // PASSWORD('') returns ''
+    return 0;
+  
+  int buffer_len= 0;
+  THD *thd= current_thd;
+  int old_passwords= 0;
+  if (thd)
+    old_passwords= thd->variables.old_passwords;
+  
+#if defined(HAVE_OPENSSL)
+  if (old_passwords == 2)
+  {
+    my_make_scrambled_password(buffer, str->ptr(),
+                               str->length());
+    buffer_len= (int) strlen(buffer) + 1;
+  }
+  else
+#endif
+  if (old_passwords == 0)
+  {
+    my_make_scrambled_password_sha1(buffer, str->ptr(),
+                                    str->length());
+    buffer_len= SCRAMBLED_PASSWORD_CHAR_LENGTH;
+  }
+  else
+  if (old_passwords == 1)
+  {
+    my_make_scrambled_password_323(buffer, str->ptr(),
+                                   str->length());
+    buffer_len= SCRAMBLED_PASSWORD_CHAR_LENGTH_323;
+  }
+  return buffer_len;
+}
+
 /* Item_func_password */
+void Item_func_password::fix_length_and_dec()
+{
+  maybe_null= false; // PASSWORD() never returns NULL
+  
+  if (args[0]->const_item())
+  {
+    String str;
+    String *res= args[0]->val_str(&str);
+    if (!args[0]->null_value)
+    {
+      m_hashed_password_buffer_len=
+        calculate_password(res, m_hashed_password_buffer);
+      fix_length_and_charset(m_hashed_password_buffer_len, default_charset());
+      m_recalculate_password= false;
+      return;
+    }
+  }
+
+  m_recalculate_password= true;
+  fix_length_and_charset(CRYPT_MAX_PASSWORD_SIZE, default_charset());
+}
 
 String *Item_func_password::val_str_ascii(String *str)
 {
   DBUG_ASSERT(fixed == 1);
-  String *res= args[0]->val_str(str); 
-  if ((null_value=args[0]->null_value))
-    return 0;
+
+  String *res= args[0]->val_str(str);
   check_password_policy(res);
-  if (res->length() == 0)
+  null_value= 0;
+  if (args[0]->null_value)  // PASSWORD(NULL) returns ''
+    return make_empty_result();
+  
+  if (m_recalculate_password)
+    m_hashed_password_buffer_len= calculate_password(res,
+                                                     m_hashed_password_buffer);
+
+  if (m_hashed_password_buffer_len == 0)
     return make_empty_result();
-  my_make_scrambled_password(tmp_value, res->ptr(), res->length());
-  str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, &my_charset_latin1);
+
+  str->set(m_hashed_password_buffer, m_hashed_password_buffer_len,
+           default_charset());
+
   return str;
 }
 
-char *Item_func_password::alloc(THD *thd, const char *password,
-                                size_t pass_len)
+char *Item_func_password::
+  create_password_hash_buffer(THD *thd, const char *password,  size_t pass_len)
 {
-  char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
-  if (buff)
-  {
-    String *password_str= new (thd->mem_root)String(password, thd->variables.
+  String *password_str= new (thd->mem_root)String(password, thd->variables.
                                                     character_set_client);
-    check_password_policy(password_str);
+  check_password_policy(password_str);
+
+  char *buff= NULL;
+  if (thd->variables.old_passwords == 0)
+  {
+    /* Allocate memory for the password scramble and one extra byte for \0 */
+    buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH + 1);
+    my_make_scrambled_password_sha1(buff, password, pass_len);
+  }
+#if defined(HAVE_OPENSSL)
+  else
+  {
+    /* Allocate memory for the password scramble and one extra byte for \0 */
+    buff= (char *) thd->alloc(CRYPT_MAX_PASSWORD_SIZE + 1);
     my_make_scrambled_password(buff, password, pass_len);
   }
+#endif
   return buff;
 }
 

=== modified file 'sql/item_strfunc.h'
--- a/sql/item_strfunc.h	2012-05-16 06:42:17 +0000
+++ b/sql/item_strfunc.h	2012-06-04 15:35:18 +0000
@@ -18,6 +18,7 @@
 
 
 /* This file defines all string functions */
+#include "crypt_genhash_impl.h"
 
 class MY_LOCALE;
 
@@ -327,16 +328,20 @@ public:
 
 class Item_func_password :public Item_str_ascii_func
 {
-  char tmp_value[SCRAMBLED_PASSWORD_CHAR_LENGTH+1]; 
+  char m_hashed_password_buffer[CRYPT_MAX_PASSWORD_SIZE + 1];
+  unsigned int m_hashed_password_buffer_len;
+  bool m_recalculate_password;
 public:
-  Item_func_password(Item *a) :Item_str_ascii_func(a) {}
-  String *val_str_ascii(String *str);
-  void fix_length_and_dec()
+  Item_func_password(Item *a) : Item_str_ascii_func(a)
   {
-    fix_length_and_charset(SCRAMBLED_PASSWORD_CHAR_LENGTH, default_charset());
+    m_hashed_password_buffer_len= 0;
+    m_recalculate_password= false;
   }
+  String *val_str_ascii(String *str);
+  void fix_length_and_dec();
   const char *func_name() const { return "password"; }
-  static char *alloc(THD *thd, const char *password, size_t pass_len);
+  static char *create_password_hash_buffer(THD *thd, const char *password,
+                                           size_t pass_len);
 };
 
 

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2012-06-05 06:42:20 +0000
+++ b/sql/mysqld.cc	2012-06-05 07:56:01 +0000
@@ -756,6 +756,12 @@ static char **remaining_argv;
 int orig_argc;
 char **orig_argv;
 
+#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)
+int init_rsa_keys(void);
+void deinit_rsa_keys(void);
+int show_rsa_public_key(THD *thd, SHOW_VAR *var, char *buff);
+#endif
+
 static volatile sig_atomic_t global_thread_count= 0;
 static std::set<THD*> *global_thread_list= NULL;
 
@@ -3513,6 +3519,8 @@ int init_common_variables()
 #endif
   default_tmp_storage_engine= default_storage_engine;
 
+  init_default_auth_plugin();
+
   /*
     Add server status variables to the dynamic list of
     status variables that is shown by SHOW STATUS.
@@ -4027,9 +4035,12 @@ static void openssl_lock(int mode, opens
 #endif /* HAVE_OPENSSL */
 
 
-static void init_ssl()
+static int init_ssl()
 {
 #ifdef HAVE_OPENSSL
+#ifndef HAVE_YASSL
+  CRYPTO_malloc_init();
+#endif
 #ifndef EMBEDDED_LIBRARY
   if (opt_use_ssl)
   {
@@ -4058,7 +4069,12 @@ static void init_ssl()
 #endif /* ! EMBEDDED_LIBRARY */
   if (des_key_file)
     load_des_key_file(des_key_file);
+#ifndef HAVE_YASSL
+  if (init_rsa_keys())
+    return 1;
+#endif
 #endif /* HAVE_OPENSSL */
+  return 0;
 }
 
 
@@ -4072,6 +4088,9 @@ static void end_ssl()
     ssl_acceptor_fd= 0;
   }
 #endif /* ! EMBEDDED_LIBRARY */
+#ifndef HAVE_YASSL
+  deinit_rsa_keys();
+#endif
 #endif /* HAVE_OPENSSL */
 }
 
@@ -5152,7 +5171,8 @@ int mysqld_main(int argc, char **argv)
     }
   }
 
-  init_ssl();
+  if (init_ssl())
+    return 1;
   network_init();
 
 #ifdef __WIN__
@@ -6867,6 +6887,10 @@ struct my_option my_long_options[]=
    "Multiple --plugin-load-add are supported.",
    0, 0, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"default_authentication_plugin", OPT_DEFAULT_AUTH,
+   "Defines what password- and authentication algorithm to use per default",
+   0, 0, 0,
+   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 
@@ -7529,6 +7553,9 @@ SHOW_VAR status_vars[]= {
     SHOW_FUNC},
   {"Ssl_server_not_after",     (char*) &show_ssl_get_server_not_after,
     SHOW_FUNC},
+#ifndef HAVE_YASSL
+  {"Rsa_public_key",           (char*) &show_rsa_public_key, SHOW_FUNC},
+#endif
 #endif
 #endif /* HAVE_OPENSSL */
   {"Table_locks_immediate",    (char*) &locks_immediate,        SHOW_LONG},
@@ -8135,7 +8162,9 @@ mysqld_get_one_option(int optid,
   case OPT_PLUGIN_LOAD_ADD:
     opt_plugin_load_list_ptr->push_back(new i_string(argument));
     break;
-
+  case OPT_DEFAULT_AUTH:
+    set_default_auth_plugin(argument, strlen(argument));
+    break;
   case OPT_PFS_INSTRUMENT:
 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
 #ifndef EMBEDDED_LIBRARY

=== modified file 'sql/mysqld.h'
--- a/sql/mysqld.h	2012-06-04 14:12:37 +0000
+++ b/sql/mysqld.h	2012-06-05 07:56:01 +0000
@@ -621,7 +621,8 @@ enum options_mysqld
   OPT_PLUGIN_LOAD_ADD,
   OPT_SSL_CRL,
   OPT_SSL_CRLPATH,
-  OPT_PFS_INSTRUMENT
+  OPT_PFS_INSTRUMENT,
+  OPT_DEFAULT_AUTH
 };
 
 

=== modified file 'sql/password.c'
--- a/sql/password.c	2012-05-09 16:53:03 +0000
+++ b/sql/password.c	2012-06-04 15:35:18 +0000
@@ -66,6 +66,7 @@
 #include <sha1.h>
 #include <my_rnd.h>
 #include "mysql.h"
+#include "crypt_genhash_impl.h"
 
 /************ MySQL 3.23-4.0 authentication routines: untouched ***********/
 
@@ -307,14 +308,13 @@ void make_password_from_salt_323(char *t
      **************** MySQL 4.1.1 authentication routines *************
 */
 
-/*
-    Generate string of printable random characters of requested length
-  SYNOPSIS
-    create_random_string()
-    to       OUT   buffer for generation; must be at least length+1 bytes
-                   long; result string is always null-terminated
-    length   IN    how many random characters to put in buffer
-    rand_st  INOUT structure used for number generation
+/**
+    Generate string of printable random characters of requested length.
+  
+    @param to[out]  Buffer for generation; must be at least length+1 bytes
+                    long; result string is always null-terminated
+    length[in]      How many random characters to put in buffer
+    rand_st         Structure used for number generation
 */
 
 void create_random_string(char *to, uint length, struct rand_struct *rand_st)
@@ -399,6 +399,23 @@ my_crypt(char *to, const uchar *s1, cons
     *to++= *s1++ ^ *s2++;
 }
 
+#if defined(HAVE_OPENSSL)
+void my_make_scrambled_password(char *to, const char *password,
+                                size_t pass_len)
+{
+
+  char salt[CRYPT_SALT_LENGTH + 1];
+  
+  generate_user_salt(salt, CRYPT_SALT_LENGTH + 1);
+  my_crypt_genhash(to,
+                     CRYPT_MAX_PASSWORD_SIZE,
+                     password,
+                     pass_len,
+                     salt,
+                     0);
+
+}
+#endif
 /**
   Compute two stage SHA1 hash of the password :
 
@@ -430,14 +447,14 @@ void compute_two_stage_sha1_hash(const c
     The result of this function is used as return value from PASSWORD() and
     is stored in the database.
   SYNOPSIS
-    my_make_scrambled_password()
+    my_make_scrambled_password_sha1()
     buf       OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string
     password  IN  password string
     pass_len  IN  length of password string
 */
 
-void my_make_scrambled_password(char *to, const char *password,
-                                size_t pass_len)
+void my_make_scrambled_password_sha1(char *to, const char *password,
+                                     size_t pass_len)
 {
   uint8 hash_stage2[SHA1_HASH_SIZE];
 
@@ -463,7 +480,7 @@ void my_make_scrambled_password(char *to
 
 void make_scrambled_password(char *to, const char *password)
 {
-  my_make_scrambled_password(to, password, strlen(password));
+  my_make_scrambled_password_sha1(to, password, strlen(password));
 }
 
 
@@ -508,7 +525,7 @@ scramble(char *to, const char *message, 
     null-terminated, reply and hash_stage2 must be at least SHA1_HASH_SIZE
     long (if not, something fishy is going on).
   SYNOPSIS
-    check_scramble()
+    check_scramble_sha1()
     scramble     clients' reply, presumably produced by scramble()
     message      original random string, previously sent to client
                  (presumably second argument of scramble()), must be 
@@ -522,8 +539,8 @@ scramble(char *to, const char *message, 
 */
 
 my_bool
-check_scramble(const uchar *scramble_arg, const char *message,
-               const uint8 *hash_stage2)
+check_scramble_sha1(const uchar *scramble_arg, const char *message,
+                    const uint8 *hash_stage2)
 {
   uint8 buf[SHA1_HASH_SIZE];
   uint8 hash_stage2_reassured[SHA1_HASH_SIZE];
@@ -540,6 +557,12 @@ check_scramble(const uchar *scramble_arg
   return test(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE));
 }
 
+my_bool
+check_scramble(const uchar *scramble_arg, const char *message,
+               const uint8 *hash_stage2)
+{
+  return check_scramble_sha1(scramble_arg, message, hash_stage2);
+}
 
 /*
   Convert scrambled password from asciiz hex string to binary form.
@@ -569,3 +592,4 @@ void make_password_from_salt(char *to, c
   *to++= PVERSION41_CHAR;
   octet2hex(to, (const char*) hash_stage2, SHA1_HASH_SIZE);
 }
+

=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc	2012-04-18 18:38:45 +0000
+++ b/sql/set_var.cc	2012-04-20 15:14:24 +0000
@@ -772,7 +772,7 @@ int set_var_password::check(THD *thd)
       user->host.length= 1;
     }
   }
-  if (!user->user.str)
+  if (user->user.length == 0)
   {
     DBUG_ASSERT(thd->security_ctx->user);
     user->user.str= (char *) thd->security_ctx->user;

=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt	2012-05-29 09:49:15 +0000
+++ b/sql/share/errmsg-utf8.txt	2012-06-04 15:35:18 +0000
@@ -6631,6 +6631,7 @@ ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_I
         eng "Foreign key constraint for table '%.192s', record '%-.192s' would lead to a duplicate entry in a child table"
         ger "Fremdschlüssel-Beschränkung für Tabelle '%.192s', Datensatz '%-.192s' würde zu einem doppelten Eintrag in einer Kind-Tabelle führen"
         swe "FOREIGN KEY constraint för tabell '%.192s', posten '%-.192s' kan inte uppdatera en barntabell på grund av UNIQUE-test"
+
 ER_SQLTHREAD_WITH_SECURE_SLAVE
   eng "Setting authentication options is not possible when only the Slave SQL Thread is being started."
 
@@ -6827,6 +6828,8 @@ ER_FK_INCORRECT_OPTION
 ER_FK_DUP_NAME
 	eng "Duplicate foreign key constraint name '%s'"
 
+ER_PASSWORD_FORMAT
+  eng "The password hash doesn't have the expected format. Check if the correct password algorithm is being used with the PASSWORD() function."
 #
 #  End of 5.6 error messages.
 #

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2012-05-29 07:07:08 +0000
+++ b/sql/sql_acl.cc	2012-06-04 15:35:18 +0000
@@ -24,6 +24,7 @@
   in the relevant fields. Empty strings comes last.
 */
 
+
 #include "my_global.h"                          /* NO_EMBEDDED_ACCESS_CHECKS */
 #include "sql_priv.h"
 #include "sql_acl.h"         // MYSQL_DB_FIELD_COUNT, ACL_ACCESS
@@ -50,11 +51,22 @@
 #include "hostname.h"
 #include "sql_db.h"
 #include <mysql/plugin_validate_password.h>
+#include "password.h"
+#include "crypt_genhash_impl.h"
+
+#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)
+#include <openssl/rsa.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#endif
 
 using std::min;
 using std::max;
 
 bool mysql_user_table_is_in_short_password_format= false;
+bool auth_plugin_is_built_in(const char *plugin_name);
+void optimize_plugin_compare_by_pointer(LEX_STRING *plugin_name);
+
 
 static const
 TABLE_FIELD_TYPE mysql_db_table_fields[MYSQL_DB_FIELD_COUNT] = {
@@ -170,9 +182,221 @@ TABLE_FIELD_TYPE mysql_db_table_fields[M
   }
 };
 
+static const
+TABLE_FIELD_TYPE mysql_user_table_fields[MYSQL_USER_FIELD_COUNT] = {
+  {
+    { C_STRING_WITH_LEN("Host") },            
+    { C_STRING_WITH_LEN("char(60)") },
+    { NULL, 0 }
+  },
+  {
+    { C_STRING_WITH_LEN("User") },            
+    { C_STRING_WITH_LEN("char(16)") },
+    { NULL, 0 }
+  },
+  {
+    { C_STRING_WITH_LEN("Password") },            
+    { C_STRING_WITH_LEN("char(41)") },
+    { C_STRING_WITH_LEN("latin1") }
+  }, 
+  {
+    { C_STRING_WITH_LEN("Select_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  {
+    { C_STRING_WITH_LEN("Insert_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  {
+    { C_STRING_WITH_LEN("Update_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  {
+    { C_STRING_WITH_LEN("Delete_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  {
+    { C_STRING_WITH_LEN("Create_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  {
+    { C_STRING_WITH_LEN("Drop_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  {
+    { C_STRING_WITH_LEN("Reload_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  {
+    { C_STRING_WITH_LEN("Shutdown_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Process_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("File_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Grant_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("References_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Index_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Alter_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Show_db_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Super_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Create_tmp_table_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Lock_tables_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Execute_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Repl_slave_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Repl_client_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Create_view_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Show_view_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Create_routine_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Alter_routine_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Create_user_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Event_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Trigger_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("Create_tablespace_priv") },
+    { C_STRING_WITH_LEN("enum('N','Y')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("ssl_type") },
+    { C_STRING_WITH_LEN("enum('','ANY','X509','SPECIFIED')") },
+    { C_STRING_WITH_LEN("utf8") }
+  },
+  { 
+    { C_STRING_WITH_LEN("ssl_cipher") },
+    { C_STRING_WITH_LEN("blob") },
+    { NULL, 0 }
+  },
+  { 
+    { C_STRING_WITH_LEN("x509_issuer") },
+    { C_STRING_WITH_LEN("blob") },
+    { NULL, 0 }
+  },
+  { 
+    { C_STRING_WITH_LEN("x509_subject") },
+    { C_STRING_WITH_LEN("blob") },
+    { NULL, 0 }
+  },
+  { 
+    { C_STRING_WITH_LEN("max_questions") },
+    { C_STRING_WITH_LEN("int(11)") },
+    { NULL, 0 }
+  },
+  { 
+    { C_STRING_WITH_LEN("max_updates") },
+    { C_STRING_WITH_LEN("int(11)") },
+    { NULL, 0 }
+  },
+  { 
+    { C_STRING_WITH_LEN("max_connections") },
+    { C_STRING_WITH_LEN("int(11)") },
+    { NULL, 0 }
+  },
+  { 
+    { C_STRING_WITH_LEN("plugin") },
+    { C_STRING_WITH_LEN("char(64)") },
+    { NULL, 0 }
+  },
+  { 
+    { C_STRING_WITH_LEN("authentication_string") },
+    { C_STRING_WITH_LEN("text") },
+    { NULL, 0 }
+  } 
+};
+
 const TABLE_FIELD_DEF
   mysql_db_table_def= {MYSQL_DB_FIELD_COUNT, mysql_db_table_fields};
 
+const TABLE_FIELD_DEF
+  mysql_user_table_def= {MYSQL_USER_FIELD_COUNT, mysql_user_table_fields};
+
 static LEX_STRING native_password_plugin_name= {
   C_STRING_WITH_LEN("mysql_native_password")
 };
@@ -180,13 +404,17 @@ static LEX_STRING native_password_plugin
 static LEX_STRING old_password_plugin_name= {
   C_STRING_WITH_LEN("mysql_old_password")
 };
-  
+
+#if defined(HAVE_OPENSSL)
+LEX_STRING sha256_password_plugin_name= {
+  C_STRING_WITH_LEN("sha256_password")
+};
+#endif
 static LEX_STRING validate_password_plugin_name= {
   C_STRING_WITH_LEN("validate_password")
 };
-
-/// @todo make it configurable
-LEX_STRING *default_auth_plugin_name= &native_password_plugin_name;
+  
+LEX_STRING default_auth_plugin_name;
 
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
 static plugin_ref old_password_plugin;
@@ -308,8 +536,16 @@ class ACL_USER :public ACL_ACCESS
 public:
   USER_RESOURCES user_resource;
   char *user;
+  /**
+    The salt variable is used as the password hash for
+    native_password_authetication and old_password_authentication.
+  */
   uint8 salt[SCRAMBLE_LENGTH + 1];       // scrambled password in binary form
-  uint8 salt_len;        // 0 - no password, 4 - 3.20, 8 - 4.0,  20 - 4.1.1 
+  /**
+    In the old protocol the salt_len indicated what type of autnetication
+    protocol was used: 0 - no password, 4 - 3.20, 8 - 4.0,  20 - 4.1.1
+  */
+  uint8 salt_len;
   enum SSL_type ssl_type;
   const char *ssl_cipher, *x509_issuer, *x509_subject;
   LEX_STRING plugin;
@@ -326,11 +562,17 @@ public:
     dst->ssl_cipher= safe_strdup_root(root, ssl_cipher);
     dst->x509_issuer= safe_strdup_root(root, x509_issuer);
     dst->x509_subject= safe_strdup_root(root, x509_subject);
-    if (plugin.str == native_password_plugin_name.str ||
-        plugin.str == old_password_plugin_name.str)
+    /*
+      If the plugin is built in we don't need to reallocate the name of the
+      plugin.
+    */
+    if (auth_plugin_is_built_in(dst->plugin.str))
       dst->plugin= plugin;
     else
+    {
       dst->plugin.str= strmake_root(root, plugin.str, plugin.length);
+      dst->plugin.length= plugin.length;
+    }
     dst->auth_string.str= safe_strdup_root(root, auth_string.str);
     dst->host.update_hostname(safe_strdup_root(root, host.get_host()));
     return dst;
@@ -349,6 +591,7 @@ static ulong get_sort(uint count,...);
 static bool show_proxy_grants (THD *thd, LEX_USER *user,
                                char *buff, size_t buffsize);
 
+
 class ACL_PROXY_USER :public ACL_ACCESS
 {
   const char *user;
@@ -605,7 +848,7 @@ static uchar* acl_entry_get_key(acl_entr
 #define AUTH_PACKET_HEADER_SIZE_PROTO_40    5  
 
 static DYNAMIC_ARRAY acl_hosts, acl_users, acl_dbs, acl_proxy_users;
-static MEM_ROOT mem, memex;
+static MEM_ROOT global_acl_memory, memex;
 static bool initialized=0;
 static bool allow_all_hosts=1;
 static HASH acl_check_hosts, column_priv_hash, proc_priv_hash, func_priv_hash;
@@ -619,23 +862,33 @@ static void init_check_host(void);
 static void rebuild_check_host(void);
 static ACL_USER *find_acl_user(const char *host, const char *user,
                                my_bool exact);
-static bool update_user_table(THD *thd, TABLE *table,
-                              const char *host, const char *user,
-			      const char *new_password, uint new_password_len,
+static bool update_user_table(THD *, TABLE *table, const char *host,
+                              const char *user,
+                              const char *new_password,
+                              uint new_password_len,
+                              enum mysql_user_table_field password_field,
                               const char must_expire);
 static my_bool acl_load(THD *thd, TABLE_LIST *tables);
 static my_bool grant_load(THD *thd, TABLE_LIST *tables);
 static inline void get_grantor(THD *thd, char* grantor);
 
-/*
+/**
   Convert scrambled password to binary form, according to scramble type, 
   Binary form is stored in user.salt.
+  
+  @param acl_user The object where to store the salt
+  @param password The password hash containing the salt
+  @param password_len The length of the password hash
+   
+  Despite the name of the function it is used when loading ACLs from disk
+  to store the password hash in the ACL_USER object.
 */
 
 static
 void
 set_user_salt(ACL_USER *acl_user, const char *password, uint password_len)
 {
+  /* Using old password protocol */
   if (password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH)
   {
     get_salt_from_password(acl_user->salt, password);
@@ -721,38 +974,6 @@ my_bool acl_init(bool dont_read_acl_tabl
   DBUG_RETURN(return_val);
 }
 
-/**
-  Choose from either native or old password plugins when assigning a password
-*/
-
-static bool
-set_user_plugin (ACL_USER *user, int password_len)
-{
-  switch (password_len) 
-  {
-  case 0: /* no password */
-  case SCRAMBLED_PASSWORD_CHAR_LENGTH:
-    user->plugin= native_password_plugin_name;
-    return FALSE;
-  case SCRAMBLED_PASSWORD_CHAR_LENGTH_323:
-    user->plugin= old_password_plugin_name;
-    return FALSE;
-  case 45: /* 4.1: to be removed */
-    sql_print_warning("Found 4.1.0 style password for user '%s@%s'. "
-                      "Ignoring user. "
-                      "You should change password for this user.",
-                      user->user ? user->user : "",
-                      user->host.get_host() ? user->host.get_host() : "");
-    return TRUE;
-  default:
-    sql_print_warning("Found invalid password for user: '%s@%s'; "
-                      "Ignoring user", user->user ? user->user : "",
-                      user->host.get_host() ? user->host.get_host() : "");
-    return TRUE;
-  }
-}
-
-
 /*
   Initialize structures responsible for user/db-level privilege checking
   and load information about grants from open privilege tables.
@@ -760,8 +981,8 @@ set_user_plugin (ACL_USER *user, int pas
   SYNOPSIS
     acl_load()
       thd     Current thread
-      tables  List containing open "mysql.host", "mysql.user" and
-              "mysql.db" tables.
+      tables  List containing open "mysql.host", "mysql.user",
+              "mysql.db" and "mysql.proxies_priv" tables in that order.
 
   RETURN VALUES
     FALSE  Success
@@ -783,9 +1004,10 @@ static my_bool acl_load(THD *thd, TABLE_
 
   grant_version++; /* Privileges updated */
 
+  
   acl_cache->clear(1);				// Clear locked hostname cache
 
-  init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
+  init_sql_alloc(&global_acl_memory, ACL_ALLOC_BLOCK_SIZE, 0);
   if (init_read_record(&read_record_info, thd, table= tables[0].table,
                        NULL, 1, 1, FALSE))
     goto end;
@@ -793,9 +1015,11 @@ static my_bool acl_load(THD *thd, TABLE_
   (void) my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50);
   while (!(read_record_info.read_record(&read_record_info)))
   {
+    /* Reading record from mysql.host table */
     ACL_HOST acl_host;
-    acl_host.host.update_hostname(get_field(&mem, table->field[0]));
-    acl_host.db= get_field(&mem, table->field[1]);
+    acl_host.host.update_hostname(get_field(&global_acl_memory,
+                                            table->field[0]));
+    acl_host.db= get_field(&global_acl_memory, table->field[1]);
     if (lower_case_table_names && acl_host.db)
     {
       /*
@@ -831,65 +1055,32 @@ static my_bool acl_load(THD *thd, TABLE_
     }
 #endif
     (void) push_dynamic(&acl_hosts,(uchar*) &acl_host);
-  }
+  } // END reading records from mysql.host
+  
   my_qsort((uchar*) dynamic_element(&acl_hosts,0,ACL_HOST*),acl_hosts.elements,
 	   sizeof(ACL_HOST),(qsort_cmp) acl_compare);
   end_read_record(&read_record_info);
   freeze_size(&acl_hosts);
 
+  /*
+    Prepare reading from the mysql.user table
+  */
   if (init_read_record(&read_record_info, thd, table=tables[1].table,
                        NULL, 1, 1, FALSE))
     goto end;
   table->use_all_columns();
   (void) my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100);
-  password_length= table->field[2]->field_length /
-    table->field[2]->charset()->mbmaxlen;
-  if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
-  {
-    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->s->fields, password_length));
-
-  mysql_mutex_lock(&LOCK_global_system_variables);
-  if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH)
-  {
-    if (opt_secure_auth)
-    {
-      mysql_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;
-    }
-    mysql_user_table_is_in_short_password_format= true;
-    if (global_system_variables.old_passwords)
-      mysql_mutex_unlock(&LOCK_global_system_variables);
-    else
-    {
-      global_system_variables.old_passwords= 1;
-      mysql_mutex_unlock(&LOCK_global_system_variables);
-      sql_print_warning("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
-  {
-    mysql_user_table_is_in_short_password_format= false;
-    mysql_mutex_unlock(&LOCK_global_system_variables);
-  }
-
+  
   allow_all_hosts=0;
   while (!(read_record_info.read_record(&read_record_info)))
   {
+    /* Reading record from mysql.user */
     ACL_USER user;
     memset(&user, 0, sizeof(user));
-    user.host.update_hostname(get_field(&mem, table->field[0]));
-    user.user= get_field(&mem, table->field[1]);
+    user.host.update_hostname(get_field(&global_acl_memory,
+                                        table->field[MYSQL_USER_FIELD_HOST]));
+    user.user= get_field(&global_acl_memory,
+                         table->field[MYSQL_USER_FIELD_USER]);
     if (check_no_resolve && hostname_requires_resolving(user.host.get_host()))
     {
       sql_print_warning("'user' entry '%s@%s' "
@@ -899,13 +1090,27 @@ static my_bool acl_load(THD *thd, TABLE_
       continue;
     }
 
-    char *password= get_field(&mem, table->field[2]);
-    uint password_len= password ? strlen(password) : 0;
-    set_user_salt(&user, password, password_len);
+    /* Read legacy password */
+    {
+      char *password= get_field(&global_acl_memory,
+                                table->field[MYSQL_USER_FIELD_PASSWORD]);
+      uint password_len= password ? strlen(password) : 0;
+      user.auth_string.str= password ? password : const_cast<char*>("");
+      user.auth_string.length= password_len;
+      /*
+         Transform hex to octets and adjust the format.
+       */
+      set_user_salt(&user, password, password_len);
+
+      /*
+        Set temporary plugin deduced from password length. If there are 
+        enough fields in the user table the real plugin will be read later.
+       */
+      user.plugin= native_password_plugin_name;
+      if (password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
+        user.plugin= old_password_plugin_name;
+    } 
 
-    if (set_user_plugin(&user, password_len))
-      continue;
-    
     {
       uint next_field;
       user.access= get_access(table,3,&next_field) & GLOBAL_ACLS;
@@ -950,7 +1155,8 @@ static my_bool acl_load(THD *thd, TABLE_
       /* Starting from 4.0.2 we have more fields */
       if (table->s->fields >= 31)
       {
-        char *ssl_type=get_field(thd->mem_root, table->field[next_field++]);
+        char *ssl_type=
+          get_field(thd->mem_root, table->field[MYSQL_USER_FIELD_SSL_TYPE]);
         if (!ssl_type)
           user.ssl_type=SSL_TYPE_NONE;
         else if (!strcmp(ssl_type, "ANY"))
@@ -960,15 +1166,21 @@ static my_bool acl_load(THD *thd, TABLE_
         else  /* !strcmp(ssl_type, "SPECIFIED") */
           user.ssl_type=SSL_TYPE_SPECIFIED;
 
-        user.ssl_cipher=   get_field(&mem, table->field[next_field++]);
-        user.x509_issuer=  get_field(&mem, table->field[next_field++]);
-        user.x509_subject= get_field(&mem, table->field[next_field++]);
+        user.ssl_cipher= 
+          get_field(&global_acl_memory, table->field[MYSQL_USER_FIELD_SSL_CIPHER]);
+        user.x509_issuer=
+          get_field(&global_acl_memory, table->field[MYSQL_USER_FIELD_X509_ISSUER]);
+        user.x509_subject=
+          get_field(&global_acl_memory, table->field[MYSQL_USER_FIELD_X509_SUBJECT]);
 
-        char *ptr = get_field(thd->mem_root, table->field[next_field++]);
+        char *ptr= get_field(thd->mem_root,
+                             table->field[MYSQL_USER_FIELD_MAX_QUESTIONS]);
         user.user_resource.questions=ptr ? atoi(ptr) : 0;
-        ptr = get_field(thd->mem_root, table->field[next_field++]);
+        ptr= get_field(thd->mem_root,
+                       table->field[MYSQL_USER_FIELD_MAX_UPDATES]);
         user.user_resource.updates=ptr ? atoi(ptr) : 0;
-        ptr = get_field(thd->mem_root, table->field[next_field++]);
+        ptr= get_field(thd->mem_root,
+                       table->field[MYSQL_USER_FIELD_MAX_CONNECTIONS]);
         user.user_resource.conn_per_hour= ptr ? atoi(ptr) : 0;
         if (user.user_resource.questions || user.user_resource.updates ||
             user.user_resource.conn_per_hour)
@@ -977,24 +1189,22 @@ static my_bool acl_load(THD *thd, TABLE_
         if (table->s->fields >= 36)
         {
           /* Starting from 5.0.3 we have max_user_connections field */
-          ptr= get_field(thd->mem_root, table->field[next_field++]);
+          ptr= get_field(thd->mem_root,
+                         table->field[MYSQL_USER_FIELD_MAX_USER_CONNECTIONS]);
           user.user_resource.user_conn= ptr ? atoi(ptr) : 0;
         }
 
         if (table->s->fields >= 41)
         {
           /* We may have plugin & auth_String fields */
-          char *tmpstr= get_field(&mem, table->field[next_field++]);
+          char *tmpstr= get_field(&global_acl_memory,
+                                  table->field[MYSQL_USER_FIELD_PLUGIN]);
           if (tmpstr)
           {
-            if (password_len)
-            {
-              sql_print_warning("'user' entry '%s@%s' has both a password "
-                                "and an authentication plugin specified. The "
-                                "password will be ignored.",
-                                user.user ? user.user : "",
-                                user.host.get_host() ? user.host.get_host() : "");
-            }
+            /*
+              By comparing the plugin with the built in plugins it is possible
+              to optimize the string allocation and comparision.
+            */
             if (my_strcasecmp(system_charset_info, tmpstr,
                               native_password_plugin_name.str) == 0)
               user.plugin= native_password_plugin_name;
@@ -1002,12 +1212,30 @@ static my_bool acl_load(THD *thd, TABLE_
               if (my_strcasecmp(system_charset_info, tmpstr,
                                 old_password_plugin_name.str) == 0)
                 user.plugin= old_password_plugin_name;
-              else
+#if defined(HAVE_OPENSSL)
+            else
+              if (my_strcasecmp(system_charset_info, tmpstr,
+                                sha256_password_plugin_name.str) == 0)
+                user.plugin= sha256_password_plugin_name;
+#endif
+            else
               {
                 user.plugin.str= tmpstr;
                 user.plugin.length= strlen(tmpstr);
               }
-            user.auth_string.str= get_field(&mem, table->field[next_field++]);
+            if (user.auth_string.length &&
+                user.plugin.str != native_password_plugin_name.str &&
+                user.plugin.str != old_password_plugin_name.str)
+            {
+              sql_print_warning("'user' entry '%s@%s' has both a password "
+                                "and an authentication plugin specified. The "
+                                "password will be ignored.",
+                                user.user ? user.user : "",
+                                user.host.get_host() ? user.host.get_host() : "");
+            }
+            user.auth_string.str=
+              get_field(&global_acl_memory,
+                        table->field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]);
             if (!user.auth_string.str)
               user.auth_string.str= const_cast<char*>("");
             user.auth_string.length= strlen(user.auth_string.str);
@@ -1018,11 +1246,12 @@ static my_bool acl_load(THD *thd, TABLE_
 
         if (table->s->fields >= 43)
         {
-          char *tmpstr= get_field(&mem, table->field[next_field++]);
+          char *tmpstr= get_field(&global_acl_memory,
+                                  table->field[MYSQL_USER_FIELD_PASSWORD_EXPIRED]);
           if (tmpstr && (*tmpstr == 'Y' || *tmpstr == 'y'))
             user.password_expired= true;
         }
-      }
+      } // end if (table->s->fields >= 31)
       else
       {
         user.ssl_type=SSL_TYPE_NONE;
@@ -1044,12 +1273,60 @@ static my_bool acl_load(THD *thd, TABLE_
       if (user.host.check_allow_all_hosts())
         allow_all_hosts=1;			// Anyone can connect
     }
-  }
+  } // END while reading records from the mysql.user table
+  
   my_qsort((uchar*) dynamic_element(&acl_users,0,ACL_USER*),acl_users.elements,
 	   sizeof(ACL_USER),(qsort_cmp) acl_compare);
   end_read_record(&read_record_info);
   freeze_size(&acl_users);
 
+  /* Legacy password integrity checks ----------------------------------------*/
+  { 
+    password_length= table->field[MYSQL_USER_FIELD_PASSWORD]->field_length /
+      table->field[MYSQL_USER_FIELD_PASSWORD]->charset()->mbmaxlen;
+    if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
+    {
+      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->s->fields, password_length));
+
+    mysql_mutex_lock(&LOCK_global_system_variables);
+    if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH)
+    { 
+      if (opt_secure_auth)
+      {
+        mysql_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;
+      }
+      mysql_user_table_is_in_short_password_format= true;
+      if (global_system_variables.old_passwords)
+        mysql_mutex_unlock(&LOCK_global_system_variables);
+      else
+      {
+        global_system_variables.old_passwords= 1;
+        mysql_mutex_unlock(&LOCK_global_system_variables);
+        sql_print_warning("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
+    {
+      mysql_user_table_is_in_short_password_format= false;
+      mysql_mutex_unlock(&LOCK_global_system_variables);
+    }
+  } /* End legacy password integrity checks ----------------------------------*/
+  
+  /*
+    Prepare reading from the mysql.db table
+  */
   if (init_read_record(&read_record_info, thd, table=tables[2].table,
                        NULL, 1, 1, FALSE))
     goto end;
@@ -1057,15 +1334,17 @@ static my_bool acl_load(THD *thd, TABLE_
   (void) my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100);
   while (!(read_record_info.read_record(&read_record_info)))
   {
+    /* Reading record in mysql.db */
     ACL_DB db;
-    db.host.update_hostname(get_field(&mem, table->field[MYSQL_DB_FIELD_HOST]));
-    db.db=get_field(&mem, table->field[MYSQL_DB_FIELD_DB]);
+    db.host.update_hostname(get_field(&global_acl_memory, 
+                            table->field[MYSQL_DB_FIELD_HOST]));
+    db.db=get_field(&global_acl_memory, table->field[MYSQL_DB_FIELD_DB]);
     if (!db.db)
     {
       sql_print_warning("Found an entry in the 'db' table with empty database name; Skipped");
       continue;
     }
-    db.user=get_field(&mem, table->field[MYSQL_DB_FIELD_USER]);
+    db.user=get_field(&global_acl_memory, table->field[MYSQL_DB_FIELD_USER]);
     if (check_no_resolve && hostname_requires_resolving(db.host.get_host()))
     {
       sql_print_warning("'db' entry '%s %s@%s' "
@@ -1105,12 +1384,14 @@ static my_bool acl_load(THD *thd, TABLE_
     }
 #endif
     (void) push_dynamic(&acl_dbs,(uchar*) &db);
-  }
+  } // END reading records from mysql.db tables
+  
   my_qsort((uchar*) dynamic_element(&acl_dbs,0,ACL_DB*),acl_dbs.elements,
 	   sizeof(ACL_DB),(qsort_cmp) acl_compare);
   end_read_record(&read_record_info);
   freeze_size(&acl_dbs);
 
+  /* Prepare to read records from the mysql.proxies_priv table */
   (void) my_init_dynamic_array(&acl_proxy_users, sizeof(ACL_PROXY_USER), 
                                50, 100);
   if (tables[3].table)
@@ -1121,8 +1402,9 @@ static my_bool acl_load(THD *thd, TABLE_
     table->use_all_columns();
     while (!(read_record_info.read_record(&read_record_info)))
     {
+      /* Reading record in mysql.proxies_priv */
       ACL_PROXY_USER proxy;
-      proxy.init(table, &mem);
+      proxy.init(table, &global_acl_memory);
       if (proxy.check_validity(check_no_resolve))
         continue;
       if (push_dynamic(&acl_proxy_users, (uchar*) &proxy))
@@ -1130,7 +1412,8 @@ static my_bool acl_load(THD *thd, TABLE_
         end_read_record(&read_record_info);
         goto end;
       }
-    }
+    } // END reading records from the mysql.proxies_priv table
+
     my_qsort((uchar*) dynamic_element(&acl_proxy_users, 0, ACL_PROXY_USER*),
              acl_proxy_users.elements,
              sizeof(ACL_PROXY_USER), (qsort_cmp) acl_compare);
@@ -1156,7 +1439,7 @@ end:
 
 void acl_free(bool end)
 {
-  free_root(&mem,MYF(0));
+  free_root(&global_acl_memory,MYF(0));
   delete_dynamic(&acl_hosts);
   delete_dynamic(&acl_users);
   delete_dynamic(&acl_dbs);
@@ -1244,7 +1527,7 @@ my_bool acl_reload(THD *thd)
   old_acl_users= acl_users;
   old_acl_proxy_users= acl_proxy_users;
   old_acl_dbs= acl_dbs;
-  old_mem= mem;
+  old_mem= global_acl_memory;
   delete_dynamic(&acl_wild_hosts);
   my_hash_free(&acl_check_hosts);
 
@@ -1256,7 +1539,7 @@ my_bool acl_reload(THD *thd)
     acl_users= old_acl_users;
     acl_proxy_users= old_acl_proxy_users;
     acl_dbs= old_acl_dbs;
-    mem= old_mem;
+    global_acl_memory= old_mem;
     init_check_host();
   }
   else
@@ -1492,8 +1775,8 @@ static void acl_update_user(const char *
 			    const LEX_STRING *plugin,
 			    const LEX_STRING *auth)
 {
+  DBUG_ENTER("acl_update_user");
   mysql_mutex_assert_owner(&acl_cache->lock);
-
   for (uint i=0 ; i < acl_users.elements ; i++)
   {
     ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*);
@@ -1504,12 +1787,13 @@ static void acl_update_user(const char *
 	  (acl_user->host.get_host() &&
 	  !my_strcasecmp(system_charset_info, host, acl_user->host.get_host())))
       {
-        if (plugin->str[0])
+        if (plugin->length > 0)
         {
-          acl_user->plugin.str= strmake_root(&mem, plugin->str, plugin->length);
+          acl_user->plugin.str= strmake_root(&global_acl_memory, plugin->str, plugin->length);
           acl_user->plugin.length= plugin->length;
           acl_user->auth_string.str= auth->str ?
-            strmake_root(&mem, auth->str, auth->length) : const_cast<char*>("");
+            strmake_root(&global_acl_memory, auth->str,
+                         auth->length) : const_cast<char*>("");
           acl_user->auth_string.length= auth->length;
         }
 	acl_user->access=privileges;
@@ -1524,20 +1808,21 @@ static void acl_update_user(const char *
 	if (ssl_type != SSL_TYPE_NOT_SPECIFIED)
 	{
 	  acl_user->ssl_type= ssl_type;
-	  acl_user->ssl_cipher= (ssl_cipher ? strdup_root(&mem,ssl_cipher) :
-				 0);
-	  acl_user->x509_issuer= (x509_issuer ? strdup_root(&mem,x509_issuer) :
-				  0);
+	  acl_user->ssl_cipher= (ssl_cipher ? strdup_root(&global_acl_memory,
+                                                    ssl_cipher) :	0);
+	  acl_user->x509_issuer= (x509_issuer ? strdup_root(&global_acl_memory,
+                                                      x509_issuer) : 0);
 	  acl_user->x509_subject= (x509_subject ?
-				   strdup_root(&mem,x509_subject) : 0);
+				   strdup_root(&global_acl_memory, x509_subject) : 0);
 	}
-	if (password)
+  if (password)
           set_user_salt(acl_user, password, password_len);
         /* search complete: */
 	break;
       }
     }
   }
+  DBUG_VOID_RETURN;
 }
 
 
@@ -1552,18 +1837,20 @@ static void acl_insert_user(const char *
 			    const LEX_STRING *plugin,
 			    const LEX_STRING *auth)
 {
+  DBUG_ENTER("acl_insert_user");
   ACL_USER acl_user;
 
   mysql_mutex_assert_owner(&acl_cache->lock);
 
-  acl_user.user=*user ? strdup_root(&mem,user) : 0;
-  acl_user.host.update_hostname( *host ? strdup_root(&mem, host): 0);
+  acl_user.user= *user ? strdup_root(&global_acl_memory,user) : 0;
+  acl_user.host.update_hostname(*host ? strdup_root(&global_acl_memory, host) : 0);
   if (plugin->str[0])
   {
-    acl_user.plugin.str= strmake_root(&mem, plugin->str, plugin->length);
+    acl_user.plugin.str= strmake_root(&global_acl_memory, plugin->str, plugin->length);
     acl_user.plugin.length= plugin->length;
     acl_user.auth_string.str= auth->str ?
-      strmake_root(&mem, auth->str, auth->length) : const_cast<char*>("");
+      strmake_root(&global_acl_memory, auth->str,
+                   auth->length) : const_cast<char*>("");
     acl_user.auth_string.length= auth->length;
   }
   else
@@ -1573,16 +1860,18 @@ static void acl_insert_user(const char *
     acl_user.auth_string.str= const_cast<char*>("");
     acl_user.auth_string.length= 0;
   }
-
-  acl_user.access=privileges;
-  acl_user.user_resource = *mqh;
-  acl_user.sort=get_sort(2,acl_user.host.get_host(),acl_user.user);
+  acl_user.access= privileges;
+  acl_user.user_resource= *mqh;
+  acl_user.sort= get_sort(2,acl_user.host.get_host(), acl_user.user);
   //acl_user.hostname_length=(uint) strlen(host);
-  acl_user.ssl_type= (ssl_type != SSL_TYPE_NOT_SPECIFIED ?
-		      ssl_type : SSL_TYPE_NONE);
-  acl_user.ssl_cipher=	ssl_cipher   ? strdup_root(&mem,ssl_cipher) : 0;
-  acl_user.x509_issuer= x509_issuer  ? strdup_root(&mem,x509_issuer) : 0;
-  acl_user.x509_subject=x509_subject ? strdup_root(&mem,x509_subject) : 0;
+  acl_user.ssl_type=
+    (ssl_type != SSL_TYPE_NOT_SPECIFIED ? ssl_type : SSL_TYPE_NONE);
+  acl_user.ssl_cipher=
+    ssl_cipher ? strdup_root(&global_acl_memory, ssl_cipher) : 0;
+  acl_user.x509_issuer=
+    x509_issuer ? strdup_root(&global_acl_memory, x509_issuer) : 0;
+  acl_user.x509_subject=
+    x509_subject ? strdup_root(&global_acl_memory, x509_subject) : 0;
 
   set_user_salt(&acl_user, password, password_len);
 
@@ -1594,6 +1883,7 @@ static void acl_insert_user(const char *
 
   /* Rebuild 'acl_check_hosts' since 'acl_users' has been modified */
   rebuild_check_host();
+  DBUG_VOID_RETURN;
 }
 
 
@@ -1646,14 +1936,14 @@ static void acl_insert_db(const char *us
 {
   ACL_DB acl_db;
   mysql_mutex_assert_owner(&acl_cache->lock);
-  acl_db.user=strdup_root(&mem,user);
-  acl_db.host.update_hostname(*host ? strdup_root(&mem,host) : 0);
-  acl_db.db=strdup_root(&mem,db);
-  acl_db.access=privileges;
-  acl_db.sort=get_sort(3,acl_db.host.get_host(),acl_db.db,acl_db.user);
-  (void) push_dynamic(&acl_dbs,(uchar*) &acl_db);
-  my_qsort((uchar*) dynamic_element(&acl_dbs,0,ACL_DB*),acl_dbs.elements,
-	   sizeof(ACL_DB),(qsort_cmp) acl_compare);
+  acl_db.user= strdup_root(&global_acl_memory,user);
+  acl_db.host.update_hostname(*host ? strdup_root(&global_acl_memory, host) : 0);
+  acl_db.db= strdup_root(&global_acl_memory, db);
+  acl_db.access= privileges;
+  acl_db.sort= get_sort(3,acl_db.host.get_host(), acl_db.db, acl_db.user);
+  (void) push_dynamic(&acl_dbs, (uchar*) &acl_db);
+  my_qsort((uchar*) dynamic_element(&acl_dbs, 0, ACL_DB*), acl_dbs.elements,
+	         sizeof(ACL_DB),(qsort_cmp) acl_compare);
 }
 
 
@@ -1850,22 +2140,19 @@ bool acl_check_host(const char *host, co
 }
 
 
-/*
+/**
   Check if the user is allowed to change password
 
-  SYNOPSIS:
-    check_change_password()
-    thd		THD
-    host	hostname for the user
-    user	user name
-    new_password new password
-
-  NOTE:
-    new_password cannot be NULL
-
-    RETURN VALUE
-      0		OK
-      1		ERROR  ; In this case the error is sent to the client.
+ @param thd THD
+ @param host Hostname for the user
+ @param user User name
+ @param new_password new password
+
+ new_password cannot be NULL
+
+ @return Error status
+   @retval 0 OK
+   @retval 1 ERROR; In this case the error is sent to the client.
 */
 
 int check_change_password(THD *thd, const char *host, const char *user,
@@ -1890,35 +2177,30 @@ int check_change_password(THD *thd, cons
                MYF(0));
     return(1);
   }
-  size_t len= strlen(new_password);
-  if (len && len != SCRAMBLED_PASSWORD_CHAR_LENGTH &&
-      len != SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
-  {
-    my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH);
-    return -1;
-  }
+
   return(0);
 }
 
 
-/*
-  Change a password for a user
+/**
+  Change a password hash for a user.
 
+  @param thd Thread handle
+  @param host Hostname
+  @param user User name
+  @param new_password New password hash for host@user
+ 
   Note : it will also reset the change_password flag.
   This is safe to do unconditionally since the simple userless form
   SET PASSWORD = PASSWORD('text') will be the only allowed form when
   this flag is on. So we don't need to check user names here.
 
-  SYNOPSIS
-    change_password()
-    thd			Thread handle
-    host		Hostname
-    user		User name
-    new_password	New password for host@user
 
-  RETURN VALUES
-    0	ok
-    1	ERROR; In this case the error is sent to the client.
+  @see set_var_password::update(THD *thd)
+
+  @return Error code
+   @retval 0 ok
+   @retval 1 ERROR; In this case the error is sent to the client.
 */
 
 bool change_password(THD *thd, const char *host, const char *user,
@@ -1932,6 +2214,7 @@ bool change_password(THD *thd, const cha
   bool save_binlog_row_based;
   uint new_password_len= (uint) strlen(new_password);
   bool result= 1;
+  enum mysql_user_table_field password_field= MYSQL_USER_FIELD_PASSWORD;
   DBUG_ENTER("change_password");
   DBUG_PRINT("enter",("host: '%s'  user: '%s'  new_password: '%s'",
 		      host,user,new_password));
@@ -1978,24 +2261,116 @@ bool change_password(THD *thd, const cha
     my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), MYF(0));
     goto end;
   }
+  
+  if (acl_user->plugin.length == 0)
+  {
+    acl_user->plugin.length= default_auth_plugin_name.length;
+    acl_user->plugin.str= default_auth_plugin_name.str;
+  }
+  
+#if defined(HAVE_OPENSSL)
+  /*
+    update loaded acl entry:
+    TODO Should password depend on @@old_variables here?
+    - Probably not if the user exists and have a plugin set already.
+  */
+  if (my_strcasecmp(system_charset_info, acl_user->plugin.str,
+                    sha256_password_plugin_name.str) == 0)
+  {
+    /*
+     Accept empty passwords
+    */
+    if (new_password_len == 0)
+      acl_user->auth_string= empty_lex_str;
+    /*
+     Check if password begins with correct magic number
+    */
+    else if (new_password[0] == '$' &&
+             new_password[1] == '5' &&
+             new_password[2] == '$')
+    {
+      password_field= MYSQL_USER_FIELD_AUTHENTICATION_STRING;
+      if (new_password_len < CRYPT_MAX_PASSWORD_SIZE + 1)
+      {
+        /* copy string including \0 */
+        acl_user->auth_string.str= (char *) memdup_root(&global_acl_memory,
+                                                       new_password,
+                                                       new_password_len + 1);
+        acl_user->auth_string.length= new_password_len;
+      }
+    } else
+    {
+      /*
+        Password format is unexpected. The user probably is using the wrong
+        password algorithm with the PASSWORD() function.
+      */
+      my_error(ER_PASSWORD_FORMAT, MYF(0));
+      result= 1;
+      mysql_mutex_unlock(&acl_cache->lock);
+      goto end;
+    }
+  }
+  else
+#endif
+  if (my_strcasecmp(system_charset_info, acl_user->plugin.str,
+                    native_password_plugin_name.str) == 0 ||
+      my_strcasecmp(system_charset_info, acl_user->plugin.str,
+                    old_password_plugin_name.str) == 0)
+  {
+    password_field= MYSQL_USER_FIELD_PASSWORD;
+    
+    /*
+      Legacy code produced an error if the password hash didn't match the
+      expectations.
+    */
+    if (new_password_len != 0)
+    {
+      if (my_strcasecmp(system_charset_info, acl_user->plugin.str,
+                        native_password_plugin_name.str) == 0 &&
+          new_password_len != SCRAMBLED_PASSWORD_CHAR_LENGTH)
+      {
+        my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH);
+        result= 1;
+        mysql_mutex_unlock(&acl_cache->lock);
+        goto end;  
+      }
+      else
+      if (my_strcasecmp(system_charset_info, acl_user->plugin.str,
+                        old_password_plugin_name.str) == 0 &&
+          new_password_len != SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
+      {
+        my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH_323);
+        result= 1;
+        mysql_mutex_unlock(&acl_cache->lock);
+        goto end;  
+      }
+    }
 
-  /* update loaded acl entry: */
-  set_user_salt(acl_user, new_password, new_password_len);
-  thd->security_ctx->password_expired= false;
-
-  if (my_strcasecmp(system_charset_info, acl_user->plugin.str,
-                    native_password_plugin_name.str) &&
-      my_strcasecmp(system_charset_info, acl_user->plugin.str,
-                    old_password_plugin_name.str))
-    push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
-                 ER_SET_PASSWORD_AUTH_PLUGIN, ER(ER_SET_PASSWORD_AUTH_PLUGIN));
+    /*
+      Update loaded acl entry in memory.
+      set_user_salt() stores a binary (compact) representation of the password
+      in memory (acl_user->salt and salt_len).
+      set_user_plugin() sets the appropriate plugin based on password length and
+      if the length doesn't match a warning is issued.
+    */
+    set_user_salt(acl_user, new_password, new_password_len);
+    thd->security_ctx->password_expired= false;
+  }
   else
-    set_user_plugin(acl_user, new_password_len);
+  {
+     push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
+                  ER_SET_PASSWORD_AUTH_PLUGIN, ER(ER_SET_PASSWORD_AUTH_PLUGIN));
+     /*
+       An undefined password factory could very well mean that the password
+       field is empty.
+     */
+     new_password_len= 0;
+  }
 
   if (update_user_table(thd, table,
-			acl_user->host.get_host() ? acl_user->host.get_host() : "",
-			acl_user->user ? acl_user->user : "",
-			new_password, new_password_len, 'N'))
+                        acl_user->host.get_host() ? acl_user->host.get_host() : "",
+                        acl_user->user ? acl_user->user : "",
+                        new_password, new_password_len, password_field, 'N'))
   {
     mysql_mutex_unlock(&acl_cache->lock); /* purecov: deadcode */
     goto end;
@@ -2169,24 +2544,27 @@ bool hostname_requires_resolving(const c
 }
 
 
-/*
+/**
   Update record for user in mysql.user privilege table with new password.
 
-  SYNOPSIS
-    update_user_table()
-      thd               Thread handle
-      table             Pointer to TABLE object for open mysql.user table
-      host/user         Hostname/username pair identifying user for which
-                        new password should be set
-      new_password      New password. Can be NULL to flag no new password
-      new_password_len  Length of new password
-      password_expired  password expiration flag
+  @param table Pointer to TABLE object for open mysql.user table
+  @param host Hostname
+  @param user Username
+  @param new_password New password hash
+  @param new_password_len Length of new password hash
+  @param password_field The password field to use 
+  @param password_expired Password expiration flag
+
+  @see change_password
+
 */
 
-static bool update_user_table(THD *thd, TABLE *table,
-                              const char *host, const char *user,
-			      const char *new_password, uint new_password_len,
-                              const char password_expired)
+static bool
+update_user_table(THD *thd, TABLE *table,
+                  const char *host, const char *user,
+                  const char *new_password, uint new_password_len,
+                  enum mysql_user_table_field password_field,
+                  const char password_expired)
 {
   char user_key[MAX_KEY_LENGTH];
   int error;
@@ -2194,8 +2572,11 @@ static bool update_user_table(THD *thd, 
   DBUG_PRINT("enter",("user: %s  host: %s",user,host));
 
   table->use_all_columns();
-  table->field[0]->store(host,(uint) strlen(host), system_charset_info);
-  table->field[1]->store(user,(uint) strlen(user), system_charset_info);
+  DBUG_ASSERT(host != '\0');
+  table->field[MYSQL_USER_FIELD_HOST]->store(host, (uint) strlen(host),
+                                             system_charset_info);
+  table->field[MYSQL_USER_FIELD_USER]->store(user, (uint) strlen(user),
+                                             system_charset_info);
   key_copy((uchar *) user_key, table->record[0], table->key_info,
            table->key_info->key_length);
 
@@ -2208,23 +2589,26 @@ static bool update_user_table(THD *thd, 
     DBUG_RETURN(1);				/* purecov: deadcode */
   }
   store_record(table,record[1]);
-  if (new_password)
+  
+  table->field[(int) password_field]->store(new_password, new_password_len,
+                                            system_charset_info);
+  if (new_password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323 &&
+      password_field == MYSQL_USER_FIELD_PASSWORD)
   {
-    table->field[2]->store(new_password, new_password_len, system_charset_info);
-
-    if (new_password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
-      WARN_DEPRECATED_41_PWD_HASH(thd);
+    WARN_DEPRECATED_41_PWD_HASH(thd);
   }
 
   /* password_expired */
-  table->field[42]->store(&password_expired, 1, system_charset_info);
+  table->field[MYSQL_USER_FIELD_PASSWORD_EXPIRED]->store(&password_expired, 1,
+                                                         system_charset_info);
 
   if ((error=table->file->ha_update_row(table->record[1],table->record[0])) &&
-      error != HA_ERR_RECORD_IS_THE_SAME)
+       error != HA_ERR_RECORD_IS_THE_SAME)
   {
     table->file->print_error(error,MYF(0));	/* purecov: deadcode */
     DBUG_RETURN(1);
   }
+
   DBUG_RETURN(0);
 }
 
@@ -2261,45 +2645,71 @@ static bool test_if_create_new_users(THD
   return create_new_users;
 }
 
+bool auth_plugin_is_built_in(const char *plugin_name)
+{
+ return (plugin_name == native_password_plugin_name.str ||
+#if defined(HAVE_OPENSSL)
+         plugin_name == sha256_password_plugin_name.str ||
+#endif
+         plugin_name == old_password_plugin_name.str);
+}
+
+void optimize_plugin_compare_by_pointer(LEX_STRING *plugin_name)
+{
+#if defined(HAVE_OPENSSL)
+  if (my_strcasecmp(system_charset_info, sha256_password_plugin_name.str,
+                    plugin_name->str) == 0)
+  {
+    plugin_name->str= sha256_password_plugin_name.str;
+    plugin_name->length= sha256_password_plugin_name.length;
+  }
+  else
+#endif
+  if (my_strcasecmp(system_charset_info, native_password_plugin_name.str,
+                    plugin_name->str) == 0)
+  {
+    plugin_name->str= native_password_plugin_name.str;
+    plugin_name->length= native_password_plugin_name.length;
+  }
+  else
+  if (my_strcasecmp(system_charset_info, old_password_plugin_name.str,
+                    plugin_name->str) == 0)
+  {
+    plugin_name->str= old_password_plugin_name.str;
+    plugin_name->length= old_password_plugin_name.length;
+  }
+
+  DBUG_ASSERT(auth_plugin_is_built_in(native_password_plugin_name.str));
+}
 
 /****************************************************************************
   Handle GRANT commands
 ****************************************************************************/
 
-static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
+static int replace_user_table(THD *thd, TABLE *table, LEX_USER *combo,
 			      ulong rights, bool revoke_grant,
 			      bool can_create_user, bool no_auto_create)
 {
   int error = -1;
   bool old_row_exists=0;
-  const char *password= "";
+  char *password= empty_c_string;
   uint password_len= 0;
   char what= (revoke_grant) ? 'N' : 'Y';
   uchar user_key[MAX_KEY_LENGTH];
   LEX *lex= thd->lex;
+#if defined(HAVE_OPENSSL)
+  bool sha2_plugin= false;
+#endif
   DBUG_ENTER("replace_user_table");
 
   mysql_mutex_assert_owner(&acl_cache->lock);
-
-  if (combo.password.str && combo.password.str[0])
-  {
-    if (combo.password.length != SCRAMBLED_PASSWORD_CHAR_LENGTH &&
-        combo.password.length != SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
-    {
-      my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH);
-      DBUG_RETURN(-1);
-    }
-    if (combo.password.length == SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
-      WARN_DEPRECATED_41_PWD_HASH(thd);
-    password_len= combo.password.length;
-    password=combo.password.str;
-  }
-
+ 
   table->use_all_columns();
-  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);
+  DBUG_ASSERT(combo->host.str != '\0');
+  table->field[MYSQL_USER_FIELD_HOST]->store(combo->host.str,combo->host.length,
+                                             system_charset_info);
+  table->field[MYSQL_USER_FIELD_USER]->store(combo->user.str,combo->user.length,
+                                             system_charset_info);
   key_copy(user_key, table->record[0], table->key_info,
            table->key_info->key_length);
 
@@ -2307,12 +2717,35 @@ static int replace_user_table(THD *thd, 
                                          HA_WHOLE_KEY,
                                          HA_READ_KEY_EXACT))
   {
-    /* what == 'N' means revoke */
+    /*
+      The user record wasn't found; if the intention was to revoke privileges
+      (indicated by what == 'N') then execution must fail now.
+    */
     if (what == 'N')
     {
-      my_error(ER_NONEXISTING_GRANT, MYF(0), combo.user.str, combo.host.str);
+      my_error(ER_NONEXISTING_GRANT, MYF(0), combo->user.str, combo->host.str);
       goto end;
     }
+    
+    /* 1. Unresolved plugins become default plugin */
+    if (!combo->uses_identified_with_clause)
+    {
+      combo->plugin.str= default_auth_plugin_name.str;
+      combo->plugin.length= default_auth_plugin_name.length;
+      combo->uses_identified_with_clause= false;
+    }
+    /* 2. Digest password if needed (plugin must have been resolved) */
+    if (combo->uses_identified_by_clause)
+    {
+      if (digest_password(thd, combo))
+      {
+        my_error(ER_OUTOFMEMORY, MYF(0), CRYPT_MAX_PASSWORD_SIZE);
+        error= 1;
+        goto end;
+      }
+    }
+    password= combo->password.str;
+    password_len= combo->password.length;
     /*
       There are four options which affect the process of creation of
       a new user (mysqld option --safe-create-user, 'insert' privilege
@@ -2326,9 +2759,11 @@ static int replace_user_table(THD *thd, 
 
       see also test_if_create_new_users()
     */
-    else if (!password_len && !combo.plugin.length && no_auto_create)
+    if (!password_len &&
+        auth_plugin_is_built_in(combo->plugin.str) && 
+        no_auto_create)
     {
-      my_error(ER_PASSWORD_NO_MATCH, MYF(0));
+      my_error(ER_PASSWORD_NO_MATCH, MYF(0), combo->user.str, combo->host.str);
       goto end;
     }
     else if (!can_create_user)
@@ -2336,41 +2771,161 @@ static int replace_user_table(THD *thd, 
       my_error(ER_CANT_CREATE_USER_WITH_GRANT, MYF(0));
       goto end;
     }
-    else if (combo.plugin.str[0])
+    else if (combo->plugin.str[0])
     {
-      if (!plugin_is_ready(&combo.plugin, MYSQL_AUTHENTICATION_PLUGIN))
+      if (!plugin_is_ready(&combo->plugin, MYSQL_AUTHENTICATION_PLUGIN))
       {
-        my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), combo.plugin.str);
+        my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), combo->plugin.str);
         goto end;
       }
     }
 
     old_row_exists = 0;
     restore_record(table,s->default_values);
-    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->field[2]->store(password, password_len,
-                           system_charset_info);
+    DBUG_ASSERT(combo->host.str != '\0');
+    table->field[MYSQL_USER_FIELD_HOST]->store(combo->host.str,combo->host.length,
+                                               system_charset_info);
+    table->field[MYSQL_USER_FIELD_USER]->store(combo->user.str,combo->user.length,
+                                               system_charset_info);
+#if defined(HAVE_OPENSSL)
+    if (combo->plugin.str == sha256_password_plugin_name.str)
+    {
+      /* Use the authentication_string field */
+      combo->auth.str= password;
+      combo->auth.length= password_len;
+      if (password_len > 0)
+        table->
+          field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]->
+            store(password, password_len, &my_charset_utf8_bin);
+      /* Assert that the proper plugin is set */
+      table->
+        field[MYSQL_USER_FIELD_PLUGIN]->
+          store(sha256_password_plugin_name.str,
+                sha256_password_plugin_name.length,
+                system_charset_info);
+
+    }
+    else
+#endif
+    {
+      /* Use the legacy Password field */
+      if (combo->password.length == SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
+        WARN_DEPRECATED_41_PWD_HASH(thd);
+      table->field[MYSQL_USER_FIELD_PASSWORD]->store(password, password_len,
+                                                     system_charset_info);
+      table->field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]->store("\0", 0,
+                                                     &my_charset_utf8_bin);
+    }
   }
-  else
+  else // if (table->file->ha_index_read_idx_map [..]
   {
+    /*
+      There is a matching user record ------------------------------------------
+     */
+
     old_row_exists = 1;
     store_record(table,record[1]);			// Save copy for update
-    /* what == 'N' means revoke */
-    if (combo.plugin.length && what != 'N')
+    
+    /* 1. resolve plugins in the LEX_USER struct if needed */
+    if (!combo->uses_identified_with_clause)
+    {
+      /*
+        Get old plugin value from storage.
+      */
+      combo->plugin.str=
+        get_field(thd->mem_root, table->field[MYSQL_USER_FIELD_PLUGIN]);
+
+      /* 
+        It is important not to include the trailing '\0' in the string length 
+        because otherwise the plugin hash search will fail.
+      */
+      if (combo->plugin.str)
+      {
+        combo->plugin.length= strlen(combo->plugin.str);
+
+        /*
+          Optimize for pointer comparision of built-in plugin name
+        */
+
+        optimize_plugin_compare_by_pointer(&combo->plugin);
+      }
+    }    
+    
+    /* No value for plugin field means default plugin is used */
+    if (combo->plugin.str == NULL || combo->plugin.str == '\0')
+    {
+      combo->plugin.str= default_auth_plugin_name.str;
+      combo->plugin.length= default_auth_plugin_name.length;
+    }
+    
+    if (combo->uses_identified_with_clause)
+    {
+      /*
+        Don't allow old plugin fields to change.
+      */
+      char *old_plugin= get_field(thd->mem_root,
+                                  table->field[MYSQL_USER_FIELD_PLUGIN]);
+      if (old_plugin != NULL &&
+          my_strcasecmp(system_charset_info, combo->plugin.str, old_plugin))
+      {
+        error= 1;
+        my_error(ER_GRANT_PLUGIN_USER_EXISTS, MYF(0), combo->user.length,
+                 combo->user.str);
+        goto end;
+      }
+    }
+
+    if (!combo->uses_authentication_string_clause)
+    {
+      combo->auth.str= get_field(thd->mem_root,
+        table->field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]);
+      if (combo->auth.str)
+        combo->auth.length= strlen(combo->auth.str);
+      else
+        combo->auth.length= 0;
+    }
+    
+    /* 2. Digest password if needed (plugin must have been resolved */
+    if (combo->uses_identified_by_clause)
     {
-        my_error(ER_GRANT_PLUGIN_USER_EXISTS, MYF(0),
-                 static_cast<int>(combo.user.length), combo.user.str);
+      if (digest_password(thd, combo))
+      {
+        error= 1;
         goto end;
+      }
+    }
+    password= combo->password.str;
+    password_len= combo->password.length;
+
+    if (password_len > 0)
+    {
+#if defined(HAVE_OPENSSL)
+      if (combo->plugin.str == sha256_password_plugin_name.str)
+      {
+        sha2_plugin= true;
+        table->field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]->
+          store(password, password_len, &my_charset_utf8_bin);
+        combo->auth.str= password;
+        combo->auth.length= password_len;
+      }
+      else
+#endif
+      {
+        /* The legacy Password field is used */
+        if (combo->password.length == SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
+          WARN_DEPRECATED_41_PWD_HASH(thd);
+        table->field[MYSQL_USER_FIELD_PASSWORD]->
+          store(password, password_len, system_charset_info);
+        table->field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]->
+          store("\0", 0, &my_charset_utf8_bin);
+      }
     }
-    if (combo.password.str)                             // If password given
-      table->field[2]->store(password, password_len, system_charset_info);
     else if (!rights && !revoke_grant &&
              lex->ssl_type == SSL_TYPE_NOT_SPECIFIED &&
              !lex->mqh.specified_limits)
     {
+     
+      DBUG_PRINT("info", ("Proxy user exit path"));
       DBUG_RETURN(0);
     }
   }
@@ -2395,69 +2950,75 @@ static int replace_user_table(THD *thd, 
     /* We write down SSL related ACL stuff */
     switch (lex->ssl_type) {
     case SSL_TYPE_ANY:
-      table->field[next_field]->store(STRING_WITH_LEN("ANY"),
+      table->field[MYSQL_USER_FIELD_SSL_TYPE]->store(STRING_WITH_LEN("ANY"),
                                       &my_charset_latin1);
-      table->field[next_field+1]->store("", 0, &my_charset_latin1);
-      table->field[next_field+2]->store("", 0, &my_charset_latin1);
-      table->field[next_field+3]->store("", 0, &my_charset_latin1);
+      table->field[MYSQL_USER_FIELD_SSL_CIPHER]->
+        store("", 0, &my_charset_latin1);
+      table->field[MYSQL_USER_FIELD_X509_ISSUER]->store("", 0, &my_charset_latin1);
+      table->field[MYSQL_USER_FIELD_X509_SUBJECT]->store("", 0, &my_charset_latin1);
       break;
     case SSL_TYPE_X509:
-      table->field[next_field]->store(STRING_WITH_LEN("X509"),
+      table->field[MYSQL_USER_FIELD_SSL_TYPE]->store(STRING_WITH_LEN("X509"),
                                       &my_charset_latin1);
-      table->field[next_field+1]->store("", 0, &my_charset_latin1);
-      table->field[next_field+2]->store("", 0, &my_charset_latin1);
-      table->field[next_field+3]->store("", 0, &my_charset_latin1);
+      table->field[MYSQL_USER_FIELD_SSL_CIPHER]->
+        store("", 0, &my_charset_latin1);
+      table->field[MYSQL_USER_FIELD_X509_ISSUER]->store("", 0, &my_charset_latin1);
+      table->field[MYSQL_USER_FIELD_X509_SUBJECT]->store("", 0, &my_charset_latin1);
       break;
     case SSL_TYPE_SPECIFIED:
-      table->field[next_field]->store(STRING_WITH_LEN("SPECIFIED"),
+      table->field[MYSQL_USER_FIELD_SSL_TYPE]->store(STRING_WITH_LEN("SPECIFIED"),
                                       &my_charset_latin1);
-      table->field[next_field+1]->store("", 0, &my_charset_latin1);
-      table->field[next_field+2]->store("", 0, &my_charset_latin1);
-      table->field[next_field+3]->store("", 0, &my_charset_latin1);
+      table->field[MYSQL_USER_FIELD_SSL_CIPHER]->store("", 0, &my_charset_latin1);
+      table->field[MYSQL_USER_FIELD_X509_ISSUER]->store("", 0, &my_charset_latin1);
+      table->field[MYSQL_USER_FIELD_X509_SUBJECT]->store("", 0, &my_charset_latin1);
       if (lex->ssl_cipher)
-        table->field[next_field+1]->store(lex->ssl_cipher,
+        table->field[MYSQL_USER_FIELD_SSL_CIPHER]->store(lex->ssl_cipher,
                                 strlen(lex->ssl_cipher), system_charset_info);
       if (lex->x509_issuer)
-        table->field[next_field+2]->store(lex->x509_issuer,
+        table->field[MYSQL_USER_FIELD_X509_ISSUER]->store(lex->x509_issuer,
                                 strlen(lex->x509_issuer), system_charset_info);
       if (lex->x509_subject)
-        table->field[next_field+3]->store(lex->x509_subject,
+        table->field[MYSQL_USER_FIELD_X509_SUBJECT]->store(lex->x509_subject,
                                 strlen(lex->x509_subject), system_charset_info);
       break;
     case SSL_TYPE_NOT_SPECIFIED:
       break;
     case SSL_TYPE_NONE:
-      table->field[next_field]->store("", 0, &my_charset_latin1);
-      table->field[next_field+1]->store("", 0, &my_charset_latin1);
-      table->field[next_field+2]->store("", 0, &my_charset_latin1);
-      table->field[next_field+3]->store("", 0, &my_charset_latin1);
+      table->field[MYSQL_USER_FIELD_SSL_TYPE]->store("", 0, &my_charset_latin1);
+      table->field[MYSQL_USER_FIELD_SSL_CIPHER]->store("", 0, &my_charset_latin1);
+      table->field[MYSQL_USER_FIELD_X509_ISSUER]->store("", 0, &my_charset_latin1);
+      table->field[MYSQL_USER_FIELD_X509_SUBJECT]->store("", 0, &my_charset_latin1);
       break;
     }
     next_field+=4;
 
     USER_RESOURCES mqh= lex->mqh;
     if (mqh.specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
-      table->field[next_field]->store((longlong) mqh.questions, TRUE);
+      table->field[MYSQL_USER_FIELD_MAX_QUESTIONS]->
+        store((longlong) mqh.questions, TRUE);
     if (mqh.specified_limits & USER_RESOURCES::UPDATES_PER_HOUR)
-      table->field[next_field+1]->store((longlong) mqh.updates, TRUE);
+      table->field[MYSQL_USER_FIELD_MAX_UPDATES]->
+        store((longlong) mqh.updates, TRUE);
     if (mqh.specified_limits & USER_RESOURCES::CONNECTIONS_PER_HOUR)
-      table->field[next_field+2]->store((longlong) mqh.conn_per_hour, TRUE);
+      table->field[MYSQL_USER_FIELD_MAX_CONNECTIONS]->
+        store((longlong) mqh.conn_per_hour, TRUE);
     if (table->s->fields >= 36 &&
         (mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS))
-      table->field[next_field+3]->store((longlong) mqh.user_conn, TRUE);
+      table->field[MYSQL_USER_FIELD_MAX_USER_CONNECTIONS]->
+        store((longlong) mqh.user_conn, TRUE);
     mqh_used= mqh_used || mqh.questions || mqh.updates || mqh.conn_per_hour;
 
     next_field+= 4;
-    if (combo.plugin.str[0])
+    if (combo->plugin.length > 0 && !old_row_exists)
     {
-      if (table->s->fields >= 41 && combo.plugin.str[0])
+      if (table->s->fields >= 41)
       {
-        table->field[next_field]->store(combo.plugin.str, combo.plugin.length,
-                                        system_charset_info);
-        table->field[next_field]->set_notnull();
-        table->field[next_field + 1]->store(combo.auth.str, combo.auth.length,
-                                            system_charset_info);
-        table->field[next_field + 1]->set_notnull();
+        table->field[MYSQL_USER_FIELD_PLUGIN]->
+          store(combo->plugin.str, combo->plugin.length, system_charset_info);
+        table->field[MYSQL_USER_FIELD_PLUGIN]->set_notnull();
+        table->field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]->
+          store(combo->auth.str, combo->auth.length, &my_charset_utf8_bin);
+        table->field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]->set_notnull();
       }
       else
       {
@@ -2468,7 +3029,7 @@ static int replace_user_table(THD *thd, 
   }
 
   if (old_row_exists)
-  {
+  {   
     /*
       We should NEVER delete from the user table, as a uses can still
       use mysqld even if he doesn't have any privileges in the user table!
@@ -2503,26 +3064,26 @@ end:
   {
     acl_cache->clear(1);			// Clear privilege cache
     if (old_row_exists)
-      acl_update_user(combo.user.str, combo.host.str,
-                      combo.password.str, password_len,
+      acl_update_user(combo->user.str, combo->host.str,
+                      combo->password.str, password_len,
 		      lex->ssl_type,
 		      lex->ssl_cipher,
 		      lex->x509_issuer,
 		      lex->x509_subject,
 		      &lex->mqh,
 		      rights,
-		      &combo.plugin,
-		      &combo.auth);
+		      &combo->plugin,
+		      &combo->auth);
     else
-      acl_insert_user(combo.user.str, combo.host.str, password, password_len,
+      acl_insert_user(combo->user.str, combo->host.str, password, password_len,
 		      lex->ssl_type,
 		      lex->ssl_cipher,
 		      lex->x509_issuer,
 		      lex->x509_subject,
 		      &lex->mqh,
 		      rights,
-		      &combo.plugin,
-		      &combo.auth);
+		      &combo->plugin,
+		      &combo->auth);
   }
   DBUG_RETURN(error);
 }
@@ -2780,7 +3341,7 @@ replace_proxies_priv_table(THD *thd, TAB
   }
   else
   {
-    new_grant.init(&mem, user->host.str, user->user.str,
+    new_grant.init(&global_acl_memory, user->host.str, user->user.str,
                    proxied_user->host.str, proxied_user->user.str,
                    with_grant_arg);
     acl_insert_proxy_user(&new_grant);
@@ -3733,9 +4294,18 @@ int mysql_table_grant(THD *thd, TABLE_LI
     {
       result= TRUE;
       continue;
-    }  
+    }
+
+    /*
+      No User, but a password?
+      They did GRANT ... TO CURRENT_USER() IDENTIFIED BY ... !
+      Get the current user, and shallow-copy the new password to them!
+    */
+    if (!tmp_Str->user.str && tmp_Str->password.str)
+      Str->password= tmp_Str->password;
+    
     /* Create user if needed */
-    error=replace_user_table(thd, tables[0].table, *Str,
+    error=replace_user_table(thd, tables[0].table, Str,
 			     0, revoke_grant, create_new_users,
                              test(thd->variables.sql_mode &
                                   MODE_NO_AUTO_CREATE_USER));
@@ -3967,9 +4537,9 @@ bool mysql_routine_grant(THD *thd, TABLE
       result= TRUE;
       continue;
     }
-
+    
     /* Create user if needed */
-    error=replace_user_table(thd, tables[0].table, *Str,
+    error=replace_user_table(thd, tables[0].table, Str,
 			     0, revoke_grant, create_new_users,
                              test(thd->variables.sql_mode &
                                   MODE_NO_AUTO_CREATE_USER));
@@ -4051,6 +4621,79 @@ bool mysql_routine_grant(THD *thd, TABLE
 }
 
 
+/**
+  Allocates a new buffer and calculates digested password hash based on plugin
+  and old_passwords. The old buffer containing the clear text password is
+  simply discarded as this memory belongs to the LEX will be freed when the
+  session ends.
+ 
+  @param THD the tread handler used for allocating memory
+  @param user_record[in, out] The user record
+ 
+  @return Failure state
+  @retval 0 OK
+  @retval 1 ERROR
+*/
+
+int digest_password(THD *thd, LEX_USER *user_record)
+{
+  /* Empty passwords stay empty */
+  if (user_record->password.length == 0)
+    return 0;
+
+#if defined(HAVE_OPENSSL)
+  /*
+    Transform password into a password hash 
+  */
+  if (user_record->plugin.str == sha256_password_plugin_name.str)
+  {
+    char *buff=  (char *) thd->alloc(CRYPT_MAX_PASSWORD_SIZE+1);
+    if (buff == NULL)
+      return 1;
+
+    my_make_scrambled_password(buff, user_record->password.str,
+                               user_record->password.length);
+    user_record->password.str= buff;
+    user_record->password.length= strlen(buff)+1;
+  }
+  else
+#endif
+  if (user_record->plugin.str == native_password_plugin_name.str ||
+      user_record->plugin.str == old_password_plugin_name.str)
+  {
+    if (thd->variables.old_passwords == 1)
+    {
+      char *buff= 
+        (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
+      if (buff == NULL)
+        return 1;
+
+      my_make_scrambled_password_323(buff, user_record->password.str,
+                                     user_record->password.length);
+      user_record->password.str= buff;
+      user_record->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323;
+    }
+    else
+    {
+      char *buff= 
+        (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
+      if (buff == NULL)
+        return 1;
+
+      my_make_scrambled_password_sha1(buff, user_record->password.str,
+                                      user_record->password.length);
+      user_record->password.str= buff;
+      user_record->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH;
+    }
+  } // end if native_password_plugin_name || old_password_plugin_name
+  else
+  {
+    user_record->password.str= 0;
+    user_record->password.length= 0;
+  }
+  return 0;
+}
+
 bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
                  ulong rights, bool revoke_grant, bool is_proxy)
 {
@@ -4162,8 +4805,8 @@ bool mysql_grant(THD *thd, const char *d
     */
     if (!tmp_Str->user.str && tmp_Str->password.str)
       Str->password= tmp_Str->password;
-
-    if (replace_user_table(thd, tables[0].table, *Str,
+ 
+    if (replace_user_table(thd, tables[0].table, Str,
                            (!db ? rights : 0), revoke_grant, create_new_users,
                            test(thd->variables.sql_mode &
                                 MODE_NO_AUTO_CREATE_USER)))
@@ -5397,6 +6040,15 @@ bool mysql_show_grants(THD *thd,LEX_USER
     global.append(lex_user->host.str,lex_user->host.length,
 		  system_charset_info);
     global.append ('\'');
+#if defined(HAVE_OPENSSL)
+    if (acl_user->plugin.str == sha256_password_plugin_name.str)
+    {
+      global.append(STRING_WITH_LEN(" IDENTIFIED BY PASSWORD '"));
+      global.append((const char *) &acl_user->auth_string.str[0]);
+      global.append('\'');
+    }
+    else
+#endif
     if (acl_user->salt_len)
     {
       char passwd_buff[SCRAMBLED_PASSWORD_CHAR_LENGTH+1];
@@ -6299,13 +6951,13 @@ static int handle_grant_struct(uint stru
     {
       switch ( struct_no ) {
       case 0:
-        acl_user->user= strdup_root(&mem, user_to->user.str);
-        acl_user->host.update_hostname(strdup_root(&mem, user_to->host.str));
+        acl_user->user= strdup_root(&global_acl_memory, user_to->user.str);
+        acl_user->host.update_hostname(strdup_root(&global_acl_memory, user_to->host.str));
         break;
 
       case 1:
-        acl_db->user= strdup_root(&mem, user_to->user.str);
-        acl_db->host.update_hostname(strdup_root(&mem, user_to->host.str));
+        acl_db->user= strdup_root(&global_acl_memory, user_to->user.str);
+        acl_db->host.update_hostname(strdup_root(&global_acl_memory, user_to->host.str));
         break;
 
       case 2:
@@ -6347,9 +6999,9 @@ static int handle_grant_struct(uint stru
         }
 
       case 5:
-        acl_proxy_user->set_user (&mem, user_to->user.str);
-        acl_proxy_user->host.update_hostname ((user_to->host.str && *user_to->host.str) ? 
-                    strdup_root(&mem, user_to->host.str) : NULL);
+        acl_proxy_user->set_user(&global_acl_memory, user_to->user.str);
+        acl_proxy_user->host.update_hostname((user_to->host.str && *user_to->host.str) ? 
+                                             strdup_root(&global_acl_memory, user_to->host.str) : NULL);
         break;
 
       }
@@ -6520,15 +7172,17 @@ static int handle_grant_data(TABLE_LIST 
 
 /**
   Auxiliary function for constructing a  user list string.
-  @param thd     Current thread.
+  This function is used for error reporting and logging.
+ 
+  @param thd     Thread context
   @param str     A String to store the user list.
   @param user    A LEX_USER which will be appended into user list.
   @param comma   If TRUE, append a ',' before the the user.
   @param ident   If TRUE, append ' IDENTIFIED BY/WITH...' after the user,
                  if the given user has credentials set with 'IDENTIFIED BY/WITH'
  */
-void append_user(THD *thd, String *str, LEX_USER *user, bool comma= TRUE,
-                 bool ident= FALSE)
+void append_user(THD *thd, String *str, LEX_USER *user, bool comma= true,
+                 bool ident= false)
 {
   String from_user(user->user.str, user->user.length, system_charset_info);
   String from_plugin(user->plugin.str, user->plugin.length, system_charset_info);
@@ -6543,7 +7197,11 @@ void append_user(THD *thd, String *str, 
 
   if (ident)
   {
-    if (user->plugin.str && (user->plugin.length > 0))
+    if (user->plugin.str && (user->plugin.length > 0) &&
+        memcmp(user->plugin.str, native_password_plugin_name.str,
+               user->plugin.length) &&
+        memcmp(user->plugin.str, old_password_plugin_name.str,
+               user->plugin.length))
     {
       /** 
           The plugin identifier is allowed to be specified,
@@ -6562,8 +7220,50 @@ void append_user(THD *thd, String *str, 
     else if (user->password.str)
     {
       str->append(STRING_WITH_LEN(" IDENTIFIED BY PASSWORD '"));
-      str->append(user->password.str, user->password.length);
-      str->append('\'');
+      if (user->uses_identified_by_password_clause)
+      {
+        str->append(user->password.str, user->password.length);
+        str->append("'");
+      }
+      else
+      {
+        /*
+          Password algorithm is chosen based on old_passwords variable or
+          TODO the new password_algorithm variable.
+          It is assumed that the variable hasn't changed since parsing.
+        */
+        if (thd->variables.old_passwords == 0)
+        {
+          /*
+            my_make_scrambled_password_sha1() requires a target buffer size of
+            SCRAMBLED_PASSWORD_CHAR_LENGTH + 1.
+            The extra character is for the probably originate from either '\0'
+            or the initial '*' character.
+          */
+          char tmp[SCRAMBLED_PASSWORD_CHAR_LENGTH + 1];
+          my_make_scrambled_password_sha1(tmp, user->password.str,
+                                          user->password.length);
+          str->append(tmp);
+        }
+#if defined(HAVE_OPENSSL)
+        else if (thd->variables.old_passwords == 2)
+        {
+          char tmp[CRYPT_MAX_PASSWORD_SIZE + 1];
+          my_make_scrambled_password(tmp, user->password.str,
+                                     user->password.length);
+          str->append(tmp, user->password.length, system_charset_info);
+        }
+#endif
+        else
+        {
+          /*
+            Legacy password algorithm is just an obfuscation of a plain text
+            so we're not going to write this.
+          */
+          str->append("<secret>");
+        }
+        str->append("'");
+      }
     }
   }
 }
@@ -6617,6 +7317,12 @@ bool mysql_create_user(THD *thd, List <L
 
   while ((tmp_user_name= user_list++))
   {
+    /*
+      If tmp_user_name.user.str is == NULL then
+      user_name := tmp_user_name.
+      Else user_name.user := sctx->user
+      TODO and all else is turned to NULL !! Why?
+    */
     if (!(user_name= get_current_user(thd, tmp_user_name)))
     {
       result= TRUE;
@@ -6624,27 +7330,36 @@ bool mysql_create_user(THD *thd, List <L
     }
 
     /*
+      If no plugin is given, set a default plugin
+    */
+    if (user_name->plugin.length == 0 && user_name->uses_identified_with_clause)
+    {
+      user_name->plugin.str= default_auth_plugin_name.str;
+      user_name->plugin.length= default_auth_plugin_name.length;
+    }
+
+    /*
       Search all in-memory structures and grant tables
       for a mention of the new user name.
     */
     if (handle_grant_data(tables, 0, user_name, NULL))
     {
-      append_user(thd, &wrong_users, user_name, wrong_users.length() > 0, 
-                  FALSE);
+      append_user(thd, &wrong_users, user_name, wrong_users.length() > 0,
+                  false);
       result= TRUE;
       continue;
     }
 
-    if (replace_user_table(thd, tables[0].table, *user_name, 0, 0, 1, 0))
+    if (replace_user_table(thd, tables[0].table, user_name, 0, 0, 1, 0))
     {
       append_user(thd, &wrong_users, user_name, wrong_users.length() > 0,
-                  FALSE);
+                  false);
       result= TRUE;
       continue;
     }
 
     some_users_created= TRUE;
-  }
+  } // END while tmp_user_name= user_lists++
 
   mysql_mutex_unlock(&acl_cache->lock);
 
@@ -6724,8 +7439,7 @@ bool mysql_drop_user(THD *thd, List <LEX
     }  
     if (handle_grant_data(tables, 1, user_name, NULL) <= 0)
     {
-      append_user(thd, &wrong_users, user_name, wrong_users.length() > 0,
-                  FALSE);
+      append_user(thd, &wrong_users, user_name, wrong_users.length() > 0, FALSE);
       result= TRUE;
       continue;
     }
@@ -6821,8 +7535,7 @@ bool mysql_rename_user(THD *thd, List <L
     if (handle_grant_data(tables, 0, user_to, NULL) ||
         handle_grant_data(tables, 0, user_from, user_to) <= 0)
     {
-      append_user(thd, &wrong_users, user_from, wrong_users.length() > 0, 
-                  FALSE);
+      append_user(thd, &wrong_users, user_from, wrong_users.length() > 0, FALSE);
       result= TRUE;
       continue;
     }
@@ -6910,7 +7623,7 @@ bool mysql_user_password_expire(THD *thd
   while ((tmp_user_from= user_list++))
   {
     ACL_USER *acl_user;
-
+   
     if (!(user_from= get_current_user(thd, tmp_user_from)))
     {
       result= true;
@@ -6919,13 +7632,14 @@ bool mysql_user_password_expire(THD *thd
       continue;
     }
 
+    enum mysql_user_table_field password_field= MYSQL_USER_FIELD_PASSWORD;
     if ((!(acl_user= find_acl_user(user_from->host.str,
                                    user_from->user.str, TRUE))) ||
-        update_user_table(thd, table,
-                          acl_user->host.get_host() ?
-                            acl_user->host.get_host() : "",
-                          acl_user->user ? acl_user->user : "",
-                          NULL, 0, 'Y'))
+         update_user_table(thd, table,
+                           acl_user->host.get_host() ?
+                           acl_user->host.get_host() : "",
+                           acl_user->user ? acl_user->user : "",
+                           NULL, 0, password_field,'Y'))
     {
       result= true;
       append_user(thd, &wrong_users, user_from, wrong_users.length() > 0,
@@ -6934,7 +7648,6 @@ bool mysql_user_password_expire(THD *thd
     }
 
     acl_user->password_expired= true;
-
     some_passwords_expired= true;
   }
 
@@ -7025,7 +7738,7 @@ bool mysql_revoke_all(THD *thd,  List <L
     }
 
     if (replace_user_table(thd, tables[0].table,
-			   *lex_user, ~(ulong)0, 1, 0, 0))
+			   lex_user, ~(ulong) 0, 1, 0, 0))
     {
       result= -1;
       continue;
@@ -7342,7 +8055,6 @@ bool sp_grant_privileges(THD *thd, const
   List<LEX_USER> user_list;
   bool result;
   ACL_USER *au;
-  char passwd_buff[SCRAMBLED_PASSWORD_CHAR_LENGTH+1];
   Dummy_error_handler error_handler;
   DBUG_ENTER("sp_grant_privileges");
 
@@ -7382,37 +8094,10 @@ bool sp_grant_privileges(THD *thd, const
   combo->password= empty_lex_str;
   combo->plugin= empty_lex_str;
   combo->auth= empty_lex_str;
-
-  if(au)
-  {
-    if (au->salt_len)
-    {
-      if (au->salt_len == SCRAMBLE_LENGTH)
-      {
-        make_password_from_salt(passwd_buff, au->salt);
-        combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH;
-      }
-      else if (au->salt_len == SCRAMBLE_LENGTH_323)
-      {
-        make_password_from_salt_323(passwd_buff, (ulong *) au->salt);
-        combo->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323;
-      }
-      else
-      {
-        push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_PASSWD_LENGTH,
-                            ER(ER_PASSWD_LENGTH), SCRAMBLED_PASSWORD_CHAR_LENGTH);
-        return TRUE;
-      }
-      combo->password.str= passwd_buff;
-    }
-
-    if (au->plugin.str != native_password_plugin_name.str &&
-        au->plugin.str != old_password_plugin_name.str)
-    {
-      combo->plugin= au->plugin;
-      combo->auth= au->auth_string;
-    }
-  }
+  combo->uses_identified_by_clause= false;
+  combo->uses_identified_with_clause= false;
+  combo->uses_identified_by_password_clause= false;
+  combo->uses_authentication_string_clause= false;
 
   if (user_list.push_back(combo))
     DBUG_RETURN(TRUE);
@@ -8197,9 +8882,51 @@ struct MPVIO_EXT :public MYSQL_PLUGIN_VI
   char *host;
   Thd_charset_adapter *charset_adapter;
   LEX_STRING acl_user_plugin;
+  int vio_is_encrypted;
 };
 
 /**
+ Sets the default default auth plugin value if no option was specified.
+*/
+void init_default_auth_plugin()
+{
+  default_auth_plugin_name.str= native_password_plugin_name.str;
+  default_auth_plugin_name.length= native_password_plugin_name.length;
+}
+
+
+/**
+ Initialize default authentication plugin based on command line options or
+ configuration file settings.
+ 
+ @param plugin_name Name of the plugin
+ @param plugin_name_length Length of the string
+ 
+ Setting default_auth_plugin may also affect old_passwords
+
+*/
+
+int set_default_auth_plugin(char *plugin_name, int plugin_name_length)
+{
+#if defined(HAVE_OPENSSL)
+  default_auth_plugin_name.str= plugin_name;
+  default_auth_plugin_name.length= plugin_name_length;
+  
+  optimize_plugin_compare_by_pointer(&default_auth_plugin_name);
+ 
+  if (default_auth_plugin_name.str == sha256_password_plugin_name.str)
+  {
+    /*
+      Adjust default password algorithm to fit the default authentication
+      method.
+    */
+    global_system_variables.old_passwords= 2;
+  }
+#endif
+  return 0;
+}
+
+/**
   a helper function to report an access denied error in all the proper places
 */
 static void login_failed_error(MPVIO_EXT *mpvio, int passwd_used)
@@ -8523,9 +9250,14 @@ static bool find_mpvio_user(MPVIO_EXT *m
         acl_user_tmp->host.compare_hostname(mpvio->host, mpvio->ip))
     {
       mpvio->acl_user= acl_user_tmp->copy(mpvio->mem_root);
-      if (acl_user_tmp->plugin.str == native_password_plugin_name.str ||
-          acl_user_tmp->plugin.str == old_password_plugin_name.str)
-        mpvio->acl_user_plugin= acl_user_tmp->plugin;
+
+      /*
+        When setting mpvio->acl_user_plugin we can save memory allocation if
+        this is a built in plugin.
+      */
+      optimize_plugin_compare_by_pointer(&acl_user_tmp->plugin);
+      if (auth_plugin_is_built_in(acl_user_tmp->plugin.str))
+        mpvio->acl_user_plugin= mpvio->acl_user->plugin;
       else
         make_lex_string_root(mpvio->mem_root, 
                              &mpvio->acl_user_plugin, 
@@ -8542,11 +9274,13 @@ static bool find_mpvio_user(MPVIO_EXT *m
     DBUG_RETURN (1);
   }
 
-  /* user account requires non-default plugin and the client is too old */
-  if (mpvio->acl_user->plugin.str != native_password_plugin_name.str &&
-      mpvio->acl_user->plugin.str != old_password_plugin_name.str &&
+  if (my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
+                    native_password_plugin_name.str) != 0 &&
+      my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
+                    old_password_plugin_name.str) != 0 &&
       !(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH))
   {
+    /* user account requires non-default plugin and the client is too old */
     DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
                               native_password_plugin_name.str));
     DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
@@ -8562,7 +9296,7 @@ static bool find_mpvio_user(MPVIO_EXT *m
   strmake(mpvio->auth_info.authenticated_as, mpvio->acl_user->user ?
           mpvio->acl_user->user : "", USERNAME_LENGTH);
   DBUG_PRINT("info", ("exit: user=%s, auth_string=%s, authenticated as=%s"
-                      "plugin=%s",
+                      ", plugin=%s",
                       mpvio->auth_info.user_name,
                       mpvio->auth_info.auth_string,
                       mpvio->auth_info.authenticated_as,
@@ -8751,7 +9485,6 @@ static bool parse_com_change_user_packet
 }
 
 #ifndef EMBEDDED_LIBRARY
-
 /** Get a string according to the protocol of the underlying buffer. */
 typedef char * (*get_proto_string_func_t) (char **, size_t *, size_t *);
 
@@ -8861,13 +9594,69 @@ char *get_40_protocol_string(char **buff
 */
 
 static
-char *get_length_encoded_string(char **buffer,
-                                size_t *max_bytes_available,
-                                size_t *string_length)
+char *get_56_lenc_string(char **buffer,
+                         size_t *max_bytes_available,
+                         size_t *string_length)
 {
+  static char empty_string[1]= { '\0' };
+  char *begin= *buffer;
+
   if (*max_bytes_available == 0)
     return NULL;
 
+  /*
+    If the length encoded string has the length 0
+    the total size of the string is only one byte long (the size byte)
+  */
+  if (*begin == 0)
+  {
+    *string_length= 0;
+    --*max_bytes_available;
+    ++*buffer;
+    /*
+      Return a pointer to the \0 character so the return value will be
+      an empty string.
+    */
+    return empty_string;
+  }
+
+  *string_length= (size_t)net_field_length_ll((uchar **)buffer);
+
+  size_t len_len= (size_t)(*buffer - begin);
+  
+  if (*string_length + len_len > *max_bytes_available)
+    return NULL;
+
+  *max_bytes_available -= *string_length + len_len;
+  *buffer += *string_length;
+  return (char *)(begin + len_len);
+}
+
+
+/**
+  Get a length encoded string from a user-supplied buffer.
+
+  @param buffer[in, out] The buffer to scan; updates position after scan.
+  @param max_bytes_available[in, out] Limit the number of bytes to scan
+  @param string_length[out] Number of characters scanned
+
+  @remark In case the length is zero, then the total size of the string is
+    considered to be 1 byte; the size byte.
+
+  @note the maximum size of the string is 255 because the header is always 
+    1 byte.
+  @return pointer to first byte after the header in buffer.
+    @retval NULL The buffer content is malformed
+*/
+
+static
+char *get_41_lenc_string(char **buffer,
+                         size_t *max_bytes_available,
+                         size_t *string_length)
+{
+ if (*max_bytes_available == 0)
+    return NULL;
+
   /* Do double cast to prevent overflow from signed / unsigned conversion */
   size_t str_len= (size_t)(unsigned char)**buffer;
 
@@ -8895,7 +9684,7 @@ char *get_length_encoded_string(char **b
   *buffer+= *string_length + 1;
   return str;
 }
-#endif
+#endif // EMBEDDED LIBRARY
 
 
 /* the packet format is described in send_client_reply_packet() */
@@ -9010,6 +9799,9 @@ skip_to_ssl:
 			   pkt_len));
       return packet_error;
     }
+    /* mark vio as encrypted */
+    mpvio->vio_is_encrypted= 1;
+  
     /*
       A new packet was read and the statistics reflecting the remaining bytes
       in the packet must be updated.
@@ -9059,6 +9851,30 @@ skip_to_ssl:
     get_string= get_40_protocol_string;
 
   /*
+    When the ability to change default plugin require that the initial password
+   field can be of arbitrary size. However, the 41 client-server protocol limits
+   the length of the auth-data-field sent from client to server to 255 bytes
+   (CLIENT_SECURE_CONNECTION). The solution is to change the type of the field
+   to a true length encoded string and indicate the protocol change with a new
+   client capability flag: CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA.
+  */
+  get_proto_string_func_t get_length_encoded_string;
+
+  if (mpvio->client_capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA)
+    get_length_encoded_string= get_56_lenc_string;
+  else
+    get_length_encoded_string= get_41_lenc_string;
+
+  /*
+    The CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA capability depends on the
+    CLIENT_SECURE_CONNECTION. Refuse any connection which have the first but
+    not the latter.
+  */
+  if ((mpvio->client_capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA) &&
+      !(mpvio->client_capabilities & CLIENT_SECURE_CONNECTION))
+    return packet_error;
+
+  /*
     In order to safely scan a head for '\0' string terminators
     we must keep track of how many bytes remain in the allocated
     buffer or we might read past the end of the buffer.
@@ -9081,7 +9897,7 @@ skip_to_ssl:
   if (mpvio->client_capabilities & CLIENT_SECURE_CONNECTION)
   {
     /*
-      4.1+ password. First byte is password length.
+      Get the password field.
     */
     passwd= get_length_encoded_string(&end, &bytes_remaining_in_packet,
                                       &passwd_len);
@@ -9526,25 +10342,33 @@ static bool acl_check_ssl(THD *thd, cons
 #endif
 
 
-static int do_auth_once(THD *thd, const LEX_STRING *auth_plugin_name,
+static int do_auth_once(THD *thd, LEX_STRING *auth_plugin_name,
                         MPVIO_EXT *mpvio)
 {
+  DBUG_ENTER("do_auth_once");
   int res= CR_OK, old_status= MPVIO_EXT::FAILURE;
   bool unlock_plugin= false;
-  plugin_ref plugin;
+  plugin_ref plugin= NULL;
 
   if (auth_plugin_name->str == native_password_plugin_name.str)
     plugin= native_password_plugin;
-  else
 #ifndef EMBEDDED_LIBRARY
+  else
   if (auth_plugin_name->str == old_password_plugin_name.str)
     plugin= old_password_plugin;
-  else if ((plugin= my_plugin_lock_by_name(thd, auth_plugin_name,
-                                           MYSQL_AUTHENTICATION_PLUGIN)))
-    unlock_plugin= true;
   else
+  {
+    if (auth_plugin_name->length == 0)
+    {
+      auth_plugin_name->str= default_auth_plugin_name.str;
+      auth_plugin_name->length= default_auth_plugin_name.length;
+    }
+    if ((plugin= my_plugin_lock_by_name(thd, auth_plugin_name,
+                                        MYSQL_AUTHENTICATION_PLUGIN)))
+      unlock_plugin= true;
+  }
 #endif
-    plugin= NULL;
+
     
   mpvio->plugin= plugin;
   old_status= mpvio->status;
@@ -9578,7 +10402,7 @@ static int do_auth_once(THD *thd, const 
   if (old_status == MPVIO_EXT::RESTART && mpvio->status == MPVIO_EXT::RESTART)
     mpvio->status= MPVIO_EXT::FAILURE; // reset to the default
 
-  return res;
+  DBUG_RETURN(res);
 }
 
 
@@ -9595,6 +10419,12 @@ server_mpvio_initialize(THD *thd, MPVIO_
     (unsigned int) strlen(thd->security_ctx->host_or_ip);
   mpvio->auth_info.user_name= NULL;
   mpvio->auth_info.user_name_length= 0;
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
+  if (thd->net.vio && thd->net.vio->ssl_arg)
+    mpvio->vio_is_encrypted= 1;
+  else
+#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
+    mpvio->vio_is_encrypted= 0;
   mpvio->status= MPVIO_EXT::FAILURE;
 
   mpvio->client_capabilities= thd->client_capabilities;
@@ -9641,7 +10471,7 @@ acl_authenticate(THD *thd, uint com_chan
   MPVIO_EXT mpvio;
   Thd_charset_adapter charset_adapter(thd);
 
-  const LEX_STRING *auth_plugin_name= default_auth_plugin_name;
+  LEX_STRING auth_plugin_name= default_auth_plugin_name;
   enum  enum_server_command command= com_change_user_pkt_len ? COM_CHANGE_USER
                                                              : COM_CONNECT;
 
@@ -9688,7 +10518,7 @@ acl_authenticate(THD *thd, uint com_chan
      the correct plugin.
     */
 
-    res= do_auth_once(thd, auth_plugin_name, &mpvio);  
+    res= do_auth_once(thd, &auth_plugin_name, &mpvio);  
   }
 
   /*
@@ -9699,11 +10529,10 @@ acl_authenticate(THD *thd, uint com_chan
   {
     DBUG_ASSERT(mpvio.acl_user);
     DBUG_ASSERT(command == COM_CHANGE_USER ||
-                my_strcasecmp(system_charset_info, auth_plugin_name->str,
+                my_strcasecmp(system_charset_info, auth_plugin_name.str,
                               mpvio.acl_user->plugin.str));
-    auth_plugin_name= &mpvio.acl_user->plugin;
-
-    res= do_auth_once(thd, auth_plugin_name, &mpvio);
+    auth_plugin_name= mpvio.acl_user->plugin;
+    res= do_auth_once(thd, &auth_plugin_name, &mpvio);
   }
 
   server_mpvio_update_thd(thd, &mpvio);
@@ -9809,6 +10638,8 @@ acl_authenticate(THD *thd, uint com_chan
         DBUG_RETURN(1);
       }
       acl_user= acl_proxy_user->copy(thd->mem_root);
+      DBUG_PRINT("info", ("User %s is a PROXY and will assume a PROXIED"
+                          " identity %s", auth_user, acl_user->user));
       mysql_mutex_unlock(&acl_cache->lock);
     }
 #endif
@@ -10077,6 +10908,439 @@ static int old_password_authenticate(MYS
   return CR_AUTH_HANDSHAKE;
 }
 
+
+/**
+  Interface for querying the MYSQL_PUBLIC_VIO about encryption state.
+ 
+*/
+
+int my_vio_is_encrypted(MYSQL_PLUGIN_VIO *vio)
+{
+  MPVIO_EXT *mpvio= (MPVIO_EXT *) vio;
+  return (mpvio->vio_is_encrypted);
+}
+
+#if defined(HAVE_OPENSSL)
+#define MAX_CIPHER_LENGTH 1024
+#if !defined(HAVE_YASSL)
+#define AUTH_DEFAULT_RSA_PRIVATE_KEY "private_key.pem"
+#define AUTH_DEFAULT_RSA_PUBLIC_KEY "public_key.pem"
+
+char *auth_rsa_private_key_path;
+char *auth_rsa_public_key_path;
+
+class Rsa_authentication_keys
+{
+private:
+  RSA *m_public_key;
+  RSA *m_private_key;
+  int m_cipher_len;
+  char *m_pem_public_key;
+public:
+  Rsa_authentication_keys()
+  {
+    m_cipher_len= 0;
+    m_private_key= 0;
+    m_public_key= 0;
+  }
+  
+  ~Rsa_authentication_keys()
+  {
+  }
+
+  void free_memory()
+  {
+    if (m_private_key)
+    {
+      RSA_free(m_private_key);
+      RSA_free(m_public_key);
+    }
+    if (m_pem_public_key)
+      delete [] m_pem_public_key;
+  }
+
+  void *allocate_pem_buffer(size_t buffer_len)
+  {
+    m_pem_public_key= new char[buffer_len];
+    return m_pem_public_key;
+  }
+
+  RSA *get_private_key()
+  {
+    return m_private_key;
+  }
+
+  RSA *get_public_key()
+  {
+    return m_public_key;
+  }
+
+  int get_cipher_length()
+  {
+    return (m_cipher_len= RSA_size(m_public_key));
+  }
+
+  int set_private_key(RSA *pk)
+  {
+    m_private_key= pk;
+    return 0;
+  }
+
+  int set_public_key(RSA *pk)
+  {
+    m_public_key= pk;
+    return 0;
+  }
+
+  const char *get_public_key_as_pem(void)
+  {
+    return m_pem_public_key;
+  }
+  
+};
+
+static Rsa_authentication_keys g_rsa_keys;
+
+/**
+ 
+*/
+int show_rsa_public_key(THD *thd, SHOW_VAR *var, char *buff)
+{ 
+  var->type= SHOW_CHAR;
+  var->value= const_cast<char *>(g_rsa_keys.get_public_key_as_pem());
+    
+  return 0;
+}
+
+void deinit_rsa_keys(void)
+{
+  g_rsa_keys.free_memory();  
+}
+
+
+/**
+  Loads the RSA key pair from disk and store them in a global variable. 
+ 
+ @see init_ssl()
+ 
+ @return Error code
+   @retval 0 Success
+   @retval 1 Error
+*/
+
+int init_rsa_keys(void)
+{
+  FILE *priv_key_file;
+  FILE *public_key_file;
+  String priv_keypath;
+  String pub_keypath;
+  int auth_rsa_private_key_path_len;
+  int auth_rsa_public_key_path_len;
+  
+  auth_rsa_private_key_path_len= strlen(auth_rsa_private_key_path);
+  auth_rsa_public_key_path_len= strlen(auth_rsa_public_key_path);
+  if (auth_rsa_private_key_path_len == 0 || auth_rsa_public_key_path_len == 0)
+  {
+     sql_print_information("RSA key files not found."
+                          " Some authentication plugins will not work.");
+    return 0;
+  }
+
+  /*
+     If a fully qualified path is entered use that, else assume the keys are 
+     stored in the data directory.
+  */
+  if (strchr(auth_rsa_private_key_path, FN_LIBCHAR) != NULL ||
+      strchr(auth_rsa_private_key_path, FN_LIBCHAR2) != NULL)
+    priv_keypath.set_quick(auth_rsa_private_key_path,
+                           auth_rsa_private_key_path_len, 
+                           system_charset_info);
+  else
+  {
+    priv_keypath.append(mysql_real_data_home, strlen(mysql_real_data_home));
+    if (priv_keypath[pub_keypath.length()] != FN_LIBCHAR)
+      priv_keypath.append(FN_LIBCHAR);
+    priv_keypath.append(auth_rsa_private_key_path);
+  }
+
+  if ((priv_key_file= fopen(priv_keypath.c_ptr(), "r")) == NULL)
+  {
+    sql_print_information("RSA private key file not found: %s."
+                          " Some authentication plugins will not work.",
+                          priv_keypath.c_ptr());
+    /* Don't return an error; server will still be able to operate. */
+    return 0;
+  }
+
+  if (strchr(auth_rsa_public_key_path, FN_LIBCHAR) != NULL ||
+      strchr(auth_rsa_public_key_path, FN_LIBCHAR2) != NULL)
+    pub_keypath.set_quick(auth_rsa_public_key_path,
+                          auth_rsa_public_key_path_len, 
+                          system_charset_info);
+  else
+  {
+    pub_keypath.append(mysql_real_data_home, strlen(mysql_real_data_home));
+    if (pub_keypath[pub_keypath.length()] != FN_LIBCHAR)
+      pub_keypath.append(FN_LIBCHAR);
+    pub_keypath.append(auth_rsa_public_key_path);
+  }
+
+  if ((public_key_file= fopen(pub_keypath.c_ptr(), "r")) == NULL)
+  {
+    sql_print_information("RSA public key file not found: %s."
+                          " Some authentication plugins will not work.",
+                          pub_keypath.c_ptr());
+    /* Don't return an error; server will still be able to operate. */
+    return 0;
+  }
+
+  RSA *rsa_private_key= RSA_new();
+  if (g_rsa_keys.set_private_key(PEM_read_RSAPrivateKey(priv_key_file,
+                                                        &rsa_private_key,
+                                                        0, 0)))
+  {
+    sql_print_error("Failure to parse RSA private key (file exists): %s",
+                    auth_rsa_private_key_path);
+    /* An intention has been made clear which can't be fulfilled; stop server.*/
+    return 1;
+    
+  }
+  
+  int filesize;
+  fseek(public_key_file, 0, SEEK_END);
+  filesize= ftell(public_key_file);
+  fseek(public_key_file, 0, SEEK_SET);
+  char *pem_file_buffer= (char *)g_rsa_keys.allocate_pem_buffer(filesize + 1);
+  (void) fread(pem_file_buffer, filesize, 1, public_key_file);
+  pem_file_buffer[filesize]= '\0';
+
+  if (int err= ferror(public_key_file))
+  {
+    sql_print_error("Failure code %d when reading RSA public key (%d bytes): %s",
+                    err, filesize, auth_rsa_private_key_path);
+    /* An intention has been made clear which can't be fulfilled; stop server.*/
+    return 1;
+  }
+  fseek(public_key_file, 0, SEEK_SET);
+
+  RSA *rsa_public_key= RSA_new();
+  if (g_rsa_keys.set_public_key(PEM_read_RSA_PUBKEY(public_key_file,
+                                                    &rsa_public_key,
+                                                    0, 0)))
+  {
+     sql_print_error("Failure to parse RSA public key (file exists): %s",
+                    auth_rsa_public_key_path);
+    /* An intention has been made clear which can't be fulfilled; stop server.*/
+    return 1;
+  }
+
+  return 0;
+}
+#endif // ifndef HAVE_YASSL
+
+static MYSQL_PLUGIN plugin_info_ptr;
+
+int init_sha256_password_handler(MYSQL_PLUGIN plugin_ref)
+{
+  plugin_info_ptr= plugin_ref;
+  return 0;
+}
+
+/** 
+ 
+ @param vio Virtual input-, output interface
+ @param info[out] Connection information
+ 
+ Authenticate the user by recieving a RSA or TLS encrypted password and
+ calculate a hash digest which should correspond to the user record digest
+ 
+ RSA keys are assumed to be pre-generated and supplied when server starts. If
+ the client hasn't got a public key it can request one.
+ 
+ TLS certificates and keys are assumed to be pre-generated and supplied when
+ server starts.
+ 
+*/
+
+static int sha256_password_authenticate(MYSQL_PLUGIN_VIO *vio,
+                                        MYSQL_SERVER_AUTH_INFO *info)
+{
+  uchar *pkt;
+  int pkt_len;
+  char  *user_salt_begin;
+  char  *user_salt_end;
+  char scramble[SCRAMBLE_LENGTH + 1];
+  char stage2[CRYPT_MAX_PASSWORD_SIZE + 1];
+  String scramble_response_packet;
+#if !defined(HAVE_YASSL)
+  int cipher_length= 0;
+  unsigned char plain_text[MAX_CIPHER_LENGTH];
+  RSA *private_key= NULL;
+  RSA *public_key= NULL;
+#endif
+
+  DBUG_ENTER("sha256_password_authenticate");
+
+  generate_user_salt(scramble, SCRAMBLE_LENGTH + 1);
+
+  if (vio->write_packet(vio, (unsigned char *) scramble, SCRAMBLE_LENGTH))
+    DBUG_RETURN(CR_ERROR);
+
+  /*
+    After the call to read_packet() the user name will appear in
+    mpvio->acl_user and info will contain current data.
+  */
+  if ((pkt_len= vio->read_packet(vio, &pkt)) == -1)
+    DBUG_RETURN(CR_ERROR);
+
+  /*
+    If first packet is a 0 byte then the client isn't sending any password
+    else the client will send a password.
+  */
+  if (pkt_len == 1 && *pkt == 0)
+  {
+    info->password_used= PASSWORD_USED_NO;
+    /*
+      Send OK signal; the authentication might still be rejected based on
+      host mask.
+    */
+    if (info->auth_string_length == 0)
+      DBUG_RETURN(CR_OK);
+    else
+      DBUG_RETURN(CR_ERROR);
+  }
+  else    
+    info->password_used= PASSWORD_USED_YES;
+
+  if (!my_vio_is_encrypted(vio))
+  {
+ #if !defined(HAVE_YASSL)
+    /*
+      Since a password is being used it must be encrypted by RSA since no 
+      other encryption is being active.
+    */
+    private_key= g_rsa_keys.get_private_key();
+    public_key=  g_rsa_keys.get_public_key();
+
+    /*
+      Without the keys encryption isn't possible.
+    */
+    if (private_key == NULL || public_key == NULL)
+    {
+      my_plugin_log_message(&plugin_info_ptr, MY_ERROR_LEVEL, 
+        "Authentication requires either RSA keys or SSL encryption");
+      DBUG_RETURN(CR_ERROR);
+    }
+      
+
+    if ((cipher_length= g_rsa_keys.get_cipher_length()) > MAX_CIPHER_LENGTH)
+    {
+      my_plugin_log_message(&plugin_info_ptr, MY_ERROR_LEVEL, 
+        "RSA key cipher length of %u is too long. Max value is %u.",
+        g_rsa_keys.get_cipher_length(), MAX_CIPHER_LENGTH);
+      DBUG_RETURN(CR_ERROR);
+    }
+
+    /*
+      Client sent a "public key request"-packet ?
+      If the first packet is 1 then the client will require a public key before
+      encrypting the password.
+    */
+    if (pkt_len == 1 && *pkt == 1)
+    {
+      uint pem_length= strlen(g_rsa_keys.get_public_key_as_pem());
+      if (vio->write_packet(vio,
+                            (unsigned char *)g_rsa_keys.get_public_key_as_pem(),
+                            pem_length))
+        DBUG_RETURN(CR_ERROR);
+      /* Get the encrypted response from the client */
+      if ((pkt_len= vio->read_packet(vio, &pkt)) == -1)
+        DBUG_RETURN(CR_ERROR);
+    }
+
+    /*
+      The packet will contain the cipher used. The length of the packet
+      must correspond to the expected cipher length.
+    */
+    if (pkt_len != cipher_length)
+      DBUG_RETURN(CR_ERROR);
+    
+    /* Decrypt password */
+    RSA_private_decrypt(cipher_length, pkt, plain_text, private_key,
+                        RSA_PKCS1_OAEP_PADDING);
+
+    plain_text[cipher_length]= '\0'; // safety
+    xor_string((char *) plain_text, cipher_length,
+               (char *) scramble, SCRAMBLE_LENGTH);
+
+    /*
+      Set packet pointers and length for the hash digest function below 
+    */
+    pkt= plain_text;
+    pkt_len= strlen((char *) plain_text) + 1; // include \0 intentionally.
+
+    if (pkt_len == 1)
+      DBUG_RETURN(CR_ERROR);
+#else
+    DBUG_RETURN(CR_ERROR);
+#endif
+  } // if(!my_vio_is_encrypter())
+
+  /* A password was sent to an account without a password */
+  if (info->auth_string_length == 0)
+    DBUG_RETURN(CR_ERROR);
+  
+  /*
+    Fetch user authentication_string and extract the password salt
+  */
+  user_salt_begin= (char *) info->auth_string;
+  user_salt_end= (char *) (info->auth_string + info->auth_string_length);
+  if (extract_user_salt(&user_salt_begin, &user_salt_end) != CRYPT_SALT_LENGTH)
+  {
+    /* User salt is not correct */
+    my_plugin_log_message(&plugin_info_ptr, MY_ERROR_LEVEL, 
+      "Password salt for user '%s' is corrupt.",
+      info->user_name);
+    DBUG_RETURN(CR_ERROR);
+  }
+
+  /* Create hash digest */
+  my_crypt_genhash(stage2,
+                     CRYPT_MAX_PASSWORD_SIZE,
+                     (char *) pkt,
+                     pkt_len-1, 
+                     (char *) user_salt_begin,
+                     (const char **) 0);
+
+  /* Compare the newly created hash digest with the password record */
+  int result= memcmp(info->auth_string,
+                     stage2,
+                     info->auth_string_length);
+
+  if (result == 0)
+    DBUG_RETURN(CR_OK);
+
+  DBUG_RETURN(CR_ERROR);
+}
+
+#if !defined(HAVE_YASSL)
+static MYSQL_SYSVAR_STR(private_key_path, auth_rsa_private_key_path,
+        PLUGIN_VAR_READONLY,
+        "A fully qualified path to the private RSA key used for authentication",
+        NULL, NULL, AUTH_DEFAULT_RSA_PRIVATE_KEY);
+static MYSQL_SYSVAR_STR(public_key_path, auth_rsa_public_key_path,
+        PLUGIN_VAR_READONLY,
+        "A fully qualified path to the public RSA key used for authentication",
+        NULL, NULL, AUTH_DEFAULT_RSA_PUBLIC_KEY);
+
+static struct st_mysql_sys_var* sha256_password_sysvars[]= {
+  MYSQL_SYSVAR(private_key_path),
+  MYSQL_SYSVAR(public_key_path),
+  0
+};
+#endif // HAVE_YASSL
+#endif // HAVE_OPENSSL
+
 static struct st_mysql_auth native_password_handler=
 {
   MYSQL_AUTHENTICATION_INTERFACE_VERSION,
@@ -10091,6 +11355,15 @@ static struct st_mysql_auth old_password
   old_password_authenticate
 };
 
+#if defined(HAVE_OPENSSL)
+static struct st_mysql_auth sha256_password_handler=
+{
+  MYSQL_AUTHENTICATION_INTERFACE_VERSION,
+  sha256_password_plugin_name.str,
+  sha256_password_authenticate
+};
+#endif
+
 mysql_declare_plugin(mysql_password)
 {
   MYSQL_AUTHENTICATION_PLUGIN,                  /* type constant    */
@@ -10122,6 +11395,28 @@ mysql_declare_plugin(mysql_password)
   NULL,                                         /* config options   */
   0,                                            /* flags            */
 }
+#if defined(HAVE_OPENSSL)
+,
+{
+  MYSQL_AUTHENTICATION_PLUGIN,                  /* type constant    */
+  &sha256_password_handler,                     /* type descriptor  */
+  sha256_password_plugin_name.str,              /* Name             */
+  "Oracle",                                     /* Author           */
+  "SHA256 password authentication",             /* Description      */
+  PLUGIN_LICENSE_GPL,                           /* License          */
+  &init_sha256_password_handler,                /* Init function    */
+  NULL,                                         /* Deinit function  */
+  0x0100,                                       /* Version (1.0)    */
+  NULL,                                         /* status variables */
+#if !defined(HAVE_YASSL)
+  sha256_password_sysvars,                      /* system variables */
+#else
+  NULL,
+#endif
+  NULL,                                         /* config options   */
+  0                                             /* flags            */
+}
+#endif
 mysql_declare_plugin_end;
 
 /*  

=== modified file 'sql/sql_acl.h'
--- a/sql/sql_acl.h	2012-05-28 10:10:17 +0000
+++ b/sql/sql_acl.h	2012-06-04 15:35:18 +0000
@@ -178,6 +178,54 @@ enum mysql_db_table_field
   MYSQL_DB_FIELD_COUNT
 };
 
+enum mysql_user_table_field
+{
+  MYSQL_USER_FIELD_HOST= 0,
+  MYSQL_USER_FIELD_USER,
+  MYSQL_USER_FIELD_PASSWORD,
+  MYSQL_USER_FIELD_SELECT_PRIV,
+  MYSQL_USER_FIELD_INSERT_PRIV,
+  MYSQL_USER_FIELD_UPDATE_PRIV,
+  MYSQL_USER_FIELD_DELETE_PRIV,
+  MYSQL_USER_FIELD_CREATE_PRIV,
+  MYSQL_USER_FIELD_DROP_PRIV,
+  MYSQL_USER_FIELD_RELOAD_PRIV,
+  MYSQL_USER_FIELD_SHUTDOWN_PRIV,
+  MYSQL_USER_FIELD_PROCESS_PRIV,
+  MYSQL_USER_FIELD_FILE_PRIV,
+  MYSQL_USER_FIELD_GRANT_PRIV,
+  MYSQL_USER_FIELD_REFERENCES_PRIV,
+  MYSQL_USER_FIELD_INDEX_PRIV,
+  MYSQL_USER_FIELD_ALTER_PRIV,
+  MYSQL_USER_FIELD_SHOW_DB_PRIV,
+  MYSQL_USER_FIELD_SUPER_PRIV,
+  MYSQL_USER_FIELD_CREATE_TMP_TABLE_PRIV,
+  MYSQL_USER_FIELD_LOCK_TABLES_PRIV,
+  MYSQL_USER_FIELD_EXECUTE_PRIV,
+  MYSQL_USER_FIELD_REPL_SLAVE_PRIV,
+  MYSQL_USER_FIELD_REPL_CLIENT_PRIV,
+  MYSQL_USER_FIELD_CREATE_VIEW_PRIV,
+  MYSQL_USER_FIELD_SHOW_VIEW_PRIV,
+  MYSQL_USER_FIELD_CREATE_ROUTINE_PRIV,
+  MYSQL_USER_FIELD_ALTER_ROUTINE_PRIV,
+  MYSQL_USER_FIELD_CREATE_USER_PRIV,
+  MYSQL_USER_FIELD_EVENT_PRIV,
+  MYSQL_USER_FIELD_TRIGGER_PRIV,
+  MYSQL_USER_FIELD_CREATE_TABLESPACE_PRIV,
+  MYSQL_USER_FIELD_SSL_TYPE,
+  MYSQL_USER_FIELD_SSL_CIPHER,
+  MYSQL_USER_FIELD_X509_ISSUER,
+  MYSQL_USER_FIELD_X509_SUBJECT,
+  MYSQL_USER_FIELD_MAX_QUESTIONS,
+  MYSQL_USER_FIELD_MAX_UPDATES,
+  MYSQL_USER_FIELD_MAX_CONNECTIONS,
+  MYSQL_USER_FIELD_MAX_USER_CONNECTIONS,
+  MYSQL_USER_FIELD_PLUGIN,
+  MYSQL_USER_FIELD_AUTHENTICATION_STRING,
+  MYSQL_USER_FIELD_PASSWORD_EXPIRED,
+  MYSQL_USER_FIELD_COUNT
+};
+
 extern const TABLE_FIELD_DEF mysql_db_table_def;
 extern bool mysql_user_table_is_in_short_password_format;
 extern const char *command_array[];
@@ -187,7 +235,8 @@ extern uint        command_lengths[];
 /* prototypes */
 
 bool hostname_requires_resolving(const char *hostname);
-void append_user(THD *thd, String *str, LEX_USER *user, bool comma, bool passwd);
+void append_user(THD *thd, String *str, LEX_USER *user, bool comma,
+                 bool passwd);
 void append_int(String *str, const char *txt, size_t len,
                 long val, int cond);
 my_bool  acl_init(bool dont_read_acl_tables);
@@ -252,6 +301,7 @@ int fill_schema_schema_privileges(THD *t
 int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, Item *cond);
 int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, Item *cond);
 int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr);
+int digest_password(THD *thd, LEX_USER *user_record);
 int check_password_strength(String *password);
 void check_password_policy(String *password);
 #ifdef NO_EMBEDDED_ACCESS_CHECKS
@@ -390,4 +440,8 @@ get_cached_table_access(GRANT_INTERNAL_I
 
 bool acl_check_proxy_grant_access (THD *thd, const char *host, const char *user,
                                    bool with_grant);
+
+void init_default_auth_plugin();
+int set_default_auth_plugin(char *, int);
+
 #endif /* SQL_ACL_INCLUDED */

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2012-06-04 04:50:38 +0000
+++ b/sql/sql_class.h	2012-06-04 15:35:18 +0000
@@ -501,7 +501,7 @@ typedef struct system_variables
   my_bool keep_files_on_create;
 
   my_bool old_alter_table;
-  my_bool old_passwords;
+  uint old_passwords;
   my_bool big_tables;
 
   plugin_ref table_plugin;

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2012-06-05 05:58:05 +0000
+++ b/sql/sql_parse.cc	2012-06-05 07:56:01 +0000
@@ -6033,25 +6033,27 @@ void mysql_parse(THD *thd, char *rawbuf,
                       ? (found_semicolon - thd->query())
                       : thd->query_length();
 
-
-    /*
-      See whether we can do any query rewriting. opt_log_raw only controls
-      writing to the general log, so rewriting still needs to happen because
-      the other logs (binlog, slow query log, ...) can not be set to raw mode
-      for security reasons.
-    */
-    mysql_rewrite_query(thd);
-
-    if (thd->rewritten_query.length())
-      lex->safe_to_cache_query= FALSE; // see comments below 
-
-    if (!thd->slave_thread && !opt_log_raw)
+    if (!err)
     {
+      /*
+        See whether we can do any query rewriting. opt_log_raw only controls
+        writing to the general log, so rewriting still needs to happen because
+        the other logs (binlog, slow query log, ...) can not be set to raw mode
+        for security reasons.
+      */
+      mysql_rewrite_query(thd);
+
       if (thd->rewritten_query.length())
-        general_log_write(thd, COM_QUERY, thd->rewritten_query.c_ptr_safe(),
-                                          thd->rewritten_query.length());
-      else
-        general_log_write(thd, COM_QUERY, thd->query(), qlen);
+        lex->safe_to_cache_query= false; // see comments below 
+
+      if (!thd->slave_thread && !opt_log_raw)
+      {
+        if (thd->rewritten_query.length())
+          general_log_write(thd, COM_QUERY, thd->rewritten_query.c_ptr_safe(),
+                                            thd->rewritten_query.length());
+        else
+          general_log_write(thd, COM_QUERY, thd->query(), qlen);
+      }
     }
 
     if (!err)
@@ -6133,6 +6135,7 @@ void mysql_parse(THD *thd, char *rawbuf,
 
       query_cache_abort(&thd->query_cache_tls);
     }
+
     THD_STAGE_INFO(thd, stage_freeing_items);
     sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size);
     sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size);
@@ -7722,6 +7725,10 @@ void get_default_definer(THD *thd, LEX_U
   definer->password= null_lex_str;
   definer->plugin= empty_lex_str;
   definer->auth= empty_lex_str;
+  definer->uses_identified_with_clause= false;
+  definer->uses_identified_by_clause= false;
+  definer->uses_authentication_string_clause= false;
+  definer->uses_identified_by_password_clause= false;
 }
 
 
@@ -7775,7 +7782,10 @@ LEX_USER *create_definer(THD *thd, LEX_S
   definer->host= *host_name;
   definer->password.str= NULL;
   definer->password.length= 0;
-
+  definer->uses_authentication_string_clause= false;
+  definer->uses_identified_by_clause= false;
+  definer->uses_identified_by_password_clause= false;
+  definer->uses_identified_with_clause= false;
   return definer;
 }
 
@@ -7795,7 +7805,31 @@ LEX_USER *create_definer(THD *thd, LEX_S
 LEX_USER *get_current_user(THD *thd, LEX_USER *user)
 {
   if (!user->user.str)  // current_user
-    return create_default_definer(thd);
+  {
+    LEX_USER *default_definer= create_default_definer(thd);
+    if (default_definer)
+    {
+      /*
+        Inherit parser semantics from the statement in which the user parameter
+        was used.
+        This is needed because a st_lex_user is both used as a component in an
+        AST and as a specifier for a particular user in the ACL subsystem.
+      */
+      default_definer->uses_authentication_string_clause=
+        user->uses_authentication_string_clause;
+      default_definer->uses_identified_by_clause=
+        user->uses_identified_by_clause;
+      default_definer->uses_identified_by_password_clause=
+        user->uses_identified_by_password_clause;
+      default_definer->uses_identified_with_clause=
+        user->uses_identified_with_clause;
+      default_definer->plugin.str= user->plugin.str;
+      default_definer->plugin.length= user->plugin.length;
+      default_definer->auth.str= user->auth.str;
+      default_definer->auth.length= user->auth.length;
+      return default_definer;
+    }
+  }
 
   return user;
 }

=== modified file 'sql/sql_rewrite.cc'
--- a/sql/sql_rewrite.cc	2012-05-16 11:03:43 +0000
+++ b/sql/sql_rewrite.cc	2012-06-04 15:35:18 +0000
@@ -116,7 +116,7 @@ static void mysql_rewrite_grant(THD *thd
     {
       if ((user_name= get_current_user(thd, tmp_user_name)))
       {
-        append_user(thd, rlb, user_name, comma, TRUE);
+        append_user(thd, rlb, user_name, comma, true);
         comma= TRUE;
       }
     }

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2012-06-06 12:12:51 +0000
+++ b/sql/sql_yacc.yy	2012-06-07 11:48:13 +0000
@@ -3083,7 +3083,7 @@ sp_decl:
             sp_instr_hpush_jump *i=
               new (thd->mem_root)
                 sp_instr_hpush_jump(sp->instructions(), handler_pctx, h);
-
+            
             if (!i || sp->add_instr(thd, i))
               MYSQL_YYABORT;
 
@@ -9790,7 +9790,7 @@ function_call_conflict:
           {
             THD *thd= YYTHD;
             Item* i1;
-            if (thd->variables.old_passwords)
+            if (thd->variables.old_passwords == 1)
               i1= new (thd->mem_root) Item_func_old_password($3);
             else
               i1= new (thd->mem_root) Item_func_password($3);
@@ -13843,12 +13843,16 @@ user:
             THD *thd= YYTHD;
             if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
               MYSQL_YYABORT;
-            $$->user = $1;
+            $$->user= $1;
             $$->host.str= (char *) "%";
             $$->host.length= 1;
             $$->password= null_lex_str; 
             $$->plugin= empty_lex_str;
             $$->auth= empty_lex_str;
+            $$->uses_identified_by_clause= false;
+            $$->uses_identified_with_clause= false;
+            $$->uses_identified_by_password_clause= false;
+            $$->uses_authentication_string_clause= false;
 
             if (check_string_char_length(&$$->user, ER(ER_USERNAME),
                                          USERNAME_CHAR_LENGTH,
@@ -13860,10 +13864,15 @@ user:
             THD *thd= YYTHD;
             if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
               MYSQL_YYABORT;
-            $$->user = $1; $$->host=$3;
+            $$->user= $1;
+            $$->host= $3;
             $$->password= null_lex_str; 
             $$->plugin= empty_lex_str;
             $$->auth= empty_lex_str;
+            $$->uses_identified_by_clause= false;
+            $$->uses_identified_with_clause= false;
+            $$->uses_identified_by_password_clause= false;
+            $$->uses_authentication_string_clause= false;
 
             if (check_string_char_length(&$$->user, ER(ER_USERNAME),
                                          USERNAME_CHAR_LENGTH,
@@ -14783,17 +14792,25 @@ text_or_password:
           TEXT_STRING { $$=$1.str;}
         | PASSWORD '(' TEXT_STRING ')'
           {
-            $$= $3.length ? YYTHD->variables.old_passwords ?
-              Item_func_old_password::alloc(YYTHD, $3.str, $3.length) :
-              Item_func_password::alloc(YYTHD, $3.str, $3.length) :
-              $3.str;
+            if ($3.length == 0)
+             $$= $3.str;
+            else
+            switch (YYTHD->variables.old_passwords) {
+              case 1: $$= Item_func_old_password::
+                alloc(YYTHD, $3.str, $3.length);
+                break;
+              case 0:
+              case 2: $$= Item_func_password::
+                create_password_hash_buffer(YYTHD, $3.str, $3.length);
+                break;
+            }
             if ($$ == NULL)
               MYSQL_YYABORT;
           }
         | OLD_PASSWORD '(' TEXT_STRING ')'
           {
-            $$= $3.length ? Item_func_old_password::alloc(YYTHD, $3.str,
-                                                          $3.length) :
+            $$= $3.length ? Item_func_old_password::
+              alloc(YYTHD, $3.str, $3.length) :
               $3.str;
             if ($$ == NULL)
               MYSQL_YYABORT;
@@ -15294,29 +15311,11 @@ grant_user:
             String *password = new (YYTHD->mem_root) String((const char*)$4.str,
                                     YYTHD->variables.character_set_client);
             check_password_policy(password);
-            if ($4.length)
-            {
-              if (YYTHD->variables.old_passwords)
-              {
-                char *buff= 
-                  (char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
-                if (buff == NULL)
-                  MYSQL_YYABORT;
-                my_make_scrambled_password_323(buff, $4.str, $4.length);
-                $1->password.str= buff;
-                $1->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323;
-              }
-              else
-              {
-                char *buff= 
-                  (char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
-                if (buff == NULL)
-                  MYSQL_YYABORT;
-                my_make_scrambled_password(buff, $4.str, $4.length);
-                $1->password.str= buff;
-                $1->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH;
-              }
-            }
+            /*
+              1. Plugin must be resolved
+              2. Password must be digested
+            */
+            $1->uses_identified_by_clause= true;
           }
         | user IDENTIFIED_SYM BY PASSWORD TEXT_STRING
           { 
@@ -15324,6 +15323,10 @@ grant_user:
               MYSQL_YYABORT;
             $$= $1; 
             $1->password= $5; 
+            /*
+              1. Plugin must be resolved
+            */
+            $1->uses_identified_by_password_clause= true;
           }
         | user IDENTIFIED_SYM WITH ident_or_text
           {
@@ -15332,6 +15335,7 @@ grant_user:
             $$= $1;
             $1->plugin= $4;
             $1->auth= empty_lex_str;
+            $1->uses_identified_with_clause= true;
           }
         | user IDENTIFIED_SYM WITH ident_or_text AS TEXT_STRING_sys
           {
@@ -15340,9 +15344,14 @@ grant_user:
             $$= $1;
             $1->plugin= $4;
             $1->auth= $6;
+            $1->uses_identified_with_clause= true;
+            $1->uses_authentication_string_clause= true;
           }
         | user
-          { $$= $1; $1->password= null_lex_str; }
+          {
+            $$= $1;
+            $1->password= null_lex_str;
+          }
         ;
 
 opt_column_list:

=== modified file 'sql/structs.h'
--- a/sql/structs.h	2012-03-06 14:29:42 +0000
+++ b/sql/structs.h	2012-03-22 18:28:07 +0000
@@ -160,6 +160,10 @@ typedef int *(*update_var)(THD *, struct
 
 typedef struct	st_lex_user {
   LEX_STRING user, host, password, plugin, auth;
+  bool uses_identified_by_clause;
+  bool uses_identified_with_clause;
+  bool uses_authentication_string_clause;
+  bool uses_identified_by_password_clause;
 } LEX_USER;
 
 /*

=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc	2012-06-01 08:45:46 +0000
+++ b/sql/sys_vars.cc	2012-06-05 07:56:01 +0000
@@ -1920,15 +1920,12 @@ static Sys_var_mybool Sys_old_alter_tabl
        "old_alter_table", "Use old, non-optimized alter table",
        SESSION_VAR(old_alter_table), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
 
-static bool check_old_passwords(sys_var *self, THD *thd, set_var *var)
-{
-  return mysql_user_table_is_in_short_password_format;
-}
-static Sys_var_mybool Sys_old_passwords(
+static Sys_var_uint Sys_old_passwords(
        "old_passwords",
-       "Use old password encryption method (needed for 4.0 and older clients)",
-       SESSION_VAR(old_passwords), CMD_LINE(OPT_ARG), DEFAULT(FALSE),
-       NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_old_passwords));
+       "Determine which hash algorithm to use when generating passwords using "
+       "the PASSWORD() function",
+       SESSION_VAR(old_passwords), CMD_LINE(REQUIRED_ARG),
+       VALID_RANGE(0, 2), DEFAULT(0), BLOCK_SIZE(1));
 
 static Sys_var_ulong Sys_open_files_limit(
        "open_files_limit",

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (kristofer.pettersson:3974 to 3975) Kristofer Pettersson9 Jun