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[] = {
"&", "&",
"<", "<",
@@ -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 Pettersson | 9 Jun |