From 21604ce58bc91d130252f914d0619cbfb44bc23f Mon Sep 17 00:00:00 2001 From: Felix Hamme Date: Tue, 17 May 2022 12:43:02 +0200 Subject: [PATCH] mysql_user: return "password_changed" boolean (true if the user got a new password) --- plugins/module_utils/user.py | 23 ++++++++++++++--------- plugins/modules/mysql_role.py | 3 ++- plugins/modules/mysql_user.py | 16 +++++++++++----- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/plugins/module_utils/user.py b/plugins/module_utils/user.py index 296ebcd..7bb7268 100644 --- a/plugins/module_utils/user.py +++ b/plugins/module_utils/user.py @@ -137,22 +137,24 @@ def user_add(cursor, user, host, host_all, password, encrypted, tls_requires, check_mode, reuse_existing_password): # we cannot create users without a proper hostname if host_all: - return False + return {'changed': False, 'password_changed': False} if check_mode: - return True + return {'changed': True, 'password_changed': None} # Determine what user management method server uses old_user_mgmt = impl.use_old_user_mgmt(cursor) mogrify = do_not_mogrify_requires if old_user_mgmt else mogrify_requires + used_existing_password = False if reuse_existing_password: existing_auth = get_existing_authentication(cursor, user) if existing_auth: plugin = existing_auth['plugin'] plugin_hash_string = existing_auth['auth_string'] password = None + used_existing_password = True if password and encrypted: if impl.supports_identified_by_password(cursor): query_with_args = "CREATE USER %s@%s IDENTIFIED BY PASSWORD %s", (user, host, password) @@ -182,7 +184,7 @@ def user_add(cursor, user, host, host_all, password, encrypted, privileges_grant(cursor, user, host, db_table, priv, tls_requires) if tls_requires is not None: privileges_grant(cursor, user, host, "*.*", get_grants(cursor, user, host), tls_requires) - return True + return {'changed': True, 'password_changed': not used_existing_password} def is_hash(password): @@ -208,6 +210,7 @@ def user_mod(cursor, user, host, host_all, password, encrypted, else: hostnames = [host] + password_changed = False for host in hostnames: # Handle clear text and hashed passwords. if not role: @@ -252,9 +255,10 @@ def user_mod(cursor, user, host, host_all, password, encrypted, encrypted_password = cursor.fetchone()[0] if current_pass_hash != encrypted_password: + password_changed = True msg = "Password updated" if module.check_mode: - return (True, msg) + return {'changed': True, 'msg': msg, 'password_changed': password_changed} if old_user_mgmt: cursor.execute("SET PASSWORD FOR %s@%s = %s", (user, host, encrypted_password)) msg = "Password updated (old style)" @@ -306,6 +310,7 @@ def user_mod(cursor, user, host, host_all, password, encrypted, query_with_args = "ALTER USER %s@%s IDENTIFIED WITH %s", (user, host, plugin) cursor.execute(*query_with_args) + password_changed = True changed = True # Handle privileges @@ -323,7 +328,7 @@ def user_mod(cursor, user, host, host_all, password, encrypted, if user != "root" and "PROXY" not in priv: msg = "Privileges updated" if module.check_mode: - return (True, msg) + return {'changed': True, 'msg': msg, 'password_changed': password_changed} privileges_revoke(cursor, user, host, db_table, priv, grant_option, maria_role) changed = True @@ -334,7 +339,7 @@ def user_mod(cursor, user, host, host_all, password, encrypted, if db_table not in curr_priv: msg = "New privileges granted" if module.check_mode: - return (True, msg) + return {'changed': True, 'msg': msg, 'password_changed': password_changed} privileges_grant(cursor, user, host, db_table, priv, tls_requires, maria_role) changed = True @@ -364,7 +369,7 @@ def user_mod(cursor, user, host, host_all, password, encrypted, if len(grant_privs) + len(revoke_privs) > 0: msg = "Privileges updated: granted %s, revoked %s" % (grant_privs, revoke_privs) if module.check_mode: - return (True, msg) + return {'changed': True, 'msg': msg, 'password_changed': password_changed} if len(revoke_privs) > 0: privileges_revoke(cursor, user, host, db_table, revoke_privs, grant_option, maria_role) if len(grant_privs) > 0: @@ -379,7 +384,7 @@ def user_mod(cursor, user, host, host_all, password, encrypted, if current_requires != tls_requires: msg = "TLS requires updated" if module.check_mode: - return (True, msg) + return {'changed': True, 'msg': msg, 'password_changed': password_changed} if not old_user_mgmt: pre_query = "ALTER USER" else: @@ -395,7 +400,7 @@ def user_mod(cursor, user, host, host_all, password, encrypted, cursor.execute(*query_with_args) changed = True - return (changed, msg) + return {'changed': changed, 'msg': msg, 'password_changed': password_changed} def user_delete(cursor, user, host, host_all, check_mode): diff --git a/plugins/modules/mysql_role.py b/plugins/modules/mysql_role.py index 790c0eb..ad3514e 100644 --- a/plugins/modules/mysql_role.py +++ b/plugins/modules/mysql_role.py @@ -911,10 +911,11 @@ class Role(): set_default_role_all=set_default_role_all) if privs: - changed, msg = user_mod(self.cursor, self.name, self.host, + result = user_mod(self.cursor, self.name, self.host, None, None, None, None, None, None, privs, append_privs, subtract_privs, None, self.module, role=True, maria_role=self.is_mariadb) + changed = result['changed'] if admin: self.role_impl.set_admin(admin) diff --git a/plugins/modules/mysql_user.py b/plugins/modules/mysql_user.py index ef9b5c7..3ca0562 100644 --- a/plugins/modules/mysql_user.py +++ b/plugins/modules/mysql_user.py @@ -447,18 +447,22 @@ def main(): except Exception as e: module.fail_json(msg=to_native(e)) priv = privileges_unpack(priv, mode, ensure_usage=not subtract_privs) - + password_changed = False if state == "present": if user_exists(cursor, user, host, host_all): try: if update_password == "always": - changed, msg = user_mod(cursor, user, host, host_all, password, encrypted, + result = user_mod(cursor, user, host, host_all, password, encrypted, plugin, plugin_hash_string, plugin_auth_string, priv, append_privs, subtract_privs, tls_requires, module) + else: - changed, msg = user_mod(cursor, user, host, host_all, None, encrypted, + result = user_mod(cursor, user, host, host_all, None, encrypted, None, None, None, priv, append_privs, subtract_privs, tls_requires, module) + changed = result['changed'] + msg = result['msg'] + password_changed = result['password_changed'] except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e: module.fail_json(msg=to_native(e)) @@ -469,9 +473,11 @@ def main(): if subtract_privs: priv = None # avoid granting unwanted privileges reuse_existing_password = update_password == 'on_new_username' - changed = user_add(cursor, user, host, host_all, password, encrypted, + result = user_add(cursor, user, host, host_all, password, encrypted, plugin, plugin_hash_string, plugin_auth_string, priv, tls_requires, module.check_mode, reuse_existing_password) + changed = result['changed'] + password_changed = result['password_changed'] if changed: msg = "User added" @@ -488,7 +494,7 @@ def main(): else: changed = False msg = "User doesn't exist" - module.exit_json(changed=changed, user=user, msg=msg) + module.exit_json(changed=changed, user=user, msg=msg, password_changed=password_changed) if __name__ == '__main__':