From 07a72865f7ef67017e1acb3d0bf898f8273bcec0 Mon Sep 17 00:00:00 2001 From: betanummeric <40263343+betanummeric@users.noreply.github.com> Date: Wed, 25 May 2022 10:16:50 +0200 Subject: [PATCH] mysql_role: fix and simplify role member detection (#368) * 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 Co-authored-by: Felix Hamme Co-authored-by: Andrew Klychkov --- .../368-mysql_role-fix-member-detection.yml | 6 +++ plugins/modules/mysql_role.py | 49 ++----------------- 2 files changed, 11 insertions(+), 44 deletions(-) create mode 100644 changelogs/fragments/368-mysql_role-fix-member-detection.yml diff --git a/changelogs/fragments/368-mysql_role-fix-member-detection.yml b/changelogs/fragments/368-mysql_role-fix-member-detection.yml new file mode 100644 index 00000000..b7cbd3e1 --- /dev/null +++ b/changelogs/fragments/368-mysql_role-fix-member-detection.yml @@ -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). diff --git a/plugins/modules/mysql_role.py b/plugins/modules/mysql_role.py index d0365418..ffff026d 100644 --- a/plugins/modules/mysql_role.py +++ b/plugins/modules/mysql_role.py @@ -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():