diff --git a/cdist/conf/type/__mysql_database/explorer/state b/cdist/conf/type/__mysql_database/explorer/state
new file mode 100755
index 00000000..16cc9ce5
--- /dev/null
+++ b/cdist/conf/type/__mysql_database/explorer/state
@@ -0,0 +1,15 @@
+#!/bin/sh -e
+
+if [ -f "$__object/parameter/name" ]
+then
+ name="$( cat "$__object/parameter/name" )"
+else
+ name="$__object_id"
+fi
+
+if [ -n "$( mysql -B -N -e "show databases like '$name'" )" ]
+then
+ echo 'present'
+else
+ echo 'absent'
+fi
diff --git a/cdist/conf/type/__mysql_database/gencode-remote b/cdist/conf/type/__mysql_database/gencode-remote
index 23e51b05..d3692572 100755
--- a/cdist/conf/type/__mysql_database/gencode-remote
+++ b/cdist/conf/type/__mysql_database/gencode-remote
@@ -1,54 +1,28 @@
#!/bin/sh -e
-#
-# 2012 Benedikt Koeppel (code@benediktkoeppel.ch)
-#
-# This file is part of cdist.
-#
-# cdist is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# cdist is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with cdist. If not, see .
-#
-#
-# if --database was specified
-if [ -f "$__object/parameter/name" ]; then
- database="$(cat "$__object/parameter/name")"
-else # otherwise use the object id as database name
- database="$__object_id"
+state_is="$( cat "$__object/explorer/state" )"
+
+state_should="$( cat "$__object/parameter/state" )"
+
+if [ "$state_is" = "$state_should" ]
+then
+ exit 0
fi
-cat <<-EOFF
-mysql -u root <<-EOF
- CREATE DATABASE IF NOT EXISTS $database
-EOF
-EOFF
-
-# if --user was specified
-if [ -f "$__object/parameter/user" ]; then
- user="$(cat "$__object/parameter/user")"
-
- # if --password was specified
- if [ -f "$__object/parameter/password" ]; then
- password="$(cat "$__object/parameter/password")"
- cat <<-EOFF
- mysql -u root <<-EOF
- GRANT ALL PRIVILEGES ON $database.* to '$user'@'localhost' IDENTIFIED BY '$password';
-EOF
-EOFF
- else
- cat <<-EOFF
- mysql -u root <<-EOF
- GRANT ALL PRIVILEGES ON $database.* to '$user'@'localhost';
-EOF
-EOFF
- fi
+if [ -f "$__object/parameter/name" ]
+then
+ name="$( cat "$__object/parameter/name" )"
+else
+ name="$__object_id"
fi
+
+case "$state_should" in
+ present)
+ echo "mysql -e 'create database \`$name\`'"
+ echo "create database $name" >> "$__messages_out"
+ ;;
+ absent)
+ echo "mysql -e 'drop database \`$name\`'"
+ echo "drop database $name" >> "$__messages_out"
+ ;;
+esac
diff --git a/cdist/conf/type/__mysql_database/man.rst b/cdist/conf/type/__mysql_database/man.rst
deleted file mode 100644
index 1e245a08..00000000
--- a/cdist/conf/type/__mysql_database/man.rst
+++ /dev/null
@@ -1,49 +0,0 @@
-cdist-type__mysql_database(7)
-=============================
-
-NAME
-----
-cdist-type__mysql_database - Manage a MySQL database
-
-
-DESCRIPTION
------------
-This cdist type allows you to install a MySQL database.
-
-
-REQUIRED PARAMETERS
--------------------
-None.
-
-OPTIONAL PARAMETERS
--------------------
-name
- The name of the database to install
- defaults to the object id
-
-user
- A user that should have access to the database
-
-password
- The password for the user who manages the database
-
-
-EXAMPLES
---------
-
-.. code-block:: sh
-
- __mysql_database "cdist" --name "cdist" --user "myuser" --password "mypwd"
-
-
-AUTHORS
--------
-Benedikt Koeppel
-
-
-COPYING
--------
-Copyright \(C) 2012 Benedikt Koeppel. You can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
diff --git a/cdist/conf/type/__mysql_database/manifest b/cdist/conf/type/__mysql_database/manifest
new file mode 100755
index 00000000..a57c31ce
--- /dev/null
+++ b/cdist/conf/type/__mysql_database/manifest
@@ -0,0 +1,26 @@
+#!/bin/sh -e
+
+if [ -f "$__object/parameter/user" ]
+then
+ user="$( cat "$__object/parameter/user" )"
+fi
+
+if [ -f "$__object/parameter/password" ]
+then
+ password="$( cat "$__object/parameter/password" )"
+fi
+
+if [ -n "$user" ] && [ -n "$password" ]
+then
+ if [ -f "$__object/parameter/name" ]
+ then
+ database="$( cat "$__object/parameter/name" )"
+ else
+ database="$__object_id"
+ fi
+
+ __mysql_user "$user" --password "$password"
+
+ require="__mysql_user/$user" \
+ __mysql_privileges "$database/$user" --database "$database" --user "$user"
+fi
diff --git a/cdist/conf/type/__mysql_database/parameter/default/state b/cdist/conf/type/__mysql_database/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__mysql_database/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__mysql_database/parameter/optional b/cdist/conf/type/__mysql_database/parameter/optional
index 756afee7..6c0b1e85 100644
--- a/cdist/conf/type/__mysql_database/parameter/optional
+++ b/cdist/conf/type/__mysql_database/parameter/optional
@@ -1,3 +1,4 @@
name
user
password
+state
diff --git a/cdist/conf/type/__mysql_privileges/explorer/state b/cdist/conf/type/__mysql_privileges/explorer/state
new file mode 100755
index 00000000..97674479
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/explorer/state
@@ -0,0 +1,22 @@
+#!/bin/sh -e
+
+privileges="$( cat "$__object/parameter/privileges" )"
+
+database="$( cat "$__object/parameter/database" )"
+
+table="$( cat "$__object/parameter/table" )"
+
+user="$( cat "$__object/parameter/user" )"
+
+host="$( cat "$__object/parameter/host" )"
+
+check_privileges="$(
+ mysql -B -N -e "show grants for '$user'@'$host'" \
+ | grep -Ei "^grant $privileges on .$database.\..$table. to " || true )"
+
+if [ -n "$check_privileges" ]
+then
+ echo 'present'
+else
+ echo 'absent'
+fi
diff --git a/cdist/conf/type/__mysql_privileges/gencode-remote b/cdist/conf/type/__mysql_privileges/gencode-remote
new file mode 100755
index 00000000..6b2e0fc1
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/gencode-remote
@@ -0,0 +1,31 @@
+#!/bin/sh -e
+
+state_is="$( cat "$__object/explorer/state" )"
+
+state_should="$( cat "$__object/parameter/state" )"
+
+if [ "$state_is" = "$state_should" ]
+then
+ exit 0
+fi
+
+privileges="$( cat "$__object/parameter/privileges" )"
+
+database="$( cat "$__object/parameter/database" )"
+
+table="$( cat "$__object/parameter/table" )"
+
+user="$( cat "$__object/parameter/user" )"
+
+host="$( cat "$__object/parameter/host" )"
+
+case "$state_should" in
+ present)
+ echo "mysql -e 'grant $privileges on \`$database\`.\`$table\` to \`$user\`@\`$host\`'"
+ echo "grant $privileges on $database.$table to $user@$host" >> "$__messages_out"
+ ;;
+ absent)
+ echo "mysql -e 'revoke $privileges on \`$database\`.\`$table\` from \`$user\`@\`$host\`'"
+ echo "revoke $privileges on $database.$table from $user@$host" >> "$__messages_out"
+ ;;
+esac
diff --git a/cdist/conf/type/__mysql_privileges/parameter/default/host b/cdist/conf/type/__mysql_privileges/parameter/default/host
new file mode 100644
index 00000000..2fbb50c4
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/parameter/default/host
@@ -0,0 +1 @@
+localhost
diff --git a/cdist/conf/type/__mysql_privileges/parameter/default/privileges b/cdist/conf/type/__mysql_privileges/parameter/default/privileges
new file mode 100644
index 00000000..5472efad
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/parameter/default/privileges
@@ -0,0 +1 @@
+all privileges
diff --git a/cdist/conf/type/__mysql_privileges/parameter/default/state b/cdist/conf/type/__mysql_privileges/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__mysql_privileges/parameter/default/table b/cdist/conf/type/__mysql_privileges/parameter/default/table
new file mode 100644
index 00000000..72e8ffc0
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/parameter/default/table
@@ -0,0 +1 @@
+*
diff --git a/cdist/conf/type/__mysql_privileges/parameter/optional b/cdist/conf/type/__mysql_privileges/parameter/optional
new file mode 100644
index 00000000..d4ed5bc5
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/parameter/optional
@@ -0,0 +1,4 @@
+privileges
+table
+host
+state
diff --git a/cdist/conf/type/__mysql_privileges/parameter/required b/cdist/conf/type/__mysql_privileges/parameter/required
new file mode 100644
index 00000000..152b4a1e
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/parameter/required
@@ -0,0 +1,2 @@
+database
+user
diff --git a/cdist/conf/type/__mysql_user/explorer/state b/cdist/conf/type/__mysql_user/explorer/state
new file mode 100755
index 00000000..c91bb36a
--- /dev/null
+++ b/cdist/conf/type/__mysql_user/explorer/state
@@ -0,0 +1,36 @@
+#!/bin/sh -e
+
+if [ -f "$__object/parameter/name" ]
+then
+ name="$( cat "$__object/parameter/name" )"
+else
+ name="$__object_id"
+fi
+
+if [ -f "$__object/parameter/password" ]
+then
+ password="$( cat "$__object/parameter/password" )"
+else
+ password=''
+fi
+
+host="$( cat "$__object/parameter/host" )"
+
+check_user="$( mysql -B -N -e "select user from mysql.user where user = '$name' and host = '$host'" )"
+
+if [ -n "$check_user" ]
+then
+ if [ -n "$password" ]
+ then
+ check_password="$( mysql -B -N -e "select user from mysql.user where user = '$name' and host = '$host' and password = password( '$password' )" )"
+ fi
+
+ if [ -n "$password" ] && [ -z "$check_password" ]
+ then
+ echo 'change-password'
+ else
+ echo 'present'
+ fi
+else
+ echo 'absent'
+fi
diff --git a/cdist/conf/type/__mysql_user/gencode-remote b/cdist/conf/type/__mysql_user/gencode-remote
new file mode 100755
index 00000000..67500716
--- /dev/null
+++ b/cdist/conf/type/__mysql_user/gencode-remote
@@ -0,0 +1,50 @@
+#!/bin/sh -e
+
+state_is="$( cat "$__object/explorer/state" )"
+
+state_should="$( cat "$__object/parameter/state" )"
+
+if [ "$state_is" = "$state_should" ]
+then
+ exit 0
+fi
+
+if [ -f "$__object/parameter/name" ]
+then
+ name="$( cat "$__object/parameter/name" )"
+else
+ name="$__object_id"
+fi
+
+host="$( cat "$__object/parameter/host" )"
+
+if [ -f "$__object/parameter/password" ]
+then
+ password="$( cat "$__object/parameter/password" )"
+else
+ if [ "$state_should" = 'present' ]
+ then
+ echo '--password needed' >&2
+ exit 1
+ else
+ password=''
+ fi
+fi
+
+if [ "$state_is" = 'absent' ] && [ "$state_should" = 'present' ]
+then
+ echo "mysql -e 'create user \`$name\`@\`$host\` identified by \"$password\"'"
+ echo "create user $name@$host" >> "$__messages_out"
+
+elif [ "$state_is" != 'absent' ] && [ "$state_should" = 'absent' ]
+then
+ echo "mysql -e 'drop user \`$name\`@\`$host\`'"
+ echo "drop user $name@$host" >> "$__messages_out"
+
+elif [ "$state_is" = 'change-password' ]
+then
+ # this only works with MySQL 5.7.6 and later or MariaDB 10.1.20 and later
+ echo "mysql -e 'alter user \`$name\`@\`$host\` identified by \"$password\"'"
+ echo "mysql -e 'flush privileges'"
+ echo "change password $name@$host" >> "$__messages_out"
+fi
diff --git a/cdist/conf/type/__mysql_user/parameter/default/host b/cdist/conf/type/__mysql_user/parameter/default/host
new file mode 100644
index 00000000..2fbb50c4
--- /dev/null
+++ b/cdist/conf/type/__mysql_user/parameter/default/host
@@ -0,0 +1 @@
+localhost
diff --git a/cdist/conf/type/__mysql_user/parameter/default/state b/cdist/conf/type/__mysql_user/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__mysql_user/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__mysql_user/parameter/optional b/cdist/conf/type/__mysql_user/parameter/optional
new file mode 100644
index 00000000..a286266c
--- /dev/null
+++ b/cdist/conf/type/__mysql_user/parameter/optional
@@ -0,0 +1,4 @@
+name
+host
+password
+state