diff options
-rw-r--r-- | .bzrignore | 3 | ||||
-rw-r--r-- | client/Makefile.am | 7 | ||||
-rw-r--r-- | client/mysqldump.c | 35 | ||||
-rw-r--r-- | include/Makefile.am | 3 | ||||
-rw-r--r-- | include/my_user.h | 35 | ||||
-rw-r--r-- | include/mysql_com.h | 8 | ||||
-rw-r--r-- | libmysqld/Makefile.am | 2 | ||||
-rw-r--r-- | mysql-test/r/mysqldump.result | 12 | ||||
-rw-r--r-- | sql-common/Makefile.am | 2 | ||||
-rw-r--r-- | sql-common/my_user.c | 57 | ||||
-rw-r--r-- | sql/Makefile.am | 4 | ||||
-rw-r--r-- | sql/sp.cc | 4 | ||||
-rw-r--r-- | sql/sp_head.cc | 30 | ||||
-rw-r--r-- | sql/sql_acl.cc | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 4 | ||||
-rw-r--r-- | sql/sql_show.cc | 6 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 2 |
17 files changed, 175 insertions, 43 deletions
diff --git a/.bzrignore b/.bzrignore index 6e1da35a08f..109f9e536a9 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1269,3 +1269,6 @@ vio/viotest.cpp zlib/*.ds? zlib/*.vcproj libmysqld/ha_blackhole.cc +client/my_user.c +libmysqld/my_user.c +sql/my_user.c diff --git a/client/Makefile.am b/client/Makefile.am index 804f194085f..2c513d3d7c7 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -46,7 +46,7 @@ mysqltestmanager_pwgen_SOURCES = mysqlmanager-pwgen.c mysqltestmanagerc_SOURCES= mysqlmanagerc.c $(yassl_dummy_link_fix) mysqlcheck_SOURCES= mysqlcheck.c $(yassl_dummy_link_fix) mysqlshow_SOURCES= mysqlshow.c $(yassl_dummy_link_fix) -mysqldump_SOURCES= mysqldump.c $(yassl_dummy_link_fix) +mysqldump_SOURCES= mysqldump.c my_user.c $(yassl_dummy_link_fix) mysqlimport_SOURCES= mysqlimport.c $(yassl_dummy_link_fix) sql_src=log_event.h mysql_priv.h log_event.cc my_decimal.h my_decimal.cc strings_src=decimal.c @@ -62,7 +62,10 @@ link_sources: for f in $(strings_src) ; do \ rm -f $(srcdir)/$$f; \ @LN_CP_F@ $(top_srcdir)/strings/$$f $$f; \ - done; + done; \ + rm -f $(srcdir)/my_user.c; \ + @LN_CP_F@ $(top_srcdir)/sql-common/my_user.c my_user.c; + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/client/mysqldump.c b/client/mysqldump.c index 454fc0df84e..b24d67ec302 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -41,6 +41,7 @@ #include <my_global.h> #include <my_sys.h> +#include <my_user.h> #include <m_string.h> #include <m_ctype.h> #include <hash.h> @@ -1840,9 +1841,37 @@ static void dump_triggers_for_table (char *table, char *db) DELIMITER ;;\n"); while ((row= mysql_fetch_row(result))) { - fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\" */;;\n\ -/*!50003 CREATE TRIGGER %s %s %s ON %s FOR EACH ROW%s%s */;;\n\n", - row[6], /* sql_mode */ + fprintf(sql_file, + "/*!50003 SET SESSION SQL_MODE=\"%s\" */;;\n" + "/*!50003 CREATE */ ", + row[6] /* sql_mode */); + + if (mysql_num_fields(result) > 7) + { + /* + mysqldump can be run against the server, that does not support definer + in triggers (there is no DEFINER column in SHOW TRIGGERS output). So, + we should check if we have this column before accessing it. + */ + + uint user_name_len; + char user_name_str[USERNAME_LENGTH + 1]; + char quoted_user_name_str[USERNAME_LENGTH * 2 + 3]; + uint host_name_len; + char host_name_str[HOSTNAME_LENGTH + 1]; + char quoted_host_name_str[HOSTNAME_LENGTH * 2 + 3]; + + parse_user(row[7], strlen(row[7]), user_name_str, &user_name_len, + host_name_str, &host_name_len); + + fprintf(sql_file, + "/*!50017 DEFINER=%s@%s */ ", + quote_name(user_name_str, quoted_user_name_str, FALSE), + quote_name(host_name_str, quoted_host_name_str, FALSE)); + } + + fprintf(sql_file, + "/*!50003 TRIGGER %s %s %s ON %s FOR EACH ROW%s%s */;;\n\n", quote_name(row[0], name_buff, 0), /* Trigger */ row[4], /* Timing */ row[1], /* Event */ diff --git a/include/Makefile.am b/include/Makefile.am index 12b8c301b8d..07c32e3127b 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -30,7 +30,8 @@ noinst_HEADERS = config-win.h config-os2.h config-netware.h \ my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \ my_aes.h my_tree.h hash.h thr_alarm.h \ thr_lock.h t_ctype.h violite.h md5.h base64.h \ - mysql_version.h.in my_handler.h my_time.h decimal.h + mysql_version.h.in my_handler.h my_time.h decimal.h \ + my_user.h # mysql_version.h are generated CLEANFILES = mysql_version.h my_config.h readline openssl diff --git a/include/my_user.h b/include/my_user.h new file mode 100644 index 00000000000..2bd4208a34c --- /dev/null +++ b/include/my_user.h @@ -0,0 +1,35 @@ +/* Copyright (C) 2005 MySQL AB + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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 */ + +/* + This is a header for libraries containing functions used in both server and + only some of clients (but not in libmysql)... +*/ + +#ifndef _my_user_h_ +#define _my_user_h_ + +#include <my_global.h> + +C_MODE_START + +void parse_user(const char *user_id_str, uint user_id_len, + char *user_name_str, uint *user_name_len, + char *host_name_str, uint *host_name_len); + +C_MODE_END + +#endif /* _my_user_h_ */ diff --git a/include/mysql_com.h b/include/mysql_com.h index 1e595cdbba3..ec1c133799f 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -27,6 +27,14 @@ #define SERVER_VERSION_LENGTH 60 #define SQLSTATE_LENGTH 5 +/* + USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain + username and hostname parts of the user identifier with trailing zero in + MySQL standard format: + user_name_part@host_name_part\0 +*/ +#define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_LENGTH + 2 + #define LOCAL_HOST "localhost" #define LOCAL_HOST_NAMEDPIPE "." diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index f07bbacba02..5ec9cdfe5bf 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -63,7 +63,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \ sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \ parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \ - ha_blackhole.cc ha_archive.cc + ha_blackhole.cc ha_archive.cc my_user.c libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources) libmysqld_a_SOURCES= diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 62d2b46e617..4e2564c69da 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1986,7 +1986,7 @@ UNLOCK TABLES; /*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/; DELIMITER ;; /*!50003 SET SESSION SQL_MODE="" */;; -/*!50003 CREATE TRIGGER `trg1` BEFORE INSERT ON `t1` FOR EACH ROW +/*!50003 CREATE */ /*!50017 DEFINER=`root`@`localhost` */ /*!50003 TRIGGER `trg1` BEFORE INSERT ON `t1` FOR EACH ROW begin if new.a > 10 then set new.a := 10; @@ -1995,12 +1995,12 @@ end if; end */;; /*!50003 SET SESSION SQL_MODE="" */;; -/*!50003 CREATE TRIGGER `trg2` BEFORE UPDATE ON `t1` FOR EACH ROW begin +/*!50003 CREATE */ /*!50017 DEFINER=`root`@`localhost` */ /*!50003 TRIGGER `trg2` BEFORE UPDATE ON `t1` FOR EACH ROW begin if old.a % 2 = 0 then set new.b := 12; end if; end */;; /*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER" */;; -/*!50003 CREATE TRIGGER `trg3` AFTER UPDATE ON `t1` FOR EACH ROW +/*!50003 CREATE */ /*!50017 DEFINER=`root`@`localhost` */ /*!50003 TRIGGER `trg3` AFTER UPDATE ON `t1` FOR EACH ROW begin if new.a = -1 then set @fired:= "Yes"; @@ -2023,7 +2023,7 @@ UNLOCK TABLES; /*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/; DELIMITER ;; /*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER" */;; -/*!50003 CREATE TRIGGER `trg4` BEFORE INSERT ON `t2` FOR EACH ROW +/*!50003 CREATE */ /*!50017 DEFINER=`root`@`localhost` */ /*!50003 TRIGGER `trg4` BEFORE INSERT ON `t2` FOR EACH ROW begin if new.a > 10 then set @fired:= "No"; @@ -2376,7 +2376,7 @@ UNLOCK TABLES; /*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/; DELIMITER ;; /*!50003 SET SESSION SQL_MODE="" */;; -/*!50003 CREATE TRIGGER `test trig` BEFORE INSERT ON `t1 test` FOR EACH ROW BEGIN +/*!50003 CREATE */ /*!50017 DEFINER=`root`@`localhost` */ /*!50003 TRIGGER `test trig` BEFORE INSERT ON `t1 test` FOR EACH ROW BEGIN INSERT INTO `t2 test` SET a2 = NEW.a1; END */;; DELIMITER ; @@ -2532,7 +2532,7 @@ UNLOCK TABLES; /*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/; DELIMITER ;; /*!50003 SET SESSION SQL_MODE="IGNORE_SPACE" */;; -/*!50003 CREATE TRIGGER `tr1` BEFORE INSERT ON `t1` FOR EACH ROW BEGIN +/*!50003 CREATE */ /*!50017 DEFINER=`root`@`localhost` */ /*!50003 TRIGGER `tr1` BEFORE INSERT ON `t1` FOR EACH ROW BEGIN SET new.a = 0; END */;; diff --git a/sql-common/Makefile.am b/sql-common/Makefile.am index 6bd42d70e4f..d71523a741c 100644 --- a/sql-common/Makefile.am +++ b/sql-common/Makefile.am @@ -15,7 +15,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## Process this file with automake to create Makefile.in -EXTRA_DIST = client.c pack.c my_time.c +EXTRA_DIST = client.c pack.c my_time.c my_user.c # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/sql-common/my_user.c b/sql-common/my_user.c new file mode 100644 index 00000000000..c39f08e520f --- /dev/null +++ b/sql-common/my_user.c @@ -0,0 +1,57 @@ +/* Copyright (C) 2005 MySQL AB + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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 */ + +#include <my_user.h> +#include <m_string.h> + + +/* + Parse user value to user name and host name parts. + + SYNOPSIS + user_id_str [IN] User value string (the source). + user_id_len [IN] Length of the user value. + user_name_str [OUT] Buffer to store user name part. + Must be not less than USERNAME_LENGTH + 1. + user_name_len [OUT] A place to store length of the user name part. + host_name_str [OUT] Buffer to store host name part. + Must be not less than HOSTNAME_LENGTH + 1. + host_name_len [OUT] A place to store length of the host name part. +*/ + +void parse_user(const char *user_id_str, uint user_id_len, + char *user_name_str, uint *user_name_len, + char *host_name_str, uint *host_name_len) +{ + char *p= strrchr(user_id_str, '@'); + + if (!p) + { + *user_name_len= 0; + *host_name_len= 0; + } + else + { + *user_name_len= p - user_id_str; + *host_name_len= user_id_len - *user_name_len - 1; + + memcpy(user_name_str, user_id_str, *user_name_len); + memcpy(host_name_str, p + 1, *host_name_len); + } + + user_name_str[*user_name_len]= 0; + host_name_str[*host_name_len]= 0; +} diff --git a/sql/Makefile.am b/sql/Makefile.am index 1437751bf2f..d701c18a4d7 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -97,7 +97,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ stacktrace.c repl_failsafe.h repl_failsafe.cc \ sql_olap.cc sql_view.cc \ gstream.cc spatial.cc sql_help.cc sql_cursor.cc \ - tztime.cc my_time.c my_decimal.cc\ + tztime.cc my_time.c my_user.c my_decimal.cc\ sp_head.cc sp_pcontext.cc sp_rcontext.cc sp.cc \ sp_cache.cc parse_file.cc sql_trigger.cc \ examples/ha_example.cc ha_archive.cc \ @@ -133,6 +133,8 @@ link_sources: mysql_tzinfo_to_sql.cc @LN_CP_F@ $(top_srcdir)/sql-common/client.c client.c rm -f my_time.c @LN_CP_F@ $(top_srcdir)/sql-common/my_time.c my_time.c + rm -f my_user.c + @LN_CP_F@ $(top_srcdir)/sql-common/my_user.c my_user.c mysql_tzinfo_to_sql.o: $(mysql_tzinfo_to_sql_SOURCES) $(CXXCOMPILE) -c $(INCLUDES) -DTZINFO2SQL $< diff --git a/sql/sp.cc b/sql/sp.cc index a9b1a462d5f..37a9c02124e 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -480,7 +480,7 @@ db_create_routine(THD *thd, int type, sp_head *sp) { int ret; TABLE *table; - char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; + char definer[USER_HOST_BUFF_SIZE]; char olddb[128]; bool dbchanged; DBUG_ENTER("db_create_routine"); @@ -940,7 +940,7 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, ulong level; sp_head *new_sp; const char *returns= ""; - char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; + char definer[USER_HOST_BUFF_SIZE]; String retstr(64); DBUG_PRINT("info", ("found: 0x%lx", (ulong)sp)); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 12f9260e7b1..d3045467f91 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -31,6 +31,8 @@ #define SP_STMT_PRINT_MAXLEN 40 +#include <my_user.h> + Item_result sp_map_result_type(enum enum_field_types type) { @@ -1752,29 +1754,21 @@ sp_head::set_info(longlong created, longlong modified, void - sp_head::set_definer(const char *definer, uint definerlen) { - const char *p= strrchr(definer, '@'); + uint user_name_len; + char user_name_str[USERNAME_LENGTH + 1]; + uint host_name_len; + char host_name_str[HOSTNAME_LENGTH + 1]; - if (!p) - { - m_definer_user.str= (char*) ""; - m_definer_user.length= 0; - m_definer_host.str= (char*) ""; - m_definer_host.length= 0; - } - else - { - const uint user_name_len= p - definer; - const uint host_name_len= definerlen - user_name_len - 1; + parse_user(definer, definerlen, user_name_str, &user_name_len, + host_name_str, &host_name_len); - m_definer_user.str= strmake_root(mem_root, definer, user_name_len); - m_definer_user.length= user_name_len; + m_definer_user.str= strmake_root(mem_root, user_name_str, user_name_len); + m_definer_user.length= user_name_len; - m_definer_host.str= strmake_root(mem_root, p + 1, host_name_len); - m_definer_host.length= host_name_len; - } + m_definer_host.str= strmake_root(mem_root, host_name_str, host_name_len); + m_definer_host.length= host_name_len; } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 7bb84895da5..130674b47f9 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2490,7 +2490,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, ulong rights, ulong col_rights, bool revoke_grant) { - char grantor[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; + char grantor[USER_HOST_BUFF_SIZE]; int old_row_exists = 1; int error=0; ulong store_table_rights, store_col_rights; @@ -2608,7 +2608,7 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, const char *db, const char *routine_name, bool is_proc, ulong rights, bool revoke_grant) { - char grantor[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; + char grantor[USER_HOST_BUFF_SIZE]; int old_row_exists= 1; int error=0; ulong store_proc_rights; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9cdb288c045..76d24ede8f5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -214,7 +214,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, { int return_val= 0; uint temp_len, user_len; - char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2]; + char temp_user[USER_HOST_BUFF_SIZE]; struct user_conn *uc; DBUG_ASSERT(user != 0); @@ -743,7 +743,7 @@ static void reset_mqh(LEX_USER *lu, bool get_them= 0) { USER_CONN *uc; uint temp_len=lu->user.length+lu->host.length+2; - char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2]; + char temp_user[USER_HOST_BUFF_SIZE]; memcpy(temp_user,lu->user.str,lu->user.length); memcpy(temp_user+lu->user.length+1,lu->host.str,lu->host.length); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 089314078a6..d15df686e40 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2887,7 +2887,7 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond) int res= 0; TABLE *table= tables->table; bool full_access; - char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; + char definer[USER_HOST_BUFF_SIZE]; Open_tables_state open_tables_state_backup; DBUG_ENTER("fill_schema_proc"); @@ -3029,7 +3029,7 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables, { CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("get_schema_views_record"); - char definer[HOSTNAME_LENGTH + USERNAME_LENGTH + 2]; + char definer[USER_HOST_BUFF_SIZE]; uint definer_len; if (tables->view) @@ -3213,7 +3213,7 @@ static int get_schema_triggers_record(THD *thd, struct st_table_list *tables, LEX_STRING trigger_name; LEX_STRING trigger_stmt; ulong sql_mode; - char definer_holder[HOSTNAME_LENGTH + USERNAME_LENGTH + 2]; + char definer_holder[USER_HOST_BUFF_SIZE]; LEX_STRING definer_buffer; definer_buffer.str= definer_holder; if (triggers->get_trigger_info(thd, (enum trg_event_type) event, diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index bbc32950c2d..c70914edc31 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -317,7 +317,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, LEX_STRING dir, file, trigname_file; LEX_STRING *trg_def, *name; ulonglong *trg_sql_mode; - char trg_definer_holder[HOSTNAME_LENGTH + USERNAME_LENGTH + 2]; + char trg_definer_holder[USER_HOST_BUFF_SIZE]; LEX_STRING *trg_definer; Item_trigger_field *trg_field; struct st_trigname trigname; |