From 018a9b70580dcb3ba2080c3b20c438f000ecc178 Mon Sep 17 00:00:00 2001 From: "serg@serg.mysql.com" <> Date: Mon, 17 Mar 2003 19:39:01 +0100 Subject: [PATCH 1/5] crash fix --- client/mysqldump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index d7d54a13c57..02e6186dbe8 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1500,7 +1500,7 @@ int main(int argc, char **argv) else { row = mysql_fetch_row(master); - if(row[0] && row[1]) { + if(row && row[0] && row[1]) { fprintf(md_result_file, "\n--\n-- Position to start replication from\n--\n\n"); fprintf(md_result_file, From cf2ebdba328452268c397849060f64bbb33807ff Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Mon, 14 Apr 2003 20:58:41 +0300 Subject: [PATCH 2/5] Back porting a fix from 4.0 at customer's request --- sql/sql_parse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 62c2f18c882..152d9c585ca 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2155,7 +2155,7 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv, if ((thd->master_access & want_access) == want_access) { - *save_priv=thd->master_access; + *save_priv=thd->master_access | thd->db_access; return FALSE; } if ((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL) || From 54100938c411f300030cce6e46f2ce512cd28cd2 Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Thu, 24 Apr 2003 00:09:19 +0300 Subject: [PATCH 3/5] Put changeset number in emails --- BitKeeper/triggers/post-commit | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/BitKeeper/triggers/post-commit b/BitKeeper/triggers/post-commit index 8780811a2da..d060c59ab39 100755 --- a/BitKeeper/triggers/post-commit +++ b/BitKeeper/triggers/post-commit @@ -18,13 +18,15 @@ BK_STATUS=$BK_STATUS$BK_COMMIT if [ "$BK_STATUS" = OK ] then + CHANGESET=`bk -R prs -r+ -h -d':I:' ChangeSet` + echo "Commit successful, notifying developers at $TO" ( cat < From: $FROM To: $TO -Subject: bk commit into 3.23 tree +Subject: bk commit into 3.23 tree ($CHANGESET) EOF bk changes -v -r+ @@ -36,7 +38,7 @@ EOF List-ID: From: $FROM To: $INTERNALS -Subject: bk commit into 3.23 tree +Subject: bk commit into 3.23 tree ($CHANGESET) Below is the list of changes that have just been committed into a local 3.23 repository of $USER. When $USER does a push these changes will @@ -63,7 +65,7 @@ EOF List-ID: From: $FROM To: $DOCS -Subject: bk commit - 3.23 tree (Manual) +Subject: bk commit - 3.23 tree (Manual) ($CHANGESET) EOF bk changes -v -r+ From 0ed1cbbd48944fb844adcf8482e39781606eecd1 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Tue, 29 Apr 2003 18:24:33 +0300 Subject: [PATCH 4/5] Porting back security fix from 4.0. All tests plus grant.pl test passed. --- sql/sql_base.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index f0b370c23d7..46370949650 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1878,8 +1878,9 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, for (; tables ; tables=tables->next) { TABLE *table=tables->table; - if (grant_option && !thd->master_access && - check_grant_all_columns(thd,SELECT_ACL,table) ) + if (grant_option && !(table->grant.privilege & + table->grant.want_privilege) && + check_grant_all_columns(thd,SELECT_ACL,table)) DBUG_RETURN(-1); if (!table_name || (!strcmp(table_name,tables->alias) && (!db_name || !tables->db || From 71ce598fa21e2e8ee3abf156af2cd95821f3d282 Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Wed, 7 May 2003 23:59:24 +0300 Subject: [PATCH 5/5] Security patch to remove wrong error when one had a global update/delete privilige and a database specific SELECT privilege. --- sql/sql_acl.cc | 9 ++++++--- sql/sql_base.cc | 9 ++++----- sql/sql_parse.cc | 12 +++++++++++- tests/grant.pl | 13 +++++++++++++ tests/grant.res | 15 +++++++++++++++ 5 files changed, 49 insertions(+), 9 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 05ec57b134a..f36e39b0645 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2118,8 +2118,8 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables, } -bool check_grant_column (THD *thd,TABLE *table, const char *name, - uint length, uint show_tables) +bool check_grant_column(THD *thd,TABLE *table, const char *name, + uint length, uint show_tables) { GRANT_TABLE *grant_table; GRANT_COLUMN *grant_column; @@ -2127,6 +2127,8 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name, uint want_access=table->grant.want_privilege; if (!want_access) return 0; // Already checked + if (!grant_option) + goto err2; pthread_mutex_lock(&LOCK_grant); @@ -2158,8 +2160,9 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name, #endif /* We must use my_printf_error() here! */ - err: +err: pthread_mutex_unlock(&LOCK_grant); +err2: if (!show_tables) { const char *command=""; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 46370949650..d28fedba25b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1616,7 +1616,7 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, else thd->dupp_field=field; } - if (check_grants && check_grant_column(thd,table,name,length)) + if (check_grants && check_grant_column(thd,table,name,length)) return WRONG_GRANT; return field; } @@ -1643,8 +1643,8 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) { found_table=1; Field *find=find_field_in_table(thd,tables->table,name,length, - grant_option && - tables->table->grant.want_privilege, + test(tables->table->grant. + want_privilege), 1); if (find) { @@ -1684,8 +1684,7 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) for (; tables ; tables=tables->next) { Field *field=find_field_in_table(thd,tables->table,name,length, - grant_option && - tables->table->grant.want_privilege, + test(tables->table->grant.want_privilege), allow_rowid); if (field) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 152d9c585ca..805063cb6dc 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2155,7 +2155,17 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv, if ((thd->master_access & want_access) == want_access) { - *save_priv=thd->master_access | thd->db_access; + /* + If we don't have a global SELECT privilege, we have to get the database + specific access rights to be able to handle queries of type + UPDATE t1 SET a=1 WHERE b > 0 + */ + db_access= thd->db_access; + if (!(thd->master_access & SELECT_ACL) && + (db && (!thd->db || strcmp(db,thd->db)))) + db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr, + thd->priv_user, db); /* purecov: inspected */ + *save_priv=thd->master_access | db_access; return FALSE; } if ((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL) || diff --git a/tests/grant.pl b/tests/grant.pl index bf67ce5e790..8ec83c85349 100644 --- a/tests/grant.pl +++ b/tests/grant.pl @@ -214,8 +214,21 @@ user_query("update $opt_database.test set b=b+1",1); safe_query("grant SELECT on *.* to $user"); user_connect(0); user_query("update $opt_database.test set b=b+1"); +user_query("update $opt_database.test set b=b+1 where a > 0"); safe_query("revoke SELECT on *.* from $user"); +safe_query("grant SELECT on $opt_database.* to $user"); user_connect(0); +user_query("update $opt_database.test set b=b+1"); +user_query("update $opt_database.test set b=b+1 where a > 0"); +safe_query("grant UPDATE on *.* to $user"); +user_connect(0); +user_query("update $opt_database.test set b=b+1"); +user_query("update $opt_database.test set b=b+1 where a > 0"); +safe_query("revoke UPDATE on *.* from $user"); +safe_query("revoke SELECT on $opt_database.* from $user"); +user_connect(0); +user_query("update $opt_database.test set b=b+1 where a > 0",1); +user_query("update $opt_database.test set b=b+1",1); # Add one privilege at a time until the user has all privileges user_query("select * from test",1); diff --git a/tests/grant.res b/tests/grant.res index 44e20db555f..086111ce567 100644 --- a/tests/grant.res +++ b/tests/grant.res @@ -195,8 +195,23 @@ Error in execute: select command denied to user: 'grant_user@localhost' for colu grant SELECT on *.* to grant_user@localhost Connecting grant_user update grant_test.test set b=b+1 +update grant_test.test set b=b+1 where a > 0 revoke SELECT on *.* from grant_user@localhost +grant SELECT on grant_test.* to grant_user@localhost Connecting grant_user +update grant_test.test set b=b+1 +update grant_test.test set b=b+1 where a > 0 +grant UPDATE on *.* to grant_user@localhost +Connecting grant_user +update grant_test.test set b=b+1 +update grant_test.test set b=b+1 where a > 0 +revoke UPDATE on *.* from grant_user@localhost +revoke SELECT on grant_test.* from grant_user@localhost +Connecting grant_user +update grant_test.test set b=b+1 where a > 0 +Error in execute: select command denied to user: 'grant_user@localhost' for column 'a' in table 'test' +update grant_test.test set b=b+1 +Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test' select * from test Error in execute: select command denied to user: 'grant_user@localhost' for table 'test' grant select on grant_test.test to grant_user@localhost