summaryrefslogtreecommitdiff
path: root/sql/sql_parse.cc
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2004-02-03 19:17:23 +0100
committerunknown <monty@mysql.com>2004-02-03 19:17:23 +0100
commit2cf47972fd31819720ee3b96f2ef1d47ca150409 (patch)
treed2e781dd8a39aa918c25b6ba10a1b6cabec62518 /sql/sql_parse.cc
parentdccf911f3786cbc43492d364168661a4c95ffe84 (diff)
downloadmariadb-git-2cf47972fd31819720ee3b96f2ef1d47ca150409.tar.gz
Ensure that privileges are tested properly for multi-table-updates.
Now one need only SELECT privilege for tables that are only read in UPDATE statements with many tables. (Bug #2377). sql/sql_acl.cc: Comment cleanup sql/sql_parse.cc: Merged duplicate code. Removed some outdated 'tables->db' tests. Check privileges for multi-updates properly (Bug #2377) sql/sql_show.cc: Remove disabled code sql/sql_update.cc: Ensure that privileges are tested properly for multi-table-updates tests/grant.pl: Added more tests tests/grant.res: updated results
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r--sql/sql_parse.cc116
1 files changed, 49 insertions, 67 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 0d22704ef3c..f97b1b8f8be 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -63,6 +63,8 @@ static bool append_file_to_dir(THD *thd, const char **filename_ptr,
const char *table_name);
static bool create_total_list(THD *thd, LEX *lex,
TABLE_LIST **result, bool skip_first);
+static bool check_one_table_access(THD *thd, ulong want_access,
+ TABLE_LIST *table, bool no_errors);
const char *any_db="*any*"; // Special symbol for check_access
@@ -870,11 +872,8 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT)))
DBUG_RETURN(1);
- if (check_access(thd, SELECT_ACL, db, &table_list->grant.privilege))
+ if (check_one_table_access(thd, SELECT_ACL, table_list, 0))
goto err;
- if (grant_option && check_grant(thd, SELECT_ACL, table_list))
- goto err;
-
thd->free_list = 0;
thd->query_length=(uint) strlen(tbl_name);
thd->query = tbl_name;
@@ -1102,9 +1101,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
casedn_str(table_list.real_name);
remove_escape(table_list.real_name); // This can't have wildcards
- if (check_access(thd,SELECT_ACL,table_list.db,&thd->col_access))
+ if (check_access(thd,SELECT_ACL,table_list.db,&table_list.grant.privilege))
break;
- table_list.grant.privilege=thd->col_access;
if (grant_option && check_grant(thd,SELECT_ACL,&table_list,2))
break;
mysqld_list_fields(thd,&table_list,fields);
@@ -1693,12 +1691,8 @@ mysql_execute_command(void)
break;
}
case SQLCOM_CREATE_INDEX:
- if (!tables->db)
- tables->db=thd->db;
- if (check_access(thd,INDEX_ACL,tables->db,&tables->grant.privilege))
+ if (check_one_table_access(thd, INDEX_ACL, tables, 0))
goto error; /* purecov: inspected */
- if (grant_option && check_grant(thd,INDEX_ACL,tables))
- goto error;
if (end_active_trans(thd))
res= -1;
else
@@ -1753,8 +1747,6 @@ mysql_execute_command(void)
res=0;
break;
}
- if (!tables->db)
- tables->db=thd->db;
if (!select_lex->db)
select_lex->db=tables->db;
if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege) ||
@@ -1763,8 +1755,6 @@ mysql_execute_command(void)
(TABLE_LIST *)
lex->create_info.merge_list.first))
goto error; /* purecov: inspected */
- if (!tables->db)
- tables->db=thd->db;
if (grant_option)
{
if (check_grant(thd,ALTER_ACL,tables))
@@ -1909,16 +1899,8 @@ mysql_execute_command(void)
break;
}
case SQLCOM_UPDATE:
- TABLE_LIST *table;
if (check_db_used(thd,tables))
goto error;
- for (table=tables ; table ; table=table->next)
- {
- if (check_access(thd,UPDATE_ACL,table->db,&table->grant.privilege))
- goto error;
- }
- if (grant_option && check_grant(thd,UPDATE_ACL,tables))
- goto error;
if (select_lex->item_list.elements != lex->value_list.elements)
{
send_error(&thd->net,ER_WRONG_VALUE_COUNT);
@@ -1926,6 +1908,10 @@ mysql_execute_command(void)
}
if (select_lex->table_list.elements == 1)
{
+ if (check_one_table_access(thd, UPDATE_ACL, tables, 0))
+ goto error; /* purecov: inspected */
+
+
res= mysql_update(thd,tables,
select_lex->item_list,
lex->value_list,
@@ -1937,7 +1923,22 @@ mysql_execute_command(void)
else
{
const char *msg= 0;
+ TABLE_LIST *table;
lex->sql_command= SQLCOM_MULTI_UPDATE;
+
+ /*
+ Ensure that we have UPDATE or SELECT privilege for each table
+ The exact privilege is checked in mysql_multi_update()
+ */
+ for (table= tables ; table ; table= table->next)
+ {
+ TABLE_LIST *save= table->next;
+ table->next= 0;
+ if (check_one_table_access(thd, UPDATE_ACL, table, 1) &&
+ check_one_table_access(thd, SELECT_ACL, table, 0))
+ goto error;
+ table->next= save;
+ }
if (select_lex->order_list.elements)
msg="ORDER BY";
else if (select_lex->select_limit && select_lex->select_limit !=
@@ -1958,21 +1959,14 @@ mysql_execute_command(void)
}
break;
case SQLCOM_INSERT:
- if (check_access(thd,INSERT_ACL,tables->db,&tables->grant.privilege))
+ if (check_one_table_access(thd, INSERT_ACL, tables, 0))
goto error; /* purecov: inspected */
- if (grant_option && check_grant(thd,INSERT_ACL,tables))
- goto error;
res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
lex->duplicates);
break;
case SQLCOM_REPLACE:
- if (check_access(thd,INSERT_ACL | DELETE_ACL,
- tables->db,&tables->grant.privilege))
+ if (check_one_table_access(thd, INSERT_ACL | DELETE_ACL, tables, 0))
goto error; /* purecov: inspected */
- if (grant_option && check_grant(thd,INSERT_ACL | DELETE_ACL,
- tables))
-
- goto error;
res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
DUP_REPLACE);
break;
@@ -1988,9 +1982,7 @@ mysql_execute_command(void)
INSERT_ACL : INSERT_ACL | DELETE_ACL);
TABLE_LIST *save_next=tables->next;
tables->next=0;
- if (check_access(thd, privilege,
- tables->db,&tables->grant.privilege) ||
- (grant_option && check_grant(thd, privilege, tables)))
+ if (check_one_table_access(thd, privilege, tables, 0))
goto error;
tables->next=save_next;
if ((res=check_table_access(thd, SELECT_ACL, save_next)))
@@ -2035,10 +2027,8 @@ mysql_execute_command(void)
break;
}
case SQLCOM_TRUNCATE:
- if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege))
+ if (check_one_table_access(thd, DELETE_ACL, tables, 0))
goto error; /* purecov: inspected */
- if (grant_option && check_grant(thd,DELETE_ACL,tables))
- goto error;
/*
Don't allow this within a transaction because we want to use
re-generate table
@@ -2052,9 +2042,7 @@ mysql_execute_command(void)
break;
case SQLCOM_DELETE:
{
- if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege))
- goto error; /* purecov: inspected */
- if (grant_option && check_grant(thd,DELETE_ACL,tables))
+ if (check_one_table_access(thd, DELETE_ACL, tables, 0))
goto error;
// Set privilege for the WHERE clause
tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
@@ -2139,8 +2127,8 @@ mysql_execute_command(void)
DROP / * 40005 TEMPORARY * / TABLE
that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE
MASTER TO), while the temporary table has already been dropped.
- To not generate such irrelevant "table does not exist errors", we silently
- add IF EXISTS if TEMPORARY was used.
+ To not generate such irrelevant "table does not exist errors",
+ we silently add IF EXISTS if TEMPORARY was used.
*/
if (thd->slave_thread && lex->drop_temporary)
lex->drop_if_exists= 1;
@@ -2151,12 +2139,8 @@ mysql_execute_command(void)
}
break;
case SQLCOM_DROP_INDEX:
- if (!tables->db)
- tables->db=thd->db;
- if (check_access(thd,INDEX_ACL,tables->db,&tables->grant.privilege))
- goto error; /* purecov: inspected */
- if (grant_option && check_grant(thd,INDEX_ACL,tables))
- goto error;
+ if (check_one_table_access(thd, INDEX_ACL, tables, 0))
+ goto error; /* purecov: inspected */
if (end_active_trans(thd))
res= -1;
else
@@ -2242,16 +2226,11 @@ mysql_execute_command(void)
#else
{
char *db=tables->db;
- if (!*db)
- {
- send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
- goto error; /* purecov: inspected */
- }
remove_escape(db); // Fix escaped '_'
remove_escape(tables->real_name);
- if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,&thd->col_access))
+ if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,
+ &tables->grant.privilege))
goto error; /* purecov: inspected */
- tables->grant.privilege=thd->col_access;
if (grant_option && check_grant(thd,SELECT_ACL,tables,2))
goto error;
res= mysqld_show_fields(thd,tables,
@@ -2267,18 +2246,10 @@ mysql_execute_command(void)
#else
{
char *db=tables->db;
- if (!db)
- {
- send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
- goto error; /* purecov: inspected */
- }
remove_escape(db); // Fix escaped '_'
remove_escape(tables->real_name);
- if (!tables->db)
- tables->db=thd->db;
- if (check_access(thd,SELECT_ACL,db,&thd->col_access))
+ if (check_access(thd,SELECT_ACL,db,&tables->grant.privilege))
goto error; /* purecov: inspected */
- tables->grant.privilege=thd->col_access;
if (grant_option && check_grant(thd,SELECT_ACL,tables,2))
goto error;
res= mysqld_show_keys(thd,tables);
@@ -2306,8 +2277,7 @@ mysql_execute_command(void)
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND);
goto error;
}
- if (check_access(thd,privilege,tables->db,&tables->grant.privilege) ||
- grant_option && check_grant(thd,privilege,tables))
+ if (check_one_table_access(thd, privilege, tables, 0))
goto error;
}
res=mysql_load(thd, lex->exchange, tables, lex->field_list,
@@ -2805,6 +2775,18 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
}
+static bool
+check_one_table_access(THD *thd, ulong want_access, TABLE_LIST *table,
+ bool no_errors)
+{
+ if (check_access(thd, want_access, table->db, &table->grant.privilege, 0,
+ no_errors))
+ return 1;
+ return (grant_option && check_grant(thd, want_access, table, 0,
+ no_errors));
+}
+
+
static bool check_db_used(THD *thd,TABLE_LIST *tables)
{
for (; tables ; tables=tables->next)