Skip to content

RANGER-5850: Validate nested role membership for cycles and avoid rec… - #1324

Open
vyommani wants to merge 1 commit into
apache:masterfrom
vyommani:RANGER-5850
Open

vyommani wants to merge 1 commit into
apache:masterfrom
vyommani:RANGER-5850

Conversation

@vyommani

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Roles can contain other roles, but nothing stops a role from ending up inside itself, directly or through other roles. Several RoleREST helpers also expand nested roles recursively, without tracking roles already visited. When a cycle is present, requests that expand it fail.

Validation on save (RoleDBStore)

Create: reject a role whose nested roles contain it. The check walks the stored definitions of the nested roles, loading each role once, so it also catches references that are only written after commit (createNonExistUserGroupRole, for example within an import).
Update: check only the nested roles the update adds. Reject the update if one of them is the role itself or one of its ancestors, found by walking x_role_ref_role ids upward with a visited set. An update that adds no nested role does no extra work.
Grant: relies on updateRole for this check, including granting a role into itself. The separate recursive check in addUsersGroupsAndRoles is removed.

Role expansion (RoleREST)

getRoleMemberNames and getRoleMembers are now iterative, with a visited set. Each nested role is loaded once, and a cycle already present in the data terminates.
ensureRoleAccess reuses the roles loaded during expansion instead of fetching them again. The access decision is unchanged.
getUserRoles shares one visited set across all of the user’s roles, so a nested role common to several of them is loaded once.
A nested role named in a role definition that doesn’t exist (yet) is skipped instead of failing the request.

Behaviour changes

Saving a role that would contain itself now fails with: “a role can not contain itself, directly or through nested roles.”
Existing data with cycles can still be read, and those roles can still be edited.

How was this patch tested?

TestRoleDBStore:
self-nesting rejected on create and on update;
a create rejected when an existing nested role already contains the new role;
adding an ancestor as a nested role rejected;
an update with unchanged nested roles doing no extra lookups;
an existing cycle above the role terminating and the update succeeding.
TestRoleREST:
GET /roles/{id} on a cyclic role returning a denial, with each role loaded at most once;
getUserRoles on a cyclic role terminating;
a missing nested role skipped on read.

}

while (!pending.isEmpty()) {
String nestedRoleName = pending.poll();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nestedRoleName => memberRoleName

continue;
}

XXRole xxNestedRole = daoMgr.getXXRole().findByRoleName(nestedRoleName);

@mneethiraj mneethiraj Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider replacing 493 to 508 with a new method in XXRoleDao to retrieve the list of refereced roles:

  XXRoleDao roleDao = daoMgr.getXXRole();

  while (!pending.isEmpty()) {
    ...
    Collection<String> refRoleNames = roleDao.getRoleMemberNames(memberRoleName);

    pending.add(refRoleNames);
  }

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants