Skip to content

Commit

Permalink
MDEV-14974: --port ignored for --host=localhost
Browse files Browse the repository at this point in the history
Problem:
=======
MariaDB's command line utilities (e.g., mysql,
mysqldump, etc) silently ignore connection
property options (e.g., --port and --socket)
when protocol is not explicitly set via the
command-line for localhost connections.

Fix:
===
If connection properties are specified without a
protocol, override the protocol to be consistent.
For example, if --port is specified, automatically
set protocol=tcp.

Caveats:
=======
 * When multiple connection properties are
specified, nothing is overridden
 * If protocol is is set via the command-line,
its value is used

Reviewers:
========
Sergei Golubchik <serg@mariadb.com>
Vladislav Vaintroub <wlad@mariadb.com>
  • Loading branch information
bnestere committed May 11, 2021
1 parent 02380cd commit b6cfb29
Show file tree
Hide file tree
Showing 27 changed files with 766 additions and 61 deletions.
58 changes: 58 additions & 0 deletions client/client_priv.h
Expand Up @@ -136,3 +136,61 @@ enum options_client
Name of the sys schema database.
*/
#define SYS_SCHEMA_DB_NAME "sys"

/**
The --socket CLI option has different meanings
across different operating systems.
*/
#ifndef _WIN32
#define SOCKET_PROTOCOL_TO_FORCE MYSQL_PROTOCOL_SOCKET
#else
#define SOCKET_PROTOCOL_TO_FORCE MYSQL_PROTOCOL_PIPE
#endif

/**
Utility function to implicitly change the connection protocol to a
consistent value given the command line arguments. Additionally,
warns the user that the protocol has been changed.
Arguments:
@param [in] host Name of the host to connect to
@param [in, out] opt_protocol Location of the protocol option
variable to update
@param [in] new_protocol New protocol to force
*/
static inline void warn_protocol_override(char *host,
uint *opt_protocol,
uint new_protocol)
{
DBUG_ASSERT(new_protocol == MYSQL_PROTOCOL_TCP
|| new_protocol == SOCKET_PROTOCOL_TO_FORCE);


if ((host == NULL
|| strncmp(host, LOCAL_HOST, sizeof(LOCAL_HOST)-1) == 0))
{
const char *protocol_name;

if (*opt_protocol == MYSQL_PROTOCOL_DEFAULT
#ifndef _WIN32
&& new_protocol == MYSQL_PROTOCOL_SOCKET
#else
&& new_protocol == MYSQL_PROTOCOL_TCP
#endif
)
{
/* This is already the default behavior, do nothing */
return;
}

protocol_name= sql_protocol_typelib.type_names[new_protocol-1];

fprintf(stderr, "%s %s %s\n",
"WARNING: Forcing protocol to ",
protocol_name,
" due to option specification. "
"Please explicitly state intended protocol.");

*opt_protocol = new_protocol;
}
}
65 changes: 64 additions & 1 deletion client/mysql.cc
Expand Up @@ -206,6 +206,8 @@ static uint opt_protocol=0;
static const char *opt_protocol_type= "";
static CHARSET_INFO *charset_info= &my_charset_latin1;

static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT;

#include "sslopt-vars.h"

const char *default_dbug_option="d:t:o,/tmp/mariadb.trace";
Expand Down Expand Up @@ -1162,6 +1164,9 @@ int main(int argc,char *argv[])
close(stdout_fileno_copy); /* Clean up dup(). */
}

/* We need to know if protocol-related options originate from CLI args */
my_defaults_mark_files = TRUE;

load_defaults_or_exit("my", load_default_groups, &argc, &argv);
defaults_argv=argv;
if ((status.exit_status= get_options(argc, (char **) argv)))
Expand All @@ -1171,6 +1176,14 @@ int main(int argc,char *argv[])
exit(status.exit_status);
}

/* Command line options override configured protocol */
if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT
&& protocol_to_force != opt_protocol)
{
warn_protocol_override(current_host, &opt_protocol, protocol_to_force);
}


if (status.batch && !status.line_buff &&
!(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, stdin)))
{
Expand Down Expand Up @@ -1715,8 +1728,11 @@ static void usage(int version)


my_bool
get_one_option(const struct my_option *opt, const char *argument, const char *)
get_one_option(const struct my_option *opt, const char *argument, const char *filename)
{
/* Track when protocol is set via CLI to not force port TCP protocol override */
static my_bool ignore_protocol_override = FALSE;

switch(opt->id) {
case OPT_CHARSETS_DIR:
strmake_buf(mysql_charsets_dir, argument);
Expand Down Expand Up @@ -1781,6 +1797,14 @@ get_one_option(const struct my_option *opt, const char *argument, const char *)
opt->name)) <= 0)
exit(1);
#endif

/* Specification of protocol via CLI trumps implicit overrides */
if (filename[0] == '\0')
{
ignore_protocol_override = TRUE;
protocol_to_force = MYSQL_PROTOCOL_DEFAULT;
}

break;
case OPT_SERVER_ARG:
#ifdef EMBEDDED_LIBRARY
Expand Down Expand Up @@ -1872,6 +1896,13 @@ get_one_option(const struct my_option *opt, const char *argument, const char *)
#ifdef __WIN__
opt_protocol = MYSQL_PROTOCOL_PIPE;
opt_protocol_type= "pipe";

/* Prioritize pipe if explicit via command line */
if (filename[0] == '\0')
{
ignore_protocol_override = TRUE;
protocol_to_force = MYSQL_PROTOCOL_DEFAULT;
}
#endif
break;
#include <sslopt-case.h>
Expand All @@ -1883,6 +1914,38 @@ get_one_option(const struct my_option *opt, const char *argument, const char *)
status.exit_status= 0;
mysql_end(-1);
break;
case 'P':
/* If port and socket are set, fall back to default behavior */
if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE)
{
ignore_protocol_override = TRUE;
protocol_to_force = MYSQL_PROTOCOL_DEFAULT;
}

/* If port is set via CLI, try to force protocol to TCP */
if (filename[0] == '\0' &&
!ignore_protocol_override &&
protocol_to_force == MYSQL_PROTOCOL_DEFAULT)
{
protocol_to_force = MYSQL_PROTOCOL_TCP;
}
break;
case 'S':
/* If port and socket are set, fall back to default behavior */
if (protocol_to_force == MYSQL_PROTOCOL_TCP)
{
ignore_protocol_override = TRUE;
protocol_to_force = MYSQL_PROTOCOL_DEFAULT;
}

/* Prioritize socket if set via command line */
if (filename[0] == '\0' &&
!ignore_protocol_override &&
protocol_to_force == MYSQL_PROTOCOL_DEFAULT)
{
protocol_to_force = SOCKET_PROTOCOL_TO_FORCE;
}
break;
case 'I':
case '?':
usage(0);
Expand Down
66 changes: 65 additions & 1 deletion client/mysqladmin.cc
Expand Up @@ -54,6 +54,8 @@ static bool sql_log_bin_off= false;
static uint opt_protocol=0;
static myf error_flags; /* flags to pass to my_printf_error, like ME_BELL */

static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT;

/*
When using extended-status relatively, ex_val_max_len is the estimated
maximum length for any relative value printed by extended-status. The
Expand Down Expand Up @@ -241,8 +243,12 @@ static const char *load_default_groups[]=
0 };

my_bool
get_one_option(const struct my_option *opt, const char *argument, const char *)
get_one_option(const struct my_option *opt, const char *argument, const char *filename)
{

/* Track when protocol is set via CLI to not force overrides */
static my_bool ignore_protocol_override = FALSE;

switch(opt->id) {
case 'c':
opt_count_iterations= 1;
Expand Down Expand Up @@ -274,6 +280,13 @@ get_one_option(const struct my_option *opt, const char *argument, const char *)
case 'W':
#ifdef __WIN__
opt_protocol = MYSQL_PROTOCOL_PIPE;

/* Prioritize pipe if explicit via command line */
if (filename[0] == '\0')
{
ignore_protocol_override = TRUE;
protocol_to_force = MYSQL_PROTOCOL_DEFAULT;
}
#endif
break;
case '#':
Expand Down Expand Up @@ -309,6 +322,46 @@ get_one_option(const struct my_option *opt, const char *argument, const char *)
sf_leaking_memory= 1; /* no memory leak reports here */
exit(1);
}

/* Specification of protocol via CLI trumps implicit overrides */
if (filename[0] == '\0')
{
ignore_protocol_override = TRUE;
protocol_to_force = MYSQL_PROTOCOL_DEFAULT;
}

break;
case 'P':
/* If port and socket are set, fall back to default behavior */
if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE)
{
ignore_protocol_override = TRUE;
protocol_to_force = MYSQL_PROTOCOL_DEFAULT;
}

/* If port is set via CLI, try to force protocol to TCP */
if (filename[0] == '\0' &&
!ignore_protocol_override &&
protocol_to_force == MYSQL_PROTOCOL_DEFAULT)
{
protocol_to_force = MYSQL_PROTOCOL_TCP;
}
break;
case 'S':
/* If port and socket are set, fall back to default behavior */
if (protocol_to_force == MYSQL_PROTOCOL_TCP)
{
ignore_protocol_override = TRUE;
protocol_to_force = MYSQL_PROTOCOL_DEFAULT;
}

/* Prioritize socket if set via command line */
if (filename[0] == '\0' &&
!ignore_protocol_override &&
protocol_to_force == MYSQL_PROTOCOL_DEFAULT)
{
protocol_to_force = SOCKET_PROTOCOL_TO_FORCE;
}
break;
}
return 0;
Expand All @@ -323,6 +376,10 @@ int main(int argc,char *argv[])

MY_INIT(argv[0]);
sf_leaking_memory=1; /* don't report memory leaks on early exits */

/* We need to know if protocol-related options originate from CLI args */
my_defaults_mark_files = TRUE;

load_defaults_or_exit("my", load_default_groups, &argc, &argv);
save_argv = argv; /* Save for free_defaults */

Expand All @@ -331,6 +388,13 @@ int main(int argc,char *argv[])
temp_argv= mask_password(argc, &argv);
temp_argc= argc;

/* Command line options override configured protocol */
if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT
&& protocol_to_force != opt_protocol)
{
warn_protocol_override(host, &opt_protocol, protocol_to_force);
}

if (debug_info_flag)
my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
if (debug_check_flag)
Expand Down
58 changes: 57 additions & 1 deletion client/mysqlbinlog.cc
Expand Up @@ -98,6 +98,8 @@ static const char *output_prefix= "";
static char **defaults_argv= 0;
static MEM_ROOT glob_root;

static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT;

#ifndef DBUG_OFF
static const char *default_dbug_option = "d:t:o,/tmp/mariadb-binlog.trace";
const char *current_dbug_option= default_dbug_option;
Expand Down Expand Up @@ -1959,9 +1961,13 @@ static my_time_t convert_str_to_timestamp(const char* str)


extern "C" my_bool
get_one_option(const struct my_option *opt, const char *argument, const char *)
get_one_option(const struct my_option *opt, const char *argument, const char *filename)
{
bool tty_password=0;

/* Track when protocol is set via CLI to not force overrides */
static my_bool ignore_protocol_override = FALSE;

switch (opt->id) {
#ifndef DBUG_OFF
case '#':
Expand Down Expand Up @@ -2011,6 +2017,14 @@ get_one_option(const struct my_option *opt, const char *argument, const char *)
sf_leaking_memory= 1; /* no memory leak reports here */
die();
}

/* Specification of protocol via CLI trumps implicit overrides */
if (filename[0] == '\0')
{
ignore_protocol_override = TRUE;
protocol_to_force = MYSQL_PROTOCOL_DEFAULT;
}

break;
#ifdef WHEN_FLASHBACK_REVIEW_READY
case opt_flashback_review:
Expand Down Expand Up @@ -2092,6 +2106,38 @@ get_one_option(const struct my_option *opt, const char *argument, const char *)
case OPT_PRINT_ROW_EVENT_POSITIONS:
print_row_event_positions_used= 1;
break;
case 'P':
/* If port and socket are set, fall back to default behavior */
if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE)
{
ignore_protocol_override = TRUE;
protocol_to_force = MYSQL_PROTOCOL_DEFAULT;
}

/* If port is set via CLI, try to force protocol to TCP */
if (filename[0] == '\0' &&
!ignore_protocol_override &&
protocol_to_force == MYSQL_PROTOCOL_DEFAULT)
{
protocol_to_force = MYSQL_PROTOCOL_TCP;
}
break;
case 'S':
/* If port and socket are set, fall back to default behavior */
if (protocol_to_force == MYSQL_PROTOCOL_TCP)
{
ignore_protocol_override = TRUE;
protocol_to_force = MYSQL_PROTOCOL_DEFAULT;
}

/* Prioritize socket if set via command line */
if (filename[0] == '\0' &&
!ignore_protocol_override &&
protocol_to_force == MYSQL_PROTOCOL_DEFAULT)
{
protocol_to_force = SOCKET_PROTOCOL_TO_FORCE;
}
break;
case 'v':
if (argument == disabled_my_option)
verbose= 0;
Expand Down Expand Up @@ -3049,6 +3095,9 @@ int main(int argc, char** argv)
my_init_time(); // for time functions
tzset(); // set tzname

/* We need to know if protocol-related options originate from CLI args */
my_defaults_mark_files = TRUE;

load_defaults_or_exit("my", load_groups, &argc, &argv);
defaults_argv= argv;

Expand All @@ -3062,6 +3111,13 @@ int main(int argc, char** argv)

parse_args(&argc, (char***)&argv);

/* Command line options override configured protocol */
if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT
&& protocol_to_force != opt_protocol)
{
warn_protocol_override(host, &opt_protocol, protocol_to_force);
}

if (!argc || opt_version)
{
if (!opt_version)
Expand Down

0 comments on commit b6cfb29

Please sign in to comment.