Commit d6370cb5 authored by Vicențiu Ciorbaru's avatar Vicențiu Ciorbaru

cleanup: execute test_if_create_new_users as part of grant_stage0

There is identical logic for all grant functions. If a grant grants to
non existant users they are created if the SQL mode is not
NO_AUTO_CREATE_USER *and* the user granting has rights to create users.

This check is done via test_if_create_new_users. Refactor all code such
that this check is only done in one (or three places for-now till more
refactoring happens).
parent 9859ce04
...@@ -7946,13 +7946,12 @@ static bool check_if_auth_can_be_changed(LEX_USER *user, THD *thd) ...@@ -7946,13 +7946,12 @@ static bool check_if_auth_can_be_changed(LEX_USER *user, THD *thd)
static int mysql_table_grant(THD *thd, TABLE_LIST *table_list, static int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
List <LEX_USER> &user_list, List <LEX_USER> &user_list,
List <LEX_COLUMN> &columns, privilege_t rights, List <LEX_COLUMN> &columns, privilege_t rights,
bool revoke_grant) bool revoke_grant, bool create_new_users)
{ {
privilege_t column_priv(NO_ACL); privilege_t column_priv(NO_ACL);
int result, res; int result, res;
List_iterator <LEX_USER> str_list (user_list); List_iterator <LEX_USER> str_list (user_list);
LEX_USER *Str, *tmp_Str; LEX_USER *Str, *tmp_Str;
bool create_new_users=0;
const char *db_name, *table_name; const char *db_name, *table_name;
DBUG_ENTER("mysql_table_grant"); DBUG_ENTER("mysql_table_grant");
...@@ -8050,8 +8049,6 @@ static int mysql_table_grant(THD *thd, TABLE_LIST *table_list, ...@@ -8050,8 +8049,6 @@ static int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(result != 1); DBUG_RETURN(result != 1);
} }
if (!revoke_grant)
create_new_users= test_if_create_new_users(thd);
mysql_rwlock_wrlock(&LOCK_grant); mysql_rwlock_wrlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock); mysql_mutex_lock(&acl_cache->lock);
MEM_ROOT *old_root= thd->mem_root; MEM_ROOT *old_root= thd->mem_root;
...@@ -8209,10 +8206,10 @@ static int mysql_table_grant(THD *thd, TABLE_LIST *table_list, ...@@ -8209,10 +8206,10 @@ static int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
static bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, static bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list,
const Sp_handler *sph, const Sp_handler *sph,
List <LEX_USER> &user_list, privilege_t rights, List <LEX_USER> &user_list, privilege_t rights,
bool revoke_grant, bool write_to_binlog) bool revoke_grant, bool write_to_binlog,
bool create_new_users)
{ {
List_iterator<LEX_USER> it(user_list); List_iterator<LEX_USER> it(user_list);
bool create_new_users= 0;
int result; int result;
const char *db_name, *table_name; const char *db_name, *table_name;
DBUG_ENTER("mysql_routine_grant"); DBUG_ENTER("mysql_routine_grant");
...@@ -8237,8 +8234,6 @@ static bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, ...@@ -8237,8 +8234,6 @@ static bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list,
DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
if (!revoke_grant)
create_new_users= test_if_create_new_users(thd);
mysql_rwlock_wrlock(&LOCK_grant); mysql_rwlock_wrlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock); mysql_mutex_lock(&acl_cache->lock);
MEM_ROOT *old_root= thd->mem_root; MEM_ROOT *old_root= thd->mem_root;
...@@ -12674,6 +12669,7 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, ...@@ -12674,6 +12669,7 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
TABLE_LIST tables[1]; TABLE_LIST tables[1];
List<LEX_USER> resolved_user_list; List<LEX_USER> resolved_user_list;
bool result; bool result;
bool create_new_users;
ACL_USER *au; ACL_USER *au;
Dummy_error_handler error_handler; Dummy_error_handler error_handler;
DBUG_ENTER("sp_grant_privileges"); DBUG_ENTER("sp_grant_privileges");
...@@ -12715,6 +12711,7 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, ...@@ -12715,6 +12711,7 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
thd->lex->account_options.reset(); thd->lex->account_options.reset();
create_new_users= test_if_create_new_users(thd);
/* /*
Only care about whether the operation failed or succeeded Only care about whether the operation failed or succeeded
...@@ -12722,7 +12719,8 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, ...@@ -12722,7 +12719,8 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
*/ */
thd->push_internal_handler(&error_handler); thd->push_internal_handler(&error_handler);
result= mysql_routine_grant(thd, tables, sph, resolved_user_list, result= mysql_routine_grant(thd, tables, sph, resolved_user_list,
DEFAULT_CREATE_PROC_ACLS, FALSE, FALSE); DEFAULT_CREATE_PROC_ACLS, FALSE, FALSE,
create_new_users);
thd->pop_internal_handler(); thd->pop_internal_handler();
DBUG_RETURN(result); DBUG_RETURN(result);
} }
...@@ -13042,6 +13040,9 @@ bool Sql_cmd_grant::grant_stage0(THD *thd) ...@@ -13042,6 +13040,9 @@ bool Sql_cmd_grant::grant_stage0(THD *thd)
resolved_user->auth= tmp_user->auth; resolved_user->auth= tmp_user->auth;
m_resolved_users.push_back(resolved_user); m_resolved_users.push_back(resolved_user);
} }
m_create_new_users= is_revoke() ? false : test_if_create_new_users(thd);
return false; return false;
} }
...@@ -13075,9 +13076,8 @@ bool Sql_cmd_grant_proxy::check_access_proxy(THD *thd, ...@@ -13075,9 +13076,8 @@ bool Sql_cmd_grant_proxy::check_access_proxy(THD *thd,
bool Sql_cmd_grant_proxy::execute(THD *thd) bool Sql_cmd_grant_proxy::execute(THD *thd)
{ {
bool result; bool result;
bool create_new_users= false; const bool no_auto_create_users= MY_TEST(thd->variables.sql_mode &
bool no_auto_create_users= MY_TEST(thd->variables.sql_mode & MODE_NO_AUTO_CREATE_USER);
MODE_NO_AUTO_CREATE_USER);
Grant_tables tables; Grant_tables tables;
DBUG_ASSERT(thd->lex->first_select_lex()->table_list.first == NULL); DBUG_ASSERT(thd->lex->first_select_lex()->table_list.first == NULL);
...@@ -13097,8 +13097,6 @@ bool Sql_cmd_grant_proxy::execute(THD *thd) ...@@ -13097,8 +13097,6 @@ bool Sql_cmd_grant_proxy::execute(THD *thd)
DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
if (!is_revoke())
create_new_users= test_if_create_new_users(thd);
mysql_rwlock_wrlock(&LOCK_grant); mysql_rwlock_wrlock(&LOCK_grant);
...@@ -13108,7 +13106,7 @@ bool Sql_cmd_grant_proxy::execute(THD *thd) ...@@ -13108,7 +13106,7 @@ bool Sql_cmd_grant_proxy::execute(THD *thd)
result= mysql_grant_proxy(thd, tables, result= mysql_grant_proxy(thd, tables,
m_resolved_users, m_resolved_users,
{m_grant_option, is_revoke()}, {m_grant_option, is_revoke()},
create_new_users, no_auto_create_users); m_create_new_users, no_auto_create_users);
mysql_mutex_unlock(&acl_cache->lock); mysql_mutex_unlock(&acl_cache->lock);
/* Write to binlog if statement succeeded. */ /* Write to binlog if statement succeeded. */
...@@ -13122,7 +13120,7 @@ bool Sql_cmd_grant_proxy::execute(THD *thd) ...@@ -13122,7 +13120,7 @@ bool Sql_cmd_grant_proxy::execute(THD *thd)
if (!is_revoke()) if (!is_revoke())
user_list_reset_mqh(); user_list_reset_mqh();
return false; return result;
#ifdef WITH_WSREP #ifdef WITH_WSREP
wsrep_error_label: wsrep_error_label:
...@@ -13145,7 +13143,67 @@ bool Sql_cmd_grant_object::grant_stage0_exact_object(THD *thd, ...@@ -13145,7 +13143,67 @@ bool Sql_cmd_grant_object::grant_stage0_exact_object(THD *thd,
} }
bool Sql_cmd_grant_table::execute_exact_table(THD *thd, TABLE_LIST *table) bool Sql_cmd_grant_table::execute_grant_database(THD *thd)
{
Grant_tables tables;
bool result;
const bool no_auto_create_users= MY_TEST(thd->variables.sql_mode &
MODE_NO_AUTO_CREATE_USER);
char tmp_db[SAFE_NAME_LEN+1];
const char *db= m_gp.db().str;
/* Convert database name to lower case if lower_case_table_names. */
if (lower_case_table_names)
{
char *end= strnmov(tmp_db, db, sizeof(tmp_db));
if (end >= tmp_db + sizeof(tmp_db))
{
my_error(ER_WRONG_DB_NAME ,MYF(0), db);
return true;
}
my_casedn_str(files_charset_info, tmp_db);
db= tmp_db;
}
/* Only allow DB level grants. */
if ((m_gp.object_privilege() & DB_ACLS) != m_gp.object_privilege())
{
my_error(ER_WRONG_USAGE, MYF(0), "DB GRANT", "GLOBAL PRIVILEGES");
return true;
}
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
if (tables.open_and_lock(thd, Table_user | Table_db, TL_WRITE))
return true;
mysql_rwlock_wrlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock);
grant_version++;
result= mysql_grant_db(thd, tables,
m_resolved_users, db,
{m_gp.object_privilege(), is_revoke()},
m_create_new_users, no_auto_create_users);
mysql_mutex_unlock(&acl_cache->lock);
/* Write to binlog if statement succeeded. */
if (!result)
result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
mysql_rwlock_unlock(&LOCK_grant);
if (!result)
my_ok(thd);
return result;
#ifdef WITH_WSREP
wsrep_error_label:
return true;
#endif // WITH_WSREP
}
bool Sql_cmd_grant_table::execute_grant_table(THD *thd, TABLE_LIST *table)
{ {
LEX *lex= thd->lex; LEX *lex= thd->lex;
privilege_t priv= m_gp.object_privilege() | m_gp.column_privilege_total() | privilege_t priv= m_gp.object_privilege() | m_gp.column_privilege_total() |
...@@ -13157,7 +13215,7 @@ bool Sql_cmd_grant_table::execute_exact_table(THD *thd, TABLE_LIST *table) ...@@ -13157,7 +13215,7 @@ bool Sql_cmd_grant_table::execute_exact_table(THD *thd, TABLE_LIST *table)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
return mysql_table_grant(thd, lex->query_tables, lex->users_list, return mysql_table_grant(thd, lex->query_tables, lex->users_list,
m_gp.columns(), m_gp.object_privilege(), m_gp.columns(), m_gp.object_privilege(),
is_revoke()); is_revoke(), m_create_new_users);
#ifdef WITH_WSREP #ifdef WITH_WSREP
wsrep_error_label: wsrep_error_label:
return true; return true;
...@@ -13191,10 +13249,12 @@ bool Sql_cmd_grant_sp::execute(THD *thd) ...@@ -13191,10 +13249,12 @@ bool Sql_cmd_grant_sp::execute(THD *thd)
/* Conditionally writes to binlog */ /* Conditionally writes to binlog */
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
if (mysql_routine_grant(thd, lex->query_tables, &m_sph, if (mysql_routine_grant(thd, lex->query_tables, &m_sph,
m_resolved_users, grants, m_resolved_users, grants,
is_revoke(), true)) is_revoke(), true, m_create_new_users))
return true; return true;
my_ok(thd); my_ok(thd);
return false; return false;
#ifdef WITH_WSREP #ifdef WITH_WSREP
...@@ -13204,19 +13264,51 @@ bool Sql_cmd_grant_sp::execute(THD *thd) ...@@ -13204,19 +13264,51 @@ bool Sql_cmd_grant_sp::execute(THD *thd)
} }
bool Sql_cmd_grant_table::execute_table_mask(THD *thd) bool Sql_cmd_grant_table::execute_grant_global(THD *thd)
{ {
LEX *lex= thd->lex;
Grant_tables tables; Grant_tables tables;
bool result; bool result;
bool create_new_users= false; const bool no_auto_create_users= MY_TEST(thd->variables.sql_mode &
bool no_auto_create_users= MY_TEST(thd->variables.sql_mode & MODE_NO_AUTO_CREATE_USER);
MODE_NO_AUTO_CREATE_USER);
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
if (tables.open_and_lock(thd, Table_user, TL_WRITE))
return true;
mysql_rwlock_wrlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock);
grant_version++;
result= mysql_grant_global(thd, tables,
m_resolved_users,
{m_gp.object_privilege(), is_revoke()},
m_create_new_users,
no_auto_create_users);
mysql_mutex_unlock(&acl_cache->lock);
/* Write to binlog if statement succeeded. */
if (!result)
result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
mysql_rwlock_unlock(&LOCK_grant);
if (!result)
my_ok(thd);
return result;
#ifdef WITH_WSREP
wsrep_error_label:
return true;
#endif // WITH_WSREP
}
bool Sql_cmd_grant_table::execute_grant_database_or_global(THD *thd)
{
bool result;
privilege_t required_access= m_gp.object_privilege() | privilege_t required_access= m_gp.object_privilege() |
m_gp.column_privilege_total() | m_gp.column_privilege_total() |
GRANT_ACL; GRANT_ACL;
DBUG_ASSERT(lex->first_select_lex()->table_list.first == NULL); DBUG_ASSERT(thd->lex->first_select_lex()->table_list.first == NULL);
if (check_access(thd, required_access, m_gp.db().str, NULL, NULL, 1, 0)) if (check_access(thd, required_access, m_gp.db().str, NULL, NULL, 1, 0))
return true; return true;
...@@ -13224,9 +13316,6 @@ bool Sql_cmd_grant_table::execute_table_mask(THD *thd) ...@@ -13224,9 +13316,6 @@ bool Sql_cmd_grant_table::execute_table_mask(THD *thd)
if (grant_stage0(thd)) if (grant_stage0(thd))
return true; return true;
if (!is_revoke())
create_new_users= test_if_create_new_users(thd);
if (m_gp.columns().elements) // e.g. GRANT SELECT (a) ON *.* if (m_gp.columns().elements) // e.g. GRANT SELECT (a) ON *.*
{ {
my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER_THD(thd, ER_ILLEGAL_GRANT_FOR_TABLE), my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER_THD(thd, ER_ILLEGAL_GRANT_FOR_TABLE),
...@@ -13234,94 +13323,27 @@ bool Sql_cmd_grant_table::execute_table_mask(THD *thd) ...@@ -13234,94 +13323,27 @@ bool Sql_cmd_grant_table::execute_table_mask(THD *thd)
return true; return true;
} }
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
if (m_gp.db().length) if (m_gp.db().length)
{ result= execute_grant_database(thd);
char tmp_db[SAFE_NAME_LEN+1];
const char *db= m_gp.db().str;
/* Convert database name to lower case if lower_case_table_names. */
if (lower_case_table_names)
{
char *end= strnmov(tmp_db, db, sizeof(tmp_db));
if (end >= tmp_db + sizeof(tmp_db))
{
my_error(ER_WRONG_DB_NAME ,MYF(0), db);
return true;
}
my_casedn_str(files_charset_info, tmp_db);
db=tmp_db;
}
/* Only allow DB level grants. */
if ((m_gp.object_privilege() & DB_ACLS) != m_gp.object_privilege())
{
my_error(ER_WRONG_USAGE, MYF(0), "DB GRANT", "GLOBAL PRIVILEGES");
return true;
}
if (tables.open_and_lock(thd, Table_user | Table_db, TL_WRITE))
return true;
mysql_rwlock_wrlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock);
grant_version++;
result= mysql_grant_db(thd, tables,
m_resolved_users, db,
{m_gp.object_privilege(), is_revoke()},
create_new_users, no_auto_create_users);
mysql_mutex_unlock(&acl_cache->lock);
/* Write to binlog if statement succeeded. */
if (!result)
result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
mysql_rwlock_unlock(&LOCK_grant);
if (!result)
my_ok(thd);
}
else else
{ result= execute_grant_global(thd);
if (tables.open_and_lock(thd, Table_user, TL_WRITE)) if (result)
return true; return true;
mysql_rwlock_wrlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock);
grant_version++;
/* Conditionally writes to binlog */
result= mysql_grant_global(thd, tables,
m_resolved_users,
{m_gp.object_privilege(), is_revoke()},
create_new_users,
no_auto_create_users);
mysql_mutex_unlock(&acl_cache->lock);
/* Write to binlog if statement succeeded. */
if (!result)
result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
mysql_rwlock_unlock(&LOCK_grant);
if (!result)
my_ok(thd);
}
if (!is_revoke()) if (!result && !is_revoke())
user_list_reset_mqh(); user_list_reset_mqh();
return false; return false;
#ifdef WITH_WSREP
wsrep_error_label:
return true;
#endif // WITH_WSREP
} }
bool Sql_cmd_grant_table::execute(THD *thd) bool Sql_cmd_grant_table::execute(THD *thd)
{ {
TABLE_LIST *table= thd->lex->first_select_lex()->table_list.first; TABLE_LIST *table= thd->lex->first_select_lex()->table_list.first;
return table ? execute_exact_table(thd, table) : if (table)
execute_table_mask(thd); return execute_grant_table(thd, table);
return execute_grant_database_or_global(thd);
} }
......
...@@ -348,6 +348,7 @@ class Sql_cmd_grant: public Sql_cmd ...@@ -348,6 +348,7 @@ class Sql_cmd_grant: public Sql_cmd
{ {
protected: protected:
enum_sql_command m_command; enum_sql_command m_command;
bool m_create_new_users;
List<LEX_USER> m_resolved_users; List<LEX_USER> m_resolved_users;
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
void warn_hostname_requires_resolving(THD *thd, List<LEX_USER> &list); void warn_hostname_requires_resolving(THD *thd, List<LEX_USER> &list);
...@@ -356,7 +357,7 @@ class Sql_cmd_grant: public Sql_cmd ...@@ -356,7 +357,7 @@ class Sql_cmd_grant: public Sql_cmd
#endif #endif
public: public:
Sql_cmd_grant(enum_sql_command command) Sql_cmd_grant(enum_sql_command command)
:m_command(command) :m_command(command), m_create_new_users(false)
{ } { }
bool is_revoke() const { return m_command == SQLCOM_REVOKE; } bool is_revoke() const { return m_command == SQLCOM_REVOKE; }
enum_sql_command sql_command_code() const { return m_command; } enum_sql_command sql_command_code() const { return m_command; }
...@@ -394,8 +395,10 @@ class Sql_cmd_grant_object: public Sql_cmd_grant ...@@ -394,8 +395,10 @@ class Sql_cmd_grant_object: public Sql_cmd_grant
class Sql_cmd_grant_table: public Sql_cmd_grant_object class Sql_cmd_grant_table: public Sql_cmd_grant_object
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
bool execute_table_mask(THD *thd); bool execute_grant_database_or_global(THD *thd);
bool execute_exact_table(THD *thd, TABLE_LIST *table); bool execute_grant_global(THD *thd);
bool execute_grant_database(THD *thd);
bool execute_grant_table(THD *thd, TABLE_LIST *table);
#endif #endif
public: public:
Sql_cmd_grant_table(enum_sql_command command, Grant_privilege &grant) Sql_cmd_grant_table(enum_sql_command command, Grant_privilege &grant)
......
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