Commit a701426b authored by Sergei Golubchik's avatar Sergei Golubchik

cleanup: refactor grant table classes in sql_acl.cc

move all backward compatibility related code into User_table,
the caller should not know or care anymore.

Other tables (Db_table, etc) are *not* refactored.

For consistency with other updates, setting a default role
no longer errors out when the mysql.user table is too old.
parent 3df7287d
...@@ -15,7 +15,6 @@ create role test_role; ...@@ -15,7 +15,6 @@ create role test_role;
create user test_user@localhost; create user test_user@localhost;
grant test_role to test_user@localhost; grant test_role to test_user@localhost;
set default role test_role for root@localhost; set default role test_role for root@localhost;
ERROR HY000: Column count of mysql.user is wrong. Expected 46, found 45. Created with MariaDB MYSQL_VERSION_ID, now running MYSQL_VERSION_ID. Please use mysql_upgrade to fix this error
drop role test_role; drop role test_role;
drop user test_user@localhost; drop user test_user@localhost;
alter table user add column default_role char(80) binary default '' not null alter table user add column default_role char(80) binary default '' not null
......
...@@ -29,8 +29,8 @@ after password_expired; ...@@ -29,8 +29,8 @@ after password_expired;
create role test_role; create role test_role;
create user test_user@localhost; create user test_user@localhost;
grant test_role to test_user@localhost; grant test_role to test_user@localhost;
--replace_regex /10\d\d\d\d/MYSQL_VERSION_ID/ #--replace_regex /10\d\d\d\d/MYSQL_VERSION_ID/
--error ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE #--error ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE
set default role test_role for root@localhost; set default role test_role for root@localhost;
drop role test_role; drop role test_role;
drop user test_user@localhost; drop user test_user@localhost;
......
...@@ -697,6 +697,19 @@ static const int Table_procs_priv= 1 << PROCS_PRIV_TABLE; ...@@ -697,6 +697,19 @@ static const int Table_procs_priv= 1 << PROCS_PRIV_TABLE;
static const int Table_proxies_priv= 1 << PROXIES_PRIV_TABLE; static const int Table_proxies_priv= 1 << PROXIES_PRIV_TABLE;
static const int Table_roles_mapping= 1 << ROLES_MAPPING_TABLE; static const int Table_roles_mapping= 1 << ROLES_MAPPING_TABLE;
/**
Choose from either native or old password plugins when assigning a password
*/
static LEX_CSTRING &guess_auth_plugin(THD *thd, size_t password_len)
{
if (thd->variables.old_passwords == 1 ||
password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
return old_password_plugin_name;
else
return native_password_plugin_name;
}
/** /**
Base class representing a generic grant table from the mysql database. Base class representing a generic grant table from the mysql database.
...@@ -718,42 +731,21 @@ class Grant_table_base ...@@ -718,42 +731,21 @@ class Grant_table_base
/* Initializes the READ_RECORD structure provided as a parameter /* Initializes the READ_RECORD structure provided as a parameter
to read through the whole table, with all columns available. Cleaning up to read through the whole table, with all columns available. Cleaning up
is the caller's job. */ is the caller's job. */
bool init_read_record(READ_RECORD* info, THD* thd) const bool init_read_record(READ_RECORD* info) const
{ {
DBUG_ASSERT(tl.table); DBUG_ASSERT(tl.table);
bool result= ::init_read_record(info, thd, tl.table, NULL, NULL, 1, bool result= ::init_read_record(info, tl.table->in_use, tl.table,
true, false); NULL, NULL, 1, true, false);
if (!result) if (!result)
tl.table->use_all_columns(); tl.table->use_all_columns();
return result; return result;
} }
/* Return the number of privilege columns for this table. */
uint num_privileges() const { return num_privilege_cols; }
/* Return a privilege column by index. */
Field* priv_field(uint privilege_idx) const
{
DBUG_ASSERT(privilege_idx < num_privileges());
return tl.table->field[start_privilege_column + privilege_idx];
}
/* Fetch the privileges from the table as a set of bits. The first column
is represented by the first bit in the result, the second column by the
second bit, etc. */
ulong get_access() const
{
return get_access(start_privilege_column,
start_privilege_column + num_privileges() - 1);
}
/* Return the underlying TABLE handle. */ /* Return the underlying TABLE handle. */
TABLE* table() const TABLE* table() const { return tl.table; }
{
return tl.table;
}
/** Check if the table was opened, issue an error otherwise. */ /** Check if the table was opened, issue an error otherwise. */
int no_such_table() const bool no_such_table() const
{ {
if (table_exists()) if (table_exists())
return 0; return 0;
...@@ -762,11 +754,21 @@ class Grant_table_base ...@@ -762,11 +754,21 @@ class Grant_table_base
return 1; return 1;
} }
ulong get_access() const
{
ulong access_bits= 0, bit= 1;
for (uint i = start_priv_columns; i < end_priv_columns; i++, bit<<=1)
{
if (get_YN_as_bool(tl.table->field[i]))
access_bits|= bit;
}
return access_bits;
}
protected: protected:
friend class Grant_tables; friend class Grant_tables;
Grant_table_base() : start_privilege_column(0), num_privilege_cols(0) Grant_table_base() : start_priv_columns(0), end_priv_columns(0)
{ {
bzero(&tl, sizeof(tl)); bzero(&tl, sizeof(tl));
}; };
...@@ -782,34 +784,6 @@ class Grant_table_base ...@@ -782,34 +784,6 @@ class Grant_table_base
tl.open_strategy= TABLE_LIST::OPEN_IF_EXISTS; tl.open_strategy= TABLE_LIST::OPEN_IF_EXISTS;
} }
/*
Get all access bits from table between start_field and end_field indices.
IMPLEMENTATION
The record should be already read in table->record[0]. All privileges
are specified as an ENUM(Y,N).
SYNOPSIS
get_access()
start_field_idx The field index at which the first privilege
specification begins.
end_field_idx The field index at which the last privilege
specification is located.
RETURN VALUE
privilege mask
*/
ulong get_access(uint start_field_idx, uint end_field_idx) const
{
ulong access_bits= 0, bit= 1;
for (uint i = start_field_idx; i <= end_field_idx; i++, bit<<=1)
{
if (get_YN_as_bool(tl.table->field[i]))
access_bits|= bit;
}
return access_bits;
}
/* Compute how many privilege columns this table has. This method /* Compute how many privilege columns this table has. This method
can only be called after the table has been opened. can only be called after the table has been opened.
...@@ -822,26 +796,24 @@ class Grant_table_base ...@@ -822,26 +796,24 @@ class Grant_table_base
if (!table_exists()) // Table does not exist or not opened. if (!table_exists()) // Table does not exist or not opened.
return; return;
num_privilege_cols= 0; for (end_priv_columns= 0; end_priv_columns < num_fields(); end_priv_columns++)
for (uint i= 0; i < num_fields(); i++)
{ {
Field *field= tl.table->field[i]; Field *field= tl.table->field[end_priv_columns];
if (num_privilege_cols > 0 && field->real_type() != MYSQL_TYPE_ENUM)
return;
if (field->real_type() == MYSQL_TYPE_ENUM && if (field->real_type() == MYSQL_TYPE_ENUM &&
static_cast<Field_enum*>(field)->typelib->count == 2) static_cast<Field_enum*>(field)->typelib->count == 2)
{ {
num_privilege_cols++; if (!start_priv_columns)
if (num_privilege_cols == 1) start_priv_columns= end_priv_columns;
start_privilege_column= i;
} }
else if (start_priv_columns)
break;
} }
} }
/* The index at which privilege columns start. */ /* The index at which privilege columns start. */
uint start_privilege_column; uint start_priv_columns;
/* The number of privilege columns in the table. */ /* The index after the last privilege column */
uint num_privilege_cols; uint end_priv_columns;
TABLE_LIST tl; TABLE_LIST tl;
}; };
...@@ -849,70 +821,252 @@ class Grant_table_base ...@@ -849,70 +821,252 @@ class Grant_table_base
class User_table: public Grant_table_base class User_table: public Grant_table_base
{ {
public: public:
/* Field getters return NULL if the column is not present in the table. bool init_read_record(READ_RECORD* info) const
This is consistent only if the table is in a supported version. We do {
not guard against corrupt tables. (yet) */ return Grant_table_base::init_read_record(info) || setup_sysvars();
Field* host() const }
{ return get_field(0); }
Field* user() const
{ return get_field(1); }
Field* password() const
{ return have_password() ? NULL : tl.table->field[2]; }
/* Columns after privilege columns. */
Field* ssl_type() const
{ return get_field(start_privilege_column + num_privileges()); }
Field* ssl_cipher() const
{ return get_field(start_privilege_column + num_privileges() + 1); }
Field* x509_issuer() const
{ return get_field(start_privilege_column + num_privileges() + 2); }
Field* x509_subject() const
{ return get_field(start_privilege_column + num_privileges() + 3); }
Field* max_questions() const
{ return get_field(start_privilege_column + num_privileges() + 4); }
Field* max_updates() const
{ return get_field(start_privilege_column + num_privileges() + 5); }
Field* max_connections() const
{ return get_field(start_privilege_column + num_privileges() + 6); }
Field* max_user_connections() const
{ return get_field(start_privilege_column + num_privileges() + 7); }
Field* plugin() const
{ return get_field(start_privilege_column + num_privileges() + 8); }
Field* authentication_string() const
{ return get_field(start_privilege_column + num_privileges() + 9); }
Field* password_expired() const
{ return get_field(start_privilege_column + num_privileges() + 10); }
Field* is_role() const
{ return get_field(start_privilege_column + num_privileges() + 11); }
Field* default_role() const
{ return get_field(start_privilege_column + num_privileges() + 12); }
Field* max_statement_time() const
{ return get_field(start_privilege_column + num_privileges() + 13); }
/* void get_auth(THD *thd, MEM_ROOT *root, const char **plugin, const char **authstr) const
Check if a user entry in the user table is marked as being a role entry {
if (have_password())
{
*authstr= safe_str(::get_field(&acl_memroot, password()));
*plugin= guess_auth_plugin(thd, strlen(*authstr)).str;
}
else
{
*plugin= native_password_plugin_name.str;
*authstr= "";
}
if (this->plugin() && this->authstr())
{
char *tmpstr= ::get_field(&acl_memroot, this->plugin());
if (tmpstr)
{
const char *passw= *authstr;
*plugin= tmpstr;
*authstr= safe_str(::get_field(&acl_memroot, this->authstr()));
IMPLEMENTATION if (*passw)
Access the coresponding column and check the coresponding ENUM of the form {
ENUM('N', 'Y') if (**authstr && strcmp(*authstr, passw))
{
sql_print_warning("'user' entry '%s@%s' has both a password and an "
"authentication plugin specified. The password will be ignored.",
safe_str(get_user(thd->mem_root)), safe_str(get_host(thd->mem_root)));
}
else
*authstr= passw;
}
}
}
}
SYNOPSIS void set_auth(const char *p, size_t pl, const char *as, size_t asl) const
check_is_role() {
form an open table to read the entry from. if (plugin())
The record should be already read in table->record[0] {
if (have_password())
password()->reset();
plugin()->store(p, pl, system_charset_info);
authstr()->store(as, asl, system_charset_info);
}
else
password()->store(as, asl, system_charset_info);
}
RETURN VALUE ulong get_access() const
TRUE if the user is marked as a role
FALSE otherwise
*/
bool check_is_role() const
{ {
/* Table version does not support roles */ ulong access= Grant_table_base::get_access();
if (!is_role()) if ((num_fields() <= 13) && (access & CREATE_ACL))
return false; access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL;
if (num_fields() <= 18)
{
access|= LOCK_TABLES_ACL | CREATE_TMP_ACL | SHOW_DB_ACL;
if (access & FILE_ACL)
access|= REPL_CLIENT_ACL | REPL_SLAVE_ACL;
if (access & PROCESS_ACL)
access|= SUPER_ACL | EXECUTE_ACL;
}
if (num_fields() <= 31 && (access & CREATE_ACL))
access|= (CREATE_VIEW_ACL | SHOW_VIEW_ACL);
if (num_fields() <= 33)
{
if (access & CREATE_ACL)
access|= CREATE_PROC_ACL;
if (access & ALTER_ACL)
access|= ALTER_PROC_ACL;
}
if (num_fields() <= 36 && (access & GRANT_ACL))
access|= CREATE_USER_ACL;
if (num_fields() <= 37 && (access & SUPER_ACL))
access|= EVENT_ACL;
if (num_fields() <= 38 && (access & SUPER_ACL))
access|= TRIGGER_ACL;
if (num_fields() <= 46 && (access & DELETE_ACL))
access|= DELETE_HISTORY_ACL;
return access & GLOBAL_ACLS;
}
return get_YN_as_bool(is_role()); void set_access(ulong rights, bool revoke) const
{
ulong priv= SELECT_ACL;
for (uint i= start_priv_columns; i < end_priv_columns; i++, priv <<= 1)
{
if (priv & rights)
tl.table->field[i]->store(1 + !revoke, 0);
}
} }
char *get_host(MEM_ROOT *root) const
{ return ::get_field(root, tl.table->field[0]); }
int set_host(const char *s, size_t l) const
{ return tl.table->field[0]->store(s, l, system_charset_info); };
char *get_user(MEM_ROOT *root) const
{ return ::get_field(root, tl.table->field[1]); }
int set_user(const char *s, size_t l) const
{ return tl.table->field[1]->store(s, l, system_charset_info); };
SSL_type get_ssl_type () const
{
Field *f= get_field(end_priv_columns, MYSQL_TYPE_ENUM);
return (SSL_type)(f ? f->val_int()-1 : 0);
}
int set_ssl_type (SSL_type x) const
{
if (Field *f= get_field(end_priv_columns, MYSQL_TYPE_ENUM))
return f->store(x+1, 0);
else
return 1;
}
const char* get_ssl_cipher (MEM_ROOT *root) const
{
Field *f= get_field(end_priv_columns + 1, MYSQL_TYPE_BLOB);
return f ? ::get_field(root,f) : 0;
}
int set_ssl_cipher (const char *s, size_t l) const
{
if (Field *f= get_field(end_priv_columns + 1, MYSQL_TYPE_BLOB))
return f->store(s, l, &my_charset_latin1);
else
return 1;
}
const char* get_x509_issuer (MEM_ROOT *root) const
{
Field *f= get_field(end_priv_columns + 2, MYSQL_TYPE_BLOB);
return f ? ::get_field(root,f) : 0;
}
int set_x509_issuer (const char *s, size_t l) const
{
if (Field *f= get_field(end_priv_columns + 2, MYSQL_TYPE_BLOB))
return f->store(s, l, &my_charset_latin1);
else
return 1;
}
const char* get_x509_subject (MEM_ROOT *root) const
{
Field *f= get_field(end_priv_columns + 3, MYSQL_TYPE_BLOB);
return f ? ::get_field(root,f) : 0;
}
int set_x509_subject (const char *s, size_t l) const
{
if (Field *f= get_field(end_priv_columns + 3, MYSQL_TYPE_BLOB))
return f->store(s, l, &my_charset_latin1);
else
return 1;
}
longlong get_max_questions () const
{
Field *f= get_field(end_priv_columns + 4, MYSQL_TYPE_LONG);
return f ? f->val_int() : 0;
}
int set_max_questions (longlong x) const
{
if (Field *f= get_field(end_priv_columns + 4, MYSQL_TYPE_LONG))
return f->store(x, 0);
else
return 1;
}
longlong get_max_updates () const
{
Field *f= get_field(end_priv_columns + 5, MYSQL_TYPE_LONG);
return f ? f->val_int() : 0;
}
int set_max_updates (longlong x) const
{
if (Field *f= get_field(end_priv_columns + 5, MYSQL_TYPE_LONG))
return f->store(x, 0);
else
return 1;
}
longlong get_max_connections () const
{
Field *f= get_field(end_priv_columns + 6, MYSQL_TYPE_LONG);
return f ? f->val_int() : 0;
}
int set_max_connections (longlong x) const
{
if (Field *f= get_field(end_priv_columns + 6, MYSQL_TYPE_LONG))
return f->store(x, 0);
else
return 1;
}
longlong get_max_user_connections () const
{
Field *f= get_field(end_priv_columns + 7, MYSQL_TYPE_LONG);
return f ? f->val_int() : 0;
}
int set_max_user_connections (longlong x) const
{
if (Field *f= get_field(end_priv_columns + 7, MYSQL_TYPE_LONG))
return f->store(x, 0);
else
return 1;
}
double get_max_statement_time () const
{
Field *f= get_field(end_priv_columns + 13, MYSQL_TYPE_NEWDECIMAL);
return f ? f->val_real() : 0;
}
int set_max_statement_time (double x) const
{
if (Field *f= get_field(end_priv_columns + 13, MYSQL_TYPE_NEWDECIMAL))
return f->store(x);
else
return 1;
}
bool get_is_role () const
{
Field *f= get_field(end_priv_columns + 11, MYSQL_TYPE_ENUM);
return f ? f->val_int()-1 : 0;
}
int set_is_role (bool x) const
{
if (Field *f= get_field(end_priv_columns + 11, MYSQL_TYPE_ENUM))
return f->store(x+1, 0);
else
return 1;
}
const char* get_default_role (MEM_ROOT *root) const
{
Field *f= get_field(end_priv_columns + 12, MYSQL_TYPE_STRING);
return f ? ::get_field(root,f) : 0;
}
int set_default_role (const char *s, size_t l) const
{
if (Field *f= get_field(end_priv_columns + 12, MYSQL_TYPE_STRING))
return f->store(s, l, system_charset_info);
else
return 1;
};
private: private:
friend class Grant_tables; friend class Grant_tables;
...@@ -937,19 +1091,72 @@ class User_table: public Grant_table_base ...@@ -937,19 +1091,72 @@ class User_table: public Grant_table_base
doesn't exist. This simplifies checking of table "version", as we don't doesn't exist. This simplifies checking of table "version", as we don't
have to make use of num_fields() any more. have to make use of num_fields() any more.
*/ */
inline Field* get_field(uint field_num) const inline Field* get_field(uint field_num, enum enum_field_types type) const
{ {
if (field_num >= num_fields()) if (field_num >= num_fields())
return NULL; return NULL;
Field *f= tl.table->field[field_num];
return f->real_type() == type ? f : NULL;
}
return tl.table->field[field_num]; int setup_sysvars() const
{
username_char_length= MY_MIN(tl.table->field[1]->char_length(),
USERNAME_CHAR_LENGTH);
if (have_password()) // Password column might be missing. (MySQL 5.7.6+)
{
int password_length= password()->field_length /
password()->charset()->mbmaxlen;
if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
{
sql_print_error("Fatal error: mysql.user table is damaged or in "
"unsupported 3.20 format.");
return 1;
}
mysql_mutex_lock(&LOCK_global_system_variables);
if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH)
{
if (opt_secure_auth)
{
mysql_mutex_unlock(&LOCK_global_system_variables);
sql_print_error("Fatal error: mysql.user table is in old format, "
"but server started with --secure-auth option.");
return 1;
}
mysql_user_table_is_in_short_password_format= true;
if (global_system_variables.old_passwords)
mysql_mutex_unlock(&LOCK_global_system_variables);
else
{
extern sys_var *Sys_old_passwords_ptr;
Sys_old_passwords_ptr->value_origin= sys_var::AUTO;
global_system_variables.old_passwords= 1;
mysql_mutex_unlock(&LOCK_global_system_variables);
sql_print_warning("mysql.user table is not updated to new password format; "
"Disabling new password usage until "
"mysql_fix_privilege_tables is run");
}
tl.table->in_use->variables.old_passwords= 1;
}
else
{
mysql_user_table_is_in_short_password_format= false;
mysql_mutex_unlock(&LOCK_global_system_variables);
}
}
return 0;
} }
/* Normally password column is the third column in the table. If privileges /* Normally password column is the third column in the table. If privileges
start on the third column instead, we are missing the password column. start on the third column instead, we are missing the password column.
This means we are using a MySQL 5.7.6+ data directory. */ This means we are using a MySQL 5.7.6+ data directory. */
bool have_password() const { return start_privilege_column == 2; } bool have_password() const { return start_priv_columns == 3; }
Field* password() const { return tl.table->field[2]; }
Field* plugin() const { return get_field(end_priv_columns + 8, MYSQL_TYPE_STRING); }
Field* authstr() const { return get_field(end_priv_columns + 9, MYSQL_TYPE_BLOB); }
}; };
class Db_table: public Grant_table_base class Db_table: public Grant_table_base
...@@ -1253,7 +1460,6 @@ class Grant_tables ...@@ -1253,7 +1460,6 @@ class Grant_tables
return m_db_table; return m_db_table;
} }
inline const Tables_priv_table& tables_priv_table() const inline const Tables_priv_table& tables_priv_table() const
{ {
return m_tables_priv_table; return m_tables_priv_table;
...@@ -1612,20 +1818,6 @@ bool acl_init(bool dont_read_acl_tables) ...@@ -1612,20 +1818,6 @@ bool acl_init(bool dont_read_acl_tables)
DBUG_RETURN(return_val); DBUG_RETURN(return_val);
} }
/**
Choose from either native or old password plugins when assigning a password
*/
static LEX_CSTRING &guess_auth_plugin(THD *thd, size_t password_len)
{
if (thd->variables.old_passwords == 1 ||
password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
return old_password_plugin_name;
else
return native_password_plugin_name;
}
static void push_new_user(const ACL_USER &user) static void push_new_user(const ACL_USER &user)
{ {
push_dynamic(&acl_users, &user); push_dynamic(&acl_users, &user);
...@@ -1667,7 +1859,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables) ...@@ -1667,7 +1859,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
init_sql_alloc(&acl_memroot, "ACL", ACL_ALLOC_BLOCK_SIZE, 0, MYF(0)); init_sql_alloc(&acl_memroot, "ACL", ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
if (host_table.table_exists()) // "host" table may not exist (e.g. in MySQL 5.6.7+) if (host_table.table_exists()) // "host" table may not exist (e.g. in MySQL 5.6.7+)
{ {
if (host_table.init_read_record(&read_record_info, thd)) if (host_table.init_read_record(&read_record_info))
DBUG_RETURN(true); DBUG_RETURN(true);
while (!(read_record_info.read_record())) while (!(read_record_info.read_record()))
{ {
...@@ -1721,266 +1913,84 @@ static bool acl_load(THD *thd, const Grant_tables& tables) ...@@ -1721,266 +1913,84 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
freeze_size(&acl_hosts); freeze_size(&acl_hosts);
const User_table& user_table= tables.user_table(); const User_table& user_table= tables.user_table();
if (user_table.init_read_record(&read_record_info, thd)) if (user_table.init_read_record(&read_record_info))
DBUG_RETURN(true); DBUG_RETURN(true);
username_char_length= MY_MIN(user_table.user()->char_length(),
USERNAME_CHAR_LENGTH);
if (user_table.password()) // Password column might be missing. (MySQL 5.7.6+)
{
int password_length= user_table.password()->field_length /
user_table.password()->charset()->mbmaxlen;
if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
{
sql_print_error("Fatal error: mysql.user table is damaged or in "
"unsupported 3.20 format.");
DBUG_RETURN(TRUE);
}
DBUG_PRINT("info",("user table fields: %d, password length: %d",
user_table.num_fields(), password_length));
mysql_mutex_lock(&LOCK_global_system_variables);
if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH)
{
if (opt_secure_auth)
{
mysql_mutex_unlock(&LOCK_global_system_variables);
sql_print_error("Fatal error: mysql.user table is in old format, "
"but server started with --secure-auth option.");
DBUG_RETURN(TRUE);
}
mysql_user_table_is_in_short_password_format= true;
if (global_system_variables.old_passwords)
mysql_mutex_unlock(&LOCK_global_system_variables);
else
{
extern sys_var *Sys_old_passwords_ptr;
Sys_old_passwords_ptr->value_origin= sys_var::AUTO;
global_system_variables.old_passwords= 1;
mysql_mutex_unlock(&LOCK_global_system_variables);
sql_print_warning("mysql.user table is not updated to new password format; "
"Disabling new password usage until "
"mysql_fix_privilege_tables is run");
}
thd->variables.old_passwords= 1;
}
else
{
mysql_user_table_is_in_short_password_format= false;
mysql_mutex_unlock(&LOCK_global_system_variables);
}
}
allow_all_hosts=0; allow_all_hosts=0;
while (!(read_record_info.read_record())) while (!(read_record_info.read_record()))
{ {
ACL_USER user; ACL_USER user;
bool is_role= FALSE; bool is_role= FALSE;
bzero(&user, sizeof(user)); bzero(&user, sizeof(user));
update_hostname(&user.host, get_field(&acl_memroot, user_table.host())); update_hostname(&user.host, user_table.get_host(&acl_memroot));
char *username= safe_str(get_field(&acl_memroot, user_table.user())); char *username= safe_str(user_table.get_user(&acl_memroot));
user.user.str= username; user.user.str= username;
user.user.length= strlen(username); user.user.length= strlen(username);
/* is_role= user_table.get_is_role();
If the user entry is a role, skip password and hostname checks
A user can not log in with a role so some checks are not necessary
*/
is_role= user_table.check_is_role();
if (is_role && is_invalid_role_name(username))
{
thd->clear_error(); // the warning is still issued
continue;
}
if (!is_role && check_no_resolve &&
hostname_requires_resolving(user.host.hostname))
{
sql_print_warning("'user' entry '%s@%s' "
"ignored in --skip-name-resolve mode.", user.user.str,
safe_str(user.host.hostname));
continue;
}
if (user_table.password())
{
const char *p= safe_str(get_field(&acl_memroot, user_table.password()));
user.auth_string.str= p;
user.auth_string.length= strlen(p);
}
else
user.auth_string= empty_clex_str;
user.plugin= guess_auth_plugin(thd, user.auth_string.length);
user.access= user_table.get_access() & GLOBAL_ACLS;
/*
if it is pre 5.0.1 privilege table then map CREATE privilege on
CREATE VIEW & SHOW VIEW privileges
*/
if (user_table.num_fields() <= 31 && (user.access & CREATE_ACL))
user.access|= (CREATE_VIEW_ACL | SHOW_VIEW_ACL);
/*
if it is pre 5.0.2 privilege table then map CREATE/ALTER privilege on
CREATE PROCEDURE & ALTER PROCEDURE privileges
*/
if (user_table.num_fields() <= 33 && (user.access & CREATE_ACL))
user.access|= CREATE_PROC_ACL;
if (user_table.num_fields() <= 33 && (user.access & ALTER_ACL))
user.access|= ALTER_PROC_ACL;
/*
pre 5.0.3 did not have CREATE_USER_ACL
*/
if (user_table.num_fields() <= 36 && (user.access & GRANT_ACL))
user.access|= CREATE_USER_ACL;
user.access= user_table.get_access();
/*
if it is pre 5.1.6 privilege table then map CREATE privilege on
CREATE|ALTER|DROP|EXECUTE EVENT
*/
if (user_table.num_fields() <= 37 && (user.access & SUPER_ACL))
user.access|= EVENT_ACL;
/*
if it is pre 5.1.6 privilege then map TRIGGER privilege on CREATE.
*/
if (user_table.num_fields() <= 38 && (user.access & SUPER_ACL))
user.access|= TRIGGER_ACL;
if (user_table.num_fields() <= 46 && (user.access & DELETE_ACL))
user.access|= DELETE_HISTORY_ACL;
user.sort= get_sort(2, user.host.hostname, user.user.str); user.sort= get_sort(2, user.host.hostname, user.user.str);
user.hostname_length= safe_strlen(user.host.hostname); user.hostname_length= safe_strlen(user.host.hostname);
user.user_resource.user_conn= 0;
user.user_resource.max_statement_time= 0.0;
/* Starting from 4.0.2 we have more fields */
if (user_table.ssl_type())
{
char *ssl_type=get_field(thd->mem_root, user_table.ssl_type());
if (!ssl_type)
user.ssl_type=SSL_TYPE_NONE;
else if (!strcmp(ssl_type, "ANY"))
user.ssl_type=SSL_TYPE_ANY;
else if (!strcmp(ssl_type, "X509"))
user.ssl_type=SSL_TYPE_X509;
else /* !strcmp(ssl_type, "SPECIFIED") */
user.ssl_type=SSL_TYPE_SPECIFIED;
user.ssl_cipher= get_field(&acl_memroot, user_table.ssl_cipher());
user.x509_issuer= get_field(&acl_memroot, user_table.x509_issuer());
user.x509_subject= get_field(&acl_memroot, user_table.x509_subject());
char *ptr = get_field(thd->mem_root, user_table.max_questions());
user.user_resource.questions=ptr ? atoi(ptr) : 0;
ptr = get_field(thd->mem_root, user_table.max_updates());
user.user_resource.updates=ptr ? atoi(ptr) : 0;
ptr = get_field(thd->mem_root, user_table.max_connections());
user.user_resource.conn_per_hour= ptr ? atoi(ptr) : 0;
if (user.user_resource.questions || user.user_resource.updates ||
user.user_resource.conn_per_hour)
mqh_used=1;
if (user_table.max_user_connections()) my_init_dynamic_array(&user.role_grants, sizeof(ACL_ROLE *), 0, 8, MYF(0));
{
/* Starting from 5.0.3 we have max_user_connections field */
ptr= get_field(thd->mem_root, user_table.max_user_connections());
user.user_resource.user_conn= ptr ? atoi(ptr) : 0;
}
if (!is_role && user_table.plugin()) if (is_role)
{
if (is_invalid_role_name(username))
{ {
/* We may have plugin & auth_string fields */ thd->clear_error(); // the warning is still issued
char *tmpstr= get_field(&acl_memroot, user_table.plugin()); continue;
if (tmpstr)
{
LEX_CSTRING password= user.auth_string;
user.plugin.str= tmpstr;
user.plugin.length= strlen(user.plugin.str);
user.auth_string.str=
safe_str(get_field(&acl_memroot,
user_table.authentication_string()));
user.auth_string.length= strlen(user.auth_string.str);
if (password.length)
{
if (user.auth_string.length &&
(user.auth_string.length != password.length ||
memcmp(user.auth_string.str, password.str, password.length)))
{
sql_print_warning("'user' entry '%s@%s' has both a password "
"and an authentication plugin specified. The "
"password will be ignored.",
user.user.str, safe_str(user.host.hostname));
}
else
user.auth_string= password;
}
fix_user_plugin_ptr(&user);
}
} }
if (user_table.max_statement_time()) ACL_ROLE *entry= new (&acl_memroot) ACL_ROLE(&user, &acl_memroot);
{ entry->role_grants = user.role_grants;
/* Starting from 10.1.1 we can have max_statement_time */ my_init_dynamic_array(&entry->parent_grantee,
ptr= get_field(thd->mem_root, sizeof(ACL_USER_BASE *), 0, 8, MYF(0));
user_table.max_statement_time()); my_hash_insert(&acl_roles, (uchar *)entry);
user.user_resource.max_statement_time= ptr ? atof(ptr) : 0.0;
} continue;
} }
else else
{ {
user.ssl_type=SSL_TYPE_NONE; if (check_no_resolve && hostname_requires_resolving(user.host.hostname))
#ifndef TO_BE_REMOVED {
if (user_table.num_fields() <= 13) sql_print_warning("'user' entry '%s@%s' "
{ // Without grant "ignored in --skip-name-resolve mode.", user.user.str,
if (user.access & CREATE_ACL) safe_str(user.host.hostname));
user.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL; continue;
} }
/* Convert old privileges */
user.access|= LOCK_TABLES_ACL | CREATE_TMP_ACL | SHOW_DB_ACL;
if (user.access & FILE_ACL)
user.access|= REPL_CLIENT_ACL | REPL_SLAVE_ACL;
if (user.access & PROCESS_ACL)
user.access|= SUPER_ACL | EXECUTE_ACL;
#endif
}
my_init_dynamic_array(&user.role_grants, sizeof(ACL_ROLE *), 0, 8, MYF(0)); user_table.get_auth(thd, &acl_memroot,
&user.plugin.str, &user.auth_string.str);
/* check default role, if any */ user.plugin.length= strlen(user.plugin.str);
if (!is_role && user_table.default_role()) user.auth_string.length= strlen(user.auth_string.str);
{ fix_user_plugin_ptr(&user);
user.default_rolename.str=
get_field(&acl_memroot, user_table.default_role()); user.ssl_type= user_table.get_ssl_type();
user.default_rolename.length= safe_strlen(user.default_rolename.str); user.ssl_cipher= user_table.get_ssl_cipher(&acl_memroot);
} user.x509_issuer= user_table.get_x509_issuer(&acl_memroot);
user.x509_subject= user_table.get_x509_subject(&acl_memroot);
user.user_resource.questions= user_table.get_max_questions();
user.user_resource.updates= user_table.get_max_updates();
user.user_resource.conn_per_hour= user_table.get_max_connections();
if (user.user_resource.questions || user.user_resource.updates ||
user.user_resource.conn_per_hour)
mqh_used=1;
if (set_user_auth(thd, &user, NULL)) user.user_resource.user_conn= user_table.get_max_user_connections();
{ user.user_resource.max_statement_time= user_table.get_max_statement_time();
thd->clear_error(); // the warning is still issued
continue;
}
if (is_role) user.default_rolename.str= user_table.get_default_role(&acl_memroot);
{ user.default_rolename.length= safe_strlen(user.default_rolename.str);
DBUG_PRINT("info", ("Found role %s", user.user.str));
ACL_ROLE *entry= new (&acl_memroot) ACL_ROLE(&user, &acl_memroot);
entry->role_grants = user.role_grants;
my_init_dynamic_array(&entry->parent_grantee,
sizeof(ACL_USER_BASE *), 0, 8, MYF(0));
my_hash_insert(&acl_roles, (uchar *)entry);
continue; if (set_user_auth(thd, &user, NULL))
{
thd->clear_error(); // the warning is still issued
continue;
}
} }
DBUG_PRINT("info", ("Found user %s", user.user.str));
push_new_user(user); push_new_user(user);
} }
rebuild_acl_users(); rebuild_acl_users();
...@@ -1988,7 +1998,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables) ...@@ -1988,7 +1998,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
freeze_size(&acl_users); freeze_size(&acl_users);
const Db_table& db_table= tables.db_table(); const Db_table& db_table= tables.db_table();
if (db_table.init_read_record(&read_record_info, thd)) if (db_table.init_read_record(&read_record_info))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
while (!(read_record_info.read_record())) while (!(read_record_info.read_record()))
{ {
...@@ -2054,7 +2064,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables) ...@@ -2054,7 +2064,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
const Proxies_priv_table& proxies_priv_table= tables.proxies_priv_table(); const Proxies_priv_table& proxies_priv_table= tables.proxies_priv_table();
if (proxies_priv_table.table_exists()) if (proxies_priv_table.table_exists())
{ {
if (proxies_priv_table.init_read_record(&read_record_info, thd)) if (proxies_priv_table.init_read_record(&read_record_info))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
while (!(read_record_info.read_record())) while (!(read_record_info.read_record()))
{ {
...@@ -2080,7 +2090,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables) ...@@ -2080,7 +2090,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
const Roles_mapping_table& roles_mapping_table= tables.roles_mapping_table(); const Roles_mapping_table& roles_mapping_table= tables.roles_mapping_table();
if (roles_mapping_table.table_exists()) if (roles_mapping_table.table_exists())
{ {
if (roles_mapping_table.init_read_record(&read_record_info, thd)) if (roles_mapping_table.init_read_record(&read_record_info))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
MEM_ROOT temp_root; MEM_ROOT temp_root;
...@@ -3413,17 +3423,8 @@ int acl_set_default_role(THD *thd, const char *host, const char *user, ...@@ -3413,17 +3423,8 @@ int acl_set_default_role(THD *thd, const char *host, const char *user,
/* update the mysql.user table with the new default role */ /* update the mysql.user table with the new default role */
tables.user_table().table()->use_all_columns(); tables.user_table().table()->use_all_columns();
if (!tables.user_table().default_role()) user_table.set_host(host, strlen(host));
{ user_table.set_user(user, strlen(user));
my_error(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE, MYF(0),
table->alias.c_ptr(), DEFAULT_ROLE_COLUMN_IDX + 1,
tables.user_table().num_fields(),
static_cast<int>(table->s->mysql_version), MYSQL_VERSION_ID);
mysql_mutex_unlock(&acl_cache->lock);
goto end;
}
user_table.host()->store(host,(uint) strlen(host), system_charset_info);
user_table.user()->store(user,(uint) strlen(user), system_charset_info);
key_copy((uchar *) user_key, table->record[0], table->key_info, key_copy((uchar *) user_key, table->record[0], table->key_info,
table->key_info->key_length); table->key_info->key_length);
...@@ -3437,9 +3438,8 @@ int acl_set_default_role(THD *thd, const char *host, const char *user, ...@@ -3437,9 +3438,8 @@ int acl_set_default_role(THD *thd, const char *host, const char *user,
goto end; goto end;
} }
store_record(table, record[1]); store_record(table, record[1]);
user_table.default_role()->store(acl_user->default_rolename.str, user_table.set_default_role(acl_user->default_rolename.str,
acl_user->default_rolename.length, acl_user->default_rolename.length);
system_charset_info);
if (unlikely(error= table->file->ha_update_row(table->record[1], if (unlikely(error= table->file->ha_update_row(table->record[1],
table->record[0])) && table->record[0])) &&
error != HA_ERR_RECORD_IS_THE_SAME) error != HA_ERR_RECORD_IS_THE_SAME)
...@@ -3739,15 +3739,14 @@ bool hostname_requires_resolving(const char *hostname) ...@@ -3739,15 +3739,14 @@ bool hostname_requires_resolving(const char *hostname)
static bool update_user_table_password(THD *thd, const User_table& user_table, static bool update_user_table_password(THD *thd, const User_table& user_table,
const ACL_USER &user) const ACL_USER &user)
{ {
CHARSET_INFO *cs= system_charset_info;
char user_key[MAX_KEY_LENGTH]; char user_key[MAX_KEY_LENGTH];
int error; int error;
DBUG_ENTER("update_user_table_password"); DBUG_ENTER("update_user_table_password");
TABLE *table= user_table.table(); TABLE *table= user_table.table();
table->use_all_columns(); table->use_all_columns();
user_table.host()->store(user.host.hostname, user.hostname_length, cs); user_table.set_host(user.host.hostname, user.hostname_length);
user_table.user()->store(user.user.str, user.user.length, cs); user_table.set_user(user.user.str, user.user.length);
key_copy((uchar *) user_key, table->record[0], table->key_info, key_copy((uchar *) user_key, table->record[0], table->key_info,
table->key_info->key_length); table->key_info->key_length);
...@@ -3761,15 +3760,8 @@ static bool update_user_table_password(THD *thd, const User_table& user_table, ...@@ -3761,15 +3760,8 @@ static bool update_user_table_password(THD *thd, const User_table& user_table,
} }
store_record(table,record[1]); store_record(table,record[1]);
if (user_table.plugin()) user_table.set_auth(user.plugin.str, user.plugin.length,
{ user.auth_string.str, user.auth_string.length);
if (user_table.password())
user_table.password()->reset();
user_table.plugin()->store(user.plugin.str, user.plugin.length, cs);
user_table.authentication_string()->store(user.auth_string.str, user.auth_string.length, cs);
}
else
user_table.password()->store(user.auth_string.str, user.auth_string.length, cs);
if (unlikely(error= table->file->ha_update_row(table->record[1], if (unlikely(error= table->file->ha_update_row(table->record[1],
table->record[0])) && table->record[0])) &&
...@@ -3837,20 +3829,9 @@ static int replace_user_table(THD *thd, const User_table &user_table, ...@@ -3837,20 +3829,9 @@ static int replace_user_table(THD *thd, const User_table &user_table,
mysql_mutex_assert_owner(&acl_cache->lock); mysql_mutex_assert_owner(&acl_cache->lock);
/* if the user table is not up to date, we can't handle role updates */
if (!user_table.is_role() && handle_as_role)
{
my_error(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE, MYF(0),
"user", ROLE_ASSIGN_COLUMN_IDX + 1, user_table.num_fields(),
static_cast<int>(table->s->mysql_version), MYSQL_VERSION_ID);
DBUG_RETURN(-1);
}
table->use_all_columns(); table->use_all_columns();
user_table.host()->store(combo->host.str,combo->host.length, user_table.set_host(combo->host.str,combo->host.length);
system_charset_info); user_table.set_user(combo->user.str,combo->user.length);
user_table.user()->store(combo->user.str,combo->user.length,
system_charset_info);
key_copy(user_key, table->record[0], table->key_info, key_copy(user_key, table->record[0], table->key_info,
table->key_info->key_length); table->key_info->key_length);
...@@ -3903,10 +3884,8 @@ static int replace_user_table(THD *thd, const User_table &user_table, ...@@ -3903,10 +3884,8 @@ static int replace_user_table(THD *thd, const User_table &user_table,
old_row_exists = 0; old_row_exists = 0;
restore_record(table,s->default_values); restore_record(table,s->default_values);
user_table.host()->store(combo->host.str,combo->host.length, user_table.set_host(combo->host.str,combo->host.length);
system_charset_info); user_table.set_user(combo->user.str,combo->user.length);
user_table.user()->store(combo->user.str,combo->user.length,
system_charset_info);
} }
else else
{ {
...@@ -3921,23 +3900,22 @@ static int replace_user_table(THD *thd, const User_table &user_table, ...@@ -3921,23 +3900,22 @@ static int replace_user_table(THD *thd, const User_table &user_table,
/* Update table columns with new privileges */ /* Update table columns with new privileges */
ulong priv; user_table.set_access(rights, revoke_grant);
priv = SELECT_ACL;
for (uint i= 0; i < user_table.num_privileges(); i++, priv <<= 1)
{
if (priv & rights)
user_table.priv_field(i)->store(&what, 1, &my_charset_latin1);
}
rights= user_table.get_access(); rights= user_table.get_access();
if (handle_as_role) if (handle_as_role)
{ {
if (old_row_exists && !user_table.check_is_role()) if (old_row_exists && !user_table.get_is_role())
{ {
goto end; goto end;
} }
user_table.is_role()->store("Y", 1, system_charset_info); if (user_table.set_is_role(true))
{
my_error(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE, MYF(0),
"user", ROLE_ASSIGN_COLUMN_IDX + 1, user_table.num_fields(),
static_cast<int>(table->s->mysql_version), MYSQL_VERSION_ID);
goto end;
}
} }
else else
{ {
...@@ -3954,90 +3932,51 @@ static int replace_user_table(THD *thd, const User_table &user_table, ...@@ -3954,90 +3932,51 @@ static int replace_user_table(THD *thd, const User_table &user_table,
rights)) rights))
goto end; goto end;
DBUG_PRINT("info",("table fields: %d", user_table.num_fields())); user_table.set_auth(new_acl_user.plugin.str, new_acl_user.plugin.length,
/* We either have the password column, the plugin column, or both. Otherwise new_acl_user.auth_string.str, new_acl_user.auth_string.length);
we have a corrupt user table. */
DBUG_ASSERT(user_table.password() || user_table.plugin());
if (user_table.ssl_type()) /* From 4.0.0 we have more fields */
{
/* We write down SSL related ACL stuff */
switch (lex->ssl_type) {
case SSL_TYPE_ANY:
user_table.ssl_type()->store(STRING_WITH_LEN("ANY"),
&my_charset_latin1);
user_table.ssl_cipher()->store("", 0, &my_charset_latin1);
user_table.x509_issuer()->store("", 0, &my_charset_latin1);
user_table.x509_subject()->store("", 0, &my_charset_latin1);
break;
case SSL_TYPE_X509:
user_table.ssl_type()->store(STRING_WITH_LEN("X509"),
&my_charset_latin1);
user_table.ssl_cipher()->store("", 0, &my_charset_latin1);
user_table.x509_issuer()->store("", 0, &my_charset_latin1);
user_table.x509_subject()->store("", 0, &my_charset_latin1);
break;
case SSL_TYPE_SPECIFIED:
user_table.ssl_type()->store(STRING_WITH_LEN("SPECIFIED"),
&my_charset_latin1);
user_table.ssl_cipher()->store("", 0, &my_charset_latin1);
user_table.x509_issuer()->store("", 0, &my_charset_latin1);
user_table.x509_subject()->store("", 0, &my_charset_latin1);
if (lex->ssl_cipher)
user_table.ssl_cipher()->store(lex->ssl_cipher,
strlen(lex->ssl_cipher),
system_charset_info);
if (lex->x509_issuer)
user_table.x509_issuer()->store(lex->x509_issuer,
strlen(lex->x509_issuer),
system_charset_info);
if (lex->x509_subject)
user_table.x509_subject()->store(lex->x509_subject,
strlen(lex->x509_subject),
system_charset_info);
break;
case SSL_TYPE_NOT_SPECIFIED:
break;
case SSL_TYPE_NONE:
user_table.ssl_type()->store("", 0, &my_charset_latin1);
user_table.ssl_cipher()->store("", 0, &my_charset_latin1);
user_table.x509_issuer()->store("", 0, &my_charset_latin1);
user_table.x509_subject()->store("", 0, &my_charset_latin1);
break;
}
USER_RESOURCES mqh= lex->mqh; switch (lex->ssl_type) {
if (mqh.specified_limits & USER_RESOURCES::QUERIES_PER_HOUR) case SSL_TYPE_NOT_SPECIFIED:
user_table.max_questions()->store((longlong) mqh.questions, TRUE); break;
if (mqh.specified_limits & USER_RESOURCES::UPDATES_PER_HOUR) case SSL_TYPE_NONE:
user_table.max_updates()->store((longlong) mqh.updates, TRUE); case SSL_TYPE_ANY:
if (mqh.specified_limits & USER_RESOURCES::CONNECTIONS_PER_HOUR) case SSL_TYPE_X509:
user_table.max_connections()->store((longlong) mqh.conn_per_hour, TRUE); user_table.set_ssl_type(lex->ssl_type);
if (user_table.max_user_connections() && user_table.set_ssl_cipher("", 0);
(mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS)) user_table.set_x509_issuer("", 0);
user_table.max_user_connections()->store((longlong) mqh.user_conn, FALSE); user_table.set_x509_subject("", 0);
if (user_table.plugin()) break;
{ case SSL_TYPE_SPECIFIED:
user_table.plugin()->set_notnull(); user_table.set_ssl_type(lex->ssl_type);
user_table.authentication_string()->set_notnull(); if (lex->ssl_cipher)
if (new_acl_user.plugin.length) user_table.set_ssl_cipher(lex->ssl_cipher, strlen(lex->ssl_cipher));
{ else
if (user_table.password()) user_table.set_ssl_cipher("", 0);
user_table.password()->reset(); if (lex->x509_issuer)
user_table.plugin()->store(new_acl_user.plugin.str, user_table.set_x509_issuer(lex->x509_issuer, strlen(lex->x509_issuer));
new_acl_user.plugin.length, system_charset_info); else
user_table.authentication_string()->store(new_acl_user.auth_string.str, user_table.set_x509_issuer("", 0);
new_acl_user.auth_string.length, system_charset_info); if (lex->x509_subject)
} user_table.set_x509_subject(lex->x509_subject, strlen(lex->x509_subject));
else
if (user_table.max_statement_time()) user_table.set_x509_subject("", 0);
{ break;
if (mqh.specified_limits & USER_RESOURCES::MAX_STATEMENT_TIME)
user_table.max_statement_time()->store(mqh.max_statement_time);
}
}
mqh_used= (mqh_used || mqh.questions || mqh.updates || mqh.conn_per_hour ||
mqh.user_conn || mqh.max_statement_time != 0.0);
} }
if (lex->mqh.specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
user_table.set_max_questions(lex->mqh.questions);
if (lex->mqh.specified_limits & USER_RESOURCES::UPDATES_PER_HOUR)
user_table.set_max_updates(lex->mqh.updates);
if (lex->mqh.specified_limits & USER_RESOURCES::CONNECTIONS_PER_HOUR)
user_table.set_max_connections(lex->mqh.conn_per_hour);
if (lex->mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS)
user_table.set_max_user_connections(lex->mqh.user_conn);
if (lex->mqh.specified_limits & USER_RESOURCES::MAX_STATEMENT_TIME)
user_table.set_max_statement_time(lex->mqh.max_statement_time);
mqh_used= (mqh_used || lex->mqh.questions || lex->mqh.updates ||
lex->mqh.conn_per_hour || lex->mqh.user_conn ||
lex->mqh.max_statement_time != 0.0);
} }
if (old_row_exists) if (old_row_exists)
...@@ -9353,7 +9292,7 @@ static int handle_grant_table(THD *thd, const Grant_table_base& grant_table, ...@@ -9353,7 +9292,7 @@ static int handle_grant_table(THD *thd, const Grant_table_base& grant_table,
if (!unlikely(error) && !*host_str) if (!unlikely(error) && !*host_str)
{ {
// verify that we got a role or a user, as needed // verify that we got a role or a user, as needed
if (static_cast<const User_table&>(grant_table).check_is_role() != if (static_cast<const User_table&>(grant_table).get_is_role() !=
user_from->is_role()) user_from->is_role())
error= HA_ERR_KEY_NOT_FOUND; error= HA_ERR_KEY_NOT_FOUND;
} }
......
...@@ -5355,8 +5355,7 @@ static bool fix_all_session_vcol_exprs(THD *thd, TABLE_LIST *tables) ...@@ -5355,8 +5355,7 @@ static bool fix_all_session_vcol_exprs(THD *thd, TABLE_LIST *tables)
@retval TRUE A lock wait timeout, deadlock or out of memory. @retval TRUE A lock wait timeout, deadlock or out of memory.
*/ */
bool lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool lock_tables(THD *thd, TABLE_LIST *tables, uint count, uint flags)
uint flags)
{ {
TABLE_LIST *table; TABLE_LIST *table;
DBUG_ENTER("lock_tables"); DBUG_ENTER("lock_tables");
......
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