Repository: ansible/ansible-modules-core

Issue:
Add plugin as parameter for mysql_user 
##### Issue Type:

Feature Idea
##### Ansible Version:

```
$ ansible --version
ansible 2.0.0.0
  config file = 
  configured module search path = Default w/o overrides
```
##### Ansible Configuration:

Default configuration.
##### Environment:

N/A
##### Summary:

From the MySQL 5.7 what's new page:

> The server now requires account rows in the mysql.user table to have a nonempty plugin column value and disables accounts with an empty value.

On a fresh installation of MySQL 5.7 the `root` user for host `localhost` is now configured with a plugin value of `auth_socket`. This prevents users other then root to connect as root using the `mysql` client utility:

```
user@server$ mysql -u root -pP4ssw0rd -h localhost
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
```

While as root this works:

```
root@server# mysql -u root -pP4ssw0rd -h localhost
```

Currently I can't change this configuration with Ansible.
##### Steps To Reproduce:

It would be nice to introduce a new parameter to this module which accepts all possible plugin values (defaulting to mysql_native_password) , e.g.:

``` yaml
mysql_user: name=root password=abc123 plugin=mysql_native_password
mysql_user: name=root password=abc123 plugin=auth_socket
```
##### Expected Results:

N/A
##### Actual Results:

N/A

Add plugin as parameter for mysql_user 
##### Issue Type:

Feature Idea
##### Ansible Version:

```
$ ansible --version
ansible 2.0.0.0
  config file = 
  configured module search path = Default w/o overrides
```
##### Ansible Configuration:

Default configuration.
##### Environment:

N/A
##### Summary:

From the MySQL 5.7 what's new page:

> The server now requires account rows in the mysql.user table to have a nonempty plugin column value and disables accounts with an empty value.

On a fresh installation of MySQL 5.7 the `root` user for host `localhost` is now configured with a plugin value of `auth_socket`. This prevents users other then root to connect as root using the `mysql` client utility:

```
user@server$ mysql -u root -pP4ssw0rd -h localhost
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
```

While as root this works:

```
root@server# mysql -u root -pP4ssw0rd -h localhost
```

Currently I can't change this configuration with Ansible.
##### Steps To Reproduce:

It would be nice to introduce a new parameter to this module which accepts all possible plugin values (defaulting to mysql_native_password) , e.g.:

``` yaml
mysql_user: name=root password=abc123 plugin=mysql_native_password
mysql_user: name=root password=abc123 plugin=auth_socket
```
##### Expected Results:

N/A
##### Actual Results:

N/A



Discussion:
@nitzmahone Thank you for bringing this to our attention. I will try and take a stab at this later in the week.

@nitzmahone 

From Mysql Docs

```
CREATE USER 'testuser'@'localhost' IDENTIFIED WITH test_plugin_server;
```

What we currently have

```
cursor.execute("CREATE USER %s@%s IDENTIFIED BY %s", (user,host,password))
```

Do you know the syntax create a user with a password, and a plugin?

Or am I looking at this completely wrong, basically if plugin is supplied, identify with plugin, otherwise identify with password?

I'll chip in here:

When you want to authenticate by auth_socket for example, you don't need a password, so 

`CREATE USER 'testuser'@'localhost' IDENTIFIED WITH auth_socket`

If you want to use a password ( mysql_native_password, ... ), you have to use

`CREATE USER 'testuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'cleartextpass'`

or

`CREATE USER 'testuser'@'localhost' IDENTIFIED WITH mysql_native_password AS '*MYSQLHASH'`

@verwilst Thank you that clears it up for me, I will continue to work on this, in the meantime if someone else beats me to it that would be great

As seen above, I've added support for plugins to the devel branch. Please review. ;-)

Second pull request for 2.1

@Jmainguy, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/jctanner/ansibullbot/blob/ISSUE_TRIAGE_CLASS/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

@Jmainguy, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

@Jmainguy, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

Hello,

Very interesting, is it possible to add a parameter to specify identified with value ?

default value : mysql_native_password
password parameter switch to non required

Typical case is ldap/pam authentication :
`create user house@'localhost' identified with auth_pam;`

Please note the warning in: https://www.percona.com/blog/2016/03/16/change-user-password-in-mysql-5-7-with-plugin-auth_socket/

You should set the password of root@localhost and enable mysql_native_password in one action. Otherwise root-access could be exposed.

Would it be possible to do the right thing automatically if MySQL(-like) 5.7+ is detected and you want to set a password?

Setting the password if auth_socket is enabled is a NOOP/ERROR anyway.

[This is the approach I used](http://stackoverflow.com/a/40059130/763419) - i.e. set the desired root password in debconf, then install the MySQL package.  It'd be nice to be able to combine those first steps into a single task, i.e. not having to specify the password separately (or twice).  

And perhaps it's desirable to remove the password from debconf afterwards (or maybe it isn't)?

@ricbra the cause of your problem is that in the current master the IDENTIFIED WITH mysql_native_password is only called if you set a password-hash but not if you use a plaintext password.

Busy with a patch right now.

@wturrell interesting but not the specific issue discussed here.

@nitzmahone Thank you for bringing this to our attention. I will try and take a stab at this later in the week.

@nitzmahone 

From Mysql Docs

```
CREATE USER 'testuser'@'localhost' IDENTIFIED WITH test_plugin_server;
```

What we currently have

```
cursor.execute("CREATE USER %s@%s IDENTIFIED BY %s", (user,host,password))
```

Do you know the syntax create a user with a password, and a plugin?

Or am I looking at this completely wrong, basically if plugin is supplied, identify with plugin, otherwise identify with password?

I'll chip in here:

When you want to authenticate by auth_socket for example, you don't need a password, so 

`CREATE USER 'testuser'@'localhost' IDENTIFIED WITH auth_socket`

If you want to use a password ( mysql_native_password, ... ), you have to use

`CREATE USER 'testuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'cleartextpass'`

or

`CREATE USER 'testuser'@'localhost' IDENTIFIED WITH mysql_native_password AS '*MYSQLHASH'`

@verwilst Thank you that clears it up for me, I will continue to work on this, in the meantime if someone else beats me to it that would be great

As seen above, I've added support for plugins to the devel branch. Please review. ;-)

Second pull request for 2.1

@Jmainguy, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/jctanner/ansibullbot/blob/ISSUE_TRIAGE_CLASS/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

@Jmainguy, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

@Jmainguy, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

Hello,

Very interesting, is it possible to add a parameter to specify identified with value ?

default value : mysql_native_password
password parameter switch to non required

Typical case is ldap/pam authentication :
`create user house@'localhost' identified with auth_pam;`

Please note the warning in: https://www.percona.com/blog/2016/03/16/change-user-password-in-mysql-5-7-with-plugin-auth_socket/

You should set the password of root@localhost and enable mysql_native_password in one action. Otherwise root-access could be exposed.

Would it be possible to do the right thing automatically if MySQL(-like) 5.7+ is detected and you want to set a password?

Setting the password if auth_socket is enabled is a NOOP/ERROR anyway.

[This is the approach I used](http://stackoverflow.com/a/40059130/763419) - i.e. set the desired root password in debconf, then install the MySQL package.  It'd be nice to be able to combine those first steps into a single task, i.e. not having to specify the password separately (or twice).  

And perhaps it's desirable to remove the password from debconf afterwards (or maybe it isn't)?

@ricbra the cause of your problem is that in the current master the IDENTIFIED WITH mysql_native_password is only called if you set a password-hash but not if you use a plaintext password.

Busy with a patch right now.

@wturrell interesting but not the specific issue discussed here.


Resolving patch:
diff --git a/database/mysql/mysql_user.py b/database/mysql/mysql_user.py
--- a/database/mysql/mysql_user.py
+++ b/database/mysql/mysql_user.py
@@ -293,7 +293,7 @@ def user_mod(cursor, user, host, host_all, password, encrypted, new_priv, append
                     if old_user_mgmt:
                         cursor.execute("SET PASSWORD FOR %s@%s = PASSWORD(%s)", (user, host, password))
                     else:
-                        cursor.execute("ALTER USER %s@%s IDENTIFIED BY %s", (user, host, password))
+                        cursor.execute("ALTER USER %s@%s IDENTIFIED WITH mysql_native_password BY %s", (user, host, password))
                     changed = True
 
         # Handle privileges


Test patch: