mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Added cascading updates from role renames. Also works if a role has been granted to a role.
This change only updates _in memory_ structures.
This commit is contained in:
committed by
Sergei Golubchik
parent
2755c342e6
commit
1007b9232b
@@ -707,6 +707,7 @@ static my_bool get_role_access(ACL_ROLE *role, ulong *access);
|
|||||||
enum enum_acl_lists
|
enum enum_acl_lists
|
||||||
{
|
{
|
||||||
USER_ACL= 0,
|
USER_ACL= 0,
|
||||||
|
ROLE_ACL,
|
||||||
DB_ACL,
|
DB_ACL,
|
||||||
COLUMN_PRIVILEGES_HASH,
|
COLUMN_PRIVILEGES_HASH,
|
||||||
PROC_PRIVILEGES_HASH,
|
PROC_PRIVILEGES_HASH,
|
||||||
@@ -6905,7 +6906,11 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
|
|||||||
int elements;
|
int elements;
|
||||||
const char *user;
|
const char *user;
|
||||||
const char *host;
|
const char *host;
|
||||||
|
const char *role;
|
||||||
|
my_bool is_role= FALSE;
|
||||||
|
uint role_not_matched= 1;
|
||||||
ACL_USER *acl_user= NULL;
|
ACL_USER *acl_user= NULL;
|
||||||
|
ACL_ROLE *acl_role= NULL;
|
||||||
ACL_DB *acl_db= NULL;
|
ACL_DB *acl_db= NULL;
|
||||||
ACL_PROXY_USER *acl_proxy_user= NULL;
|
ACL_PROXY_USER *acl_proxy_user= NULL;
|
||||||
GRANT_NAME *grant_name= NULL;
|
GRANT_NAME *grant_name= NULL;
|
||||||
@@ -6921,6 +6926,35 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
|
|||||||
|
|
||||||
mysql_mutex_assert_owner(&acl_cache->lock);
|
mysql_mutex_assert_owner(&acl_cache->lock);
|
||||||
|
|
||||||
|
/* test if the current query targets a role */
|
||||||
|
is_role= (!user_from->host.length &&
|
||||||
|
(acl_role= find_acl_role(user_from->user.str))) ? TRUE : FALSE;
|
||||||
|
if (is_role && (struct_no != ROLE_ACL || struct_no != ROLES_MAPPINGS_HASH))
|
||||||
|
{
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
else if (struct_no == ROLE_ACL) //no need to scan the structures in this case
|
||||||
|
{
|
||||||
|
if (!is_role || (!drop && !user_to))
|
||||||
|
DBUG_RETURN(is_role);
|
||||||
|
|
||||||
|
/* this calls for a role update */
|
||||||
|
char *old_key= acl_role->user.str;
|
||||||
|
size_t old_key_length= acl_role->user.length;
|
||||||
|
if (drop)
|
||||||
|
{
|
||||||
|
my_hash_delete(&acl_roles, (uchar*) acl_role);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
acl_role->user.str= strdup_root(&mem, user_to->user.str);
|
||||||
|
acl_role->user.length= user_to->user.length;
|
||||||
|
|
||||||
|
my_hash_update(&acl_roles, (uchar*) acl_role, (uchar*) old_key,
|
||||||
|
old_key_length);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the number of elements in the in-memory structure. */
|
/* Get the number of elements in the in-memory structure. */
|
||||||
switch (struct_no) {
|
switch (struct_no) {
|
||||||
case USER_ACL:
|
case USER_ACL:
|
||||||
@@ -6994,6 +7028,7 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
|
|||||||
role_grant_pair= (ROLE_GRANT_PAIR *) my_hash_element(roles_mappings_hash, idx);
|
role_grant_pair= (ROLE_GRANT_PAIR *) my_hash_element(roles_mappings_hash, idx);
|
||||||
user= role_grant_pair->u_uname;
|
user= role_grant_pair->u_uname;
|
||||||
host= role_grant_pair->u_hname;
|
host= role_grant_pair->u_hname;
|
||||||
|
role= role_grant_pair->r_uname;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -7003,13 +7038,18 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
|
|||||||
user= "";
|
user= "";
|
||||||
if (! host)
|
if (! host)
|
||||||
host= "";
|
host= "";
|
||||||
|
if (! role)
|
||||||
|
role= "";
|
||||||
|
|
||||||
#ifdef EXTRA_DEBUG
|
#ifdef EXTRA_DEBUG
|
||||||
DBUG_PRINT("loop",("scan struct: %u index: %u user: '%s' host: '%s'",
|
DBUG_PRINT("loop",("scan struct: %u index: %u user: '%s' host: '%s'",
|
||||||
struct_no, idx, user, host));
|
struct_no, idx, user, host));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (strcmp(user_from->user.str, user) ||
|
if (strcmp(user_from->user.str, user) ||
|
||||||
my_strcasecmp(system_charset_info, user_from->host.str, host))
|
my_strcasecmp(system_charset_info, user_from->host.str, host) ||
|
||||||
|
(is_role && (role_not_matched= strcmp(user_from->user.str, role)))
|
||||||
|
)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
result= 1; /* At least one element found. */
|
result= 1; /* At least one element found. */
|
||||||
@@ -7049,6 +7089,9 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
|
|||||||
my_hash_delete(roles_mappings_hash, (uchar*) role_grant_pair);
|
my_hash_delete(roles_mappings_hash, (uchar*) role_grant_pair);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( user_to )
|
else if ( user_to )
|
||||||
@@ -7117,15 +7160,24 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
|
|||||||
char *old_key= role_grant_pair->hashkey.str;
|
char *old_key= role_grant_pair->hashkey.str;
|
||||||
size_t old_key_length= role_grant_pair->hashkey.length;
|
size_t old_key_length= role_grant_pair->hashkey.length;
|
||||||
|
|
||||||
init_role_grant_pair(&mem, role_grant_pair,
|
if (role_not_matched)
|
||||||
user_to->user.str, user_to->host.str,
|
init_role_grant_pair(&mem, role_grant_pair,
|
||||||
role_grant_pair->r_uname);
|
user_to->user.str, user_to->host.str,
|
||||||
|
role_grant_pair->r_uname);
|
||||||
|
else
|
||||||
|
init_role_grant_pair(&mem, role_grant_pair,
|
||||||
|
role_grant_pair->u_uname,
|
||||||
|
role_grant_pair->u_hname,
|
||||||
|
user_to->user.str);
|
||||||
|
|
||||||
my_hash_update(roles_mappings_hash, (uchar*) role_grant_pair,
|
my_hash_update(roles_mappings_hash, (uchar*) role_grant_pair,
|
||||||
(uchar*) old_key, old_key_length);
|
(uchar*) old_key, old_key_length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7190,6 +7242,13 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
|
|||||||
if (! drop && ! user_to)
|
if (! drop && ! user_to)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
if ((handle_grant_struct(ROLE_ACL, drop, user_from, user_to)) || found)
|
||||||
|
{
|
||||||
|
result= 1; /* At least one record/element found. */
|
||||||
|
/* If search is requested, we do not need to search further. */
|
||||||
|
if (! drop && ! user_to)
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle db table. */
|
/* Handle db table. */
|
||||||
|
Reference in New Issue
Block a user