Merge branch '2.2' into 2.2-mrm
This commit is contained in:
@ -23,6 +23,7 @@
|
|||||||
* Binlog router supports MariaDB 10 GTID at both ends.
|
* Binlog router supports MariaDB 10 GTID at both ends.
|
||||||
* KILL CONNECTION can now be used through MaxScale.
|
* KILL CONNECTION can now be used through MaxScale.
|
||||||
* Environment variables can now be used in the MaxScale configuration file.
|
* Environment variables can now be used in the MaxScale configuration file.
|
||||||
|
* By default, MaxScale can no longer be run as root.
|
||||||
|
|
||||||
For more details, please refer to:
|
For more details, please refer to:
|
||||||
* [MariaDB MaxScale 2.2.0 Release Notes](Release-Notes/MaxScale-2.2.0-Release-Notes.md)
|
* [MariaDB MaxScale 2.2.0 Release Notes](Release-Notes/MaxScale-2.2.0-Release-Notes.md)
|
||||||
|
@ -10,6 +10,21 @@ report at [Jira](https://jira.mariadb.org).
|
|||||||
|
|
||||||
## Changed Features
|
## Changed Features
|
||||||
|
|
||||||
|
### Process identity
|
||||||
|
|
||||||
|
By default, MaxScale can no longer be run as `root`, but must be run as some
|
||||||
|
other user. However, it is possible to start MaxScale as `root`, as long as
|
||||||
|
the user to run MaxScale as is provided as a command line argument:
|
||||||
|
```
|
||||||
|
root@host:~# maxscale --user=maxuser ...
|
||||||
|
```
|
||||||
|
If it is imperative to run MaxScale as root, e.g. in a Docker container, it
|
||||||
|
can be achieved by invoking MaxScale as root and by explicitly specifying
|
||||||
|
the user to also be root:
|
||||||
|
```
|
||||||
|
root@host:~# maxscale --user=root ...
|
||||||
|
```
|
||||||
|
|
||||||
### Binlog server
|
### Binlog server
|
||||||
|
|
||||||
* The `mariadb10_slave_gtid` parameter was removed and slave connections can now
|
* The `mariadb10_slave_gtid` parameter was removed and slave connections can now
|
||||||
|
@ -107,6 +107,7 @@ const char *progname = NULL;
|
|||||||
static struct option long_options[] =
|
static struct option long_options[] =
|
||||||
{
|
{
|
||||||
{"config-check", no_argument, 0, 'c'},
|
{"config-check", no_argument, 0, 'c'},
|
||||||
|
{"daemon", no_argument, 0, 'n'},
|
||||||
{"nodaemon", no_argument, 0, 'd'},
|
{"nodaemon", no_argument, 0, 'd'},
|
||||||
{"config", required_argument, 0, 'f'},
|
{"config", required_argument, 0, 'f'},
|
||||||
{"log", required_argument, 0, 'l'},
|
{"log", required_argument, 0, 'l'},
|
||||||
@ -186,6 +187,7 @@ static void modules_process_finish();
|
|||||||
static void disable_module_unloading(const char* arg);
|
static void disable_module_unloading(const char* arg);
|
||||||
static void enable_module_unloading(const char* arg);
|
static void enable_module_unloading(const char* arg);
|
||||||
static void redirect_output_to_file(const char* arg);
|
static void redirect_output_to_file(const char* arg);
|
||||||
|
static bool user_is_acceptable(const char* specified_user);
|
||||||
|
|
||||||
struct DEBUG_ARGUMENT
|
struct DEBUG_ARGUMENT
|
||||||
{
|
{
|
||||||
@ -1367,6 +1369,7 @@ int main(int argc, char **argv)
|
|||||||
int numlocks = 0;
|
int numlocks = 0;
|
||||||
bool pid_file_created = false;
|
bool pid_file_created = false;
|
||||||
Worker* worker;
|
Worker* worker;
|
||||||
|
const char* specified_user = NULL;
|
||||||
|
|
||||||
config_set_global_defaults();
|
config_set_global_defaults();
|
||||||
MXS_CONFIG* cnf = config_get_global_options();
|
MXS_CONFIG* cnf = config_get_global_options();
|
||||||
@ -1382,7 +1385,7 @@ int main(int argc, char **argv)
|
|||||||
file_write_header(stderr);
|
file_write_header(stderr);
|
||||||
|
|
||||||
// Option string for getopt
|
// Option string for getopt
|
||||||
const char accepted_opts[] = "dcf:g:l:vVs:S:?L:D:C:B:U:A:P:G:N:E:F:M:H:p";
|
const char accepted_opts[] = "dncf:g:l:vVs:S:?L:D:C:B:U:A:P:G:N:E:F:M:H:p";
|
||||||
|
|
||||||
/*<
|
/*<
|
||||||
* Register functions which are called at exit.
|
* Register functions which are called at exit.
|
||||||
@ -1411,8 +1414,13 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
switch (opt)
|
switch (opt)
|
||||||
{
|
{
|
||||||
|
case 'n':
|
||||||
|
/*< Daemon mode, MaxScale forks and parent exits. */
|
||||||
|
daemon_mode = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
/*< Debug mode, maxscale runs in this same process */
|
/*< Non-daemon mode, MaxScale does not fork. */
|
||||||
daemon_mode = false;
|
daemon_mode = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1653,7 +1661,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'U':
|
case 'U':
|
||||||
if (set_user(optarg) != 0)
|
specified_user = optarg;
|
||||||
|
if (set_user(specified_user) != 0)
|
||||||
{
|
{
|
||||||
succp = false;
|
succp = false;
|
||||||
}
|
}
|
||||||
@ -1694,6 +1703,13 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!user_is_acceptable(specified_user))
|
||||||
|
{
|
||||||
|
// Error was logged in user_is_acceptable().
|
||||||
|
rc = MAXSCALE_INTERNALERROR;
|
||||||
|
goto return_main;
|
||||||
|
}
|
||||||
|
|
||||||
if (config_check)
|
if (config_check)
|
||||||
{
|
{
|
||||||
daemon_mode = false;
|
daemon_mode = false;
|
||||||
@ -3204,3 +3220,41 @@ static bool handle_debug_args(char* args)
|
|||||||
}
|
}
|
||||||
return !arg_error;
|
return !arg_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool user_is_acceptable(const char* specified_user)
|
||||||
|
{
|
||||||
|
bool acceptable = false;
|
||||||
|
|
||||||
|
// This is very early, so we do not have logging available, but write to stderr.
|
||||||
|
// As this is security related, we want to do as little as possible.
|
||||||
|
|
||||||
|
uid_t uid = getuid(); // Always succeeds
|
||||||
|
errno = 0;
|
||||||
|
struct passwd *pw = getpwuid(uid);
|
||||||
|
if (pw)
|
||||||
|
{
|
||||||
|
if (strcmp(pw->pw_name, "root") == 0)
|
||||||
|
{
|
||||||
|
if (specified_user && (strcmp(specified_user, "root") == 0))
|
||||||
|
{
|
||||||
|
// MaxScale was invoked as root and with --user=root.
|
||||||
|
acceptable = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: MaxScale cannot be run as root.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
acceptable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: Could not obtain user information, MaxScale will not run: %s",
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
return acceptable;
|
||||||
|
}
|
||||||
|
@ -784,7 +784,7 @@ createInstance(SERVICE *service, char **options)
|
|||||||
"'tree' mode using GTID domain_id and server_id");
|
"'tree' mode using GTID domain_id and server_id");
|
||||||
|
|
||||||
/* Enable MariaDB the GTID maps store */
|
/* Enable MariaDB the GTID maps store */
|
||||||
if (inst->mariadb10_compat && inst->mariadb10_master_gtid)
|
if (inst->mariadb10_compat)
|
||||||
{
|
{
|
||||||
/* Create/Open R/W GTID sqlite3 storage */
|
/* Create/Open R/W GTID sqlite3 storage */
|
||||||
if (!blr_open_gtid_maps_storage(inst))
|
if (!blr_open_gtid_maps_storage(inst))
|
||||||
|
Reference in New Issue
Block a user