Skip to content

Commit

Permalink
mysql_role: fix and simplify role member detection (#368)
Browse files Browse the repository at this point in the history
* mysql_role: fix and simplify role membership detection

* add changelog fragment

* Update changelogs/fragments/368-mysql_role-fix-member-detection.yml

Co-authored-by: Andrew Klychkov <[email protected]>

Co-authored-by: Felix Hamme <[email protected]>
Co-authored-by: Andrew Klychkov <[email protected]>
  • Loading branch information
3 people authored May 25, 2022
1 parent c489cf1 commit 07a7286
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 44 deletions.
6 changes: 6 additions & 0 deletions changelogs/fragments/368-mysql_role-fix-member-detection.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
bugfixes:
- >
mysql_role - in some cases (when "SHOW GRANTS" did not use backticks for quotes), no unwanted members were detached
from the role (and redundant "GRANT" statements were executed for wanted members). This is fixed by querying the
existing role members from the mysql.role_edges (MySQL) or mysql.roles_mapping (MariaDB) tables instead of parsing
the "SHOW GRANTS" output (https://github.com/ansible-collections/community.mysql/pull/368).
49 changes: 5 additions & 44 deletions plugins/modules/mysql_role.py
Original file line number Diff line number Diff line change
Expand Up @@ -896,50 +896,11 @@ def __get_members(self):
Returns:
set: Members.
"""
members = set()

for user, host in self.server.get_users():
# Don't handle itself
if user == self.name and host == self.host:
continue

grants = self.server.get_grants(user, host)

if self.__is_member(grants):
members.add((user, host))

return members

def __is_member(self, grants):
"""Check if a user / role is a member of a role.
To check if a user is a member of a role,
we parse their grants looking for the role name in them.
In the following grants, we can see that test@% is a member of readers.
+---------------------------------------------------+
| Grants for test@% |
+---------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE ON *.* TO `test`@`%` |
| GRANT ALL PRIVILEGES ON `mysql`.* TO `test`@`%` |
| GRANT INSERT ON `mysql`.`user` TO `test`@`%` |
| GRANT `readers`@`%` TO `test`@`%` |
+---------------------------------------------------+
Args:
grants (list): Grants of a user to parse.
Returns:
bool: True if the self.full_name has been found in grants,
otherwise returns False.
"""
if not grants:
return False

for grant in grants:
if self.full_name in grant[0]:
return True

return False
if self.is_mariadb:
self.cursor.execute('select user, host from mysql.roles_mapping where role = %s', (self.name,))
else:
self.cursor.execute('select TO_USER as user, TO_HOST as host from mysql.role_edges where FROM_USER = %s', (self.name,))
return set(self.cursor.fetchall())


def main():
Expand Down

0 comments on commit 07a7286

Please sign in to comment.