Commit cdba1d56 authored by unknown's avatar unknown

Merge bk-internal.mysql.com:/home/bk/mysql-5.0

into neptunus.(none):/home/msvensson/mysql/mysql-5.0

parents 7d740ed6 92834915
...@@ -23,10 +23,10 @@ root@localhost 1 ...@@ -23,10 +23,10 @@ root@localhost 1
select db(); select db();
db() db()
db1_secret db1_secret
grant execute on db1_secret.stamp to user1@'%'; grant execute on procedure db1_secret.stamp to user1@'%';
grant execute on db1_secret.db to user1@'%'; grant execute on function db1_secret.db to user1@'%';
grant execute on db1_secret.stamp to ''@'%'; grant execute on procedure db1_secret.stamp to ''@'%';
grant execute on db1_secret.db to ''@'%'; grant execute on function db1_secret.db to ''@'%';
call db1_secret.stamp(2); call db1_secret.stamp(2);
select db1_secret.db(); select db1_secret.db();
db1_secret.db() db1_secret.db()
...@@ -105,8 +105,8 @@ select * from t2; ...@@ -105,8 +105,8 @@ select * from t2;
s1 s1
0 0
2 2
grant usage on db2.q to user2@localhost with grant option; grant usage on procedure db2.q to user2@localhost with grant option;
grant execute on db2.q to user1@localhost; grant execute on procedure db2.q to user1@localhost;
use db2; use db2;
call q(); call q();
select * from t2; select * from t2;
...@@ -117,9 +117,9 @@ s1 ...@@ -117,9 +117,9 @@ s1
alter procedure p modifies sql data; alter procedure p modifies sql data;
drop procedure p; drop procedure p;
alter procedure q modifies sql data; alter procedure q modifies sql data;
ERROR 42000: alter procedure command denied to user 'user1'@'localhost' for routine 'db2.q' ERROR 42000: alter routine command denied to user 'user1'@'localhost' for routine 'db2.q'
drop procedure q; drop procedure q;
ERROR 42000: alter procedure command denied to user 'user1'@'localhost' for routine 'db2.q' ERROR 42000: alter routine command denied to user 'user1'@'localhost' for routine 'db2.q'
use db2; use db2;
alter procedure q modifies sql data; alter procedure q modifies sql data;
drop procedure q; drop procedure q;
...@@ -141,52 +141,52 @@ create database sptest; ...@@ -141,52 +141,52 @@ create database sptest;
create table t1 ( u varchar(64), i int ); create table t1 ( u varchar(64), i int );
create procedure sptest.p1(i int) insert into test.t1 values (user(), i); create procedure sptest.p1(i int) insert into test.t1 values (user(), i);
grant insert on t1 to usera@localhost; grant insert on t1 to usera@localhost;
grant execute on sptest.p1 to usera@localhost; grant execute on procedure sptest.p1 to usera@localhost;
show grants for usera@localhost; show grants for usera@localhost;
Grants for usera@localhost Grants for usera@localhost
GRANT USAGE ON *.* TO 'usera'@'localhost' GRANT USAGE ON *.* TO 'usera'@'localhost'
GRANT INSERT ON `test`.`t1` TO 'usera'@'localhost' GRANT INSERT ON `test`.`t1` TO 'usera'@'localhost'
GRANT EXECUTE ON `sptest`.`p1` TO 'usera'@'localhost' GRANT EXECUTE ON PROCEDURE `sptest`.`p1` TO 'usera'@'localhost'
grant execute on sptest.p1 to userc@localhost with grant option; grant execute on procedure sptest.p1 to userc@localhost with grant option;
show grants for userc@localhost; show grants for userc@localhost;
Grants for userc@localhost Grants for userc@localhost
GRANT USAGE ON *.* TO 'userc'@'localhost' GRANT USAGE ON *.* TO 'userc'@'localhost'
GRANT EXECUTE ON `sptest`.`p1` TO 'userc'@'localhost' WITH GRANT OPTION GRANT EXECUTE ON PROCEDURE `sptest`.`p1` TO 'userc'@'localhost' WITH GRANT OPTION
call sptest.p1(1); call sptest.p1(1);
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
ERROR 42000: grant command denied to user 'usera'@'localhost' for routine 'sptest.p1' ERROR 42000: grant command denied to user 'usera'@'localhost' for routine 'sptest.p1'
drop procedure sptest.p1; drop procedure sptest.p1;
ERROR 42000: alter procedure command denied to user 'usera'@'localhost' for routine 'sptest.p1' ERROR 42000: alter routine command denied to user 'usera'@'localhost' for routine 'sptest.p1'
call sptest.p1(2); call sptest.p1(2);
ERROR 42000: execute command denied to user 'userb'@'localhost' for routine 'sptest.p1' ERROR 42000: execute command denied to user 'userb'@'localhost' for routine 'sptest.p1'
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
ERROR 42000: execute command denied to user 'userb'@'localhost' for routine 'sptest.p1' ERROR 42000: execute command denied to user 'userb'@'localhost' for routine 'sptest.p1'
drop procedure sptest.p1; drop procedure sptest.p1;
ERROR 42000: alter procedure command denied to user 'userb'@'localhost' for routine 'sptest.p1' ERROR 42000: alter routine command denied to user 'userb'@'localhost' for routine 'sptest.p1'
call sptest.p1(3); call sptest.p1(3);
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
drop procedure sptest.p1; drop procedure sptest.p1;
ERROR 42000: alter procedure command denied to user 'userc'@'localhost' for routine 'sptest.p1' ERROR 42000: alter routine command denied to user 'userc'@'localhost' for routine 'sptest.p1'
call sptest.p1(4); call sptest.p1(4);
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
ERROR 42000: grant command denied to user 'userb'@'localhost' for routine 'sptest.p1' ERROR 42000: grant command denied to user 'userb'@'localhost' for routine 'sptest.p1'
drop procedure sptest.p1; drop procedure sptest.p1;
ERROR 42000: alter procedure command denied to user 'userb'@'localhost' for routine 'sptest.p1' ERROR 42000: alter routine command denied to user 'userb'@'localhost' for routine 'sptest.p1'
select * from t1; select * from t1;
u i u i
usera@localhost 1 usera@localhost 1
userc@localhost 3 userc@localhost 3
userb@localhost 4 userb@localhost 4
grant all privileges on sptest.p1 to userc@localhost; grant all privileges on procedure sptest.p1 to userc@localhost;
show grants for userc@localhost; show grants for userc@localhost;
Grants for userc@localhost Grants for userc@localhost
GRANT USAGE ON *.* TO 'userc'@'localhost' GRANT USAGE ON *.* TO 'userc'@'localhost'
GRANT EXECUTE, ALTER ROUTINE ON `sptest`.`p1` TO 'userc'@'localhost' WITH GRANT OPTION GRANT EXECUTE, ALTER ROUTINE ON PROCEDURE `sptest`.`p1` TO 'userc'@'localhost' WITH GRANT OPTION
show grants for userb@localhost; show grants for userb@localhost;
Grants for userb@localhost Grants for userb@localhost
GRANT USAGE ON *.* TO 'userb'@'localhost' GRANT USAGE ON *.* TO 'userb'@'localhost'
GRANT EXECUTE ON `sptest`.`p1` TO 'userb'@'localhost' GRANT EXECUTE ON PROCEDURE `sptest`.`p1` TO 'userb'@'localhost'
revoke all privileges on sptest.p1 from userb@localhost; revoke all privileges on procedure sptest.p1 from userb@localhost;
show grants for userb@localhost; show grants for userb@localhost;
Grants for userb@localhost Grants for userb@localhost
GRANT USAGE ON *.* TO 'userb'@'localhost' GRANT USAGE ON *.* TO 'userb'@'localhost'
......
...@@ -152,10 +152,11 @@ procs_priv CREATE TABLE `procs_priv` ( ...@@ -152,10 +152,11 @@ procs_priv CREATE TABLE `procs_priv` (
`Db` char(64) collate utf8_bin NOT NULL default '', `Db` char(64) collate utf8_bin NOT NULL default '',
`User` char(16) collate utf8_bin NOT NULL default '', `User` char(16) collate utf8_bin NOT NULL default '',
`Routine_name` char(64) collate utf8_bin NOT NULL default '', `Routine_name` char(64) collate utf8_bin NOT NULL default '',
`Routine_type` enum('FUNCTION','PROCEDURE') collate utf8_bin NOT NULL default 'FUNCTION',
`Grantor` char(77) collate utf8_bin NOT NULL default '', `Grantor` char(77) collate utf8_bin NOT NULL default '',
`Timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`Proc_priv` set('Execute','Alter Routine','Grant') character set utf8 NOT NULL default '', `Proc_priv` set('Execute','Alter Routine','Grant') character set utf8 NOT NULL default '',
PRIMARY KEY (`Host`,`Db`,`User`,`Routine_name`), `Timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`Host`,`Db`,`User`,`Routine_name`,`Routine_type`),
KEY `Grantor` (`Grantor`) KEY `Grantor` (`Grantor`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Procedure privileges' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Procedure privileges'
show create table proc; show create table proc;
......
...@@ -43,10 +43,10 @@ call stamp(1); ...@@ -43,10 +43,10 @@ call stamp(1);
select * from t1; select * from t1;
select db(); select db();
grant execute on db1_secret.stamp to user1@'%'; grant execute on procedure db1_secret.stamp to user1@'%';
grant execute on db1_secret.db to user1@'%'; grant execute on function db1_secret.db to user1@'%';
grant execute on db1_secret.stamp to ''@'%'; grant execute on procedure db1_secret.stamp to ''@'%';
grant execute on db1_secret.db to ''@'%'; grant execute on function db1_secret.db to ''@'%';
connect (con2user1,localhost,user1,,); connect (con2user1,localhost,user1,,);
connect (con3anon,localhost,anon,,); connect (con3anon,localhost,anon,,);
...@@ -183,10 +183,10 @@ call q(); ...@@ -183,10 +183,10 @@ call q();
select * from t2; select * from t2;
connection con1root; connection con1root;
grant usage on db2.q to user2@localhost with grant option; grant usage on procedure db2.q to user2@localhost with grant option;
connection con4user2; connection con4user2;
grant execute on db2.q to user1@localhost; grant execute on procedure db2.q to user1@localhost;
connection con2user1; connection con2user1;
use db2; use db2;
...@@ -245,9 +245,9 @@ create database sptest; ...@@ -245,9 +245,9 @@ create database sptest;
create table t1 ( u varchar(64), i int ); create table t1 ( u varchar(64), i int );
create procedure sptest.p1(i int) insert into test.t1 values (user(), i); create procedure sptest.p1(i int) insert into test.t1 values (user(), i);
grant insert on t1 to usera@localhost; grant insert on t1 to usera@localhost;
grant execute on sptest.p1 to usera@localhost; grant execute on procedure sptest.p1 to usera@localhost;
show grants for usera@localhost; show grants for usera@localhost;
grant execute on sptest.p1 to userc@localhost with grant option; grant execute on procedure sptest.p1 to userc@localhost with grant option;
show grants for userc@localhost; show grants for userc@localhost;
connect (con2usera,localhost,usera,,); connect (con2usera,localhost,usera,,);
...@@ -257,7 +257,7 @@ connect (con4userc,localhost,userc,,); ...@@ -257,7 +257,7 @@ connect (con4userc,localhost,userc,,);
connection con2usera; connection con2usera;
call sptest.p1(1); call sptest.p1(1);
--error 1370 --error 1370
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
--error 1370 --error 1370
drop procedure sptest.p1; drop procedure sptest.p1;
...@@ -265,32 +265,32 @@ connection con3userb; ...@@ -265,32 +265,32 @@ connection con3userb;
--error 1370 --error 1370
call sptest.p1(2); call sptest.p1(2);
--error 1370 --error 1370
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
--error 1370 --error 1370
drop procedure sptest.p1; drop procedure sptest.p1;
connection con4userc; connection con4userc;
call sptest.p1(3); call sptest.p1(3);
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
--error 1370 --error 1370
drop procedure sptest.p1; drop procedure sptest.p1;
connection con3userb; connection con3userb;
call sptest.p1(4); call sptest.p1(4);
--error 1370 --error 1370
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
--error 1370 --error 1370
drop procedure sptest.p1; drop procedure sptest.p1;
connection con1root; connection con1root;
select * from t1; select * from t1;
grant all privileges on sptest.p1 to userc@localhost; grant all privileges on procedure sptest.p1 to userc@localhost;
show grants for userc@localhost; show grants for userc@localhost;
show grants for userb@localhost; show grants for userb@localhost;
connection con4userc; connection con4userc;
revoke all privileges on sptest.p1 from userb@localhost; revoke all privileges on procedure sptest.p1 from userb@localhost;
connection con1root; connection con1root;
show grants for userb@localhost; show grants for userb@localhost;
......
...@@ -255,10 +255,11 @@ then ...@@ -255,10 +255,11 @@ then
c_pp="$c_pp Db char(64) binary DEFAULT '' NOT NULL," c_pp="$c_pp Db char(64) binary DEFAULT '' NOT NULL,"
c_pp="$c_pp User char(16) binary DEFAULT '' NOT NULL," c_pp="$c_pp User char(16) binary DEFAULT '' NOT NULL,"
c_pp="$c_pp Routine_name char(64) binary DEFAULT '' NOT NULL," c_pp="$c_pp Routine_name char(64) binary DEFAULT '' NOT NULL,"
c_pp="$c_pp Routine_type enum('FUNCTION','PROCEDURE') NOT NULL,"
c_pp="$c_pp Grantor char(77) DEFAULT '' NOT NULL," c_pp="$c_pp Grantor char(77) DEFAULT '' NOT NULL,"
c_pp="$c_pp Timestamp timestamp(14),"
c_pp="$c_pp Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL," c_pp="$c_pp Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL,"
c_pp="$c_pp PRIMARY KEY (Host,Db,User,Routine_name)," c_pp="$c_pp Timestamp timestamp(14),"
c_pp="$c_pp PRIMARY KEY (Host,Db,User,Routine_name,Routine_type),"
c_pp="$c_pp KEY Grantor (Grantor)" c_pp="$c_pp KEY Grantor (Grantor)"
c_pp="$c_pp ) engine=MyISAM" c_pp="$c_pp ) engine=MyISAM"
c_pp="$c_pp CHARACTER SET utf8 COLLATE utf8_bin" c_pp="$c_pp CHARACTER SET utf8 COLLATE utf8_bin"
......
...@@ -67,6 +67,10 @@ ALTER TABLE tables_priv ...@@ -67,6 +67,10 @@ ALTER TABLE tables_priv
ALTER TABLE procs_priv ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; ALTER TABLE procs_priv ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;
ALTER TABLE procs_priv ALTER TABLE procs_priv
modify Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL; modify Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL;
ALTER TABLE procs_priv
add Routine_type enum('FUNCTION','PROCEDURE') COLLATE utf8_general_ci NOT NULL AFTER Routine_name;
ALTER TABLE procs_priv
modify Timestamp timestamp(14) AFTER Proc_priv;
CREATE TABLE IF NOT EXISTS columns_priv ( CREATE TABLE IF NOT EXISTS columns_priv (
Host char(60) DEFAULT '' NOT NULL, Host char(60) DEFAULT '' NOT NULL,
...@@ -316,10 +320,11 @@ Host char(60) binary DEFAULT '' NOT NULL, ...@@ -316,10 +320,11 @@ Host char(60) binary DEFAULT '' NOT NULL,
Db char(64) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL,
User char(16) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL,
Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL,
Routine_type enum('FUNCTION','PROCEDURE') NOT NULL,
Grantor char(77) DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL,
Timestamp timestamp(14),
Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL,
PRIMARY KEY (Host,Db,User,Routine_name), Timestamp timestamp(14),
PRIMARY KEY (Host,Db,User,Routine_name,Routine_type),
KEY Grantor (Grantor) KEY Grantor (Grantor)
) CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges'; ) CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
......
...@@ -3170,12 +3170,28 @@ ha_innobase::write_row( ...@@ -3170,12 +3170,28 @@ ha_innobase::write_row(
prebuilt->sql_stat_start = TRUE; prebuilt->sql_stat_start = TRUE;
} }
/* /* We have to use the transactional lock mechanism on the
We must use the handler code to update the auto-increment auto-inc counter of the table to ensure that replication and
value to be sure that increment it correctly. roll-forward of the binlog exactly imitates also the given
*/ auto-inc values. The lock is released at each SQL statement's
end. This lock also prevents a race where two threads would
call ::get_auto_increment() simultaneously. */
error = row_lock_table_autoinc_for_mysql(prebuilt);
if (error != DB_SUCCESS) {
/* Deadlock or lock wait timeout */
error = convert_error_code_to_mysql(error, user_thd);
goto func_exit;
}
/* We must use the handler code to update the auto-increment
value to be sure that we increment it correctly. */
update_auto_increment(); update_auto_increment();
auto_inc_used= 1; auto_inc_used = 1;
} }
...@@ -3198,24 +3214,9 @@ ha_innobase::write_row( ...@@ -3198,24 +3214,9 @@ ha_innobase::write_row(
auto_inc = table->next_number_field->val_int(); auto_inc = table->next_number_field->val_int();
if (auto_inc != 0) { if (auto_inc != 0) {
/* This call will calculate the max of the current /* This call will update the counter according to the
value and the value supplied by the user and value that was inserted in the table */
update the counter accordingly */
/* We have to use the transactional lock mechanism
on the auto-inc counter of the table to ensure
that replication and roll-forward of the binlog
exactly imitates also the given auto-inc values.
The lock is released at each SQL statement's
end. */
error = row_lock_table_autoinc_for_mysql(prebuilt);
if (error != DB_SUCCESS) {
error = convert_error_code_to_mysql(error,
user_thd);
goto func_exit;
}
dict_table_autoinc_update(prebuilt->table, auto_inc); dict_table_autoinc_update(prebuilt->table, auto_inc);
} }
} }
...@@ -5795,7 +5796,6 @@ ha_innobase::start_stmt( ...@@ -5795,7 +5796,6 @@ ha_innobase::start_stmt(
read_view_close_for_mysql(trx); read_view_close_for_mysql(trx);
} }
auto_inc_counter_for_this_stat = 0;
prebuilt->sql_stat_start = TRUE; prebuilt->sql_stat_start = TRUE;
prebuilt->hint_need_to_fetch_extra_cols = 0; prebuilt->hint_need_to_fetch_extra_cols = 0;
prebuilt->read_just_key = 0; prebuilt->read_just_key = 0;
...@@ -5985,7 +5985,7 @@ ha_innobase::external_lock( ...@@ -5985,7 +5985,7 @@ ha_innobase::external_lock(
trx->n_mysql_tables_in_use--; trx->n_mysql_tables_in_use--;
prebuilt->mysql_has_locked = FALSE; prebuilt->mysql_has_locked = FALSE;
auto_inc_counter_for_this_stat = 0;
if (trx->n_lock_table_exp) { if (trx->n_lock_table_exp) {
row_unlock_tables_for_mysql(trx); row_unlock_tables_for_mysql(trx);
} }
...@@ -6505,7 +6505,7 @@ ha_innobase::store_lock( ...@@ -6505,7 +6505,7 @@ ha_innobase::store_lock(
/*********************************************************************** /***********************************************************************
This function initializes the auto-inc counter if it has not been This function initializes the auto-inc counter if it has not been
initialized yet. This function does not change the value of the auto-inc initialized yet. This function does not change the value of the auto-inc
counter if it already has been initialized. In paramete ret returns counter if it already has been initialized. In parameter ret returns
the value of the auto-inc counter. */ the value of the auto-inc counter. */
int int
...@@ -6624,7 +6624,14 @@ ha_innobase::get_auto_increment() ...@@ -6624,7 +6624,14 @@ ha_innobase::get_auto_increment()
error = innobase_read_and_init_auto_inc(&nr); error = innobase_read_and_init_auto_inc(&nr);
if (error) { if (error) {
/* This should never happen in the current (5.0.6) code, since
we call this function only after the counter has been
initialized. */
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: error %lu in ::get_auto_increment()\n",
(ulong)error);
return(~(ulonglong) 0); return(~(ulonglong) 0);
} }
......
...@@ -70,7 +70,6 @@ class ha_innobase: public handler ...@@ -70,7 +70,6 @@ class ha_innobase: public handler
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX, ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
or undefined */ or undefined */
uint num_write_row; /* number of write_row() calls */ uint num_write_row; /* number of write_row() calls */
longlong auto_inc_counter_for_this_stat;
ulong max_supported_row_length(const byte *buf); ulong max_supported_row_length(const byte *buf);
uint store_key_val_for_row(uint keynr, char* buff, uint buff_len, uint store_key_val_for_row(uint keynr, char* buff, uint buff_len,
......
...@@ -4771,13 +4771,13 @@ Item_func_sp::execute(Item **itp) ...@@ -4771,13 +4771,13 @@ Item_func_sp::execute(Item **itp)
#endif #endif
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_procedure_access(thd, EXECUTE_ACL, if (check_routine_access(thd, EXECUTE_ACL,
m_sp->m_db.str, m_sp->m_name.str, 0)) m_sp->m_db.str, m_sp->m_name.str, 0, 0))
DBUG_RETURN(-1); DBUG_RETURN(-1);
sp_change_security_context(thd, m_sp, &save_ctx); sp_change_security_context(thd, m_sp, &save_ctx);
if (save_ctx.changed && if (save_ctx.changed &&
check_procedure_access(thd, EXECUTE_ACL, check_routine_access(thd, EXECUTE_ACL,
m_sp->m_db.str, m_sp->m_name.str, 0)) m_sp->m_db.str, m_sp->m_name.str, 0, 0))
{ {
sp_restore_security_context(thd, m_sp, &save_ctx); sp_restore_security_context(thd, m_sp, &save_ctx);
thd->client_capabilities|= old_client_capabilites & CLIENT_MULTI_RESULTS; thd->client_capabilities|= old_client_capabilites & CLIENT_MULTI_RESULTS;
......
...@@ -473,12 +473,12 @@ void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0, ...@@ -473,12 +473,12 @@ void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0,
TABLE *stopper= 0); TABLE *stopper= 0);
bool check_one_table_access(THD *thd, ulong privilege, bool check_one_table_access(THD *thd, ulong privilege,
TABLE_LIST *tables); TABLE_LIST *tables);
bool check_procedure_access(THD *thd,ulong want_access,char *db,char *name, bool check_routine_access(THD *thd,ulong want_access,char *db,char *name,
bool no_errors); bool is_proc, bool no_errors);
bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table); bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table);
bool check_merge_table_access(THD *thd, char *db, bool check_merge_table_access(THD *thd, char *db,
TABLE_LIST *table_list); TABLE_LIST *table_list);
bool check_some_routine_access(THD *thd, const char *db, const char *name); bool check_some_routine_access(THD *thd, const char *db, const char *name, bool is_proc);
bool multi_update_precheck(THD *thd, TABLE_LIST *tables); bool multi_update_precheck(THD *thd, TABLE_LIST *tables);
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count);
bool mysql_multi_update_prepare(THD *thd); bool mysql_multi_update_prepare(THD *thd);
......
...@@ -1111,7 +1111,8 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access) ...@@ -1111,7 +1111,8 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
(!strcmp(sp->m_definer_user.str, thd->priv_user) && (!strcmp(sp->m_definer_user.str, thd->priv_user) &&
!strcmp(sp->m_definer_host.str, thd->priv_host))); !strcmp(sp->m_definer_host.str, thd->priv_host)));
if (!*full_access) if (!*full_access)
return check_some_routine_access(thd, sp->m_db.str, sp->m_name.str); return check_some_routine_access(thd, sp->m_db.str, sp->m_name.str,
sp->m_type == TYPE_ENUM_PROCEDURE);
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -185,9 +185,9 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list, ...@@ -185,9 +185,9 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list,
bool mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list, bool mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
List <LEX_COLUMN> &column_list, ulong rights, List <LEX_COLUMN> &column_list, ulong rights,
bool revoke); bool revoke);
bool mysql_procedure_grant(THD *thd, TABLE_LIST *table, bool mysql_routine_grant(THD *thd, TABLE_LIST *table, bool is_proc,
List <LEX_USER> &user_list, ulong rights, List <LEX_USER> &user_list, ulong rights,
bool revoke, bool no_error); bool revoke, bool no_error);
ACL_USER *check_acl_user(LEX_USER *user_name, uint *acl_acl_userdx); ACL_USER *check_acl_user(LEX_USER *user_name, uint *acl_acl_userdx);
my_bool grant_init(THD *thd); my_bool grant_init(THD *thd);
void grant_free(void); void grant_free(void);
...@@ -200,8 +200,8 @@ bool check_grant_column (THD *thd, GRANT_INFO *grant, ...@@ -200,8 +200,8 @@ bool check_grant_column (THD *thd, GRANT_INFO *grant,
bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant, bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant,
const char* db_name, const char *table_name, const char* db_name, const char *table_name,
Field_iterator *fields); Field_iterator *fields);
bool check_grant_procedure(THD *thd, ulong want_access, bool check_grant_routine(THD *thd, ulong want_access,
TABLE_LIST *procs, bool no_error); TABLE_LIST *procs, bool is_proc, bool no_error);
bool check_grant_db(THD *thd,const char *db); bool check_grant_db(THD *thd,const char *db);
ulong get_table_grant(THD *thd, TABLE_LIST *table); ulong get_table_grant(THD *thd, TABLE_LIST *table);
ulong get_column_grant(THD *thd, GRANT_INFO *grant, ulong get_column_grant(THD *thd, GRANT_INFO *grant,
...@@ -216,9 +216,12 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list); ...@@ -216,9 +216,12 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list);
bool mysql_revoke_all(THD *thd, List <LEX_USER> &list); bool mysql_revoke_all(THD *thd, List <LEX_USER> &list);
void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
const char *db, const char *table); const char *db, const char *table);
bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name); bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name); bool is_proc);
bool check_routine_level_acl(THD *thd, const char *db, const char *name); bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool is_proc);
bool check_routine_level_acl(THD *thd, const char *db, const char *name,
bool is_proc);
#ifdef NO_EMBEDDED_ACCESS_CHECKS #ifdef NO_EMBEDDED_ACCESS_CHECKS
#define check_grant(A,B,C,D,E,F) 0 #define check_grant(A,B,C,D,E,F) 0
......
...@@ -3669,17 +3669,20 @@ mysql_execute_command(THD *thd) ...@@ -3669,17 +3669,20 @@ mysql_execute_command(THD *thd)
} }
if (first_table) if (first_table)
{ {
if (!lex->columns.elements && if (lex->type == TYPE_ENUM_PROCEDURE ||
sp_exists_routine(thd, all_tables, 1, 1)) lex->type == TYPE_ENUM_FUNCTION)
{ {
uint grants= lex->all_privileges uint grants= lex->all_privileges
? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL) ? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL)
: lex->grant; : lex->grant;
if (grant_option && if (grant_option &&
check_grant_procedure(thd, grants | GRANT_ACL, all_tables, 0)) check_grant_routine(thd, grants | GRANT_ACL, all_tables,
lex->type == TYPE_ENUM_PROCEDURE, 0))
goto error; goto error;
res= mysql_procedure_grant(thd, all_tables, lex->users_list, res= mysql_routine_grant(thd, all_tables,
grants, lex->sql_command == SQLCOM_REVOKE,0); lex->type == TYPE_ENUM_PROCEDURE,
lex->users_list, grants,
lex->sql_command == SQLCOM_REVOKE, 0);
} }
else else
{ {
...@@ -3701,7 +3704,7 @@ mysql_execute_command(THD *thd) ...@@ -3701,7 +3704,7 @@ mysql_execute_command(THD *thd)
} }
else else
{ {
if (lex->columns.elements) if (lex->columns.elements || lex->type)
{ {
my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE), my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
MYF(0)); MYF(0));
...@@ -3983,11 +3986,13 @@ mysql_execute_command(THD *thd) ...@@ -3983,11 +3986,13 @@ mysql_execute_command(THD *thd)
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
/* only add privileges if really neccessary */ /* only add privileges if really neccessary */
if (sp_automatic_privileges && if (sp_automatic_privileges &&
check_procedure_access(thd, DEFAULT_CREATE_PROC_ACLS, check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
db, name, 1)) db, name,
lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1))
{ {
close_thread_tables(thd); close_thread_tables(thd);
if (sp_grant_privileges(thd, db, name)) if (sp_grant_privileges(thd, db, name,
lex->sql_command == SQLCOM_CREATE_PROCEDURE))
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_PROC_AUTO_GRANT_FAIL, ER_PROC_AUTO_GRANT_FAIL,
ER(ER_PROC_AUTO_GRANT_FAIL)); ER(ER_PROC_AUTO_GRANT_FAIL));
...@@ -4072,8 +4077,8 @@ mysql_execute_command(THD *thd) ...@@ -4072,8 +4077,8 @@ mysql_execute_command(THD *thd)
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_procedure_access(thd, EXECUTE_ACL, if (check_routine_access(thd, EXECUTE_ACL,
sp->m_db.str, sp->m_name.str, 0)) sp->m_db.str, sp->m_name.str, TRUE, 0))
{ {
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok; thd->net.no_send_ok= nsok;
...@@ -4082,8 +4087,8 @@ mysql_execute_command(THD *thd) ...@@ -4082,8 +4087,8 @@ mysql_execute_command(THD *thd)
} }
sp_change_security_context(thd, sp, &save_ctx); sp_change_security_context(thd, sp, &save_ctx);
if (save_ctx.changed && if (save_ctx.changed &&
check_procedure_access(thd, EXECUTE_ACL, check_routine_access(thd, EXECUTE_ACL,
sp->m_db.str, sp->m_name.str, 0)) sp->m_db.str, sp->m_name.str, TRUE, 0))
{ {
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok; thd->net.no_send_ok= nsok;
...@@ -4185,8 +4190,9 @@ mysql_execute_command(THD *thd) ...@@ -4185,8 +4190,9 @@ mysql_execute_command(THD *thd)
} }
else else
{ {
if (check_procedure_access(thd, ALTER_PROC_ACL, sp->m_db.str, if (check_routine_access(thd, ALTER_PROC_ACL, sp->m_db.str,
sp->m_name.str, 0)) sp->m_name.str,
lex->sql_command == SQLCOM_ALTER_PROCEDURE, 0))
goto error; goto error;
memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics)); memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
if (!trust_routine_creators && mysql_bin_log.is_open() && if (!trust_routine_creators && mysql_bin_log.is_open() &&
...@@ -4244,11 +4250,13 @@ mysql_execute_command(THD *thd) ...@@ -4244,11 +4250,13 @@ mysql_execute_command(THD *thd)
{ {
db= thd->strdup(sp->m_db.str); db= thd->strdup(sp->m_db.str);
name= thd->strdup(sp->m_name.str); name= thd->strdup(sp->m_name.str);
if (check_procedure_access(thd, ALTER_PROC_ACL, db, name, 0)) if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
lex->sql_command == SQLCOM_DROP_PROCEDURE, 0))
goto error; goto error;
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (sp_automatic_privileges && if (sp_automatic_privileges &&
sp_revoke_privileges(thd, db, name)) sp_revoke_privileges(thd, db, name,
lex->sql_command == SQLCOM_DROP_PROCEDURE))
{ {
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_PROC_AUTO_REVOKE_FAIL, ER_PROC_AUTO_REVOKE_FAIL,
...@@ -4832,8 +4840,8 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, ...@@ -4832,8 +4840,8 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
bool bool
check_procedure_access(THD *thd, ulong want_access,char *db, char *name, check_routine_access(THD *thd, ulong want_access,char *db, char *name,
bool no_errors) bool is_proc, bool no_errors)
{ {
TABLE_LIST tables[1]; TABLE_LIST tables[1];
...@@ -4849,7 +4857,7 @@ check_procedure_access(THD *thd, ulong want_access,char *db, char *name, ...@@ -4849,7 +4857,7 @@ check_procedure_access(THD *thd, ulong want_access,char *db, char *name,
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (grant_option) if (grant_option)
return check_grant_procedure(thd, want_access, tables, no_errors); return check_grant_routine(thd, want_access, tables, is_proc, no_errors);
#endif #endif
return FALSE; return FALSE;
...@@ -4870,7 +4878,8 @@ check_procedure_access(THD *thd, ulong want_access,char *db, char *name, ...@@ -4870,7 +4878,8 @@ check_procedure_access(THD *thd, ulong want_access,char *db, char *name,
1 error 1 error
*/ */
bool check_some_routine_access(THD *thd, const char *db, const char *name) bool check_some_routine_access(THD *thd, const char *db, const char *name,
bool is_proc)
{ {
ulong save_priv; ulong save_priv;
if (thd->master_access & SHOW_PROC_ACLS) if (thd->master_access & SHOW_PROC_ACLS)
...@@ -4878,7 +4887,7 @@ bool check_some_routine_access(THD *thd, const char *db, const char *name) ...@@ -4878,7 +4887,7 @@ bool check_some_routine_access(THD *thd, const char *db, const char *name)
if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, 0, 1) || if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, 0, 1) ||
(save_priv & SHOW_PROC_ACLS)) (save_priv & SHOW_PROC_ACLS))
return FALSE; return FALSE;
return check_routine_level_acl(thd, db, name); return check_routine_level_acl(thd, db, name, is_proc);
} }
......
...@@ -2625,7 +2625,8 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, ...@@ -2625,7 +2625,8 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
definer= get_field(thd->mem_root, proc_table->field[11]); definer= get_field(thd->mem_root, proc_table->field[11]);
if (!full_access) if (!full_access)
full_access= !strcmp(sp_user, definer); full_access= !strcmp(sp_user, definer);
if (!full_access && check_some_routine_access(thd, sp_db, sp_name)) if (!full_access && check_some_routine_access(thd, sp_db, sp_name,
proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE))
return 0; return 0;
if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC && if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC &&
......
...@@ -804,7 +804,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -804,7 +804,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
opt_delete_options opt_delete_option varchar nchar nvarchar opt_delete_options opt_delete_option varchar nchar nvarchar
opt_outer table_list table_name opt_option opt_place opt_outer table_list table_name opt_option opt_place
opt_attribute opt_attribute_list attribute column_list column_list_id opt_attribute opt_attribute_list attribute column_list column_list_id
opt_column_list grant_privileges opt_table grant_list grant_option opt_column_list grant_privileges grant_ident grant_list grant_option
object_privilege object_privilege_list user_list rename_list object_privilege object_privilege_list user_list rename_list
clear_privileges flush_options flush_option clear_privileges flush_options flush_option
equal optional_braces opt_key_definition key_usage_list2 equal optional_braces opt_key_definition key_usage_list2
...@@ -7907,9 +7907,36 @@ revoke: ...@@ -7907,9 +7907,36 @@ revoke:
; ;
revoke_command: revoke_command:
grant_privileges ON opt_table FROM grant_list grant_privileges ON opt_table grant_ident FROM grant_list
{ {
Lex->sql_command = SQLCOM_REVOKE; LEX *lex= Lex;
lex->sql_command= SQLCOM_REVOKE;
lex->type= 0;
}
|
grant_privileges ON FUNCTION_SYM grant_ident FROM grant_list
{
LEX *lex= Lex;
if (lex->columns.elements)
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
lex->sql_command= SQLCOM_REVOKE;
lex->type= TYPE_ENUM_FUNCTION;
}
|
grant_privileges ON PROCEDURE grant_ident FROM grant_list
{
LEX *lex= Lex;
if (lex->columns.elements)
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
lex->sql_command= SQLCOM_REVOKE;
lex->type= TYPE_ENUM_PROCEDURE;
} }
| |
ALL opt_privileges ',' GRANT OPTION FROM grant_list ALL opt_privileges ',' GRANT OPTION FROM grant_list
...@@ -7919,11 +7946,50 @@ revoke_command: ...@@ -7919,11 +7946,50 @@ revoke_command:
; ;
grant: grant:
GRANT clear_privileges grant_privileges ON opt_table TO_SYM grant_list GRANT clear_privileges grant_command
{}
;
grant_command:
grant_privileges ON opt_table grant_ident TO_SYM grant_list
require_clause grant_options require_clause grant_options
{ Lex->sql_command= SQLCOM_GRANT; } {
; LEX *lex= Lex;
lex->sql_command= SQLCOM_GRANT;
lex->type= 0;
}
|
grant_privileges ON FUNCTION_SYM grant_ident TO_SYM grant_list
require_clause grant_options
{
LEX *lex= Lex;
if (lex->columns.elements)
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
lex->sql_command= SQLCOM_GRANT;
lex->type= TYPE_ENUM_FUNCTION;
}
|
grant_privileges ON PROCEDURE grant_ident TO_SYM grant_list
require_clause grant_options
{
LEX *lex= Lex;
if (lex->columns.elements)
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
lex->sql_command= SQLCOM_GRANT;
lex->type= TYPE_ENUM_PROCEDURE;
}
;
opt_table:
/* Empty */
| TABLE_SYM ;
grant_privileges: grant_privileges:
object_privilege_list { } object_privilege_list { }
| ALL opt_privileges | ALL opt_privileges
...@@ -8016,7 +8082,7 @@ require_list_element: ...@@ -8016,7 +8082,7 @@ require_list_element:
} }
; ;
opt_table: grant_ident:
'*' '*'
{ {
LEX *lex= Lex; LEX *lex= Lex;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment