From 92e31e96a2c6f2f98e77217534fcc3712e7b4fa5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Dec 2007 13:24:43 +0000 Subject: Add new pkgplugindir handling to seperate plugins from libraries, and allow override for binary distributions. Extend mysql_config to print compiled-in plugin location for third-party plugins to use. Resolves bug#31736. libmysqld/Makefile.am: Use pkgplugindir. plugin/daemon_example/Makefile.am: Use pkgplugindir. plugin/fulltext/Makefile.am: Use pkgplugindir. scripts/Makefile.am: Add pkgplugindir. scripts/make_binary_distribution.sh: Add pkgplugindir. scripts/mysql_config.sh: Add pkgplugindir. sql/Makefile.am: Use pkgplugindir. sql/mysqld.cc: Use PLUGINDIR, derived from pkgplugindir, instead of LIBDIR for plugins. sql/unireg.h: Use PLUGINDIR instead of LIBDIR, and define to be the default setting of pkgplugindir. storage/innobase/Makefile.am: Use pkgplugindir. storage/archive/Makefile.am: Use pkgplugindir. storage/blackhole/Makefile.am: Use pkgplugindir. storage/example/Makefile.am: Use pkgplugindir. storage/federated/Makefile.am: Use pkgplugindir. --- sql/Makefile.am | 3 ++- sql/mysqld.cc | 2 +- sql/unireg.h | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/Makefile.am b/sql/Makefile.am index 0081417d492..02a92dee7a7 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -19,6 +19,7 @@ MYSQLDATAdir = $(localstatedir) MYSQLSHAREdir = $(pkgdatadir) MYSQLBASEdir= $(prefix) MYSQLLIBdir= $(pkglibdir) +pkgplugindir = $(libdir)/@PACKAGE@/plugin INCLUDES = @ZLIB_INCLUDES@ \ -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_srcdir)/regex -I$(srcdir) $(openssl_includes) @@ -136,7 +137,7 @@ DEFS = -DMYSQL_SERVER \ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ -DDATADIR="\"$(MYSQLDATAdir)\"" \ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \ - -DLIBDIR="\"$(MYSQLLIBdir)\"" \ + -DPLUGINDIR="\"$(pkgplugindir)\"" \ @DEFS@ BUILT_MAINT_SRC = sql_yacc.cc sql_yacc.h diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2f264482d94..48e486f8d02 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8032,7 +8032,7 @@ static void fix_paths(void) (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home); (void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home); (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr : - get_relative_path(LIBDIR), mysql_home); + get_relative_path(PLUGINDIR), mysql_home); opt_plugin_dir_ptr= opt_plugin_dir; char *sharedir=get_relative_path(SHAREDIR); diff --git a/sql/unireg.h b/sql/unireg.h index f0b4a88c7f8..d6a72e6589f 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -35,8 +35,8 @@ #ifndef SHAREDIR #define SHAREDIR "share/" #endif -#ifndef LIBDIR -#define LIBDIR "lib/" +#ifndef PLUGINDIR +#define PLUGINDIR "lib/plugin" #endif #define ER(X) errmesg[(X) - ER_ERROR_FIRST] -- cgit v1.2.1 From ad367fe00a28d4d3b652900344597f6517fa8462 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Jan 2008 13:00:46 +0000 Subject: Use pkglibdir to simplify pkgplugindir, and fix the path in a couple of Makefiles. Continuation of the fix for bug#31736. libmysqld/Makefile.am: Use pkglibdir plugin/daemon_example/Makefile.am: Use pkglibdir plugin/fulltext/Makefile.am: Use pkglibdir scripts/Makefile.am: Use pkglibdir scripts/make_binary_distribution.sh: Update comment sql/Makefile.am: Use pkglibdir storage/archive/Makefile.am: Use pkglibdir storage/blackhole/Makefile.am: Use pkglibdir storage/example/Makefile.am: Use pkglibdir, fix pkgplugindir storage/federated/Makefile.am: Use pkglibdir storage/innobase/Makefile.am: Use pkglibdir, fix pkgplugindir --- sql/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/Makefile.am b/sql/Makefile.am index 02a92dee7a7..92ae7a05df7 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -19,7 +19,7 @@ MYSQLDATAdir = $(localstatedir) MYSQLSHAREdir = $(pkgdatadir) MYSQLBASEdir= $(prefix) MYSQLLIBdir= $(pkglibdir) -pkgplugindir = $(libdir)/@PACKAGE@/plugin +pkgplugindir = $(pkglibdir)/plugin INCLUDES = @ZLIB_INCLUDES@ \ -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_srcdir)/regex -I$(srcdir) $(openssl_includes) -- cgit v1.2.1 From 2b7dda9e9d06f2ab6036da39250a765926c9c437 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 5 Mar 2008 09:33:32 -0500 Subject: Bug#33464: DROP FUNCTION caused a crash The cause of the crash is an assertion failure that we do not emit an error message (grant not found) and then return "ok". The assertion is valid, and we were ignoring the buggy behavior prior to the "Diagnostics" result-verification. Use an error handler to mutate innocuous missing-grant errors, when removing routines, into warnings. mysql-test/r/drop.result: Show that the crash disappears. Also prepare for the larger bug to be fixed with only minor changes to this test. mysql-test/t/drop.test: Show that the crash disappears. Also prepare for the larger bug to be fixed with only minor changes to this test. sql/sql_acl.cc: Disable a segment of code that makes a faulty assumption about the existence of a routine's defining user, until that assumption becomes true. Push a new handler onto the error-handler stack, so that when removing a routine, a missing ACL grant is now a warning instead of an error. If any unexpected error is raised then tell the caller. --- sql/sql_acl.cc | 105 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 83 insertions(+), 22 deletions(-) (limited to 'sql') diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 0d563ab9051..b9d72998933 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2779,6 +2779,10 @@ table_error: } +/** + @retval 0 success + @retval -1 error +*/ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, TABLE *table, const LEX_USER &combo, const char *db, const char *routine_name, @@ -2800,14 +2804,11 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, thd->security_ctx->host_or_ip, NullS); /* - The following should always succeed as new users are created before - this function is called! + New users are created before this function is called. + + There may be some cases where a routine's definer is removed but the + routine remains. */ - if (!find_acl_user(combo.host.str, combo.user.str, FALSE)) - { - my_error(ER_PASSWORD_NO_MATCH,MYF(0)); - DBUG_RETURN(-1); - } table->use_all_columns(); restore_record(table, s->default_values); // Get empty record @@ -3321,7 +3322,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, } if (replace_routine_table(thd, grant_name, tables[1].table, *Str, - db_name, table_name, is_proc, rights, revoke_grant)) + db_name, table_name, is_proc, rights, + revoke_grant) != 0) { result= TRUE; continue; @@ -5949,11 +5951,11 @@ bool mysql_revoke_all(THD *thd, List &list) if (!strcmp(lex_user->user.str,user) && !strcmp(lex_user->host.str, host)) { - if (!replace_routine_table(thd,grant_proc,tables[4].table,*lex_user, + if (replace_routine_table(thd,grant_proc,tables[4].table,*lex_user, grant_proc->db, grant_proc->tname, is_proc, - ~(ulong)0, 1)) + ~(ulong)0, 1) == 0) { revoked= 1; continue; @@ -5979,17 +5981,73 @@ bool mysql_revoke_all(THD *thd, List &list) } -/* - Revoke privileges for all users on a stored procedure - SYNOPSIS - sp_revoke_privileges() + +/** + If the defining user for a routine does not exist, then the ACL lookup + code should raise two errors which we should intercept. We convert the more + descriptive error into a warning, and consume the other. + + If any other errors are raised, then we set a flag that should indicate + that there was some failure we should complain at a higher level. +*/ +class Silence_routine_definer_errors : public Internal_error_handler +{ +public: + Silence_routine_definer_errors() + : is_grave(FALSE) + {} + + virtual ~Silence_routine_definer_errors() + {} + + virtual bool handle_error(uint sql_errno, const char *message, + MYSQL_ERROR::enum_warning_level level, + THD *thd); + + bool has_errors() { return is_grave; } + +private: + bool is_grave; +}; + +bool +Silence_routine_definer_errors::handle_error(uint sql_errno, + const char *message, + MYSQL_ERROR::enum_warning_level level, + THD *thd) +{ + if (level == MYSQL_ERROR::WARN_LEVEL_ERROR) + { + switch (sql_errno) + { + case ER_NONEXISTING_PROC_GRANT: + /* Convert the error into a warning. */ + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, sql_errno, message); + return TRUE; + default: + is_grave= TRUE; + } + } + + return FALSE; +} + + +/** + Revoke privileges for all users on a stored procedure. Use an error handler + that converts errors about missing grants into warnings. + + @param thd The current thread. + @param db DB of the stored procedure + @param name Name of the stored procedure - RETURN + @retval 0 OK. + @retval < 0 Error. Error message not yet sent. */ @@ -6000,11 +6058,15 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, int result; TABLE_LIST tables[GRANT_TABLES]; HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash; + Silence_routine_definer_errors error_handler; DBUG_ENTER("sp_revoke_privileges"); if ((result= open_grant_tables(thd, tables))) DBUG_RETURN(result != 1); + /* Be sure to pop this before exiting this scope! */ + thd->push_internal_handler(&error_handler); + rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -6031,14 +6093,14 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, grant_proc->host.hostname : (char*)""; lex_user.host.length= grant_proc->host.hostname ? strlen(grant_proc->host.hostname) : 0; - if (!replace_routine_table(thd,grant_proc,tables[4].table,lex_user, - grant_proc->db, grant_proc->tname, - is_proc, ~(ulong)0, 1)) + + if (replace_routine_table(thd,grant_proc,tables[4].table,lex_user, + grant_proc->db, grant_proc->tname, + is_proc, ~(ulong)0, 1) == 0) { revoked= 1; continue; } - result= -1; // Something went wrong } counter++; } @@ -6048,10 +6110,9 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, rw_unlock(&LOCK_grant); close_thread_tables(thd); - if (result) - my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0)); + thd->pop_internal_handler(); - DBUG_RETURN(result); + DBUG_RETURN(error_handler.has_errors()); } -- cgit v1.2.1 From b6595704efebe3678b5696996bd84d35e3511256 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 5 Mar 2008 11:23:58 -0500 Subject: Bug#34726: open_tables() crashes server if running with --debug The DBUG code emits the current value of the proc_info member of THD, which may be set to NULL. It was wrong to dereference that value with the format string %s without verifying that it was valid. Now, insert an inline test that substitutes the string "(null)" for NULL pointers. sql/sql_class.cc: Dereferencing a NULL is illegal (though not fatal for %s on some platforms), and we have no assurance that the caller didn't call us with a valid string. --- sql/sql_class.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 75376c53f68..ead7439bc81 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -253,7 +253,8 @@ const char *set_thd_proc_info(THD *thd, const char *info, const unsigned int calling_line) { const char *old_info= thd->proc_info; - DBUG_PRINT("proc_info", ("%s:%d %s", calling_file, calling_line, info)); + DBUG_PRINT("proc_info", ("%s:%d %s", calling_file, calling_line, + (info != NULL) ? info : "(null)")); #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) thd->profiling.status_change(info, calling_function, calling_file, calling_line); #endif -- cgit v1.2.1 From b5978a9424c6213a8282713feb3734c2f92968c8 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Mar 2008 12:40:12 -0400 Subject: Bug#26703: DROP DATABASE fails if database contains a #mysql50# \ table with backticks (Thanks to Lu Jingdong, though I did not take his patch directly, as it contained a significant flaw.) It wasn't a backtick/parsing problem. We merely didn't anticipate and allocate enough space to handle the optional "#mysql50#" table- name prefix. Now, allocate that extra space in case we need it when we look up a legacy table to get its file's name. mysql-test/r/drop.result: Verify that databases with old-style files can be removed. mysql-test/t/drop.test: Verify that databases with old-style files can be removed. sql/sql_db.cc: Extend the size of the memory that holds the table's name, so that the legacy "mysql50" prefix fits. --- sql/sql_db.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_db.cc b/sql/sql_db.cc index d03ac7921ac..75f9f5e847d 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -1111,12 +1111,17 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, /* Drop the table nicely */ *extension= 0; // Remove extension TABLE_LIST *table_list=(TABLE_LIST*) - thd->calloc(sizeof(*table_list)+ strlen(db)+strlen(file->name)+2); + thd->calloc(sizeof(*table_list) + + strlen(db) + 1 + + MYSQL50_TABLE_NAME_PREFIX_LENGTH + + strlen(file->name) + 1); + if (!table_list) - goto err; + goto err; table_list->db= (char*) (table_list+1); table_list->table_name= strmov(table_list->db, db) + 1; VOID(filename_to_tablename(file->name, table_list->table_name, + MYSQL50_TABLE_NAME_PREFIX_LENGTH + strlen(file->name) + 1)); table_list->alias= table_list->table_name; // If lower_case_table_names=2 table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix); -- cgit v1.2.1