adding password_hash support to mysql_user module

fixing user_add arguments error

fixing user_mod arguments error
This commit is contained in:
trevoro 2014-10-02 10:05:35 -07:00 committed by Matt Clay
parent 55f2345829
commit b5a3dd4818

View file

@ -36,6 +36,11 @@ options:
- set the user's password. (Required when adding a user) - set the user's password. (Required when adding a user)
required: false required: false
default: null default: null
password_hash:
description:
- set the user's password hash (used in place of plain text password)
required: false
default: null
host: host:
description: description:
- the 'host' part of the MySQL username - the 'host' part of the MySQL username
@ -159,6 +164,7 @@ password=n<_665{vS43y
import getpass import getpass
import tempfile import tempfile
import re import re
import string
try: try:
import MySQLdb import MySQLdb
except ImportError: except ImportError:
@ -208,26 +214,48 @@ def user_exists(cursor, user, host):
count = cursor.fetchone() count = cursor.fetchone()
return count[0] > 0 return count[0] > 0
def user_add(cursor, user, host, password, new_priv): def user_add(cursor, user, host, password, password_hash, new_priv):
cursor.execute("CREATE USER %s@%s IDENTIFIED BY %s", (user,host,password)) if password and not password_hash:
cursor.execute("CREATE USER %s@%s IDENTIFIED BY %s", (user,host,password))
elif password_hash:
cursor.execute("CREATE USER %s@%s IDENTIFIED BY PASSWORD %s", (user,host,password_hash))
if new_priv is not None: if new_priv is not None:
for db_table, priv in new_priv.iteritems(): for db_table, priv in new_priv.iteritems():
privileges_grant(cursor, user,host,db_table,priv) privileges_grant(cursor, user,host,db_table,priv)
return True return True
def user_mod(cursor, user, host, password, new_priv, append_privs): def is_hash(password):
ishash = False
if len(password) is 41 and password[0] is '*':
ishash = True
for i in password[1:]:
if i not in string.hexdigits:
ishash = False
break
return ishash
def user_mod(cursor, user, host, password, password_hash, new_priv, append_privs):
changed = False changed = False
grant_option = False grant_option = False
# Handle passwords # Handle passwords.
if password is not None: if password is not None or password_hash is not None:
cursor.execute("SELECT password FROM user WHERE user = %s AND host = %s", (user,host)) cursor.execute("SELECT password FROM user WHERE user = %s AND host = %s", (user,host))
current_pass_hash = cursor.fetchone() current_pass_hash = cursor.fetchone()
cursor.execute("SELECT PASSWORD(%s)", (password,))
new_pass_hash = cursor.fetchone() if password:
if current_pass_hash[0] != new_pass_hash[0]: cursor.execute("SELECT PASSWORD(%s)", (password,))
cursor.execute("SET PASSWORD FOR %s@%s = PASSWORD(%s)", (user,host,password)) new_pass_hash = cursor.fetchone()
changed = True if current_pass_hash[0] != new_pass_hash[0]:
cursor.execute("SET PASSWORD FOR %s@%s = PASSWORD(%s)", (user,host,password))
changed = True
elif password_hash:
if is_hash(password_hash):
if current_pass_hash[0] != password_hash:
cursor.execute("SET PASSWORD FOR %s@%s = %s", (user, host, password_hash))
changed = True
else:
module.fail_json(msg="password_hash was specified however it does not appear to be a valid hash expecting: *SHA1(SHA1(your_password))")
# Handle privileges # Handle privileges
if new_priv is not None: if new_priv is not None:
@ -384,7 +412,8 @@ def main():
login_port=dict(default=3306, type='int'), login_port=dict(default=3306, type='int'),
login_unix_socket=dict(default=None), login_unix_socket=dict(default=None),
user=dict(required=True, aliases=['name']), user=dict(required=True, aliases=['name']),
password=dict(default=None, no_log=True), password=dict(default=None),
password_hash=dict(default=None),
host=dict(default="localhost"), host=dict(default="localhost"),
state=dict(default="present", choices=["absent", "present"]), state=dict(default="present", choices=["absent", "present"]),
priv=dict(default=None), priv=dict(default=None),
@ -398,7 +427,8 @@ def main():
login_password = module.params["login_password"] login_password = module.params["login_password"]
user = module.params["user"] user = module.params["user"]
password = module.params["password"] password = module.params["password"]
host = module.params["host"].lower() password_hash = module.params["password_hash"]
host = module.params["host"]
state = module.params["state"] state = module.params["state"]
priv = module.params["priv"] priv = module.params["priv"]
check_implicit_admin = module.params['check_implicit_admin'] check_implicit_admin = module.params['check_implicit_admin']
@ -430,21 +460,11 @@ def main():
if state == "present": if state == "present":
if user_exists(cursor, user, host): if user_exists(cursor, user, host):
try: changed = user_mod(cursor, user, host, password, password_hash, priv, append_privs)
if update_password == 'always':
changed = user_mod(cursor, user, host, password, priv, append_privs)
else:
changed = user_mod(cursor, user, host, None, priv, append_privs)
except (SQLParseError, InvalidPrivsError, MySQLdb.Error), e:
module.fail_json(msg=str(e))
else: else:
if password is None: if password is None and password_hash is None:
module.fail_json(msg="password parameter required when adding a user") module.fail_json(msg="password or password_hash parameter required when adding a user")
try: changed = user_add(cursor, user, host, password, password_hash, priv)
changed = user_add(cursor, user, host, password, priv)
except (SQLParseError, InvalidPrivsError, MySQLdb.Error), e:
module.fail_json(msg=str(e))
elif state == "absent": elif state == "absent":
if user_exists(cursor, user, host): if user_exists(cursor, user, host):
changed = user_delete(cursor, user, host) changed = user_delete(cursor, user, host)