Below is the list of changes that have just been committed into a local
5.0 repository of bell. When bell does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.1992 05/09/20 21:27:28 bell@stripped +6 -0
Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-5.0
into sanja.is.com.ua:/home/bell/mysql/bk/work-owner5-5.0
sql/item_func.cc
1.254 05/09/20 21:27:24 bell@stripped +0 -3
merge
sql/sql_view.cc
1.66 05/09/20 21:24:21 bell@stripped +0 -0
Auto merged
sql/sql_show.cc
1.284 05/09/20 21:24:21 bell@stripped +0 -0
Auto merged
sql/sql_base.cc
1.304 05/09/20 21:24:21 bell@stripped +0 -0
Auto merged
sql/item_strfunc.cc
1.254 05/09/20 21:24:21 bell@stripped +0 -0
Auto merged
sql/ha_innodb.cc
1.258 05/09/20 21:24:21 bell@stripped +0 -0
Auto merged
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: bell
# Host: sanja.is.com.ua
# Root: /home/bell/mysql/bk/work-owner5-5.0/RESYNC
--- 1.253/sql/item_func.cc 2005-09-20 21:20:32 +03:00
+++ 1.254/sql/item_func.cc 2005-09-20 21:27:24 +03:00
@@ -4723,14 +4723,8 @@
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (check_routine_access(thd, EXECUTE_ACL,
- m_sp->m_db.str, m_sp->m_name.str, 0, 0) ||
- sp_change_security_context(thd, m_sp, &save_ctx))
+ if (check_access(EXECUTE_ACL, 0, &save_ctx))
goto error;
- if (save_ctx &&
- check_routine_access(thd, EXECUTE_ACL,
- m_sp->m_db.str, m_sp->m_name.str, 0, 0))
- goto error_check_ctx;
#endif
/*
Disable the binlogging if this is not a SELECT statement. If this is a
@@ -4749,7 +4743,6 @@
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
#ifndef NO_EMBEDDED_ACCESS_CHECKS
-error_check_ctx:
sp_restore_security_context(thd, save_ctx);
#endif
@@ -4856,4 +4849,84 @@
res= Item_func::tmp_table_field(t_arg);
DBUG_RETURN(res);
+}
+
+/*
+ Check access rigths to function
+
+ SYNOPSIS
+ check_access()
+ want_access requested access
+ report_error whether to set error to thd->net.report_error
+ sp_ctx sp security context for switching
+
+ RETURN
+ 0 Access granted
+ 1 Requested access can't be granted or function doesn't exists
+
+ NOTES
+ Checks if requested access to function can be granted to user.
+ If function isn't found yet, it searches function first.
+ If function can't be found or user don't have requested access
+ and report_error is true error is raised.
+ If security context sp_ctx is provided and access can be granted then
+ switch back to previous context isn't performed.
+ In case of access error or if context is not provided then check_access()
+ switches back to previous security context.
+*/
+bool
+Item_func_sp::check_access(ulong want_access, bool report_error, st_sp_security_context *sp_ctx)
+{
+ bool res;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ THD *thd= current_thd;
+ st_sp_security_context save_ctx, *curr_ctx= sp_ctx?sp_ctx:&save_ctx;
+ bool ctx_switched= 0;
+ res= 1;
+ if (! m_sp && ! (m_sp= sp_find_function(thd, m_name, TRUE)))
+ {
+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
+ if (report_error)
+ thd->net.report_error= 1;
+ goto error;
+ }
+
+ if (check_routine_access(thd, want_access,
+ m_sp->m_db.str, m_sp->m_name.str, 0, 0))
+ {
+ if (report_error)
+ thd->net.report_error= 1;
+ goto error;
+ }
+
+ sp_change_security_context(thd, m_sp, curr_ctx);
+ ctx_switched= curr_ctx->changed;
+ if (curr_ctx->changed &&
+ check_routine_access(thd, want_access,
+ m_sp->m_db.str, m_sp->m_name.str, 0, 0))
+ {
+ if (report_error)
+ thd->net.report_error= 1;
+ goto error_check_ctx;
+ }
+ res= 0;
+error_check_ctx:
+ if (ctx_switched && (res || !sp_ctx))
+ sp_restore_security_context(thd, m_sp, curr_ctx);
+error:
+#else
+ res= 0;
+#endif
+ return res;
+};
+
+bool
+Item_func_sp::fix_fields(THD *thd, Item **ref)
+{
+ bool res;
+ DBUG_ASSERT(fixed == 0);
+ res= Item_func::fix_fields(thd, ref);
+ if (!res && check_access(EXECUTE_ACL, 1, NULL))
+ res= 1;
+ return res;
}
--- 1.253/sql/item_strfunc.cc 2005-09-20 21:20:32 +03:00
+++ 1.254/sql/item_strfunc.cc 2005-09-20 21:24:21 +03:00
@@ -1981,6 +1981,33 @@
}
str->set_charset(collation.collation);
str->realloc(str->length()); // Add end 0 (for Purify)
+
+ /* Check whether we got a well-formed string */
+ CHARSET_INFO *cs= collation.collation;
+ int well_formed_error;
+ uint wlen= cs->cset->well_formed_len(cs,
+ str->ptr(), str->ptr() + str->length(),
+ str->length(), &well_formed_error);
+ if (wlen < str->length())
+ {
+ THD *thd= current_thd;
+ char hexbuf[7];
+ enum MYSQL_ERROR::enum_warning_level level;
+ uint diff= str->length() - wlen;
+ set_if_smaller(diff, 3);
+ octet2hex(hexbuf, (const uchar*) str->ptr() + wlen, diff);
+ if (thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))
+ {
+ level= MYSQL_ERROR::WARN_LEVEL_ERROR;
+ null_value= 1;
+ str= 0;
+ }
+ else
+ level= MYSQL_ERROR::WARN_LEVEL_WARN;
+ push_warning_printf(thd, level, ER_INVALID_CHARACTER_STRING,
+ ER(ER_INVALID_CHARACTER_STRING), cs->csname, hexbuf);
+ }
return str;
}
--- 1.303/sql/sql_base.cc 2005-09-15 22:29:01 +03:00
+++ 1.304/sql/sql_base.cc 2005-09-20 21:24:21 +03:00
@@ -2948,6 +2948,18 @@
belongs - differs from 'table_list' only for
NATURAL_USING joins.
+ DESCRIPTION
+ Find a field in a table reference depending on the type of table
+ reference. There are three types of table references with respect
+ to the representation of their result columns:
+ - an array of Field_translator objects for MERGE views and some
+ information_schema tables,
+ - an array of Field objects (and possibly a name hash) for stored
+ tables,
+ - a list of Natural_join_column objects for NATURAL/USING joins.
+ This procedure detects the type of the table reference 'table_list'
+ and calls the corresponding search routine.
+
RETURN
0 field is not found
view_ref_found found value in VIEW (real result is in *ref)
@@ -2971,16 +2983,30 @@
/*
Check that the table and database that qualify the current field name
- are the same as the table we are going to search for the field.
- This is done differently for NATURAL/USING joins or nested joins that
- are operands of NATURAL/USING joins because there we can't simply
- compare the qualifying table and database names with the ones of
- 'table_list' because each field in such a join may originate from a
- different table.
+ are the same as the table reference we are going to search for the field.
+
+ We exclude from the test below NATURAL/USING joins and any nested join
+ that is an operand of NATURAL/USING join, because each column in such
+ joins may potentially originate from a different table. However, base
+ tables and views that are under some NATURAL/USING join are searched
+ as usual base tables/views.
+
+ We include explicitly table references with a 'field_translation' table,
+ because if there are views over natural joins we don't want to search
+ inside the view, but we want to search directly in the view columns
+ which are represented as a 'field_translation'.
+
TODO: Ensure that table_name, db_name and tables->db always points to
something !
*/
- if (!(table_list->nested_join && table_list->join_columns) &&
+ if (/* Exclude natural joins and nested joins underlying natural joins. */
+ (!(table_list->nested_join && table_list->join_columns) ||
+ /* Include merge views and information schema tables. */
+ table_list->field_translation) &&
+ /*
+ Test if the field qualifiers match the table reference we plan
+ to search.
+ */
table_name && table_name[0] &&
(my_strcasecmp(table_alias_charset, table_list->alias, table_name) ||
(db_name && db_name[0] && table_list->db && table_list->db[0] &&
@@ -2988,25 +3014,48 @@
DBUG_RETURN(0);
*actual_table= NULL;
+
if (table_list->field_translation)
{
+ /* 'table_list' is a view or an information schema table. */
if ((fld= find_field_in_view(thd, table_list, name, item_name, length,
ref, check_grants_view,
register_tree_change)))
*actual_table= table_list;
}
- else if (table_list->nested_join && table_list->join_columns)
+ else if (!(table_list->nested_join && table_list->join_columns))
+ {
+ /*
+ 'table_list' is a stored table. It is so because the only type of nested
+ join passed to this procedure is a NATURAL/USING join or an operand of a
+ NATURAL/USING join.
+ */
+ if ((fld= find_field_in_table(thd, table_list->table, name, length,
+ check_grants_table, allow_rowid,
+ cached_field_index_ptr)))
+ *actual_table= table_list;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ /* check for views with temporary table algorithm */
+ if (check_grants_view && table_list->view &&
+ fld && fld != WRONG_GRANT &&
+ check_grant_column(thd, &table_list->grant,
+ table_list->view_db.str,
+ table_list->view_name.str,
+ name, length))
+ fld= WRONG_GRANT;
+#endif
+ }
+ else
{
/*
- If this is a NATURAL/USING join, or an operand of such join which is a
- join itself, and the field name is qualified, then search for the field
- in the operands of the join.
+ 'table_list' is a NATURAL/USING join, or an operand of such join that
+ is a nested join itself.
+
+ If the field name we search for is qualified, then search for the field
+ in the table references used by NATURAL/USING the join.
*/
if (table_name && table_name[0])
{
- /*
- Qualified field; Search for it in the tables used by the natural join.
- */
List_iterator<TABLE_LIST> it(table_list->nested_join->join_list);
TABLE_LIST *table;
while ((table= it++))
@@ -3031,23 +3080,6 @@
/* TIMOUR_TODO: check this with Sanja */
check_grants_table || check_grants_view,
register_tree_change, actual_table);
- }
- else
- {
- if ((fld= find_field_in_table(thd, table_list->table, name, length,
- check_grants_table, allow_rowid,
- cached_field_index_ptr)))
- *actual_table= table_list;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- /* check for views with temporary table algorithm */
- if (check_grants_view && table_list->view &&
- fld && fld != WRONG_GRANT &&
- check_grant_column(thd, &table_list->grant,
- table_list->view_db.str,
- table_list->view_name.str,
- name, length))
- fld= WRONG_GRANT;
-#endif
}
DBUG_RETURN(fld);
--- 1.283/sql/sql_show.cc 2005-09-16 09:15:41 +03:00
+++ 1.284/sql/sql_show.cc 2005-09-20 21:24:21 +03:00
@@ -415,8 +415,9 @@
bool mysqld_show_create_db(THD *thd, char *dbname,
HA_CREATE_INFO *create_info)
{
+ Security_context *sctx= thd->security_ctx;
int length;
- char path[FN_REFLEN];
+ char path[FN_REFLEN];
char buff[2048];
String buffer(buff, sizeof(buff), system_charset_info);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -435,17 +436,17 @@
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (test_all_bits(thd->master_access,DB_ACLS))
+ if (test_all_bits(sctx->master_access, DB_ACLS))
db_access=DB_ACLS;
else
- db_access= (acl_get(thd->host,thd->ip, thd->priv_user,dbname,0) |
- thd->master_access);
+ db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname, 0) |
+ sctx->master_access);
if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname)))
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
- thd->priv_user, thd->host_or_ip, dbname);
+ sctx->priv_user, sctx->host_or_ip, dbname);
mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
- thd->priv_user, thd->host_or_ip, dbname);
+ sctx->priv_user, sctx->host_or_ip, dbname);
DBUG_RETURN(TRUE);
}
#endif
@@ -1185,24 +1186,26 @@
THD *tmp;
while ((tmp=it++))
{
+ Security_context *tmp_sctx= tmp->security_ctx;
struct st_my_thread_var *mysys_var;
if ((tmp->vio_ok() || tmp->system_thread) &&
- (!user || (tmp->user && !strcmp(tmp->user,user))))
+ (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
{
- thread_info *thd_info=new thread_info;
+ thread_info *thd_info= new thread_info;
thd_info->thread_id=tmp->thread_id;
- thd_info->user=thd->strdup(tmp->user ? tmp->user :
- (tmp->system_thread ?
- "system user" : "unauthenticated user"));
- if (tmp->peer_port && (tmp->host || tmp->ip) && thd->host_or_ip[0])
+ thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
+ (tmp->system_thread ?
+ "system user" : "unauthenticated user"));
+ if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
+ thd->security_ctx->host_or_ip[0])
{
if ((thd_info->host= thd->alloc(LIST_PROCESS_HOST_LEN+1)))
my_snprintf((char *) thd_info->host, LIST_PROCESS_HOST_LEN,
- "%s:%u", tmp->host_or_ip, tmp->peer_port);
+ "%s:%u", tmp_sctx->host_or_ip, tmp->peer_port);
}
else
- thd_info->host= thd->strdup(tmp->host_or_ip);
+ thd_info->host= thd->strdup(tmp_sctx->host);
if ((thd_info->db=tmp->db)) // Safe test
thd_info->db=thd->strdup(thd_info->db);
thd_info->command=(int) tmp->command;
@@ -1253,6 +1256,9 @@
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thread_info *thd_info;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ Security_context *sctx;
+#endif
time_t now= time(0);
while ((thd_info=thread_infos.get()))
{
@@ -1989,7 +1995,8 @@
enum enum_schema_tables schema_table_idx;
List<char> bases;
List_iterator_fast<char> it(bases);
- COND *partial_cond;
+ COND *partial_cond;
+ Security_context *sctx= thd->security_ctx;
uint derived_tables= lex->derived_tables;
int error= 1;
Open_tables_state open_tables_state_backup;
@@ -2061,8 +2068,8 @@
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!check_access(thd,SELECT_ACL, base_name,
&thd->col_access, 0, 1, with_i_schema) ||
- thd->master_access & (DB_ACLS | SHOW_DB_ACL) ||
- acl_get(thd->host, thd->ip, thd->priv_user, base_name,0) ||
+ sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
+ acl_get(sctx->host, sctx->ip, sctx->priv_user, base_name,0) ||
(grant_option && !check_grant_db(thd, base_name)))
#endif
{
@@ -2194,6 +2201,7 @@
bool with_i_schema;
HA_CREATE_INFO create;
TABLE *table= tables->table;
+ Security_context *sctx= thd->security_ctx;
DBUG_ENTER("fill_schema_shemata");
if (make_db_list(thd, &files, &idx_field_vals,
@@ -2212,8 +2220,8 @@
continue;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) ||
- acl_get(thd->host, thd->ip, thd->priv_user, file_name,0) ||
+ if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
+ acl_get(sctx->host, sctx->ip, sctx->priv_user, file_name,0) ||
(grant_option && !check_grant_db(thd, file_name)))
#endif
{
@@ -2814,7 +2822,8 @@
Open_tables_state open_tables_state_backup;
DBUG_ENTER("fill_schema_proc");
- strxmov(definer, thd->priv_user, "@", thd->priv_host, NullS);
+ strxmov(definer, thd->security_ctx->priv_user, "@",
+ thd->security_ctx->priv_host, NullS);
/* We use this TABLE_LIST instance only for checking of privileges. */
bzero((char*) &proc_tables,sizeof(proc_tables));
proc_tables.db= (char*) "mysql";
--- 1.65/sql/sql_view.cc 2005-09-19 06:32:35 +03:00
+++ 1.66/sql/sql_view.cc 2005-09-20 21:24:21 +03:00
@@ -214,12 +214,13 @@
- same as current user
- current user has SUPER_ACL
*/
- if (strcmp(lex->create_view_definer->user.str, thd->priv_user) != 0 ||
+ if (strcmp(lex->create_view_definer->user.str,
+ thd->security_ctx->priv_user) != 0 ||
my_strcasecmp(system_charset_info,
lex->create_view_definer->host.str,
- thd->priv_host) != 0)
+ thd->security_ctx->priv_host) != 0)
{
- if (!(thd->master_access & SUPER_ACL))
+ if (!(thd->security_ctx->master_access & SUPER_ACL))
{
my_error(ER_VIEW_OTHER_USER, MYF(0), lex->create_view_definer->user.str,
lex->create_view_definer->host.str);
@@ -275,7 +276,8 @@
if (check_some_access(thd, VIEW_ANY_ACL, tbl))
{
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
- "ANY", thd->priv_user, thd->host_or_ip, tbl->table_name);
+ "ANY", thd->security_ctx->priv_user,
+ thd->security_ctx->priv_host, tbl->table_name);
res= TRUE;
goto err;
}
@@ -441,7 +443,8 @@
{
/* VIEW column has more privileges */
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
- "create view", thd->priv_user, thd->host_or_ip, item->name,
+ "create view", thd->security_ctx->priv_user,
+ thd->security_ctx->priv_host, item->name,
view->table_name);
res= TRUE;
goto err;
@@ -790,7 +793,7 @@
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_VIEW_FRM_NO_USER, ER(ER_VIEW_FRM_NO_USER),
table->db, table->table_name);
- if (default_view_definer(thd, &table->definer))
+ if (default_view_definer(thd->security_ctx, &table->definer))
goto err;
}
--- 1.257/sql/ha_innodb.cc 2005-09-20 21:20:32 +03:00
+++ 1.258/sql/ha_innodb.cc 2005-09-20 21:24:21 +03:00
@@ -206,7 +206,7 @@
static int innobase_savepoint(THD* thd, void *savepoint);
static int innobase_release_savepoint(THD* thd, void *savepoint);
-static handlerton innobase_hton = {
+handlerton innobase_hton = {
"InnoDB",
0, /* slot */
sizeof(trx_named_savept_t), /* savepoint size. TODO: use it */
| Thread |
|---|
| • bk commit into 5.0 tree (bell:1.1992) | sanja | 20 Sep |