mirror of
https://github.com/MariaDB/server.git
synced 2025-07-08 17:02:21 +03:00
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.0
into dl145c.mysql.com:/home/ndbdev/tomas/mysql-5.1 scripts/mysql_create_system_tables.sh: Auto merged scripts/mysql_fix_privilege_tables.sql: Auto merged sql/ha_innodb.cc: Auto merged sql/ha_innodb.h: Auto merged sql/mysql_priv.h: Auto merged sql/sql_acl.cc: Auto merged sql/sql_acl.h: Auto merged sql/sql_base.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_yacc.yy: Auto merged
This commit is contained in:
@ -51,3 +51,11 @@ select a from t1 where mid(a+0,6,3) = ( mid(20040106123400,6,3) );
|
||||
a
|
||||
2004-01-06 12:34:00
|
||||
drop table t1;
|
||||
create table t1 as select uuid(), length(uuid());
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`uuid()` varchar(36) character set utf8 NOT NULL default '',
|
||||
`length(uuid())` int(10) NOT NULL default '0'
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
|
@ -23,10 +23,10 @@ root@localhost 1
|
||||
select db();
|
||||
db()
|
||||
db1_secret
|
||||
grant execute on db1_secret.stamp to user1@'%';
|
||||
grant execute on db1_secret.db to user1@'%';
|
||||
grant execute on db1_secret.stamp to ''@'%';
|
||||
grant execute on db1_secret.db to ''@'%';
|
||||
grant execute on procedure db1_secret.stamp to user1@'%';
|
||||
grant execute on function db1_secret.db to user1@'%';
|
||||
grant execute on procedure db1_secret.stamp to ''@'%';
|
||||
grant execute on function db1_secret.db to ''@'%';
|
||||
call db1_secret.stamp(2);
|
||||
select db1_secret.db();
|
||||
db1_secret.db()
|
||||
@ -105,8 +105,8 @@ select * from t2;
|
||||
s1
|
||||
0
|
||||
2
|
||||
grant usage on db2.q to user2@localhost with grant option;
|
||||
grant execute on db2.q to user1@localhost;
|
||||
grant usage on procedure db2.q to user2@localhost with grant option;
|
||||
grant execute on procedure db2.q to user1@localhost;
|
||||
use db2;
|
||||
call q();
|
||||
select * from t2;
|
||||
@ -117,9 +117,9 @@ s1
|
||||
alter procedure p modifies sql data;
|
||||
drop procedure p;
|
||||
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;
|
||||
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;
|
||||
alter procedure q modifies sql data;
|
||||
drop procedure q;
|
||||
@ -141,52 +141,52 @@ create database sptest;
|
||||
create table t1 ( u varchar(64), i int );
|
||||
create procedure sptest.p1(i int) insert into test.t1 values (user(), i);
|
||||
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;
|
||||
Grants for usera@localhost
|
||||
GRANT USAGE ON *.* TO 'usera'@'localhost'
|
||||
GRANT INSERT ON `test`.`t1` TO 'usera'@'localhost'
|
||||
GRANT EXECUTE ON `sptest`.`p1` TO 'usera'@'localhost'
|
||||
grant execute on sptest.p1 to userc@localhost with grant option;
|
||||
GRANT EXECUTE ON PROCEDURE `sptest`.`p1` TO 'usera'@'localhost'
|
||||
grant execute on procedure sptest.p1 to userc@localhost with grant option;
|
||||
show grants for userc@localhost;
|
||||
Grants for 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);
|
||||
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'
|
||||
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);
|
||||
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'
|
||||
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);
|
||||
grant execute on sptest.p1 to userb@localhost;
|
||||
grant execute on procedure sptest.p1 to userb@localhost;
|
||||
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);
|
||||
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'
|
||||
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;
|
||||
u i
|
||||
usera@localhost 1
|
||||
userc@localhost 3
|
||||
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;
|
||||
Grants for 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;
|
||||
Grants for userb@localhost
|
||||
GRANT USAGE ON *.* TO 'userb'@'localhost'
|
||||
GRANT EXECUTE ON `sptest`.`p1` TO 'userb'@'localhost'
|
||||
revoke all privileges on sptest.p1 from userb@localhost;
|
||||
GRANT EXECUTE ON PROCEDURE `sptest`.`p1` TO 'userb'@'localhost'
|
||||
revoke all privileges on procedure sptest.p1 from userb@localhost;
|
||||
show grants for userb@localhost;
|
||||
Grants for userb@localhost
|
||||
GRANT USAGE ON *.* TO 'userb'@'localhost'
|
||||
|
@ -152,10 +152,11 @@ procs_priv CREATE TABLE `procs_priv` (
|
||||
`Db` char(64) 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_type` enum('FUNCTION','PROCEDURE') collate utf8_bin NOT NULL default 'FUNCTION',
|
||||
`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 '',
|
||||
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`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Procedure privileges'
|
||||
show create table proc;
|
||||
|
@ -38,3 +38,11 @@ select a from t1 where mid(a+0,6,3) = ( mid(20040106123400,6,3) );
|
||||
|
||||
drop table t1;
|
||||
|
||||
# Test for BUG#9535
|
||||
create table t1 as select uuid(), length(uuid());
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -43,10 +43,10 @@ call stamp(1);
|
||||
select * from t1;
|
||||
select db();
|
||||
|
||||
grant execute on db1_secret.stamp to user1@'%';
|
||||
grant execute on db1_secret.db to user1@'%';
|
||||
grant execute on db1_secret.stamp to ''@'%';
|
||||
grant execute on db1_secret.db to ''@'%';
|
||||
grant execute on procedure db1_secret.stamp to user1@'%';
|
||||
grant execute on function db1_secret.db to user1@'%';
|
||||
grant execute on procedure db1_secret.stamp to ''@'%';
|
||||
grant execute on function db1_secret.db to ''@'%';
|
||||
|
||||
connect (con2user1,localhost,user1,,);
|
||||
connect (con3anon,localhost,anon,,);
|
||||
@ -183,10 +183,10 @@ call q();
|
||||
select * from t2;
|
||||
|
||||
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;
|
||||
grant execute on db2.q to user1@localhost;
|
||||
grant execute on procedure db2.q to user1@localhost;
|
||||
|
||||
connection con2user1;
|
||||
use db2;
|
||||
@ -245,9 +245,9 @@ create database sptest;
|
||||
create table t1 ( u varchar(64), i int );
|
||||
create procedure sptest.p1(i int) insert into test.t1 values (user(), i);
|
||||
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;
|
||||
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;
|
||||
|
||||
connect (con2usera,localhost,usera,,);
|
||||
@ -257,7 +257,7 @@ connect (con4userc,localhost,userc,,);
|
||||
connection con2usera;
|
||||
call sptest.p1(1);
|
||||
--error 1370
|
||||
grant execute on sptest.p1 to userb@localhost;
|
||||
grant execute on procedure sptest.p1 to userb@localhost;
|
||||
--error 1370
|
||||
drop procedure sptest.p1;
|
||||
|
||||
@ -265,32 +265,32 @@ connection con3userb;
|
||||
--error 1370
|
||||
call sptest.p1(2);
|
||||
--error 1370
|
||||
grant execute on sptest.p1 to userb@localhost;
|
||||
grant execute on procedure sptest.p1 to userb@localhost;
|
||||
--error 1370
|
||||
drop procedure sptest.p1;
|
||||
|
||||
connection con4userc;
|
||||
call sptest.p1(3);
|
||||
grant execute on sptest.p1 to userb@localhost;
|
||||
grant execute on procedure sptest.p1 to userb@localhost;
|
||||
--error 1370
|
||||
drop procedure sptest.p1;
|
||||
|
||||
connection con3userb;
|
||||
call sptest.p1(4);
|
||||
--error 1370
|
||||
grant execute on sptest.p1 to userb@localhost;
|
||||
grant execute on procedure sptest.p1 to userb@localhost;
|
||||
--error 1370
|
||||
drop procedure sptest.p1;
|
||||
|
||||
connection con1root;
|
||||
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 userb@localhost;
|
||||
|
||||
connection con4userc;
|
||||
revoke all privileges on sptest.p1 from userb@localhost;
|
||||
revoke all privileges on procedure sptest.p1 from userb@localhost;
|
||||
|
||||
connection con1root;
|
||||
show grants for userb@localhost;
|
||||
|
@ -255,10 +255,11 @@ then
|
||||
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 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 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 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 ) engine=MyISAM"
|
||||
c_pp="$c_pp CHARACTER SET utf8 COLLATE utf8_bin"
|
||||
|
@ -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
|
||||
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 (
|
||||
Host char(60) DEFAULT '' NOT NULL,
|
||||
@ -315,10 +319,11 @@ Host char(60) binary DEFAULT '' NOT NULL,
|
||||
Db char(64) binary DEFAULT '' NOT NULL,
|
||||
User char(16) 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,
|
||||
Timestamp timestamp(14),
|
||||
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)
|
||||
) CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
|
||||
|
||||
|
@ -3171,10 +3171,26 @@ no_commit:
|
||||
prebuilt->sql_stat_start = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
We must use the handler code to update the auto-increment
|
||||
value to be sure that increment it correctly.
|
||||
*/
|
||||
/* 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. 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();
|
||||
auto_inc_used = 1;
|
||||
|
||||
@ -3199,24 +3215,9 @@ no_commit:
|
||||
auto_inc = table->next_number_field->val_int();
|
||||
|
||||
if (auto_inc != 0) {
|
||||
/* This call will calculate the max of the current
|
||||
value and the value supplied by the user and
|
||||
update the counter accordingly */
|
||||
/* This call will update the counter according to the
|
||||
value that was inserted in the table */
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
@ -5796,7 +5797,6 @@ ha_innobase::start_stmt(
|
||||
read_view_close_for_mysql(trx);
|
||||
}
|
||||
|
||||
auto_inc_counter_for_this_stat = 0;
|
||||
prebuilt->sql_stat_start = TRUE;
|
||||
prebuilt->hint_need_to_fetch_extra_cols = 0;
|
||||
prebuilt->read_just_key = 0;
|
||||
@ -5986,7 +5986,7 @@ ha_innobase::external_lock(
|
||||
|
||||
trx->n_mysql_tables_in_use--;
|
||||
prebuilt->mysql_has_locked = FALSE;
|
||||
auto_inc_counter_for_this_stat = 0;
|
||||
|
||||
if (trx->n_lock_table_exp) {
|
||||
row_unlock_tables_for_mysql(trx);
|
||||
}
|
||||
@ -6506,7 +6506,7 @@ ha_innobase::store_lock(
|
||||
/***********************************************************************
|
||||
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
|
||||
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. */
|
||||
|
||||
int
|
||||
@ -6625,7 +6625,14 @@ ha_innobase::get_auto_increment()
|
||||
error = innobase_read_and_init_auto_inc(&nr);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,6 @@ class ha_innobase: public handler
|
||||
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
|
||||
or undefined */
|
||||
uint num_write_row; /* number of write_row() calls */
|
||||
longlong auto_inc_counter_for_this_stat;
|
||||
ulong max_supported_row_length(const byte *buf);
|
||||
|
||||
uint store_key_val_for_row(uint keynr, char* buff, uint buff_len,
|
||||
|
@ -4771,13 +4771,13 @@ Item_func_sp::execute(Item **itp)
|
||||
#endif
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (check_procedure_access(thd, EXECUTE_ACL,
|
||||
m_sp->m_db.str, m_sp->m_name.str, 0))
|
||||
if (check_routine_access(thd, EXECUTE_ACL,
|
||||
m_sp->m_db.str, m_sp->m_name.str, 0, 0))
|
||||
DBUG_RETURN(-1);
|
||||
sp_change_security_context(thd, m_sp, &save_ctx);
|
||||
if (save_ctx.changed &&
|
||||
check_procedure_access(thd, EXECUTE_ACL,
|
||||
m_sp->m_db.str, m_sp->m_name.str, 0))
|
||||
check_routine_access(thd, EXECUTE_ACL,
|
||||
m_sp->m_db.str, m_sp->m_name.str, 0, 0))
|
||||
{
|
||||
sp_restore_security_context(thd, m_sp, &save_ctx);
|
||||
thd->client_capabilities|= old_client_capabilites & CLIENT_MULTI_RESULTS;
|
||||
|
@ -726,7 +726,12 @@ public:
|
||||
Item_func_uuid(): Item_str_func() {}
|
||||
void fix_length_and_dec() {
|
||||
collation.set(system_charset_info);
|
||||
max_length= UUID_LENGTH;
|
||||
/*
|
||||
NOTE! uuid() should be changed to use 'ascii'
|
||||
charset when hex(), format(), md5(), etc, and implicit
|
||||
number-to-string conversion will use 'ascii'
|
||||
*/
|
||||
max_length= UUID_LENGTH * system_charset_info->mbmaxlen;
|
||||
}
|
||||
const char *func_name() const{ return "uuid"; }
|
||||
String *val_str(String *);
|
||||
|
@ -477,12 +477,12 @@ void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0,
|
||||
TABLE *stopper= 0);
|
||||
bool check_one_table_access(THD *thd, ulong privilege,
|
||||
TABLE_LIST *tables);
|
||||
bool check_procedure_access(THD *thd,ulong want_access,char *db,char *name,
|
||||
bool no_errors);
|
||||
bool check_routine_access(THD *thd,ulong want_access,char *db,char *name,
|
||||
bool is_proc, bool no_errors);
|
||||
bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table);
|
||||
bool check_merge_table_access(THD *thd, char *db,
|
||||
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_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count);
|
||||
bool mysql_multi_update_prepare(THD *thd);
|
||||
|
@ -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_host.str, thd->priv_host)));
|
||||
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;
|
||||
}
|
||||
|
||||
|
194
sql/sql_acl.cc
194
sql/sql_acl.cc
@ -59,7 +59,7 @@ static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs;
|
||||
static MEM_ROOT mem, memex;
|
||||
static bool initialized=0;
|
||||
static bool allow_all_hosts=1;
|
||||
static HASH acl_check_hosts, column_priv_hash, proc_priv_hash;
|
||||
static HASH acl_check_hosts, column_priv_hash, proc_priv_hash, func_priv_hash;
|
||||
static DYNAMIC_ARRAY acl_wild_hosts;
|
||||
static hash_filo *acl_cache;
|
||||
static uint grant_version=0; /* Version of priv tables. incremented by acl_init */
|
||||
@ -2135,11 +2135,12 @@ static GRANT_NAME *name_hash_search(HASH *name_hash,
|
||||
|
||||
|
||||
inline GRANT_NAME *
|
||||
proc_hash_search(const char *host, const char *ip, const char *db,
|
||||
const char *user, const char *tname, bool exact)
|
||||
routine_hash_search(const char *host, const char *ip, const char *db,
|
||||
const char *user, const char *tname, bool proc, bool exact)
|
||||
{
|
||||
return (GRANT_TABLE*) name_hash_search(&proc_priv_hash, host, ip, db,
|
||||
user, tname, exact);
|
||||
return (GRANT_TABLE*)
|
||||
name_hash_search(proc ? &proc_priv_hash : &func_priv_hash,
|
||||
host, ip, db, user, tname, exact);
|
||||
}
|
||||
|
||||
|
||||
@ -2465,16 +2466,17 @@ table_error:
|
||||
}
|
||||
|
||||
|
||||
static int replace_proc_table(THD *thd, GRANT_NAME *grant_name,
|
||||
static int replace_routine_table(THD *thd, GRANT_NAME *grant_name,
|
||||
TABLE *table, const LEX_USER &combo,
|
||||
const char *db, const char *proc_name,
|
||||
ulong rights, bool revoke_grant)
|
||||
const char *db, const char *routine_name,
|
||||
bool is_proc, ulong rights, bool revoke_grant)
|
||||
{
|
||||
char grantor[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
|
||||
int old_row_exists= 1;
|
||||
int error=0;
|
||||
ulong store_proc_rights;
|
||||
DBUG_ENTER("replace_proc_table");
|
||||
byte *key;
|
||||
DBUG_ENTER("replace_routine_table");
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
@ -2498,7 +2500,10 @@ static int replace_proc_table(THD *thd, GRANT_NAME *grant_name,
|
||||
table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1);
|
||||
table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1);
|
||||
table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1);
|
||||
table->field[3]->store(proc_name,(uint) strlen(proc_name), &my_charset_latin1);
|
||||
table->field[3]->store(routine_name,(uint) strlen(routine_name),
|
||||
&my_charset_latin1);
|
||||
table->field[4]->store((longlong)(is_proc ?
|
||||
TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION));
|
||||
store_record(table,record[1]); // store at pos 1
|
||||
|
||||
if (table->file->index_read_idx(table->record[0],0,
|
||||
@ -2513,7 +2518,7 @@ static int replace_proc_table(THD *thd, GRANT_NAME *grant_name,
|
||||
if (revoke_grant)
|
||||
{ // no row, no revoke
|
||||
my_error(ER_NONEXISTING_PROC_GRANT, MYF(0),
|
||||
combo.user.str, combo.host.str, proc_name);
|
||||
combo.user.str, combo.host.str, routine_name);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
old_row_exists= 0;
|
||||
@ -2538,7 +2543,7 @@ static int replace_proc_table(THD *thd, GRANT_NAME *grant_name,
|
||||
}
|
||||
}
|
||||
|
||||
table->field[4]->store(grantor,(uint) strlen(grantor), &my_charset_latin1);
|
||||
table->field[5]->store(grantor,(uint) strlen(grantor), &my_charset_latin1);
|
||||
table->field[6]->store((longlong) store_proc_rights);
|
||||
rights=fix_rights_for_procedure(store_proc_rights);
|
||||
|
||||
@ -2565,7 +2570,7 @@ static int replace_proc_table(THD *thd, GRANT_NAME *grant_name,
|
||||
}
|
||||
else
|
||||
{
|
||||
hash_delete(&proc_priv_hash,(byte*) grant_name);
|
||||
hash_delete(is_proc ? &proc_priv_hash : &func_priv_hash,(byte*) grant_name);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
|
||||
@ -2841,12 +2846,13 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
||||
|
||||
|
||||
/*
|
||||
Store procedure level grants in the privilege tables
|
||||
Store routine level grants in the privilege tables
|
||||
|
||||
SYNOPSIS
|
||||
mysql_procedure_grant()
|
||||
mysql_routine_grant()
|
||||
thd Thread handle
|
||||
table_list List of procedures to give grant
|
||||
table_list List of routines to give grant
|
||||
is_proc true indicates routine list are procedures
|
||||
user_list List of users to give grant
|
||||
rights Table level grant
|
||||
revoke_grant Set to 1 if this is a REVOKE command
|
||||
@ -2856,7 +2862,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
||||
1 error
|
||||
*/
|
||||
|
||||
bool mysql_procedure_grant(THD *thd, TABLE_LIST *table_list,
|
||||
bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
|
||||
List <LEX_USER> &user_list, ulong rights,
|
||||
bool revoke_grant, bool no_error)
|
||||
{
|
||||
@ -2865,7 +2871,7 @@ bool mysql_procedure_grant(THD *thd, TABLE_LIST *table_list,
|
||||
TABLE_LIST tables[2];
|
||||
bool create_new_users=0, result=0;
|
||||
char *db_name, *table_name;
|
||||
DBUG_ENTER("mysql_procedure_grant");
|
||||
DBUG_ENTER("mysql_routine_grant");
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
@ -2884,7 +2890,7 @@ bool mysql_procedure_grant(THD *thd, TABLE_LIST *table_list,
|
||||
|
||||
if (!revoke_grant)
|
||||
{
|
||||
if (sp_exists_routine(thd, table_list, 0, no_error)<0)
|
||||
if (sp_exists_routine(thd, table_list, is_proc, no_error)<0)
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
@ -2957,8 +2963,8 @@ bool mysql_procedure_grant(THD *thd, TABLE_LIST *table_list,
|
||||
db_name= table_list->db;
|
||||
table_name= table_list->table_name;
|
||||
|
||||
grant_name= proc_hash_search(Str->host.str, NullS, db_name,
|
||||
Str->user.str, table_name, 1);
|
||||
grant_name= routine_hash_search(Str->host.str, NullS, db_name,
|
||||
Str->user.str, table_name, is_proc, 1);
|
||||
if (!grant_name)
|
||||
{
|
||||
if (revoke_grant)
|
||||
@ -2977,11 +2983,11 @@ bool mysql_procedure_grant(THD *thd, TABLE_LIST *table_list,
|
||||
result= TRUE;
|
||||
continue;
|
||||
}
|
||||
my_hash_insert(&proc_priv_hash,(byte*) grant_name);
|
||||
my_hash_insert(is_proc ? &proc_priv_hash : &func_priv_hash,(byte*) grant_name);
|
||||
}
|
||||
|
||||
if (replace_proc_table(thd, grant_name, tables[1].table, *Str,
|
||||
db_name, table_name, rights, revoke_grant))
|
||||
if (replace_routine_table(thd, grant_name, tables[1].table, *Str,
|
||||
db_name, table_name, is_proc, rights, revoke_grant))
|
||||
{
|
||||
result= TRUE;
|
||||
continue;
|
||||
@ -3133,6 +3139,9 @@ my_bool grant_init(THD *org_thd)
|
||||
(void) hash_init(&proc_priv_hash,system_charset_info,
|
||||
0,0,0, (hash_get_key) get_grant_table,
|
||||
0,0);
|
||||
(void) hash_init(&func_priv_hash,system_charset_info,
|
||||
0,0,0, (hash_get_key) get_grant_table,
|
||||
0,0);
|
||||
init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0);
|
||||
|
||||
/* Don't do anything if running with --skip-grant */
|
||||
@ -3206,6 +3215,8 @@ my_bool grant_init(THD *org_thd)
|
||||
do
|
||||
{
|
||||
GRANT_NAME *mem_check;
|
||||
longlong proc_type;
|
||||
HASH *hash;
|
||||
if (!(mem_check=new GRANT_NAME(p_table)))
|
||||
{
|
||||
/* This could only happen if we are out memory */
|
||||
@ -3224,11 +3235,27 @@ my_bool grant_init(THD *org_thd)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (p_table->field[4]->val_int() == TYPE_ENUM_PROCEDURE)
|
||||
{
|
||||
hash= &proc_priv_hash;
|
||||
}
|
||||
else
|
||||
if (p_table->field[4]->val_int() == TYPE_ENUM_FUNCTION)
|
||||
{
|
||||
hash= &func_priv_hash;
|
||||
}
|
||||
else
|
||||
{
|
||||
sql_print_warning("'procs_priv' entry '%s' "
|
||||
"ignored, bad routine type",
|
||||
mem_check->tname);
|
||||
continue;
|
||||
}
|
||||
|
||||
mem_check->privs= fix_rights_for_procedure(mem_check->privs);
|
||||
if (! mem_check->ok())
|
||||
delete mem_check;
|
||||
else if (my_hash_insert(&proc_priv_hash,(byte*) mem_check))
|
||||
else if (my_hash_insert(hash, (byte*) mem_check))
|
||||
{
|
||||
delete mem_check;
|
||||
grant_option= FALSE;
|
||||
@ -3272,7 +3299,7 @@ end:
|
||||
|
||||
void grant_reload(THD *thd)
|
||||
{
|
||||
HASH old_column_priv_hash, old_proc_priv_hash;
|
||||
HASH old_column_priv_hash, old_proc_priv_hash, old_func_priv_hash;
|
||||
bool old_grant_option;
|
||||
MEM_ROOT old_mem;
|
||||
DBUG_ENTER("grant_reload");
|
||||
@ -3281,6 +3308,7 @@ void grant_reload(THD *thd)
|
||||
grant_version++;
|
||||
old_column_priv_hash= column_priv_hash;
|
||||
old_proc_priv_hash= proc_priv_hash;
|
||||
old_func_priv_hash= func_priv_hash;
|
||||
old_grant_option= grant_option;
|
||||
old_mem= memex;
|
||||
|
||||
@ -3290,6 +3318,7 @@ void grant_reload(THD *thd)
|
||||
grant_free(); /* purecov: deadcode */
|
||||
column_priv_hash= old_column_priv_hash; /* purecov: deadcode */
|
||||
proc_priv_hash= old_proc_priv_hash;
|
||||
func_priv_hash= old_func_priv_hash;
|
||||
grant_option= old_grant_option; /* purecov: deadcode */
|
||||
memex= old_mem; /* purecov: deadcode */
|
||||
}
|
||||
@ -3297,6 +3326,7 @@ void grant_reload(THD *thd)
|
||||
{
|
||||
hash_free(&old_column_priv_hash);
|
||||
hash_free(&old_proc_priv_hash);
|
||||
hash_free(&old_func_priv_hash);
|
||||
free_root(&old_mem,MYF(0));
|
||||
}
|
||||
rw_unlock(&LOCK_grant);
|
||||
@ -3540,13 +3570,14 @@ bool check_grant_db(THD *thd,const char *db)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Check procedure level grants
|
||||
Check routine level grants
|
||||
|
||||
SYNPOSIS
|
||||
bool check_grant_procedure()
|
||||
bool check_grant_routine()
|
||||
thd Thread handler
|
||||
want_access Bits of privileges user needs to have
|
||||
procs List of procedures to check. The user should have 'want_access'
|
||||
procs List of routines to check. The user should have 'want_access'
|
||||
is_proc True if the list is all procedures, else functions
|
||||
no_errors If 0 then we write an error. The error is sent directly to
|
||||
the client
|
||||
|
||||
@ -3555,13 +3586,13 @@ bool check_grant_db(THD *thd,const char *db)
|
||||
1 Error: User did not have the requested privielges
|
||||
****************************************************************************/
|
||||
|
||||
bool check_grant_procedure(THD *thd, ulong want_access,
|
||||
TABLE_LIST *procs, bool no_errors)
|
||||
bool check_grant_routine(THD *thd, ulong want_access,
|
||||
TABLE_LIST *procs, bool is_proc, bool no_errors)
|
||||
{
|
||||
TABLE_LIST *table;
|
||||
char *user= thd->priv_user;
|
||||
char *host= thd->priv_host;
|
||||
DBUG_ENTER("check_grant_procedure");
|
||||
DBUG_ENTER("check_grant_routine");
|
||||
|
||||
want_access&= ~thd->master_access;
|
||||
if (!want_access)
|
||||
@ -3571,8 +3602,8 @@ bool check_grant_procedure(THD *thd, ulong want_access,
|
||||
for (table= procs; table; table= table->next_global)
|
||||
{
|
||||
GRANT_NAME *grant_proc;
|
||||
if ((grant_proc= proc_hash_search(host,thd->ip,
|
||||
table->db, user, table->table_name, 0)))
|
||||
if ((grant_proc= routine_hash_search(host,thd->ip, table->db, user,
|
||||
table->table_name, is_proc, 0)))
|
||||
table->grant.privilege|= grant_proc->privs;
|
||||
|
||||
if (want_access & ~table->grant.privilege)
|
||||
@ -3594,7 +3625,7 @@ err:
|
||||
if (want_access & EXECUTE_ACL)
|
||||
command= "execute";
|
||||
else if (want_access & ALTER_PROC_ACL)
|
||||
command= "alter procedure";
|
||||
command= "alter routine";
|
||||
else if (want_access & GRANT_ACL)
|
||||
command= "grant";
|
||||
my_error(ER_PROCACCESS_DENIED_ERROR, MYF(0),
|
||||
@ -3606,7 +3637,7 @@ err:
|
||||
|
||||
/*
|
||||
Check if routine has any of the
|
||||
procedure level grants
|
||||
routine level grants
|
||||
|
||||
SYNPOSIS
|
||||
bool check_routine_level_acl()
|
||||
@ -3619,15 +3650,15 @@ err:
|
||||
1 error
|
||||
*/
|
||||
|
||||
bool check_routine_level_acl(THD *thd, const char *db, const char *name)
|
||||
bool check_routine_level_acl(THD *thd, const char *db, const char *name, bool is_proc)
|
||||
{
|
||||
bool no_routine_acl= 1;
|
||||
if (grant_option)
|
||||
{
|
||||
GRANT_NAME *grant_proc;
|
||||
rw_rdlock(&LOCK_grant);
|
||||
if ((grant_proc= proc_hash_search(thd->priv_host, thd->ip, db,
|
||||
thd->priv_user, name, 0)))
|
||||
if ((grant_proc= routine_hash_search(thd->priv_host, thd->ip, db,
|
||||
thd->priv_user, name, is_proc, 0)))
|
||||
no_routine_acl= !(grant_proc->privs & SHOW_PROC_ACLS);
|
||||
rw_unlock(&LOCK_grant);
|
||||
}
|
||||
@ -3730,6 +3761,11 @@ static uint command_lengths[]=
|
||||
};
|
||||
|
||||
|
||||
static int show_routine_grants(THD *thd, LEX_USER *lex_user, HASH *hash,
|
||||
const char *type, int typelen,
|
||||
char *buff, int buffsize);
|
||||
|
||||
|
||||
/*
|
||||
SHOW GRANTS; Send grants for a user to the client
|
||||
|
||||
@ -4076,12 +4112,40 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||
}
|
||||
}
|
||||
|
||||
/* Add procedure access */
|
||||
for (index=0 ; index < proc_priv_hash.records ; index++)
|
||||
if (show_routine_grants(thd, lex_user, &proc_priv_hash,
|
||||
"PROCEDURE", 9, buff, sizeof(buff)))
|
||||
{
|
||||
error= -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (show_routine_grants(thd, lex_user, &func_priv_hash,
|
||||
"FUNCTION", 8, buff, sizeof(buff)))
|
||||
{
|
||||
error= -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
VOID(pthread_mutex_unlock(&acl_cache->lock));
|
||||
rw_unlock(&LOCK_grant);
|
||||
|
||||
send_eof(thd);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
static int show_routine_grants(THD* thd, LEX_USER *lex_user, HASH *hash,
|
||||
const char *type, int typelen,
|
||||
char *buff, int buffsize)
|
||||
{
|
||||
uint counter, index;
|
||||
int error= 0;
|
||||
Protocol *protocol= thd->protocol;
|
||||
/* Add routine access */
|
||||
for (index=0 ; index < hash->records ; index++)
|
||||
{
|
||||
const char *user;
|
||||
GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(&proc_priv_hash,
|
||||
index);
|
||||
GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(hash, index);
|
||||
|
||||
if (!(user=grant_proc->user))
|
||||
user= "";
|
||||
@ -4093,7 +4157,7 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||
ulong proc_access= grant_proc->privs;
|
||||
if (proc_access != 0)
|
||||
{
|
||||
String global(buff, sizeof(buff), system_charset_info);
|
||||
String global(buff, buffsize, system_charset_info);
|
||||
ulong test_access= proc_access & ~GRANT_ACL;
|
||||
|
||||
global.length(0);
|
||||
@ -4119,6 +4183,8 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||
}
|
||||
}
|
||||
global.append(" ON ",4);
|
||||
global.append(type,typelen);
|
||||
global.append(' ');
|
||||
append_identifier(thd, &global, grant_proc->db,
|
||||
strlen(grant_proc->db));
|
||||
global.append('.');
|
||||
@ -4143,15 +4209,9 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||
}
|
||||
}
|
||||
}
|
||||
end:
|
||||
VOID(pthread_mutex_unlock(&acl_cache->lock));
|
||||
rw_unlock(&LOCK_grant);
|
||||
|
||||
send_eof(thd);
|
||||
DBUG_RETURN(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Make a clear-text version of the requested privilege.
|
||||
*/
|
||||
@ -4977,7 +5037,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
|
||||
|
||||
bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
|
||||
{
|
||||
uint counter, revoked;
|
||||
uint counter, revoked, is_proc;
|
||||
int result;
|
||||
ACL_DB *acl_db;
|
||||
TABLE_LIST tables[GRANT_TABLES];
|
||||
@ -5092,12 +5152,12 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
|
||||
} while (revoked);
|
||||
|
||||
/* Remove procedure access */
|
||||
do {
|
||||
for (counter= 0, revoked= 0 ; counter < proc_priv_hash.records ; )
|
||||
for (is_proc=0; is_proc<2; is_proc++) do {
|
||||
HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash;
|
||||
for (counter= 0, revoked= 0 ; counter < hash->records ; )
|
||||
{
|
||||
const char *user,*host;
|
||||
GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(&proc_priv_hash,
|
||||
counter);
|
||||
GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(hash, counter);
|
||||
if (!(user=grant_proc->user))
|
||||
user= "";
|
||||
if (!(host=grant_proc->host.hostname))
|
||||
@ -5106,9 +5166,10 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
|
||||
if (!strcmp(lex_user->user.str,user) &&
|
||||
!my_strcasecmp(system_charset_info, lex_user->host.str, host))
|
||||
{
|
||||
if (!replace_proc_table(thd,grant_proc,tables[4].table,*lex_user,
|
||||
if (!replace_routine_table(thd,grant_proc,tables[4].table,*lex_user,
|
||||
grant_proc->db,
|
||||
grant_proc->tname,
|
||||
is_proc,
|
||||
~0, 1))
|
||||
{
|
||||
revoked= 1;
|
||||
@ -5146,11 +5207,13 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
|
||||
< 0 Error. Error message not yet sent.
|
||||
*/
|
||||
|
||||
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 is_proc)
|
||||
{
|
||||
uint counter, revoked;
|
||||
int result;
|
||||
TABLE_LIST tables[GRANT_TABLES];
|
||||
HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash;
|
||||
DBUG_ENTER("sp_revoke_privileges");
|
||||
|
||||
if ((result= open_grant_tables(thd, tables)))
|
||||
@ -5162,10 +5225,9 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name)
|
||||
/* Remove procedure access */
|
||||
do
|
||||
{
|
||||
for (counter= 0, revoked= 0 ; counter < proc_priv_hash.records ; )
|
||||
for (counter= 0, revoked= 0 ; counter < hash->records ; )
|
||||
{
|
||||
GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(&proc_priv_hash,
|
||||
counter);
|
||||
GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(hash, counter);
|
||||
if (!my_strcasecmp(system_charset_info, grant_proc->db, sp_db) &&
|
||||
!my_strcasecmp(system_charset_info, grant_proc->tname, sp_name))
|
||||
{
|
||||
@ -5174,8 +5236,9 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name)
|
||||
lex_user.user.length= strlen(grant_proc->user);
|
||||
lex_user.host.str= grant_proc->host.hostname;
|
||||
lex_user.host.length= strlen(grant_proc->host.hostname);
|
||||
if (!replace_proc_table(thd,grant_proc,tables[4].table,lex_user,
|
||||
grant_proc->db, grant_proc->tname, ~0, 1))
|
||||
if (!replace_routine_table(thd,grant_proc,tables[4].table,lex_user,
|
||||
grant_proc->db, grant_proc->tname,
|
||||
is_proc, ~0, 1))
|
||||
{
|
||||
revoked= 1;
|
||||
continue;
|
||||
@ -5211,7 +5274,8 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name)
|
||||
< 0 Error. Error message not yet sent.
|
||||
*/
|
||||
|
||||
bool sp_grant_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)
|
||||
{
|
||||
LEX_USER *combo;
|
||||
TABLE_LIST tables[1];
|
||||
@ -5249,7 +5313,7 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name)
|
||||
thd->lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
|
||||
bzero((char*) &thd->lex->mqh, sizeof(thd->lex->mqh));
|
||||
|
||||
result= mysql_procedure_grant(thd, tables, user_list,
|
||||
result= mysql_routine_grant(thd, tables, is_proc, user_list,
|
||||
DEFAULT_CREATE_PROC_ACLS, 0, 1);
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ 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,
|
||||
List <LEX_COLUMN> &column_list, ulong rights,
|
||||
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,
|
||||
bool revoke, bool no_error);
|
||||
ACL_USER *check_acl_user(LEX_USER *user_name, uint *acl_acl_userdx);
|
||||
@ -201,8 +201,8 @@ bool check_grant_column (THD *thd, GRANT_INFO *grant,
|
||||
bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant,
|
||||
const char* db_name, const char *table_name,
|
||||
Field_iterator *fields);
|
||||
bool check_grant_procedure(THD *thd, ulong want_access,
|
||||
TABLE_LIST *procs, bool no_error);
|
||||
bool check_grant_routine(THD *thd, ulong want_access,
|
||||
TABLE_LIST *procs, bool is_proc, bool no_error);
|
||||
bool check_grant_db(THD *thd,const char *db);
|
||||
ulong get_table_grant(THD *thd, TABLE_LIST *table);
|
||||
ulong get_column_grant(THD *thd, GRANT_INFO *grant,
|
||||
@ -217,9 +217,12 @@ bool mysql_rename_user(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,
|
||||
const char *db, const char *table);
|
||||
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 check_routine_level_acl(THD *thd, const char *db, const char *name);
|
||||
bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
|
||||
bool is_proc);
|
||||
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
|
||||
#define check_grant(A,B,C,D,E,F) 0
|
||||
|
@ -3673,17 +3673,20 @@ unsent_create_error:
|
||||
}
|
||||
if (first_table)
|
||||
{
|
||||
if (!lex->columns.elements &&
|
||||
sp_exists_routine(thd, all_tables, 1, 1))
|
||||
if (lex->type == TYPE_ENUM_PROCEDURE ||
|
||||
lex->type == TYPE_ENUM_FUNCTION)
|
||||
{
|
||||
uint grants= lex->all_privileges
|
||||
? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL)
|
||||
: lex->grant;
|
||||
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;
|
||||
res= mysql_procedure_grant(thd, all_tables, lex->users_list,
|
||||
grants, lex->sql_command == SQLCOM_REVOKE,0);
|
||||
res= mysql_routine_grant(thd, all_tables,
|
||||
lex->type == TYPE_ENUM_PROCEDURE,
|
||||
lex->users_list, grants,
|
||||
lex->sql_command == SQLCOM_REVOKE, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3705,7 +3708,7 @@ unsent_create_error:
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lex->columns.elements)
|
||||
if (lex->columns.elements || lex->type)
|
||||
{
|
||||
my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
|
||||
MYF(0));
|
||||
@ -3987,11 +3990,13 @@ unsent_create_error:
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
/* only add privileges if really neccessary */
|
||||
if (sp_automatic_privileges &&
|
||||
check_procedure_access(thd, DEFAULT_CREATE_PROC_ACLS,
|
||||
db, name, 1))
|
||||
check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
|
||||
db, name,
|
||||
lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1))
|
||||
{
|
||||
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,
|
||||
ER_PROC_AUTO_GRANT_FAIL,
|
||||
ER(ER_PROC_AUTO_GRANT_FAIL));
|
||||
@ -4076,8 +4081,8 @@ unsent_create_error:
|
||||
}
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (check_procedure_access(thd, EXECUTE_ACL,
|
||||
sp->m_db.str, sp->m_name.str, 0))
|
||||
if (check_routine_access(thd, EXECUTE_ACL,
|
||||
sp->m_db.str, sp->m_name.str, TRUE, 0))
|
||||
{
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
thd->net.no_send_ok= nsok;
|
||||
@ -4086,8 +4091,8 @@ unsent_create_error:
|
||||
}
|
||||
sp_change_security_context(thd, sp, &save_ctx);
|
||||
if (save_ctx.changed &&
|
||||
check_procedure_access(thd, EXECUTE_ACL,
|
||||
sp->m_db.str, sp->m_name.str, 0))
|
||||
check_routine_access(thd, EXECUTE_ACL,
|
||||
sp->m_db.str, sp->m_name.str, TRUE, 0))
|
||||
{
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
thd->net.no_send_ok= nsok;
|
||||
@ -4189,8 +4194,9 @@ unsent_create_error:
|
||||
}
|
||||
else
|
||||
{
|
||||
if (check_procedure_access(thd, ALTER_PROC_ACL, sp->m_db.str,
|
||||
sp->m_name.str, 0))
|
||||
if (check_routine_access(thd, ALTER_PROC_ACL, sp->m_db.str,
|
||||
sp->m_name.str,
|
||||
lex->sql_command == SQLCOM_ALTER_PROCEDURE, 0))
|
||||
goto error;
|
||||
memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
|
||||
if (!trust_routine_creators && mysql_bin_log.is_open() &&
|
||||
@ -4248,11 +4254,13 @@ unsent_create_error:
|
||||
{
|
||||
db= thd->strdup(sp->m_db.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;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
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,
|
||||
ER_PROC_AUTO_REVOKE_FAIL,
|
||||
@ -4836,8 +4844,8 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
|
||||
|
||||
|
||||
bool
|
||||
check_procedure_access(THD *thd, ulong want_access,char *db, char *name,
|
||||
bool no_errors)
|
||||
check_routine_access(THD *thd, ulong want_access,char *db, char *name,
|
||||
bool is_proc, bool no_errors)
|
||||
{
|
||||
TABLE_LIST tables[1];
|
||||
|
||||
@ -4853,7 +4861,7 @@ check_procedure_access(THD *thd, ulong want_access,char *db, char *name,
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
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
|
||||
|
||||
return FALSE;
|
||||
@ -4874,7 +4882,8 @@ check_procedure_access(THD *thd, ulong want_access,char *db, char *name,
|
||||
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;
|
||||
if (thd->master_access & SHOW_PROC_ACLS)
|
||||
@ -4882,7 +4891,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) ||
|
||||
(save_priv & SHOW_PROC_ACLS))
|
||||
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,
|
||||
definer= get_field(thd->mem_root, proc_table->field[11]);
|
||||
if (!full_access)
|
||||
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;
|
||||
|
||||
if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC &&
|
||||
|
@ -804,7 +804,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
opt_delete_options opt_delete_option varchar nchar nvarchar
|
||||
opt_outer table_list table_name opt_option opt_place
|
||||
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
|
||||
clear_privileges flush_options flush_option
|
||||
equal optional_braces opt_key_definition key_usage_list2
|
||||
@ -7907,9 +7907,36 @@ revoke:
|
||||
;
|
||||
|
||||
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
|
||||
@ -7919,11 +7946,50 @@ revoke_command:
|
||||
;
|
||||
|
||||
grant:
|
||||
GRANT clear_privileges grant_privileges ON opt_table TO_SYM grant_list
|
||||
require_clause grant_options
|
||||
{ Lex->sql_command= SQLCOM_GRANT; }
|
||||
GRANT clear_privileges grant_command
|
||||
{}
|
||||
;
|
||||
|
||||
grant_command:
|
||||
grant_privileges ON opt_table grant_ident TO_SYM grant_list
|
||||
require_clause grant_options
|
||||
{
|
||||
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:
|
||||
object_privilege_list { }
|
||||
| ALL opt_privileges
|
||||
@ -8016,7 +8082,7 @@ require_list_element:
|
||||
}
|
||||
;
|
||||
|
||||
opt_table:
|
||||
grant_ident:
|
||||
'*'
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
|
Reference in New Issue
Block a user