mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
5.5-merge
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2005 MySQL AB, 2009 Sun Microsystems, Inc.
|
||||
/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
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 */
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include "sql_priv.h" // SHOW_MY_BOOL
|
||||
#include "unireg.h"
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <my_pthread.h>
|
||||
#include <my_getopt.h>
|
||||
#include "sql_audit.h"
|
||||
#include <mysql/plugin_auth.h>
|
||||
#include "lock.h" // MYSQL_LOCK_IGNORE_TIMEOUT
|
||||
#include <mysql/plugin_auth.h>
|
||||
#define REPORT_TO_LOG 1
|
||||
@@ -42,9 +43,8 @@ extern struct st_maria_plugin *mysql_mandatory_plugins[];
|
||||
@note The order of the enumeration is critical.
|
||||
@see construct_options
|
||||
*/
|
||||
static const char *global_plugin_typelib_names[]=
|
||||
{ "OFF", "ON", "FORCE", NULL };
|
||||
enum enum_plugin_load_policy {PLUGIN_OFF, PLUGIN_ON, PLUGIN_FORCE};
|
||||
const char *global_plugin_typelib_names[]=
|
||||
{ "OFF", "ON", "FORCE", "FORCE_PLUS_PERMANENT", NULL };
|
||||
static TYPELIB global_plugin_typelib=
|
||||
{ array_elements(global_plugin_typelib_names)-1,
|
||||
"", global_plugin_typelib_names, NULL };
|
||||
@@ -301,6 +301,26 @@ static void report_error(int where_to, uint error, ...)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Check if the provided path is valid in the sense that it does cause
|
||||
a relative reference outside the directory.
|
||||
|
||||
@note Currently, this function only check if there are any
|
||||
characters in FN_DIRSEP in the string, but it might change in the
|
||||
future.
|
||||
|
||||
@code
|
||||
check_valid_path("../foo.so") -> true
|
||||
check_valid_path("foo.so") -> false
|
||||
@endcode
|
||||
*/
|
||||
bool check_valid_path(const char *path, size_t len)
|
||||
{
|
||||
size_t prefix= my_strcspn(files_charset_info, path, path + len, FN_DIRSEP);
|
||||
return prefix < len;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Value type thunks, allows the C world to play in the C++ world
|
||||
****************************************************************************/
|
||||
@@ -492,7 +512,8 @@ static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl,
|
||||
if (!cur)
|
||||
{
|
||||
free_plugin_mem(plugin_dl);
|
||||
report_error(report, ER_OUTOFMEMORY, plugin_dl->dl.length);
|
||||
report_error(report, ER_OUTOFMEMORY,
|
||||
static_cast<int>(plugin_dl.dl.length));
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
/*
|
||||
@@ -617,7 +638,8 @@ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl,
|
||||
if (!cur)
|
||||
{
|
||||
free_plugin_mem(plugin_dl);
|
||||
report_error(report, ER_OUTOFMEMORY, plugin_dl->dl.length);
|
||||
report_error(report, ER_OUTOFMEMORY,
|
||||
static_cast<int>(plugin_dl.dl.length));
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
/*
|
||||
@@ -648,13 +670,15 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
|
||||
struct st_plugin_dl *tmp, plugin_dl;
|
||||
void *sym;
|
||||
DBUG_ENTER("plugin_dl_add");
|
||||
DBUG_PRINT("enter", ("dl->str: '%s', dl->length: %d",
|
||||
dl->str, (int) dl->length));
|
||||
plugin_dir_len= strlen(opt_plugin_dir);
|
||||
/*
|
||||
Ensure that the dll doesn't have a path.
|
||||
This is done to ensure that only approved libraries from the
|
||||
plugin directory are used (to make this even remotely secure).
|
||||
*/
|
||||
if (my_strchr(files_charset_info, dl->str, dl->str + dl->length, FN_LIBCHAR) ||
|
||||
if (check_valid_path(dl->str, dl->length) ||
|
||||
check_string_char_length((LEX_STRING *) dl, "", NAME_CHAR_LEN,
|
||||
system_charset_info, 1) ||
|
||||
plugin_dir_len + dl->length + 1 >= FN_REFLEN)
|
||||
@@ -729,7 +753,8 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
|
||||
if (! (plugin_dl.dl.str= (char*) my_malloc(plugin_dl.dl.length, MYF(0))))
|
||||
{
|
||||
free_plugin_mem(&plugin_dl);
|
||||
report_error(report, ER_OUTOFMEMORY, plugin_dl.dl.length);
|
||||
report_error(report, ER_OUTOFMEMORY,
|
||||
static_cast<int>(plugin_dl.dl.length));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
plugin_dl.dl.length= copy_and_convert(plugin_dl.dl.str, plugin_dl.dl.length,
|
||||
@@ -740,7 +765,8 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
|
||||
if (! (tmp= plugin_dl_insert_or_reuse(&plugin_dl)))
|
||||
{
|
||||
free_plugin_mem(&plugin_dl);
|
||||
report_error(report, ER_OUTOFMEMORY, sizeof(struct st_plugin_dl));
|
||||
report_error(report, ER_OUTOFMEMORY,
|
||||
static_cast<int>(sizeof(struct st_plugin_dl)));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
DBUG_RETURN(tmp);
|
||||
@@ -1014,6 +1040,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
|
||||
tmp.name.length= name_len;
|
||||
tmp.ref_count= 0;
|
||||
tmp.state= PLUGIN_IS_UNINITIALIZED;
|
||||
tmp.load_option= PLUGIN_ON;
|
||||
if (test_plugin_options(tmp_root, &tmp, argc, argv))
|
||||
tmp.state= PLUGIN_IS_DISABLED;
|
||||
|
||||
@@ -1460,7 +1487,7 @@ int plugin_init(int *argc, char **argv, int flags)
|
||||
tmp.name.str= (char *)plugin->name;
|
||||
tmp.name.length= strlen(plugin->name);
|
||||
tmp.state= 0;
|
||||
tmp.is_mandatory= mandatory;
|
||||
tmp.load_option= mandatory ? PLUGIN_FORCE : PLUGIN_ON;
|
||||
|
||||
/*
|
||||
If the performance schema is compiled in,
|
||||
@@ -1479,7 +1506,7 @@ int plugin_init(int *argc, char **argv, int flags)
|
||||
to work, by using '--skip-performance-schema' (the plugin)
|
||||
*/
|
||||
if (!my_strcasecmp(&my_charset_latin1, plugin->name, "PERFORMANCE_SCHEMA"))
|
||||
tmp.is_mandatory= true;
|
||||
tmp.load_option= PLUGIN_FORCE;
|
||||
|
||||
free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE));
|
||||
if (test_plugin_options(&tmp_root, &tmp, argc, argv))
|
||||
@@ -1557,7 +1584,8 @@ int plugin_init(int *argc, char **argv, int flags)
|
||||
while ((plugin_ptr= *(--reap)))
|
||||
{
|
||||
mysql_mutex_unlock(&LOCK_plugin);
|
||||
if (plugin_ptr->is_mandatory)
|
||||
if (plugin_ptr->load_option == PLUGIN_FORCE ||
|
||||
plugin_ptr->load_option == PLUGIN_FORCE_PLUS_PERMANENT)
|
||||
reaped_mandatory_plugin= TRUE;
|
||||
plugin_deinitialize(plugin_ptr, true);
|
||||
mysql_mutex_lock(&LOCK_plugin);
|
||||
@@ -1961,7 +1989,11 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
|
||||
mysql_mutex_lock(&LOCK_plugin);
|
||||
mysql_rwlock_wrlock(&LOCK_system_variables_hash);
|
||||
|
||||
my_load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv, NULL);
|
||||
if (my_load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv, NULL))
|
||||
{
|
||||
report_error(REPORT_TO_USER, ER_PLUGIN_IS_NOT_LOADED, name->str);
|
||||
goto err;
|
||||
}
|
||||
error= plugin_add(thd->mem_root, name, dl, &argc, argv, REPORT_TO_USER);
|
||||
if (argv)
|
||||
free_defaults(argv);
|
||||
@@ -2073,6 +2105,11 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
|
||||
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str);
|
||||
goto err;
|
||||
}
|
||||
if (plugin->load_option == PLUGIN_FORCE_PLUS_PERMANENT)
|
||||
{
|
||||
my_error(ER_PLUGIN_IS_PERMANENT, MYF(0), name->str);
|
||||
goto err;
|
||||
}
|
||||
|
||||
plugin->state= PLUGIN_IS_DELETED;
|
||||
if (plugin->ref_count)
|
||||
@@ -3283,7 +3320,8 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
|
||||
plugin_dash.length + 1);
|
||||
strxmov(plugin_name_with_prefix_ptr, plugin_dash.str, plugin_name_ptr, NullS);
|
||||
|
||||
if (!tmp->is_mandatory)
|
||||
if (tmp->load_option != PLUGIN_FORCE &&
|
||||
tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT)
|
||||
{
|
||||
/* support --skip-plugin-foo syntax */
|
||||
options[0].name= plugin_name_ptr;
|
||||
@@ -3543,7 +3581,8 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
|
||||
{
|
||||
struct sys_var_chain chain= { NULL, NULL };
|
||||
bool disable_plugin;
|
||||
enum_plugin_load_policy plugin_load_policy= tmp->is_mandatory ? PLUGIN_FORCE : PLUGIN_ON;
|
||||
enum_plugin_load_option plugin_load_option= tmp->load_option;
|
||||
|
||||
MEM_ROOT *mem_root= alloc_root_inited(&tmp->mem_root) ?
|
||||
&tmp->mem_root : &plugin_mem_root;
|
||||
st_mysql_sys_var **opt;
|
||||
@@ -3557,13 +3596,11 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
|
||||
DBUG_ENTER("test_plugin_options");
|
||||
DBUG_ASSERT(tmp->plugin && tmp->name.str);
|
||||
|
||||
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
|
||||
/*
|
||||
The 'ndbcluster' storage engines is always disabled by default.
|
||||
*/
|
||||
if (!my_strcasecmp(&my_charset_latin1, tmp->name.str, "ndbcluster"))
|
||||
plugin_load_policy= PLUGIN_OFF;
|
||||
#endif
|
||||
plugin_load_option= PLUGIN_OFF;
|
||||
|
||||
for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
|
||||
count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */
|
||||
@@ -3587,8 +3624,9 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
|
||||
We adjust the default value to account for the hardcoded exceptions
|
||||
we have set for the federated and ndbcluster storage engines.
|
||||
*/
|
||||
if (!tmp->is_mandatory)
|
||||
opts[0].def_value= opts[1].def_value= plugin_load_policy;
|
||||
if (tmp->load_option != PLUGIN_FORCE &&
|
||||
tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT)
|
||||
opts[0].def_value= opts[1].def_value= plugin_load_option;
|
||||
|
||||
error= handle_options(argc, &argv, opts, NULL);
|
||||
(*argc)++; /* add back one for the program name */
|
||||
@@ -3603,12 +3641,13 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
|
||||
Set plugin loading policy from option value. First element in the option
|
||||
list is always the <plugin name> option value.
|
||||
*/
|
||||
if (!tmp->is_mandatory)
|
||||
plugin_load_policy= (enum_plugin_load_policy)*(ulong*)opts[0].value;
|
||||
if (tmp->load_option != PLUGIN_FORCE &&
|
||||
tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT)
|
||||
plugin_load_option= (enum_plugin_load_option) *(ulong*) opts[0].value;
|
||||
}
|
||||
|
||||
disable_plugin= (plugin_load_policy == PLUGIN_OFF);
|
||||
tmp->is_mandatory= (plugin_load_policy == PLUGIN_FORCE);
|
||||
disable_plugin= (plugin_load_option == PLUGIN_OFF);
|
||||
tmp->load_option= plugin_load_option;
|
||||
|
||||
/*
|
||||
If the plugin is disabled it should not be initialized.
|
||||
|
Reference in New Issue
Block a user