summaryrefslogtreecommitdiff
path: root/sql/sql_acl.cc
diff options
context:
space:
mode:
authorunknown <tsmith@rhel5-ia64-a.mysql.com>2008-03-27 08:20:25 +0100
committerunknown <tsmith@rhel5-ia64-a.mysql.com>2008-03-27 08:20:25 +0100
commit45ebe9953385f48f99058eaedf448bb6ff8caeaa (patch)
tree1cd9471bfb066e2ed5fdc557a5948b95230098ec /sql/sql_acl.cc
parent27c0540bd8e785499accbd4777bdb5067911cce9 (diff)
parent19afc9d9e75b44c01e254300913b716798c40108 (diff)
downloadmariadb-git-45ebe9953385f48f99058eaedf448bb6ff8caeaa.tar.gz
Merge tsmith@bk-internal.mysql.com:/home/bk/mysql-5.1
into rhel5-ia64-a.mysql.com:/data0/tsmith/build/51 sql/mysqld.cc: Auto merged sql/sql_acl.cc: Auto merged sql/sql_class.cc: Auto merged mysql-test/r/drop.result: SCCS merged mysql-test/t/drop.test: SCCS merged
Diffstat (limited to 'sql/sql_acl.cc')
-rw-r--r--sql/sql_acl.cc105
1 files changed, 83 insertions, 22 deletions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index f84e33cceb8..e20dc71e6cb 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -2785,6 +2785,10 @@ table_error:
}
+/**
+ @retval 0 success
+ @retval -1 error
+*/
static int replace_routine_table(THD *thd, GRANT_NAME *grant_name,
TABLE *table, const LEX_USER &combo,
const char *db, const char *routine_name,
@@ -2806,14 +2810,11 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name,
thd->security_ctx->host_or_ip, NullS);
/*
- The following should always succeed as new users are created before
- this function is called!
+ New users are created before this function is called.
+
+ There may be some cases where a routine's definer is removed but the
+ routine remains.
*/
- if (!find_acl_user(combo.host.str, combo.user.str, FALSE))
- {
- my_error(ER_PASSWORD_NO_MATCH,MYF(0));
- DBUG_RETURN(-1);
- }
table->use_all_columns();
restore_record(table, s->default_values); // Get empty record
@@ -3334,7 +3335,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
}
if (replace_routine_table(thd, grant_name, tables[1].table, *Str,
- db_name, table_name, is_proc, rights, revoke_grant))
+ db_name, table_name, is_proc, rights,
+ revoke_grant) != 0)
{
result= TRUE;
continue;
@@ -5967,11 +5969,11 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
if (!strcmp(lex_user->user.str,user) &&
!strcmp(lex_user->host.str, host))
{
- if (!replace_routine_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,
- ~(ulong)0, 1))
+ ~(ulong)0, 1) == 0)
{
revoked= 1;
continue;
@@ -5997,17 +5999,73 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
}
-/*
- Revoke privileges for all users on a stored procedure
- SYNOPSIS
- sp_revoke_privileges()
+
+/**
+ If the defining user for a routine does not exist, then the ACL lookup
+ code should raise two errors which we should intercept. We convert the more
+ descriptive error into a warning, and consume the other.
+
+ If any other errors are raised, then we set a flag that should indicate
+ that there was some failure we should complain at a higher level.
+*/
+class Silence_routine_definer_errors : public Internal_error_handler
+{
+public:
+ Silence_routine_definer_errors()
+ : is_grave(FALSE)
+ {}
+
+ virtual ~Silence_routine_definer_errors()
+ {}
+
+ virtual bool handle_error(uint sql_errno, const char *message,
+ MYSQL_ERROR::enum_warning_level level,
+ THD *thd);
+
+ bool has_errors() { return is_grave; }
+
+private:
+ bool is_grave;
+};
+
+bool
+Silence_routine_definer_errors::handle_error(uint sql_errno,
+ const char *message,
+ MYSQL_ERROR::enum_warning_level level,
+ THD *thd)
+{
+ if (level == MYSQL_ERROR::WARN_LEVEL_ERROR)
+ {
+ switch (sql_errno)
+ {
+ case ER_NONEXISTING_PROC_GRANT:
+ /* Convert the error into a warning. */
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, sql_errno, message);
+ return TRUE;
+ default:
+ is_grave= TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+/**
+ Revoke privileges for all users on a stored procedure. Use an error handler
+ that converts errors about missing grants into warnings.
+
+ @param
thd The current thread.
+ @param
db DB of the stored procedure
+ @param
name Name of the stored procedure
- RETURN
+ @retval
0 OK.
+ @retval
< 0 Error. Error message not yet sent.
*/
@@ -6018,11 +6076,15 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
int result;
TABLE_LIST tables[GRANT_TABLES];
HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash;
+ Silence_routine_definer_errors error_handler;
DBUG_ENTER("sp_revoke_privileges");
if ((result= open_grant_tables(thd, tables)))
DBUG_RETURN(result != 1);
+ /* Be sure to pop this before exiting this scope! */
+ thd->push_internal_handler(&error_handler);
+
rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock));
@@ -6049,14 +6111,14 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
grant_proc->host.hostname : (char*)"";
lex_user.host.length= grant_proc->host.hostname ?
strlen(grant_proc->host.hostname) : 0;
- if (!replace_routine_table(thd,grant_proc,tables[4].table,lex_user,
- grant_proc->db, grant_proc->tname,
- is_proc, ~(ulong)0, 1))
+
+ if (replace_routine_table(thd,grant_proc,tables[4].table,lex_user,
+ grant_proc->db, grant_proc->tname,
+ is_proc, ~(ulong)0, 1) == 0)
{
revoked= 1;
continue;
}
- result= -1; // Something went wrong
}
counter++;
}
@@ -6066,10 +6128,9 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
- if (result)
- my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
+ thd->pop_internal_handler();
- DBUG_RETURN(result);
+ DBUG_RETURN(error_handler.has_errors());
}