diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_acl.cc | 10 | ||||
-rw-r--r-- | sql/sql_acl.h | 16 | ||||
-rw-r--r-- | sql/sql_show.cc | 1 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 48 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 1 |
5 files changed, 45 insertions, 31 deletions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 8877d607e92..dc56880a1a0 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -361,6 +361,12 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) if (table->s->fields <= 37 && (user.access & CREATE_ACL)) user.access|= EVENT_ACL; + /* + if it is pre 5.1.6 privilege then map TRIGGER privilege on CREATE. + */ + if (table->s->fields <= 38 && (user.access & SUPER_ACL)) + user.access|= TRIGGER_ACL; + user.sort= get_sort(2,user.host.hostname,user.user); user.hostname_length= (user.host.hostname ? (uint) strlen(user.host.hostname) : 0); @@ -4070,13 +4076,13 @@ static const char *command_array[]= "ALTER", "SHOW DATABASES", "SUPER", "CREATE TEMPORARY TABLES", "LOCK TABLES", "EXECUTE", "REPLICATION SLAVE", "REPLICATION CLIENT", "CREATE VIEW", "SHOW VIEW", "CREATE ROUTINE", "ALTER ROUTINE", - "CREATE USER", "EVENT" + "CREATE USER", "EVENT", "TRIGGER" }; static uint command_lengths[]= { 6, 6, 6, 6, 6, 4, 6, 8, 7, 4, 5, 10, 5, 5, 14, 5, 23, 11, 7, 17, 18, 11, 9, - 14, 13, 11, 5 + 14, 13, 11, 5, 7 }; diff --git a/sql/sql_acl.h b/sql/sql_acl.h index f42406ca1d2..66799986413 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -43,6 +43,7 @@ #define ALTER_PROC_ACL (1L << 24) #define CREATE_USER_ACL (1L << 25) #define EVENT_ACL (1L << 26) +#define TRIGGER_ACL (1L << 27) /* don't forget to update 1. static struct show_privileges_st sys_privileges[] @@ -57,12 +58,12 @@ (UPDATE_ACL | SELECT_ACL | INSERT_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | \ LOCK_TABLES_ACL | EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | \ - CREATE_PROC_ACL | ALTER_PROC_ACL | EVENT_ACL) + CREATE_PROC_ACL | ALTER_PROC_ACL | EVENT_ACL | TRIGGER_ACL) #define TABLE_ACLS \ (SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | \ - SHOW_VIEW_ACL) + SHOW_VIEW_ACL | TRIGGER_ACL) #define COL_ACLS \ (SELECT_ACL | INSERT_ACL | UPDATE_ACL | REFERENCES_ACL) @@ -79,7 +80,7 @@ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | SHOW_DB_ACL | SUPER_ACL | \ CREATE_TMP_ACL | LOCK_TABLES_ACL | REPL_SLAVE_ACL | REPL_CLIENT_ACL | \ EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | \ - ALTER_PROC_ACL | CREATE_USER_ACL | EVENT_ACL) + ALTER_PROC_ACL | CREATE_USER_ACL | EVENT_ACL | TRIGGER_ACL) #define DEFAULT_CREATE_PROC_ACLS \ (ALTER_PROC_ACL | EXECUTE_ACL) @@ -97,7 +98,7 @@ #define DB_CHUNK3 (CREATE_VIEW_ACL | SHOW_VIEW_ACL | \ CREATE_PROC_ACL | ALTER_PROC_ACL ) #define DB_CHUNK4 (EXECUTE_ACL) -#define DB_CHUNK5 (EVENT_ACL) +#define DB_CHUNK5 (EVENT_ACL | TRIGGER_ACL) #define fix_rights_for_db(A) (((A) & DB_CHUNK0) | \ (((A) << 4) & DB_CHUNK1) | \ @@ -114,12 +115,15 @@ #define TBL_CHUNK0 DB_CHUNK0 #define TBL_CHUNK1 DB_CHUNK1 #define TBL_CHUNK2 (CREATE_VIEW_ACL | SHOW_VIEW_ACL) +#define TBL_CHUNK3 TRIGGER_ACL #define fix_rights_for_table(A) (((A) & TBL_CHUNK0) | \ (((A) << 4) & TBL_CHUNK1) | \ - (((A) << 11) & TBL_CHUNK2)) + (((A) << 11) & TBL_CHUNK2) | \ + (((A) << 15) & TBL_CHUNK3)) #define get_rights_for_table(A) (((A) & TBL_CHUNK0) | \ (((A) & TBL_CHUNK1) >> 4) | \ - (((A) & TBL_CHUNK2) >> 11)) + (((A) & TBL_CHUNK2) >> 11) | \ + (((A) & TBL_CHUNK3) >> 15)) #define fix_rights_for_column(A) (((A) & 7) | (((A) & ~7) << 8)) #define get_rights_for_column(A) (((A) & 7) | ((A) >> 8)) #define fix_rights_for_procedure(A) ((((A) << 18) & EXECUTE_ACL) | \ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 6f8072f1b9f..55c402638d8 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -267,6 +267,7 @@ static struct show_privileges_st sys_privileges[]= {"Show view","Tables","To see views with SHOW CREATE VIEW"}, {"Shutdown","Server Admin", "To shut down the server"}, {"Super","Server Admin","To use KILL thread, SET GLOBAL, CHANGE MASTER, etc."}, + {"Trigger","Tables", "To use triggers"}, {"Update", "Tables", "To update existing rows"}, {"Usage","Server Admin","No privileges - allow connect only"}, {NullS, NullS, NullS} diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index b9da49632d2..ec41e02f439 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -177,12 +177,20 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) DBUG_ASSERT(tables->next_global == 0); /* - TODO: We should check if user has TRIGGER privilege for table here. - Now we just require SUPER privilege for creating/dropping because - we don't have proper privilege checking for triggers in place yet. + Check that the user has TRIGGER privilege on the subject table. */ - if (check_global_access(thd, SUPER_ACL)) - DBUG_RETURN(TRUE); + { + bool err_status; + TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last; + thd->lex->query_tables_own_last= 0; + + err_status= check_table_access(thd, TRIGGER_ACL, tables, 0); + + thd->lex->query_tables_own_last= save_query_tables_own_last; + + if (err_status) + DBUG_RETURN(TRUE); + } /* There is no DETERMINISTIC clause for triggers, so can't check it. @@ -1151,24 +1159,10 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, if (sp_change_security_context(thd, sp_trigger, &save_ctx)) return TRUE; - /* - NOTE: TRIGGER_ACL should be used below. - */ - - if (check_global_access(thd, SUPER_ACL)) - { - sp_restore_security_context(thd, save_ctx); - return TRUE; - } - - /* - If the trigger uses special variables (NEW/OLD), check that we have - SELECT and UPDATE privileges on the subject table. - */ - - if (is_special_var_used(event, time_type)) { TABLE_LIST table_list, **save_query_tables_own_last; + ulong wanted_access = TRIGGER_ACL; + bzero((char *) &table_list, sizeof (table_list)); table_list.db= (char *) table->s->db.str; table_list.db_length= table->s->db.length; @@ -1178,9 +1172,17 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, table_list.table= table; save_query_tables_own_last= thd->lex->query_tables_own_last; thd->lex->query_tables_own_last= 0; + + /* + If the trigger uses special variables (NEW/OLD), check that we have + SELECT and UPDATE privileges on the subject table. + */ + + if (is_special_var_used(event, time_type)) + wanted_access|= SELECT_ACL | UPDATE_ACL; + + err_status= check_table_access(thd, wanted_access, &table_list, 0); - err_status= check_table_access(thd, SELECT_ACL | UPDATE_ACL, - &table_list, 0); thd->lex->query_tables_own_last= save_query_tables_own_last; if (err_status) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a86eccb493f..513dc0b7416 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -10237,6 +10237,7 @@ object_privilege: | ALTER ROUTINE_SYM { Lex->grant |= ALTER_PROC_ACL; } | CREATE USER { Lex->grant |= CREATE_USER_ACL; } | EVENT_SYM { Lex->grant |= EVENT_ACL;} + | TRIGGER_SYM { Lex->grant |= TRIGGER_ACL; } ; |