Commit d0429218 authored by anarcat's avatar anarcat Committed by anarcat
Browse files

Refactor the algorigthms to guess the proper 'host' part of the MySQL

user names

Completely remove the user when revoking his privileges.

Closes: #455954
parent 897577ca
......@@ -11,8 +11,6 @@ function drush_provision_mysql_provision_delete_validate() {
* This will drop the database, revoke the privileges and flush the privileges.
*/
function drush_provision_mysql_provision_delete($url = NULL) {
return _provision_mysql_destroy_site_db(
drush_get_option('db_name'), drush_get_option('db_user'),
drush_get_option('db_passwd'), drush_get_option('db_host'));
return _provision_mysql_destroy_site_db(drush_get_option('db_name'), drush_get_option('db_user'), drush_get_option('db_passwd'));
}
......@@ -11,7 +11,7 @@ function drush_provision_mysql_provision_deploy($url) {
$db_name = drush_set_option('db_name', _provision_mysql_suggest_db_name($url), 'site');
$db_user = drush_set_option('db_user', $db_name, 'site');
_provision_mysql_new_site_db($db_name, $db_user, $db_passwd, $db_host);
_provision_mysql_new_site_db($db_name, $db_user, $db_passwd);
_provision_mysql_import_dump(
drush_get_option('sites_path') .'/'. $url .'/database.sql',
......@@ -20,10 +20,7 @@ function drush_provision_mysql_provision_deploy($url) {
function drush_provision_mysql_provision_deploy_rollback($url = NULL) {
_provision_mysql_destroy_site_db(
drush_get_option('db_name'), drush_get_option('db_user'),
drush_get_option('db_passwd'), drush_get_option('db_host')
);
_provision_mysql_destroy_site_db(drush_get_option('db_name'), drush_get_option('db_user'), drush_get_option('db_passwd'));
}
// Rollback doesn't apply here yet. Unless we trigger a deploy of the first dump
......
......@@ -11,21 +11,9 @@ function drush_provision_mysql_pre_provision_install($url = NULL) {
$db_name = drush_set_option('db_name', _provision_mysql_suggest_db_name($url), 'site');
$db_user = drush_set_option('db_user', $db_name, 'site');
// fetch the webserver name to create a GRANT specific to this server
$db_client = drush_get_option('web_ip');
if (!$db_client) {
// the IP isn't available, use the web host for the GRANT
$db_client = drush_get_option('web_host');
} elseif ($db_host = 'localhost' && $db_client == '127.0.0.1') {
// 'localhost' really means the socket here, so IP-based doesn't work
$db_client = 'localhost';
}
_provision_mysql_new_site_db($db_name, $db_user, $db_passwd, $db_client);
_provision_mysql_new_site_db($db_name, $db_user, $db_passwd);
}
function drush_provision_mysql_pre_provision_install_rollback($url = NULL) {
_provision_mysql_destroy_site_db(
drush_get_option('db_name'), drush_get_option('db_user'),
drush_get_option('db_passwd'), drush_get_option('db_host')
);
_provision_mysql_destroy_site_db(drush_get_option('db_name'), drush_get_option('db_user'), drush_get_option('db_passwd'));
}
......@@ -70,6 +70,17 @@ function provision_db_result($result, $row = 0) {
return FALSE;
}
/**
* Fetch one row from the result set
*
* @see db_fetch_array
*/
function provision_db_fetch_array($result) {
if ($result) {
return mysql_fetch_array($result, MYSQL_ASSOC);
}
return $result;
}
/**
* Indicates the place holders that should be replaced in _db_query_callback().
......
......@@ -39,7 +39,10 @@ function provision_mysql_drush_help($section) {
/**
* Generate a new mysql database and user account for the specified credentials
*/
function _provision_mysql_new_site_db($db_name, $db_user, $db_passwd, $db_client) {
function _provision_mysql_new_site_db($db_name, $db_user, $db_passwd, $db_client = NULL) {
if (is_null($db_client)) {
$db_client = _provision_mysql_guess_dbclient(drush_get_option('web_ip'), drush_get_option('web_host'));
}
if (!_provision_mysql_create_database($db_name) ||
!_provision_mysql_database_exists($db_name) ) {
drush_set_error('PROVISION_CREATE_DB_FAILED');
......@@ -67,8 +70,10 @@ function _provision_mysql_new_site_db($db_name, $db_user, $db_passwd, $db_client
/**
* Remove the database and user account for the supplied credentials
*/
function _provision_mysql_destroy_site_db($db_name, $db_user, $db_passwd, $db_host) {
function _provision_mysql_destroy_site_db($db_name, $db_user, $db_passwd, $db_client = NULL) {
if (is_null($db_client)) {
$db_client = _provision_mysql_guess_dbclient(drush_get_option('web_ip'), drush_get_option('web_host'));
}
if ( _provision_mysql_database_exists($db_name) ) {
drush_log(dt("Dropping database @dbname", array('@dbname' => $db_name)));
if (!_provision_mysql_drop_database($db_name)) {
......@@ -81,9 +86,9 @@ function _provision_mysql_destroy_site_db($db_name, $db_user, $db_passwd, $db_ho
return FALSE;
}
drush_log("Revoking privileges");
drush_log(dt("Revoking privileges of %user@%client from %database", array('%user' => $db_user, '%client' => $db_client, '%database' => $db_name)));
_provision_mysql_flush_privileges();
if (!_provision_mysql_revoke($db_name, $db_user)) {
if (!_provision_mysql_revoke($db_name, $db_user, $db_client)) {
drush_log(dt("Failed to revoke user privileges"), 'warning');
}
}
......@@ -124,7 +129,23 @@ function _provision_mysql_grant($name, $username, $password, $host = '') {
function _provision_mysql_revoke($name, $username, $host = '') {
$host = ($host) ? $host : '%';
return provision_db_query("REVOKE ALL PRIVILEGES ON `%s`.* FROM `%s`@`%s`", $name, $username, $host);
$success = provision_db_query("REVOKE ALL PRIVILEGES ON `%s`.* FROM `%s`@`%s`", $name, $username, $host);
// check if there are any privileges left for the user
$grants = provision_db_query("SHOW GRANTS FOR `%s`@`%s`", $username, $host);
$grant_found = FALSE;
while ($grant = provision_db_fetch_array($grants)) {
// those are empty grants: just the user line
if (!preg_match("/^GRANT USAGE ON /", array_pop($grant))) {
// real grant, we shouldn't remove the user
$grant_found = TRUE;
break;
}
}
if (!$grant_found) {
$success = provision_db_query("DROP USER `%s`@`%s`", $username, $host) && $success;
}
return $success;
}
function _provision_mysql_import_dump($dump_file, $db_name, $db_user, $db_passwd, $db_host) {
......@@ -188,3 +209,28 @@ function _provision_mysql_suggest_db_name($url) {
return false;
}
/**
* Properly guess the host part of the MySQL username based on a given
* IP and web_host
*
* Basically, we give priority to the IP. If it's not present, we use
* the hostname directly.
*
* There is a special case to handle the case where the host is
* 'localhost' and (therefore) the IP resolved in the frontend is
* '127.0.0.1': in this case, we want to use the socket, so we revert
* back to the 'localhost' string.
*/
function _provision_mysql_guess_dbclient($web_ip, $web_host) {
// fetch the webserver name to create a GRANT specific to this server
$db_client = $web_ip;
if (!$db_client) {
// the IP isn't available, use the web host for the GRANT
$db_client = $web_host;
} elseif ($db_host = 'localhost' && $db_client == '127.0.0.1') {
// 'localhost' really means the socket here, so IP-based doesn't work
$db_client = 'localhost';
}
return $db_client;
}
\ No newline at end of file
......@@ -11,7 +11,7 @@ function drush_provision_mysql_pre_provision_restore($url = NULL) {
$db_name = drush_set_option('db_name', _provision_mysql_suggest_db_name($url));
$db_user = drush_set_option('db_user', $db_name);
_provision_mysql_new_site_db($db_name, $db_user, $db_passwd, $db_host);
_provision_mysql_new_site_db($db_name, $db_user, $db_passwd);
}
function drush_provision_mysql_provision_restore($url) {
......@@ -24,9 +24,7 @@ function drush_provision_mysql_provision_restore($url) {
function drush_provision_mysql_pre_provision_restore_rollback($url = NULL) {
_provision_mysql_destroy_site_db(
drush_get_option('db_name'), drush_get_option('db_user'),
drush_get_option('db_passwd'), drush_get_option('db_host'));
_provision_mysql_destroy_site_db(drush_get_option('db_name'), drush_get_option('db_user'), drush_get_option('db_passwd'));
$keys = array('db_name', 'db_passwd', 'db_user', 'db_host');
......@@ -46,11 +44,9 @@ function drush_provision_mysql_post_provision_restore($url = NULL) {
dt("Removed dump file @path after restoring from it"),
dt("Could not remove dump file @path"), DRUSH_PERM_ERROR);
$db_client = _provision_mysql_guess_dbclient(drush_get_option('web_ip', null, 'site'), drush_get_option('web_host', null, 'site'));
// We have now completed successfully, remove the old database.
_provision_mysql_destroy_site_db(
drush_get_option('db_name', null, 'site'), drush_get_option('db_user', null, 'site'),
drush_get_option('db_passwd', null, 'site'), drush_get_option('db_host', null, 'site')
);
_provision_mysql_destroy_site_db(drush_get_option('db_name', null, 'site'), drush_get_option('db_user', null, 'site'), drush_get_option('db_passwd', null, 'site'), $db_client);
// The new database credentials will be saved against the site now.
drush_set_option('db_name', drush_get_option('db_name'), 'site');
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment