mirror of
https://github.com/ansible-collections/community.mysql.git
synced 2025-04-07 11:10:32 -07:00
Add salt parameter to hash generation for sha256 plugins (#631)
* add salt parameter to hash generation for sha256 plugin * technomax review modification * no general user test for salt
This commit is contained in:
parent
50e7413b88
commit
0bc3e3d848
6 changed files with 251 additions and 7 deletions
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
minor_changes:
|
||||||
|
- mysql_user - Add salt parameter to generate static hash for `caching_sha2_password` and `sha256_password` plugins.
|
125
plugins/module_utils/implementations/mysql/hash.py
Normal file
125
plugins/module_utils/implementations/mysql/hash.py
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
"""
|
||||||
|
Generate MySQL sha256 compatible plugins hash for a given password and salt
|
||||||
|
|
||||||
|
based on
|
||||||
|
* https://www.akkadia.org/drepper/SHA-crypt.txt
|
||||||
|
* https://crypto.stackexchange.com/questions/77427/whats-the-algorithm-behind-mysqls-sha256-password-hashing-scheme/111174#111174
|
||||||
|
* https://github.com/hashcat/hashcat/blob/master/tools/test_modules/m07400.pm
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
|
||||||
|
def _to64(v, n):
|
||||||
|
"""Convert a 32-bit integer to a base-64 string"""
|
||||||
|
i64 = (
|
||||||
|
[".", "/"]
|
||||||
|
+ [chr(x) for x in range(48, 58)]
|
||||||
|
+ [chr(x) for x in range(65, 91)]
|
||||||
|
+ [chr(x) for x in range(97, 123)]
|
||||||
|
)
|
||||||
|
result = ""
|
||||||
|
while n > 0:
|
||||||
|
n -= 1
|
||||||
|
result += i64[v & 0x3F]
|
||||||
|
v >>= 6
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _hashlib_sha256(data):
|
||||||
|
"""Return SHA-256 digest from hashlib ."""
|
||||||
|
return hashlib.sha256(data).digest()
|
||||||
|
|
||||||
|
|
||||||
|
def _sha256_digest(key, salt, loops):
|
||||||
|
"""Return a SHA-256 digest of the concatenation of the key, the salt, and the key, repeated as necessary."""
|
||||||
|
# https://www.akkadia.org/drepper/SHA-crypt.txt
|
||||||
|
num_bytes = 32
|
||||||
|
bytes_key = key.encode()
|
||||||
|
bytes_salt = salt.encode()
|
||||||
|
digest_b = _hashlib_sha256(bytes_key + bytes_salt + bytes_key)
|
||||||
|
|
||||||
|
tmp = bytes_key + bytes_salt
|
||||||
|
for i in range(len(bytes_key), 0, -num_bytes):
|
||||||
|
tmp += digest_b if i > num_bytes else digest_b[:i]
|
||||||
|
|
||||||
|
i = len(bytes_key)
|
||||||
|
while i > 0:
|
||||||
|
tmp += digest_b if (i & 1) != 0 else bytes_key
|
||||||
|
i >>= 1
|
||||||
|
|
||||||
|
digest_a = _hashlib_sha256(tmp)
|
||||||
|
|
||||||
|
tmp = b""
|
||||||
|
for i in range(len(bytes_key)):
|
||||||
|
tmp += bytes_key
|
||||||
|
|
||||||
|
digest_dp = _hashlib_sha256(tmp)
|
||||||
|
|
||||||
|
byte_sequence_p = b""
|
||||||
|
for i in range(len(bytes_key), 0, -num_bytes):
|
||||||
|
byte_sequence_p += digest_dp if i > num_bytes else digest_dp[:i]
|
||||||
|
|
||||||
|
tmp = b""
|
||||||
|
til = 16 + digest_a[0]
|
||||||
|
|
||||||
|
for i in range(til):
|
||||||
|
tmp += bytes_salt
|
||||||
|
|
||||||
|
digest_ds = _hashlib_sha256(tmp)
|
||||||
|
|
||||||
|
byte_sequence_s = b""
|
||||||
|
for i in range(len(bytes_salt), 0, -num_bytes):
|
||||||
|
byte_sequence_s += digest_ds if i > num_bytes else digest_ds[:i]
|
||||||
|
|
||||||
|
digest_c = digest_a
|
||||||
|
|
||||||
|
for i in range(loops):
|
||||||
|
tmp = byte_sequence_p if (i & 1) else digest_c
|
||||||
|
if i % 3:
|
||||||
|
tmp += byte_sequence_s
|
||||||
|
if i % 7:
|
||||||
|
tmp += byte_sequence_p
|
||||||
|
tmp += digest_c if (i & 1) else byte_sequence_p
|
||||||
|
digest_c = _hashlib_sha256(tmp)
|
||||||
|
|
||||||
|
inc1, inc2, mod, end = (10, 21, 30, 0)
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
tmp = ""
|
||||||
|
|
||||||
|
while True:
|
||||||
|
tmp += _to64(
|
||||||
|
(digest_c[i] << 16)
|
||||||
|
| (digest_c[(i + inc1) % mod] << 8)
|
||||||
|
| digest_c[(i + inc1 * 2) % mod],
|
||||||
|
4,
|
||||||
|
)
|
||||||
|
i = (i + inc2) % mod
|
||||||
|
if i == end:
|
||||||
|
break
|
||||||
|
|
||||||
|
tmp += _to64((digest_c[31] << 8) | digest_c[30], 3)
|
||||||
|
|
||||||
|
return tmp
|
||||||
|
|
||||||
|
|
||||||
|
def mysql_sha256_password_hash(password, salt):
|
||||||
|
"""Return a MySQL compatible caching_sha2_password hash in raw format."""
|
||||||
|
if len(salt) != 20:
|
||||||
|
raise ValueError("Salt must be 20 characters long.")
|
||||||
|
|
||||||
|
count = 5
|
||||||
|
iteration = 1000 * count
|
||||||
|
|
||||||
|
digest = _sha256_digest(password, salt, iteration)
|
||||||
|
return "$A${0:>03}${1}{2}".format(count, salt, digest)
|
||||||
|
|
||||||
|
|
||||||
|
def mysql_sha256_password_hash_hex(password, salt):
|
||||||
|
"""Return a MySQL compatible caching_sha2_password hash in hex format."""
|
||||||
|
return mysql_sha256_password_hash(password, salt).encode().hex().upper()
|
|
@ -1,4 +1,6 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
|
||||||
|
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
# This code is part of Ansible, but is an independent component.
|
# This code is part of Ansible, but is an independent component.
|
||||||
|
@ -19,6 +21,10 @@ from ansible_collections.community.mysql.plugins.module_utils.mysql import (
|
||||||
mysql_driver,
|
mysql_driver,
|
||||||
get_server_implementation,
|
get_server_implementation,
|
||||||
)
|
)
|
||||||
|
from ansible_collections.community.mysql.plugins.module_utils.implementations.mysql.hash import (
|
||||||
|
mysql_sha256_password_hash,
|
||||||
|
mysql_sha256_password_hash_hex,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class InvalidPrivsError(Exception):
|
class InvalidPrivsError(Exception):
|
||||||
|
@ -135,7 +141,7 @@ def get_existing_authentication(cursor, user, host):
|
||||||
|
|
||||||
|
|
||||||
def user_add(cursor, user, host, host_all, password, encrypted,
|
def user_add(cursor, user, host, host_all, password, encrypted,
|
||||||
plugin, plugin_hash_string, plugin_auth_string, new_priv,
|
plugin, plugin_hash_string, plugin_auth_string, salt, new_priv,
|
||||||
attributes, tls_requires, reuse_existing_password, module,
|
attributes, tls_requires, reuse_existing_password, module,
|
||||||
password_expire, password_expire_interval):
|
password_expire, password_expire_interval):
|
||||||
# If attributes are set, perform a sanity check to ensure server supports user attributes before creating user
|
# If attributes are set, perform a sanity check to ensure server supports user attributes before creating user
|
||||||
|
@ -181,6 +187,12 @@ def user_add(cursor, user, host, host_all, password, encrypted,
|
||||||
# Mysql and MariaDB differ in naming pam plugin and Syntax to set it
|
# Mysql and MariaDB differ in naming pam plugin and Syntax to set it
|
||||||
if plugin == 'pam': # Used by MariaDB which requires the USING keyword, not BY
|
if plugin == 'pam': # Used by MariaDB which requires the USING keyword, not BY
|
||||||
query_with_args = "CREATE USER %s@%s IDENTIFIED WITH %s USING %s", (user, host, plugin, plugin_auth_string)
|
query_with_args = "CREATE USER %s@%s IDENTIFIED WITH %s USING %s", (user, host, plugin, plugin_auth_string)
|
||||||
|
elif salt:
|
||||||
|
if plugin in ['caching_sha2_password', 'sha256_password']:
|
||||||
|
generated_hash_string = mysql_sha256_password_hash_hex(password=plugin_auth_string, salt=salt)
|
||||||
|
else:
|
||||||
|
module.fail_json(msg="salt not handled for %s authentication plugin" % plugin)
|
||||||
|
query_with_args = ("CREATE USER %s@%s IDENTIFIED WITH %s AS 0x" + generated_hash_string), (user, host, plugin)
|
||||||
else:
|
else:
|
||||||
query_with_args = "CREATE USER %s@%s IDENTIFIED WITH %s BY %s", (user, host, plugin, plugin_auth_string)
|
query_with_args = "CREATE USER %s@%s IDENTIFIED WITH %s BY %s", (user, host, plugin, plugin_auth_string)
|
||||||
elif plugin:
|
elif plugin:
|
||||||
|
@ -221,7 +233,7 @@ def is_hash(password):
|
||||||
|
|
||||||
|
|
||||||
def user_mod(cursor, user, host, host_all, password, encrypted,
|
def user_mod(cursor, user, host, host_all, password, encrypted,
|
||||||
plugin, plugin_hash_string, plugin_auth_string, new_priv,
|
plugin, plugin_hash_string, plugin_auth_string, salt, new_priv,
|
||||||
append_privs, subtract_privs, attributes, tls_requires, module,
|
append_privs, subtract_privs, attributes, tls_requires, module,
|
||||||
password_expire, password_expire_interval, role=False, maria_role=False):
|
password_expire, password_expire_interval, role=False, maria_role=False):
|
||||||
changed = False
|
changed = False
|
||||||
|
@ -342,7 +354,11 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
||||||
if plugin_hash_string and current_plugin[1] != plugin_hash_string:
|
if plugin_hash_string and current_plugin[1] != plugin_hash_string:
|
||||||
update = True
|
update = True
|
||||||
|
|
||||||
if plugin_auth_string and current_plugin[1] != plugin_auth_string:
|
if salt:
|
||||||
|
if plugin in ['caching_sha2_password', 'sha256_password']:
|
||||||
|
if current_plugin[1] != mysql_sha256_password_hash(password=plugin_auth_string, salt=salt):
|
||||||
|
update = True
|
||||||
|
elif plugin_auth_string and current_plugin[1] != plugin_auth_string:
|
||||||
# this case can cause more updates than expected,
|
# this case can cause more updates than expected,
|
||||||
# as plugin can hash auth_string in any way it wants
|
# as plugin can hash auth_string in any way it wants
|
||||||
# and there's no way to figure it out for
|
# and there's no way to figure it out for
|
||||||
|
@ -356,6 +372,12 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
||||||
# Mysql and MariaDB differ in naming pam plugin and syntax to set it
|
# Mysql and MariaDB differ in naming pam plugin and syntax to set it
|
||||||
if plugin in ('pam', 'ed25519'):
|
if plugin in ('pam', 'ed25519'):
|
||||||
query_with_args = "ALTER USER %s@%s IDENTIFIED WITH %s USING %s", (user, host, plugin, plugin_auth_string)
|
query_with_args = "ALTER USER %s@%s IDENTIFIED WITH %s USING %s", (user, host, plugin, plugin_auth_string)
|
||||||
|
elif salt:
|
||||||
|
if plugin in ['caching_sha2_password', 'sha256_password']:
|
||||||
|
generated_hash_string = mysql_sha256_password_hash_hex(password=plugin_auth_string, salt=salt)
|
||||||
|
else:
|
||||||
|
module.fail_json(msg="salt not handled for %s authentication plugin" % plugin)
|
||||||
|
query_with_args = ("ALTER USER %s@%s IDENTIFIED WITH %s AS 0x" + generated_hash_string), (user, host, plugin)
|
||||||
else:
|
else:
|
||||||
query_with_args = "ALTER USER %s@%s IDENTIFIED WITH %s BY %s", (user, host, plugin, plugin_auth_string)
|
query_with_args = "ALTER USER %s@%s IDENTIFIED WITH %s BY %s", (user, host, plugin, plugin_auth_string)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -931,7 +931,7 @@ class Role():
|
||||||
|
|
||||||
if privs:
|
if privs:
|
||||||
result = user_mod(self.cursor, self.name, self.host,
|
result = user_mod(self.cursor, self.name, self.host,
|
||||||
None, None, None, None, None, None,
|
None, None, None, None, None, None, None,
|
||||||
privs, append_privs, subtract_privs, None, None,
|
privs, append_privs, subtract_privs, None, None,
|
||||||
self.module, None, None, role=True,
|
self.module, None, None, role=True,
|
||||||
maria_role=self.is_mariadb)
|
maria_role=self.is_mariadb)
|
||||||
|
|
|
@ -139,8 +139,16 @@ options:
|
||||||
description:
|
description:
|
||||||
- User's plugin auth_string (``CREATE USER user IDENTIFIED WITH plugin BY plugin_auth_string``).
|
- User's plugin auth_string (``CREATE USER user IDENTIFIED WITH plugin BY plugin_auth_string``).
|
||||||
- If I(plugin) is ``pam`` (MariaDB) or ``auth_pam`` (MySQL) an optional I(plugin_auth_string) can be used to choose a specific PAM service.
|
- If I(plugin) is ``pam`` (MariaDB) or ``auth_pam`` (MySQL) an optional I(plugin_auth_string) can be used to choose a specific PAM service.
|
||||||
|
- You need to define a I(salt) to have idempotence on password change with ``caching_sha2_password`` and ``sha256_password`` plugins.
|
||||||
type: str
|
type: str
|
||||||
version_added: '0.1.0'
|
version_added: '0.1.0'
|
||||||
|
salt:
|
||||||
|
description:
|
||||||
|
- Salt used to generate password hash from I(plugin_auth_string).
|
||||||
|
- Salt length must be 20 characters.
|
||||||
|
- Salt only support ``caching_sha2_password`` or ``sha256_password`` authentication I(plugin).
|
||||||
|
type: str
|
||||||
|
version_added: '3.10.0'
|
||||||
resource_limits:
|
resource_limits:
|
||||||
description:
|
description:
|
||||||
- Limit the user for certain server resources. Provided since MySQL 5.6 / MariaDB 10.2.
|
- Limit the user for certain server resources. Provided since MySQL 5.6 / MariaDB 10.2.
|
||||||
|
@ -369,6 +377,13 @@ EXAMPLES = r'''
|
||||||
priv: '*.*:ALL'
|
priv: '*.*:ALL'
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
- name: Create user 'bob' authenticated with plugin 'caching_sha2_password' and static salt
|
||||||
|
community.mysql.mysql_user:
|
||||||
|
name: bob
|
||||||
|
plugin: caching_sha2_password
|
||||||
|
plugin_auth_string: password
|
||||||
|
salt: 1234567890abcdefghij
|
||||||
|
|
||||||
- name: Limit bob's resources to 10 queries per hour and 5 connections per hour
|
- name: Limit bob's resources to 10 queries per hour and 5 connections per hour
|
||||||
community.mysql.mysql_user:
|
community.mysql.mysql_user:
|
||||||
name: bob
|
name: bob
|
||||||
|
@ -440,6 +455,7 @@ def main():
|
||||||
plugin=dict(default=None, type='str'),
|
plugin=dict(default=None, type='str'),
|
||||||
plugin_hash_string=dict(default=None, type='str'),
|
plugin_hash_string=dict(default=None, type='str'),
|
||||||
plugin_auth_string=dict(default=None, type='str'),
|
plugin_auth_string=dict(default=None, type='str'),
|
||||||
|
salt=dict(default=None, type='str'),
|
||||||
resource_limits=dict(type='dict'),
|
resource_limits=dict(type='dict'),
|
||||||
force_context=dict(type='bool', default=False),
|
force_context=dict(type='bool', default=False),
|
||||||
session_vars=dict(type='dict'),
|
session_vars=dict(type='dict'),
|
||||||
|
@ -480,6 +496,7 @@ def main():
|
||||||
plugin = module.params["plugin"]
|
plugin = module.params["plugin"]
|
||||||
plugin_hash_string = module.params["plugin_hash_string"]
|
plugin_hash_string = module.params["plugin_hash_string"]
|
||||||
plugin_auth_string = module.params["plugin_auth_string"]
|
plugin_auth_string = module.params["plugin_auth_string"]
|
||||||
|
salt = module.params["salt"]
|
||||||
resource_limits = module.params["resource_limits"]
|
resource_limits = module.params["resource_limits"]
|
||||||
session_vars = module.params["session_vars"]
|
session_vars = module.params["session_vars"]
|
||||||
column_case_sensitive = module.params["column_case_sensitive"]
|
column_case_sensitive = module.params["column_case_sensitive"]
|
||||||
|
@ -499,6 +516,14 @@ def main():
|
||||||
module.fail_json(msg="password_expire_interval value \
|
module.fail_json(msg="password_expire_interval value \
|
||||||
should be positive number")
|
should be positive number")
|
||||||
|
|
||||||
|
if salt:
|
||||||
|
if not plugin_auth_string:
|
||||||
|
module.fail_json(msg="salt requires plugin_auth_string")
|
||||||
|
if len(salt) != 20:
|
||||||
|
module.fail_json(msg="salt must be 20 characters long")
|
||||||
|
if plugin not in ['caching_sha2_password', 'sha256_password']:
|
||||||
|
module.fail_json(msg="salt requires caching_sha2_password or sha256_password plugin")
|
||||||
|
|
||||||
cursor = None
|
cursor = None
|
||||||
try:
|
try:
|
||||||
if check_implicit_admin:
|
if check_implicit_admin:
|
||||||
|
@ -542,13 +567,13 @@ def main():
|
||||||
try:
|
try:
|
||||||
if update_password == "always":
|
if update_password == "always":
|
||||||
result = 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,
|
plugin, plugin_hash_string, plugin_auth_string, salt,
|
||||||
priv, append_privs, subtract_privs, attributes, tls_requires, module,
|
priv, append_privs, subtract_privs, attributes, tls_requires, module,
|
||||||
password_expire, password_expire_interval)
|
password_expire, password_expire_interval)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
result = user_mod(cursor, user, host, host_all, None, encrypted,
|
result = user_mod(cursor, user, host, host_all, None, encrypted,
|
||||||
None, None, None,
|
None, None, None, None,
|
||||||
priv, append_privs, subtract_privs, attributes, tls_requires, module,
|
priv, append_privs, subtract_privs, attributes, tls_requires, module,
|
||||||
password_expire, password_expire_interval)
|
password_expire, password_expire_interval)
|
||||||
changed = result['changed']
|
changed = result['changed']
|
||||||
|
@ -566,7 +591,7 @@ def main():
|
||||||
priv = None # avoid granting unwanted privileges
|
priv = None # avoid granting unwanted privileges
|
||||||
reuse_existing_password = update_password == 'on_new_username'
|
reuse_existing_password = update_password == 'on_new_username'
|
||||||
result = 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,
|
plugin, plugin_hash_string, plugin_auth_string, salt,
|
||||||
priv, attributes, tls_requires, reuse_existing_password, module,
|
priv, attributes, tls_requires, reuse_existing_password, module,
|
||||||
password_expire, password_expire_interval)
|
password_expire, password_expire_interval)
|
||||||
changed = result['changed']
|
changed = result['changed']
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
test_plugin_auth_string: 'Fdt8fd^34ds'
|
test_plugin_auth_string: 'Fdt8fd^34ds'
|
||||||
test_plugin_new_hash: '*E74368AC90460FA669F6D41BFB7F2A877DB73745'
|
test_plugin_new_hash: '*E74368AC90460FA669F6D41BFB7F2A877DB73745'
|
||||||
test_plugin_new_auth_string: 'c$K01LsmK7nJnIR4!h'
|
test_plugin_new_auth_string: 'c$K01LsmK7nJnIR4!h'
|
||||||
|
test_salt: 'TDwqdanU82d0yNtvaabb'
|
||||||
test_default_priv_type: 'SELECT'
|
test_default_priv_type: 'SELECT'
|
||||||
test_default_priv: '*.*:{{ test_default_priv_type }}'
|
test_default_priv: '*.*:{{ test_default_priv_type }}'
|
||||||
|
|
||||||
|
@ -475,3 +476,71 @@
|
||||||
- include_tasks: utils/remove_user.yml
|
- include_tasks: utils/remove_user.yml
|
||||||
vars:
|
vars:
|
||||||
user_name: "{{ test_user_name }}"
|
user_name: "{{ test_user_name }}"
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Test plugin auth with a salt
|
||||||
|
#
|
||||||
|
- name: Plugin auth | Create user with plugin auth and salt
|
||||||
|
community.mysql.mysql_user:
|
||||||
|
<<: *mysql_params
|
||||||
|
name: "{{ test_user_name }}"
|
||||||
|
host: "%"
|
||||||
|
plugin: caching_sha2_password
|
||||||
|
plugin_auth_string: "{{ test_plugin_auth_string }}"
|
||||||
|
salt: "{{ test_salt }}"
|
||||||
|
priv: "{{ test_default_priv }}"
|
||||||
|
|
||||||
|
- name: Plugin auth | Connect with user and password
|
||||||
|
ansible.builtin.command: '{{ mysql_command }} -u {{ test_user_name }} -p{{ test_plugin_auth_string }} -e "SELECT 1"'
|
||||||
|
|
||||||
|
- name: Plugin auth | Alter user with same plugin auth and same salt
|
||||||
|
community.mysql.mysql_user:
|
||||||
|
<<: *mysql_params
|
||||||
|
name: "{{ test_user_name }}"
|
||||||
|
host: "%"
|
||||||
|
plugin: caching_sha2_password
|
||||||
|
plugin_auth_string: "{{ test_plugin_auth_string }}"
|
||||||
|
salt: "{{ test_salt }}"
|
||||||
|
priv: "{{ test_default_priv }}"
|
||||||
|
register: result
|
||||||
|
failed_when: result is changed
|
||||||
|
|
||||||
|
- name: cleanup user
|
||||||
|
ansible.builtin.include_tasks: utils/remove_user.yml
|
||||||
|
vars:
|
||||||
|
user_name: "{{ test_user_name }}"
|
||||||
|
|
||||||
|
- name: Plugin auth | Create user with too short salt (should fail)
|
||||||
|
community.mysql.mysql_user:
|
||||||
|
<<: *mysql_params
|
||||||
|
name: "{{ test_user_name }}"
|
||||||
|
host: "%"
|
||||||
|
plugin: caching_sha2_password
|
||||||
|
plugin_auth_string: "{{ test_plugin_auth_string }}"
|
||||||
|
salt: "1234567890az"
|
||||||
|
priv: "{{ test_default_priv }}"
|
||||||
|
register: result
|
||||||
|
failed_when: result is success
|
||||||
|
|
||||||
|
- name: Plugin auth | Create user with salt and no plugin auth string (should fail)
|
||||||
|
community.mysql.mysql_user:
|
||||||
|
<<: *mysql_params
|
||||||
|
name: "{{ test_user_name }}"
|
||||||
|
host: "%"
|
||||||
|
plugin: caching_sha2_password
|
||||||
|
salt: "{{ test_salt }}"
|
||||||
|
priv: "{{ test_default_priv }}"
|
||||||
|
register: result
|
||||||
|
failed_when: result is success
|
||||||
|
|
||||||
|
- name: Plugin auth | Create user with salt and plugin not handled by internal hash generation (should fail)
|
||||||
|
community.mysql.mysql_user:
|
||||||
|
<<: *mysql_params
|
||||||
|
name: "{{ test_user_name }}"
|
||||||
|
host: "%"
|
||||||
|
plugin: mysql_native_password
|
||||||
|
plugin_auth_string: "{{ test_plugin_auth_string }}"
|
||||||
|
salt: "{{ test_salt }}"
|
||||||
|
priv: "{{ test_default_priv }}"
|
||||||
|
register: result
|
||||||
|
failed_when: result is success
|
||||||
|
|
Loading…
Add table
Reference in a new issue