Commit 875617c0 authored by Vicențiu Ciorbaru's avatar Vicențiu Ciorbaru Committed by Sergei Golubchik

Added separation between roles and users in the mysql.user table

parent 9f512dca
...@@ -542,7 +542,16 @@ static uchar* acl_entry_get_key(acl_entry *entry, size_t *length, ...@@ -542,7 +542,16 @@ static uchar* acl_entry_get_key(acl_entry *entry, size_t *length,
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */ #endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
#define NORMAL_HANDSHAKE_SIZE 6 #define NORMAL_HANDSHAKE_SIZE 6
static DYNAMIC_ARRAY acl_hosts, acl_users, acl_dbs, acl_proxy_users; static DYNAMIC_ARRAY acl_hosts, acl_users, acl_dbs, acl_proxy_users, acl_roles;
/* XXX
***** Potential optimization *****
role_grants could potentially be a HASH with keys as usernames and values
as a DYNAMIC_ARRAY of pointers to granted roles
XXX
***** Implementation choice for now *****
An array representing mappings between acl_users and acl_roles;
*/
static DYNAMIC_ARRAY role_grants;
static MEM_ROOT mem, memex; static MEM_ROOT mem, memex;
static bool initialized=0; static bool initialized=0;
static bool allow_all_hosts=1; static bool allow_all_hosts=1;
...@@ -576,6 +585,11 @@ enum enum_acl_lists ...@@ -576,6 +585,11 @@ enum enum_acl_lists
PROXY_USERS_ACL PROXY_USERS_ACL
}; };
typedef struct st_role_grant
{
ACL_USER *user;
ACL_USER *role;
} ROLE_GRANT_PAIR;
/* /*
Convert scrambled password to binary form, according to scramble type, Convert scrambled password to binary form, according to scramble type,
Binary form is stored in user.salt. Binary form is stored in user.salt.
...@@ -829,6 +843,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) ...@@ -829,6 +843,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
table->use_all_columns(); table->use_all_columns();
(void) my_init_dynamic_array(&acl_users,sizeof(ACL_USER), 50, 100, MYF(0)); (void) my_init_dynamic_array(&acl_users,sizeof(ACL_USER), 50, 100, MYF(0));
(void) my_init_dynamic_array(&acl_roles,sizeof(ACL_USER), 50, 100, MYF(0));
username_char_length= min(table->field[1]->char_length(), USERNAME_CHAR_LENGTH); username_char_length= min(table->field[1]->char_length(), USERNAME_CHAR_LENGTH);
password_length= table->field[2]->field_length / password_length= table->field[2]->field_length /
table->field[2]->charset()->mbmaxlen; table->field[2]->charset()->mbmaxlen;
...@@ -875,11 +890,20 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) ...@@ -875,11 +890,20 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
while (!(read_record_info.read_record(&read_record_info))) while (!(read_record_info.read_record(&read_record_info)))
{ {
ACL_USER user; ACL_USER user;
bool is_role= FALSE;
bzero(&user, sizeof(user)); bzero(&user, sizeof(user));
update_hostname(&user.host, get_field(&mem, table->field[0])); update_hostname(&user.host, get_field(&mem, table->field[0]));
user.user= get_field(&mem, table->field[1]); user.user= get_field(&mem, table->field[1]);
DBUG_PRINT("info", ("user_entry %s", user.user));
if (check_no_resolve && hostname_requires_resolving(user.host.hostname)) /* 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
*/
if (!user.host.hostname) {
is_role= TRUE;
}
if (!is_role && check_no_resolve &&
hostname_requires_resolving(user.host.hostname))
{ {
sql_print_warning("'user' entry '%s@%s' " sql_print_warning("'user' entry '%s@%s' "
"ignored in --skip-name-resolve mode.", "ignored in --skip-name-resolve mode.",
...@@ -894,7 +918,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) ...@@ -894,7 +918,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
user.auth_string.length= password_len; user.auth_string.length= password_len;
set_user_salt(&user, password, password_len); set_user_salt(&user, password, password_len);
if (set_user_plugin(&user, password_len)) if (!is_role && set_user_plugin(&user, password_len))
continue; continue;
{ {
...@@ -974,7 +998,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) ...@@ -974,7 +998,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
user.user_resource.user_conn= ptr ? atoi(ptr) : 0; user.user_resource.user_conn= ptr ? atoi(ptr) : 0;
} }
if (table->s->fields >= 41) if (!is_role && table->s->fields >= 41)
{ {
/* We may have plugin & auth_String fields */ /* We may have plugin & auth_String fields */
char *tmpstr= get_field(&mem, table->field[next_field++]); char *tmpstr= get_field(&mem, table->field[next_field++]);
...@@ -1016,7 +1040,13 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) ...@@ -1016,7 +1040,13 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
user.access|= SUPER_ACL | EXECUTE_ACL; user.access|= SUPER_ACL | EXECUTE_ACL;
#endif #endif
} }
(void) push_dynamic(&acl_users,(uchar*) &user); if (is_role) {
(void) push_dynamic(&acl_roles,(uchar*) &user);
}
else
{
(void) push_dynamic(&acl_users,(uchar*) &user);
}
if (!user.host.hostname || if (!user.host.hostname ||
(user.host.hostname[0] == wild_many && !user.host.hostname[1])) (user.host.hostname[0] == wild_many && !user.host.hostname[1]))
allow_all_hosts=1; // Anyone can connect allow_all_hosts=1; // Anyone can connect
......
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