diff --git a/changelogs/fragments/grant_to_public.yml b/changelogs/fragments/grant_to_public.yml new file mode 100644 index 0000000..ea24da0 --- /dev/null +++ b/changelogs/fragments/grant_to_public.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - mysql_info - fix a crash (ERROR 1141, There is no such grant defined for user 'PUBLIC' on host '%') when using the ``users_info`` filter with a PUBLIC role present in MariaDB 10.11+. Do note that the fix doesn't change the fact that the module won't return the privileges from the PUBLIC role in the users privileges list. It can't do that because you have to login as the particular user and use `SHOW GRANTS FOR CURRENT_USER`. We considered using an aggregation with the `SHOW GRANTS FOR PUBLIC` command. However, this approach would make copying users from one server to another transform the privileges inherited from the role as if they were direct privileges on the user. diff --git a/plugins/module_utils/user.py b/plugins/module_utils/user.py index 9de1c6d..337cc67 100644 --- a/plugins/module_utils/user.py +++ b/plugins/module_utils/user.py @@ -662,7 +662,7 @@ def privileges_get(cursor, user, host, maria_role=False): if not maria_role: res = re.match("""GRANT (.+) ON (.+) TO (['`"]).*\\3@(['`"]).*\\4( IDENTIFIED BY PASSWORD (['`"]).+\\6)? ?(.*)""", grant[0]) else: - res = re.match("""GRANT (.+) ON (.+) TO (['`"]).*\\3""", grant[0]) + res = re.match("""GRANT (.+) ON (.+) TO .*""", grant[0]) if res is None: # If a user has roles assigned, we'll have one of priv tuples looking like diff --git a/plugins/modules/mysql_info.py b/plugins/modules/mysql_info.py index a630f18..0447743 100644 --- a/plugins/modules/mysql_info.py +++ b/plugins/modules/mysql_info.py @@ -50,6 +50,7 @@ notes: - Compatible with MariaDB or MySQL. - Calculating the size of a database might be slow, depending on the number and size of tables in it. To avoid this, use I(exclude_fields=db_size). +- filters C(users_info) doesn't support MariaDB roles. attributes: check_mode: @@ -161,6 +162,7 @@ EXAMPLES = r''' - item.name != 'root' # In case you don't want to import admin accounts - item.name != 'mariadb.sys' - item.name != 'mysql' + - item.name != 'PUBLIC' # MariaDB roles are not supported ''' RETURN = r''' @@ -606,7 +608,9 @@ class MySQL_Info(object): user = line['User'] host = line['Host'] - user_priv = privileges_get(self.cursor, user, host) + # MariaDB roles have no host + is_role = self.server_implementation == 'mariadb' and not host + user_priv = privileges_get(self.cursor, user, host, maria_role=is_role) if not user_priv: self.module.warn("No privileges found for %s on host %s" % (user, host)) diff --git a/tests/integration/targets/test_mysql_info/tasks/filter_users_info.yml b/tests/integration/targets/test_mysql_info/tasks/filter_users_info.yml index 558d309..102bf59 100644 --- a/tests/integration/targets/test_mysql_info/tasks/filter_users_info.yml +++ b/tests/integration/targets/test_mysql_info/tasks/filter_users_info.yml @@ -31,6 +31,19 @@ CREATE TABLE IF NOT EXISTS users_info_db.T_UPPER (id int, name1 varchar(9), NAME2 varchar(9), Name3 varchar(9)) + # No need for a specific test later. When the module will retrieve the + # users privileges, it will fail with an error "1141 - There is no such + # grant defined for user 'PUBLIC' on host'%'" if the PUBLIC role is not + # handled properly by our module. + - name: Mysql_info users_info | Grant to PUBLIC for MariaDB 10.11+ + community.mysql.mysql_query: + query: + - >- + GRANT SELECT,INSERT,UPDATE,DELETE on users_info_db.* TO PUBLIC + when: + - db_engine == 'mariadb' + - db_version is version('10.11.1', '>=') + # I failed to create a procedure using community.mysql.mysql_query. # Maybe it's because we must changed the delimiter. - name: Mysql_info users_info | Create procedure SQL file @@ -277,7 +290,7 @@ - item.name != 'mysql.sys' - item.name != 'mysql.infoschema' - item.name != 'mysql.session' - + - item.name != 'PUBLIC' # MariaDB roles are not supported # ================================== Cleanup ============================