summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2013-11-25 23:59:15 +0100
committerGuilhem Moulin <guilhem@fripost.org>2015-06-07 02:50:49 +0200
commit98f094ac5f59ad223f2dd930fc70c36059d631c8 (patch)
treea9642a4cc85604dfa6810dd4cee38d498683c89d
parent652b443f210abef9cd1e6d01799533761bd4d484 (diff)
Add support for MySQL's Authentication Plugins.
A.k.a "IDENTIFIED WITH ...". The plugin is automatically loaded on first use. References: - https://dev.mysql.com/doc/refman/5.5/en/pluggable-authentication.html - https://dev.mysql.com/doc/refman/5.5/en/socket-authentication-plugin.html Sadly as of MySQL 5.5, the "ALTER USER" command does not allow changing the Authentication Plugin, so we have to manually manipulate `mysql.user` (and FLUSH PRIVILEGES) instead. See also http://bugs.mysql.com/bug.php?id=67449
-rw-r--r--lib/mysql_user39
1 files changed, 32 insertions, 7 deletions
diff --git a/lib/mysql_user b/lib/mysql_user
index 9758939..602235a 100644
--- a/lib/mysql_user
+++ b/lib/mysql_user
@@ -151,17 +151,40 @@ def user_exists(cursor, user, host):
count = cursor.fetchone()
return count[0] > 0
-def user_add(cursor, user, host, password, new_priv):
- cursor.execute("CREATE USER %s@%s IDENTIFIED BY %s", (user,host,password))
+def load_plugin(cursor, plugin):
+ cursor.execute("SELECT count(*) FROM plugin WHERE name = %s", plugin)
+ count = cursor.fetchone()
+ if count[0] == 0:
+ so = "%s.so" % plugin
+ cursor.execute("INSTALL PLUGIN %s SONAME %s", (plugin, so))
+
+def user_add(cursor, user, host, password, new_priv, auth_plugin):
+ if password is None:
+ # Automatically loaded on first first use.
+ load_plugin(cursor, auth_plugin)
+ cursor.execute("CREATE USER %s@%s IDENTIFIED WITH %s", (user,host,auth_plugin))
+ else:
+ cursor.execute("CREATE USER %s@%s IDENTIFIED BY %s", (user,host,password))
if new_priv is not None:
for db_table, priv in new_priv.iteritems():
privileges_grant(cursor, user,host,db_table,priv)
return True
-def user_mod(cursor, user, host, password, new_priv, append_privs):
+def user_mod(cursor, user, host, password, new_priv, append_privs, auth_plugin):
changed = False
grant_option = False
+ # Handle plugin.
+ if auth_plugin is not None:
+ cursor.execute("SELECT plugin FROM user WHERE user = %s AND host = %s", (user,host))
+ if cursor.fetchone()[0] != auth_plugin:
+ # Sadly there is no proper way to updade the authentication plugin:
+ # http://bugs.mysql.com/bug.php?id=67449
+ cursor.execute( "UPDATE user SET plugin = %s, password = '' WHERE user = %s AND host = %s"
+ , (auth_plugin,user,host))
+ cursor.execute("FLUSH PRIVILEGES")
+ changed = True
+
# Handle passwords.
if password is not None:
cursor.execute("SELECT password FROM user WHERE user = %s AND host = %s", (user,host))
@@ -399,6 +422,7 @@ def main():
priv=dict(default=None),
append_privs=dict(type="bool", default="no"),
check_implicit_admin=dict(default=False),
+ auth_plugin=dict(default=None)
)
)
user = module.params["user"]
@@ -408,6 +432,7 @@ def main():
priv = module.params["priv"]
check_implicit_admin = module.params['check_implicit_admin']
append_privs = module.boolean(module.params["append_privs"])
+ auth_plugin = module.params['auth_plugin']
if not mysqldb_found:
module.fail_json(msg="the python mysqldb module is required")
@@ -449,11 +474,11 @@ def main():
if state == "present":
if user_exists(cursor, user, host):
- changed = user_mod(cursor, user, host, password, priv, append_privs)
+ changed = user_mod(cursor, user, host, password, priv, append_privs, auth_plugin)
else:
- if password is None:
- module.fail_json(msg="password parameter required when adding a user")
- changed = user_add(cursor, user, host, password, priv)
+ if (password is None and auth_plugin is None) or (password is not None and auth_plugin is not None):
+ module.fail_json(msg="password xor auth_plugin is required when adding a user")
+ changed = user_add(cursor, user, host, password, priv, auth_plugin)
elif state == "absent":
if user_exists(cursor, user, host):
changed = user_delete(cursor, user, host)