Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mysql_role: fix and simplify role member detection #368

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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