Commit 745c53ec authored by Sergei Golubchik's avatar Sergei Golubchik

5.2->5.3 merge

parents 63d32c11 6404504d
......@@ -4337,9 +4337,10 @@ char *get_arg(char *line, my_bool get_next_arg)
string, and the "dialog" plugin will free() it.
*/
extern "C" char *mysql_authentication_dialog_ask(MYSQL *mysql, int type,
const char *prompt,
char *buf, int buf_len)
MYSQL_PLUGIN_EXPORT
char *mysql_authentication_dialog_ask(MYSQL *mysql, int type,
const char *prompt,
char *buf, int buf_len)
{
char *s=buf;
......
......@@ -117,6 +117,7 @@ static my_bool disable_connect_log= 1;
static my_bool disable_warnings= 0, disable_column_names= 0;
static my_bool prepare_warnings_enabled= 0;
static my_bool disable_info= 1;
static char *opt_plugin_dir= 0, *opt_default_auth;
static my_bool abort_on_error= 1;
static my_bool server_initialized= 0;
static my_bool is_windows= 0;
......@@ -6238,6 +6239,13 @@ static struct my_option my_long_options[] =
{"view-protocol", OPT_VIEW_PROTOCOL, "Use views for select.",
&view_protocol, &view_protocol, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
(uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"default_auth", OPT_PLUGIN_DIR,
"Default authentication client-side plugin to use.",
(uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 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}
};
......@@ -8228,6 +8236,12 @@ int main(int argc, char **argv)
if (opt_protocol)
mysql_options(con->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
if (opt_plugin_dir && *opt_plugin_dir)
mysql_options(con->mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
if (opt_default_auth && *opt_default_auth)
mysql_options(con->mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
......@@ -10194,3 +10208,33 @@ static int setenv(const char *name, const char *value, int overwrite)
return 0;
}
#endif
/*
for the purpose of testing (see dialog.test)
we replace default mysql_authentication_dialog_ask function with the one,
that always reads from stdin with explicit echo.
*/
MYSQL_PLUGIN_EXPORT
char *mysql_authentication_dialog_ask(MYSQL *mysql, int type,
const char *prompt,
char *buf, int buf_len)
{
char *s=buf;
fputs(prompt, stdout);
fputs(" ", stdout);
if (!fgets(buf, buf_len-1, stdin))
buf[0]= 0;
else if (buf[0] && (s= strend(buf))[-1] == '\n')
s[-1]= 0;
for (s= buf; *s; s++)
fputc(type == 2 ? '*' : *s, stdout);
fputc('\n', stdout);
return buf;
}
......@@ -13,11 +13,6 @@ dnl When changing the major version number please also check the switch
dnl statement in mysqlbinlog::check_master_version(). You may also need
dnl to update version.c in ndb.
dnl
dnl When merging new MySQL releases, update the version number to match the
dnl MySQL version number.
dnl
dnl Note: the following line must be parseable by win/configure.js:GetVersion()
AC_INIT([MariaDB Server], [5.3.2-MariaDB-beta], [], [mysql])
AC_CONFIG_SRCDIR([sql/mysqld.cc])
......
......@@ -1555,18 +1555,20 @@ do { doubleget_union _tmp; \
#define NO_EMBEDDED_ACCESS_CHECKS
#endif
#ifdef HAVE_DLOPEN
#if defined(__WIN__)
#if defined(_WIN32)
#define dlsym(lib, name) GetProcAddress((HMODULE)lib, name)
#define dlopen(libname, unused) LoadLibraryEx(libname, NULL, 0)
#define dlclose(lib) FreeLibrary((HMODULE)lib)
#elif defined(HAVE_DLFCN_H)
#define HAVE_DLOPEN
#endif
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#ifndef HAVE_DLERROR
#define dlerror() ""
#endif
#endif
/* FreeBSD 2.2.2 does not define RTLD_NOW) */
#ifndef RTLD_NOW
......
......@@ -140,6 +140,7 @@ void get_salt_from_password(unsigned char *res, const char *password);
void make_password_from_salt(char *to, const unsigned char *hash_stage2);
char *octet2hex(char *to, const char *str, unsigned int len);
char *get_tty_password(const char *opt_message);
void get_tty_password_buff(const char *opt_message, char *to, size_t length);
const char *mysql_errno_to_sqlstate(unsigned int mysql_errno);
my_bool my_thread_init(void);
void my_thread_end(void);
......
......@@ -28,9 +28,7 @@
#include <stdlib.h>
#endif
#ifdef MYSQL_PLUGIN_EXPORT
#undef MYSQL_PLUGIN_EXPORT
#endif
#if defined(_MSC_VER)
#ifdef __cplusplus
#define MYSQL_PLUGIN_EXPORT extern "C" __declspec(dllexport)
......@@ -38,7 +36,11 @@
#define MYSQL_PLUGIN_EXPORT __declspec(dllexport)
#endif
#else /*_MSC_VER */
#define MYSQL_PLUGIN_EXPORT
#ifdef __cplusplus
#define MYSQL_PLUGIN_EXPORT extern "C"
#else
#define MYSQL_PLUGIN_EXPORT
#endif
#endif
/* known plugin types */
......
......@@ -25,21 +25,17 @@
for functions.
*/
#if defined(_MSC_VER)
#if defined(MYSQL_DYNAMIC_PLUGIN)
#ifdef __cplusplus
#define MYSQL_PLUGIN_EXPORT extern "C" __declspec(dllexport)
#else
#define MYSQL_PLUGIN_EXPORT __declspec(dllexport)
#endif
#else /* MYSQL_DYNAMIC_PLUGIN */
#else /*_MSC_VER */
#ifdef __cplusplus
#define MYSQL_PLUGIN_EXPORT extern "C"
#define MYSQL_PLUGIN_EXPORT extern "C"
#else
#define MYSQL_PLUGIN_EXPORT
#define MYSQL_PLUGIN_EXPORT
#endif
#endif /*MYSQL_DYNAMIC_PLUGIN */
#else /*_MSC_VER */
#define MYSQL_PLUGIN_EXPORT
#endif
#ifdef __cplusplus
......@@ -129,14 +125,20 @@ struct st_maria_plugin DECLS[]= {
#else
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]= {
#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int _maria_plugin_interface_version_= MARIA_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int _maria_sizeof_struct_st_plugin_= sizeof(struct st_maria_plugin); \
MYSQL_PLUGIN_EXPORT struct st_maria_plugin _maria_plugin_declarations_[]= {
MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_; \
int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_; \
int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]; \
struct st_mysql_plugin _mysql_plugin_declarations_[]= {
#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int _maria_plugin_interface_version_; \
int _maria_plugin_interface_version_= MARIA_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int _maria_sizeof_struct_st_plugin_; \
int _maria_sizeof_struct_st_plugin_= sizeof(struct st_maria_plugin); \
MYSQL_PLUGIN_EXPORT struct st_maria_plugin _maria_plugin_declarations_[]; \
struct st_maria_plugin _maria_plugin_declarations_[]= {
#endif
......
......@@ -524,6 +524,7 @@ char *octet2hex(char *to, const char *str, unsigned int len);
/* end of password.c */
char *get_tty_password(const char *opt_message);
void get_tty_password_buff(const char *opt_message, char *to, size_t length);
const char *mysql_errno_to_sqlstate(unsigned int mysql_errno);
/* Some other useful functions */
......
......@@ -123,7 +123,6 @@ IF(WIN32)
ENDIF(WIN32)
ADD_DEPENDENCIES(libmysql GenError)
TARGET_LINK_LIBRARIES(libmysql mysqlclient ws2_32)
ADD_DEFINITIONS(-DHAVE_DLOPEN)
MYSQL_INSTALL_TARGETS(mysqlclient DESTINATION lib COMPONENT Development)
MYSQL_INSTALL_TARGETS(libmysql DESTINATION lib COMPONENT SharedLibraries)
......@@ -75,12 +75,10 @@
#define _cputs(A) putstring(A)
#endif
char *get_tty_password(const char *opt_message)
void get_tty_password_buff(const char *opt_message, char *to, size_t length)
{
char to[80];
char *pos=to,*end=to+sizeof(to)-1;
char *pos=to,*end=to+length-1;
int i=0;
DBUG_ENTER("get_tty_password");
_cputs(opt_message ? opt_message : "Enter password: ");
for (;;)
{
......@@ -106,7 +104,6 @@ char *get_tty_password(const char *opt_message)
pos--; /* Allow dummy space at end */
*pos=0;
_cputs("\n");
DBUG_RETURN(my_strdup(to,MYF(MY_FAE)));
}
#else
......@@ -159,22 +156,19 @@ static void get_password(char *to,uint length,int fd, my_bool echo)
#endif /* ! HAVE_GETPASS */
char *get_tty_password(const char *opt_message)
void get_tty_password_buff(const char *opt_message, char *buff, size_t buflen)
{
#ifdef HAVE_GETPASS
char *passbuff;
#else /* ! HAVE_GETPASS */
TERMIO org,tmp;
#endif /* HAVE_GETPASS */
char buff[80];
DBUG_ENTER("get_tty_password");
#ifdef HAVE_GETPASS
passbuff = getpass(opt_message ? opt_message : "Enter password: ");
/* copy the password to buff and clear original (static) buffer */
strnmov(buff, passbuff, sizeof(buff) - 1);
strnmov(buff, passbuff, buflen - 1);
#ifdef _PASSWORD_LEN
memset(passbuff, 0, _PASSWORD_LEN);
#endif
......@@ -191,7 +185,7 @@ char *get_tty_password(const char *opt_message)
tmp.c_cc[VMIN] = 1;
tmp.c_cc[VTIME] = 0;
tcsetattr(fileno(stdin), TCSADRAIN, &tmp);
get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stdout)));
get_password(buff, buflen, fileno(stdin), isatty(fileno(stdout)));
tcsetattr(fileno(stdin), TCSADRAIN, &org);
#elif defined(HAVE_TERMIO_H)
ioctl(fileno(stdin), (int) TCGETA, &org);
......@@ -200,7 +194,7 @@ char *get_tty_password(const char *opt_message)
tmp.c_cc[VMIN] = 1;
tmp.c_cc[VTIME]= 0;
ioctl(fileno(stdin),(int) TCSETA, &tmp);
get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
get_password(buff,buflen-1,fileno(stdin),isatty(fileno(stdout)));
ioctl(fileno(stdin),(int) TCSETA, &org);
#else
gtty(fileno(stdin), &org);
......@@ -208,13 +202,20 @@ char *get_tty_password(const char *opt_message)
tmp.sg_flags &= ~ECHO;
tmp.sg_flags |= RAW;
stty(fileno(stdin), &tmp);
get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
get_password(buff,buflen-1,fileno(stdin),isatty(fileno(stdout)));
stty(fileno(stdin), &org);
#endif
if (isatty(fileno(stdout)))
fputc('\n',stdout);
#endif /* HAVE_GETPASS */
DBUG_RETURN(my_strdup(buff,MYF(MY_FAE)));
}
#endif /*__WIN__*/
#ifndef MYSQL_DYNAMIC_PLUGIN
char *get_tty_password(const char *opt_message)
{
char buff[80];
get_tty_password_buff(opt_message, buff, sizeof(buff));
return my_strdup(buff, MYF(MY_FAE));
}
#endif
......@@ -21,7 +21,7 @@ IF(WIN32)
ADD_DEFINITIONS(-DUSE_TLS)
ENDIF(WIN32)
ADD_DEFINITIONS(-DMYSQL_SERVER -DEMBEDDED_LIBRARY -DHAVE_DLOPEN)
ADD_DEFINITIONS(-DMYSQL_SERVER -DEMBEDDED_LIBRARY)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/libmysqld
......
......@@ -110,7 +110,7 @@ TEST_DIRS = t r include std_data std_data/parts collections \
suite/innodb suite/innodb/t suite/innodb/r suite/innodb/include \
suite/innodb_plugin suite/innodb_plugin/t suite/innodb_plugin/r \
suite/innodb_plugin/include \
suite/percona suite/handler \
suite/percona suite/handler suite/plugins suite/plugins/t suite/plugins/r \
suite/engines suite/engines/funcs suite/engines/iuds suite/engines/rr_trx \
suite/engines/funcs/r suite/engines/funcs/t suite/engines/iuds/r \
suite/engines/iuds/t suite/engines/rr_trx/include suite/engines/rr_trx/r \
......
......@@ -162,7 +162,7 @@ our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
my $DEFAULT_SUITES="main,binlog,federated,rpl,maria,handler,parts,innodb," .
"innodb_plugin,percona,ndb,vcol,oqgraph,sphinx," .
"optimizer_unfixed_bugs";
"optimizer_unfixed_bugs,plugins";
my $opt_suites;
our $opt_verbose= 0; # Verbose output, enable with --verbose
......
......@@ -2927,4 +2927,249 @@ ORDER BY min_a;
min_a
NULL
DROP TABLE t1;
#
# LP BUG#888456 Wrong result with DISTINCT , ANY , subquery_cache=off , NOT NULL
#
CREATE TABLE t1 ( a int NOT NULL) ;
INSERT INTO t1 VALUES (28),(29),(9);
CREATE TABLE t2 ( a int, KEY (a)) ;
INSERT INTO t2 VALUES (1),(1),(1),(4),(4),(5),(5),(8),(8),(9);
explain select (select t2.a from t2 where t2.a >= t1.a group by t2.a) from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
2 DEPENDENT SUBQUERY t2 index a a 5 NULL 10 Using where; Using index
select (select t2.a from t2 where t2.a >= t1.a group by t2.a) from t1;
(select t2.a from t2 where t2.a >= t1.a group by t2.a)
NULL
NULL
9
drop table t1, t2;
#
# LP BUG#900375 Wrong result with derived_merge=ON, DISTINCT or GROUP BY, EXISTS
#
CREATE TABLE t1 ( a INT, b INT, KEY (b) );
INSERT INTO t1 VALUES
(100,10),(101,11),(102,12),(103,13),(104,14),
(105,15),(106,16),(107,17),(108,18),(109,19);
EXPLAIN
SELECT alias1.* FROM t1, (SELECT * FROM t1) AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL b 5 NULL 10 Using index
1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
3 DEPENDENT SUBQUERY t1 index b b 5 NULL 10 Using where; Using index; Using temporary
SELECT alias1.* FROM t1, (SELECT * FROM t1) AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
a b
100 10
100 10
100 10
100 10
100 10
100 10
100 10
100 10
100 10
100 10
101 11
101 11
101 11
101 11
101 11
101 11
101 11
101 11
101 11
101 11
102 12
102 12
102 12
102 12
102 12
102 12
102 12
102 12
102 12
102 12
103 13
103 13
103 13
103 13
103 13
103 13
103 13
103 13
103 13
103 13
104 14
104 14
104 14
104 14
104 14
104 14
104 14
104 14
104 14
104 14
105 15
105 15
105 15
105 15
105 15
105 15
105 15
105 15
105 15
105 15
106 16
106 16
106 16
106 16
106 16
106 16
106 16
106 16
106 16
106 16
107 17
107 17
107 17
107 17
107 17
107 17
107 17
107 17
107 17
107 17
108 18
108 18
108 18
108 18
108 18
108 18
108 18
108 18
108 18
108 18
109 19
109 19
109 19
109 19
109 19
109 19
109 19
109 19
109 19
109 19
EXPLAIN
SELECT alias1.* FROM t1, t1 AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL b 5 NULL 10 Using index
1 PRIMARY alias1 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
2 DEPENDENT SUBQUERY t1 ALL b NULL NULL NULL 10 Range checked for each record (index map: 0x1); Using temporary
SELECT alias1.* FROM t1, t1 AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
a b
100 10
100 10
100 10
100 10
100 10
100 10
100 10
100 10
100 10
100 10
101 11
101 11
101 11
101 11
101 11
101 11
101 11
101 11
101 11
101 11
102 12
102 12
102 12
102 12
102 12
102 12
102 12
102 12
102 12
102 12
103 13
103 13
103 13
103 13
103 13
103 13
103 13
103 13
103 13
103 13
104 14
104 14
104 14
104 14
104 14
104 14
104 14
104 14
104 14
104 14
105 15
105 15
105 15
105 15
105 15
105 15
105 15
105 15
105 15
105 15
106 16
106 16
106 16
106 16
106 16
106 16
106 16
106 16
106 16
106 16
107 17
107 17
107 17
107 17
107 17
107 17
107 17
107 17
107 17
107 17
108 18
108 18
108 18
108 18
108 18
108 18
108 18
108 18
108 18
108 18
109 19
109 19
109 19
109 19
109 19
109 19
109 19
109 19
109 19
109 19
drop table t1;
End of 5.1 tests
......@@ -5649,7 +5649,7 @@ WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY table1 ALL NULL NULL NULL NULL 2
1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
2 DEPENDENT SUBQUERY t2 ALL f1_key NULL NULL NULL 10 Range checked for each record (index map: 0x1); Using temporary
DROP TABLE t1,t2;
#
# LP bug #826279: assertion failure with GROUP BY a result of subquery
......
......@@ -5648,7 +5648,7 @@ WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY table1 ALL NULL NULL NULL NULL 2
1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
2 DEPENDENT SUBQUERY t2 ALL f1_key NULL NULL NULL 10 Range checked for each record (index map: 0x1); Using temporary
DROP TABLE t1,t2;
#
# LP bug #826279: assertion failure with GROUP BY a result of subquery
......
......@@ -5644,7 +5644,7 @@ WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY table1 ALL NULL NULL NULL NULL 2
1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
2 DEPENDENT SUBQUERY t2 ALL f1_key NULL NULL NULL 10 Range checked for each record (index map: 0x1); Using temporary
DROP TABLE t1,t2;
#
# LP bug #826279: assertion failure with GROUP BY a result of subquery
......
......@@ -5653,7 +5653,7 @@ WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY table1 ALL NULL NULL NULL NULL 2
1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
2 DEPENDENT SUBQUERY t2 ALL f1_key NULL NULL NULL 10 Range checked for each record (index map: 0x1); Using temporary
DROP TABLE t1,t2;
#
# LP bug #826279: assertion failure with GROUP BY a result of subquery
......
......@@ -5644,7 +5644,7 @@ WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY table1 ALL NULL NULL NULL NULL 2
1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
2 DEPENDENT SUBQUERY t2 ALL f1_key NULL NULL NULL 10 Range checked for each record (index map: 0x1); Using temporary
DROP TABLE t1,t2;
#
# LP bug #826279: assertion failure with GROUP BY a result of subquery
......
install plugin three_attempts soname 'dialog.so';
create user test_dialog identified via three_attempts using 'SECRET';
#
# -pSECRET is picked up, no questions asked.
#
select user(), current_user();
user() current_user()
test_dialog@localhost test_dialog@%
#
# without -p. up to three questions are asked on the stdin.
# athentication is successful, the correct pasword is on the third line
#
Password, please: ***
Password, please: ****
Password, please: ******
select user(), current_user();
user() current_user()
test_dialog@localhost test_dialog@%
#
# athentication is unsuccessful, first three lines are all wrong
#
Password, please: ***
Password, please: ****
Password, please: *****
drop user test_dialog;
uninstall plugin three_attempts;
install plugin pam soname 'auth_pam.so';
create user test_pam identified via pam using 'mariadb_mtr';
#
# athentication is successful, challenge/pin are ok
# note that current_user() differts from user()
#
Challenge input first.
Enter: not very secret challenge
Now, the magic number!
PIN: ****
select user(), current_user(), database();
user() current_user() database()
test_pam@localhost pam_test@% test
#
# athentication is unsuccessful
#
Challenge input first.
Enter: not very secret challenge
Now, the magic number!
PIN: ****
drop user test_pam;
uninstall plugin pam;
package My::Suite::Plugins;
@ISA = qw(My::Suite);
$ENV{PAM_SETUP_FOR_MTR}=1 if -e '/etc/pam.d/mariadb_mtr';
bless { };
#
# test for the client "dialog" plugin
#
--source include/not_embedded.inc
if (!$DIALOG_SO) {
skip No dialog auth plugin;
}
--replace_result .dll .so
eval install plugin three_attempts soname '$DIALOG_SO';
create user test_dialog identified via three_attempts using 'SECRET';
let $plugindir=`SELECT @@global.plugin_dir`;
--write_file $MYSQLTEST_VARDIR/tmp/dialog_good.txt
foo
1234
SECRET
select user(), current_user();
EOF
--write_file $MYSQLTEST_VARDIR/tmp/dialog_bad.txt
foo
1234
wrong
SECRET
EOF
--echo #
--echo # -pSECRET is picked up, no questions asked.
--echo #
--exec echo "select user(), current_user();"|$MYSQL_TEST -u test_dialog -pSECRET --plugin-dir=$plugindir
--echo #
--echo # without -p. up to three questions are asked on the stdin.
--echo # athentication is successful, the correct pasword is on the third line
--echo #
--exec $MYSQL_TEST -u test_dialog --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/dialog_good.txt
--echo #
--echo # athentication is unsuccessful, first three lines are all wrong
--echo #
--error 1
--exec $MYSQL_TEST -u test_dialog --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/dialog_bad.txt
--remove_file $MYSQLTEST_VARDIR/tmp/dialog_good.txt
--remove_file $MYSQLTEST_VARDIR/tmp/dialog_bad.txt
drop user test_dialog;
uninstall plugin three_attempts;
source t/feedback_plugin_load.test;
source feedback_plugin_load.test;
if (!$MTR_FEEDBACK_PLUGIN) {
skip MTR_FEEDBACK_PLUGIN is not set;
......
--source include/not_embedded.inc
if (!$AUTH_PAM_SO) {
skip No pam auth plugin;
}
if (!$PAM_SETUP_FOR_MTR) {
skip No pam setup for mtr;
}
--replace_result .dll .so
eval install plugin pam soname '$AUTH_PAM_SO';
create user test_pam identified via pam using 'mariadb_mtr';
let $plugindir=`SELECT @@global.plugin_dir`;
--write_file $MYSQLTEST_VARDIR/tmp/pam_good.txt
not very secret challenge
9225
select user(), current_user(), database();
EOF
--write_file $MYSQLTEST_VARDIR/tmp/pam_bad.txt
not very secret challenge
9224
select user(), current_user(), database();
EOF
--echo #
--echo # athentication is successful, challenge/pin are ok
--echo # note that current_user() differts from user()
--echo #
--exec $MYSQL_TEST -u test_pam --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/pam_good.txt
--echo #
--echo # athentication is unsuccessful
--echo #
--error 1
--exec $MYSQL_TEST -u test_pam --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/pam_bad.txt
--remove_file $MYSQLTEST_VARDIR/tmp/pam_good.txt
--remove_file $MYSQLTEST_VARDIR/tmp/pam_bad.txt
drop user test_pam;
uninstall plugin pam;
......@@ -1149,5 +1149,42 @@ ORDER BY min_a;
DROP TABLE t1;
--echo #
--echo # LP BUG#888456 Wrong result with DISTINCT , ANY , subquery_cache=off , NOT NULL
--echo #
CREATE TABLE t1 ( a int NOT NULL) ;
INSERT INTO t1 VALUES (28),(29),(9);
CREATE TABLE t2 ( a int, KEY (a)) ;
INSERT INTO t2 VALUES (1),(1),(1),(4),(4),(5),(5),(8),(8),(9);
explain select (select t2.a from t2 where t2.a >= t1.a group by t2.a) from t1;
select (select t2.a from t2 where t2.a >= t1.a group by t2.a) from t1;
drop table t1, t2;
--echo #
--echo # LP BUG#900375 Wrong result with derived_merge=ON, DISTINCT or GROUP BY, EXISTS
--echo #
CREATE TABLE t1 ( a INT, b INT, KEY (b) );
INSERT INTO t1 VALUES
(100,10),(101,11),(102,12),(103,13),(104,14),
(105,15),(106,16),(107,17),(108,18),(109,19);
EXPLAIN
SELECT alias1.* FROM t1, (SELECT * FROM t1) AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
SELECT alias1.* FROM t1, (SELECT * FROM t1) AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
EXPLAIN
SELECT alias1.* FROM t1, t1 AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
SELECT alias1.* FROM t1, t1 AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
drop table t1;
--echo End of 5.1 tests
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
SET(AUTH_SOURCES dialog.c)
SET(AUTH_SOURCES dialog.c ${CMAKE_SOURCE_DIR}/libmysql/get_password.c)
MYSQL_PLUGIN(AUTH)
......@@ -4,7 +4,7 @@ AM_LDFLAGS=-module -rpath $(pkgplugindir)
AM_CPPFLAGS=-DMYSQL_DYNAMIC_PLUGIN -I$(top_srcdir)/include
pkgplugin_LTLIBRARIES= dialog.la
dialog_la_SOURCES= dialog.c
dialog_la_SOURCES= dialog.c $(top_srcdir)/libmysql/get_password.c
if HAVE_PEERCRED
pkgplugin_LTLIBRARIES+= auth_socket.la
......
......@@ -142,36 +142,6 @@ static struct st_mysql_auth three_handler=
three_attempts
};
mysql_declare_plugin(dialog)
{
MYSQL_AUTHENTICATION_PLUGIN,
&two_handler,
"two_questions",
"Sergei Golubchik",
"Dialog plugin demo 1",
PLUGIN_LICENSE_GPL,
NULL,
NULL,
0x0100,
NULL,
NULL,
NULL
},
{
MYSQL_AUTHENTICATION_PLUGIN,
&three_handler,
"three_attempts",
"Sergei Golubchik",
"Dialog plugin demo 2",
PLUGIN_LICENSE_GPL,
NULL,
NULL,
0x0100,
NULL,
NULL,
NULL
}
mysql_declare_plugin_end;
maria_declare_plugin(dialog)
{
MYSQL_AUTHENTICATION_PLUGIN,
......@@ -186,7 +156,7 @@ maria_declare_plugin(dialog)
NULL,
NULL,
"1.0",
MariaDB_PLUGIN_MATURITY_BETA
MariaDB_PLUGIN_MATURITY_EXPERIMENTAL
},
{
MYSQL_AUTHENTICATION_PLUGIN,
......@@ -201,7 +171,7 @@ maria_declare_plugin(dialog)
NULL,
NULL,
"1.0",
MariaDB_PLUGIN_MATURITY_BETA
MariaDB_PLUGIN_MATURITY_EXPERIMENTAL
}
maria_declare_plugin_end;
......@@ -224,16 +194,25 @@ static char *builtin_ask(MYSQL *mysql __attribute__((unused)),
const char *prompt,
char *buf, int buf_len)
{
int len;
fputs(prompt, stdout);
fputc(' ', stdout);
if (fgets(buf, buf_len, stdin) == 0)
return 0;
len= strlen(buf);
if (len && buf[len-1]=='\n')
buf[len-1]=0;
if (type == 2) /* password */
{
get_tty_password_buff("", buf, buf_len);
buf[buf_len-1]= 0;
}
else
{
if (!fgets(buf, buf_len-1, stdin))
buf[0]= 0;
else
{
int len= strlen(buf);
if (len && buf[len-1] == '\n')
buf[len-1]= 0;
}
}
return buf;
}
......@@ -261,6 +240,7 @@ static int perform_dialog(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
unsigned char *pkt, cmd= 0;
int pkt_len, res;
char reply_buf[1024], *reply;
int first = 1;
do
{
......@@ -269,7 +249,7 @@ static int perform_dialog(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
if (pkt_len < 0)
return CR_ERROR;
if (pkt == 0)
if (pkt == 0 && first)
{
/*
in mysql_change_user() the client sends the first packet, so
......@@ -291,10 +271,10 @@ static int perform_dialog(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
return CR_OK_HANDSHAKE_COMPLETE; /* yes. we're done */
/*
asking for a password with an empty prompt means mysql->password
asking for a password in the first packet mean mysql->password, if it's set
otherwise we ask the user and read the reply
*/
if ((cmd >> 1) == 2 && *pkt == 0)
if ((cmd >> 1) == 2 && first && mysql->passwd[0])
reply= mysql->passwd;
else
reply= ask(mysql, cmd >> 1, (char*) pkt, reply_buf, sizeof(reply_buf));
......
EXTRA_LTLIBRARIES = auth_pam.la libauth_pam.la
pkgplugindir=$(pkglibdir)/plugin
AM_CPPFLAGS = -I$(top_srcdir)/include
pkgplugin_LTLIBRARIES = @plugin_auth_pam_shared_target@
auth_pam_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices -lpam
auth_pam_la_CFLAGS = -shared -DMYSQL_DYNAMIC_PLUGIN
auth_pam_la_SOURCES = auth_pam.c
noinst_LTLIBRARIES = @plugin_auth_pam_static_target@
libauth_pam_la_LDFLAGS = -lpam
libauth_pam_la_SOURCES = auth_pam.c
EXTRA_DIST = plug.in
#include <mysql/plugin_auth.h>
#include <string.h>
#include <security/pam_appl.h>
#include <security/pam_modules.h>
struct param {
unsigned char buf[10240], *ptr;
MYSQL_PLUGIN_VIO *vio;
};
static int conv(int n, const struct pam_message **msg,
struct pam_response **resp, void *data)
{
struct param *param = (struct param *)data;
unsigned char *end = param->buf + sizeof(param->buf) - 1;
int i;
*resp = 0;
for (i = 0; i < n; i++)
{
/* if there's a message - append it to the buffer */
if (msg[i]->msg)
{
int len = strlen(msg[i]->msg);
if (len > end - param->ptr)
len = end - param->ptr;
if (len > 0)
{
memcpy(param->ptr, msg[i]->msg, len);
param->ptr+= len;
*(param->ptr)++ = '\n';
}
}
/* if the message style is *_PROMPT_*, meaning PAM asks a question,
send the accumulated text to the client, read the reply */
if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF ||
msg[i]->msg_style == PAM_PROMPT_ECHO_ON)
{
int pkt_len;
unsigned char *pkt;
/* allocate the response array.
freeing it is the responsibility of the caller */
if (*resp == 0)
{
*resp = calloc(sizeof(struct pam_response), n);
if (*resp == 0)
return PAM_BUF_ERR;
}
/* dialog plugin interprets the first byte of the packet
as the magic number.
2 means "read the input with the echo enabled"
4 means "password-like input, echo disabled"
C'est la vie. */
param->buf[0] = msg[i]->msg_style == PAM_PROMPT_ECHO_ON ? 2 : 4;
if (param->vio->write_packet(param->vio, param->buf, param->ptr - param->buf - 1))
return PAM_CONV_ERR;
pkt_len = param->vio->read_packet(param->vio, &pkt);
if (pkt_len < 0)
return PAM_CONV_ERR;
/* allocate and copy the reply to the response array */
(*resp)[i].resp = strndup((char*)pkt, pkt_len);
param->ptr = param->buf + 1;
}
}
return PAM_SUCCESS;
}
#define DO(X) if ((status = (X)) != PAM_SUCCESS) goto end
static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
{
pam_handle_t *pamh = NULL;
int status;
const char *new_username;
struct param param;
struct pam_conv c = { &conv, &param };
/*
get the service name, as specified in
CREATE USER ... IDENTIFIED WITH pam_auth AS "service"
*/
const char *service = info->auth_string && info->auth_string[0]
? info->auth_string : "mysql";
param.ptr = param.buf + 1;
param.vio = vio;
DO( pam_start(service, info->user_name, &c, &pamh) );
DO( pam_authenticate (pamh, 0) );
DO( pam_acct_mgmt(pamh, 0) );
DO( pam_get_item(pamh, PAM_USER, (const void**)&new_username) );
if (new_username && strcmp(new_username, info->user_name))
strncpy(info->authenticated_as, new_username,
sizeof(info->authenticated_as));
end:
pam_end(pamh, status);
return status == PAM_SUCCESS ? CR_OK : CR_ERROR;
}
static struct st_mysql_auth pam_info =
{
MYSQL_AUTHENTICATION_INTERFACE_VERSION,
"dialog",
pam_auth
};
maria_declare_plugin(pam)
{
MYSQL_AUTHENTICATION_PLUGIN,
&pam_info,
"pam",
"Sergei Golubchik",
"PAM based authentication",
PLUGIN_LICENSE_GPL,
NULL,
NULL,
0x0100,
NULL,
NULL,
"1.0",
MariaDB_PLUGIN_MATURITY_BETA
}
maria_declare_plugin_end;
MYSQL_PLUGIN(auth_pam, [PAM Authentication Plugin], [PAM Authentication Plugin])
MYSQL_PLUGIN_DYNAMIC(auth_pam, [auth_pam.la])
AC_CHECK_HEADER([security/pam_appl.h],,[MYSQL_PLUGIN_WITHOUT(auth_pam)])
/*
Pam module to test pam authentication plugin. Used in pam.test.
Linux only.
Compile as
gcc pam_mariadb_mtr.c -shared -lpam -fPIC -o pam_mariadb_mtr.so
Install as appropriate (for example, in /lib/security/).
Create /etc/pam.d/mariadb_mtr with
=========================================================
auth required pam_mariadb_mtr.so pam_test
account required pam_mariadb_mtr.so
=========================================================
*/
#include <stdlib.h>
#include <string.h>
#include <security/pam_modules.h>
#include <security/pam_appl.h>
#define N 3
PAM_EXTERN int
pam_sm_authenticate(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
struct pam_conv *conv;
struct pam_response *resp = 0;
int pam_err, retval = PAM_SYSTEM_ERR;
struct pam_message msg[N] = {
{ PAM_TEXT_INFO, "Challenge input first." },
{ PAM_PROMPT_ECHO_ON, "Enter:" },
{ PAM_ERROR_MSG, "Now, the magic number!" }
};
const struct pam_message *msgp[N] = { msg, msg+1, msg+2 };
char *r1 = 0, *r2 = 0;
pam_err = pam_get_item(pamh, PAM_CONV, (const void **)&conv);
if (pam_err != PAM_SUCCESS)
goto ret;
pam_err = (*conv->conv)(N, msgp, &resp, conv->appdata_ptr);
if (pam_err != PAM_SUCCESS || !resp || !((r1= resp[1].resp)))
goto ret;
free(resp);
msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
msg[0].msg = "PIN:";
pam_err = (*conv->conv)(1, msgp, &resp, conv->appdata_ptr);
if (pam_err != PAM_SUCCESS || !resp || !((r2= resp[0].resp)))
goto ret;
if (strlen(r1) == atoi(r2) % 100)
retval = PAM_SUCCESS;
else
retval = PAM_AUTH_ERR;
if (argc > 0 && argv[0])
pam_set_item(pamh, PAM_USER, argv[0]);
ret:
free(resp);
free(r1);
free(r2);
return retval;
}
PAM_EXTERN int
pam_sm_setcred(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
return PAM_SUCCESS;
}
PAM_EXTERN int
pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
return PAM_SUCCESS;
}
......@@ -12,9 +12,8 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef MYSQL_SERVER
#define MYSQL_SERVER
#endif
#define MYSQL_SERVER 1
#include <mysql_priv.h>
namespace feedback {
......
......@@ -36,7 +36,7 @@ SET_SOURCE_FILES_PROPERTIES(${CMAKE_BINARY_DIR}/sql/sql_yacc.h
${CMAKE_BINARY_DIR}/include/sql_state.h
PROPERTIES GENERATED 1)
ADD_DEFINITIONS(-DMYSQL_SERVER -D_CONSOLE -DHAVE_DLOPEN -DHAVE_EVENT_SCHEDULER)
ADD_DEFINITIONS(-DMYSQL_SERVER -D_CONSOLE -DHAVE_EVENT_SCHEDULER)
IF(WITH_FEEDBACK_STORAGE_ENGINE)
ADD_DEFINITIONS(-DWITH_FEEDBACK_PLUGIN)
ENDIF()
......
......@@ -11607,6 +11607,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
DBUG_RETURN(NULL);
if (table->s->keys == 0) /* There are no indexes to use. */
DBUG_RETURN(NULL);
if (join->conds && join->conds->used_tables() & OUTER_REF_TABLE_BIT)
DBUG_RETURN(NULL); /* Cannot execute with correlated conditions. */
/* Analyze the query in more detail. */
List_iterator<Item> select_items_it(join->fields_list);
......@@ -12916,6 +12918,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void)
int result;
DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::reset");
seen_first_key= FALSE;
if (!head->key_read)
{
doing_key_read= 1;
......
......@@ -1596,7 +1596,7 @@ page_rec_get_n_recs_before(
n--;
ut_ad(n >= 0);
ut_ad(n < UNIV_PAGE_SIZE / (REC_N_NEW_EXTRA_BYTES + 1));
ut_ad(n < (lint)UNIV_PAGE_SIZE / (REC_N_NEW_EXTRA_BYTES + 1));
return((ulint) n);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment