Commit 2755c342 authored by Vicențiu Ciorbaru's avatar Vicențiu Ciorbaru Committed by Sergei Golubchik

Added extra comments to explain the ACL_USER_BASE flags usage, as well as fix...

Added extra comments to explain the ACL_USER_BASE flags usage, as well as fix an issue with get_role_access.

The bug caused roles rights to not be propagated if a push on the stack happened. The newly finished neighbour
was never reevaluated.
parent f37168d4
...@@ -648,7 +648,12 @@ static void init_role_grant_pair(MEM_ROOT *mem, ROLE_GRANT_PAIR *entry, ...@@ -648,7 +648,12 @@ static void init_role_grant_pair(MEM_ROOT *mem, ROLE_GRANT_PAIR *entry,
#define ROLE_ASSIGN_COLUMN_IDX 42 #define ROLE_ASSIGN_COLUMN_IDX 42
/* various flags valid for ACL_USER */ /* various flags valid for ACL_USER */
#define IS_ROLE (1L << 0) #define IS_ROLE (1L << 0)
/* Flag to mark that a ROLE has been visited in a DEPTH_FIRST_SEARCH */
#define ROLE_VISITED (1L << 1) #define ROLE_VISITED (1L << 1)
/*
Flag to mark that the ROLE's access bits are final, having been inherited
from other granted roles
*/
#define ROLE_GRANTS_FINAL (1L << 2) #define ROLE_GRANTS_FINAL (1L << 2)
...@@ -2236,6 +2241,7 @@ my_bool acl_user_reset_grant(ACL_USER *user, ...@@ -2236,6 +2241,7 @@ my_bool acl_user_reset_grant(ACL_USER *user,
my_bool get_role_access(ACL_ROLE *role, ulong *access) my_bool get_role_access(ACL_ROLE *role, ulong *access)
{ {
DBUG_ENTER("get_role_access"); DBUG_ENTER("get_role_access");
DBUG_PRINT("enter",("role: '%s'", role->user.str));
DBUG_ASSERT(role); DBUG_ASSERT(role);
DBUG_ASSERT(access); DBUG_ASSERT(access);
/* /*
...@@ -2252,6 +2258,7 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access) ...@@ -2252,6 +2258,7 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access)
if (role->flags & ROLE_GRANTS_FINAL) if (role->flags & ROLE_GRANTS_FINAL)
{ {
*access= role->access; *access= role->access;
DBUG_PRINT("exit", ("Role access: %lu", *access));
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
...@@ -2267,7 +2274,7 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access) ...@@ -2267,7 +2274,7 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access)
state.node_data= role; state.node_data= role;
role->flags|= ROLE_VISITED; role->flags|= ROLE_VISITED;
(void) my_init_dynamic_array(&stack,sizeof(NODE_STATE), 20, 50, MYF(0)); (void) my_init_dynamic_array(&stack, sizeof(NODE_STATE), 20, 50, MYF(0));
push_dynamic(&stack, &state); push_dynamic(&stack, &state);
while (stack.elements) while (stack.elements)
...@@ -2277,8 +2284,9 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access) ...@@ -2277,8 +2284,9 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access)
DBUG_ASSERT(curr_state->node_data->flags & ROLE_VISITED); DBUG_ASSERT(curr_state->node_data->flags & ROLE_VISITED);
ACL_ROLE *current= state.node_data; ACL_ROLE *current= curr_state->node_data;
ACL_ROLE *neighbour= NULL; ACL_ROLE *neighbour= NULL;
DBUG_PRINT("info", ("Examining role %s", current->user.str));
/* /*
Iterate through the neighbours until a first valid jump-to Iterate through the neighbours until a first valid jump-to
neighbour is found neighbour is found
...@@ -2289,11 +2297,13 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access) ...@@ -2289,11 +2297,13 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access)
i < current->role_grants.elements && found == FALSE; i++) i < current->role_grants.elements && found == FALSE; i++)
{ {
neighbour= *(dynamic_element(&current->role_grants, i, ACL_ROLE**)); neighbour= *(dynamic_element(&current->role_grants, i, ACL_ROLE**));
DBUG_PRINT("info", ("Examining neighbour role %s", neighbour->user.str));
/* check if it forms a cycle */ /* check if it forms a cycle */
if (neighbour->flags & ROLE_VISITED) if (neighbour->flags & ROLE_VISITED)
{ {
/* TODO the edge needs to be ignored */ /* TODO the edge needs to be ignored */
DBUG_PRINT("info", ("Found cycle"));
continue; continue;
} }
...@@ -2303,6 +2313,7 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access) ...@@ -2303,6 +2313,7 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access)
*/ */
if (neighbour->flags & ROLE_GRANTS_FINAL) if (neighbour->flags & ROLE_GRANTS_FINAL)
{ {
DBUG_PRINT("info", ("Neighbour access is final, merging"));
current->access|= neighbour->access; current->access|= neighbour->access;
continue; continue;
} }
...@@ -2313,6 +2324,7 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access) ...@@ -2313,6 +2324,7 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access)
pointer is valid pointer is valid
*/ */
found= TRUE; found= TRUE;
break;
} }
if (found) if (found)
...@@ -2344,6 +2356,9 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access) ...@@ -2344,6 +2356,9 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access)
curr_state->node_data->flags|= ROLE_GRANTS_FINAL; curr_state->node_data->flags|= ROLE_GRANTS_FINAL;
/* Add the own role's rights once it's finished exploring */ /* Add the own role's rights once it's finished exploring */
curr_state->node_data->access|= curr_state->node_data->initial_role_access; curr_state->node_data->access|= curr_state->node_data->initial_role_access;
DBUG_PRINT("info",
("Setting final access for node: %s %lu",
curr_state->node_data->user.str, curr_state->node_data->access));
} }
} }
...@@ -2352,7 +2367,8 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access) ...@@ -2352,7 +2367,8 @@ my_bool get_role_access(ACL_ROLE *role, ulong *access)
delete_dynamic(&stack); delete_dynamic(&stack);
/* Finally set the access */ /* Finally set the access */
*access= role->access; *access= role->access;
DBUG_RETURN(0); DBUG_PRINT("exit", ("Role access: %lu", *access));
DBUG_RETURN(FALSE);
} }
/* /*
......
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